mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-19 04:04:45 +00:00
test: clear provider attribution broad matchers
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
function expectRecordFields(record: unknown, expected: Record<string, unknown>) {
|
||||
expect(record).toBeDefined();
|
||||
const actual = record as Record<string, unknown>;
|
||||
for (const [key, value] of Object.entries(expected)) {
|
||||
expect(actual[key]).toEqual(value);
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
|
||||
const providerEndpointPlugins = vi.hoisted(() => [
|
||||
{
|
||||
providerEndpoints: [
|
||||
@@ -198,7 +207,7 @@ describe("provider attribution", () => {
|
||||
});
|
||||
|
||||
it("authorizes hidden OpenAI attribution only on verified native hosts", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy(
|
||||
{
|
||||
provider: "openai",
|
||||
@@ -209,16 +218,17 @@ describe("provider attribution", () => {
|
||||
},
|
||||
{ OPENCLAW_VERSION: "2026.3.22" },
|
||||
),
|
||||
).toMatchObject({
|
||||
endpointClass: "openai-public",
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
usesKnownNativeOpenAIEndpoint: true,
|
||||
usesVerifiedOpenAIAttributionHost: true,
|
||||
usesExplicitProxyLikeEndpoint: false,
|
||||
});
|
||||
{
|
||||
endpointClass: "openai-public",
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
usesKnownNativeOpenAIEndpoint: true,
|
||||
usesVerifiedOpenAIAttributionHost: true,
|
||||
usesExplicitProxyLikeEndpoint: false,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy(
|
||||
{
|
||||
provider: "openai",
|
||||
@@ -229,32 +239,34 @@ describe("provider attribution", () => {
|
||||
},
|
||||
{ OPENCLAW_VERSION: "2026.3.22" },
|
||||
),
|
||||
).toMatchObject({
|
||||
endpointClass: "custom",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
usesKnownNativeOpenAIEndpoint: false,
|
||||
usesVerifiedOpenAIAttributionHost: false,
|
||||
usesExplicitProxyLikeEndpoint: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "custom",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
usesKnownNativeOpenAIEndpoint: false,
|
||||
usesVerifiedOpenAIAttributionHost: false,
|
||||
usesExplicitProxyLikeEndpoint: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("classifies OpenAI-family default, codex, and Azure routes distinctly", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openai",
|
||||
api: "openai-responses",
|
||||
transport: "stream",
|
||||
capability: "llm",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "default",
|
||||
attributionProvider: undefined,
|
||||
usesKnownNativeOpenAIRoute: true,
|
||||
usesExplicitProxyLikeEndpoint: false,
|
||||
});
|
||||
{
|
||||
endpointClass: "default",
|
||||
attributionProvider: undefined,
|
||||
usesKnownNativeOpenAIRoute: true,
|
||||
usesExplicitProxyLikeEndpoint: false,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openai-codex",
|
||||
api: "openai-responses",
|
||||
@@ -262,13 +274,14 @@ describe("provider attribution", () => {
|
||||
transport: "stream",
|
||||
capability: "llm",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "openai-codex",
|
||||
attributionProvider: "openai-codex",
|
||||
allowsHiddenAttribution: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "openai-codex",
|
||||
attributionProvider: "openai-codex",
|
||||
allowsHiddenAttribution: true,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "azure-openai",
|
||||
api: "azure-openai-responses",
|
||||
@@ -276,21 +289,22 @@ describe("provider attribution", () => {
|
||||
transport: "stream",
|
||||
capability: "llm",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "azure-openai",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
usesKnownNativeOpenAIEndpoint: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "azure-openai",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
usesKnownNativeOpenAIEndpoint: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("classifies native Mistral hosts centrally", () => {
|
||||
expect(resolveProviderEndpoint("https://api.mistral.ai/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.mistral.ai/v1"), {
|
||||
endpointClass: "mistral-public",
|
||||
hostname: "api.mistral.ai",
|
||||
});
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "mistral",
|
||||
api: "openai-completions",
|
||||
@@ -298,50 +312,51 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "mistral-public",
|
||||
isKnownNativeEndpoint: true,
|
||||
knownProviderFamily: "mistral",
|
||||
});
|
||||
{
|
||||
endpointClass: "mistral-public",
|
||||
isKnownNativeEndpoint: true,
|
||||
knownProviderFamily: "mistral",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("classifies native OpenAI-compatible vendor hosts centrally", () => {
|
||||
expect(resolveProviderEndpoint("https://api.x.ai/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.x.ai/v1"), {
|
||||
endpointClass: "xai-native",
|
||||
hostname: "api.x.ai",
|
||||
});
|
||||
expect(resolveProviderEndpoint("https://api.grok.x.ai/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.grok.x.ai/v1"), {
|
||||
endpointClass: "xai-native",
|
||||
hostname: "api.grok.x.ai",
|
||||
});
|
||||
expect(resolveProviderEndpoint("https://api.z.ai/api/coding/paas/v4")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.z.ai/api/coding/paas/v4"), {
|
||||
endpointClass: "zai-native",
|
||||
hostname: "api.z.ai",
|
||||
});
|
||||
expect(resolveProviderEndpoint("https://api.deepseek.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.deepseek.com"), {
|
||||
endpointClass: "deepseek-native",
|
||||
hostname: "api.deepseek.com",
|
||||
});
|
||||
expect(resolveProviderEndpoint("https://llm.chutes.ai/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://llm.chutes.ai/v1"), {
|
||||
endpointClass: "chutes-native",
|
||||
hostname: "llm.chutes.ai",
|
||||
});
|
||||
expect(resolveProviderEndpoint("https://api.groq.com/openai/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.groq.com/openai/v1"), {
|
||||
endpointClass: "groq-native",
|
||||
hostname: "api.groq.com",
|
||||
});
|
||||
expect(resolveProviderEndpoint("https://api.cerebras.ai/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.cerebras.ai/v1"), {
|
||||
endpointClass: "cerebras-native",
|
||||
hostname: "api.cerebras.ai",
|
||||
});
|
||||
expect(resolveProviderEndpoint("https://opencode.ai/api")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://opencode.ai/api"), {
|
||||
endpointClass: "opencode-native",
|
||||
hostname: "opencode.ai",
|
||||
});
|
||||
});
|
||||
|
||||
it("treats OpenRouter-hosted Responses routes as explicit proxy-like endpoints", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openrouter",
|
||||
api: "openai-responses",
|
||||
@@ -349,15 +364,16 @@ describe("provider attribution", () => {
|
||||
transport: "stream",
|
||||
capability: "llm",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "openrouter",
|
||||
usesExplicitProxyLikeEndpoint: true,
|
||||
attributionProvider: "openrouter",
|
||||
});
|
||||
{
|
||||
endpointClass: "openrouter",
|
||||
usesExplicitProxyLikeEndpoint: true,
|
||||
attributionProvider: "openrouter",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("gates documented OpenRouter attribution to known OpenRouter endpoints", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openrouter",
|
||||
api: "openai-responses",
|
||||
@@ -365,11 +381,12 @@ describe("provider attribution", () => {
|
||||
transport: "stream",
|
||||
capability: "llm",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "openrouter",
|
||||
attributionProvider: "openrouter",
|
||||
allowsHiddenAttribution: false,
|
||||
});
|
||||
{
|
||||
endpointClass: "openrouter",
|
||||
attributionProvider: "openrouter",
|
||||
allowsHiddenAttribution: false,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
resolveProviderRequestAttributionHeaders({
|
||||
@@ -453,163 +470,167 @@ describe("provider attribution", () => {
|
||||
});
|
||||
|
||||
it("models other provider families without enabling hidden attribution", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "google",
|
||||
baseUrl: "https://generativelanguage.googleapis.com",
|
||||
transport: "http",
|
||||
capability: "image",
|
||||
}),
|
||||
).toMatchObject({
|
||||
knownProviderFamily: "google",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
});
|
||||
{
|
||||
knownProviderFamily: "google",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "github-copilot",
|
||||
transport: "http",
|
||||
capability: "llm",
|
||||
}),
|
||||
).toMatchObject({
|
||||
knownProviderFamily: "github-copilot",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
});
|
||||
{
|
||||
knownProviderFamily: "github-copilot",
|
||||
attributionProvider: undefined,
|
||||
allowsHiddenAttribution: false,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("classifies native Anthropic endpoints separately from custom hosts", () => {
|
||||
expect(resolveProviderEndpoint("https://api.anthropic.com/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.anthropic.com/v1"), {
|
||||
endpointClass: "anthropic-public",
|
||||
hostname: "api.anthropic.com",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("https://proxy.example.com/anthropic")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://proxy.example.com/anthropic"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "proxy.example.com",
|
||||
});
|
||||
});
|
||||
|
||||
it("classifies Google Gemini and Vertex endpoints separately from custom hosts", () => {
|
||||
expect(resolveProviderEndpoint("https://generativelanguage.googleapis.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://generativelanguage.googleapis.com"), {
|
||||
endpointClass: "google-generative-ai",
|
||||
hostname: "generativelanguage.googleapis.com",
|
||||
});
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderEndpoint("https://europe-west4-aiplatform.googleapis.com/v1/projects/test"),
|
||||
).toMatchObject({
|
||||
endpointClass: "google-vertex",
|
||||
hostname: "europe-west4-aiplatform.googleapis.com",
|
||||
googleVertexRegion: "europe-west4",
|
||||
});
|
||||
{
|
||||
endpointClass: "google-vertex",
|
||||
hostname: "europe-west4-aiplatform.googleapis.com",
|
||||
googleVertexRegion: "europe-west4",
|
||||
},
|
||||
);
|
||||
|
||||
expect(resolveProviderEndpoint("https://aiplatform.googleapis.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://aiplatform.googleapis.com"), {
|
||||
endpointClass: "google-vertex",
|
||||
hostname: "aiplatform.googleapis.com",
|
||||
googleVertexRegion: "global",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("https://proxy.example.com/google")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://proxy.example.com/google"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "proxy.example.com",
|
||||
});
|
||||
});
|
||||
|
||||
it("classifies native Moonshot and ModelStudio endpoints separately from custom hosts", () => {
|
||||
expect(resolveProviderEndpoint("https://api.moonshot.ai/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.moonshot.ai/v1"), {
|
||||
endpointClass: "moonshot-native",
|
||||
hostname: "api.moonshot.ai",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("https://api.moonshot.cn/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.moonshot.cn/v1"), {
|
||||
endpointClass: "moonshot-native",
|
||||
hostname: "api.moonshot.cn",
|
||||
});
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderEndpoint("https://dashscope-intl.aliyuncs.com/compatible-mode/v1"),
|
||||
).toMatchObject({
|
||||
endpointClass: "modelstudio-native",
|
||||
hostname: "dashscope-intl.aliyuncs.com",
|
||||
});
|
||||
{
|
||||
endpointClass: "modelstudio-native",
|
||||
hostname: "dashscope-intl.aliyuncs.com",
|
||||
},
|
||||
);
|
||||
|
||||
expect(resolveProviderEndpoint("https://proxy.example.com/v1")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://proxy.example.com/v1"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "proxy.example.com",
|
||||
});
|
||||
});
|
||||
|
||||
it("classifies native GitHub Copilot endpoints separately from custom hosts", () => {
|
||||
expect(resolveProviderEndpoint("https://api.individual.githubcopilot.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.individual.githubcopilot.com"), {
|
||||
endpointClass: "github-copilot-native",
|
||||
hostname: "api.individual.githubcopilot.com",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("https://api.enterprise.githubcopilot.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.enterprise.githubcopilot.com"), {
|
||||
endpointClass: "github-copilot-native",
|
||||
hostname: "api.enterprise.githubcopilot.com",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("https://api.githubcopilot.example.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://api.githubcopilot.example.com"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "api.githubcopilot.example.com",
|
||||
});
|
||||
});
|
||||
|
||||
it("does not classify malformed or embedded Google host strings as native endpoints", () => {
|
||||
expect(resolveProviderEndpoint("proxy/generativelanguage.googleapis.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("proxy/generativelanguage.googleapis.com"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "proxy",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("https://xgenerativelanguage.googleapis.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://xgenerativelanguage.googleapis.com"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "xgenerativelanguage.googleapis.com",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("proxy/aiplatform.googleapis.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("proxy/aiplatform.googleapis.com"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "proxy",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("https://xaiplatform.googleapis.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("https://xaiplatform.googleapis.com"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "xaiplatform.googleapis.com",
|
||||
});
|
||||
});
|
||||
|
||||
it("does not trust schemeless or embedded trusted-provider substrings", () => {
|
||||
expect(resolveProviderEndpoint("api.anthropic.com.attacker.example")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("api.anthropic.com.attacker.example"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "api.anthropic.com.attacker.example",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("api.openai.com.attacker.example")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("api.openai.com.attacker.example"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "api.openai.com.attacker.example",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("attacker.example/?target=api.openai.com")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("attacker.example/?target=api.openai.com"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "attacker.example",
|
||||
});
|
||||
|
||||
expect(resolveProviderEndpoint("openrouter.ai.attacker.example")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("openrouter.ai.attacker.example"), {
|
||||
endpointClass: "custom",
|
||||
hostname: "openrouter.ai.attacker.example",
|
||||
});
|
||||
});
|
||||
|
||||
it("ignores non-http schemes when normalizing native comparable base URLs", () => {
|
||||
expect(resolveProviderEndpoint("javascript:alert(1)")).toMatchObject({
|
||||
expectRecordFields(resolveProviderEndpoint("javascript:alert(1)"), {
|
||||
endpointClass: "invalid",
|
||||
});
|
||||
});
|
||||
|
||||
it("applies OpenAI attribution to every verified native capability", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openai",
|
||||
api: "openai-audio-transcriptions",
|
||||
@@ -617,12 +638,13 @@ describe("provider attribution", () => {
|
||||
transport: "media-understanding",
|
||||
capability: "audio",
|
||||
}),
|
||||
).toMatchObject({
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
});
|
||||
{
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openai",
|
||||
api: "openai-responses",
|
||||
@@ -630,38 +652,41 @@ describe("provider attribution", () => {
|
||||
transport: "media-understanding",
|
||||
capability: "audio",
|
||||
}),
|
||||
).toMatchObject({
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
});
|
||||
{
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openai",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
transport: "http",
|
||||
capability: "image",
|
||||
}),
|
||||
).toMatchObject({
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
});
|
||||
{
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestPolicy({
|
||||
provider: "openai",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
transport: "websocket",
|
||||
capability: "audio",
|
||||
}),
|
||||
).toMatchObject({
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
});
|
||||
{
|
||||
attributionProvider: "openai",
|
||||
allowsHiddenAttribution: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("resolves centralized request capabilities for native and proxied routes", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "openai",
|
||||
api: "openai-responses",
|
||||
@@ -669,28 +694,30 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "openai-public",
|
||||
allowsOpenAIServiceTier: true,
|
||||
supportsOpenAIReasoningCompatPayload: true,
|
||||
allowsResponsesStore: true,
|
||||
supportsResponsesStoreField: true,
|
||||
shouldStripResponsesPromptCache: false,
|
||||
});
|
||||
{
|
||||
endpointClass: "openai-public",
|
||||
allowsOpenAIServiceTier: true,
|
||||
supportsOpenAIReasoningCompatPayload: true,
|
||||
allowsResponsesStore: true,
|
||||
supportsResponsesStoreField: true,
|
||||
shouldStripResponsesPromptCache: false,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "anthropic",
|
||||
api: "anthropic-messages",
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "default",
|
||||
allowsAnthropicServiceTier: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "default",
|
||||
allowsAnthropicServiceTier: true,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "custom-proxy",
|
||||
api: "openai-responses",
|
||||
@@ -698,20 +725,21 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "custom",
|
||||
allowsOpenAIServiceTier: false,
|
||||
supportsOpenAIReasoningCompatPayload: false,
|
||||
allowsResponsesStore: false,
|
||||
supportsResponsesStoreField: true,
|
||||
shouldStripResponsesPromptCache: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "custom",
|
||||
allowsOpenAIServiceTier: false,
|
||||
supportsOpenAIReasoningCompatPayload: false,
|
||||
allowsResponsesStore: false,
|
||||
supportsResponsesStoreField: true,
|
||||
shouldStripResponsesPromptCache: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("respects compat.supportsPromptCacheKey override on prompt cache stripping", () => {
|
||||
// compat.supportsPromptCacheKey = true disables the strip even on a
|
||||
// proxy-like endpoint that would otherwise trigger it.
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "custom-proxy",
|
||||
api: "openai-responses",
|
||||
@@ -720,14 +748,15 @@ describe("provider attribution", () => {
|
||||
transport: "stream",
|
||||
compat: { supportsPromptCacheKey: true },
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "custom",
|
||||
shouldStripResponsesPromptCache: false,
|
||||
});
|
||||
{
|
||||
endpointClass: "custom",
|
||||
shouldStripResponsesPromptCache: false,
|
||||
},
|
||||
);
|
||||
|
||||
// compat.supportsPromptCacheKey = false forces the strip even on a
|
||||
// native OpenAI endpoint that would otherwise forward the field.
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "openai",
|
||||
api: "openai-responses",
|
||||
@@ -736,15 +765,16 @@ describe("provider attribution", () => {
|
||||
transport: "stream",
|
||||
compat: { supportsPromptCacheKey: false },
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "openai-public",
|
||||
shouldStripResponsesPromptCache: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "openai-public",
|
||||
shouldStripResponsesPromptCache: true,
|
||||
},
|
||||
);
|
||||
|
||||
// compat.supportsPromptCacheKey unset preserves the existing default
|
||||
// (strip on proxy-like responses endpoints, preserving the fix from
|
||||
// #48155 for providers that reject the field).
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "custom-proxy",
|
||||
api: "openai-responses",
|
||||
@@ -752,13 +782,14 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
shouldStripResponsesPromptCache: true,
|
||||
});
|
||||
{
|
||||
shouldStripResponsesPromptCache: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("resolves shared compat families and native streaming-usage gates", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "moonshot",
|
||||
api: "openai-completions",
|
||||
@@ -766,13 +797,14 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "moonshot-native",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
compatibilityFamily: "moonshot",
|
||||
});
|
||||
{
|
||||
endpointClass: "moonshot-native",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
compatibilityFamily: "moonshot",
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "qwen",
|
||||
api: "openai-completions",
|
||||
@@ -780,12 +812,13 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "modelstudio-native",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "modelstudio-native",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "generic",
|
||||
api: "openai-completions",
|
||||
@@ -793,12 +826,13 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "modelstudio-native",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "modelstudio-native",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "custom-local",
|
||||
api: "openai-completions",
|
||||
@@ -806,14 +840,15 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "local",
|
||||
supportsNativeStreamingUsageCompat: false,
|
||||
});
|
||||
{
|
||||
endpointClass: "local",
|
||||
supportsNativeStreamingUsageCompat: false,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("treats native GitHub Copilot base URLs as known native endpoints", () => {
|
||||
expect(
|
||||
expectRecordFields(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "github-copilot",
|
||||
api: "openai-responses",
|
||||
@@ -821,11 +856,12 @@ describe("provider attribution", () => {
|
||||
capability: "llm",
|
||||
transport: "http",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "github-copilot-native",
|
||||
knownProviderFamily: "github-copilot",
|
||||
isKnownNativeEndpoint: true,
|
||||
});
|
||||
{
|
||||
endpointClass: "github-copilot-native",
|
||||
knownProviderFamily: "github-copilot",
|
||||
isKnownNativeEndpoint: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("resolves a provider capability matrix for representative native and proxied routes", () => {
|
||||
@@ -1072,9 +1108,7 @@ describe("provider attribution", () => {
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
expect(resolveProviderRequestCapabilities(testCase.input), testCase.name).toMatchObject(
|
||||
testCase.expected,
|
||||
);
|
||||
expectRecordFields(resolveProviderRequestCapabilities(testCase.input), testCase.expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user