mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 15:58:36 +00:00
fix: validate vercel gateway model token metadata
This commit is contained in:
@@ -3,6 +3,7 @@ import { readProviderJsonArrayFieldResponse } from "openclaw/plugin-sdk/provider
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { asPositiveSafeInteger } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
export const VERCEL_AI_GATEWAY_PROVIDER_ID = "vercel-ai-gateway";
|
||||
export const VERCEL_AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
|
||||
@@ -151,13 +152,13 @@ function buildDiscoveredModelDefinition(
|
||||
|
||||
const fallback = getStaticFallbackModel(id);
|
||||
const contextWindow =
|
||||
typeof model.context_window === "number" && Number.isFinite(model.context_window)
|
||||
? model.context_window
|
||||
: (fallback?.contextWindow ?? VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW);
|
||||
asPositiveSafeInteger(model.context_window) ??
|
||||
fallback?.contextWindow ??
|
||||
VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW;
|
||||
const maxTokens =
|
||||
typeof model.max_tokens === "number" && Number.isFinite(model.max_tokens)
|
||||
? model.max_tokens
|
||||
: (fallback?.maxTokens ?? VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS);
|
||||
asPositiveSafeInteger(model.max_tokens) ??
|
||||
fallback?.maxTokens ??
|
||||
VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS;
|
||||
const normalizedCost = normalizeCost(model.pricing);
|
||||
|
||||
return {
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
discoverVercelAiGatewayModels,
|
||||
getStaticVercelAiGatewayModelCatalog,
|
||||
VERCEL_AI_GATEWAY_BASE_URL,
|
||||
VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW,
|
||||
VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS,
|
||||
} from "./api.js";
|
||||
import {
|
||||
buildStaticVercelAiGatewayProvider,
|
||||
@@ -93,4 +95,47 @@ describe("vercel ai gateway provider catalog", () => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("falls back from malformed live token metadata", async () => {
|
||||
fetchWithSsrFGuardMock.mockResolvedValueOnce({
|
||||
response: {
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: async () => ({
|
||||
data: [
|
||||
{
|
||||
id: "anthropic/claude-opus-4.6",
|
||||
name: "Claude Opus 4.6",
|
||||
context_window: -1,
|
||||
max_tokens: 128_000.5,
|
||||
tags: ["vision", "reasoning"],
|
||||
},
|
||||
{
|
||||
id: "custom/provider-model",
|
||||
name: "Custom model",
|
||||
context_window: Number.POSITIVE_INFINITY,
|
||||
max_tokens: 0,
|
||||
tags: ["reasoning"],
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
release: async () => {},
|
||||
});
|
||||
|
||||
await withLiveDiscovery(async () => {
|
||||
const models = await discoverVercelAiGatewayModels();
|
||||
|
||||
expect(models[0]).toMatchObject({
|
||||
id: "anthropic/claude-opus-4.6",
|
||||
contextWindow: 1_000_000,
|
||||
maxTokens: 128_000,
|
||||
});
|
||||
expect(models[1]).toMatchObject({
|
||||
id: "custom/provider-model",
|
||||
contextWindow: VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW,
|
||||
maxTokens: VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user