mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 02:10:21 +00:00
test(providers): cover stream family plugin hooks
This commit is contained in:
@@ -2,6 +2,8 @@ import type {
|
||||
ProviderReplaySessionEntry,
|
||||
ProviderSanitizeReplayHistoryContext,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import type { Context, Model } from "@mariozechner/pi-ai";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
registerProviderPlugin,
|
||||
@@ -127,4 +129,55 @@ describe("google provider plugin hooks", () => {
|
||||
} as never),
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it("wires google-thinking stream hooks for direct and Gemini CLI providers", async () => {
|
||||
const { providers } = await registerProviderPlugin({
|
||||
plugin: googlePlugin,
|
||||
id: "google",
|
||||
name: "Google Provider",
|
||||
});
|
||||
const googleProvider = requireRegisteredProvider(providers, "google");
|
||||
const cliProvider = requireRegisteredProvider(providers, "google-gemini-cli");
|
||||
let capturedPayload: Record<string, unknown> | undefined;
|
||||
|
||||
const baseStreamFn: StreamFn = (model, _context, options) => {
|
||||
const payload = { config: { thinkingConfig: { thinkingBudget: -1 } } } as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
options?.onPayload?.(payload as never, model as never);
|
||||
capturedPayload = payload;
|
||||
return {} as never;
|
||||
};
|
||||
|
||||
const runCase = (provider: typeof googleProvider, providerId: string) => {
|
||||
const wrapped = provider.wrapStreamFn?.({
|
||||
provider: providerId,
|
||||
modelId: "gemini-3.1-pro-preview",
|
||||
thinkingLevel: "high",
|
||||
streamFn: baseStreamFn,
|
||||
} as never);
|
||||
|
||||
void wrapped?.(
|
||||
{
|
||||
api: "google-generative-ai",
|
||||
provider: providerId,
|
||||
id: "gemini-3.1-pro-preview",
|
||||
} as Model<"google-generative-ai">,
|
||||
{ messages: [] } as Context,
|
||||
{},
|
||||
);
|
||||
|
||||
expect(capturedPayload).toMatchObject({
|
||||
config: { thinkingConfig: { thinkingLevel: "HIGH" } },
|
||||
});
|
||||
const thinkingConfig = (
|
||||
(capturedPayload as Record<string, unknown>).config as Record<string, unknown>
|
||||
).thinkingConfig as Record<string, unknown>;
|
||||
expect(thinkingConfig).not.toHaveProperty("thinkingBudget");
|
||||
};
|
||||
|
||||
runCase(googleProvider, "google");
|
||||
runCase(cliProvider, "google-gemini-cli");
|
||||
});
|
||||
});
|
||||
|
||||
81
extensions/kilocode/index.test.ts
Normal file
81
extensions/kilocode/index.test.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import type { Context, Model } from "@mariozechner/pi-ai";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { registerSingleProviderPlugin } from "../../test/helpers/plugins/plugin-registration.js";
|
||||
import plugin from "./index.js";
|
||||
|
||||
describe("kilocode provider plugin", () => {
|
||||
it("owns passthrough-gemini replay policy for Gemini-backed models", async () => {
|
||||
const provider = await registerSingleProviderPlugin(plugin);
|
||||
|
||||
expect(
|
||||
provider.buildReplayPolicy?.({
|
||||
provider: "kilocode",
|
||||
modelApi: "openai-completions",
|
||||
modelId: "gemini-2.5-pro",
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
applyAssistantFirstOrderingFix: false,
|
||||
validateGeminiTurns: false,
|
||||
validateAnthropicTurns: false,
|
||||
sanitizeThoughtSignatures: {
|
||||
allowBase64Only: true,
|
||||
includeCamelCase: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("wires kilocode-thinking stream hooks", async () => {
|
||||
const provider = await registerSingleProviderPlugin(plugin);
|
||||
let capturedPayload: Record<string, unknown> | undefined;
|
||||
const baseStreamFn: StreamFn = (model, _context, options) => {
|
||||
const payload = { config: { thinkingConfig: { thinkingBudget: -1 } } } as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
options?.onPayload?.(payload as never, model as never);
|
||||
capturedPayload = payload;
|
||||
return {} as never;
|
||||
};
|
||||
|
||||
const wrappedReasoning = provider.wrapStreamFn?.({
|
||||
provider: "kilocode",
|
||||
modelId: "openai/gpt-5.4",
|
||||
thinkingLevel: "high",
|
||||
streamFn: baseStreamFn,
|
||||
} as never);
|
||||
|
||||
void wrappedReasoning?.(
|
||||
{
|
||||
api: "openai-completions",
|
||||
provider: "kilocode",
|
||||
id: "openai/gpt-5.4",
|
||||
} as Model<"openai-completions">,
|
||||
{ messages: [] } as Context,
|
||||
{},
|
||||
);
|
||||
|
||||
expect(capturedPayload).toMatchObject({
|
||||
reasoning: { effort: "high" },
|
||||
});
|
||||
|
||||
const wrappedAuto = provider.wrapStreamFn?.({
|
||||
provider: "kilocode",
|
||||
modelId: "kilo/auto",
|
||||
thinkingLevel: "high",
|
||||
streamFn: baseStreamFn,
|
||||
} as never);
|
||||
|
||||
void wrappedAuto?.(
|
||||
{
|
||||
api: "openai-completions",
|
||||
provider: "kilocode",
|
||||
id: "kilo/auto",
|
||||
} as Model<"openai-completions">,
|
||||
{ messages: [] } as Context,
|
||||
{},
|
||||
);
|
||||
|
||||
expect(capturedPayload).not.toHaveProperty("reasoning");
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import type { Context, Model } from "@mariozechner/pi-ai";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { registerSingleProviderPlugin } from "../../test/helpers/plugins/plugin-registration.js";
|
||||
import plugin from "./index.js";
|
||||
@@ -20,4 +22,40 @@ describe("moonshot provider plugin", () => {
|
||||
validateAnthropicTurns: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("wires moonshot-thinking stream hooks", async () => {
|
||||
const provider = await registerSingleProviderPlugin(plugin);
|
||||
let capturedPayload: Record<string, unknown> | undefined;
|
||||
const baseStreamFn: StreamFn = (model, _context, options) => {
|
||||
const payload = { config: { thinkingConfig: { thinkingBudget: -1 } } } as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
options?.onPayload?.(payload as never, model as never);
|
||||
capturedPayload = payload;
|
||||
return {} as never;
|
||||
};
|
||||
|
||||
const wrapped = provider.wrapStreamFn?.({
|
||||
provider: "moonshot",
|
||||
modelId: "kimi-k2.5",
|
||||
thinkingLevel: "off",
|
||||
streamFn: baseStreamFn,
|
||||
} as never);
|
||||
|
||||
void wrapped?.(
|
||||
{
|
||||
api: "openai-completions",
|
||||
provider: "moonshot",
|
||||
id: "kimi-k2.5",
|
||||
} as Model<"openai-completions">,
|
||||
{ messages: [] } as Context,
|
||||
{},
|
||||
);
|
||||
|
||||
expect(capturedPayload).toMatchObject({
|
||||
config: { thinkingConfig: { thinkingBudget: -1 } },
|
||||
thinking: { type: "disabled" },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user