revenium-python-sdk 0.1.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.
Files changed (73) hide show
  1. revenium_middleware/__init__.py +184 -0
  2. revenium_middleware/_core/__init__.py +65 -0
  3. revenium_middleware/_core/config.py +165 -0
  4. revenium_middleware/_core/context.py +109 -0
  5. revenium_middleware/_core/decorators.py +202 -0
  6. revenium_middleware/_core/metering.py +207 -0
  7. revenium_middleware/_core/prompt_extraction.py +55 -0
  8. revenium_middleware/_core/subscriber.py +51 -0
  9. revenium_middleware/_core/trace_fields.py +265 -0
  10. revenium_middleware/anthropic/__init__.py +108 -0
  11. revenium_middleware/anthropic/bedrock_adapter.py +753 -0
  12. revenium_middleware/anthropic/config.py +29 -0
  13. revenium_middleware/anthropic/middleware.py +1070 -0
  14. revenium_middleware/anthropic/prompt_extractor.py +178 -0
  15. revenium_middleware/anthropic/provider.py +141 -0
  16. revenium_middleware/anthropic/summary_printer.py +286 -0
  17. revenium_middleware/anthropic/trace_fields.py +158 -0
  18. revenium_middleware/google/__init__.py +114 -0
  19. revenium_middleware/google/common/__init__.py +127 -0
  20. revenium_middleware/google/common/exceptions.py +137 -0
  21. revenium_middleware/google/common/protocols.py +192 -0
  22. revenium_middleware/google/common/summary_printer.py +271 -0
  23. revenium_middleware/google/common/trace_fields.py +205 -0
  24. revenium_middleware/google/common/types.py +208 -0
  25. revenium_middleware/google/common/utils.py +1111 -0
  26. revenium_middleware/google/config.py +64 -0
  27. revenium_middleware/google/google_ai/__init__.py +53 -0
  28. revenium_middleware/google/google_ai/middleware.py +667 -0
  29. revenium_middleware/google/google_ai/provider.py +135 -0
  30. revenium_middleware/google/prompt_extractor.py +396 -0
  31. revenium_middleware/google/vertex_ai/__init__.py +56 -0
  32. revenium_middleware/google/vertex_ai/middleware.py +1162 -0
  33. revenium_middleware/google/vertex_ai/provider.py +99 -0
  34. revenium_middleware/litellm/__init__.py +25 -0
  35. revenium_middleware/litellm/client/__init__.py +81 -0
  36. revenium_middleware/litellm/client/config.py +53 -0
  37. revenium_middleware/litellm/client/context.py +198 -0
  38. revenium_middleware/litellm/client/decorators.py +912 -0
  39. revenium_middleware/litellm/client/hooks.py +192 -0
  40. revenium_middleware/litellm/client/integrations/__init__.py +26 -0
  41. revenium_middleware/litellm/client/integrations/crewai.py +446 -0
  42. revenium_middleware/litellm/client/middleware.py +321 -0
  43. revenium_middleware/litellm/client/summary_printer.py +314 -0
  44. revenium_middleware/litellm/client/trace_fields.py +51 -0
  45. revenium_middleware/litellm/client/validation.py +207 -0
  46. revenium_middleware/litellm/proxy/__init__.py +25 -0
  47. revenium_middleware/litellm/proxy/middleware.py +217 -0
  48. revenium_middleware/ollama/__init__.py +28 -0
  49. revenium_middleware/ollama/middleware.py +569 -0
  50. revenium_middleware/ollama/trace_fields.py +63 -0
  51. revenium_middleware/openai/__init__.py +23 -0
  52. revenium_middleware/openai/azure_config.py +169 -0
  53. revenium_middleware/openai/azure_model_resolver.py +219 -0
  54. revenium_middleware/openai/config.py +45 -0
  55. revenium_middleware/openai/exceptions.py +115 -0
  56. revenium_middleware/openai/langchain/__init__.py +114 -0
  57. revenium_middleware/openai/langchain/_utils.py +129 -0
  58. revenium_middleware/openai/langchain/unified_handler.py +526 -0
  59. revenium_middleware/openai/middleware.py +1451 -0
  60. revenium_middleware/openai/prompt_extractor.py +173 -0
  61. revenium_middleware/openai/provider.py +170 -0
  62. revenium_middleware/openai/summary_printer.py +292 -0
  63. revenium_middleware/openai/trace_fields.py +98 -0
  64. revenium_middleware/perplexity/__init__.py +97 -0
  65. revenium_middleware/perplexity/middleware.py +379 -0
  66. revenium_middleware/perplexity/perplexity_sdk.py +256 -0
  67. revenium_middleware/perplexity/provider.py +84 -0
  68. revenium_middleware/perplexity/trace_fields.py +25 -0
  69. revenium_python_sdk-0.1.0.dist-info/METADATA +252 -0
  70. revenium_python_sdk-0.1.0.dist-info/RECORD +73 -0
  71. revenium_python_sdk-0.1.0.dist-info/WHEEL +5 -0
  72. revenium_python_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
  73. revenium_python_sdk-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,208 @@
