openclaw/extensions/openai/index.test.ts

106 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { ProviderPlugin } from "../../src/plugins/types.js";
import openAIPlugin from "./index.js";
function registerProviders(): ProviderPlugin[] {
const providers: ProviderPlugin[] = [];
openAIPlugin.register({
registerProvider(nextProvider: ProviderPlugin) {
providers.push(nextProvider);
},
} as never);
return providers;
}
function requireProvider(id: string): ProviderPlugin {
const provider = registerProviders().find((entry) => entry.id === id);
if (!provider) {
throw new Error(`provider registration missing for ${id}`);
}
return provider;
}
describe("openai plugin", () => {
it("registers openai and openai-codex providers from one extension", () => {
expect(registerProviders().map((provider) => provider.id)).toEqual(["openai", "openai-codex"]);
});
it("owns openai gpt-5.4 forward-compat resolution", () => {
const provider = requireProvider("openai");
const model = provider.resolveDynamicModel?.({
provider: "openai",
modelId: "gpt-5.4-pro",
modelRegistry: {
find: (_provider: string, id: string) =>
id === "gpt-5.2-pro"
? {
id,
name: id,
api: "openai-responses",
provider: "openai",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 200_000,
maxTokens: 8_192,
}
: null,
} as never,
});
expect(model).toMatchObject({
id: "gpt-5.4-pro",
provider: "openai",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
contextWindow: 1_050_000,
maxTokens: 128_000,
});
});
it("owns direct openai transport normalization", () => {
const provider = requireProvider("openai");
expect(
provider.normalizeResolvedModel?.({
provider: "openai",
modelId: "gpt-5.4",
model: {
id: "gpt-5.4",
name: "gpt-5.4",
api: "openai-completions",
provider: "openai",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 1_050_000,
maxTokens: 128_000,
},
}),
).toMatchObject({
api: "openai-responses",
});
});
it("owns codex-only missing-auth hints and Spark suppression", () => {
const provider = requireProvider("openai");
expect(
provider.buildMissingAuthMessage?.({
env: {} as NodeJS.ProcessEnv,
provider: "openai",
listProfileIds: (providerId) => (providerId === "openai-codex" ? ["p1"] : []),
}),
).toContain("openai-codex/gpt-5.4");
expect(
provider.suppressBuiltInModel?.({
env: {} as NodeJS.ProcessEnv,
provider: "azure-openai-responses",
modelId: "gpt-5.3-codex-spark",
}),
).toMatchObject({
suppress: true,
});
});
});