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
Original file line number Diff line number Diff line change
Expand Up @@ -1043,3 +1043,7 @@ or expiry does not extend the history-recovery contract.
Sender and recipient on routed Responses are context for the receiving model, not a new
machine-readable routing protocol. Tool routing continues to use the existing collaboration
contracts.

### Renamed API-key presets

A provider saved under another name, such as `CommandCode`, inherits missing reasoning-effort metadata when its adapter and fixed API-key endpoint match a registry preset. Your explicit per-model lists, including `[]`, remain authoritative. An omitted provider-wide list inherits the preset default; an explicit list remains unchanged. This does not match OAuth, unrelated endpoints, or templated/custom endpoint presets.
12 changes: 9 additions & 3 deletions src/providers/derive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,13 +441,19 @@ function applyVerbosityDefaults(prov: OcxProviderConfig, entry: ProviderRegistry
* was skipped and the reasoning ladder was advertised without summary support — exactly the
* inconsistency that makes Codex drop the inbound reasoning object.
*
* Deliberately narrow: only the reasoning-summary map, and only via
* Deliberately narrow: reasoning-summary and effort metadata only, via
* `registryEntryForProviderDestination`, which matches fixed key destinations and refuses
* templated or overridable base URLs. A custom row keeps its own identity for everything else.
*/
function enrichReasoningSummariesByDestination(prov: OcxProviderConfig): void {
function enrichReasoningMetadataByDestination(prov: OcxProviderConfig): void {
const destination = registryEntryForProviderDestination(prov);
applyReasoningSummaryDefaults(prov, destination?.modelSupportsReasoningSummaries);
if (destination?.modelReasoningEfforts) {
prov.modelReasoningEfforts = fillRecordOfArrays(destination.modelReasoningEfforts, prov.modelReasoningEfforts);
}
if (prov.reasoningEfforts === undefined && destination?.reasoningEfforts !== undefined) {
prov.reasoningEfforts = [...destination.reasoningEfforts];
}
}

/** Repair the exact low-only ClinePass ladder generated by older key-login presets. */
Expand All @@ -467,7 +473,7 @@ export function enrichProviderFromRegistry(name: string, prov: OcxProviderConfig
// `registryEntryForProviderDestination` answers the question that actually matters here —
// which vendor endpoint is this row talking to — and is already restricted to fixed key
// destinations, so a templated or overridable base URL cannot be claimed by it.
enrichReasoningSummariesByDestination(prov);
enrichReasoningMetadataByDestination(prov);
applyServiceTierModelDefaults(prov, serviceTierModelDefaultsFor(registryEntryForProviderDestination(prov), prov));
applyVerbosityDefaults(prov, registryEntryForProviderDestination(prov));
return;
Expand Down
4 changes: 4 additions & 0 deletions structure/catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,7 @@ see [Combo editor routing quota](gui-and-management-api.md#combo-editor-routing-

Claude replay carries [Go conversation affinity](data-planes/inbound-compat.md#claude-affinity-at-final-go-dispatch)
privately to final dispatch; preliminary route selection does not inject Go-only headers.

## Renamed destination reasoning metadata

`src/providers/derive.ts` fills missing reasoning tables for renamed providers accepted by the existing fixed-key destination matcher. Model entries are cloned and explicit user entries (including empty arrays) win. Provider-wide effort defaults fill only when undefined; Command Code unknown models therefore keep the registry's empty picker policy unless overridden. Identity, transport and other capability axes are unchanged. The gathered row drives client exports; this metadata contract does not prove arbitrary gateway routing.
2 changes: 2 additions & 0 deletions structure/ops/docs-and-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,5 @@ see [Combo editor routing quota](../gui-and-management-api.md#combo-editor-routi
`src/codex/history-provider.ts` refuses external writes to paginated or migration-capable history. `src/codex/inject.ts` checks affected rows and manifest-owned restore targets before artifact changes and compensates detected migration. Failed config restore stops later catalog/history work. See the [history writer contract](../codex-home.md#paginated-history-writer-boundary) for guarantees and concurrent-writer limits.

The integrations guide documents Cline CLI as a two-file, loopback-only integration. Hosted CI validates its source-backed fixtures; the packaged dashboard exposes it through the existing client list.

Renamed fixed-key providers receive [missing reasoning metadata](../catalog.md#renamed-destination-reasoning-metadata) during derivation; explicit per-model entries and provider defaults retain precedence.
2 changes: 2 additions & 0 deletions structure/providers/xai-grok.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ see [Combo editor routing quota](../gui-and-management-api.md#combo-editor-routi

Claude replay carries [Go conversation affinity](../data-planes/inbound-compat.md#claude-affinity-at-final-go-dispatch)
privately to final dispatch; preliminary route selection does not inject Go-only headers.

Renamed fixed-key providers receive [missing reasoning metadata](../catalog.md#renamed-destination-reasoning-metadata) during derivation; explicit per-model entries and provider defaults retain precedence.
2 changes: 2 additions & 0 deletions structure/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,5 @@ Cline CLI joins the existing export/client integration registries. Explicit CLI
`claudeCode.stabilizePromptCache` is a default-off operator setting for
[translated instruction stabilization](data-planes/inbound-compat.md#opt-in-claude-instruction-stabilization).
Config JSON preserves the boolean; only literal true activates the role-changing transform.

Renamed fixed-key providers receive [missing reasoning metadata](catalog.md#renamed-destination-reasoning-metadata) during derivation; explicit per-model entries and provider defaults retain precedence.
2 changes: 2 additions & 0 deletions structure/subagents.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,5 @@ see [Combo editor routing quota](gui-and-management-api.md#combo-editor-routing-

Claude replay carries [Go conversation affinity](data-planes/inbound-compat.md#claude-affinity-at-final-go-dispatch)
privately to final dispatch; preliminary route selection does not inject Go-only headers.

Renamed fixed-key providers receive [missing reasoning metadata](catalog.md#renamed-destination-reasoning-metadata) during derivation; explicit per-model entries and provider defaults retain precedence.
2 changes: 2 additions & 0 deletions structure/transports/inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ see [Combo editor routing quota](../gui-and-management-api.md#combo-editor-routi

Claude replay carries [Go conversation affinity](../data-planes/inbound-compat.md#claude-affinity-at-final-go-dispatch)
privately to final dispatch; preliminary route selection does not inject Go-only headers.

Renamed fixed-key providers receive [missing reasoning metadata](../catalog.md#renamed-destination-reasoning-metadata) during derivation; explicit per-model entries and provider defaults retain precedence.
40 changes: 40 additions & 0 deletions tests/config/client-config-export.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,3 +1105,43 @@ describe("EXPORT_CLIENTS registry", () => {
expect(piConfig(empty).providers.opencodex!.models).toEqual([]);
});
});


test("renamed CommandCode gathered effort tables reach DSH and ZCode exports", async () => {
const { gatherRoutedModels } = await import("../../src/codex/catalog");
const { clearModelCache } = await import("../../src/codex/model-cache");
const { installIsolatedCodexHome } = await import("../helpers/isolated-codex-home");
const isolated = installIsolatedCodexHome("ocx-renamed-provider-export-");
const known = "deepseek/deepseek-v4-flash";
const overridden = "deepseek/deepseek-v4.1-flash";
const config = cfg({ defaultProvider: "CommandCode", providers: { CommandCode: {
adapter: "openai-chat", authMode: "key", baseUrl: "https://api.commandcode.ai/provider/v1",
liveModels: false, models: [known, overridden, "unknown-model"],
modelReasoningEfforts: { [overridden]: ["low"] },
} } });
try {
clearModelCache();
const gathered = await gatherRoutedModels(config);
const rows = gathered.map(row => ({ ...row, namespaced: `CommandCode/${row.id}` }));
const models = exportModelsFromProxyRows(rows, config);
const context = ctx({ models, config });
const dshConfig = dsh.buildDshClientConfig(context);
const dshModels = Object.values(dshConfig["llm-pi-ai"].providers).flatMap(provider => provider.models);
expect(dshModels.find(model => model.id === `CommandCode/${known}`)?.reasoningEfforts).toEqual({ high: "high", max: "max" });
expect(dshModels.find(model => model.id === `CommandCode/${overridden}`)?.reasoningEfforts).toEqual({ low: "low" });
expect(dshModels.find(model => model.id === "CommandCode/unknown-model")?.reasoningEfforts).toBeUndefined();
for (const id of [known, overridden, "unknown-model"]) {
expect(dshModels.find(model => model.id === `CommandCode/${id}`)).toBeDefined();
}
const zcodeModels = Object.assign({}, ...Object.values(zcode.buildZcodeClientConfig(context).provider).map(provider => provider.models)) as Record<string, zcode.ZcodeModelEntry>;
expect(zcodeModels[`CommandCode/${known}`]).toBeDefined();
expect(zcodeModels[`CommandCode/${known}`]!.reasoning?.variants).toEqual(["high", "max"]);
expect(zcodeModels[`CommandCode/${overridden}`]).toBeDefined();
expect(zcodeModels[`CommandCode/${overridden}`]!.reasoning?.variants).toEqual(["low"]);
expect(zcodeModels["CommandCode/unknown-model"]).toBeDefined();
expect(zcodeModels["CommandCode/unknown-model"]!.reasoning).toBeUndefined();
} finally {
clearModelCache();
isolated.restore();
}
});
49 changes: 49 additions & 0 deletions tests/providers/provider-registry-parity.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { configuredReasoningEfforts } from "../../src/reasoning-effort";
import { describe, expect, spyOn, test } from "bun:test";
import { buildCatalogEntries } from "../../src/codex/catalog";
import { CURSOR_NO_VISION_MODELS } from "../../src/adapters/cursor/discovery";
Expand Down Expand Up @@ -1527,3 +1528,51 @@ describe("free-provider directory isolation", () => {
}
});
});


describe("renamed fixed-key destination reasoning metadata", () => {
const known = "deepseek/deepseek-v4-flash";
const newer = "deepseek/deepseek-v4.1-flash";
const make = (overrides: Partial<OcxProviderConfig> = {}): OcxProviderConfig => ({
adapter: "openai-chat", authMode: "key", baseUrl: "https://api.commandcode.ai/provider/v1", ...overrides,
});
test("fills known model tables and unknown-model default for CommandCode", () => {
const provider = make();
enrichProviderFromRegistry("CommandCode", provider);
expect(configuredReasoningEfforts(provider, known)).toEqual(["high", "max"]);
expect(configuredReasoningEfforts(provider, newer)).toEqual(["high", "max"]);
expect(configuredReasoningEfforts(provider, "unknown-model")).toEqual([]);
});
test("preserves explicit entries and clones arrays without losing other table rows", () => {
const caller = ["low"];
const provider = make({ reasoningEfforts: ["medium"], modelReasoningEfforts: { [known]: caller, custom: [] } });
const registry = registryEntryForProviderDestination(provider)!;
const registryBefore = structuredClone(registry.modelReasoningEfforts);
enrichProviderFromRegistry("CommandCode", provider);
const once = structuredClone(provider);
enrichProviderFromRegistry("CommandCode", provider);
expect(provider).toEqual(once);
expect(configuredReasoningEfforts(provider, known)).toEqual(["low"]);
expect(configuredReasoningEfforts(provider, newer)).toEqual(["high", "max"]);
expect(configuredReasoningEfforts(provider, "custom")).toEqual([]);
expect(configuredReasoningEfforts(provider, "unknown-model")).toEqual(["medium"]);
provider.modelReasoningEfforts![known]!.push("high");
provider.modelReasoningEfforts![newer]!.push("low");
expect(caller).toEqual(["low"]);
expect(registry.modelReasoningEfforts).toEqual(registryBefore);
});
test("explicit empty model declaration overrides a seeded ladder", () => {
const provider = make({ modelReasoningEfforts: { [known]: [] } });
enrichProviderFromRegistry("CommandCode", provider);
expect(configuredReasoningEfforts(provider, known)).toEqual([]);
expect(configuredReasoningEfforts(provider, newer)).toEqual(["high", "max"]);
});
test("does not infer metadata for a different adapter, OAuth, or unrelated endpoint", () => {
for (const override of [{ adapter: "openai-responses" }, { authMode: "oauth" as const }, { baseUrl: "https://example.test/v1" }]) {
const provider = make(override);
enrichProviderFromRegistry("CommandCode", provider);
expect(provider.modelReasoningEfforts).toBeUndefined();
expect(provider.reasoningEfforts).toBeUndefined();
}
});
});
Loading