fix(pi-plugin): load native handoff SDK only on supported runtimes
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import {expect, it} from "vitest";
|
||||
|
||||
const [major, minor] = process.versions.node.split(".").map(Number);
|
||||
// The real Pi 0.79 SDK declares Node >=22.19; Node 20 tests cover startup and the explicit guard.
|
||||
it.skipIf(major < 22 || (major === 22 && minor < 19))("native Pi resolves the selected leaf and readable compaction context", async () => {
|
||||
const {buildSessionContext, convertToLlm} = await import("@earendil-works/pi-coding-agent");
|
||||
const entries = [
|
||||
{type: "message", id: "old", parentId: null, message: {role: "user", content: "old context"}},
|
||||
{type: "message", id: "keep", parentId: "old", message: {role: "user", content: "retained tail"}},
|
||||
{type: "compaction", id: "compact", parentId: "keep", summary: "Native summary", firstKeptEntryId: "keep", tokensBefore: 100},
|
||||
{type: "message", id: "new", parentId: "compact", message: {role: "user", content: "Continue this task"}},
|
||||
{type: "message", id: "other", parentId: "old", message: {role: "user", content: "abandoned branch"}},
|
||||
];
|
||||
const context = buildSessionContext(entries as Parameters<typeof buildSessionContext>[0], "new");
|
||||
const messages = JSON.stringify(convertToLlm(context.messages));
|
||||
expect(messages).toContain("Native summary");
|
||||
expect(messages).toContain("retained tail");
|
||||
expect(messages).toContain("Continue this task");
|
||||
expect(messages).not.toContain("old context");
|
||||
expect(messages).not.toContain("abandoned branch");
|
||||
});
|
||||
@@ -1,10 +1,18 @@
|
||||
import {afterEach, beforeEach, describe, expect, it, vi} from "vitest";
|
||||
import mem0Extension from "./entry.ts";
|
||||
import {buildSessionContext, convertToLlm} from "@earendil-works/pi-coding-agent";
|
||||
import {runHandoff} from "../../agent-plugin-core/typescript/src/handoff.ts";
|
||||
vi.mock("../../agent-plugin-core/typescript/src/handoff.ts", async (original) => ({...await original<typeof import("../../agent-plugin-core/typescript/src/handoff.ts")>(), runHandoff: vi.fn()}));
|
||||
vi.mock("@earendil-works/pi-coding-agent", () => ({
|
||||
buildSessionContext: vi.fn(() => ({messages: [{role: "user", content: "Native summary and retained tail"}]})),
|
||||
convertToLlm: vi.fn(messages => messages),
|
||||
}));
|
||||
vi.mock("./config/index.ts", () => ({loadConfig: () => ({apiKey: ""}), CONFIG_DIR: "/tmp/mem0-pi-handoff-tests"}));
|
||||
beforeEach(() => { vi.clearAllMocks(); });
|
||||
afterEach(() => vi.restoreAllMocks());
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
vi.stubGlobal("process", {...process, versions: {...process.versions, node: "22.19.0"}});
|
||||
});
|
||||
afterEach(() => { vi.restoreAllMocks(); vi.unstubAllGlobals(); });
|
||||
function setup() {
|
||||
const commands = new Map<string, any>();
|
||||
const pi = {registerCommand: vi.fn((name, command) => commands.set(name, command)), sendMessage: vi.fn()};
|
||||
@@ -23,10 +31,20 @@ function setup() {
|
||||
return {pi, ctx, handler: commands.get("mem0-handoff").handler};
|
||||
}
|
||||
describe("native Pi handoff", () => {
|
||||
it("keeps startup working on Node 20 and explains the native handoff runtime requirement", async () => {
|
||||
vi.stubGlobal("process", {...process, versions: {...process.versions, node: "20.20.2"}});
|
||||
const {ctx, handler} = setup();
|
||||
await handler("codex", ctx);
|
||||
expect(ctx.ui.notify).toHaveBeenCalledWith(expect.stringContaining("Node.js 22.19+"), "error");
|
||||
expect(buildSessionContext).not.toHaveBeenCalled();
|
||||
expect(runHandoff).not.toHaveBeenCalled();
|
||||
});
|
||||
it("uses host compaction/branch selection and the current session without a Mem0 key", async () => {
|
||||
const {pi, ctx, handler} = setup();
|
||||
vi.mocked(runHandoff).mockResolvedValue("Created Codex task");
|
||||
await handler("codex", ctx);
|
||||
expect(buildSessionContext).toHaveBeenCalledWith(ctx.sessionManager.getEntries(), "new");
|
||||
expect(convertToLlm).toHaveBeenCalledOnce();
|
||||
const bundle = vi.mocked(runHandoff).mock.calls[0][1];
|
||||
expect(bundle.source).toMatchObject({host: "pi-agent", session_id: "pi-native", title: "My Pi task"});
|
||||
expect(JSON.stringify(bundle.items)).toContain("Native summary");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { buildSessionContext, convertToLlm, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||
import { buildHandoffBundle, runHandoff } from "../../agent-plugin-core/typescript/src/handoff.ts";
|
||||
|
||||
export function registerHandoffCommand(pi: ExtensionAPI): void {
|
||||
@@ -11,6 +11,11 @@ export function registerHandoffCommand(pi: ExtensionAPI): void {
|
||||
}
|
||||
try {
|
||||
if (!ctx.isIdle()) throw new Error("Finish the current response before handing off this session.");
|
||||
const [major, minor] = process.versions.node.split(".").map(Number);
|
||||
if (major < 22 || (major === 22 && minor < 19)) {
|
||||
throw new Error("Pi session handoff requires Node.js 22.19+ (the native Pi SDK requirement). Memory features remain available.");
|
||||
}
|
||||
const { buildSessionContext, convertToLlm } = await import("@earendil-works/pi-coding-agent");
|
||||
const session = ctx.sessionManager;
|
||||
const context = buildSessionContext(session.getEntries(), session.getLeafId());
|
||||
const bundle = await buildHandoffBundle({
|
||||
|
||||
Reference in New Issue
Block a user