port(pi-mono): normalize Bedrock model names for inference profiles (refs ed4bc7308)
Pi-mono Tier 0 #5 — first sf-driven port. sf-from-source dispatched the task in print mode and produced this fix autonomously. Adds getModelMatchCandidates(modelId, modelName?) helper that normalizes both inputs to lowercase and dash-separated form (s.replace(/[\s_.:]+/g, "-")). Inference profile ARNs don't embed the model name; the helper lets capability checks match against either the inference profile ARN or the underlying model name. Updated: - supportsAdaptiveThinking — uses the helper; consolidates the opus-4.6/opus-4-6 dot-vs-dash variants. - mapThinkingLevelToEffort — same pattern. - supportsPromptCaching — same pattern (also from pi-mono PR #3527). - streamSimpleBedrock and buildAdditionalModelRequestFields — pass model.name through to capability checks. Type-check passes (cd packages/pi-ai && npx tsc --noEmit). Co-Authored-By: sf v2.75.1 (session 911dd2de) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a3c487c918
commit
7c487bb60e
1 changed files with 38 additions and 22 deletions
|
|
@ -230,7 +230,7 @@ export const streamSimpleBedrock: StreamFunction<"bedrock-converse-stream", Simp
|
||||||
const effectiveReasoning = resolveReasoningLevel(model, options.reasoning);
|
const effectiveReasoning = resolveReasoningLevel(model, options.reasoning);
|
||||||
|
|
||||||
if (model.id.includes("anthropic.claude") || model.id.includes("anthropic/claude")) {
|
if (model.id.includes("anthropic.claude") || model.id.includes("anthropic/claude")) {
|
||||||
if (supportsAdaptiveThinking(model.id) && isAutoReasoning(options.reasoning)) {
|
if (supportsAdaptiveThinking(model.id, model.name) && isAutoReasoning(options.reasoning)) {
|
||||||
return streamBedrock(model, context, {
|
return streamBedrock(model, context, {
|
||||||
...base,
|
...base,
|
||||||
reasoning: options.reasoning,
|
reasoning: options.reasoning,
|
||||||
|
|
@ -238,7 +238,7 @@ export const streamSimpleBedrock: StreamFunction<"bedrock-converse-stream", Simp
|
||||||
} satisfies BedrockOptions);
|
} satisfies BedrockOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supportsAdaptiveThinking(model.id)) {
|
if (supportsAdaptiveThinking(model.id, model.name)) {
|
||||||
return streamBedrock(model, context, {
|
return streamBedrock(model, context, {
|
||||||
...base,
|
...base,
|
||||||
reasoning: effectiveReasoning,
|
reasoning: effectiveReasoning,
|
||||||
|
|
@ -393,22 +393,32 @@ function handleContentBlockStop(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks both model ID and model name to support application inference profiles
|
||||||
|
* whose ARNs don't contain the model name.
|
||||||
|
*/
|
||||||
|
function getModelMatchCandidates(modelId: string, modelName?: string): string[] {
|
||||||
|
const values = modelName ? [modelId, modelName] : [modelId];
|
||||||
|
return values.flatMap((value) => {
|
||||||
|
const lower = value.toLowerCase();
|
||||||
|
return [lower, lower.replace(/[\s_.:]+/g, "-")];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the model supports adaptive thinking (Opus 4.6/4.7, Sonnet 4.6/4.7, Haiku 4.5).
|
* Check if the model supports adaptive thinking (Opus 4.6/4.7, Sonnet 4.6/4.7, Haiku 4.5).
|
||||||
* @internal exported for testing only
|
* @internal exported for testing only
|
||||||
*/
|
*/
|
||||||
export function supportsAdaptiveThinking(modelId: string): boolean {
|
export function supportsAdaptiveThinking(modelId: string, modelName?: string): boolean {
|
||||||
|
const candidates = getModelMatchCandidates(modelId, modelName);
|
||||||
return (
|
return (
|
||||||
modelId.includes("opus-4-6") ||
|
candidates.some((s) =>
|
||||||
modelId.includes("opus-4.6") ||
|
s.includes("opus-4-6") ||
|
||||||
modelId.includes("opus-4-7") ||
|
s.includes("opus-4-7") ||
|
||||||
modelId.includes("opus-4.7") ||
|
s.includes("sonnet-4-6") ||
|
||||||
modelId.includes("sonnet-4-6") ||
|
s.includes("sonnet-4-7") ||
|
||||||
modelId.includes("sonnet-4.6") ||
|
s.includes("haiku-4-5"),
|
||||||
modelId.includes("sonnet-4-7") ||
|
)
|
||||||
modelId.includes("sonnet-4.7") ||
|
|
||||||
modelId.includes("haiku-4-5") ||
|
|
||||||
modelId.includes("haiku-4.5")
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -416,7 +426,9 @@ export function supportsAdaptiveThinking(modelId: string): boolean {
|
||||||
export function mapThinkingLevelToEffort(
|
export function mapThinkingLevelToEffort(
|
||||||
level: SimpleStreamOptions["reasoning"],
|
level: SimpleStreamOptions["reasoning"],
|
||||||
modelId: string,
|
modelId: string,
|
||||||
|
modelName?: string,
|
||||||
): "low" | "medium" | "high" | "xhigh" | "max" {
|
): "low" | "medium" | "high" | "xhigh" | "max" {
|
||||||
|
const candidates = getModelMatchCandidates(modelId, modelName);
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case "auto":
|
case "auto":
|
||||||
return "medium";
|
return "medium";
|
||||||
|
|
@ -428,8 +440,8 @@ export function mapThinkingLevelToEffort(
|
||||||
case "high":
|
case "high":
|
||||||
return "high";
|
return "high";
|
||||||
case "xhigh":
|
case "xhigh":
|
||||||
if (modelId.includes("opus-4-7") || modelId.includes("opus-4.7")) return "xhigh";
|
if (candidates.some((s) => s.includes("opus-4-7"))) return "xhigh";
|
||||||
if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6")) return "max";
|
if (candidates.some((s) => s.includes("opus-4-6"))) return "max";
|
||||||
return "high";
|
return "high";
|
||||||
default:
|
default:
|
||||||
return "high";
|
return "high";
|
||||||
|
|
@ -459,13 +471,17 @@ function supportsPromptCaching(model: Model<"bedrock-converse-stream">): boolean
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = model.id.toLowerCase();
|
const candidates = getModelMatchCandidates(model.id, model.name);
|
||||||
|
const hasClaudeRef = candidates.some((s) => s.includes("claude"));
|
||||||
|
if (!hasClaudeRef) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Claude 4.x models (opus-4, sonnet-4, haiku-4)
|
// Claude 4.x models (opus-4, sonnet-4, haiku-4)
|
||||||
if (id.includes("claude") && (id.includes("-4-") || id.includes("-4."))) return true;
|
if (candidates.some((s) => s.includes("-4-"))) return true;
|
||||||
// Claude 3.7 Sonnet
|
// Claude 3.7 Sonnet
|
||||||
if (id.includes("claude-3-7-sonnet")) return true;
|
if (candidates.some((s) => s.includes("claude-3-7-sonnet"))) return true;
|
||||||
// Claude 3.5 Haiku
|
// Claude 3.5 Haiku
|
||||||
if (id.includes("claude-3-5-haiku")) return true;
|
if (candidates.some((s) => s.includes("claude-3-5-haiku"))) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -721,14 +737,14 @@ export function buildAdditionalModelRequestFields(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.id.includes("anthropic.claude") || model.id.includes("anthropic/claude")) {
|
if (model.id.includes("anthropic.claude") || model.id.includes("anthropic/claude")) {
|
||||||
const result: Record<string, any> = supportsAdaptiveThinking(model.id)
|
const result: Record<string, any> = supportsAdaptiveThinking(model.id, model.name)
|
||||||
? options.reasoning === "auto"
|
? options.reasoning === "auto"
|
||||||
? {
|
? {
|
||||||
thinking: { type: "adaptive" },
|
thinking: { type: "adaptive" },
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
thinking: { type: "adaptive" },
|
thinking: { type: "adaptive" },
|
||||||
output_config: { effort: mapThinkingLevelToEffort(options.reasoning, model.id) },
|
output_config: { effort: mapThinkingLevelToEffort(options.reasoning, model.id, model.name) },
|
||||||
}
|
}
|
||||||
: (() => {
|
: (() => {
|
||||||
const defaultBudgets: Record<ThinkingLevel, number> = {
|
const defaultBudgets: Record<ThinkingLevel, number> = {
|
||||||
|
|
@ -752,7 +768,7 @@ export function buildAdditionalModelRequestFields(
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
if (!supportsAdaptiveThinking(model.id) && (options.interleavedThinking ?? true)) {
|
if (!supportsAdaptiveThinking(model.id, model.name) && (options.interleavedThinking ?? true)) {
|
||||||
result.anthropic_beta = ["interleaved-thinking-2025-05-14"];
|
result.anthropic_beta = ["interleaved-thinking-2025-05-14"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue