paygent-sdk 3.0.0__py3-none-any.whl → 4.0.0__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.
@@ -21,251 +21,279 @@ from .constants import (
21
21
  DeepgramTTSModels,
22
22
  ElevenLabsTTSModels,
23
23
  )
24
- from .models import SttModelPricing, TtsModelPricing
24
+ from .models import RawUsageData
25
25
 
26
26
 
27
- # STT model pricing (cost per hour in USD)
28
- STT_MODEL_PRICING: Dict[str, SttModelPricing] = {
29
- # Deepgram Models
30
- DeepgramSTTModels.FLUX: SttModelPricing(cost_per_hour=0.462), # $0.462 per hour
31
- DeepgramSTTModels.NOVA_3_MONOLINGUAL: SttModelPricing(cost_per_hour=0.462), # $0.462 per hour
32
- DeepgramSTTModels.NOVA_3_MULTILINGUAL: SttModelPricing(cost_per_hour=0.552), # $0.552 per hour
33
- DeepgramSTTModels.NOVA_1: SttModelPricing(cost_per_hour=0.348), # $0.348 per hour
34
- DeepgramSTTModels.NOVA_2: SttModelPricing(cost_per_hour=0.348), # $0.348 per hour
35
- DeepgramSTTModels.ENHANCED: SttModelPricing(cost_per_hour=0.99), # $0.99 per hour
36
- DeepgramSTTModels.BASE: SttModelPricing(cost_per_hour=0.87), # $0.87 per hour
37
- DeepgramSTTModels.REDACTION: SttModelPricing(cost_per_hour=0.12), # $0.12 per hour (add-on)
38
- DeepgramSTTModels.KEYTERM_PROMPTING: SttModelPricing(cost_per_hour=0.072), # $0.072 per hour (add-on)
39
- DeepgramSTTModels.SPEAKER_DIARIZATION: SttModelPricing(cost_per_hour=0.12), # $0.12 per hour (add-on)
40
- # Growth tier models
41
- DeepgramSTTModels.GROWTH_NOVA_3_MONOLINGUAL: SttModelPricing(cost_per_hour=0.39), # $0.39 per hour
42
- DeepgramSTTModels.GROWTH_NOVA_3_MULTILINGUAL: SttModelPricing(cost_per_hour=0.468), # $0.468 per hour
43
- DeepgramSTTModels.GROWTH_NOVA_1: SttModelPricing(cost_per_hour=0.282), # $0.282 per hour
44
- DeepgramSTTModels.GROWTH_NOVA_2: SttModelPricing(cost_per_hour=0.282), # $0.282 per hour
45
-
46
- # Microsoft Azure Speech Service Models
47
- MicrosoftAzureSpeechSTTModels.STANDARD: SttModelPricing(cost_per_hour=1.0), # $1.0 per hour
48
- MicrosoftAzureSpeechSTTModels.CUSTOM: SttModelPricing(cost_per_hour=1.2), # $1.2 per hour
49
-
50
- # Google Cloud Speech-to-Text Models
51
- GoogleCloudSpeechSTTModels.STANDARD: SttModelPricing(cost_per_hour=0.96), # $0.96 per hour
52
-
53
- # AssemblyAI Models
54
- AssemblyAISTTModels.UNIVERSAL_STREAMING: SttModelPricing(cost_per_hour=0.15), # $0.15 per hour
55
- AssemblyAISTTModels.UNIVERSAL_STREAMING_MULTILANG: SttModelPricing(cost_per_hour=0.15), # $0.15 per hour
56
- AssemblyAISTTModels.KEYTERMS_PROMPTING: SttModelPricing(cost_per_hour=0.04), # $0.04 per hour
57
-
58
- # Eleven Labs STT Models
59
- ElevenLabsSTTModels.BUSINESS_SCRIBE_V1_V2: SttModelPricing(cost_per_hour=0.22), # $0.22 per hour
60
-
61
- # Soniox STT Models
62
- SonioxSTTModels.REAL_TIME: SttModelPricing(cost_per_hour=0.12), # $0.12 per hour
63
- }
64
-
65
-
66
- # TTS model pricing (cost per 1 million characters in USD)
67
- TTS_MODEL_PRICING: Dict[str, TtsModelPricing] = {
68
- # Amazon Polly Models
69
- AmazonPollyTTSModels.STANDARD: TtsModelPricing(cost_per_million_characters=0.4), # $0.4 per 1 million characters
70
- AmazonPollyTTSModels.NEURAL: TtsModelPricing(cost_per_million_characters=16.0), # $16 per 1 million characters
71
- AmazonPollyTTSModels.LONG_FORM: TtsModelPricing(cost_per_million_characters=100.0), # $100 per 1 million characters
72
- AmazonPollyTTSModels.GENERATIVE: TtsModelPricing(cost_per_million_characters=30.0), # $30 per 1 million characters
73
-
74
- # Microsoft Azure Speech Service TTS Models
75
- MicrosoftAzureSpeechTTSModels.STANDARD_NEURAL: TtsModelPricing(cost_per_million_characters=15.0), # $15 per 1 million characters
76
- MicrosoftAzureSpeechTTSModels.CUSTOM_SYNTHESIS: TtsModelPricing(cost_per_million_characters=24.0), # $24 per 1 million characters
77
- MicrosoftAzureSpeechTTSModels.CUSTOM_SYNTHESIS_NEURAL_HD: TtsModelPricing(cost_per_million_characters=48.0), # $48 per 1 million characters
78
-
79
- # Google Cloud Text-to-Speech TTS Models
80
- GoogleCloudTextToSpeechTTSModels.CHIRP_3_HD: TtsModelPricing(cost_per_million_characters=30.0), # $30 per 1 million characters
81
- GoogleCloudTextToSpeechTTSModels.INSTANT_CUSTOM: TtsModelPricing(cost_per_million_characters=60.0), # $60 per 1 million characters
82
- GoogleCloudTextToSpeechTTSModels.WAVENET: TtsModelPricing(cost_per_million_characters=4.0), # $4 per 1 million characters
83
- GoogleCloudTextToSpeechTTSModels.STUDIO: TtsModelPricing(cost_per_million_characters=160.0), # $160 per 1 million characters
84
- GoogleCloudTextToSpeechTTSModels.STANDARD: TtsModelPricing(cost_per_million_characters=4.0), # $4 per 1 million characters
85
- GoogleCloudTextToSpeechTTSModels.NEURAL2: TtsModelPricing(cost_per_million_characters=16.0), # $16 per 1 million characters
86
- GoogleCloudTextToSpeechTTSModels.POLYGLOT_PREVIEW: TtsModelPricing(cost_per_million_characters=16.0), # $16 per 1 million characters
87
-
88
- # Deepgram TTS Models
89
- DeepgramTTSModels.AURA_2: TtsModelPricing(cost_per_million_characters=30.0), # $30 per 1 million characters
90
- DeepgramTTSModels.AURA_1: TtsModelPricing(cost_per_million_characters=15.0), # $15 per 1 million characters
91
- # Growth tier models
92
- DeepgramTTSModels.GROWTH_AURA_2: TtsModelPricing(cost_per_million_characters=27.0), # $27 per 1 million characters
93
- DeepgramTTSModels.GROWTH_AURA_1: TtsModelPricing(cost_per_million_characters=13.5), # $13.5 per 1 million characters
94
-
95
- # Eleven Labs TTS Models
96
- ElevenLabsTTSModels.BUSINESS_MULTILINGUAL_V2_V3: TtsModelPricing(cost_per_million_characters=120.0), # $120 per 1 million characters
97
- }
98
-
99
-
100
- def _calculate_stt_cost(client_instance, model: str, audio_duration_seconds: int) -> float:
27
+ def send_stt_usage(client_instance, agent_id: str, customer_id: str, stt_usage_data) -> None:
101
28
  """
102
- Calculate the cost based on STT model and audio duration.
29
+ Send STT usage data to the Paygent API using V2 endpoint.
103
30
 
104
31
  Args:
105
32
  client_instance: The Client instance
106
- model: The STT model name
107
- audio_duration_seconds: Audio duration in seconds
33
+ agent_id: Unique identifier for the agent
34
+ customer_id: Unique identifier for the customer
35
+ stt_usage_data: SttUsageData containing model and audio duration information
108
36
 
109
- Returns:
110
- Calculated cost in USD
37
+ Raises:
38
+ requests.RequestException: If the request fails
111
39
  """
