mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: map claude-sonnet-4-5 alias to full snapshot name claude-sonnet-4-5-20250929
- Add claude-sonnet-4-5-20250929 model definition to anthropic.ts - Update AnthropicHandler to map the alias to snapshot name for API calls - Add tests to verify the mapping works correctly - Fixes issue where custom base URLs that require exact snapshot IDs were failing Fixes #8545
This commit is contained in:
parent
5a3f911321
commit
5d890d8b77
3 changed files with 94 additions and 6 deletions
|
|
@ -28,6 +28,28 @@ export const anthropicModels = {
|
|||
},
|
||||
],
|
||||
},
|
||||
"claude-sonnet-4-5-20250929": {
|
||||
maxTokens: 64_000, // Overridden to 8k if `enableReasoningEffort` is false.
|
||||
contextWindow: 200_000, // Default 200K, extendable to 1M with beta flag 'context-1m-2025-08-07'
|
||||
supportsImages: true,
|
||||
supportsComputerUse: true,
|
||||
supportsPromptCache: true,
|
||||
inputPrice: 3.0, // $3 per million input tokens (≤200K context)
|
||||
outputPrice: 15.0, // $15 per million output tokens (≤200K context)
|
||||
cacheWritesPrice: 3.75, // $3.75 per million tokens
|
||||
cacheReadsPrice: 0.3, // $0.30 per million tokens
|
||||
supportsReasoningBudget: true,
|
||||
// Tiered pricing for extended context (requires beta flag 'context-1m-2025-08-07')
|
||||
tiers: [
|
||||
{
|
||||
contextWindow: 1_000_000, // 1M tokens with beta flag
|
||||
inputPrice: 6.0, // $6 per million input tokens (>200K context)
|
||||
outputPrice: 22.5, // $22.50 per million output tokens (>200K context)
|
||||
cacheWritesPrice: 7.5, // $7.50 per million tokens (>200K context)
|
||||
cacheReadsPrice: 0.6, // $0.60 per million tokens (>200K context)
|
||||
},
|
||||
],
|
||||
},
|
||||
"claude-sonnet-4-20250514": {
|
||||
maxTokens: 64_000, // Overridden to 8k if `enableReasoningEffort` is false.
|
||||
contextWindow: 200_000, // Default 200K, extendable to 1M with beta flag 'context-1m-2025-08-07'
|
||||
|
|
|
|||
|
|
@ -288,5 +288,55 @@ describe("AnthropicHandler", () => {
|
|||
expect(model.info.inputPrice).toBe(6.0)
|
||||
expect(model.info.outputPrice).toBe(22.5)
|
||||
})
|
||||
|
||||
it("should map claude-sonnet-4-5 to claude-sonnet-4-5-20250929 for API calls", async () => {
|
||||
const handler = new AnthropicHandler({
|
||||
apiKey: "test-api-key",
|
||||
apiModelId: "claude-sonnet-4-5",
|
||||
})
|
||||
|
||||
// Test createMessage
|
||||
const stream = handler.createMessage("Test system", [{ role: "user", content: "Test message" }])
|
||||
|
||||
// Consume the stream to trigger the API call
|
||||
for await (const chunk of stream) {
|
||||
// Just consume the stream
|
||||
}
|
||||
|
||||
// Verify the API was called with the full snapshot name
|
||||
expect(mockCreate).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
model: "claude-sonnet-4-5-20250929",
|
||||
stream: true,
|
||||
}),
|
||||
expect.any(Object),
|
||||
)
|
||||
|
||||
// Clear mock for next test
|
||||
mockCreate.mockClear()
|
||||
|
||||
// Test completePrompt
|
||||
await handler.completePrompt("Test prompt")
|
||||
|
||||
// Verify the API was called with the full snapshot name
|
||||
expect(mockCreate).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
model: "claude-sonnet-4-5-20250929",
|
||||
stream: false,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("should handle claude-sonnet-4-5-20250929 model directly", () => {
|
||||
const handler = new AnthropicHandler({
|
||||
apiKey: "test-api-key",
|
||||
apiModelId: "claude-sonnet-4-5-20250929",
|
||||
})
|
||||
const model = handler.getModel()
|
||||
expect(model.id).toBe("claude-sonnet-4-5-20250929")
|
||||
expect(model.info.maxTokens).toBe(64000)
|
||||
expect(model.info.contextWindow).toBe(200000)
|
||||
expect(model.info.supportsReasoningBudget).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -47,14 +47,20 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
|
|||
|
||||
// Add 1M context beta flag if enabled for Claude Sonnet 4 and 4.5
|
||||
if (
|
||||
(modelId === "claude-sonnet-4-20250514" || modelId === "claude-sonnet-4-5") &&
|
||||
(modelId === "claude-sonnet-4-20250514" ||
|
||||
modelId === "claude-sonnet-4-5" ||
|
||||
modelId === "claude-sonnet-4-5-20250929") &&
|
||||
this.options.anthropicBeta1MContext
|
||||
) {
|
||||
betas.push("context-1m-2025-08-07")
|
||||
}
|
||||
|
||||
// Map the alias to the full snapshot name for API calls
|
||||
const apiModelId = modelId === "claude-sonnet-4-5" ? "claude-sonnet-4-5-20250929" : modelId
|
||||
|
||||
switch (modelId) {
|
||||
case "claude-sonnet-4-5":
|
||||
case "claude-sonnet-4-5-20250929":
|
||||
case "claude-sonnet-4-20250514":
|
||||
case "claude-opus-4-1-20250805":
|
||||
case "claude-opus-4-20250514":
|
||||
|
|
@ -83,7 +89,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
|
|||
|
||||
stream = await this.client.messages.create(
|
||||
{
|
||||
model: modelId,
|
||||
model: apiModelId,
|
||||
max_tokens: maxTokens ?? ANTHROPIC_DEFAULT_MAX_TOKENS,
|
||||
temperature,
|
||||
thinking,
|
||||
|
|
@ -115,6 +121,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
|
|||
// Then check for models that support prompt caching
|
||||
switch (modelId) {
|
||||
case "claude-sonnet-4-5":
|
||||
case "claude-sonnet-4-5-20250929":
|
||||
case "claude-sonnet-4-20250514":
|
||||
case "claude-opus-4-1-20250805":
|
||||
case "claude-opus-4-20250514":
|
||||
|
|
@ -134,7 +141,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
|
|||
}
|
||||
default: {
|
||||
stream = (await this.client.messages.create({
|
||||
model: modelId,
|
||||
model: apiModelId,
|
||||
max_tokens: maxTokens ?? ANTHROPIC_DEFAULT_MAX_TOKENS,
|
||||
temperature,
|
||||
system: [{ text: systemPrompt, type: "text" }],
|
||||
|
|
@ -249,7 +256,10 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
|
|||
let info: ModelInfo = anthropicModels[id]
|
||||
|
||||
// If 1M context beta is enabled for Claude Sonnet 4 or 4.5, update the model info
|
||||
if ((id === "claude-sonnet-4-20250514" || id === "claude-sonnet-4-5") && this.options.anthropicBeta1MContext) {
|
||||
if (
|
||||
(id === "claude-sonnet-4-20250514" || id === "claude-sonnet-4-5" || id === "claude-sonnet-4-5-20250929") &&
|
||||
this.options.anthropicBeta1MContext
|
||||
) {
|
||||
// Use the tier pricing for 1M context
|
||||
const tier = info.tiers?.[0]
|
||||
if (tier) {
|
||||
|
|
@ -286,8 +296,11 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
|
|||
async completePrompt(prompt: string) {
|
||||
let { id: model, temperature } = this.getModel()
|
||||
|
||||
// Map the alias to the full snapshot name for API calls
|
||||
const apiModel = model === "claude-sonnet-4-5" ? "claude-sonnet-4-5-20250929" : model
|
||||
|
||||
const message = await this.client.messages.create({
|
||||
model,
|
||||
model: apiModel,
|
||||
max_tokens: ANTHROPIC_DEFAULT_MAX_TOKENS,
|
||||
thinking: undefined,
|
||||
temperature,
|
||||
|
|
@ -310,8 +323,11 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
|
|||
// Use the current model
|
||||
const { id: model } = this.getModel()
|
||||
|
||||
// Map the alias to the full snapshot name for API calls
|
||||
const apiModel = model === "claude-sonnet-4-5" ? "claude-sonnet-4-5-20250929" : model
|
||||
|
||||
const response = await this.client.messages.countTokens({
|
||||
model,
|
||||
model: apiModel,
|
||||
messages: [{ role: "user", content: content }],
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue