From 1b8df6ff1dd0fdaa8d0fab0faeaf15b4657478bc Mon Sep 17 00:00:00 2001 From: better629 Date: Mon, 17 Mar 2025 11:22:32 +0800 Subject: [PATCH] update bedrock claude usage --- metagpt/provider/bedrock/base_provider.py | 3 ++- metagpt/provider/bedrock/bedrock_provider.py | 8 ++++++-- metagpt/provider/bedrock_api.py | 3 +++ metagpt/utils/token_counter.py | 4 ++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/metagpt/provider/bedrock/base_provider.py b/metagpt/provider/bedrock/base_provider.py index 7eb5dfb61..8cd961128 100644 --- a/metagpt/provider/bedrock/base_provider.py +++ b/metagpt/provider/bedrock/base_provider.py @@ -1,11 +1,12 @@ import json from abc import ABC, abstractmethod -from typing import Union +from typing import Optional, Union class BaseBedrockProvider(ABC): # to handle different generation kwargs max_tokens_field_name = "max_tokens" + usage: Optional[dict] = None def __init__(self, reasoning: bool = False, reasoning_max_token: int = 4000): self.reasoning = reasoning diff --git a/metagpt/provider/bedrock/bedrock_provider.py b/metagpt/provider/bedrock/bedrock_provider.py index 10627f40b..2ecbddd64 100644 --- a/metagpt/provider/bedrock/bedrock_provider.py +++ b/metagpt/provider/bedrock/bedrock_provider.py @@ -68,8 +68,12 @@ class AnthropicProvider(BaseBedrockProvider): elif delta_type == "signature_delta": completions = "" return reasoning, completions - else: - return False, "" + elif rsp_dict["type"] == "message_stop": + self.usage = { + "prompt_tokens": rsp_dict.get("amazon-bedrock-invocationMetrics", {}).get("inputTokenCount", 0), + "completion_tokens": rsp_dict.get("amazon-bedrock-invocationMetrics", {}).get("outputTokenCount", 0), + } + return False, "" class CohereProvider(BaseBedrockProvider): diff --git a/metagpt/provider/bedrock_api.py b/metagpt/provider/bedrock_api.py index c99241043..80da95eae 100644 --- a/metagpt/provider/bedrock_api.py +++ b/metagpt/provider/bedrock_api.py @@ -130,6 +130,9 @@ class BedrockLLM(BaseLLM): collected_content = await self._get_stream_response_body(stream_response) log_llm_stream("\n") full_text = ("".join(collected_content)).lstrip() + if self.__provider.usage: + # if provider provide usage, update it + self._update_costs(self.__provider.usage, self.config.model) return full_text def _get_response_body(self, response) -> dict: diff --git a/metagpt/utils/token_counter.py b/metagpt/utils/token_counter.py index 1629f90c9..80bdacae5 100644 --- a/metagpt/utils/token_counter.py +++ b/metagpt/utils/token_counter.py @@ -373,6 +373,10 @@ BEDROCK_TOKEN_COSTS = { "anthropic.claude-3-haiku-20240307-v1:0:200k": {"prompt": 0.00025, "completion": 0.00125}, # currently (2024-4-29) only available at US West (Oregon) AWS Region. "anthropic.claude-3-opus-20240229-v1:0": {"prompt": 0.015, "completion": 0.075}, + "anthropic.claude-3-5-sonnet-20241022-v2:0": {"prompt": 0.003, "completion": 0.015}, + "us.anthropic.claude-3-5-sonnet-20241022-v2:0": {"prompt": 0.003, "completion": 0.015}, + "anthropic.claude-3-7-sonnet-20250219-v1:0": {"prompt": 0.003, "completion": 0.015}, + "us.anthropic.claude-3-7-sonnet-20250219-v1:0": {"prompt": 0.003, "completion": 0.015}, "cohere.command-text-v14": {"prompt": 0.0015, "completion": 0.0015}, "cohere.command-text-v14:7:4k": {"prompt": 0.0015, "completion": 0.0015}, "cohere.command-light-text-v14": {"prompt": 0.0003, "completion": 0.0003},