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.
- paygent_sdk/__init__.py +11 -6
- paygent_sdk/client.py +204 -180
- paygent_sdk/constants.py +1913 -256
- paygent_sdk/models.py +57 -479
- paygent_sdk/voice_client.py +209 -176
- paygent_sdk/wrappers/anthropic_wrapper.py +3 -2
- paygent_sdk/wrappers/gemini_wrapper.py +7 -6
- paygent_sdk/wrappers/mistral_wrapper.py +3 -2
- paygent_sdk/wrappers/openai_wrapper.py +7 -6
- {paygent_sdk-3.0.0.dist-info → paygent_sdk-4.0.0.dist-info}/METADATA +1 -1
- paygent_sdk-4.0.0.dist-info/RECORD +22 -0
- {paygent_sdk-3.0.0.dist-info → paygent_sdk-4.0.0.dist-info}/WHEEL +1 -1
- paygent_sdk-3.0.0.dist-info/RECORD +0 -22
- {paygent_sdk-3.0.0.dist-info → paygent_sdk-4.0.0.dist-info}/licenses/LICENSE +0 -0
- {paygent_sdk-3.0.0.dist-info → paygent_sdk-4.0.0.dist-info}/top_level.txt +0 -0
paygent_sdk/voice_client.py
CHANGED
|
@@ -21,251 +21,279 @@ from .constants import (
|
|
|
21
21
|
DeepgramTTSModels,
|
|
22
22
|
ElevenLabsTTSModels,
|
|
23
23
|
)
|
|
24
|
-
from .models import
|
|
24
|
+
from .models import RawUsageData
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
|
|
107
|
-
|
|
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
|
-
|
|
110
|
-
|
|
37
|
+
Raises:
|
|
38
|
+
requests.RequestException: If the request fails
|
|
111
39
|
"""
|
|
112
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
|
60
|
+
def send_tts_usage(client_instance, agent_id: str, customer_id: str, tts_usage_data) -> None:
|
|
134
61
|
"""
|
|
135
|
-
|
|
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
|
-
|
|
140
|
-
|
|
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
|
-
|
|
143
|
-
|
|
70
|
+
Raises:
|
|
71
|
+
requests.RequestException: If the request fails
|
|
144
72
|
"""
|
|
145
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
|
93
|
+
def initialize_voice_session(client_instance, session_id: str, agent_id: str, customer_id: str) -> None:
|
|
167
94
|
"""
|
|
168
|
-
|
|
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.
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
190
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-
|
|
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
|
|
171
|
+
client_instance.logger.error(f"Failed to track voice STT: {str(e)}")
|
|
216
172
|
raise
|
|
217
173
|
|
|
218
174
|
|
|
219
|
-
def
|
|
175
|
+
def track_voice_llm(
|
|
176
|
+
client_instance,
|
|
177
|
+
session_id: str,
|
|
178
|
+
llm_usage_data: dict
|
|
179
|
+
) -> None:
|
|
220
180
|
"""
|
|
221
|
-
|
|
181
|
+
Track LLM usage for a voice session.
|
|
222
182
|
|
|
223
183
|
Args:
|
|
224
184
|
client_instance: The Client instance
|
|
225
|
-
|
|
226
|
-
|
|
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.
|
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
"
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
-
|
|
254
|
-
|
|
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
|
-
|
|
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
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
+
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
|