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.
@@ -19,56 +19,12 @@ class ResponseCost:
19
19
  total_cost: Union[float, str, None] = None
20
20
 
21
21
 
22
- class PriceManager:
23
- _instance = None
24
- _price_lookup: Dict[Tuple[str, str], Dict] = {}
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 refresh_prices(self) -> None:
64
- """Fetch fresh prices and update the internal price lookup."""
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
- default_price_info = {
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": 1.0,
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 = default_price_info
112
- output_price_info = default_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.56
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 (>=0.9.0,<0.10.0)
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=sAxmq9B-f2SmXYi2UsleAKRrYxtQcxVilh7UIDB0-yM,23
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=cf7E8PaTi3jcgPXGtpIsx2x8AM-TxGXNfcw8zrjUoFs,65537
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=N8RvZc-PZvz78sJJvyEW_66smWI3f4AlG5iJjoQ-_ZA,6530
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=Vgc6UVnzRdln_ZrxxcZVDGC7B0u_cQOQHpaJ0I2TWvo,10201
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=4ouDnUWFsDQGl51wy95HsDHBYU8RyWRmvHE8WZ_Qfjw,20670
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=u7LHxCH5DF1rJvPkjjAQxlxu58m1qoAyHi8sIFtZM4U,16828
140
- edsl/jobs/jobs_remote_inference_logger.py,sha256=2v3uxkq2UA10UEiwTFGAaC7ekYC0M0UGK3U67WvATpk,9325
141
- edsl/jobs/jobs_runner_status.py,sha256=ME0v4TTH7qzS4vOROGtNKaWqHZmhzrCl_-FeTRSa9C8,10701
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=J9lLFy7JZR4SkXfzBreT4qhPFeuQip_Qvo03Z9a0upg,14630
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=9ZKmt_v0cPAUkonNegrlh2h-1ixtnjonGZCcsFpmEz0,44630
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=GXNjD5NjutD44vZ2FRdQ7ayJWiuxkisETlX7UNGfpIk,9505
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.56.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
386
- edsl-0.1.56.dist-info/METADATA,sha256=9pPRI9zdy9a7TGVJmANKNXiiEFuyPtUPMxMTYYLEd4Y,12039
387
- edsl-0.1.56.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
388
- edsl-0.1.56.dist-info/entry_points.txt,sha256=JnG7xqMtHaQu9BU-yPATxdyCeA48XJpuclnWCqMfIMU,38
389
- edsl-0.1.56.dist-info/RECORD,,
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