1
+ """
2
+ Shared type definitions for Google AI middleware.
3
+
4
+ This module contains common data structures and enums used across both
5
+ Google AI SDK and Vertex AI SDK middleware implementations.
6
+ """
7
+
8
+ import datetime
9
+ from dataclasses import dataclass
10
+ from enum import Enum
11
+ from typing import Dict, Any, Optional
12
+
13
+
14
+ class OperationType(str, Enum):
15
+ """Operation types for AI API calls."""
16
+
17
+ CHAT = "CHAT"
18
+ EMBED = "EMBED"
19
+ IMAGE = "IMAGE"
20
+ VIDEO = "VIDEO"
21
+
22
+
23
+ class Provider(Enum):
24
+ """Supported Google AI providers."""
25
+
26
+ GOOGLE_AI_SDK = "google_ai_sdk"
27
+ VERTEX_AI_SDK = "vertex_ai_sdk"
28
+
29
+
30
+ @dataclass
31
+ class ProviderMetadata:
32
+ """Provider-specific metadata for usage records."""
33
+
34
+ provider: str # Always "Google" for unified reporting
35
+ model_source: str # Always "GOOGLE"
36
+ sdk_type: Provider # Which SDK is being used
37
+
38
+ @classmethod
39
+ def for_google_ai_sdk(cls) -> "ProviderMetadata":
40
+ """Create metadata for Google AI SDK."""
41
+ return cls(
42
+ provider="Google", model_source="GOOGLE", sdk_type=Provider.GOOGLE_AI_SDK
43
+ )
44
+
45
+ @classmethod
46
+ def for_vertex_ai_sdk(cls) -> "ProviderMetadata":
47
+ """Create metadata for Vertex AI SDK."""
48
+ return cls(
49
+ provider="Google", model_source="GOOGLE", sdk_type=Provider.VERTEX_AI_SDK
50
+ )
51
+
52
+
53
+ @dataclass
54
+ class UsageData:
55
+ """Standardized usage data structure for both SDKs."""
56
+
57
+ # Core token counts (required)
58
+ input_token_count: int
59
+ output_token_count: int
60
+ total_token_count: int
61
+
62
+ # Operation details (required)
63
+ operation_type: str # OperationType value
64
+ stop_reason: str
65
+ transaction_id: str
66
+ model: str
67
+
68
+ # Provider information (required)
69
+ provider: str # Always "Google"
70
+ model_source: str # Always "GOOGLE"
71
+ sdk_type: Provider # Which SDK was used
72
+
73
+ # Timing information (required)
74
+ request_time: str
75
+ response_time: str
76
+ completion_start_time: str
77
+ request_duration: int # milliseconds
78
+
79
+ # Streaming and timing (optional with defaults)
80
+ is_streamed: bool = False
81
+ time_to_first_token: int = 0
82
+
83
+ # Advanced token counts (optional with defaults)
84
+ cache_creation_token_count: int = 0
85
+ cache_read_token_count: int = 0
86
+ reasoning_token_count: int = 0
87
+
88
+ # Cost information (optional with defaults)
89
+ cost_type: str = "AI"
90
+ input_token_cost: Optional[float] = None
91
+ output_token_cost: Optional[float] = None
92
+ total_cost: Optional[float] = None
93
+
94
+ def to_dict(self) -> Dict[str, Any]:
95
+ """Convert to dictionary for API calls."""
96
+ return {
97
+ "input_token_count": self.input_token_count,
98
+ "output_token_count": self.output_token_count,
99
+ "total_token_count": self.total_token_count,
100
+ "operation_type": self.operation_type,
101
+ "stop_reason": self.stop_reason,
102
+ "transaction_id": self.transaction_id,
103
+ "model": self.model,
104
+ "provider": self.provider,
105
+ "model_source": self.model_source,
106
+ "is_streamed": self.is_streamed,
107
+ "time_to_first_token": self.time_to_first_token,
108
+ "cache_creation_token_count": self.cache_creation_token_count,
109
+ "cache_read_token_count": self.cache_read_token_count,
110
+ "reasoning_token_count": self.reasoning_token_count,
111
+ "request_time": self.request_time,
112
+ "response_time": self.response_time,
113
+ "completion_start_time": self.completion_start_time,
114
+ "request_duration": self.request_duration,
115
+ "cost_type": self.cost_type,
116
+ "input_token_cost": self.input_token_cost,
117
+ "output_token_cost": self.output_token_cost,
118
+ "total_cost": self.total_cost,
119
+ }
120
+
121
+ @classmethod
122
+ def create(
123
+ cls,
124
+ operation_type: OperationType,
125
+ input_tokens: int,
126
+ output_tokens: int,
127
+ total_tokens: int,
128
+ model: str,
129
+ provider_metadata: ProviderMetadata,
130
+ stop_reason: str,
131
+ request_time: datetime.datetime,
132
+ response_time: datetime.datetime,
133
+ transaction_id: Optional[str] = None,
134
+ **kwargs,
135
+ ) -> "UsageData":
136
+ """Create UsageData with common defaults."""
137
+ import uuid
138
+
139
+ if transaction_id is None:
140
+ transaction_id = str(uuid.uuid4())
141
+
142
+ request_time_str = request_time.strftime("%Y-%m-%dT%H:%M:%SZ")
143
+ response_time_str = response_time.strftime("%Y-%m-%dT%H:%M:%SZ")
144
+ request_duration = int((response_time - request_time).total_seconds() * 1000)
145
+
146
+ return cls(
147
+ input_token_count=input_tokens,
148
+ output_token_count=output_tokens,
149
+ total_token_count=total_tokens,
150
+ operation_type=operation_type.value,
151
+ stop_reason=stop_reason,
152
+ transaction_id=transaction_id,
153
+ model=model,
154
+ provider=provider_metadata.provider,
155
+ model_source=provider_metadata.model_source,
156
+ sdk_type=provider_metadata.sdk_type,
157
+ request_time=request_time_str,
158
+ response_time=response_time_str,
159
+ completion_start_time=response_time_str,
160
+ request_duration=request_duration,
161
+ **kwargs,
162
+ )
163
+
164
+
165
+ @dataclass
166
+ class TokenCounts:
167
+ """Token count information extracted from API responses."""
168
+
169
+ input_tokens: int
170
+ output_tokens: int
171
+ total_tokens: int
172
+ cached_tokens: int = 0
173
+
174
+ @property
175
+ def has_counts(self) -> bool:
176
+ """Check if any token counts are available."""
177
+ return self.total_tokens > 0 or self.input_tokens > 0 or self.output_tokens > 0
178
+
179
+
180
+ # Stop reason mappings for different SDKs
181
+ # Valid Revenium stop reasons: "END", "END_SEQUENCE", "TIMEOUT", "TOKEN_LIMIT", "ERROR"
182
+ GOOGLE_AI_STOP_REASONS = {
183
+ "STOP": "END",
184
+ "MAX_TOKENS": "TOKEN_LIMIT",
185
+ "SAFETY": "ERROR",
186
+ "RECITATION": "ERROR",
187
+ "OTHER": "END", # Default to END for unknown reasons
188
+ None: "END",
189
+ }
190
+
191
+ VERTEX_AI_STOP_REASONS = {
192
+ "STOP": "END",
193
+ "MAX_TOKENS": "TOKEN_LIMIT",
194
+ "SAFETY": "ERROR",
195
+ "RECITATION": "ERROR",
196
+ "FINISH_REASON_UNSPECIFIED": "END", # Default to END for unknown reasons
197
+ None: "END",
198
+ }
199
+
200
+
201
+ def normalize_stop_reason(finish_reason: Optional[str], sdk_type: Provider) -> str:
202
+ """Normalize stop reasons across different SDKs."""
203
+ if sdk_type == Provider.GOOGLE_AI_SDK:
204
+ return GOOGLE_AI_STOP_REASONS.get(finish_reason, "END")
205
+ elif sdk_type == Provider.VERTEX_AI_SDK:
206
+ return VERTEX_AI_STOP_REASONS.get(finish_reason, "END")
207
+ else:
208
+ return "END"