posthoganalytics 6.7.0__tar.gz → 6.7.2__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.
- {posthoganalytics-6.7.0/posthoganalytics.egg-info → posthoganalytics-6.7.2}/PKG-INFO +1 -1
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/anthropic/__init__.py +10 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/anthropic/anthropic.py +94 -63
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/anthropic/anthropic_async.py +88 -21
- posthoganalytics-6.7.2/posthoganalytics/ai/anthropic/anthropic_converter.py +393 -0
- posthoganalytics-6.7.2/posthoganalytics/ai/gemini/__init__.py +22 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/gemini/gemini.py +61 -67
- posthoganalytics-6.7.2/posthoganalytics/ai/gemini/gemini_converter.py +438 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/langchain/callbacks.py +3 -2
- posthoganalytics-6.7.2/posthoganalytics/ai/openai/__init__.py +20 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/openai/openai.py +114 -148
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/openai/openai_async.py +72 -73
- posthoganalytics-6.7.2/posthoganalytics/ai/openai/openai_converter.py +585 -0
- posthoganalytics-6.7.2/posthoganalytics/ai/sanitization.py +226 -0
- posthoganalytics-6.7.2/posthoganalytics/ai/types.py +142 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/utils.py +232 -255
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/client.py +7 -7
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_feature_flags.py +2 -2
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/version.py +1 -1
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2/posthoganalytics.egg-info}/PKG-INFO +1 -1
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics.egg-info/SOURCES.txt +5 -0
- posthoganalytics-6.7.0/posthoganalytics/ai/gemini/__init__.py +0 -11
- posthoganalytics-6.7.0/posthoganalytics/ai/openai/__init__.py +0 -5
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/LICENSE +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/MANIFEST.in +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/README.md +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/__init__.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/__init__.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/anthropic/anthropic_providers.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/langchain/__init__.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/openai/openai_providers.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/args.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/consumer.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/contexts.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/exception_capture.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/exception_utils.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/feature_flags.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/integrations/__init__.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/integrations/django.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/poller.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/py.typed +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/request.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/__init__.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_before_send.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_client.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_consumer.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_contexts.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_exception_capture.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_feature_flag.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_feature_flag_result.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_module.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_request.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_size_limited_dict.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_types.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/test/test_utils.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/types.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/utils.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics.egg-info/dependency_links.txt +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics.egg-info/requires.txt +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics.egg-info/top_level.txt +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/pyproject.toml +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/setup.cfg +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/setup.py +0 -0
- {posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/setup_analytics.py +0 -0
|
@@ -6,6 +6,12 @@ from .anthropic_providers import (
|
|
|
6
6
|
AsyncAnthropicBedrock,
|
|
7
7
|
AsyncAnthropicVertex,
|
|
8
8
|
)
|
|
9
|
+
from .anthropic_converter import (
|
|
10
|
+
format_anthropic_response,
|
|
11
|
+
format_anthropic_input,
|
|
12
|
+
extract_anthropic_tools,
|
|
13
|
+
format_anthropic_streaming_content,
|
|
14
|
+
)
|
|
9
15
|
|
|
10
16
|
__all__ = [
|
|
11
17
|
"Anthropic",
|
|
@@ -14,4 +20,8 @@ __all__ = [
|
|
|
14
20
|
"AsyncAnthropicBedrock",
|
|
15
21
|
"AnthropicVertex",
|
|
16
22
|
"AsyncAnthropicVertex",
|
|
23
|
+
"format_anthropic_response",
|
|
24
|
+
"format_anthropic_input",
|
|
25
|
+
"extract_anthropic_tools",
|
|
26
|
+
"format_anthropic_streaming_content",
|
|
17
27
|
]
|
{posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/anthropic/anthropic.py
RENAMED
|
@@ -8,14 +8,21 @@ except ImportError:
|
|
|
8
8
|
|
|
9
9
|
import time
|
|
10
10
|
import uuid
|
|
11
|
-
from typing import Any, Dict, Optional
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
12
|
|
|
13
|
+
from posthoganalytics.ai.types import StreamingContentBlock, ToolInProgress
|
|
13
14
|
from posthoganalytics.ai.utils import (
|
|
14
15
|
call_llm_and_track_usage,
|
|
15
|
-
|
|
16
|
-
merge_system_prompt,
|
|
17
|
-
with_privacy_mode,
|
|
16
|
+
merge_usage_stats,
|
|
18
17
|
)
|
|
18
|
+
from posthoganalytics.ai.anthropic.anthropic_converter import (
|
|
19
|
+
extract_anthropic_usage_from_event,
|
|
20
|
+
handle_anthropic_content_block_start,
|
|
21
|
+
handle_anthropic_text_delta,
|
|
22
|
+
handle_anthropic_tool_delta,
|
|
23
|
+
finalize_anthropic_tool_input,
|
|
24
|
+
)
|
|
25
|
+
from posthoganalytics.ai.sanitization import sanitize_anthropic
|
|
19
26
|
from posthoganalytics.client import Client as PostHogClient
|
|
20
27
|
from posthoganalytics import setup
|
|
21
28
|
|
|
@@ -61,6 +68,7 @@ class WrappedMessages(Messages):
|
|
|
61
68
|
posthog_groups: Optional group analytics properties
|
|
62
69
|
**kwargs: Arguments passed to Anthropic's messages.create
|
|
63
70
|
"""
|
|
71
|
+
|
|
64
72
|
if posthog_trace_id is None:
|
|
65
73
|
posthog_trace_id = str(uuid.uuid4())
|
|
66
74
|
|
|
@@ -119,34 +127,65 @@ class WrappedMessages(Messages):
|
|
|
119
127
|
):
|
|
120
128
|
start_time = time.time()
|
|
121
129
|
usage_stats: Dict[str, int] = {"input_tokens": 0, "output_tokens": 0}
|
|
122
|
-
accumulated_content =
|
|
130
|
+
accumulated_content = ""
|
|
131
|
+
content_blocks: List[StreamingContentBlock] = []
|
|
132
|
+
tools_in_progress: Dict[str, ToolInProgress] = {}
|
|
133
|
+
current_text_block: Optional[StreamingContentBlock] = None
|
|
123
134
|
response = super().create(**kwargs)
|
|
124
135
|
|
|
125
136
|
def generator():
|
|
126
137
|
nonlocal usage_stats
|
|
127
|
-
nonlocal accumulated_content
|
|
138
|
+
nonlocal accumulated_content
|
|
139
|
+
nonlocal content_blocks
|
|
140
|
+
nonlocal tools_in_progress
|
|
141
|
+
nonlocal current_text_block
|
|
142
|
+
|
|
128
143
|
try:
|
|
129
144
|
for event in response:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
# Extract usage stats from event
|
|
146
|
+
event_usage = extract_anthropic_usage_from_event(event)
|
|
147
|
+
merge_usage_stats(usage_stats, event_usage)
|
|
148
|
+
|
|
149
|
+
# Handle content block start events
|
|
150
|
+
if hasattr(event, "type") and event.type == "content_block_start":
|
|
151
|
+
block, tool = handle_anthropic_content_block_start(event)
|
|
152
|
+
|
|
153
|
+
if block:
|
|
154
|
+
content_blocks.append(block)
|
|
155
|
+
|
|
156
|
+
if block.get("type") == "text":
|
|
157
|
+
current_text_block = block
|
|
158
|
+
else:
|
|
159
|
+
current_text_block = None
|
|
160
|
+
|
|
161
|
+
if tool:
|
|
162
|
+
tool_id = tool["block"].get("id")
|
|
163
|
+
if tool_id:
|
|
164
|
+
tools_in_progress[tool_id] = tool
|
|
165
|
+
|
|
166
|
+
# Handle text delta events
|
|
167
|
+
delta_text = handle_anthropic_text_delta(event, current_text_block)
|
|
168
|
+
|
|
169
|
+
if delta_text:
|
|
170
|
+
accumulated_content += delta_text
|
|
171
|
+
|
|
172
|
+
# Handle tool input delta events
|
|
173
|
+
handle_anthropic_tool_delta(
|
|
174
|
+
event, content_blocks, tools_in_progress
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Handle content block stop events
|
|
178
|
+
if hasattr(event, "type") and event.type == "content_block_stop":
|
|
179
|
+
current_text_block = None
|
|
180
|
+
finalize_anthropic_tool_input(
|
|
181
|
+
event, content_blocks, tools_in_progress
|
|
182
|
+
)
|
|
143
183
|
|
|
144
184
|
yield event
|
|
145
185
|
|
|
146
186
|
finally:
|
|
147
187
|
end_time = time.time()
|
|
148
188
|
latency = end_time - start_time
|
|
149
|
-
output = "".join(accumulated_content)
|
|
150
189
|
|
|
151
190
|
self._capture_streaming_event(
|
|
152
191
|
posthog_distinct_id,
|
|
@@ -157,7 +196,8 @@ class WrappedMessages(Messages):
|
|
|
157
196
|
kwargs,
|
|
158
197
|
usage_stats,
|
|
159
198
|
latency,
|
|
160
|
-
|
|
199
|
+
content_blocks,
|
|
200
|
+
accumulated_content,
|
|
161
201
|
)
|
|
162
202
|
|
|
163
203
|
return generator()
|
|
@@ -172,47 +212,38 @@ class WrappedMessages(Messages):
|
|
|
172
212
|
kwargs: Dict[str, Any],
|
|
173
213
|
usage_stats: Dict[str, int],
|
|
174
214
|
latency: float,
|
|
175
|
-
|
|
215
|
+
content_blocks: List[StreamingContentBlock],
|
|
216
|
+
accumulated_content: str,
|
|
176
217
|
):
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
"$ai_cache_read_input_tokens": usage_stats.get(
|
|
198
|
-
"cache_read_input_tokens", 0
|
|
199
|
-
),
|
|
200
|
-
"$ai_cache_creation_input_tokens": usage_stats.get(
|
|
201
|
-
"cache_creation_input_tokens", 0
|
|
218
|
+
from posthoganalytics.ai.types import StreamingEventData
|
|
219
|
+
from posthoganalytics.ai.anthropic.anthropic_converter import (
|
|
220
|
+
standardize_anthropic_usage,
|
|
221
|
+
format_anthropic_streaming_input,
|
|
222
|
+
format_anthropic_streaming_output_complete,
|
|
223
|
+
)
|
|
224
|
+
from posthoganalytics.ai.utils import capture_streaming_event
|
|
225
|
+
|
|
226
|
+
# Prepare standardized event data
|
|
227
|
+
formatted_input = format_anthropic_streaming_input(kwargs)
|
|
228
|
+
sanitized_input = sanitize_anthropic(formatted_input)
|
|
229
|
+
|
|
230
|
+
event_data = StreamingEventData(
|
|
231
|
+
provider="anthropic",
|
|
232
|
+
model=kwargs.get("model", "unknown"),
|
|
233
|
+
base_url=str(self._client.base_url),
|
|
234
|
+
kwargs=kwargs,
|
|
235
|
+
formatted_input=sanitized_input,
|
|
236
|
+
formatted_output=format_anthropic_streaming_output_complete(
|
|
237
|
+
content_blocks, accumulated_content
|
|
202
238
|
),
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
distinct_id=posthog_distinct_id or posthog_trace_id,
|
|
215
|
-
event="$ai_generation",
|
|
216
|
-
properties=event_properties,
|
|
217
|
-
groups=posthog_groups,
|
|
218
|
-
)
|
|
239
|
+
usage_stats=standardize_anthropic_usage(usage_stats),
|
|
240
|
+
latency=latency,
|
|
241
|
+
distinct_id=posthog_distinct_id,
|
|
242
|
+
trace_id=posthog_trace_id,
|
|
243
|
+
properties=posthog_properties,
|
|
244
|
+
privacy_mode=posthog_privacy_mode,
|
|
245
|
+
groups=posthog_groups,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# Use the common capture function
|
|
249
|
+
capture_streaming_event(self._client._ph_client, event_data)
|
{posthoganalytics-6.7.0 → posthoganalytics-6.7.2}/posthoganalytics/ai/anthropic/anthropic_async.py
RENAMED
|
@@ -8,15 +8,27 @@ except ImportError:
|
|
|
8
8
|
|
|
9
9
|
import time
|
|
10
10
|
import uuid
|
|
11
|
-
from typing import Any, Dict, Optional
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
12
|
|
|
13
13
|
from posthoganalytics import setup
|
|
14
|
+
from posthoganalytics.ai.types import StreamingContentBlock, ToolInProgress
|
|
14
15
|
from posthoganalytics.ai.utils import (
|
|
15
16
|
call_llm_and_track_usage_async,
|
|
17
|
+
extract_available_tool_calls,
|
|
16
18
|
get_model_params,
|
|
17
19
|
merge_system_prompt,
|
|
20
|
+
merge_usage_stats,
|
|
18
21
|
with_privacy_mode,
|
|
19
22
|
)
|
|
23
|
+
from posthoganalytics.ai.anthropic.anthropic_converter import (
|
|
24
|
+
format_anthropic_streaming_content,
|
|
25
|
+
extract_anthropic_usage_from_event,
|
|
26
|
+
handle_anthropic_content_block_start,
|
|
27
|
+
handle_anthropic_text_delta,
|
|
28
|
+
handle_anthropic_tool_delta,
|
|
29
|
+
finalize_anthropic_tool_input,
|
|
30
|
+
)
|
|
31
|
+
from posthoganalytics.ai.sanitization import sanitize_anthropic
|
|
20
32
|
from posthoganalytics.client import Client as PostHogClient
|
|
21
33
|
|
|
22
34
|
|
|
@@ -61,6 +73,7 @@ class AsyncWrappedMessages(AsyncMessages):
|
|
|
61
73
|
posthog_groups: Optional group analytics properties
|
|
62
74
|
**kwargs: Arguments passed to Anthropic's messages.create
|
|
63
75
|
"""
|
|
76
|
+
|
|
64
77
|
if posthog_trace_id is None:
|
|
65
78
|
posthog_trace_id = str(uuid.uuid4())
|
|
66
79
|
|
|
@@ -119,34 +132,65 @@ class AsyncWrappedMessages(AsyncMessages):
|
|
|
119
132
|
):
|
|
120
133
|
start_time = time.time()
|
|
121
134
|
usage_stats: Dict[str, int] = {"input_tokens": 0, "output_tokens": 0}
|
|
122
|
-
accumulated_content =
|
|
135
|
+
accumulated_content = ""
|
|
136
|
+
content_blocks: List[StreamingContentBlock] = []
|
|
137
|
+
tools_in_progress: Dict[str, ToolInProgress] = {}
|
|
138
|
+
current_text_block: Optional[StreamingContentBlock] = None
|
|
123
139
|
response = await super().create(**kwargs)
|
|
124
140
|
|
|
125
141
|
async def generator():
|
|
126
142
|
nonlocal usage_stats
|
|
127
|
-
nonlocal accumulated_content
|
|
143
|
+
nonlocal accumulated_content
|
|
144
|
+
nonlocal content_blocks
|
|
145
|
+
nonlocal tools_in_progress
|
|
146
|
+
nonlocal current_text_block
|
|
147
|
+
|
|
128
148
|
try:
|
|
129
149
|
async for event in response:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
# Extract usage stats from event
|
|
151
|
+
event_usage = extract_anthropic_usage_from_event(event)
|
|
152
|
+
merge_usage_stats(usage_stats, event_usage)
|
|
153
|
+
|
|
154
|
+
# Handle content block start events
|
|
155
|
+
if hasattr(event, "type") and event.type == "content_block_start":
|
|
156
|
+
block, tool = handle_anthropic_content_block_start(event)
|
|
157
|
+
|
|
158
|
+
if block:
|
|
159
|
+
content_blocks.append(block)
|
|
160
|
+
|
|
161
|
+
if block.get("type") == "text":
|
|
162
|
+
current_text_block = block
|
|
163
|
+
else:
|
|
164
|
+
current_text_block = None
|
|
165
|
+
|
|
166
|
+
if tool:
|
|
167
|
+
tool_id = tool["block"].get("id")
|
|
168
|
+
if tool_id:
|
|
169
|
+
tools_in_progress[tool_id] = tool
|
|
170
|
+
|
|
171
|
+
# Handle text delta events
|
|
172
|
+
delta_text = handle_anthropic_text_delta(event, current_text_block)
|
|
173
|
+
|
|
174
|
+
if delta_text:
|
|
175
|
+
accumulated_content += delta_text
|
|
176
|
+
|
|
177
|
+
# Handle tool input delta events
|
|
178
|
+
handle_anthropic_tool_delta(
|
|
179
|
+
event, content_blocks, tools_in_progress
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# Handle content block stop events
|
|
183
|
+
if hasattr(event, "type") and event.type == "content_block_stop":
|
|
184
|
+
current_text_block = None
|
|
185
|
+
finalize_anthropic_tool_input(
|
|
186
|
+
event, content_blocks, tools_in_progress
|
|
187
|
+
)
|
|
143
188
|
|
|
144
189
|
yield event
|
|
145
190
|
|
|
146
191
|
finally:
|
|
147
192
|
end_time = time.time()
|
|
148
193
|
latency = end_time - start_time
|
|
149
|
-
output = "".join(accumulated_content)
|
|
150
194
|
|
|
151
195
|
await self._capture_streaming_event(
|
|
152
196
|
posthog_distinct_id,
|
|
@@ -157,7 +201,8 @@ class AsyncWrappedMessages(AsyncMessages):
|
|
|
157
201
|
kwargs,
|
|
158
202
|
usage_stats,
|
|
159
203
|
latency,
|
|
160
|
-
|
|
204
|
+
content_blocks,
|
|
205
|
+
accumulated_content,
|
|
161
206
|
)
|
|
162
207
|
|
|
163
208
|
return generator()
|
|
@@ -172,11 +217,27 @@ class AsyncWrappedMessages(AsyncMessages):
|
|
|
172
217
|
kwargs: Dict[str, Any],
|
|
173
218
|
usage_stats: Dict[str, int],
|
|
174
219
|
latency: float,
|
|
175
|
-
|
|
220
|
+
content_blocks: List[StreamingContentBlock],
|
|
221
|
+
accumulated_content: str,
|
|
176
222
|
):
|
|
177
223
|
if posthog_trace_id is None:
|
|
178
224
|
posthog_trace_id = str(uuid.uuid4())
|
|
179
225
|
|
|
226
|
+
# Format output using converter
|
|
227
|
+
formatted_content = format_anthropic_streaming_content(content_blocks)
|
|
228
|
+
formatted_output = []
|
|
229
|
+
|
|
230
|
+
if formatted_content:
|
|
231
|
+
formatted_output = [{"role": "assistant", "content": formatted_content}]
|
|
232
|
+
else:
|
|
233
|
+
# Fallback to accumulated content if no blocks
|
|
234
|
+
formatted_output = [
|
|
235
|
+
{
|
|
236
|
+
"role": "assistant",
|
|
237
|
+
"content": [{"type": "text", "text": accumulated_content}],
|
|
238
|
+
}
|
|
239
|
+
]
|
|
240
|
+
|
|
180
241
|
event_properties = {
|
|
181
242
|
"$ai_provider": "anthropic",
|
|
182
243
|
"$ai_model": kwargs.get("model"),
|
|
@@ -184,12 +245,12 @@ class AsyncWrappedMessages(AsyncMessages):
|
|
|
184
245
|
"$ai_input": with_privacy_mode(
|
|
185
246
|
self._client._ph_client,
|
|
186
247
|
posthog_privacy_mode,
|
|
187
|
-
merge_system_prompt(kwargs, "anthropic"),
|
|
248
|
+
sanitize_anthropic(merge_system_prompt(kwargs, "anthropic")),
|
|
188
249
|
),
|
|
189
250
|
"$ai_output_choices": with_privacy_mode(
|
|
190
251
|
self._client._ph_client,
|
|
191
252
|
posthog_privacy_mode,
|
|
192
|
-
|
|
253
|
+
formatted_output,
|
|
193
254
|
),
|
|
194
255
|
"$ai_http_status": 200,
|
|
195
256
|
"$ai_input_tokens": usage_stats.get("input_tokens", 0),
|
|
@@ -206,6 +267,12 @@ class AsyncWrappedMessages(AsyncMessages):
|
|
|
206
267
|
**(posthog_properties or {}),
|
|
207
268
|
}
|
|
208
269
|
|
|
270
|
+
# Add tools if available
|
|
271
|
+
available_tools = extract_available_tool_calls("anthropic", kwargs)
|
|
272
|
+
|
|
273
|
+
if available_tools:
|
|
274
|
+
event_properties["$ai_tools"] = available_tools
|
|
275
|
+
|
|
209
276
|
if posthog_distinct_id is None:
|
|
210
277
|
event_properties["$process_person_profile"] = False
|
|
211
278
|
|