Files
openclaw/extensions/openai/transport-policy.test.ts
2026-04-06 19:57:56 +01:00

130 lines
3.5 KiB
TypeScript

import type { ProviderRuntimeModel } from "openclaw/plugin-sdk/plugin-entry";
import { describe, expect, it } from "vitest";
import {
resolveOpenAITransportTurnState,
resolveOpenAIWebSocketSessionPolicy,
} from "./transport-policy.js";
describe("openai transport policy", () => {
const nativeModel = {
id: "gpt-5.4",
name: "GPT-5.4",
api: "openai-responses",
provider: "openai",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 200000,
maxTokens: 8192,
} satisfies ProviderRuntimeModel;
const proxyModel = {
...nativeModel,
id: "proxy-model",
name: "Proxy Model",
baseUrl: "https://proxy.example.com/v1",
} satisfies ProviderRuntimeModel;
it("builds native turn state for direct OpenAI routes", () => {
expect(
resolveOpenAITransportTurnState({
provider: "openai",
modelId: nativeModel.id,
model: nativeModel,
sessionId: "session-123",
turnId: "turn-123",
attempt: 2,
transport: "websocket",
}),
).toMatchObject({
headers: {
"x-client-request-id": "session-123",
"x-openclaw-session-id": "session-123",
"x-openclaw-turn-id": "turn-123",
"x-openclaw-turn-attempt": "2",
},
metadata: {
openclaw_session_id: "session-123",
openclaw_turn_id: "turn-123",
openclaw_turn_attempt: "2",
openclaw_transport: "websocket",
},
});
});
it("skips turn state for proxy-like OpenAI routes", () => {
expect(
resolveOpenAITransportTurnState({
provider: "openai",
modelId: proxyModel.id,
model: proxyModel,
sessionId: "session-123",
turnId: "turn-123",
attempt: 1,
transport: "stream",
}),
).toBeUndefined();
});
it("returns websocket session headers and cooldown for native routes", () => {
expect(
resolveOpenAIWebSocketSessionPolicy({
provider: "openai",
modelId: nativeModel.id,
model: nativeModel,
sessionId: "session-123",
}),
).toMatchObject({
headers: {
"x-client-request-id": "session-123",
"x-openclaw-session-id": "session-123",
},
degradeCooldownMs: 60_000,
});
});
it("treats Azure routes as native OpenAI-family transports", () => {
expect(
resolveOpenAIWebSocketSessionPolicy({
provider: "azure-openai-responses",
modelId: "gpt-5.4",
model: {
...nativeModel,
provider: "azure-openai-responses",
baseUrl: "https://demo.openai.azure.com/openai/v1",
},
sessionId: "session-123",
}),
).toMatchObject({
headers: {
"x-client-request-id": "session-123",
"x-openclaw-session-id": "session-123",
},
degradeCooldownMs: 60_000,
});
});
it("treats ChatGPT Codex backend routes as native OpenAI-family transports", () => {
expect(
resolveOpenAIWebSocketSessionPolicy({
provider: "openai-codex",
modelId: "gpt-5.4",
model: {
...nativeModel,
provider: "openai-codex",
api: "openai-codex-responses",
baseUrl: "https://chatgpt.com/backend-api",
},
sessionId: "session-123",
}),
).toMatchObject({
headers: {
"x-client-request-id": "session-123",
"x-openclaw-session-id": "session-123",
},
degradeCooldownMs: 60_000,
});
});
});