112
- pricing = STT_MODEL_PRICING.get(model)
113
-
114
- if not pricing:
115
- client_instance.logger.warning(f"Unknown STT model '{model}', using default pricing")
116
- # Use default pricing for unknown models (per hour)
117
- pricing = SttModelPricing(cost_per_hour=0.5) # $0.50 per hour default
40
+ client_instance.logger.debug(f"Sending STT usage data for model: {stt_usage_data.model}")
118
41
 
119
- # Calculate cost: (duration in seconds / 3600) * cost per hour
120
- # Convert seconds to hours and multiply by cost per hour
121
- duration_hours = audio_duration_seconds / 3600.0
122
- total_cost = duration_hours * pricing.cost_per_hour
123
-
124
- client_instance.logger.debug(
125
- f"STT cost calculation for model '{model}': "
126
- f"duration={audio_duration_seconds} seconds ({duration_hours:.6f} hours), "
127
- f"cost_per_hour={pricing.cost_per_hour:.6f}, total={total_cost:.6f}"
128
- )
129
-
130
- return total_cost
42
+ try:
43
+ from .models import RawUsageData
44
+
45
+ # Use V2 usage tracking for server-side pricing
46
+ raw_usage = RawUsageData(
47
+ provider=stt_usage_data.service_provider,
48
+ model=stt_usage_data.model,
49
+ audio_duration=stt_usage_data.audio_duration
50
+ )
51
+
52
+ client_instance.send_usage_v2(agent_id, customer_id, 'stt-usage', raw_usage)
53
+ client_instance.logger.info('STT usage data sent successfully')
54
+
55
+ except Exception as e:
56
+ client_instance.logger.error(f"Failed to send STT usage data: {str(e)}")
57
+ raise
131
58
 
