paygent-sdk 2.0.0__tar.gz → 3.0.0__tar.gz
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-2.0.0/paygent_sdk.egg-info → paygent_sdk-3.0.0}/PKG-INFO +1 -1
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/__init__.py +30 -18
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/client.py +33 -3
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/constants.py +40 -3
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/models.py +28 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/voice_client.py +23 -3
- paygent_sdk-3.0.0/paygent_sdk/wrappers/__init__.py +44 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/wrappers/openai_wrapper.py +9 -1
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0/paygent_sdk.egg-info}/PKG-INFO +1 -1
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/pyproject.toml +1 -1
- paygent_sdk-2.0.0/paygent_sdk/wrappers/__init__.py +0 -30
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/LICENSE +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/MANIFEST.in +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/README.md +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/examples/__init__.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/examples/advanced_usage.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/examples/basic_usage.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/examples/constants_usage.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/wrappers/anthropic_wrapper.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/wrappers/gemini_wrapper.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/wrappers/langchain_wrapper.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk/wrappers/mistral_wrapper.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk.egg-info/SOURCES.txt +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk.egg-info/dependency_links.txt +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk.egg-info/requires.txt +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/paygent_sdk.egg-info/top_level.txt +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/requirements.txt +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/setup.cfg +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/setup.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/tests/__init__.py +0 -0
- {paygent_sdk-2.0.0 → paygent_sdk-3.0.0}/tests/test_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: paygent-sdk
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.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
|
|
@@ -13,24 +13,11 @@ from .models import (
|
|
|
13
13
|
)
|
|
14
14
|
from .voice_client import send_stt_usage, send_tts_usage # Import to attach methods to Client
|
|
15
15
|
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
PaygentMistral,
|
|
22
|
-
PaygentGemini,
|
|
23
|
-
PaygentLangChainCallback
|
|
24
|
-
)
|
|
25
|
-
_has_langchain = True
|
|
26
|
-
except ImportError:
|
|
27
|
-
from .wrappers import (
|
|
28
|
-
PaygentOpenAI,
|
|
29
|
-
PaygentAnthropic,
|
|
30
|
-
PaygentMistral,
|
|
31
|
-
PaygentGemini
|
|
32
|
-
)
|
|
33
|
-
_has_langchain = False
|
|
16
|
+
# Wrappers are lazily imported in the wrappers module to avoid requiring
|
|
17
|
+
# installation of peer dependencies (openai, anthropic, mistral, etc.) that aren't being used.
|
|
18
|
+
# You can still import them normally:
|
|
19
|
+
# from paygent_sdk import PaygentOpenAI, PaygentGemini, etc.
|
|
20
|
+
# But they will only actually load when first accessed.
|
|
34
21
|
from .constants import (
|
|
35
22
|
ServiceProvider,
|
|
36
23
|
OpenAIModels,
|
|
@@ -41,14 +28,18 @@ from .constants import (
|
|
|
41
28
|
MistralAIModels,
|
|
42
29
|
CohereModels,
|
|
43
30
|
DeepSeekModels,
|
|
31
|
+
MoonshotAIModels,
|
|
44
32
|
DeepgramSTTModels,
|
|
45
33
|
MicrosoftAzureSpeechSTTModels,
|
|
46
34
|
GoogleCloudSpeechSTTModels,
|
|
47
35
|
AssemblyAISTTModels,
|
|
36
|
+
ElevenLabsSTTModels,
|
|
37
|
+
SonioxSTTModels,
|
|
48
38
|
AmazonPollyTTSModels,
|
|
49
39
|
MicrosoftAzureSpeechTTSModels,
|
|
50
40
|
GoogleCloudTextToSpeechTTSModels,
|
|
51
41
|
DeepgramTTSModels,
|
|
42
|
+
ElevenLabsTTSModels,
|
|
52
43
|
is_model_supported
|
|
53
44
|
)
|
|
54
45
|
|
|
@@ -84,17 +75,38 @@ __all__ = [
|
|
|
84
75
|
"MistralAIModels",
|
|
85
76
|
"CohereModels",
|
|
86
77
|
"DeepSeekModels",
|
|
78
|
+
"MoonshotAIModels",
|
|
87
79
|
|
|
88
80
|
# STT/TTS Model constants
|
|
89
81
|
"DeepgramSTTModels",
|
|
90
82
|
"MicrosoftAzureSpeechSTTModels",
|
|
91
83
|
"GoogleCloudSpeechSTTModels",
|
|
92
84
|
"AssemblyAISTTModels",
|
|
85
|
+
"ElevenLabsSTTModels",
|
|
86
|
+
"SonioxSTTModels",
|
|
93
87
|
"AmazonPollyTTSModels",
|
|
94
88
|
"MicrosoftAzureSpeechTTSModels",
|
|
95
89
|
"GoogleCloudTextToSpeechTTSModels",
|
|
96
90
|
"DeepgramTTSModels",
|
|
91
|
+
"ElevenLabsTTSModels",
|
|
97
92
|
|
|
98
93
|
# Utility functions
|
|
99
94
|
"is_model_supported"
|
|
100
95
|
]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def __getattr__(name):
|
|
99
|
+
"""
|
|
100
|
+
Lazy import wrapper classes to avoid requiring peer dependencies that aren't being used.
|
|
101
|
+
|
|
102
|
+
This allows importing wrappers like:
|
|
103
|
+
from paygent_sdk import PaygentOpenAI
|
|
104
|
+
|
|
105
|
+
But the actual import only happens when accessed, so if you never use PaygentOpenAI,
|
|
106
|
+
you don't need the openai package installed.
|
|
107
|
+
"""
|
|
108
|
+
if name in ["PaygentOpenAI", "PaygentAnthropic", "PaygentMistral", "PaygentGemini", "PaygentLangChainCallback"]:
|
|
109
|
+
from . import wrappers
|
|
110
|
+
return getattr(wrappers, name)
|
|
111
|
+
|
|
112
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
@@ -101,12 +101,25 @@ class Client:
|
|
|
101
101
|
|
|
102
102
|
# Calculate cost per 1000 tokens
|
|
103
103
|
prompt_cost = (usage_data.prompt_tokens / 1000.0) * pricing.prompt_tokens_cost
|
|
104
|
+
|
|
105
|
+
# Handle cached tokens: if model doesn't support caching (cached_tokens_cost is None),
|
|
106
|
+
# bill cached tokens at regular prompt token rate
|
|
107
|
+
cached_cost = 0.0
|
|
108
|
+
if usage_data.cached_tokens and usage_data.cached_tokens > 0:
|
|
109
|
+
if pricing.cached_tokens_cost is not None:
|
|
110
|
+
# Model supports caching - use cached token price
|
|
111
|
+
cached_cost = (usage_data.cached_tokens / 1000.0) * pricing.cached_tokens_cost
|
|
112
|
+
else:
|
|
113
|
+
# Model doesn't support caching - bill at prompt token rate
|
|
114
|
+
cached_cost = (usage_data.cached_tokens / 1000.0) * pricing.prompt_tokens_cost
|
|
115
|
+
|
|
104
116
|
completion_cost = (usage_data.completion_tokens / 1000.0) * pricing.completion_tokens_cost
|
|
105
|
-
total_cost = prompt_cost + completion_cost
|
|
117
|
+
total_cost = prompt_cost + cached_cost + completion_cost
|
|
106
118
|
|
|
107
119
|
self.logger.debug(
|
|
108
120
|
f"Cost calculation for model '{model}': "
|
|
109
121
|
f"prompt_tokens={usage_data.prompt_tokens} ({prompt_cost:.6f}), "
|
|
122
|
+
f"cached_tokens={usage_data.cached_tokens or 0} ({cached_cost:.6f}), "
|
|
110
123
|
f"completion_tokens={usage_data.completion_tokens} ({completion_cost:.6f}), "
|
|
111
124
|
f"total={total_cost:.6f}"
|
|
112
125
|
)
|
|
@@ -135,9 +148,25 @@ class Client:
|
|
|
135
148
|
"""
|
|
136
149
|
# Removed verbose logging - only log errors
|
|
137
150
|
|
|
151
|
+
# 🎯 AUTOMATIC CACHED TOKEN HANDLING
|
|
152
|
+
# Users can pass total prompt tokens - we automatically subtract cached tokens
|
|
153
|
+
# This makes manual tracking easier (no math required!)
|
|
154
|
+
cached_tokens = usage_data.cached_tokens or 0
|
|
155
|
+
regular_prompt_tokens = usage_data.prompt_tokens - cached_tokens
|
|
156
|
+
|
|
157
|
+
# Calculate cost using separated token counts
|
|
158
|
+
adjusted_usage_data = UsageData(
|
|
159
|
+
service_provider=usage_data.service_provider,
|
|
160
|
+
model=usage_data.model,
|
|
161
|
+
prompt_tokens=regular_prompt_tokens,
|
|
162
|
+
completion_tokens=usage_data.completion_tokens,
|
|
163
|
+
total_tokens=usage_data.total_tokens,
|
|
164
|
+
cached_tokens=cached_tokens
|
|
165
|
+
)
|
|
166
|
+
|
|
138
167
|
# Calculate cost
|
|
139
168
|
try:
|
|
140
|
-
cost = self._calculate_cost(usage_data.model,
|
|
169
|
+
cost = self._calculate_cost(usage_data.model, adjusted_usage_data)
|
|
141
170
|
except Exception as e:
|
|
142
171
|
self.logger.error(f"Failed to calculate cost: {e}")
|
|
143
172
|
raise ValueError(f"Failed to calculate cost: {e}") from e
|
|
@@ -158,7 +187,8 @@ class Client:
|
|
|
158
187
|
"customerId": api_request.customer_id,
|
|
159
188
|
"indicator": api_request.indicator,
|
|
160
189
|
"amount": api_request.amount,
|
|
161
|
-
"inputToken":
|
|
190
|
+
"inputToken": regular_prompt_tokens, # Send non-cached tokens
|
|
191
|
+
"cachedToken": cached_tokens, # Send cached tokens separately
|
|
162
192
|
"outputToken": usage_data.completion_tokens,
|
|
163
193
|
"model": usage_data.model,
|
|
164
194
|
"serviceProvider": usage_data.service_provider
|
|
@@ -18,6 +18,7 @@ class ServiceProvider:
|
|
|
18
18
|
MISTRAL_AI = "Mistral AI"
|
|
19
19
|
COHERE = "Cohere"
|
|
20
20
|
DEEPSEEK = "DeepSeek"
|
|
21
|
+
MOONSHOT_AI = "Moonshot AI"
|
|
21
22
|
CUSTOM = "Custom"
|
|
22
23
|
|
|
23
24
|
# STT Service Providers
|
|
@@ -25,12 +26,15 @@ class ServiceProvider:
|
|
|
25
26
|
MICROSOFT_AZURE_SPEECH = "Microsoft Azure Speech Service"
|
|
26
27
|
GOOGLE_CLOUD_SPEECH = "Google Cloud Speech-to-Text"
|
|
27
28
|
ASSEMBLY_AI = "AssemblyAI"
|
|
29
|
+
ELEVEN_LABS_STT = "Eleven Labs STT"
|
|
30
|
+
SONIOX = "Soniox"
|
|
28
31
|
|
|
29
32
|
# TTS Service Providers
|
|
30
33
|
AMAZON_POLLY = "Amazon Polly"
|
|
31
34
|
MICROSOFT_AZURE_SPEECH_TTS = "Microsoft Azure Speech Service"
|
|
32
35
|
GOOGLE_CLOUD_TEXT_TO_SPEECH = "Google Cloud Text-to-Speech"
|
|
33
36
|
DEEPGRAM_TTS = "Deepgram"
|
|
37
|
+
ELEVEN_LABS_TTS = "Eleven Labs TTS"
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
# OpenAI Models
|
|
@@ -210,6 +214,13 @@ class DeepSeekModels:
|
|
|
210
214
|
DEEPSEEK_V3_2_EXP = "DeepSeek V3.2-Exp"
|
|
211
215
|
|
|
212
216
|
|
|
217
|
+
# Moonshot AI Models
|
|
218
|
+
class MoonshotAIModels:
|
|
219
|
+
"""Moonshot AI / Kimi model constants."""
|
|
220
|
+
KIMI_K2_INSTRUCT_0905 = "Kimi k2-instruct-0905"
|
|
221
|
+
KIMI_K2_0905_1T_256K = "Kimi k2-0905-1T-256K"
|
|
222
|
+
|
|
223
|
+
|
|
213
224
|
|
|
214
225
|
|
|
215
226
|
|
|
@@ -227,6 +238,11 @@ class DeepgramSTTModels:
|
|
|
227
238
|
REDACTION = "Redaction (Add-on)"
|
|
228
239
|
KEYTERM_PROMPTING = "Keyterm Prompting (Add-on)"
|
|
229
240
|
SPEAKER_DIARIZATION = "Speaker Diarization (Add-on)"
|
|
241
|
+
# Growth tier models
|
|
242
|
+
GROWTH_NOVA_3_MONOLINGUAL = "Growth Nova-3 (Monolingual)"
|
|
243
|
+
GROWTH_NOVA_3_MULTILINGUAL = "Growth Nova-3 (Multilingual)"
|
|
244
|
+
GROWTH_NOVA_1 = "Growth Nova-1"
|
|
245
|
+
GROWTH_NOVA_2 = "Growth Nova-2"
|
|
230
246
|
|
|
231
247
|
|
|
232
248
|
# Microsoft Azure Speech Service STT Models
|
|
@@ -250,6 +266,18 @@ class AssemblyAISTTModels:
|
|
|
250
266
|
KEYTERMS_PROMPTING = "Keyterms Prompting"
|
|
251
267
|
|
|
252
268
|
|
|
269
|
+
# Eleven Labs STT Models
|
|
270
|
+
class ElevenLabsSTTModels:
|
|
271
|
+
"""Eleven Labs STT model constants."""
|
|
272
|
+
BUSINESS_SCRIBE_V1_V2 = "Eleven Labs Business Scribe V1/V2"
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# Soniox STT Models
|
|
276
|
+
class SonioxSTTModels:
|
|
277
|
+
"""Soniox STT model constants."""
|
|
278
|
+
REAL_TIME = "Soniox Real Time"
|
|
279
|
+
|
|
280
|
+
|
|
253
281
|
# Amazon Polly TTS Models
|
|
254
282
|
class AmazonPollyTTSModels:
|
|
255
283
|
"""Amazon Polly TTS model constants."""
|
|
@@ -262,9 +290,9 @@ class AmazonPollyTTSModels:
|
|
|
262
290
|
# Microsoft Azure Speech Service TTS Models
|
|
263
291
|
class MicrosoftAzureSpeechTTSModels:
|
|
264
292
|
"""Microsoft Azure Speech Service TTS model constants."""
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
293
|
+
STANDARD_NEURAL = "Azure TTS Standard Neural"
|
|
294
|
+
CUSTOM_SYNTHESIS = "Azure TTS Custom Synthesis"
|
|
295
|
+
CUSTOM_SYNTHESIS_NEURAL_HD = "Azure TTS Custom Synthesis Neural HD"
|
|
268
296
|
|
|
269
297
|
|
|
270
298
|
# Google Cloud Text-to-Speech TTS Models
|
|
@@ -284,6 +312,15 @@ class DeepgramTTSModels:
|
|
|
284
312
|
"""Deepgram TTS model constants."""
|
|
285
313
|
AURA_2 = "Deepgram Aura-2"
|
|
286
314
|
AURA_1 = "Deepgram Aura-1"
|
|
315
|
+
# Growth tier models
|
|
316
|
+
GROWTH_AURA_2 = "Deepgram Growth Aura-2"
|
|
317
|
+
GROWTH_AURA_1 = "Deepgram Growth Aura-1"
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
# Eleven Labs TTS Models
|
|
321
|
+
class ElevenLabsTTSModels:
|
|
322
|
+
"""Eleven Labs TTS model constants."""
|
|
323
|
+
BUSINESS_MULTILINGUAL_V2_V3 = "Eleven Labs Business Multilingual V2/V3"
|
|
287
324
|
|
|
288
325
|
|
|
289
326
|
def is_model_supported(model: str) -> bool:
|
|
@@ -15,6 +15,7 @@ from .constants import (
|
|
|
15
15
|
MistralAIModels,
|
|
16
16
|
CohereModels,
|
|
17
17
|
DeepSeekModels,
|
|
18
|
+
MoonshotAIModels,
|
|
18
19
|
)
|
|
19
20
|
|
|
20
21
|
|
|
@@ -26,6 +27,7 @@ class UsageData:
|
|
|
26
27
|
prompt_tokens: int
|
|
27
28
|
completion_tokens: int
|
|
28
29
|
total_tokens: int
|
|
30
|
+
cached_tokens: Optional[int] = None # Optional cached tokens
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
@dataclass
|
|
@@ -51,6 +53,7 @@ class ModelPricing:
|
|
|
51
53
|
"""Represents pricing information for different models."""
|
|
52
54
|
prompt_tokens_cost: float
|
|
53
55
|
completion_tokens_cost: float
|
|
56
|
+
cached_tokens_cost: Optional[float] = None # Optional cached token cost (if None, model doesn't support caching)
|
|
54
57
|
|
|
55
58
|
|
|
56
59
|
@dataclass
|
|
@@ -86,22 +89,27 @@ MODEL_PRICING: Dict[str, ModelPricing] = {
|
|
|
86
89
|
# OpenAI Models (pricing per 1000 tokens)
|
|
87
90
|
OpenAIModels.GPT_5: ModelPricing(
|
|
88
91
|
prompt_tokens_cost=0.00125, # $0.00125 per 1000 tokens
|
|
92
|
+
cached_tokens_cost=0.000125, # 90% discount for cached tokens
|
|
89
93
|
completion_tokens_cost=0.01 # $0.01 per 1000 tokens
|
|
90
94
|
),
|
|
91
95
|
OpenAIModels.GPT_5_MINI: ModelPricing(
|
|
92
96
|
prompt_tokens_cost=0.00025, # $0.00025 per 1000 tokens
|
|
97
|
+
cached_tokens_cost=0.000025, # 90% discount for cached tokens
|
|
93
98
|
completion_tokens_cost=0.002 # $0.002 per 1000 tokens
|
|
94
99
|
),
|
|
95
100
|
OpenAIModels.GPT_5_NANO: ModelPricing(
|
|
96
101
|
prompt_tokens_cost=0.00005, # $0.00005 per 1000 tokens
|
|
102
|
+
cached_tokens_cost=0.000005, # 90% discount for cached tokens
|
|
97
103
|
completion_tokens_cost=0.0004 # $0.0004 per 1000 tokens
|
|
98
104
|
),
|
|
99
105
|
OpenAIModels.GPT_5_CHAT_LATEST: ModelPricing(
|
|
100
106
|
prompt_tokens_cost=0.00125, # $0.00125 per 1000 tokens
|
|
107
|
+
cached_tokens_cost=0.000125, # 90% discount for cached tokens
|
|
101
108
|
completion_tokens_cost=0.01 # $0.01 per 1000 tokens
|
|
102
109
|
),
|
|
103
110
|
OpenAIModels.GPT_5_CODEX: ModelPricing(
|
|
104
111
|
prompt_tokens_cost=0.00125, # $0.00125 per 1000 tokens
|
|
112
|
+
cached_tokens_cost=0.000125, # 90% discount for cached tokens
|
|
105
113
|
completion_tokens_cost=0.01 # $0.01 per 1000 tokens
|
|
106
114
|
),
|
|
107
115
|
OpenAIModels.GPT_5_PRO: ModelPricing(
|
|
@@ -114,26 +122,32 @@ MODEL_PRICING: Dict[str, ModelPricing] = {
|
|
|
114
122
|
),
|
|
115
123
|
OpenAIModels.GPT_4_1: ModelPricing(
|
|
116
124
|
prompt_tokens_cost=0.002, # $0.002 per 1000 tokens
|
|
125
|
+
cached_tokens_cost=0.0005, # 50% discount for cached tokens
|
|
117
126
|
completion_tokens_cost=0.008 # $0.008 per 1000 tokens
|
|
118
127
|
),
|
|
119
128
|
OpenAIModels.GPT_4_1_MINI: ModelPricing(
|
|
120
129
|
prompt_tokens_cost=0.0004, # $0.0004 per 1000 tokens
|
|
130
|
+
cached_tokens_cost=0.0001, # 50% discount for cached tokens
|
|
121
131
|
completion_tokens_cost=0.0016 # $0.0016 per 1000 tokens
|
|
122
132
|
),
|
|
123
133
|
OpenAIModels.GPT_4_1_NANO: ModelPricing(
|
|
124
134
|
prompt_tokens_cost=0.0001, # $0.0001 per 1000 tokens
|
|
135
|
+
cached_tokens_cost=0.000025, # 50% discount for cached tokens
|
|
125
136
|
completion_tokens_cost=0.0004 # $0.0004 per 1000 tokens
|
|
126
137
|
),
|
|
127
138
|
OpenAIModels.GPT_4O: ModelPricing(
|
|
128
139
|
prompt_tokens_cost=0.0025, # $0.0025 per 1000 tokens
|
|
140
|
+
cached_tokens_cost=0.00125, # 50% discount for cached tok
|
|
129
141
|
completion_tokens_cost=0.01 # $0.01 per 1000 tokens
|
|
130
142
|
),
|
|
131
143
|
OpenAIModels.GPT_4O_2024_05_13: ModelPricing(
|
|
132
144
|
prompt_tokens_cost=0.005, # $0.005 per 1000 tokens
|
|
145
|
+
cached_tokens_cost=0.0025, # 50% discount for cached tokens
|
|
133
146
|
completion_tokens_cost=0.015 # $0.015 per 1000 tokens
|
|
134
147
|
),
|
|
135
148
|
OpenAIModels.GPT_4O_MINI: ModelPricing(
|
|
136
149
|
prompt_tokens_cost=0.00015, # $0.00015 per 1000 tokens
|
|
150
|
+
cached_tokens_cost=0.000075, # 50% discount for cached tokens
|
|
137
151
|
completion_tokens_cost=0.0006 # $0.0006 per 1000 tokens
|
|
138
152
|
),
|
|
139
153
|
OpenAIModels.GPT_REALTIME: ModelPricing(
|
|
@@ -146,10 +160,12 @@ MODEL_PRICING: Dict[str, ModelPricing] = {
|
|
|
146
160
|
),
|
|
147
161
|
OpenAIModels.GPT_4O_REALTIME_PREVIEW: ModelPricing(
|
|
148
162
|
prompt_tokens_cost=0.005, # $0.005 per 1000 tokens
|
|
163
|
+
cached_tokens_cost=0.0025, # 50% discount for cached tokens
|
|
149
164
|
completion_tokens_cost=0.02 # $0.02 per 1000 tokens
|
|
150
165
|
),
|
|
151
166
|
OpenAIModels.GPT_4O_MINI_REALTIME_PREVIEW: ModelPricing(
|
|
152
167
|
prompt_tokens_cost=0.0006, # $0.0006 per 1000 tokens
|
|
168
|
+
cached_tokens_cost=0.0003, # 50% discount for cached tokens
|
|
153
169
|
completion_tokens_cost=0.0024 # $0.0024 per 1000 tokens
|
|
154
170
|
),
|
|
155
171
|
OpenAIModels.GPT_AUDIO: ModelPricing(
|
|
@@ -510,4 +526,16 @@ MODEL_PRICING: Dict[str, ModelPricing] = {
|
|
|
510
526
|
prompt_tokens_cost=0.000028, # $0.000028 per 1000 tokens
|
|
511
527
|
completion_tokens_cost=0.00042 # $0.00042 per 1000 tokens
|
|
512
528
|
),
|
|
529
|
+
|
|
530
|
+
# Moonshot AI / Kimi Models (pricing per 1000 tokens)
|
|
531
|
+
MoonshotAIModels.KIMI_K2_INSTRUCT_0905: ModelPricing(
|
|
532
|
+
prompt_tokens_cost=0.001, # $0.001 per 1000 tokens
|
|
533
|
+
cached_tokens_cost=0.0005, # $0.0005 per 1000 tokens (as specified)
|
|
534
|
+
completion_tokens_cost=0.003 # $0.003 per 1000 tokens
|
|
535
|
+
),
|
|
536
|
+
MoonshotAIModels.KIMI_K2_0905_1T_256K: ModelPricing(
|
|
537
|
+
prompt_tokens_cost=0.001, # $0.001 per 1000 tokens
|
|
538
|
+
# cached_tokens_cost not specified - model doesn't support cached tokens
|
|
539
|
+
completion_tokens_cost=0.003 # $0.003 per 1000 tokens
|
|
540
|
+
),
|
|
513
541
|
}
|
|
@@ -13,10 +13,13 @@ from .constants import (
|
|
|
13
13
|
MicrosoftAzureSpeechSTTModels,
|
|
14
14
|
GoogleCloudSpeechSTTModels,
|
|
15
15
|
AssemblyAISTTModels,
|
|
16
|
+
ElevenLabsSTTModels,
|
|
17
|
+
SonioxSTTModels,
|
|
16
18
|
AmazonPollyTTSModels,
|
|
17
19
|
MicrosoftAzureSpeechTTSModels,
|
|
18
20
|
GoogleCloudTextToSpeechTTSModels,
|
|
19
21
|
DeepgramTTSModels,
|
|
22
|
+
ElevenLabsTTSModels,
|
|
20
23
|
)
|
|
21
24
|
from .models import SttModelPricing, TtsModelPricing
|
|
22
25
|
|
|
@@ -34,6 +37,11 @@ STT_MODEL_PRICING: Dict[str, SttModelPricing] = {
|
|
|
34
37
|
DeepgramSTTModels.REDACTION: SttModelPricing(cost_per_hour=0.12), # $0.12 per hour (add-on)
|
|
35
38
|
DeepgramSTTModels.KEYTERM_PROMPTING: SttModelPricing(cost_per_hour=0.072), # $0.072 per hour (add-on)
|
|
36
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
|
|
37
45
|
|
|
38
46
|
# Microsoft Azure Speech Service Models
|
|
39
47
|
MicrosoftAzureSpeechSTTModels.STANDARD: SttModelPricing(cost_per_hour=1.0), # $1.0 per hour
|
|
@@ -46,6 +54,12 @@ STT_MODEL_PRICING: Dict[str, SttModelPricing] = {
|
|
|
46
54
|
AssemblyAISTTModels.UNIVERSAL_STREAMING: SttModelPricing(cost_per_hour=0.15), # $0.15 per hour
|
|
47
55
|
AssemblyAISTTModels.UNIVERSAL_STREAMING_MULTILANG: SttModelPricing(cost_per_hour=0.15), # $0.15 per hour
|
|
48
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
|
|
49
63
|
}
|
|
50
64
|
|
|
51
65
|
|
|
@@ -58,9 +72,9 @@ TTS_MODEL_PRICING: Dict[str, TtsModelPricing] = {
|
|
|
58
72
|
AmazonPollyTTSModels.GENERATIVE: TtsModelPricing(cost_per_million_characters=30.0), # $30 per 1 million characters
|
|
59
73
|
|
|
60
74
|
# Microsoft Azure Speech Service TTS Models
|
|
61
|
-
MicrosoftAzureSpeechTTSModels.
|
|
62
|
-
MicrosoftAzureSpeechTTSModels.
|
|
63
|
-
MicrosoftAzureSpeechTTSModels.
|
|
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
|
|
64
78
|
|
|
65
79
|
# Google Cloud Text-to-Speech TTS Models
|
|
66
80
|
GoogleCloudTextToSpeechTTSModels.CHIRP_3_HD: TtsModelPricing(cost_per_million_characters=30.0), # $30 per 1 million characters
|
|
@@ -74,6 +88,12 @@ TTS_MODEL_PRICING: Dict[str, TtsModelPricing] = {
|
|
|
74
88
|
# Deepgram TTS Models
|
|
75
89
|
DeepgramTTSModels.AURA_2: TtsModelPricing(cost_per_million_characters=30.0), # $30 per 1 million characters
|
|
76
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
|
|
77
97
|
}
|
|
78
98
|
|
|
79
99
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Wrappers for automatic usage tracking with AI provider SDKs.
|
|
3
|
+
|
|
4
|
+
This module provides wrapper classes that intercept API calls to various AI providers
|
|
5
|
+
and automatically send usage data to Paygent for tracking and billing.
|
|
6
|
+
|
|
7
|
+
Note: All wrappers are lazily imported to avoid requiring installation of peer dependencies
|
|
8
|
+
that you don't use. For example, if you only use Gemini, you don't need to install openai,
|
|
9
|
+
anthropic, or mistral packages.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"PaygentOpenAI",
|
|
14
|
+
"PaygentAnthropic",
|
|
15
|
+
"PaygentMistral",
|
|
16
|
+
"PaygentGemini",
|
|
17
|
+
"PaygentLangChainCallback",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def __getattr__(name):
|
|
22
|
+
"""
|
|
23
|
+
Lazy import wrappers to avoid requiring peer dependencies that aren't being used.
|
|
24
|
+
|
|
25
|
+
This allows users to only install the AI provider packages they actually use,
|
|
26
|
+
rather than requiring all of them as dependencies.
|
|
27
|
+
"""
|
|
28
|
+
if name == "PaygentOpenAI":
|
|
29
|
+
from .openai_wrapper import PaygentOpenAI
|
|
30
|
+
return PaygentOpenAI
|
|
31
|
+
elif name == "PaygentAnthropic":
|
|
32
|
+
from .anthropic_wrapper import PaygentAnthropic
|
|
33
|
+
return PaygentAnthropic
|
|
34
|
+
elif name == "PaygentMistral":
|
|
35
|
+
from .mistral_wrapper import PaygentMistral
|
|
36
|
+
return PaygentMistral
|
|
37
|
+
elif name == "PaygentGemini":
|
|
38
|
+
from .gemini_wrapper import PaygentGemini
|
|
39
|
+
return PaygentGemini
|
|
40
|
+
elif name == "PaygentLangChainCallback":
|
|
41
|
+
from .langchain_wrapper import PaygentLangChainCallback
|
|
42
|
+
return PaygentLangChainCallback
|
|
43
|
+
|
|
44
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
@@ -113,12 +113,20 @@ class ChatCompletionsWrapper:
|
|
|
113
113
|
|
|
114
114
|
if has_valid_usage:
|
|
115
115
|
# Primary path: Use usage data from API response
|
|
116
|
+
# Extract cached tokens if available (OpenAI prompt caching feature)
|
|
117
|
+
cached_tokens = 0
|
|
118
|
+
if hasattr(response.usage, 'prompt_tokens_details'):
|
|
119
|
+
prompt_details = response.usage.prompt_tokens_details
|
|
120
|
+
if hasattr(prompt_details, 'cached_tokens') and prompt_details.cached_tokens:
|
|
121
|
+
cached_tokens = prompt_details.cached_tokens
|
|
122
|
+
|
|
116
123
|
usage_data = UsageData(
|
|
117
124
|
service_provider=model,
|
|
118
125
|
model=model,
|
|
119
126
|
prompt_tokens=response.usage.prompt_tokens,
|
|
120
127
|
completion_tokens=response.usage.completion_tokens,
|
|
121
|
-
total_tokens=response.usage.total_tokens
|
|
128
|
+
total_tokens=response.usage.total_tokens,
|
|
129
|
+
cached_tokens=cached_tokens
|
|
122
130
|
)
|
|
123
131
|
|
|
124
132
|
self.paygent_client.send_usage(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: paygent-sdk
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.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
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "paygent-sdk"
|
|
7
|
-
version = "
|
|
7
|
+
version = "3.0.0"
|
|
8
8
|
description = "Official Python SDK for Paygent - Track AI usage and costs across multiple providers (OpenAI, Anthropic, Google, DeepSeek, etc.)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.7"
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Wrappers for automatic usage tracking with AI provider SDKs.
|
|
3
|
-
|
|
4
|
-
This module provides wrapper classes that intercept API calls to various AI providers
|
|
5
|
-
and automatically send usage data to Paygent for tracking and billing.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from .openai_wrapper import PaygentOpenAI
|
|
9
|
-
from .anthropic_wrapper import PaygentAnthropic
|
|
10
|
-
from .mistral_wrapper import PaygentMistral
|
|
11
|
-
from .gemini_wrapper import PaygentGemini
|
|
12
|
-
|
|
13
|
-
# LangChain integration (optional dependency)
|
|
14
|
-
try:
|
|
15
|
-
from .langchain_wrapper import PaygentLangChainCallback
|
|
16
|
-
__all__ = [
|
|
17
|
-
"PaygentOpenAI",
|
|
18
|
-
"PaygentAnthropic",
|
|
19
|
-
"PaygentMistral",
|
|
20
|
-
"PaygentGemini",
|
|
21
|
-
"PaygentLangChainCallback",
|
|
22
|
-
]
|
|
23
|
-
except ImportError:
|
|
24
|
-
# LangChain not installed
|
|
25
|
-
__all__ = [
|
|
26
|
-
"PaygentOpenAI",
|
|
27
|
-
"PaygentAnthropic",
|
|
28
|
-
"PaygentMistral",
|
|
29
|
-
"PaygentGemini",
|
|
30
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|