Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/responses/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -674,10 +674,13 @@ async function writeBoundedSnapshot(path: string, attemptLimit: number): Promise
try {
for (let attempt = 0; attempt < attemptLimit; attempt += 1) {
const revision = stateRevision;
const entries: Array<[string, unknown]> = [];
const serializedEntries: string[] = [];
let total = 0;
// Newest-first so the most recent chains survive both legacy snapshot caps.
for (const [id, state] of [...states].reverse()) {
// Walk backwards by index without duplicating or reversing the map entries array.
const stateList = Array.from(states);
for (let i = stateList.length - 1; i >= 0; i--) {
const [id, state] = stateList[i];
let persistable: unknown;
if (state.kind === "resident") {
const { sizeBytes: _sizeBytes, kind: _kind, ...resident } = state;
Expand All @@ -689,14 +692,15 @@ async function writeBoundedSnapshot(path: string, attemptLimit: number): Promise
const persistEntry: [string, unknown] = [id, persistable];
// UTF-8 bytes, not UTF-16 code units: multibyte items otherwise slip
// past both snapshot caps at up to 2x the intended size.
const size = Buffer.byteLength(JSON.stringify(persistEntry), "utf8");
const serialized = JSON.stringify(persistEntry);
const size = Buffer.byteLength(serialized, "utf8");
if (state.kind === "resident" && size > SNAPSHOT_ENTRY_MAX_BYTES) continue;
if (total + size > SNAPSHOT_TOTAL_MAX_BYTES) break;
total += size;
entries.push(persistEntry);
serializedEntries.push(serialized);
}
entries.reverse();
const payload = JSON.stringify({ version: 2, states: entries });
serializedEntries.reverse();
const payload = '{"version":2,"states":[' + serializedEntries.join(",") + ']}';
const payloadBytes = Buffer.byteLength(payload, "utf8");
const payloadDigest = Bun.hash(payload).toString(36);
// A mutation does not always change what gets persisted: entries past the
Expand Down
45 changes: 32 additions & 13 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,28 @@ export interface RouteResult {
routeDecision?: RouteDecisionTraceV1;
}

const REGISTRY_BY_ID = new Map(PROVIDER_REGISTRY.map(entry => [entry.id, entry]));

const REGISTRY_STATIC_MODEL_IDS = new Map<string, readonly string[]>(
PROVIDER_REGISTRY.map(entry => {
const ids = new Set<string>();
for (const id of entry.models ?? []) ids.add(id);
for (const id of registryModelIdKeys(entry)) ids.add(id);
return [entry.id, Object.freeze([...ids])];
}),
);

const REGISTRY_ALIAS_BY_ID = new Map(PROVIDER_REGISTRY.flatMap(entry => entry.alias ? [[entry.id, entry.alias]] : []));

export function captureRouteStaticPolicy(
providerName: string,
modelId: string,
provider: OcxProviderConfig,
effectiveAlias?: string | null,
inboundWire: "responses" | "chat" | "anthropic" = "responses",
): ResolvedModelPolicy {
const registryEntry = PROVIDER_REGISTRY.find(entry => entry.id === providerName);
const registryEntry = REGISTRY_BY_ID.get(providerName)
?? PROVIDER_REGISTRY.find(entry => entry.id === providerName);
const transportMatchedRegistry = !!registryEntry
&& providerMatchesRegistryTransportWithStaticGuards(providerName, provider);
return resolveModelPolicy({
Expand Down Expand Up @@ -125,6 +139,7 @@ const MODEL_PROVIDER_PATTERNS: Array<{ providerNames: string[]; prefixes: string
},
];


/**
* Known native model ids for a provider — the decode source for the Codex slug codec
* (src/providers/slug-codec.ts). Union of static config ids, registry seeds, and the
Expand All @@ -139,16 +154,18 @@ export function knownModelIdsForProvider(
const ids = new Set<string>();
for (const id of prov.models ?? []) ids.add(id);
if (prov.defaultModel) ids.add(prov.defaultModel);
const registry = providerMatchesRegistryTransportWithStaticGuards(provName, prov)
? PROVIDER_REGISTRY.find(entry => entry.id === provName)
: undefined;
for (const id of registry?.models ?? []) ids.add(id);
// Registry model-keyed hint maps double as known native ids (e.g. NVIDIA carries no
// static models list but names `moonshotai/kimi-k2.6` in its effort/window maps). Which
// maps count is classified by the registry itself rather than listed here, so an id declared
// only in a map this function forgot is no longer undecodable, and a new model-keyed field
// fails typecheck until its keys are given a meaning.
for (const id of registry ? registryModelIdKeys(registry) : []) ids.add(id);
if (providerMatchesRegistryTransportWithStaticGuards(provName, prov)) {
const staticIds = REGISTRY_STATIC_MODEL_IDS.get(provName);
if (staticIds) {
for (let i = 0; i < staticIds.length; i++) ids.add(staticIds[i]);
} else {
const dynamicEntry = PROVIDER_REGISTRY.find(entry => entry.id === provName);
if (dynamicEntry) {
for (const id of dynamicEntry.models ?? []) ids.add(id);
for (const id of registryModelIdKeys(dynamicEntry)) ids.add(id);
}
}
}
for (const cached of getStaleCached(provName) ?? []) ids.add(cached.id);
for (const model of config?.customModels ?? []) {
if (model.provider === provName && model.modelId) ids.add(model.modelId);
Expand Down Expand Up @@ -258,7 +275,8 @@ function usableResolvedApiKey(apiKey: string | undefined): string | undefined {

export function routedProviderConfig(providerName: string, provider: OcxProviderConfig): OcxProviderConfig {
provider = { ...provider, _apiKeyAttempt: provider._apiKeyAttempt ?? captureProviderApiKeySelection(provider) };
const registryEntry = PROVIDER_REGISTRY.find(entry => entry.id === providerName);
const registryEntry = REGISTRY_BY_ID.get(providerName)
?? PROVIDER_REGISTRY.find(entry => entry.id === providerName);
if (!registryEntry || !providerMatchesRegistryTransportWithStaticGuards(providerName, provider)) {
assertProviderDestinationAllowed(providerName, provider);
// A row whose adapter no longer matches its registry entry still reaches the Responses
Expand Down Expand Up @@ -698,7 +716,8 @@ function routeModelInternal(
// and whose registry alias has not been claimed by another configured provider name or alias
const registryMatches = Object.entries(config.providers).filter(([name, provider]) => {
if (provider.alias !== undefined) return false;
const regAlias = PROVIDER_REGISTRY.find(e => e.id === name)?.alias;
const regAlias = REGISTRY_ALIAS_BY_ID.get(name)
?? PROVIDER_REGISTRY.find(entry => entry.id === name)?.alias;
if (!regAlias || regAlias.toLowerCase() !== requestedLower) return false;
const claimedByOther = Object.entries(config.providers).some(([otherName, p]) =>
otherName !== name && (
Expand Down
17 changes: 17 additions & 0 deletions tests/responses/responses-state-write-amplification.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,21 @@ describe("responses-state snapshot write amplification (#2460)", () => {
expect(parsed.version).toBe(2);
expect(parsed.states.map(([id]) => id)).toContain("resp_amp_roundtrip");
});
test("writeBoundedSnapshot serializes entries with version 2 and preserves parse integrity", async () => {
remember("resp_amp_order_1", "entry1");
remember("resp_amp_order_2", "entry2");
await flushResponseState();

const raw = await Bun.file(snapshot).text();
expect(raw.startsWith('{"version":2,"states":[')).toBe(true);
expect(raw.endsWith("]}"));
const parsed = JSON.parse(raw) as {
version: number;
states: [string, Record<string, unknown>][];
};
expect(parsed.version).toBe(2);
const ids = parsed.states.map(([id]) => id);
expect(ids).toContain("resp_amp_order_1");
expect(ids).toContain("resp_amp_order_2");
});
});
11 changes: 10 additions & 1 deletion tests/routing/router.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test } from "bun:test";
import { mapReasoningEffort } from "../../src/reasoning-effort";
import { NoEnabledOpenAiProviderError, routeCompactionModel, routeModel } from "../../src/router";
import { NoEnabledOpenAiProviderError, knownModelIdsForProvider, routeCompactionModel, routeModel } from "../../src/router";
import type { OcxConfig, OcxProviderConfig } from "../../src/types";

describe("routeModel registry effort defaults", () => {
Expand Down Expand Up @@ -771,4 +771,13 @@ describe("routeCompactionModel (#2901)", () => {
};
expect(() => routeCompactionModel(openAiDefaultDisabled, "gpt-5.6-sol")).toThrow(NoEnabledOpenAiProviderError);
});
test("knownModelIdsForProvider retrieves static registry models and hint maps via cached maps", () => {
const provConfig = {
adapter: "openai-chat",
baseUrl: "https://api.nvidia.com/v1",
apiKey: "test-key",
};
const knownIds = knownModelIdsForProvider("nvidia", provConfig as any);
expect(knownIds).toContain("moonshotai/kimi-k2.6");
});
});
Loading