test: share pi embedded helper setup

This commit is contained in:
Peter Steinberger
2026-04-19 04:31:01 +01:00
parent efda761724
commit 2a35ea4f07
2 changed files with 50 additions and 52 deletions

View File

@@ -121,6 +121,26 @@ async function emitMcpMediaToolResult(ctx: EmbeddedPiSubscribeContext, mediaPath
});
}
async function handleCaseVariantBuiltinMedia(mediaPathOrUrl: string) {
const ctx = createMockContext({
shouldEmitToolOutput: false,
onToolResult: vi.fn(),
builtinToolNames: new Set(["web_search"]),
});
await handleToolExecutionEnd(ctx, {
type: "tool_execution_end",
toolName: "Web_Search",
toolCallId: "tc-1",
isError: false,
result: {
content: [{ type: "text", text: `MEDIA:${mediaPathOrUrl}` }],
},
});
return ctx;
}
describe("handleToolExecutionEnd media emission", () => {
it("does not warn for read tool when path is provided via file_path alias", async () => {
const ctx = createMockContext();
@@ -176,41 +196,13 @@ describe("handleToolExecutionEnd media emission", () => {
});
it("does NOT emit local media for case-variant collisions with trusted built-ins", async () => {
const ctx = createMockContext({
shouldEmitToolOutput: false,
onToolResult: vi.fn(),
builtinToolNames: new Set(["web_search"]),
});
await handleToolExecutionEnd(ctx, {
type: "tool_execution_end",
toolName: "Web_Search",
toolCallId: "tc-1",
isError: false,
result: {
content: [{ type: "text", text: "MEDIA:/tmp/secret.png" }],
},
});
const ctx = await handleCaseVariantBuiltinMedia("/tmp/secret.png");
expect(ctx.state.pendingToolMediaUrls).toEqual([]);
});
it("still emits remote media for case-variant collisions with trusted built-ins", async () => {
const ctx = createMockContext({
shouldEmitToolOutput: false,
onToolResult: vi.fn(),
builtinToolNames: new Set(["web_search"]),
});
await handleToolExecutionEnd(ctx, {
type: "tool_execution_end",
toolName: "Web_Search",
toolCallId: "tc-1",
isError: false,
result: {
content: [{ type: "text", text: "MEDIA:https://example.com/file.png" }],
},
});
const ctx = await handleCaseVariantBuiltinMedia("https://example.com/file.png");
expect(ctx.state.pendingToolMediaUrls).toEqual(["https://example.com/file.png"]);
});

View File

@@ -74,6 +74,30 @@ function emitOpenAiResponsesFinalMessageEnd(params: {
});
}
async function emitSuppressedCommentary(params: {
emit: TextEndBlockReplyHarness["emit"];
text: string;
}) {
params.emit({ type: "message_start", message: { role: "assistant" } });
emitOpenAiResponsesTextDeltaAndEnd({
emit: params.emit,
text: params.text,
id: "item_commentary",
phase: "commentary",
});
await Promise.resolve();
}
function expectSingleBlockReplyText(params: {
onBlockReply: ReturnType<typeof vi.fn>;
subscription: TextEndBlockReplyHarness["subscription"];
text: string;
}) {
expect(params.onBlockReply).toHaveBeenCalledTimes(1);
expect(params.onBlockReply.mock.calls[0]?.[0]?.text).toBe(params.text);
expect(params.subscription.assistantTexts).toEqual([params.text]);
}
describe("subscribeEmbeddedPiSession", () => {
it("emits block replies on text_end and does not duplicate on message_end", async () => {
const onBlockReply = vi.fn();
@@ -167,14 +191,7 @@ describe("subscribeEmbeddedPiSession", () => {
const onBlockReply = vi.fn();
const { emit, subscription } = createTextEndBlockReplyHarness({ onBlockReply });
emit({ type: "message_start", message: { role: "assistant" } });
emitOpenAiResponsesTextDeltaAndEnd({
emit,
text: "Working...",
id: "item_commentary",
phase: "commentary",
});
await Promise.resolve();
await emitSuppressedCommentary({ emit, text: "Working..." });
expect(onBlockReply).not.toHaveBeenCalled();
expect(subscription.assistantTexts).toEqual([]);
@@ -189,9 +206,7 @@ describe("subscribeEmbeddedPiSession", () => {
emitOpenAiResponsesFinalMessageEnd({ emit, commentaryText: "Working...", finalText: "Done." });
expect(onBlockReply).toHaveBeenCalledTimes(1);
expect(onBlockReply.mock.calls[0]?.[0]?.text).toBe("Done.");
expect(subscription.assistantTexts).toEqual(["Done."]);
expectSingleBlockReplyText({ onBlockReply, subscription, text: "Done." });
});
it("emits the full final answer on text_end when it extends suppressed commentary", async () => {
@@ -253,19 +268,10 @@ describe("subscribeEmbeddedPiSession", () => {
const onBlockReply = vi.fn();
const { emit, subscription } = createTextEndBlockReplyHarness({ onBlockReply });
emit({ type: "message_start", message: { role: "assistant" } });
emitOpenAiResponsesTextDeltaAndEnd({
emit,
text: "Working...",
id: "item_commentary",
phase: "commentary",
});
await Promise.resolve();
await emitSuppressedCommentary({ emit, text: "Working..." });
emitOpenAiResponsesFinalMessageEnd({ emit, commentaryText: "Working...", finalText: "Done." });
expect(onBlockReply).toHaveBeenCalledTimes(1);
expect(onBlockReply.mock.calls[0]?.[0]?.text).toBe("Done.");
expect(subscription.assistantTexts).toEqual(["Done."]);
expectSingleBlockReplyText({ onBlockReply, subscription, text: "Done." });
});
});