@od-oneapp/analytics 2026.1.1301
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.
- package/README.md +509 -0
- package/dist/ai-YMnynb-t.mjs +3347 -0
- package/dist/ai-YMnynb-t.mjs.map +1 -0
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/client-CTzJVFU5.mjs +9 -0
- package/dist/client-CTzJVFU5.mjs.map +1 -0
- package/dist/client-CcFTauAh.mjs +54 -0
- package/dist/client-CcFTauAh.mjs.map +1 -0
- package/dist/client-CeOLjbac.mjs +281 -0
- package/dist/client-CeOLjbac.mjs.map +1 -0
- package/dist/client-D339NFJS.mjs +267 -0
- package/dist/client-D339NFJS.mjs.map +1 -0
- package/dist/client-next.d.mts +62 -0
- package/dist/client-next.d.mts.map +1 -0
- package/dist/client-next.mjs +525 -0
- package/dist/client-next.mjs.map +1 -0
- package/dist/client.d.mts +30 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +186 -0
- package/dist/client.mjs.map +1 -0
- package/dist/config-DPS6bSYo.d.mts +34 -0
- package/dist/config-DPS6bSYo.d.mts.map +1 -0
- package/dist/config-P6P5adJg.mjs +287 -0
- package/dist/config-P6P5adJg.mjs.map +1 -0
- package/dist/console-8bND3mMU.mjs +128 -0
- package/dist/console-8bND3mMU.mjs.map +1 -0
- package/dist/ecommerce-Cgu4wlux.mjs +993 -0
- package/dist/ecommerce-Cgu4wlux.mjs.map +1 -0
- package/dist/emitters-6-nKo8i-.mjs +208 -0
- package/dist/emitters-6-nKo8i-.mjs.map +1 -0
- package/dist/emitters-DldkVSPp.d.mts +12 -0
- package/dist/emitters-DldkVSPp.d.mts.map +1 -0
- package/dist/index-BfNWgfa5.d.mts +1494 -0
- package/dist/index-BfNWgfa5.d.mts.map +1 -0
- package/dist/index-BkIWe--N.d.mts +953 -0
- package/dist/index-BkIWe--N.d.mts.map +1 -0
- package/dist/index-jPzXRn52.d.mts +184 -0
- package/dist/index-jPzXRn52.d.mts.map +1 -0
- package/dist/manager-DvRRjza6.d.mts +76 -0
- package/dist/manager-DvRRjza6.d.mts.map +1 -0
- package/dist/posthog-bootstrap-CYfIy_WS.mjs +1769 -0
- package/dist/posthog-bootstrap-CYfIy_WS.mjs.map +1 -0
- package/dist/posthog-bootstrap-DWxFrxlt.d.mts +81 -0
- package/dist/posthog-bootstrap-DWxFrxlt.d.mts.map +1 -0
- package/dist/providers-http-client.d.mts +37 -0
- package/dist/providers-http-client.d.mts.map +1 -0
- package/dist/providers-http-client.mjs +320 -0
- package/dist/providers-http-client.mjs.map +1 -0
- package/dist/providers-http-server.d.mts +31 -0
- package/dist/providers-http-server.d.mts.map +1 -0
- package/dist/providers-http-server.mjs +297 -0
- package/dist/providers-http-server.mjs.map +1 -0
- package/dist/providers-http.d.mts +46 -0
- package/dist/providers-http.d.mts.map +1 -0
- package/dist/providers-http.mjs +4 -0
- package/dist/server-edge.d.mts +9 -0
- package/dist/server-edge.d.mts.map +1 -0
- package/dist/server-edge.mjs +373 -0
- package/dist/server-edge.mjs.map +1 -0
- package/dist/server-next.d.mts +67 -0
- package/dist/server-next.d.mts.map +1 -0
- package/dist/server-next.mjs +193 -0
- package/dist/server-next.mjs.map +1 -0
- package/dist/server.d.mts +10 -0
- package/dist/server.mjs +7 -0
- package/dist/service-cYtBBL8x.mjs +945 -0
- package/dist/service-cYtBBL8x.mjs.map +1 -0
- package/dist/shared.d.mts +16 -0
- package/dist/shared.d.mts.map +1 -0
- package/dist/shared.mjs +93 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/types-BxBnNQ0V.d.mts +354 -0
- package/dist/types-BxBnNQ0V.d.mts.map +1 -0
- package/dist/types-CBvxUEaF.d.mts +216 -0
- package/dist/types-CBvxUEaF.d.mts.map +1 -0
- package/dist/types.d.mts +4 -0
- package/dist/types.mjs +0 -0
- package/dist/vercel-types-lwakUfoI.d.mts +102 -0
- package/dist/vercel-types-lwakUfoI.d.mts.map +1 -0
- package/package.json +129 -0
- package/src/client/index.ts +164 -0
- package/src/client/manager.ts +71 -0
- package/src/client/next/components.tsx +270 -0
- package/src/client/next/hooks.ts +217 -0
- package/src/client/next/manager.ts +141 -0
- package/src/client/next.ts +144 -0
- package/src/client-next.ts +101 -0
- package/src/client.ts +89 -0
- package/src/examples/ai-sdk-patterns.ts +583 -0
- package/src/examples/emitter-patterns.ts +476 -0
- package/src/examples/nextjs-emitter-patterns.tsx +403 -0
- package/src/next/app-router.tsx +564 -0
- package/src/next/client.ts +419 -0
- package/src/next/index.ts +84 -0
- package/src/next/middleware.ts +429 -0
- package/src/next/rsc.tsx +300 -0
- package/src/next/server.ts +253 -0
- package/src/next/types.d.ts +220 -0
- package/src/providers/base-provider.ts +419 -0
- package/src/providers/console/client.ts +10 -0
- package/src/providers/console/index.ts +152 -0
- package/src/providers/console/server.ts +6 -0
- package/src/providers/console/types.ts +15 -0
- package/src/providers/http/client.ts +464 -0
- package/src/providers/http/index.ts +30 -0
- package/src/providers/http/server.ts +396 -0
- package/src/providers/http/types.ts +135 -0
- package/src/providers/posthog/client.ts +518 -0
- package/src/providers/posthog/index.ts +11 -0
- package/src/providers/posthog/server.ts +329 -0
- package/src/providers/posthog/types.ts +104 -0
- package/src/providers/segment/client.ts +113 -0
- package/src/providers/segment/index.ts +11 -0
- package/src/providers/segment/server.ts +115 -0
- package/src/providers/segment/types.ts +51 -0
- package/src/providers/vercel/client.ts +102 -0
- package/src/providers/vercel/index.ts +11 -0
- package/src/providers/vercel/server.ts +89 -0
- package/src/providers/vercel/types.ts +27 -0
- package/src/server/index.ts +103 -0
- package/src/server/manager.ts +62 -0
- package/src/server/next.ts +210 -0
- package/src/server-edge.ts +442 -0
- package/src/server-next.ts +39 -0
- package/src/server.ts +106 -0
- package/src/shared/emitters/ai/README.md +981 -0
- package/src/shared/emitters/ai/events/agent.ts +130 -0
- package/src/shared/emitters/ai/events/artifacts.ts +167 -0
- package/src/shared/emitters/ai/events/chat.ts +126 -0
- package/src/shared/emitters/ai/events/chatbot-ecommerce.ts +133 -0
- package/src/shared/emitters/ai/events/completion.ts +103 -0
- package/src/shared/emitters/ai/events/content-generation.ts +347 -0
- package/src/shared/emitters/ai/events/conversation.ts +332 -0
- package/src/shared/emitters/ai/events/product-features.ts +1402 -0
- package/src/shared/emitters/ai/events/streaming.ts +114 -0
- package/src/shared/emitters/ai/events/tool.ts +93 -0
- package/src/shared/emitters/ai/index.ts +69 -0
- package/src/shared/emitters/ai/track-ai-sdk.ts +74 -0
- package/src/shared/emitters/ai/track-ai.ts +50 -0
- package/src/shared/emitters/ai/types.ts +1041 -0
- package/src/shared/emitters/ai/utils.ts +468 -0
- package/src/shared/emitters/ecommerce/events/cart-checkout.ts +106 -0
- package/src/shared/emitters/ecommerce/events/coupon.ts +49 -0
- package/src/shared/emitters/ecommerce/events/engagement.ts +61 -0
- package/src/shared/emitters/ecommerce/events/marketplace.ts +119 -0
- package/src/shared/emitters/ecommerce/events/order.ts +199 -0
- package/src/shared/emitters/ecommerce/events/product.ts +205 -0
- package/src/shared/emitters/ecommerce/events/registry.ts +123 -0
- package/src/shared/emitters/ecommerce/events/wishlist-sharing.ts +140 -0
- package/src/shared/emitters/ecommerce/index.ts +46 -0
- package/src/shared/emitters/ecommerce/track-ecommerce.ts +53 -0
- package/src/shared/emitters/ecommerce/types.ts +314 -0
- package/src/shared/emitters/ecommerce/utils.ts +216 -0
- package/src/shared/emitters/emitter-types.ts +974 -0
- package/src/shared/emitters/emitters.ts +292 -0
- package/src/shared/emitters/helpers.ts +419 -0
- package/src/shared/emitters/index.ts +66 -0
- package/src/shared/index.ts +142 -0
- package/src/shared/ingestion/index.ts +66 -0
- package/src/shared/ingestion/schemas.ts +386 -0
- package/src/shared/ingestion/service.ts +628 -0
- package/src/shared/node22-features.ts +848 -0
- package/src/shared/providers/console-provider.ts +160 -0
- package/src/shared/types/base-types.ts +54 -0
- package/src/shared/types/console-types.ts +19 -0
- package/src/shared/types/posthog-types.ts +131 -0
- package/src/shared/types/segment-types.ts +15 -0
- package/src/shared/types/types.ts +397 -0
- package/src/shared/types/vercel-types.ts +19 -0
- package/src/shared/utils/config-client.ts +19 -0
- package/src/shared/utils/config.ts +250 -0
- package/src/shared/utils/emitter-adapter.ts +212 -0
- package/src/shared/utils/manager.test.ts +36 -0
- package/src/shared/utils/manager.ts +1322 -0
- package/src/shared/utils/posthog-bootstrap.ts +136 -0
- package/src/shared/utils/posthog-client-utils.ts +48 -0
- package/src/shared/utils/posthog-next-utils.ts +282 -0
- package/src/shared/utils/posthog-server-utils.ts +210 -0
- package/src/shared/utils/rate-limit.ts +289 -0
- package/src/shared/utils/security.ts +545 -0
- package/src/shared/utils/validation-client.ts +161 -0
- package/src/shared/utils/validation.ts +399 -0
- package/src/shared.ts +155 -0
- package/src/types/index.ts +62 -0
|
@@ -0,0 +1,981 @@
|
|
|
1
|
+
# AI Product Analytics Tracking
|
|
2
|
+
|
|
3
|
+
Comprehensive analytics tracking for AI product features like ChatGPT, Claude, and GitHub Copilot. Track how users
|
|
4
|
+
interact with your AI-powered chat interface, code generation tools, and collaborative AI features.
|
|
5
|
+
|
|
6
|
+
## Philosophy
|
|
7
|
+
|
|
8
|
+
**Track the AI product itself, not what users do with it.**
|
|
9
|
+
|
|
10
|
+
This package tracks **product features** like message regeneration, conversation branching, artifact creation, and code
|
|
11
|
+
generation. It does NOT track business use cases like e-commerce orders or support tickets.
|
|
12
|
+
|
|
13
|
+
### Clear Separation
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// ✅ AI Product Features (this package)
|
|
17
|
+
ai.MESSAGE_REGENERATED({ ... }); // User regenerated a response
|
|
18
|
+
ai.BRANCH_CREATED({ ... }); // User explored alternative response
|
|
19
|
+
ai.ARTIFACT_CREATED({ ... }); // System created interactive artifact
|
|
20
|
+
ai.CODE_GENERATED({ ... }); // AI generated code snippet
|
|
21
|
+
|
|
22
|
+
// ✅ E-commerce Behaviors (separate package)
|
|
23
|
+
ecommerce.productViewed({ ... }); // User viewed a product
|
|
24
|
+
ecommerce.cartUpdated({ ... }); // User added to cart
|
|
25
|
+
ecommerce.checkoutStarted({ ... }); // User started checkout
|
|
26
|
+
|
|
27
|
+
// ✅ You can use both together
|
|
28
|
+
// Track AI features in your e-commerce chatbot
|
|
29
|
+
ai.MESSAGE_SENT({ ... }); // Track the chat feature
|
|
30
|
+
ecommerce.productViewed({ ... }); // Track the business action
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Overview
|
|
34
|
+
|
|
35
|
+
This module provides **90+ standardized AI product events** that follow the same emitter-based architecture as the
|
|
36
|
+
e-commerce tracking system. It integrates seamlessly with PostHog, Vercel Analytics, Segment, and other analytics
|
|
37
|
+
providers.
|
|
38
|
+
|
|
39
|
+
### What This Tracks
|
|
40
|
+
|
|
41
|
+
- **Conversation Features**: Message regeneration, editing, branching, conversation management
|
|
42
|
+
- **Content Generation**: Code generation, image generation, text summaries, translations
|
|
43
|
+
- **Interactive Elements**: Artifacts (Claude-style), canvas mode, live previews
|
|
44
|
+
- **Files & Attachments**: Upload, processing, referencing
|
|
45
|
+
- **Context Management**: Memory, custom instructions, project context, RAG operations
|
|
46
|
+
- **Collaboration**: Sharing, forking, team workspaces
|
|
47
|
+
- **User Interactions**: Copy, execute, download, modify generated content
|
|
48
|
+
- **System Operations**: Model selection, streaming, errors, performance
|
|
49
|
+
- **Quality & Feedback**: User ratings, regenerations, stop generation
|
|
50
|
+
- **Advanced Features**: Multi-step reasoning, tool usage, search & citations
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Already available in @repo/analytics
|
|
56
|
+
pnpm install @repo/analytics
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
### Basic Conversation Tracking
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { ai } from "@repo/analytics/shared";
|
|
65
|
+
|
|
66
|
+
// Track conversation start
|
|
67
|
+
ai.CONVERSATION_STARTED({
|
|
68
|
+
conversation_id: "conv_123",
|
|
69
|
+
model_id: "claude-3-5-sonnet",
|
|
70
|
+
conversation_type: "chat"
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Track user message
|
|
74
|
+
ai.MESSAGE_SENT({
|
|
75
|
+
conversation_id: "conv_123",
|
|
76
|
+
message_id: "msg_456",
|
|
77
|
+
model_id: "claude-3-5-sonnet",
|
|
78
|
+
message_role: "user",
|
|
79
|
+
message_length: 50
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Track AI response
|
|
83
|
+
ai.MESSAGE_RECEIVED({
|
|
84
|
+
conversation_id: "conv_123",
|
|
85
|
+
message_id: "msg_457",
|
|
86
|
+
model_id: "claude-3-5-sonnet",
|
|
87
|
+
message_role: "assistant",
|
|
88
|
+
message_length: 250,
|
|
89
|
+
response_time_ms: 850,
|
|
90
|
+
finish_reason: "stop"
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### ChatGPT-Style Features
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { ai } from "@repo/analytics/shared";
|
|
98
|
+
|
|
99
|
+
// User regenerates a response
|
|
100
|
+
ai.MESSAGE_REGENERATED({
|
|
101
|
+
conversation_id: "conv_123",
|
|
102
|
+
model_id: "gpt-4",
|
|
103
|
+
original_message_id: "msg_457",
|
|
104
|
+
attempt_number: 2,
|
|
105
|
+
reason: "user-requested"
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// User edits their message
|
|
109
|
+
ai.MESSAGE_EDITED({
|
|
110
|
+
conversation_id: "conv_123",
|
|
111
|
+
model_id: "claude-3-5-sonnet",
|
|
112
|
+
message_id: "msg_456",
|
|
113
|
+
edit_type: "user-edit",
|
|
114
|
+
original_length: 50,
|
|
115
|
+
new_length: 75
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// User creates conversation branch
|
|
119
|
+
ai.BRANCH_CREATED({
|
|
120
|
+
conversation_id: "conv_123",
|
|
121
|
+
model_id: "gpt-4",
|
|
122
|
+
branch_point_message_id: "msg_457",
|
|
123
|
+
original_conversation_id: "conv_123",
|
|
124
|
+
new_conversation_id: "conv_124",
|
|
125
|
+
reason: "explore-alternative"
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// User stops generation mid-response
|
|
129
|
+
ai.STOP_GENERATION({
|
|
130
|
+
conversation_id: "conv_123",
|
|
131
|
+
model_id: "claude-3-5-sonnet",
|
|
132
|
+
message_id: "msg_458",
|
|
133
|
+
partial_length: 120,
|
|
134
|
+
stop_reason: "user-interrupted"
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Content Generation Tracking
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { ai } from "@repo/analytics/shared";
|
|
142
|
+
|
|
143
|
+
// Code generation
|
|
144
|
+
ai.CODE_GENERATED({
|
|
145
|
+
conversation_id: "conv_123",
|
|
146
|
+
model_id: "gpt-4",
|
|
147
|
+
language: "typescript",
|
|
148
|
+
code_length: 450,
|
|
149
|
+
code_type: "function",
|
|
150
|
+
has_explanation: true
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// User copies generated code
|
|
154
|
+
ai.CODE_COPIED({
|
|
155
|
+
conversation_id: "conv_123",
|
|
156
|
+
model_id: "gpt-4",
|
|
157
|
+
code_id: "code_789",
|
|
158
|
+
language: "typescript",
|
|
159
|
+
code_length: 450
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// User executes generated code
|
|
163
|
+
ai.CODE_EXECUTED({
|
|
164
|
+
conversation_id: "conv_123",
|
|
165
|
+
model_id: "gpt-4",
|
|
166
|
+
code_id: "code_789",
|
|
167
|
+
language: "typescript",
|
|
168
|
+
execution_status: "success",
|
|
169
|
+
execution_time_ms: 120
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Image generation
|
|
173
|
+
ai.IMAGE_GENERATED({
|
|
174
|
+
conversation_id: "conv_123",
|
|
175
|
+
model_id: "dall-e-3",
|
|
176
|
+
image_type: "generated",
|
|
177
|
+
prompt_length: 80,
|
|
178
|
+
image_format: "png",
|
|
179
|
+
image_size: "1024x1024"
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Summary generation
|
|
183
|
+
ai.SUMMARY_GENERATED({
|
|
184
|
+
conversation_id: "conv_123",
|
|
185
|
+
model_id: "claude-3-5-sonnet",
|
|
186
|
+
source_type: "document",
|
|
187
|
+
source_length: 5000,
|
|
188
|
+
summary_length: 300,
|
|
189
|
+
compression_ratio: 16.7
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Artifacts & Canvas (Claude-Style)
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { ai } from "@repo/analytics/shared";
|
|
197
|
+
|
|
198
|
+
// Create interactive artifact
|
|
199
|
+
ai.ARTIFACT_CREATED({
|
|
200
|
+
conversation_id: "conv_123",
|
|
201
|
+
model_id: "claude-3-5-sonnet",
|
|
202
|
+
artifact_id: "art_001",
|
|
203
|
+
artifact_type: "react-component",
|
|
204
|
+
action: "create",
|
|
205
|
+
language: "tsx"
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// User edits artifact
|
|
209
|
+
ai.ARTIFACT_EDITED({
|
|
210
|
+
conversation_id: "conv_123",
|
|
211
|
+
model_id: "claude-3-5-sonnet",
|
|
212
|
+
artifact_id: "art_001",
|
|
213
|
+
artifact_type: "react-component",
|
|
214
|
+
action: "edit",
|
|
215
|
+
version: 2
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// User forks artifact
|
|
219
|
+
ai.ARTIFACT_FORKED({
|
|
220
|
+
conversation_id: "conv_123",
|
|
221
|
+
model_id: "claude-3-5-sonnet",
|
|
222
|
+
artifact_id: "art_001",
|
|
223
|
+
artifact_type: "react-component",
|
|
224
|
+
action: "fork",
|
|
225
|
+
new_artifact_id: "art_002"
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Canvas mode
|
|
229
|
+
ai.CANVAS_OPENED({
|
|
230
|
+
conversation_id: "conv_123",
|
|
231
|
+
model_id: "claude-3-5-sonnet",
|
|
232
|
+
canvas_type: "code",
|
|
233
|
+
initial_content_length: 500
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Live preview
|
|
237
|
+
ai.LIVE_PREVIEW_TOGGLED({
|
|
238
|
+
conversation_id: "conv_123",
|
|
239
|
+
model_id: "claude-3-5-sonnet",
|
|
240
|
+
artifact_id: "art_001",
|
|
241
|
+
preview_enabled: true
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Files & Attachments
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { ai } from "@repo/analytics/shared";
|
|
249
|
+
|
|
250
|
+
// User uploads file
|
|
251
|
+
ai.FILE_UPLOADED({
|
|
252
|
+
conversation_id: "conv_123",
|
|
253
|
+
model_id: "gpt-4",
|
|
254
|
+
file_type: "pdf",
|
|
255
|
+
file_size_bytes: 1024000,
|
|
256
|
+
file_count: 1
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// File processed successfully
|
|
260
|
+
ai.FILE_PROCESSED({
|
|
261
|
+
conversation_id: "conv_123",
|
|
262
|
+
model_id: "gpt-4",
|
|
263
|
+
file_type: "pdf",
|
|
264
|
+
processing_time_ms: 2500,
|
|
265
|
+
extracted_text_length: 5000,
|
|
266
|
+
processing_status: "success"
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// File referenced in conversation
|
|
270
|
+
ai.FILE_REFERENCED({
|
|
271
|
+
conversation_id: "conv_123",
|
|
272
|
+
model_id: "gpt-4",
|
|
273
|
+
file_id: "file_123",
|
|
274
|
+
file_type: "pdf",
|
|
275
|
+
reference_context: "answer-question"
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Context & Memory
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { ai } from "@repo/analytics/shared";
|
|
283
|
+
|
|
284
|
+
// Custom instructions updated
|
|
285
|
+
ai.CUSTOM_INSTRUCTIONS_UPDATED({
|
|
286
|
+
model_id: "gpt-4",
|
|
287
|
+
user_id: "user_123",
|
|
288
|
+
instructions_length: 200,
|
|
289
|
+
has_preferences: true,
|
|
290
|
+
has_constraints: true
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Memory created
|
|
294
|
+
ai.MEMORY_CREATED({
|
|
295
|
+
conversation_id: "conv_123",
|
|
296
|
+
model_id: "claude-3-5-sonnet",
|
|
297
|
+
memory_type: "user-preference",
|
|
298
|
+
memory_content_length: 50,
|
|
299
|
+
memory_source: "explicit"
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// RAG query executed
|
|
303
|
+
ai.RAG_QUERY_EXECUTED({
|
|
304
|
+
conversation_id: "conv_123",
|
|
305
|
+
model_id: "gpt-4",
|
|
306
|
+
query_text: "Find documentation about React hooks",
|
|
307
|
+
query_embedding_dimensions: 1536,
|
|
308
|
+
chunks_retrieved: 5,
|
|
309
|
+
retrieval_time_ms: 150,
|
|
310
|
+
retrieval_status: "success"
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Collaboration & Sharing
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import { ai } from "@repo/analytics/shared";
|
|
318
|
+
|
|
319
|
+
// Share conversation
|
|
320
|
+
ai.CONVERSATION_SHARED({
|
|
321
|
+
conversation_id: "conv_123",
|
|
322
|
+
model_id: "claude-3-5-sonnet",
|
|
323
|
+
share_type: "public-link",
|
|
324
|
+
share_permissions: "view-only",
|
|
325
|
+
message_count: 15
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Fork conversation
|
|
329
|
+
ai.CONVERSATION_FORKED({
|
|
330
|
+
conversation_id: "conv_123",
|
|
331
|
+
model_id: "gpt-4",
|
|
332
|
+
original_conversation_id: "conv_123",
|
|
333
|
+
new_conversation_id: "conv_125",
|
|
334
|
+
forked_from_message_id: "msg_460"
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
// Team workspace created
|
|
338
|
+
ai.WORKSPACE_CREATED({
|
|
339
|
+
workspace_id: "ws_001",
|
|
340
|
+
model_id: "claude-3-5-sonnet",
|
|
341
|
+
workspace_type: "team",
|
|
342
|
+
member_count: 5
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Event Categories (90+ Events)
|
|
347
|
+
|
|
348
|
+
### 1. Conversation & Messaging (14 events)
|
|
349
|
+
|
|
350
|
+
Core conversation lifecycle and message management.
|
|
351
|
+
|
|
352
|
+
- `CONVERSATION_STARTED` - New conversation initiated
|
|
353
|
+
- `CONVERSATION_RESUMED` - Existing conversation reopened
|
|
354
|
+
- `CONVERSATION_ENDED` - Conversation closed or archived
|
|
355
|
+
- `MESSAGE_SENT` - User sends message
|
|
356
|
+
- `MESSAGE_RECEIVED` - AI responds to message
|
|
357
|
+
- `MESSAGE_REGENERATED` - User requests new response
|
|
358
|
+
- `MESSAGE_EDITED` - User or AI edits message
|
|
359
|
+
- `MESSAGE_DELETED` - Message removed from history
|
|
360
|
+
- `BRANCH_CREATED` - Alternative conversation path created
|
|
361
|
+
- `BRANCH_MERGED` - Conversation branches combined
|
|
362
|
+
- `STOP_GENERATION` - User stops mid-generation
|
|
363
|
+
- `STREAMING_STARTED` - Response streaming begins
|
|
364
|
+
- `STREAMING_CHUNK_RECEIVED` - Stream chunk delivered
|
|
365
|
+
- `STREAMING_COMPLETED` - Stream finished successfully
|
|
366
|
+
|
|
367
|
+
### 2. Content Generation (15 events)
|
|
368
|
+
|
|
369
|
+
All types of AI-generated content.
|
|
370
|
+
|
|
371
|
+
- `CODE_GENERATED` - Code snippet created
|
|
372
|
+
- `CODE_EXPLAINED` - Code explanation provided
|
|
373
|
+
- `CODE_DEBUGGED` - Debug suggestions offered
|
|
374
|
+
- `CODE_REFACTORED` - Code improvement suggested
|
|
375
|
+
- `CODE_TRANSLATED` - Code converted between languages
|
|
376
|
+
- `IMAGE_GENERATED` - Image created from prompt
|
|
377
|
+
- `IMAGE_EDITED` - Existing image modified
|
|
378
|
+
- `TEXT_GENERATED` - General text content created
|
|
379
|
+
- `SUMMARY_GENERATED` - Document/content summarized
|
|
380
|
+
- `TRANSLATION_GENERATED` - Text translated
|
|
381
|
+
- `COMPLETION_GENERATED` - Text completion provided
|
|
382
|
+
- `REWRITE_GENERATED` - Content rewritten
|
|
383
|
+
- `EMAIL_DRAFTED` - Email composition assisted
|
|
384
|
+
- `DOCUMENT_CREATED` - Document generated
|
|
385
|
+
- `OUTLINE_CREATED` - Content outline generated
|
|
386
|
+
|
|
387
|
+
### 3. Files & Attachments (7 events)
|
|
388
|
+
|
|
389
|
+
File upload, processing, and usage.
|
|
390
|
+
|
|
391
|
+
- `FILE_UPLOADED` - File attached to conversation
|
|
392
|
+
- `FILE_PROCESSED` - File successfully analyzed
|
|
393
|
+
- `FILE_PROCESSING_FAILED` - File analysis failed
|
|
394
|
+
- `FILE_DOWNLOADED` - Generated file downloaded
|
|
395
|
+
- `FILE_REFERENCED` - File context used in response
|
|
396
|
+
- `FILE_DELETED` - Attachment removed
|
|
397
|
+
- `BATCH_FILES_PROCESSED` - Multiple files processed
|
|
398
|
+
|
|
399
|
+
### 4. Search, Browse & Citations (6 events)
|
|
400
|
+
|
|
401
|
+
Web search and source attribution.
|
|
402
|
+
|
|
403
|
+
- `WEB_SEARCH_PERFORMED` - Internet search executed
|
|
404
|
+
- `CITATION_ADDED` - Source cited in response
|
|
405
|
+
- `BROWSE_SESSION_STARTED` - Web browsing initiated
|
|
406
|
+
- `PAGE_CONTENT_FETCHED` - Webpage content retrieved
|
|
407
|
+
- `SEARCH_RESULTS_RANKED` - Results ordered by relevance
|
|
408
|
+
- `EXTERNAL_SOURCE_ACCESSED` - Outside data referenced
|
|
409
|
+
|
|
410
|
+
### 5. Tools & Functions (7 events)
|
|
411
|
+
|
|
412
|
+
Tool calls and function execution.
|
|
413
|
+
|
|
414
|
+
- `TOOL_CALL_STARTED` - Tool execution begins
|
|
415
|
+
- `TOOL_CALL_COMPLETED` - Tool finishes successfully
|
|
416
|
+
- `TOOL_CALL_FAILED` - Tool execution error
|
|
417
|
+
- `FUNCTION_EXECUTED` - Custom function called
|
|
418
|
+
- `API_REQUEST_MADE` - External API called
|
|
419
|
+
- `PLUGIN_ACTIVATED` - Extension enabled
|
|
420
|
+
- `EXTENSION_USED` - Add-on functionality used
|
|
421
|
+
|
|
422
|
+
### 6. Context & Memory (10 events)
|
|
423
|
+
|
|
424
|
+
Context management and long-term memory.
|
|
425
|
+
|
|
426
|
+
- `CONTEXT_WINDOW_UPDATED` - Active context changed
|
|
427
|
+
- `MEMORY_CREATED` - New memory stored
|
|
428
|
+
- `MEMORY_RETRIEVED` - Past memory recalled
|
|
429
|
+
- `MEMORY_UPDATED` - Existing memory modified
|
|
430
|
+
- `MEMORY_DELETED` - Memory removed
|
|
431
|
+
- `CUSTOM_INSTRUCTIONS_UPDATED` - User preferences changed
|
|
432
|
+
- `PROJECT_CONTEXT_LOADED` - Project-specific context applied
|
|
433
|
+
- `RAG_QUERY_EXECUTED` - Vector search performed
|
|
434
|
+
- `EMBEDDING_GENERATED` - Text vectorized
|
|
435
|
+
- `KNOWLEDGE_BASE_QUERIED` - Internal knowledge searched
|
|
436
|
+
|
|
437
|
+
### 7. User Interactions (9 events)
|
|
438
|
+
|
|
439
|
+
User actions on generated content.
|
|
440
|
+
|
|
441
|
+
- `CODE_COPIED` - Code copied to clipboard
|
|
442
|
+
- `CODE_EXECUTED` - Code run in environment
|
|
443
|
+
- `CONTENT_COPIED` - General content copied
|
|
444
|
+
- `CONTENT_DOWNLOADED` - Content saved locally
|
|
445
|
+
- `CONTENT_SHARED` - Content shared externally
|
|
446
|
+
- `SUGGESTION_ACCEPTED` - AI suggestion applied
|
|
447
|
+
- `SUGGESTION_REJECTED` - AI suggestion dismissed
|
|
448
|
+
- `INLINE_EDIT_APPLIED` - Direct edit to AI content
|
|
449
|
+
- `DIFF_VIEWED` - Code changes reviewed
|
|
450
|
+
|
|
451
|
+
### 8. Workspace & Organization (7 events)
|
|
452
|
+
|
|
453
|
+
Organization and workspace management.
|
|
454
|
+
|
|
455
|
+
- `CONVERSATION_RENAMED` - Title changed
|
|
456
|
+
- `CONVERSATION_ARCHIVED` - Moved to archive
|
|
457
|
+
- `CONVERSATION_DELETED` - Permanently removed
|
|
458
|
+
- `FOLDER_CREATED` - Organization folder made
|
|
459
|
+
- `TAG_ADDED` - Conversation tagged
|
|
460
|
+
- `SEARCH_PERFORMED` - Conversation history searched
|
|
461
|
+
- `FILTER_APPLIED` - Conversation list filtered
|
|
462
|
+
|
|
463
|
+
### 9. Collaboration & Sharing (6 events)
|
|
464
|
+
|
|
465
|
+
Team features and sharing.
|
|
466
|
+
|
|
467
|
+
- `CONVERSATION_SHARED` - Conversation link shared
|
|
468
|
+
- `CONVERSATION_FORKED` - Copy created from original
|
|
469
|
+
- `WORKSPACE_CREATED` - Team workspace initialized
|
|
470
|
+
- `MEMBER_INVITED` - User added to workspace
|
|
471
|
+
- `COMMENT_ADDED` - Collaboration comment posted
|
|
472
|
+
- `PERMISSION_CHANGED` - Access level modified
|
|
473
|
+
|
|
474
|
+
### 10. Artifacts & Canvas (7 events)
|
|
475
|
+
|
|
476
|
+
Interactive artifacts and canvas mode (Claude-style).
|
|
477
|
+
|
|
478
|
+
- `ARTIFACT_CREATED` - Interactive artifact generated
|
|
479
|
+
- `ARTIFACT_EDITED` - Artifact modified
|
|
480
|
+
- `ARTIFACT_EXECUTED` - Artifact code run
|
|
481
|
+
- `ARTIFACT_PUBLISHED` - Artifact made available
|
|
482
|
+
- `ARTIFACT_FORKED` - Artifact copied
|
|
483
|
+
- `CANVAS_OPENED` - Canvas mode activated
|
|
484
|
+
- `LIVE_PREVIEW_TOGGLED` - Real-time preview toggled
|
|
485
|
+
|
|
486
|
+
### 11. Feedback & Quality (6 events)
|
|
487
|
+
|
|
488
|
+
User feedback and quality signals.
|
|
489
|
+
|
|
490
|
+
- `FEEDBACK_PROVIDED` - User rating submitted
|
|
491
|
+
- `RESPONSE_RATED` - Response quality scored
|
|
492
|
+
- `BUG_REPORTED` - Issue reported
|
|
493
|
+
- `FEATURE_REQUESTED` - Enhancement suggested
|
|
494
|
+
- `HARMFUL_CONTENT_FLAGGED` - Safety issue reported
|
|
495
|
+
- `QUALITY_ISSUE_REPORTED` - Quality problem noted
|
|
496
|
+
|
|
497
|
+
### 12. System & Performance (6 events)
|
|
498
|
+
|
|
499
|
+
Technical operations and model management.
|
|
500
|
+
|
|
501
|
+
- `MODEL_SWITCHED` - AI model changed
|
|
502
|
+
- `SETTINGS_UPDATED` - Configuration modified
|
|
503
|
+
- `ERROR_OCCURRED` - System error encountered
|
|
504
|
+
- `RATE_LIMIT_HIT` - Usage limit reached
|
|
505
|
+
- `TOKEN_USAGE_TRACKED` - Token consumption recorded
|
|
506
|
+
- `PERFORMANCE_MEASURED` - Metrics captured
|
|
507
|
+
|
|
508
|
+
## Property Types
|
|
509
|
+
|
|
510
|
+
### BaseAIProperties
|
|
511
|
+
|
|
512
|
+
Core properties shared across most events:
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
interface BaseAIProperties {
|
|
516
|
+
conversation_id?: string; // Links events to conversation
|
|
517
|
+
message_id?: string; // Specific message identifier
|
|
518
|
+
model_id: string; // Required: AI model used
|
|
519
|
+
model_provider?: "anthropic" | "openai" | "google" | "perplexity" | "other";
|
|
520
|
+
session_id?: string; // Browser/app session
|
|
521
|
+
user_id?: string; // User identifier
|
|
522
|
+
workspace_id?: string; // Team workspace
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### TokenUsageProperties
|
|
527
|
+
|
|
528
|
+
Token consumption tracking:
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
interface TokenUsageProperties {
|
|
532
|
+
input_tokens?: number;
|
|
533
|
+
output_tokens?: number;
|
|
534
|
+
total_tokens?: number;
|
|
535
|
+
cost?: number;
|
|
536
|
+
cost_currency?: string; // Default: 'USD'
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### ModelConfigProperties
|
|
541
|
+
|
|
542
|
+
Model configuration parameters:
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
interface ModelConfigProperties {
|
|
546
|
+
temperature?: number; // 0-2
|
|
547
|
+
max_output_tokens?: number;
|
|
548
|
+
top_p?: number; // 0-1
|
|
549
|
+
frequency_penalty?: number; // -2 to 2
|
|
550
|
+
presence_penalty?: number; // -2 to 2
|
|
551
|
+
seed?: number;
|
|
552
|
+
}
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
## Utility Functions
|
|
556
|
+
|
|
557
|
+
### cleanProperties
|
|
558
|
+
|
|
559
|
+
Remove undefined and null values:
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
import { cleanProperties } from "@repo/analytics/shared";
|
|
563
|
+
|
|
564
|
+
const cleaned = cleanProperties({
|
|
565
|
+
model_id: "gpt-4",
|
|
566
|
+
temperature: undefined,
|
|
567
|
+
max_tokens: null
|
|
568
|
+
});
|
|
569
|
+
// Result: { model_id: 'gpt-4' }
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### validateRequiredProperties
|
|
573
|
+
|
|
574
|
+
Validate required fields are present:
|
|
575
|
+
|
|
576
|
+
```typescript
|
|
577
|
+
import { validateRequiredProperties } from "@repo/analytics/shared";
|
|
578
|
+
|
|
579
|
+
validateRequiredProperties(properties, ["model_id", "conversation_id"]);
|
|
580
|
+
// Throws error if missing
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### extractModelProvider
|
|
584
|
+
|
|
585
|
+
Auto-detect provider from model ID:
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
import { extractModelProvider } from "@repo/analytics/shared";
|
|
589
|
+
|
|
590
|
+
const provider = extractModelProvider("claude-3-5-sonnet");
|
|
591
|
+
// Result: 'anthropic'
|
|
592
|
+
|
|
593
|
+
const provider2 = extractModelProvider("gpt-4-turbo");
|
|
594
|
+
// Result: 'openai'
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
## Integration Examples
|
|
598
|
+
|
|
599
|
+
### Next.js App Router - Chat Interface
|
|
600
|
+
|
|
601
|
+
```typescript
|
|
602
|
+
// app/api/chat/route.ts
|
|
603
|
+
import { streamText } from "ai";
|
|
604
|
+
import { openai } from "@ai-sdk/openai";
|
|
605
|
+
import { ai } from "@repo/analytics/server/next";
|
|
606
|
+
|
|
607
|
+
export async function POST(req: Request) {
|
|
608
|
+
const { messages, conversationId } = await req.json();
|
|
609
|
+
|
|
610
|
+
ai.MESSAGE_SENT({
|
|
611
|
+
conversation_id: conversationId,
|
|
612
|
+
model_id: "gpt-4",
|
|
613
|
+
message_role: "user",
|
|
614
|
+
message_length: messages[messages.length - 1].content.length
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
const result = await streamText({
|
|
618
|
+
model: openai("gpt-4"),
|
|
619
|
+
messages,
|
|
620
|
+
onFinish: ({ text, usage }) => {
|
|
621
|
+
ai.MESSAGE_RECEIVED({
|
|
622
|
+
conversation_id: conversationId,
|
|
623
|
+
model_id: "gpt-4",
|
|
624
|
+
message_role: "assistant",
|
|
625
|
+
message_length: text.length,
|
|
626
|
+
input_tokens: usage.promptTokens,
|
|
627
|
+
output_tokens: usage.completionTokens,
|
|
628
|
+
finish_reason: "stop"
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
return result.toAIStreamResponse();
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### React Client - Regenerate Feature
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
// components/ChatMessage.tsx
|
|
641
|
+
import { ai } from '@repo/analytics/client/next';
|
|
642
|
+
|
|
643
|
+
export function ChatMessage({ message, conversationId, onRegenerate }) {
|
|
644
|
+
const [attemptNumber, setAttemptNumber] = useState(1);
|
|
645
|
+
|
|
646
|
+
const handleRegenerate = () => {
|
|
647
|
+
setAttemptNumber(prev => prev + 1);
|
|
648
|
+
|
|
649
|
+
ai.MESSAGE_REGENERATED({
|
|
650
|
+
conversation_id: conversationId,
|
|
651
|
+
model_id: 'gpt-4',
|
|
652
|
+
original_message_id: message.id,
|
|
653
|
+
attempt_number: attemptNumber + 1,
|
|
654
|
+
reason: 'user-requested',
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
onRegenerate();
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
return (
|
|
661
|
+
<div>
|
|
662
|
+
<p>{message.content}</p>
|
|
663
|
+
{message.role === 'assistant' && (
|
|
664
|
+
<button onClick={handleRegenerate}>
|
|
665
|
+
↻ Regenerate
|
|
666
|
+
</button>
|
|
667
|
+
)}
|
|
668
|
+
</div>
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Conversation Branching
|
|
674
|
+
|
|
675
|
+
```typescript
|
|
676
|
+
// components/MessageBranching.tsx
|
|
677
|
+
import { ai } from '@repo/analytics/client/next';
|
|
678
|
+
|
|
679
|
+
export function MessageBranching({ message, conversationId }) {
|
|
680
|
+
const handleCreateBranch = async () => {
|
|
681
|
+
const newConversationId = generateId();
|
|
682
|
+
|
|
683
|
+
ai.BRANCH_CREATED({
|
|
684
|
+
conversation_id: conversationId,
|
|
685
|
+
model_id: 'claude-3-5-sonnet',
|
|
686
|
+
branch_point_message_id: message.id,
|
|
687
|
+
original_conversation_id: conversationId,
|
|
688
|
+
new_conversation_id: newConversationId,
|
|
689
|
+
reason: 'explore-alternative',
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
// Navigate to new conversation
|
|
693
|
+
router.push(`/chat/${newConversationId}`);
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
return (
|
|
697
|
+
<button onClick={handleCreateBranch}>
|
|
698
|
+
🌿 Branch conversation
|
|
699
|
+
</button>
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Code Generation with Execution
|
|
705
|
+
|
|
706
|
+
```typescript
|
|
707
|
+
// components/CodeBlock.tsx
|
|
708
|
+
import { ai } from '@repo/analytics/client/next';
|
|
709
|
+
|
|
710
|
+
export function CodeBlock({ code, language, conversationId, codeId }) {
|
|
711
|
+
const handleCopy = () => {
|
|
712
|
+
navigator.clipboard.writeText(code);
|
|
713
|
+
|
|
714
|
+
ai.CODE_COPIED({
|
|
715
|
+
conversation_id: conversationId,
|
|
716
|
+
model_id: 'gpt-4',
|
|
717
|
+
code_id: codeId,
|
|
718
|
+
language,
|
|
719
|
+
code_length: code.length,
|
|
720
|
+
});
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
const handleExecute = async () => {
|
|
724
|
+
const startTime = Date.now();
|
|
725
|
+
|
|
726
|
+
try {
|
|
727
|
+
const result = await executeCode(code, language);
|
|
728
|
+
|
|
729
|
+
ai.CODE_EXECUTED({
|
|
730
|
+
conversation_id: conversationId,
|
|
731
|
+
model_id: 'gpt-4',
|
|
732
|
+
code_id: codeId,
|
|
733
|
+
language,
|
|
734
|
+
execution_status: 'success',
|
|
735
|
+
execution_time_ms: Date.now() - startTime,
|
|
736
|
+
});
|
|
737
|
+
} catch (error) {
|
|
738
|
+
ai.CODE_EXECUTED({
|
|
739
|
+
conversation_id: conversationId,
|
|
740
|
+
model_id: 'gpt-4',
|
|
741
|
+
code_id: codeId,
|
|
742
|
+
language,
|
|
743
|
+
execution_status: 'error',
|
|
744
|
+
execution_time_ms: Date.now() - startTime,
|
|
745
|
+
error_message: error.message,
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
return (
|
|
751
|
+
<pre>
|
|
752
|
+
<code>{code}</code>
|
|
753
|
+
<button onClick={handleCopy}>Copy</button>
|
|
754
|
+
<button onClick={handleExecute}>▶ Run</button>
|
|
755
|
+
</pre>
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### Artifact Creation (Claude-Style)
|
|
761
|
+
|
|
762
|
+
````typescript
|
|
763
|
+
// app/api/chat/route.ts
|
|
764
|
+
import { ai } from "@repo/analytics/server/next";
|
|
765
|
+
|
|
766
|
+
function detectArtifact(text: string): ArtifactInfo | null {
|
|
767
|
+
// Detect if response should be an artifact
|
|
768
|
+
const hasCodeBlock = /```(\w+)/.test(text);
|
|
769
|
+
const isComponent = /export (default )?function/.test(text);
|
|
770
|
+
|
|
771
|
+
if (isComponent) {
|
|
772
|
+
return {
|
|
773
|
+
type: "react-component",
|
|
774
|
+
language: "tsx"
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
// ... more detection logic
|
|
778
|
+
|
|
779
|
+
return null;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
export async function POST(req: Request) {
|
|
783
|
+
const result = await streamText({
|
|
784
|
+
model: anthropic("claude-3-5-sonnet"),
|
|
785
|
+
messages,
|
|
786
|
+
onFinish: ({ text }) => {
|
|
787
|
+
const artifact = detectArtifact(text);
|
|
788
|
+
|
|
789
|
+
if (artifact) {
|
|
790
|
+
const artifactId = generateId();
|
|
791
|
+
|
|
792
|
+
ai.ARTIFACT_CREATED({
|
|
793
|
+
conversation_id: conversationId,
|
|
794
|
+
model_id: "claude-3-5-sonnet",
|
|
795
|
+
artifact_id: artifactId,
|
|
796
|
+
artifact_type: artifact.type,
|
|
797
|
+
action: "create",
|
|
798
|
+
language: artifact.language
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
return result.toAIStreamResponse();
|
|
805
|
+
}
|
|
806
|
+
````
|
|
807
|
+
|
|
808
|
+
## Best Practices
|
|
809
|
+
|
|
810
|
+
### 1. Always Include Model ID
|
|
811
|
+
|
|
812
|
+
```typescript
|
|
813
|
+
// ✅ Good
|
|
814
|
+
ai.MESSAGE_RECEIVED({
|
|
815
|
+
model_id: "claude-3-5-sonnet",
|
|
816
|
+
message_role: "assistant"
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
// ❌ Bad - model_id is required
|
|
820
|
+
ai.MESSAGE_RECEIVED({
|
|
821
|
+
message_role: "assistant"
|
|
822
|
+
});
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
### 2. Use Conversation IDs for Context
|
|
826
|
+
|
|
827
|
+
```typescript
|
|
828
|
+
// Track all related events with same conversation_id
|
|
829
|
+
const conversationId = generateId();
|
|
830
|
+
|
|
831
|
+
ai.CONVERSATION_STARTED({ conversation_id: conversationId, model_id: 'gpt-4' });
|
|
832
|
+
ai.MESSAGE_SENT({ conversation_id: conversationId, model_id: 'gpt-4', ... });
|
|
833
|
+
ai.MESSAGE_RECEIVED({ conversation_id: conversationId, model_id: 'gpt-4', ... });
|
|
834
|
+
ai.MESSAGE_REGENERATED({ conversation_id: conversationId, model_id: 'gpt-4', ... });
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
### 3. Track User Actions on Generated Content
|
|
838
|
+
|
|
839
|
+
```typescript
|
|
840
|
+
// Track when users interact with AI output
|
|
841
|
+
ai.CODE_GENERATED({ ... }); // AI creates code
|
|
842
|
+
ai.CODE_COPIED({ ... }); // User copies it
|
|
843
|
+
ai.CODE_EXECUTED({ ... }); // User runs it
|
|
844
|
+
|
|
845
|
+
ai.ARTIFACT_CREATED({ ... }); // AI creates artifact
|
|
846
|
+
ai.ARTIFACT_EDITED({ ... }); // User modifies it
|
|
847
|
+
ai.ARTIFACT_FORKED({ ... }); // User copies it
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
### 4. Sample High-Frequency Events
|
|
851
|
+
|
|
852
|
+
```typescript
|
|
853
|
+
// Don't track every single chunk in a stream
|
|
854
|
+
let chunkCount = 0;
|
|
855
|
+
stream.on('chunk', () => {
|
|
856
|
+
chunkCount++;
|
|
857
|
+
// Sample every 10th chunk
|
|
858
|
+
if (chunkCount % 10 === 0) {
|
|
859
|
+
ai.STREAMING_CHUNK_RECEIVED({
|
|
860
|
+
model_id: 'gpt-4',
|
|
861
|
+
chunk_index: chunkCount,
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
// Always track start and complete
|
|
867
|
+
ai.STREAMING_STARTED({ ... });
|
|
868
|
+
ai.STREAMING_COMPLETED({ chunk_count: chunkCount, ... });
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
### 5. Track Both Success and Failure
|
|
872
|
+
|
|
873
|
+
```typescript
|
|
874
|
+
try {
|
|
875
|
+
const result = await generateCode(prompt);
|
|
876
|
+
|
|
877
|
+
ai.CODE_GENERATED({
|
|
878
|
+
model_id: "gpt-4",
|
|
879
|
+
language: "typescript",
|
|
880
|
+
code_length: result.length,
|
|
881
|
+
code_type: "function"
|
|
882
|
+
});
|
|
883
|
+
} catch (error) {
|
|
884
|
+
ai.ERROR_OCCURRED({
|
|
885
|
+
model_id: "gpt-4",
|
|
886
|
+
error_type: "generation-failed",
|
|
887
|
+
error_message: error.message
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
## Advanced Usage
|
|
893
|
+
|
|
894
|
+
### Custom Context
|
|
895
|
+
|
|
896
|
+
```typescript
|
|
897
|
+
import { ai } from "@repo/analytics/server/next";
|
|
898
|
+
|
|
899
|
+
ai.MESSAGE_RECEIVED(
|
|
900
|
+
{
|
|
901
|
+
model_id: "claude-3-5-sonnet",
|
|
902
|
+
message_role: "assistant"
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
context: {
|
|
906
|
+
app: {
|
|
907
|
+
name: "ai-chatbot",
|
|
908
|
+
version: "2.0.0"
|
|
909
|
+
},
|
|
910
|
+
feature: {
|
|
911
|
+
name: "code-generation",
|
|
912
|
+
variant: "with-artifacts"
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
);
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
### Performance Tracking
|
|
920
|
+
|
|
921
|
+
```typescript
|
|
922
|
+
import { ai } from "@repo/analytics/client/next";
|
|
923
|
+
|
|
924
|
+
const startTime = performance.now();
|
|
925
|
+
|
|
926
|
+
await generateResponse();
|
|
927
|
+
|
|
928
|
+
const duration = performance.now() - startTime;
|
|
929
|
+
|
|
930
|
+
ai.PERFORMANCE_MEASURED({
|
|
931
|
+
model_id: "gpt-4",
|
|
932
|
+
operation_type: "message-generation",
|
|
933
|
+
duration_ms: duration,
|
|
934
|
+
performance_tier: duration < 1000 ? "fast" : duration < 3000 ? "normal" : "slow"
|
|
935
|
+
});
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
## Testing
|
|
939
|
+
|
|
940
|
+
```typescript
|
|
941
|
+
import { describe, it, expect } from "vitest";
|
|
942
|
+
import { ai } from "@repo/analytics/shared";
|
|
943
|
+
|
|
944
|
+
describe("AI Product Tracking", () => {
|
|
945
|
+
it("should track message regeneration", () => {
|
|
946
|
+
const payload = ai.MESSAGE_REGENERATED({
|
|
947
|
+
conversation_id: "conv_123",
|
|
948
|
+
model_id: "gpt-4",
|
|
949
|
+
original_message_id: "msg_456",
|
|
950
|
+
attempt_number: 2,
|
|
951
|
+
reason: "user-requested"
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
expect(payload.type).toBe("track");
|
|
955
|
+
expect(payload.event).toBe("AI Message Regenerated");
|
|
956
|
+
expect(payload.properties?.attempt_number).toBe(2);
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
it("should track conversation branching", () => {
|
|
960
|
+
const payload = ai.BRANCH_CREATED({
|
|
961
|
+
conversation_id: "conv_123",
|
|
962
|
+
model_id: "claude-3-5-sonnet",
|
|
963
|
+
branch_point_message_id: "msg_457",
|
|
964
|
+
original_conversation_id: "conv_123",
|
|
965
|
+
new_conversation_id: "conv_124",
|
|
966
|
+
reason: "explore-alternative"
|
|
967
|
+
});
|
|
968
|
+
|
|
969
|
+
expect(payload.type).toBe("track");
|
|
970
|
+
expect(payload.event).toBe("AI Branch Created");
|
|
971
|
+
expect(payload.properties?.new_conversation_id).toBe("conv_124");
|
|
972
|
+
});
|
|
973
|
+
});
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
## See Also
|
|
977
|
+
|
|
978
|
+
- [Analytics Package README](../../../README.md)
|
|
979
|
+
- [E-commerce Tracking](../ecommerce/README.md) - Separate business tracking
|
|
980
|
+
- [Types Reference](./types.ts) - Complete event and property type definitions
|
|
981
|
+
- [Segment.io Specification](https://segment.com/docs/connections/spec/)
|