mirror of
https://github.com/harivansh-afk/clanker-agent.git
synced 2026-04-15 17:00:58 +00:00
- Copy all pi-mono source into apps/companion-os/ - Update Dockerfile to COPY pre-built binary instead of downloading from GitHub Releases - Update deploy-staging.yml to build pi from source (bun compile) before Docker build - Add apps/companion-os/** to path triggers - No more cross-repo dispatch needed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
import { Type } from "@sinclair/typebox";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { streamGoogleGeminiCli } from "../src/providers/google-gemini-cli.js";
|
|
import type { Context, Model, ToolCall } from "../src/types.js";
|
|
|
|
const emptySchema = Type.Object({});
|
|
|
|
const originalFetch = global.fetch;
|
|
|
|
afterEach(() => {
|
|
global.fetch = originalFetch;
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe("google providers tool call missing args", () => {
|
|
it("defaults arguments to empty object when provider omits args field", async () => {
|
|
// Simulate a tool call response where args is missing (no-arg tool)
|
|
const sse = `${[
|
|
`data: ${JSON.stringify({
|
|
response: {
|
|
candidates: [
|
|
{
|
|
content: {
|
|
role: "model",
|
|
parts: [
|
|
{
|
|
functionCall: {
|
|
name: "get_status",
|
|
// args intentionally omitted
|
|
},
|
|
},
|
|
],
|
|
},
|
|
finishReason: "STOP",
|
|
},
|
|
],
|
|
usageMetadata: {
|
|
promptTokenCount: 10,
|
|
candidatesTokenCount: 5,
|
|
totalTokenCount: 15,
|
|
},
|
|
},
|
|
})}`,
|
|
].join("\n\n")}\n\n`;
|
|
|
|
const encoder = new TextEncoder();
|
|
const dataStream = new ReadableStream<Uint8Array>({
|
|
start(controller) {
|
|
controller.enqueue(encoder.encode(sse));
|
|
controller.close();
|
|
},
|
|
});
|
|
|
|
const fetchMock = vi.fn(async () => {
|
|
return new Response(dataStream, {
|
|
status: 200,
|
|
headers: { "content-type": "text/event-stream" },
|
|
});
|
|
});
|
|
|
|
global.fetch = fetchMock as typeof fetch;
|
|
|
|
const model: Model<"google-gemini-cli"> = {
|
|
id: "gemini-2.5-flash",
|
|
name: "Gemini 2.5 Flash",
|
|
api: "google-gemini-cli",
|
|
provider: "google-gemini-cli",
|
|
baseUrl: "https://cloudcode-pa.googleapis.com",
|
|
reasoning: false,
|
|
input: ["text"],
|
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
contextWindow: 128000,
|
|
maxTokens: 8192,
|
|
};
|
|
|
|
const context: Context = {
|
|
messages: [
|
|
{ role: "user", content: "Check status", timestamp: Date.now() },
|
|
],
|
|
tools: [
|
|
{
|
|
name: "get_status",
|
|
description: "Get current status",
|
|
parameters: emptySchema,
|
|
},
|
|
],
|
|
};
|
|
|
|
const stream = streamGoogleGeminiCli(model, context, {
|
|
apiKey: JSON.stringify({ token: "token", projectId: "project" }),
|
|
});
|
|
|
|
for await (const _ of stream) {
|
|
// consume stream
|
|
}
|
|
|
|
const result = await stream.result();
|
|
|
|
expect(result.stopReason).toBe("toolUse");
|
|
expect(result.content).toHaveLength(1);
|
|
|
|
const toolCall = result.content[0] as ToolCall;
|
|
expect(toolCall.type).toBe("toolCall");
|
|
expect(toolCall.name).toBe("get_status");
|
|
expect(toolCall.arguments).toEqual({});
|
|
});
|
|
});
|