import type { ProviderReplaySessionEntry, ProviderSanitizeReplayHistoryContext, } from "openclaw/plugin-sdk/plugin-entry"; import { describe, expect, it } from "vitest"; import { registerProviderPlugin, requireRegisteredProvider, } from "../../test/helpers/plugins/provider-registration.js"; import googlePlugin from "./index.js"; describe("google provider plugin hooks", () => { it("owns replay policy and reasoning mode for the direct Gemini provider", async () => { const { providers } = await registerProviderPlugin({ plugin: googlePlugin, id: "google", name: "Google Provider", }); const provider = requireRegisteredProvider(providers, "google"); const customEntries: ProviderReplaySessionEntry[] = []; expect( provider.buildReplayPolicy?.({ provider: "google", modelApi: "google-generative-ai", modelId: "gemini-3.1-pro-preview", } as never), ).toEqual({ sanitizeMode: "full", sanitizeToolCallIds: true, toolCallIdMode: "strict", sanitizeThoughtSignatures: { allowBase64Only: true, includeCamelCase: true, }, repairToolUseResultPairing: true, applyAssistantFirstOrderingFix: true, validateGeminiTurns: true, validateAnthropicTurns: false, allowSyntheticToolResults: true, }); expect( provider.resolveReasoningOutputMode?.({ provider: "google", modelApi: "google-generative-ai", modelId: "gemini-3.1-pro-preview", } as never), ).toBe("tagged"); const sanitized = await Promise.resolve( provider.sanitizeReplayHistory?.({ provider: "google", modelApi: "google-generative-ai", modelId: "gemini-3.1-pro-preview", sessionId: "session-1", messages: [ { role: "assistant", content: [{ type: "text", text: "hello" }], }, ], sessionState: { getCustomEntries: () => customEntries, appendCustomEntry: (customType: string, data: unknown) => { customEntries.push({ customType, data }); }, }, } as ProviderSanitizeReplayHistoryContext), ); expect(sanitized).toEqual( expect.arrayContaining([ expect.objectContaining({ role: "user", content: "(session bootstrap)", }), ]), ); expect(customEntries).toHaveLength(1); expect(customEntries[0]?.customType).toBe("google-turn-ordering-bootstrap"); }); it("owns Gemini CLI tool schema normalization", async () => { const { providers } = await registerProviderPlugin({ plugin: googlePlugin, id: "google", name: "Google Provider", }); const provider = requireRegisteredProvider(providers, "google-gemini-cli"); const [tool] = provider.normalizeToolSchemas?.({ provider: "google-gemini-cli", tools: [ { name: "write_file", description: "Write a file", parameters: { type: "object", additionalProperties: false, properties: { path: { type: "string", pattern: "^src/" }, }, }, }, ], } as never) ?? []; expect(tool).toMatchObject({ name: "write_file", parameters: { type: "object", properties: { path: { type: "string" }, }, }, }); expect(tool?.parameters).not.toHaveProperty("additionalProperties"); expect( (tool?.parameters as { properties?: { path?: Record } })?.properties?.path, ).not.toHaveProperty("pattern"); expect( provider.inspectToolSchemas?.({ provider: "google-gemini-cli", tools: [tool], } as never), ).toEqual([]); }); });