edsl 0.1.56__py3-none-any.whl → 0.1.58__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- edsl/__version__.py +1 -1
- edsl/coop/coop.py +174 -37
- edsl/coop/utils.py +63 -0
- edsl/interviews/exception_tracking.py +26 -0
- edsl/jobs/html_table_job_logger.py +377 -48
- edsl/jobs/jobs_pricing_estimation.py +19 -96
- edsl/jobs/jobs_remote_inference_logger.py +27 -0
- edsl/jobs/jobs_runner_status.py +52 -21
- edsl/jobs/remote_inference.py +187 -30
- edsl/language_models/language_model.py +1 -1
- edsl/language_models/price_manager.py +91 -57
- {edsl-0.1.56.dist-info → edsl-0.1.58.dist-info}/METADATA +2 -2
- {edsl-0.1.56.dist-info → edsl-0.1.58.dist-info}/RECORD +16 -17
- edsl/language_models/compute_cost.py +0 -78
- {edsl-0.1.56.dist-info → edsl-0.1.58.dist-info}/LICENSE +0 -0
- {edsl-0.1.56.dist-info → edsl-0.1.58.dist-info}/WHEEL +0 -0
- {edsl-0.1.56.dist-info → edsl-0.1.58.dist-info}/entry_points.txt +0 -0
@@ -19,56 +19,12 @@ class ResponseCost:
|
|
19
19
|
total_cost: Union[float, str, None] = None
|
20
20
|
|
21
21
|
|
22
|
-
class
|
23
|
-
|
24
|
-
|
25
|
-
_is_initialized = False
|
26
|
-
|
27
|
-
def __new__(cls):
|
28
|
-
if cls._instance is None:
|
29
|
-
instance = super(PriceManager, cls).__new__(cls)
|
30
|
-
instance._price_lookup = {} # Instance-specific attribute
|
31
|
-
instance._is_initialized = False
|
32
|
-
cls._instance = instance # Store the instance directly
|
33
|
-
return instance
|
34
|
-
return cls._instance
|
35
|
-
|
36
|
-
def __init__(self):
|
37
|
-
"""Initialize the singleton instance only once."""
|
38
|
-
if not self._is_initialized:
|
39
|
-
self._is_initialized = True
|
40
|
-
self.refresh_prices()
|
41
|
-
|
42
|
-
@classmethod
|
43
|
-
def get_instance(cls):
|
44
|
-
"""Get the singleton instance, creating it if necessary."""
|
45
|
-
if cls._instance is None:
|
46
|
-
cls() # Create the instance if it doesn't exist
|
47
|
-
return cls._instance
|
48
|
-
|
49
|
-
@classmethod
|
50
|
-
def reset(cls):
|
51
|
-
"""Reset the singleton instance to clean up resources."""
|
52
|
-
cls._instance = None
|
53
|
-
cls._is_initialized = False
|
54
|
-
cls._price_lookup = {}
|
55
|
-
|
56
|
-
def __del__(self):
|
57
|
-
"""Ensure proper cleanup when the instance is garbage collected."""
|
58
|
-
try:
|
59
|
-
self._price_lookup = {} # Clean up resources
|
60
|
-
except:
|
61
|
-
pass # Ignore any cleanup errors
|
22
|
+
class PriceRetriever:
|
23
|
+
DEFAULT_INPUT_PRICE_PER_MILLION_TOKENS = 1.0
|
24
|
+
DEFAULT_OUTPUT_PRICE_PER_MILLION_TOKENS = 1.0
|
62
25
|
|
63
|
-
def
|
64
|
-
|
65
|
-
from edsl.coop import Coop
|
66
|
-
|
67
|
-
c = Coop()
|
68
|
-
try:
|
69
|
-
self._price_lookup = c.fetch_prices()
|
70
|
-
except Exception as e:
|
71
|
-
print(f"Error fetching prices: {str(e)}")
|
26
|
+
def __init__(self, price_lookup: Dict[Tuple[str, str], Dict]):
|
27
|
+
self._price_lookup = price_lookup
|
72
28
|
|
73
29
|
def get_price(self, inference_service: str, model: str) -> Dict:
|
74
30
|
"""Get the price information for a specific service and model."""
|
@@ -77,10 +33,6 @@ class PriceManager:
|
|
77
33
|
inference_service
|
78
34
|
)
|
79
35
|
|
80
|
-
def get_all_prices(self) -> Dict[Tuple[str, str], Dict]:
|
81
|
-
"""Get the complete price lookup dictionary."""
|
82
|
-
return self._price_lookup.copy()
|
83
|
-
|
84
36
|
def _get_fallback_price(self, inference_service: str) -> Dict:
|
85
37
|
"""
|
86
38
|
Get fallback prices for a service.
|
@@ -101,15 +53,21 @@ class PriceManager:
|
|
101
53
|
if service == inference_service
|
102
54
|
]
|
103
55
|
|
104
|
-
|
56
|
+
default_input_price_info = {
|
57
|
+
"one_usd_buys": 1_000_000,
|
58
|
+
"service_stated_token_qty": 1_000_000,
|
59
|
+
"service_stated_token_price": self.DEFAULT_INPUT_PRICE_PER_MILLION_TOKENS,
|
60
|
+
}
|
61
|
+
|
62
|
+
default_output_price_info = {
|
105
63
|
"one_usd_buys": 1_000_000,
|
106
64
|
"service_stated_token_qty": 1_000_000,
|
107
|
-
"service_stated_token_price":
|
65
|
+
"service_stated_token_price": self.DEFAULT_OUTPUT_PRICE_PER_MILLION_TOKENS,
|
108
66
|
}
|
109
67
|
|
110
68
|
# Find the most expensive price entries (lowest tokens per USD)
|
111
|
-
input_price_info =
|
112
|
-
output_price_info =
|
69
|
+
input_price_info = default_input_price_info
|
70
|
+
output_price_info = default_output_price_info
|
113
71
|
|
114
72
|
input_prices = [
|
115
73
|
PriceEntry(float(p["input"]["one_usd_buys"]), p["input"])
|
@@ -156,6 +114,82 @@ class PriceManager:
|
|
156
114
|
price_per_million_tokens = round(price_per_token * 1_000_000, 10)
|
157
115
|
return price_per_million_tokens
|
158
116
|
|
117
|
+
|
118
|
+
class PriceManager:
|
119
|
+
_instance = None
|
120
|
+
_price_lookup: Dict[Tuple[str, str], Dict] = {}
|
121
|
+
_is_initialized = False
|
122
|
+
|
123
|
+
def __new__(cls):
|
124
|
+
if cls._instance is None:
|
125
|
+
instance = super(PriceManager, cls).__new__(cls)
|
126
|
+
instance._price_lookup = {} # Instance-specific attribute
|
127
|
+
instance._is_initialized = False
|
128
|
+
cls._instance = instance # Store the instance directly
|
129
|
+
return instance
|
130
|
+
return cls._instance
|
131
|
+
|
132
|
+
def __init__(self):
|
133
|
+
"""Initialize the singleton instance only once."""
|
134
|
+
if not self._is_initialized:
|
135
|
+
self._is_initialized = True
|
136
|
+
self.refresh_prices()
|
137
|
+
|
138
|
+
@classmethod
|
139
|
+
def get_instance(cls):
|
140
|
+
"""Get the singleton instance, creating it if necessary."""
|
141
|
+
if cls._instance is None:
|
142
|
+
cls() # Create the instance if it doesn't exist
|
143
|
+
return cls._instance
|
144
|
+
|
145
|
+
@classmethod
|
146
|
+
def reset(cls):
|
147
|
+
"""Reset the singleton instance to clean up resources."""
|
148
|
+
cls._instance = None
|
149
|
+
cls._is_initialized = False
|
150
|
+
cls._price_lookup = {}
|
151
|
+
|
152
|
+
def __del__(self):
|
153
|
+
"""Ensure proper cleanup when the instance is garbage collected."""
|
154
|
+
try:
|
155
|
+
self._price_lookup = {} # Clean up resources
|
156
|
+
except:
|
157
|
+
pass # Ignore any cleanup errors
|
158
|
+
|
159
|
+
@property
|
160
|
+
def price_retriever(self):
|
161
|
+
return PriceRetriever(self._price_lookup)
|
162
|
+
|
163
|
+
def refresh_prices(self) -> None:
|
164
|
+
"""Fetch fresh prices and update the internal price lookup."""
|
165
|
+
from edsl.coop import Coop
|
166
|
+
|
167
|
+
c = Coop()
|
168
|
+
try:
|
169
|
+
self._price_lookup = c.fetch_prices()
|
170
|
+
except Exception as e:
|
171
|
+
print(f"Error fetching prices: {str(e)}")
|
172
|
+
|
173
|
+
def get_price(self, inference_service: str, model: str) -> Dict:
|
174
|
+
"""Get the price information for a specific service and model."""
|
175
|
+
return self.price_retriever.get_price(inference_service, model)
|
176
|
+
|
177
|
+
def get_all_prices(self) -> Dict[Tuple[str, str], Dict]:
|
178
|
+
"""Get the complete price lookup dictionary."""
|
179
|
+
return self._price_lookup.copy()
|
180
|
+
|
181
|
+
def get_price_per_million_tokens(
|
182
|
+
self,
|
183
|
+
relevant_prices: Dict,
|
184
|
+
token_type: Literal["input", "output"],
|
185
|
+
) -> Dict:
|
186
|
+
"""
|
187
|
+
Get the price per million tokens for a specific service, model, and token type.
|
188
|
+
"""
|
189
|
+
return self.price_retriever.get_price_per_million_tokens(
|
190
|
+
relevant_prices, token_type
|
191
|
+
)
|
192
|
+
|
159
193
|
def _calculate_total_cost(
|
160
194
|
self,
|
161
195
|
relevant_prices: Dict,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: edsl
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.58
|
4
4
|
Summary: Create and analyze LLM-based surveys
|
5
5
|
Home-page: https://www.expectedparrot.com/
|
6
6
|
License: MIT
|
@@ -23,7 +23,7 @@ Requires-Dist: azure-ai-inference (>=1.0.0b3,<2.0.0)
|
|
23
23
|
Requires-Dist: black[jupyter] (>=24.4.2,<25.0.0)
|
24
24
|
Requires-Dist: boto3 (>=1.34.161,<2.0.0)
|
25
25
|
Requires-Dist: google-generativeai (>=0.8.2,<0.9.0)
|
26
|
-
Requires-Dist: groq (
|
26
|
+
Requires-Dist: groq (==0.23.1)
|
27
27
|
Requires-Dist: jinja2 (>=3.1.2,<4.0.0)
|
28
28
|
Requires-Dist: json-repair (>=0.28.4,<0.29.0)
|
29
29
|
Requires-Dist: jupyter (>=1.0.0,<2.0.0)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
edsl/__init__.py,sha256=EkpMsEKqKRbN9Qqcn_y8CjX8OjlWFyhxslLrt3SJY0Q,4827
|
2
2
|
edsl/__init__original.py,sha256=PzMzANf98PrSleSThXT4anNkeVqZMdw0tfFonzsoiGk,4446
|
3
|
-
edsl/__version__.py,sha256=
|
3
|
+
edsl/__version__.py,sha256=ujgZXX_cw13M2UkyXWVg5j1fgdE25Qb3rUzLZVokSKg,23
|
4
4
|
edsl/agents/__init__.py,sha256=AyhfXjygRHT1Pd9w16lcu5Bu0jnBmMPz86aKP1uRL3Y,93
|
5
5
|
edsl/agents/agent.py,sha256=J0y8dH8tWXffiAVhyPEWJ4xmOKdi-XtSrSlMJ08fd58,55606
|
6
6
|
edsl/agents/agent_list.py,sha256=-bm8jozPPIHJAqb-1nt9m3TZGw5-tgg4LAjz5Mpj0AE,23071
|
@@ -40,7 +40,7 @@ edsl/conversation/exceptions.py,sha256=DoUCg-ymqGOjOl0cpGT8-sNRVsr3SEwdxGAKtdeZ2
|
|
40
40
|
edsl/conversation/mug_negotiation.py,sha256=do3PTykM6A2cDGOcsohlevRgLpCICoPx8B0WIYe6hy8,2518
|
41
41
|
edsl/conversation/next_speaker_utilities.py,sha256=bqr5JglCd6bdLc9IZ5zGOAsmN2F4ERiubSMYvZIG7qk,3629
|
42
42
|
edsl/coop/__init__.py,sha256=DU2w1Nu8q6tMAa3xoPC722RrvGhmB_UgUUBJDUywsKY,1542
|
43
|
-
edsl/coop/coop.py,sha256=
|
43
|
+
edsl/coop/coop.py,sha256=NVcteUNmd-1k-MbSzplJnMzFHmFhqr_tjAIvdq2fhLI,71303
|
44
44
|
edsl/coop/coop_functions.py,sha256=d31kddfj9MVZaMhqwUvkSIBwrdCTQglIvFWVfUr4NuE,688
|
45
45
|
edsl/coop/coop_jobs_objects.py,sha256=_OFPVLKswXY9mKl9b3Y7gxlUhaMZ7GULx5OqyANpecU,1701
|
46
46
|
edsl/coop/coop_objects.py,sha256=_cEspdAxh7BT672poxb0HsjU-QZ4Kthg-tKDvZ6I_v0,859
|
@@ -48,7 +48,7 @@ edsl/coop/coop_regular_objects.py,sha256=indDQPeesQjHEX_CkICpJPI7o-R8KX66m9DOR9Z
|
|
48
48
|
edsl/coop/ep_key_handling.py,sha256=X0tskEaYKsRIbFUijaCL69uHYpLJcLbYFITzAu3PGJE,7872
|
49
49
|
edsl/coop/exceptions.py,sha256=EY3eNTeJM15VzFnag93hgmiqn4pR3Y-6nS9ixKGIhM8,8874
|
50
50
|
edsl/coop/price_fetcher.py,sha256=uvEPgKaSRsFq-ouRl5W9aksawUkJg9Lo7ucSePecwa4,4735
|
51
|
-
edsl/coop/utils.py,sha256=
|
51
|
+
edsl/coop/utils.py,sha256=DON2ns5nWlUqqvlNVUsdgiPlz-6oEqFVOmjhnOwHQBs,8174
|
52
52
|
edsl/data_transfer_models.py,sha256=pPaKsbo9pgNcBB9kX-U2O_dUtNkd0Xm4JNmv26jrbhI,265
|
53
53
|
edsl/dataset/__init__.py,sha256=RIzfFIytKJfniKZ0VThMk8Z2fjejx91t9PZBct78xXw,422
|
54
54
|
edsl/dataset/dataset.py,sha256=kfjfF4B-SlTeBL2FHDiLdwTZOm8RmWqTUOTQStNiOqk,39563
|
@@ -106,7 +106,7 @@ edsl/instructions/instruction_handler.py,sha256=MXy0LSyAUE5H2G8Pdhs-WerZM8VWGqNR
|
|
106
106
|
edsl/interviews/ReportErrors.py,sha256=5NC6fFGaVe6Qk4gnFd7fUFRsw9MKb7g4MFOr-EblS0o,1728
|
107
107
|
edsl/interviews/__init__.py,sha256=BC6NBomroZEc8uwOeZBMtVuXwAVQzTzm7kkgDBqEBic,328
|
108
108
|
edsl/interviews/answering_function.py,sha256=zmUMGP1xSpDm49_dqj39g8BoGGy0OmhlcUrJQvUyio8,13695
|
109
|
-
edsl/interviews/exception_tracking.py,sha256=
|
109
|
+
edsl/interviews/exception_tracking.py,sha256=ayM7Ntoe7_FQbcsJICQ-fWiqo71hvu-nj62DLct4rfU,11223
|
110
110
|
edsl/interviews/exceptions.py,sha256=qID-2HnSHJt5DyxBQd4698GZfTEu8rwk_VbIrBHcIRc,2626
|
111
111
|
edsl/interviews/interview.py,sha256=LyLY6kbjeUih_DREgIU38AIkrSWsKqSSgoVoLiUMlCE,26450
|
112
112
|
edsl/interviews/interview_status_dictionary.py,sha256=0ZvXLusfOA8xD_Fco4PjEBGwmR2sizHOGijTQI8RrI8,3031
|
@@ -131,17 +131,17 @@ edsl/jobs/data_structures.py,sha256=i-XXq2zul1K1aOZDZXbPIO8l-0bJLqDL2t7pxITXbks,
|
|
131
131
|
edsl/jobs/decorators.py,sha256=0Eot9pFPsWmQIJAafNd0f5hdb9RUAFp_hGMmSUTJ_C8,3272
|
132
132
|
edsl/jobs/exceptions.py,sha256=5lktTya2VgiBR5Bd977tG2xHdrMjDqhPhQO17O6jIdc,7220
|
133
133
|
edsl/jobs/fetch_invigilator.py,sha256=nzXAIulvOvuDpRDEN5TDNmEfikUEwrnS_XCtnYG2uPQ,2795
|
134
|
-
edsl/jobs/html_table_job_logger.py,sha256=
|
134
|
+
edsl/jobs/html_table_job_logger.py,sha256=rtVnfP9aBG6_S-PdkUI3K4DZN7sS-paAj-smgyknDuE,33729
|
135
135
|
edsl/jobs/jobs.py,sha256=WL3ODJ4HBElnw2XVaPXqfvHzyTsEe0XeUghOZOyI0FA,42334
|
136
136
|
edsl/jobs/jobs_checks.py,sha256=bfPJ3hQ4qvRBhyte4g-4J8zExJxJr3nlLHmtVmFPJcQ,5390
|
137
137
|
edsl/jobs/jobs_component_constructor.py,sha256=9956UURv3eo-cURNPd4EV8wAQsY-AlEtQRmBu1nCOH8,6982
|
138
138
|
edsl/jobs/jobs_interview_constructor.py,sha256=8nIhhwBQWH_aZ9ZWjvRgOL0y2y6juRTb3pVngQ9Cs8g,2017
|
139
|
-
edsl/jobs/jobs_pricing_estimation.py,sha256=
|
140
|
-
edsl/jobs/jobs_remote_inference_logger.py,sha256=
|
141
|
-
edsl/jobs/jobs_runner_status.py,sha256=
|
139
|
+
edsl/jobs/jobs_pricing_estimation.py,sha256=vCrqAMdzocKcJ3d0sWYStajY2G4YwGD26PAQZdS_Stk,14085
|
140
|
+
edsl/jobs/jobs_remote_inference_logger.py,sha256=gHVxumpFQ2NxbLkd1fdkiZkOcMNoCdHqeQHxFdXOv9s,10039
|
141
|
+
edsl/jobs/jobs_runner_status.py,sha256=gW8EA-BAKpBvahqRipzomALEAQizd24aRW8G2y7faLQ,11905
|
142
142
|
edsl/jobs/jobs_status_enums.py,sha256=8Kgtr-ffcGGniQ2x5gCOqwURb_HaBWmYcWbUB_KTCY0,214
|
143
143
|
edsl/jobs/progress_bar_manager.py,sha256=d8wuZf7SHq3LCA36JIv1sfYymyHFOUsYRSRlRpR6K04,2832
|
144
|
-
edsl/jobs/remote_inference.py,sha256=
|
144
|
+
edsl/jobs/remote_inference.py,sha256=d3Bxg4bJzZnQ2vVlZdMgMM8vMXkWh5odgH4svpfyb_Q,21308
|
145
145
|
edsl/jobs/results_exceptions_handler.py,sha256=VCtnd60xwdFznzGhtXPbxLmyVf3kIjR2419LUJdFjEQ,3053
|
146
146
|
edsl/key_management/__init__.py,sha256=JiOJ71Ly9aw-tVYbWZu-qRjsW4QETYMQ9IJjsKgW1DQ,1274
|
147
147
|
edsl/key_management/exceptions.py,sha256=dDtoDh1UL52BUBrAlCIc_McgtZCAQkUx6onoSz26qeM,2158
|
@@ -150,12 +150,11 @@ edsl/key_management/key_lookup_builder.py,sha256=AlQxXbUYwyJc-3JjLddXBOBPVsYJ-B2
|
|
150
150
|
edsl/key_management/key_lookup_collection.py,sha256=b1STYU4FIqgCtCf90bRZh6IXf8kcoTC8ad8RSHPmw-w,3471
|
151
151
|
edsl/key_management/models.py,sha256=z9TimNMnz47mnITM5SlJy2m2sk1aKKtt0ybV89rsaiY,6703
|
152
152
|
edsl/language_models/__init__.py,sha256=WtefJs6XOCn5RSz22PgoAi3eTEr1NzGtnnBpDIie2mg,240
|
153
|
-
edsl/language_models/compute_cost.py,sha256=noWk0osCANksfKSh0sXFkPrcQegtSV8-jCRBjz_52uQ,2570
|
154
153
|
edsl/language_models/exceptions.py,sha256=P9dMA8XfK_qcuXNJZ-Xsb_Ny-12Ldu3fPC133RB40Ek,13728
|
155
|
-
edsl/language_models/language_model.py,sha256=
|
154
|
+
edsl/language_models/language_model.py,sha256=u1sclHfmIfjXlgW6IGpr-nK4V-HJRIrpBmPiNAqbZOo,44675
|
156
155
|
edsl/language_models/model.py,sha256=oYZsfgvko_EH4EWT9XZPEgLcs9KA36SGEAKZwYRFjv8,12013
|
157
156
|
edsl/language_models/model_list.py,sha256=Eb62xQdrlayqWYyJVgYxheMiNi14e1U9b_12qYzy1ws,4522
|
158
|
-
edsl/language_models/price_manager.py,sha256=
|
157
|
+
edsl/language_models/price_manager.py,sha256=74XEkoVdQv06w7gMFZmXeeXGW6om4_ISr-qFnmX4lFE,10711
|
159
158
|
edsl/language_models/raw_response_handler.py,sha256=i2Ye1WzjYq_2YJ1EKX946dx9m331GilwqC5qymGJlEI,4003
|
160
159
|
edsl/language_models/registry.py,sha256=io_Cp-7PtLpPuvZs_j8XaMxJiv-zSplbAQdrzPp2pzg,7308
|
161
160
|
edsl/language_models/repair.py,sha256=ljm0xc9e1tMdyKc9b-v7ikpYRBh639xJ11SkDzI2vZE,5245
|
@@ -382,8 +381,8 @@ edsl/utilities/repair_functions.py,sha256=EXkXsqnmgPqj9b3dff1cZnJyaZw-qEvGENXCRH
|
|
382
381
|
edsl/utilities/restricted_python.py,sha256=248N2p5EWHDSpcK1G-q7DUoJeWy4sB6aO-RV0-5O7uY,2038
|
383
382
|
edsl/utilities/template_loader.py,sha256=SCAcnTnxNQ67MNSkmfz7F-S_u2peyGn2j1oRIqi1wfg,870
|
384
383
|
edsl/utilities/utilities.py,sha256=irHheAGOnl_6RwI--Hi9StVzvsHcWCqB48PWsWJQYOw,12045
|
385
|
-
edsl-0.1.
|
386
|
-
edsl-0.1.
|
387
|
-
edsl-0.1.
|
388
|
-
edsl-0.1.
|
389
|
-
edsl-0.1.
|
384
|
+
edsl-0.1.58.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
|
385
|
+
edsl-0.1.58.dist-info/METADATA,sha256=nEQbjRPWHb8aJaKUrfyakIvvXL2qIQyyQsDYa0IToqU,12032
|
386
|
+
edsl-0.1.58.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
387
|
+
edsl-0.1.58.dist-info/entry_points.txt,sha256=JnG7xqMtHaQu9BU-yPATxdyCeA48XJpuclnWCqMfIMU,38
|
388
|
+
edsl-0.1.58.dist-info/RECORD,,
|
@@ -1,78 +0,0 @@
|
|
1
|
-
from typing import Any, Union, TYPE_CHECKING
|
2
|
-
|
3
|
-
if TYPE_CHECKING:
|
4
|
-
from .language_model import LanguageModel
|
5
|
-
|
6
|
-
class ComputeCost:
|
7
|
-
"""Computes the dollar cost of a raw response.
|
8
|
-
|
9
|
-
# TODO: Add doctests
|
10
|
-
>>> True
|
11
|
-
True
|
12
|
-
|
13
|
-
"""
|
14
|
-
def __init__(self, language_model: "LanguageModel"):
|
15
|
-
self.language_model = language_model
|
16
|
-
self._price_lookup = None
|
17
|
-
|
18
|
-
@property
|
19
|
-
def price_lookup(self):
|
20
|
-
if self._price_lookup is None:
|
21
|
-
from ..coop import Coop
|
22
|
-
|
23
|
-
c = Coop()
|
24
|
-
self._price_lookup = c.fetch_prices()
|
25
|
-
return self._price_lookup
|
26
|
-
|
27
|
-
def cost(self, raw_response: dict[str, Any]) -> Union[float, str]:
|
28
|
-
"""Return the dollar cost of a raw response."""
|
29
|
-
|
30
|
-
usage = self.get_usage_dict(raw_response)
|
31
|
-
from ..coop import Coop
|
32
|
-
|
33
|
-
c = Coop()
|
34
|
-
price_lookup = c.fetch_prices()
|
35
|
-
key = (self._inference_service_, self.model)
|
36
|
-
if key not in price_lookup:
|
37
|
-
return f"Could not find price for model {self.model} in the price lookup."
|
38
|
-
|
39
|
-
relevant_prices = price_lookup[key]
|
40
|
-
try:
|
41
|
-
input_tokens = int(usage[self.input_token_name])
|
42
|
-
output_tokens = int(usage[self.output_token_name])
|
43
|
-
except Exception as e:
|
44
|
-
return f"Could not fetch tokens from model response: {e}"
|
45
|
-
|
46
|
-
try:
|
47
|
-
inverse_output_price = relevant_prices["output"]["one_usd_buys"]
|
48
|
-
inverse_input_price = relevant_prices["input"]["one_usd_buys"]
|
49
|
-
except Exception as e:
|
50
|
-
if "output" not in relevant_prices:
|
51
|
-
return f"Could not fetch prices from {relevant_prices} - {e}; Missing 'output' key."
|
52
|
-
if "input" not in relevant_prices:
|
53
|
-
return f"Could not fetch prices from {relevant_prices} - {e}; Missing 'input' key."
|
54
|
-
return f"Could not fetch prices from {relevant_prices} - {e}"
|
55
|
-
|
56
|
-
if inverse_input_price == "infinity":
|
57
|
-
input_cost = 0
|
58
|
-
else:
|
59
|
-
try:
|
60
|
-
input_cost = input_tokens / float(inverse_input_price)
|
61
|
-
except Exception as e:
|
62
|
-
return f"Could not compute input price - {e}."
|
63
|
-
|
64
|
-
if inverse_output_price == "infinity":
|
65
|
-
output_cost = 0
|
66
|
-
else:
|
67
|
-
try:
|
68
|
-
output_cost = output_tokens / float(inverse_output_price)
|
69
|
-
except Exception as e:
|
70
|
-
return f"Could not compute output price - {e}"
|
71
|
-
|
72
|
-
return input_cost + output_cost
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
if __name__ == "__main__":
|
77
|
-
import doctest
|
78
|
-
doctest.testmod()
|
File without changes
|
File without changes
|
File without changes
|