mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 07:23:06 +00:00
68 lines
2.9 KiB
TypeScript
68 lines
2.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { chmod, mkdir, mkdtemp, readFile, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import test from "node:test";
|
|
|
|
import hippoExtension from "../hippo-memory-pi/index.ts";
|
|
|
|
test("official Hippo extension registers five tools and runs lifecycle CLI calls", async () => {
|
|
const root = await mkdtemp(join(tmpdir(), "my-pi-hippo-extension-"));
|
|
const bin = join(root, "bin");
|
|
const project = join(root, "project");
|
|
const log = join(root, "hippo.log");
|
|
await mkdir(bin, { recursive: true });
|
|
await mkdir(join(project, ".hippo"), { recursive: true });
|
|
const hippo = join(bin, "hippo");
|
|
await writeFile(
|
|
hippo,
|
|
`#!/bin/sh\nprintf '%s\\n' "$*" >> "$HIPPO_TEST_LOG"\ncase "$1" in\n status) printf '%s\\n' 'Hippo status ok' ;;\n context) printf '%s\\n' 'Remembered project context for testing' ;;\n recall) printf '%s\\n' 'Relevant project memory' ;;\n remember) printf '%s\\n' 'Remembered [test]' ;;\n outcome) printf '%s\\n' 'Outcome recorded' ;;\n sleep) printf '%s\\n' 'Sleep complete' ;;\nesac\n`,
|
|
"utf8",
|
|
);
|
|
await chmod(hippo, 0o755);
|
|
|
|
const previousPath = process.env.PATH;
|
|
const previousLog = process.env.HIPPO_TEST_LOG;
|
|
process.env.PATH = `${bin}:${previousPath ?? ""}`;
|
|
process.env.HIPPO_TEST_LOG = log;
|
|
try {
|
|
const handlers = new Map<string, Array<(event: any, ctx: any) => Promise<any>>>();
|
|
const tools = new Map<string, any>();
|
|
hippoExtension({
|
|
on(name: string, handler: (event: any, ctx: any) => Promise<any>) {
|
|
const entries = handlers.get(name) ?? [];
|
|
entries.push(handler);
|
|
handlers.set(name, entries);
|
|
},
|
|
registerTool(tool: any) {
|
|
tools.set(tool.name, tool);
|
|
},
|
|
});
|
|
|
|
assert.deepEqual(
|
|
[...tools.keys()].sort(),
|
|
["hippo_context", "hippo_outcome", "hippo_recall", "hippo_remember", "hippo_status"],
|
|
);
|
|
const ctx = { cwd: project };
|
|
const startResult = await handlers.get("session_start")?.[0]?.({}, ctx);
|
|
assert.match(startResult.systemPromptAppend, /Remembered project context/);
|
|
const rememberResult = await tools.get("hippo_remember").execute("call-1", { text: "A durable lesson" }, undefined, undefined, ctx);
|
|
assert.match(rememberResult.content[0].text, /Remembered \[test\]/);
|
|
await handlers.get("tool_result")?.[0]?.(
|
|
{ isError: true, toolName: "build", content: "Compilation failed because the generated symbol was missing" },
|
|
ctx,
|
|
);
|
|
await handlers.get("session_shutdown")?.[0]?.({}, ctx);
|
|
|
|
const calls = await readFile(log, "utf8");
|
|
assert.match(calls, /context --auto/);
|
|
assert.match(calls, /remember A durable lesson/);
|
|
assert.match(calls, /remember Tool 'build' failed:/);
|
|
assert.match(calls, /sleep/);
|
|
} finally {
|
|
process.env.PATH = previousPath;
|
|
if (previousLog === undefined) delete process.env.HIPPO_TEST_LOG;
|
|
else process.env.HIPPO_TEST_LOG = previousLog;
|
|
}
|
|
});
|