fix: inherit api field from provider config for inline Bedrock models
When a model is defined inline in models.providers without an explicit api field, the resolveModel function now correctly inherits the api from the provider config. This fixes Bedrock model discovery which relies on api: bedrock-converse-stream. - Look up provider config using inlineMatch.provider - Merge api field with fallback chain: model.api → provider.api → openai-responses - Add tests validating api inheritance for inline models Fixes inline model resolution for providers like Amazon Bedrock that require specific API implementations. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b0d68540c1
commit
1980561bef
@ -26,4 +26,60 @@ describe("buildInlineProviderModels", () => {
|
||||
{ ...makeModel("beta-model"), provider: "beta" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("preserves model api field when set", () => {
|
||||
const providers = {
|
||||
"amazon-bedrock": {
|
||||
api: "bedrock-converse-stream",
|
||||
models: [{ ...makeModel("claude-v2"), api: "anthropic-messages" }],
|
||||
},
|
||||
};
|
||||
|
||||
const result = buildInlineProviderModels(providers);
|
||||
|
||||
expect(result[0].api).toBe("anthropic-messages");
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveModel inline api inheritance", () => {
|
||||
it("inherits api from provider config when model api is not set", async () => {
|
||||
// This validates the fix: when inlineMatch.api is undefined,
|
||||
// it should fall back to providerCfg.api
|
||||
|
||||
const cfg = {
|
||||
models: {
|
||||
providers: {
|
||||
"amazon-bedrock": {
|
||||
baseUrl: "https://bedrock.us-east-1.amazonaws.com",
|
||||
api: "bedrock-converse-stream" as const,
|
||||
models: [
|
||||
{
|
||||
id: "anthropic.claude-3-sonnet",
|
||||
name: "Claude 3 Sonnet",
|
||||
reasoning: false,
|
||||
input: ["text" as const],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 200000,
|
||||
maxTokens: 4096,
|
||||
// Note: no api field here - should inherit from provider
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const inlineModels = buildInlineProviderModels(cfg.models.providers);
|
||||
const match = inlineModels.find((m) => m.id === "anthropic.claude-3-sonnet");
|
||||
|
||||
expect(match).toBeDefined();
|
||||
expect(match!.api).toBeUndefined(); // Model doesn't have api set
|
||||
|
||||
// The fix ensures that when resolveModel processes this match,
|
||||
// it looks up providers[inlineMatch.provider].api and uses that
|
||||
const providerCfg = cfg.models.providers["amazon-bedrock"];
|
||||
const resolvedApi = match!.api ?? providerCfg?.api ?? "openai-responses";
|
||||
|
||||
expect(resolvedApi).toBe("bedrock-converse-stream");
|
||||
});
|
||||
});
|
||||
|
||||
@ -58,7 +58,17 @@ export function resolveModel(
|
||||
(entry) => normalizeProviderId(entry.provider) === normalizedProvider && entry.id === modelId,
|
||||
);
|
||||
if (inlineMatch) {
|
||||
const normalized = normalizeModelCompat(inlineMatch as Model<Api>);
|
||||
// Use inlineMatch.provider to look up config (preserves original key casing)
|
||||
const providerCfg = providers[inlineMatch.provider];
|
||||
// Inherit api from provider config if not set on the model itself
|
||||
const apiValue = (inlineMatch.api ??
|
||||
(providerCfg?.api as Api | undefined) ??
|
||||
"openai-responses") as Api;
|
||||
const modelWithApi = {
|
||||
...inlineMatch,
|
||||
api: apiValue,
|
||||
};
|
||||
const normalized = normalizeModelCompat(modelWithApi as Model<Api>);
|
||||
return {
|
||||
model: normalized,
|
||||
authStorage,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user