132
59
 
133
- def _calculate_tts_cost(client_instance, model: str, character_count: int) -> float:
60
+ def send_tts_usage(client_instance, agent_id: str, customer_id: str, tts_usage_data) -> None:
134
61
  """
135
- Calculate the cost based on TTS model and character count.
62
+ Send TTS usage data to the Paygent API using V2 endpoint.
136
63
 
137
64
  Args:
138
65
  client_instance: The Client instance
139
- model: The TTS model name
140
- character_count: Number of characters
66
+ agent_id: Unique identifier for the agent
67
+ customer_id: Unique identifier for the customer
68
+ tts_usage_data: TtsUsageData containing model and character count information
141
69
 
142
- Returns:
143
- Calculated cost in USD
70
+ Raises:
71
+ requests.RequestException: If the request fails
144
72
  """
145
- pricing = TTS_MODEL_PRICING.get(model)
146
-
147
- if not pricing:
148
- client_instance.logger.warning(f"Unknown TTS model '{model}', using default pricing")
149
- # Use default pricing for unknown models (per 1 million characters)
150
- pricing = TtsModelPricing(cost_per_million_characters=10.0) # $10 per 1 million characters default
73
+ client_instance.logger.debug(f"Sending TTS usage data for model: {tts_usage_data.model}")
151
74
 
