Răsfoiți Sursa

Support specifying custom cost per token (#2083)

* support specifying custom cost per token

* fix test for new attrs

* add to docs

---------

Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
Xingyao Wang 1 an în urmă
părinte
comite
ae8cda1495
3 a modificat fișierele cu 22 adăugiri și 1 ștergeri
  1. 4 0
      opendevin/core/config.py
  2. 16 1
      opendevin/llm/llm.py
  3. 2 0
      tests/unit/test_config.py

+ 4 - 0
opendevin/core/config.py

@@ -44,6 +44,8 @@ class LLMConfig(metaclass=Singleton):
         custom_llm_provider: The custom LLM provider to use. This is undocumented in opendevin, and normally not used. It is documented on the litellm side.
         custom_llm_provider: The custom LLM provider to use. This is undocumented in opendevin, and normally not used. It is documented on the litellm side.
         max_input_tokens: The maximum number of input tokens. Note that this is currently unused, and the value at runtime is actually the total tokens in OpenAI (e.g. 128,000 tokens for GPT-4).
         max_input_tokens: The maximum number of input tokens. Note that this is currently unused, and the value at runtime is actually the total tokens in OpenAI (e.g. 128,000 tokens for GPT-4).
         max_output_tokens: The maximum number of output tokens. This is sent to the LLM.
         max_output_tokens: The maximum number of output tokens. This is sent to the LLM.
+        input_cost_per_token: The cost per input token. This will available in logs for the user to check.
+        output_cost_per_token: The cost per output token. This will available in logs for the user to check.
     """
     """
 
 
     model: str = 'gpt-3.5-turbo'
     model: str = 'gpt-3.5-turbo'
@@ -66,6 +68,8 @@ class LLMConfig(metaclass=Singleton):
     custom_llm_provider: str | None = None
     custom_llm_provider: str | None = None
     max_input_tokens: int | None = None
     max_input_tokens: int | None = None
     max_output_tokens: int | None = None
     max_output_tokens: int | None = None
+    input_cost_per_token: float | None = None
+    output_cost_per_token: float | None = None
 
 
     def defaults_to_dict(self) -> dict:
     def defaults_to_dict(self) -> dict:
         """
         """

+ 16 - 1
opendevin/llm/llm.py

@@ -11,6 +11,7 @@ from litellm.exceptions import (
     RateLimitError,
     RateLimitError,
     ServiceUnavailableError,
     ServiceUnavailableError,
 )
 )
+from litellm.types.utils import CostPerToken
 from tenacity import (
 from tenacity import (
     retry,
     retry,
     retry_if_exception_type,
     retry_if_exception_type,
@@ -267,9 +268,23 @@ class LLM:
         Returns:
         Returns:
             number: The cost of the response.
             number: The cost of the response.
         """
         """
+        extra_kwargs = {}
+        if (
+            config.llm.input_cost_per_token is not None
+            and config.llm.output_cost_per_token is not None
+        ):
+            cost_per_token = CostPerToken(
+                input_cost_per_token=config.llm.input_cost_per_token,
+                output_cost_per_token=config.llm.output_cost_per_token,
+            )
+            logger.info(f'Using custom cost per token: {cost_per_token}')
+            extra_kwargs['custom_cost_per_token'] = cost_per_token
+
         if not self.is_local():
         if not self.is_local():
             try:
             try:
-                cost = litellm_completion_cost(completion_response=response)
+                cost = litellm_completion_cost(
+                    completion_response=response, **extra_kwargs
+                )
                 self.metrics.add_cost(cost)
                 self.metrics.add_cost(cost)
                 return cost
                 return cost
             except Exception:
             except Exception:

+ 2 - 0
tests/unit/test_config.py

@@ -232,6 +232,8 @@ def test_api_keys_repr_str():
         'api_key',
         'api_key',
         'aws_access_key_id',
         'aws_access_key_id',
         'aws_secret_access_key',
         'aws_secret_access_key',
+        'input_cost_per_token',
+        'output_cost_per_token',
     ]
     ]
     for attr_name in dir(LLMConfig):
     for attr_name in dir(LLMConfig):
         if (
         if (