Skip to content

Commit 5e34862

Browse files
authored
Merge pull request #30 from AgentOps-AI/29-update-table-to-use-usdm-tokens
updated table
2 parents 6c5144d + ebcc4d2 commit 5e34862

6 files changed

Lines changed: 1706 additions & 280 deletions

File tree

models_pricing_table.md

Lines changed: 246 additions & 0 deletions
Large diffs are not rendered by default.

tests/test_costs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def test_calculate_invalid_input_types():
205205
with pytest.raises(KeyError):
206206
calculate_completion_cost(STRING, model="invalid_model")
207207

208-
with pytest.raises(TypeError):
208+
with pytest.raises(KeyError):
209209
# Message objects not allowed, must be list of message objects.
210210
calculate_prompt_cost(MESSAGES[0], model="invalid_model")
211211

tokencost/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
calculate_completion_cost,
55
calculate_prompt_cost,
66
)
7-
from .constants import TOKEN_COSTS
7+
from .constants import TOKEN_COSTS_STATIC, TOKEN_COSTS_STATIC

tokencost/constants.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import os
22
import json
3-
from urllib.request import urlopen
3+
import aiohttp
4+
import asyncio
5+
import logging
46

57
"""
68
Prompt (aka context) tokens are based on number of words + other chars (eg spaces and punctuation) in input.
@@ -20,16 +22,40 @@
2022
# Each completion token costs __ USD per token.
2123
# Max prompt limit of each model is __ tokens.
2224

23-
# Fetch the latest prices using urllib.request
2425
PRICES_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
2526

27+
28+
async def fetch_costs():
29+
"""Fetch the latest token costs from the LiteLLM cost tracker asynchronously.
30+
Returns:
31+
dict: The token costs for each model.
32+
Raises:
33+
Exception: If the request fails.
34+
"""
35+
async with aiohttp.ClientSession() as session:
36+
async with session.get(PRICES_URL) as response:
37+
if response.status == 200:
38+
return await response.json(content_type=None)
39+
else:
40+
raise Exception(f"Failed to fetch token costs, status code: {response.status}")
41+
42+
43+
async def update_token_costs():
44+
"""Update the TOKEN_COSTS dictionary with the latest costs from the LiteLLM cost tracker asynchronously."""
45+
global TOKEN_COSTS
46+
try:
47+
TOKEN_COSTS = await fetch_costs()
48+
print("TOKEN_COSTS updated successfully.")
49+
except Exception as e:
50+
logging.error(f"Failed to update TOKEN_COSTS: {e}")
51+
52+
with open(os.path.join(os.path.dirname(__file__), "model_prices.json"), "r") as f:
53+
TOKEN_COSTS_STATIC = json.load(f)
54+
55+
56+
# Ensure TOKEN_COSTS is up to date when the module is loaded
2657
try:
27-
with urlopen(PRICES_URL) as response:
28-
if response.status == 200:
29-
TOKEN_COSTS = json.loads(response.read())
30-
else:
31-
raise Exception("Failed to fetch token costs, status code: {}".format(response.status))
58+
asyncio.run(update_token_costs())
3259
except Exception:
33-
# If fetching fails, use the local model_prices.json as a fallback
34-
with open(os.path.join(os.path.dirname(__file__), "model_prices.json"), "r") as f:
35-
TOKEN_COSTS = json.load(f)
60+
logging.error('Failed to update token costs. Using static costs.')
61+
TOKEN_COSTS = TOKEN_COSTS_STATIC

tokencost/costs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def strip_ft_model_name(model: str) -> str:
2222
model = "ft:gpt-3.5-turbo"
2323
return model
2424

25+
2526
def count_message_tokens(messages: List[Dict[str, str]], model: str) -> int:
2627
"""
2728
Return the total number of tokens in a prompt's messages.

0 commit comments

Comments
 (0)