152
- # Calculate cost: (character count / 1,000,000) * cost per 1 million characters
153
- # Convert character count to millions and multiply by cost per million
154
- characters_in_millions = character_count / 1000000.0
155
- total_cost = characters_in_millions * pricing.cost_per_million_characters
156
-
157
- client_instance.logger.debug(
158
- f"TTS cost calculation for model '{model}': "
159
- f"characters={character_count} ({characters_in_millions:.6f} millions), "
160
- f"cost_per_million={pricing.cost_per_million_characters:.6f}, total={total_cost:.6f}"
161
- )
162
-
163
- return total_cost
75
+ try:
76
+ from .models import RawUsageData
77
+
78
+ # Use V2 usage tracking for server-side pricing
79
+ raw_usage = RawUsageData(
80
+ provider=tts_usage_data.service_provider,
81
+ model=tts_usage_data.model,
82
+ character_count=tts_usage_data.character_count
83
+ )
84
+
85
+ client_instance.send_usage_v2(agent_id, customer_id, 'tts-usage', raw_usage)
86
+ client_instance.logger.info('TTS usage data sent successfully')
87
+
88
+ except Exception as e:
89
+ client_instance.logger.error(f"Failed to send TTS usage data: {str(e)}")
90
+ raise
164
91
 
165
92
 
166
- def send_stt_usage(client_instance, agent_id: str, customer_id: str, stt_usage_data) -> None:
93
+ def initialize_voice_session(client_instance, session_id: str, agent_id: str, customer_id: str) -> None:
167
94
  """
168
- Send STT usage data to the Paygent API.
95
+ Initialize a new voice session.
169
96
 
170
97
  Args:
171
98
  client_instance: The Client instance
99
+ session_id: Unique identifier for the session
172
100
  agent_id: Unique identifier for the agent
173
101
  customer_id: Unique identifier for the customer
174
- stt_usage_data: SttUsageData containing model and audio duration information
175
102
 
176
103
  Raises:
177
104
  requests.RequestException: If the request fails
178
105
  """
179
- client_instance.logger.info(
180
- f"Starting send_stt_usage for agentID={agent_id}, customerID={customer_id}, "
181
- f"model={stt_usage_data.model}, duration={stt_usage_data.audio_duration} seconds"
182
- )
106
+ client_instance.logger.debug(f"Initializing voice session: {session_id}")
183
107
 
184
108
  try:
185
- # Calculate cost
186
- cost = _calculate_stt_cost(client_instance, stt_usage_data.model, stt_usage_data.audio_duration)
187
- client_instance.logger.info(f"Calculated STT cost: {cost:.6f} for model {stt_usage_data.model}")
109
+ url = urljoin(client_instance.base_url, "/api/v1/voice/session")
110
+ headers = {
111
+ "Content-Type": "application/json",
112
+ "paygent-api-key": client_instance.api_key,
113
+ }
188
114
 
