mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 17:24:32 +00:00
test(agents): dedupe media and thinking sanitize test setup
This commit is contained in:
@@ -38,6 +38,33 @@ async function sanitizeGoogleAssistantWithContent(content: unknown[]) {
|
|||||||
return getAssistantMessage(out);
|
return getAssistantMessage(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function sanitizeSimpleSession(params: {
|
||||||
|
modelApi: string;
|
||||||
|
sessionId: string;
|
||||||
|
content: unknown[];
|
||||||
|
modelId?: string;
|
||||||
|
}) {
|
||||||
|
const sessionManager = SessionManager.inMemory();
|
||||||
|
const input = [
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: "hi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "assistant",
|
||||||
|
content: params.content,
|
||||||
|
},
|
||||||
|
] as unknown as AgentMessage[];
|
||||||
|
|
||||||
|
return sanitizeSessionHistory({
|
||||||
|
messages: input,
|
||||||
|
modelApi: params.modelApi,
|
||||||
|
modelId: params.modelId,
|
||||||
|
sessionManager,
|
||||||
|
sessionId: params.sessionId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("sanitizeSessionHistory (google thinking)", () => {
|
describe("sanitizeSessionHistory (google thinking)", () => {
|
||||||
it("keeps thinking blocks without signatures for Google models", async () => {
|
it("keeps thinking blocks without signatures for Google models", async () => {
|
||||||
const assistant = await sanitizeGoogleAssistantWithContent([
|
const assistant = await sanitizeGoogleAssistantWithContent([
|
||||||
@@ -65,24 +92,11 @@ describe("sanitizeSessionHistory (google thinking)", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("drops unsigned thinking blocks for Antigravity Claude", async () => {
|
it("drops unsigned thinking blocks for Antigravity Claude", async () => {
|
||||||
const sessionManager = SessionManager.inMemory();
|
const out = await sanitizeSimpleSession({
|
||||||
const input = [
|
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: "hi",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: [{ type: "thinking", thinking: "reasoning" }],
|
|
||||||
},
|
|
||||||
] as unknown as AgentMessage[];
|
|
||||||
|
|
||||||
const out = await sanitizeSessionHistory({
|
|
||||||
messages: input,
|
|
||||||
modelApi: "google-antigravity",
|
modelApi: "google-antigravity",
|
||||||
modelId: "anthropic/claude-3.5-sonnet",
|
modelId: "anthropic/claude-3.5-sonnet",
|
||||||
sessionManager,
|
|
||||||
sessionId: "session:antigravity-claude",
|
sessionId: "session:antigravity-claude",
|
||||||
|
content: [{ type: "thinking", thinking: "reasoning" }],
|
||||||
});
|
});
|
||||||
|
|
||||||
const assistant = out.find((msg) => (msg as { role?: string }).role === "assistant");
|
const assistant = out.find((msg) => (msg as { role?: string }).role === "assistant");
|
||||||
@@ -273,23 +287,10 @@ describe("sanitizeSessionHistory (google thinking)", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("keeps thinking blocks for non-Google models", async () => {
|
it("keeps thinking blocks for non-Google models", async () => {
|
||||||
const sessionManager = SessionManager.inMemory();
|
const out = await sanitizeSimpleSession({
|
||||||
const input = [
|
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: "hi",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: [{ type: "thinking", thinking: "reasoning" }],
|
|
||||||
},
|
|
||||||
] as unknown as AgentMessage[];
|
|
||||||
|
|
||||||
const out = await sanitizeSessionHistory({
|
|
||||||
messages: input,
|
|
||||||
modelApi: "openai",
|
modelApi: "openai",
|
||||||
sessionManager,
|
|
||||||
sessionId: "session:openai",
|
sessionId: "session:openai",
|
||||||
|
content: [{ type: "thinking", thinking: "reasoning" }],
|
||||||
});
|
});
|
||||||
|
|
||||||
const assistant = out.find((msg) => (msg as { role?: string }).role === "assistant") as {
|
const assistant = out.find((msg) => (msg as { role?: string }).role === "assistant") as {
|
||||||
|
|||||||
@@ -59,6 +59,25 @@ function createMockContext(overrides?: {
|
|||||||
} as unknown as EmbeddedPiSubscribeContext;
|
} as unknown as EmbeddedPiSubscribeContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function emitPngMediaToolResult(
|
||||||
|
ctx: EmbeddedPiSubscribeContext,
|
||||||
|
opts?: { isError?: boolean },
|
||||||
|
) {
|
||||||
|
await handleToolExecutionEnd(ctx, {
|
||||||
|
type: "tool_execution_end",
|
||||||
|
toolName: "browser",
|
||||||
|
toolCallId: "tc-1",
|
||||||
|
isError: opts?.isError ?? false,
|
||||||
|
result: {
|
||||||
|
content: [
|
||||||
|
{ type: "text", text: "MEDIA:/tmp/screenshot.png" },
|
||||||
|
{ type: "image", data: "base64", mimeType: "image/png" },
|
||||||
|
],
|
||||||
|
details: { path: "/tmp/screenshot.png" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("handleToolExecutionEnd media emission", () => {
|
describe("handleToolExecutionEnd media emission", () => {
|
||||||
it("does not warn for read tool when path is provided via file_path alias", async () => {
|
it("does not warn for read tool when path is provided via file_path alias", async () => {
|
||||||
const ctx = createMockContext();
|
const ctx = createMockContext();
|
||||||
@@ -77,19 +96,7 @@ describe("handleToolExecutionEnd media emission", () => {
|
|||||||
const onToolResult = vi.fn();
|
const onToolResult = vi.fn();
|
||||||
const ctx = createMockContext({ shouldEmitToolOutput: false, onToolResult });
|
const ctx = createMockContext({ shouldEmitToolOutput: false, onToolResult });
|
||||||
|
|
||||||
await handleToolExecutionEnd(ctx, {
|
await emitPngMediaToolResult(ctx);
|
||||||
type: "tool_execution_end",
|
|
||||||
toolName: "browser",
|
|
||||||
toolCallId: "tc-1",
|
|
||||||
isError: false,
|
|
||||||
result: {
|
|
||||||
content: [
|
|
||||||
{ type: "text", text: "MEDIA:/tmp/screenshot.png" },
|
|
||||||
{ type: "image", data: "base64", mimeType: "image/png" },
|
|
||||||
],
|
|
||||||
details: { path: "/tmp/screenshot.png" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(onToolResult).toHaveBeenCalledWith({
|
expect(onToolResult).toHaveBeenCalledWith({
|
||||||
mediaUrls: ["/tmp/screenshot.png"],
|
mediaUrls: ["/tmp/screenshot.png"],
|
||||||
@@ -100,19 +107,7 @@ describe("handleToolExecutionEnd media emission", () => {
|
|||||||
const onToolResult = vi.fn();
|
const onToolResult = vi.fn();
|
||||||
const ctx = createMockContext({ shouldEmitToolOutput: true, onToolResult });
|
const ctx = createMockContext({ shouldEmitToolOutput: true, onToolResult });
|
||||||
|
|
||||||
await handleToolExecutionEnd(ctx, {
|
await emitPngMediaToolResult(ctx);
|
||||||
type: "tool_execution_end",
|
|
||||||
toolName: "browser",
|
|
||||||
toolCallId: "tc-1",
|
|
||||||
isError: false,
|
|
||||||
result: {
|
|
||||||
content: [
|
|
||||||
{ type: "text", text: "MEDIA:/tmp/screenshot.png" },
|
|
||||||
{ type: "image", data: "base64", mimeType: "image/png" },
|
|
||||||
],
|
|
||||||
details: { path: "/tmp/screenshot.png" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// onToolResult should NOT be called by the new media path (emitToolOutput handles it).
|
// onToolResult should NOT be called by the new media path (emitToolOutput handles it).
|
||||||
// It may be called by emitToolOutput, but the new block should not fire.
|
// It may be called by emitToolOutput, but the new block should not fire.
|
||||||
@@ -133,19 +128,7 @@ describe("handleToolExecutionEnd media emission", () => {
|
|||||||
const onToolResult = vi.fn();
|
const onToolResult = vi.fn();
|
||||||
const ctx = createMockContext({ shouldEmitToolOutput: false, onToolResult });
|
const ctx = createMockContext({ shouldEmitToolOutput: false, onToolResult });
|
||||||
|
|
||||||
await handleToolExecutionEnd(ctx, {
|
await emitPngMediaToolResult(ctx, { isError: true });
|
||||||
type: "tool_execution_end",
|
|
||||||
toolName: "browser",
|
|
||||||
toolCallId: "tc-1",
|
|
||||||
isError: true,
|
|
||||||
result: {
|
|
||||||
content: [
|
|
||||||
{ type: "text", text: "MEDIA:/tmp/screenshot.png" },
|
|
||||||
{ type: "image", data: "base64", mimeType: "image/png" },
|
|
||||||
],
|
|
||||||
details: { path: "/tmp/screenshot.png" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(onToolResult).not.toHaveBeenCalled();
|
expect(onToolResult).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user