openclaw/extensions/google/google-shared.ensures-funct...

87 lines
2.7 KiB
TypeScript

import type { Context } from "@mariozechner/pi-ai";
import { describe, expect, it } from "vitest";
import { convertMessages } from "../../node_modules/@mariozechner/pi-ai/dist/providers/google-shared.js";
import {
asRecord,
expectConvertedRoles,
makeGeminiCliAssistantMessage,
makeGeminiCliModel,
makeGoogleAssistantMessage,
makeModel,
} from "./google-shared.test-helpers.js";
describe("google-shared convertTools", () => {
it("ensures function call comes after user turn, not after model turn", () => {
const model = makeModel("gemini-1.5-pro");
const context = {
messages: [
{
role: "user",
content: "Hello",
},
makeGoogleAssistantMessage(model.id, [{ type: "text", text: "Hi!" }]),
makeGoogleAssistantMessage(model.id, [
{
type: "toolCall",
id: "call_1",
name: "myTool",
arguments: {},
},
]),
],
} as unknown as Context;
const contents = convertMessages(model, context);
expectConvertedRoles(contents, ["user", "model", "model"]);
const toolCallPart = contents[2].parts?.find(
(part) => typeof part === "object" && part !== null && "functionCall" in part,
);
const toolCall = asRecord(toolCallPart);
expect(toolCall.functionCall).toBeTruthy();
});
it("strips tool call and response ids for google-gemini-cli", () => {
const model = makeGeminiCliModel("gemini-3-flash");
const context = {
messages: [
{
role: "user",
content: "Use a tool",
},
makeGeminiCliAssistantMessage(model.id, [
{
type: "toolCall",
id: "call_1",
name: "myTool",
arguments: { arg: "value" },
thoughtSignature: "dGVzdA==",
},
]),
{
role: "toolResult",
toolCallId: "call_1",
toolName: "myTool",
content: [{ type: "text", text: "Tool result" }],
isError: false,
timestamp: 0,
},
],
} as unknown as Context;
const contents = convertMessages(model, context);
const parts = contents.flatMap((content) => content.parts ?? []);
const toolCallPart = parts.find(
(part) => typeof part === "object" && part !== null && "functionCall" in part,
);
const toolResponsePart = parts.find(
(part) => typeof part === "object" && part !== null && "functionResponse" in part,
);
const toolCall = asRecord(toolCallPart);
const toolResponse = asRecord(toolResponsePart);
expect(asRecord(toolCall.functionCall).id).toBeUndefined();
expect(asRecord(toolResponse.functionResponse).id).toBeUndefined();
});
});