189
- # Prepare API request
190
- api_request = {
115
+ request_data = {
116
+ "sessionId": session_id,
191
117
  "agentId": agent_id,
192
118
  "customerId": customer_id,
193
- "indicator": "stt-usage", # Default indicator for STT usage
194
- "amount": cost,
195
- "audioDuration": stt_usage_data.audio_duration,
196
- "model": stt_usage_data.model,
197
- "serviceProvider": stt_usage_data.service_provider,
198
119
  }
199
120
 
200
- # Make HTTP request
201
- url = urljoin(client_instance.base_url, "/api/v1/usage")
121
+ response = client_instance.session.post(url, json=request_data, headers=headers)
122
+ response.raise_for_status()
123
+
124
+ client_instance.logger.info("Voice session initialized successfully")
125
+ except requests.RequestException as e:
126
+ client_instance.logger.error(f"Failed to initialize voice session: {str(e)}")
127
+ raise
128
+
129
+
130
+ def track_voice_stt(
131
+ client_instance,
132
+ session_id: str,
133
+ stt_usage_data: dict
134
+ ) -> None:
135
+ """
136
+ Track STT usage for a voice session.
137
+
138
+ Args:
139
+ client_instance: The Client instance
140
+ session_id: Unique identifier for the session
141
+ stt_usage_data: Dict containing audioDuration, serviceProvider, model, and optional language
142
+
143
+ Raises:
144
+ requests.RequestException: If the request fails
145
+ """
146
+ client_instance.logger.debug(f"Tracking voice STT usage for session: {session_id}")
147
+
148
+ try:
149
+ url = urljoin(client_instance.base_url, "/api/v1/voice/stt")
202
150
  headers = {
203
151
  "Content-Type": "application/json",
204
152
  "paygent-api-key": client_instance.api_key,
205
153
  }
206
154
 
207
- response = client_instance.session.post(url, json=api_request, headers=headers)
155
+ request_data = {
156
+ "sessionId": session_id,
157
+ "audioMinutes": stt_usage_data.get("audioDuration"),
158
+ "provider": stt_usage_data.get("serviceProvider"),
159
+ "model": stt_usage_data.get("model"),
160
+ }
161
+
162
+ # Add optional language field
163
+ if "language" in stt_usage_data:
164
+ request_data["language"] = stt_usage_data["language"]
165
+
166
+ response = client_instance.session.post(url, json=request_data, headers=headers)
208
167
  response.raise_for_status()
209
168
 
210
- client_instance.logger.info(
211
- f"Successfully sent STT usage data for agentID={agent_id}, "
212
- f"customerID={customer_id}, cost={cost:.6f}"
213
- )
169
+ client_instance.logger.info("Voice STT usage tracked successfully")
214
170
  except requests.RequestException as e:
215
- client_instance.logger.error(f"Failed to send STT usage data: {str(e)}")
171
+ client_instance.logger.error(f"Failed to track voice STT: {str(e)}")
216
172
  raise
217
173
 
218
174
 
219
- def send_tts_usage(client_instance, agent_id: str, customer_id: str, tts_usage_data) -> None:
175
+ def track_voice_llm(
176
+ client_instance,
177
+ session_id: str,
178
+ llm_usage_data: dict
179
+ ) -> None:
220
180
  """
221
- Send TTS usage data to the Paygent API.
181
+ Track LLM usage for a voice session.
222
182
 
223
183
  Args:
224
184
  client_instance: The Client instance
225
- agent_id: Unique identifier for the agent
226
- customer_id: Unique identifier for the customer
227
- tts_usage_data: TtsUsageData containing model and character count information
185
+ session_id: Unique identifier for the session
186
+ llm_usage_data: Dict containing serviceProvider, model, promptTokens, completionTokens
228
187
 
229
188
  Raises:
230
189
  requests.RequestException: If the request fails
231
190
  """
232
- client_instance.logger.info(
233
- f"Starting send_tts_usage for agentID={agent_id}, customerID={customer_id}, "
234
- f"model={tts_usage_data.model}, characters={tts_usage_data.character_count}"
235
- )
191
+ client_instance.logger.debug(f"Tracking voice LLM usage for session: {session_id}")
236
192
 
237
193
  try:
238
- # Calculate cost
239
- cost = _calculate_tts_cost(client_instance, tts_usage_data.model, tts_usage_data.character_count)
240
- client_instance.logger.info(f"Calculated TTS cost: {cost:.6f} for model {tts_usage_data.model}")
194
+ url = urljoin(client_instance.base_url, "/api/v1/voice/llm")
195
+ headers = {
196
+ "Content-Type": "application/json",
197
+ "paygent-api-key": client_instance.api_key,
198
+ }
241
199
 
242
- # Prepare API request
243
- api_request = {
244
- "agentId": agent_id,
245
- "customerId": customer_id,
246
- "indicator": "tts-usage", # Default indicator for TTS usage
247
- "amount": cost,
248
- "characterCount": tts_usage_data.character_count,
249
- "model": tts_usage_data.model,
250
- "serviceProvider": tts_usage_data.service_provider,
200
+ request_data = {
201
+ "sessionId": session_id,
202
+ "provider": llm_usage_data.get("serviceProvider"),
203
+ "model": llm_usage_data.get("model"),
204
+ "promptTokens": llm_usage_data.get("promptTokens"),
205
+ "completionTokens": llm_usage_data.get("completionTokens"),
206
+ }
207
+
208
+ response = client_instance.session.post(url, json=request_data, headers=headers)
209
+ response.raise_for_status()
210
+
211
+ client_instance.logger.info("Voice LLM usage tracked successfully")
212
+ except requests.RequestException as e:
213
+ client_instance.logger.error(f"Failed to track voice LLM: {str(e)}")
214
+ raise
215
+
216
+
217
+ def track_voice_tts(
218
+ client_instance,
219
+ session_id: str,
220
+ tts_usage_data: dict
221
+ ) -> None:
222
+ """
223
+ Track TTS usage for a voice session.
224
+
225
+ Args:
226
+ client_instance: The Client instance
227
+ session_id: Unique identifier for the session
228
+ tts_usage_data: Dict containing serviceProvider, model, characterCount
229
+
230
+ Raises:
231
+ requests.RequestException: If the request fails
232
+ """
233
+ client_instance.logger.debug(f"Tracking voice TTS usage for session: {session_id}")
234
+
235
+ try:
236
+ url = urljoin(client_instance.base_url, "/api/v1/voice/tts")
237
+ headers = {
238
+ "Content-Type": "application/json",
239
+ "paygent-api-key": client_instance.api_key,
240
+ }
241
+
242
+ request_data = {
243
+ "sessionId": session_id,
244
+ "provider": tts_usage_data.get("serviceProvider"),
245
+ "model": tts_usage_data.get("model"),
246
+ "characters": tts_usage_data.get("characterCount"),
251
247
  }
252
248
 
253
- # Make HTTP request
254
- url = urljoin(client_instance.base_url, "/api/v1/usage")
249
+ response = client_instance.session.post(url, json=request_data, headers=headers)
250
+ response.raise_for_status()
251
+
252
+ client_instance.logger.info("Voice TTS usage tracked successfully")
253
+ except requests.RequestException as e:
254
+ client_instance.logger.error(f"Failed to track voice TTS: {str(e)}")
255
+ raise
256
+
257
+
258
+ def set_voice_indicator(
259
+ client_instance,
260
+ session_id: str,
261
+ indicator: str,
262
+ total_duration: int
263
+ ) -> None:
264
+ """
265
+ Set an indicator for a voice session with final duration.
266
+
267
+ Args:
268
+ client_instance: The Client instance
269
+ session_id: Unique identifier for the session
270
+ indicator: Indicator for the session
271
+ total_duration: Total duration of the session in seconds
272
+
273
+ Raises:
274
+ requests.RequestException: If the request fails
275
+ """
276
+ client_instance.logger.debug(f"Setting voice indicator: {indicator} for session: {session_id}")
277
+
278
+ try:
279
+ url = urljoin(client_instance.base_url, "/api/v1/voice/indicator")
255
280
  headers = {
256
281
  "Content-Type": "application/json",
257
282
  "paygent-api-key": client_instance.api_key,
258
283
  }
259
284
 
260
- response = client_instance.session.post(url, json=api_request, headers=headers)
285
+ request_data = {
286
+ "sessionId": session_id,
287
+ "indicator": indicator,
288
+ "totalDuration": total_duration,
289
+ }
290
+
291
+ response = client_instance.session.post(url, json=request_data, headers=headers)
261
292
  response.raise_for_status()
262
293
 
263
- client_instance.logger.info(
264
- f"Successfully sent TTS usage data for agentID={agent_id}, "
265
- f"customerID={customer_id}, cost={cost:.6f}"
266
- )
294
+ client_instance.logger.info("Voice indicator set successfully")
267
295
  except requests.RequestException as e:
268
- client_instance.logger.error(f"Failed to send TTS usage data: {str(e)}")
296
+ client_instance.logger.error(f"Failed to set voice indicator: {str(e)}")
269
297
  raise
270
298
 
271
299
 
@@ -276,6 +304,11 @@ def _add_voice_methods_to_client():
276
304
 
277
305
  Client.send_stt_usage = send_stt_usage
278
306
  Client.send_tts_usage = send_tts_usage
307
+ Client.initialize_voice_session = initialize_voice_session
308
+ Client.track_voice_stt = track_voice_stt
309
+ Client.track_voice_llm = track_voice_llm
310
+ Client.track_voice_tts = track_voice_tts
311
+ Client.set_voice_indicator = set_voice_indicator
279
312
 
280
313
 
281
314
  # Call this function to attach methods when module is imported
@@ -16,6 +16,7 @@ except ImportError:
16
16
 
17
17
  from ..client import Client
18
18
  from ..models import UsageData, UsageDataWithStrings
19
+ from ..constants import ServiceProvider
19
20
 
20
21
 
21
22
  class PaygentAnthropic:
@@ -94,7 +95,7 @@ class MessagesWrapper:
94
95
  if has_valid_usage:
95
96
  # Primary path: Use usage data from API response
96
97
  usage_data = UsageData(
97
- service_provider=model,
98
+ service_provider=ServiceProvider.ANTHROPIC,
98
99
  model=model,
99
100
  prompt_tokens=response.usage.input_tokens,
100
101
  completion_tokens=response.usage.output_tokens,
@@ -116,7 +117,7 @@ class MessagesWrapper:
116
117
  output_string = response.content[0].text or ''
117
118
 
118
119
  usage_data_with_strings = UsageDataWithStrings(
119
- service_provider=model,
120
+ service_provider=ServiceProvider.ANTHROPIC,
120
121
  model=model,
121
122
  prompt_string=prompt_string,
122
123
  output_string=output_string
@@ -18,6 +18,7 @@ except ImportError:
18
18
 
19
19
  from ..client import Client
20
20
  from ..models import UsageData, UsageDataWithStrings
21
+ from ..constants import ServiceProvider
21
22
 
22
23
 
23
24
  class PaygentGemini:
@@ -89,7 +90,7 @@ class ModelsWrapper:
89
90
  if has_valid_usage:
90
91
  # Primary path: Use usage metadata from API response
91
92
  usage_data = UsageData(
92
- service_provider=model,
93
+ service_provider=ServiceProvider.GOOGLE,
93
94
  model=model,
94
95
  prompt_tokens=response.usage_metadata.prompt_token_count or 0,
95
96
  completion_tokens=response.usage_metadata.candidates_token_count or 0,
@@ -117,7 +118,7 @@ class ModelsWrapper:
117
118
  output_string = part.text or ''
118
119
 
119
120
  usage_data_with_strings = UsageDataWithStrings(
120
- service_provider=model,
121
+ service_provider=ServiceProvider.GOOGLE,
121
122
  model=model,
122
123
  prompt_string=prompt_string,
123
124
  output_string=output_string
@@ -208,7 +209,7 @@ class ModelsWrapper:
208
209
  if has_valid_usage:
209
210
  # Primary path: Use usage metadata from API response
210
211
  usage_data = UsageData(
211
- service_provider=model,
212
+ service_provider=ServiceProvider.GOOGLE,
212
213
  model=model,
213
214
  prompt_tokens=response.usage_metadata.prompt_token_count or 0,
214
215
  completion_tokens=response.usage_metadata.candidates_token_count or 0,
@@ -224,7 +225,7 @@ class ModelsWrapper:
224
225
  else:
225
226
  # Fallback path: Calculate tokens from prompt string
226
227
  usage_data_with_strings = UsageDataWithStrings(
227
- service_provider=model,
228
+ service_provider=ServiceProvider.GOOGLE,
228
229
  model=model,
229
230
  prompt_string=prompt,
230
231
  output_string='' # Image generation doesn't have text output
@@ -283,7 +284,7 @@ class ChatSessionWrapper:
283
284
  if has_valid_usage:
284
285
  # Primary path: Use usage metadata from API response
285
286
  usage_data = UsageData(
286
- service_provider=self.model_name,
287
+ service_provider=ServiceProvider.GOOGLE,
287
288
  model=self.model_name,
288
289
  prompt_tokens=response.usage_metadata.prompt_token_count or 0,
289
290
  completion_tokens=response.usage_metadata.candidates_token_count or 0,
@@ -309,7 +310,7 @@ class ChatSessionWrapper:
309
310
  output_string = part.text or ''
310
311
 
311
312
  usage_data_with_strings = UsageDataWithStrings(
312
- service_provider=self.model_name,
313
+ service_provider=ServiceProvider.GOOGLE,
313
314
  model=self.model_name,
314
315
  prompt_string=message,
315
316
  output_string=output_string
@@ -16,6 +16,7 @@ except ImportError:
16
16
 
17
17
  from ..client import Client
18
18
  from ..models import UsageData, UsageDataWithStrings
19
+ from ..constants import ServiceProvider
19
20
 
20
21
 
21
22
  class PaygentMistral:
@@ -88,7 +89,7 @@ class ChatWrapper:
88
89
  if has_valid_usage:
89
90
  # Primary path: Use usage data from API response
90
91
  usage_data = UsageData(
91
- service_provider=model,
92
+ service_provider=ServiceProvider.MISTRAL_AI,
92
93
  model=model,
93
94
  prompt_tokens=response.usage.prompt_tokens,
94
95
  completion_tokens=response.usage.completion_tokens,
@@ -112,7 +113,7 @@ class ChatWrapper:
112
113
  output_string = choice.message.content or ''
113
114
 
114
115
  usage_data_with_strings = UsageDataWithStrings(
115
- service_provider=model,
116
+ service_provider=ServiceProvider.MISTRAL_AI,
116
117
  model=model,
117
118
  prompt_string=prompt_string,
118
119
  output_string=output_string
@@ -16,6 +16,7 @@ except ImportError:
16
16
 
17
17
  from ..client import Client
18
18
  from ..models import UsageData, UsageDataWithStrings
19
+ from ..constants import ServiceProvider
19
20
 
20
21
 
21
22
  class PaygentOpenAI:
@@ -121,7 +122,7 @@ class ChatCompletionsWrapper:
121
122
  cached_tokens = prompt_details.cached_tokens
122
123
 
123
124
  usage_data = UsageData(
124
- service_provider=model,
125
+ service_provider=ServiceProvider.OPENAI,
125
126
  model=model,
126
127
  prompt_tokens=response.usage.prompt_tokens,
127
128
  completion_tokens=response.usage.completion_tokens,
@@ -145,7 +146,7 @@ class ChatCompletionsWrapper:
145
146
  output_string = response.choices[0].message.content or ''
146
147
 
147
148
  usage_data_with_strings = UsageDataWithStrings(
148
- service_provider=model,
149
+ service_provider=ServiceProvider.OPENAI,
149
150
  model=model,
150
151
  prompt_string=prompt_string,
151
152
  output_string=output_string
@@ -209,7 +210,7 @@ class EmbeddingsWrapper:
209
210
  if has_valid_usage:
210
211
  # Primary path: Use usage data from API response
211
212
  usage_data = UsageData(
212
- service_provider=model,
213
+ service_provider=ServiceProvider.OPENAI,
213
214
  model=model,
214
215
  prompt_tokens=response.usage.prompt_tokens,
215
216
  completion_tokens=response.usage.prompt_tokens, # Embeddings don't have completion tokens
@@ -231,7 +232,7 @@ class EmbeddingsWrapper:
231
232
  input_text = str(input)
232
233
 
233
234
  usage_data_with_strings = UsageDataWithStrings(
234
- service_provider=model,
235
+ service_provider=ServiceProvider.OPENAI,
235
236
  model=model,
236
237
  prompt_string=input_text,
237
238
  output_string='' # Embeddings don't have output
@@ -297,8 +298,8 @@ class ImagesWrapper:
297
298
  # For image generation, we'll use a simplified usage tracking
298
299
  # since OpenAI doesn't provide token counts for images
299
300
  usage_data = UsageData(
300
- service_provider=model,
301
- model=model,
301
+ service_provider=ServiceProvider.OPENAI,
302
+ model=model if model else 'dall-e-2',
302
303
  prompt_tokens=0, # Images don't use traditional tokens
303
304
  completion_tokens=0,
304
305
  total_tokens=0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: paygent-sdk
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: Official Python SDK for Paygent - Track AI usage and costs across multiple providers (OpenAI, Anthropic, Google, DeepSeek, etc.)
5
5
  Home-page: https://github.com/paygent/paygent-sdk-python
6
6
  Author: Paygent