langwatch 0.0.1

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 (132) hide show
  1. package/.eslintrc.cjs +37 -0
  2. package/README.md +3 -0
  3. package/dist/chunk-GOA2HL4A.mjs +269 -0
  4. package/dist/chunk-GOA2HL4A.mjs.map +1 -0
  5. package/dist/index.d.mts +82 -0
  6. package/dist/index.d.ts +82 -0
  7. package/dist/index.js +940 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/index.mjs +666 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/dist/utils-s3gGR6vj.d.mts +209 -0
  12. package/dist/utils-s3gGR6vj.d.ts +209 -0
  13. package/dist/utils.d.mts +3 -0
  14. package/dist/utils.d.ts +3 -0
  15. package/dist/utils.js +263 -0
  16. package/dist/utils.js.map +1 -0
  17. package/dist/utils.mjs +7 -0
  18. package/dist/utils.mjs.map +1 -0
  19. package/example/.env.example +12 -0
  20. package/example/.eslintrc.json +26 -0
  21. package/example/LICENSE +13 -0
  22. package/example/README.md +10 -0
  23. package/example/app/(chat)/chat/[id]/page.tsx +60 -0
  24. package/example/app/(chat)/layout.tsx +14 -0
  25. package/example/app/(chat)/page.tsx +22 -0
  26. package/example/app/actions.ts +156 -0
  27. package/example/app/globals.css +76 -0
  28. package/example/app/layout.tsx +64 -0
  29. package/example/app/login/actions.ts +71 -0
  30. package/example/app/login/page.tsx +18 -0
  31. package/example/app/new/page.tsx +5 -0
  32. package/example/app/opengraph-image.png +0 -0
  33. package/example/app/share/[id]/page.tsx +58 -0
  34. package/example/app/signup/actions.ts +111 -0
  35. package/example/app/signup/page.tsx +18 -0
  36. package/example/app/twitter-image.png +0 -0
  37. package/example/auth.config.ts +42 -0
  38. package/example/auth.ts +45 -0
  39. package/example/components/button-scroll-to-bottom.tsx +36 -0
  40. package/example/components/chat-history.tsx +49 -0
  41. package/example/components/chat-list.tsx +52 -0
  42. package/example/components/chat-message-actions.tsx +40 -0
  43. package/example/components/chat-message.tsx +80 -0
  44. package/example/components/chat-panel.tsx +139 -0
  45. package/example/components/chat-share-dialog.tsx +95 -0
  46. package/example/components/chat.tsx +84 -0
  47. package/example/components/clear-history.tsx +75 -0
  48. package/example/components/empty-screen.tsx +38 -0
  49. package/example/components/external-link.tsx +29 -0
  50. package/example/components/footer.tsx +19 -0
  51. package/example/components/header.tsx +80 -0
  52. package/example/components/login-button.tsx +42 -0
  53. package/example/components/login-form.tsx +97 -0
  54. package/example/components/markdown.tsx +9 -0
  55. package/example/components/prompt-form.tsx +115 -0
  56. package/example/components/providers.tsx +17 -0
  57. package/example/components/sidebar-actions.tsx +125 -0
  58. package/example/components/sidebar-desktop.tsx +19 -0
  59. package/example/components/sidebar-footer.tsx +16 -0
  60. package/example/components/sidebar-item.tsx +124 -0
  61. package/example/components/sidebar-items.tsx +42 -0
  62. package/example/components/sidebar-list.tsx +38 -0
  63. package/example/components/sidebar-mobile.tsx +31 -0
  64. package/example/components/sidebar-toggle.tsx +24 -0
  65. package/example/components/sidebar.tsx +21 -0
  66. package/example/components/signup-form.tsx +95 -0
  67. package/example/components/stocks/events-skeleton.tsx +31 -0
  68. package/example/components/stocks/events.tsx +30 -0
  69. package/example/components/stocks/index.tsx +36 -0
  70. package/example/components/stocks/message.tsx +134 -0
  71. package/example/components/stocks/spinner.tsx +16 -0
  72. package/example/components/stocks/stock-purchase.tsx +146 -0
  73. package/example/components/stocks/stock-skeleton.tsx +22 -0
  74. package/example/components/stocks/stock.tsx +210 -0
  75. package/example/components/stocks/stocks-skeleton.tsx +9 -0
  76. package/example/components/stocks/stocks.tsx +67 -0
  77. package/example/components/tailwind-indicator.tsx +14 -0
  78. package/example/components/theme-toggle.tsx +31 -0
  79. package/example/components/ui/alert-dialog.tsx +141 -0
  80. package/example/components/ui/badge.tsx +36 -0
  81. package/example/components/ui/button.tsx +57 -0
  82. package/example/components/ui/codeblock.tsx +148 -0
  83. package/example/components/ui/dialog.tsx +122 -0
  84. package/example/components/ui/dropdown-menu.tsx +205 -0
  85. package/example/components/ui/icons.tsx +507 -0
  86. package/example/components/ui/input.tsx +25 -0
  87. package/example/components/ui/label.tsx +26 -0
  88. package/example/components/ui/select.tsx +164 -0
  89. package/example/components/ui/separator.tsx +31 -0
  90. package/example/components/ui/sheet.tsx +140 -0
  91. package/example/components/ui/sonner.tsx +31 -0
  92. package/example/components/ui/switch.tsx +29 -0
  93. package/example/components/ui/textarea.tsx +24 -0
  94. package/example/components/ui/tooltip.tsx +30 -0
  95. package/example/components/user-menu.tsx +53 -0
  96. package/example/components.json +17 -0
  97. package/example/lib/chat/actions.tsx +606 -0
  98. package/example/lib/hooks/use-copy-to-clipboard.tsx +33 -0
  99. package/example/lib/hooks/use-enter-submit.tsx +23 -0
  100. package/example/lib/hooks/use-local-storage.ts +24 -0
  101. package/example/lib/hooks/use-scroll-anchor.tsx +86 -0
  102. package/example/lib/hooks/use-sidebar.tsx +60 -0
  103. package/example/lib/hooks/use-streamable-text.ts +25 -0
  104. package/example/lib/types.ts +41 -0
  105. package/example/lib/utils.ts +89 -0
  106. package/example/middleware.ts +8 -0
  107. package/example/next-env.d.ts +5 -0
  108. package/example/next.config.js +13 -0
  109. package/example/package-lock.json +9249 -0
  110. package/example/package.json +77 -0
  111. package/example/pnpm-lock.yaml +5712 -0
  112. package/example/postcss.config.js +6 -0
  113. package/example/prettier.config.cjs +34 -0
  114. package/example/public/apple-touch-icon.png +0 -0
  115. package/example/public/favicon-16x16.png +0 -0
  116. package/example/public/favicon.ico +0 -0
  117. package/example/public/next.svg +1 -0
  118. package/example/public/thirteen.svg +1 -0
  119. package/example/public/vercel.svg +1 -0
  120. package/example/tailwind.config.ts +81 -0
  121. package/example/tsconfig.json +35 -0
  122. package/package.json +45 -0
  123. package/src/helpers.ts +64 -0
  124. package/src/index.test.ts +255 -0
  125. package/src/index.ts +397 -0
  126. package/src/server/types/.gitkeep +0 -0
  127. package/src/types.ts +69 -0
  128. package/src/utils.ts +134 -0
  129. package/ts-to-zod.config.js +18 -0
  130. package/tsconfig.json +32 -0
  131. package/tsup.config.ts +10 -0
  132. package/vitest.config.ts +8 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,666 @@
1
+ import {
2
+ __spreadProps,
3
+ __spreadValues,
4
+ convertFromVercelAIMessages
5
+ } from "./chunk-GOA2HL4A.mjs";
6
+
7
+ // src/index.ts
8
+ import EventEmitter from "events";
9
+ import { nanoid } from "nanoid";
10
+ import { ZodError } from "zod";
11
+ import { fromZodError } from "zod-validation-error";
12
+
13
+ // src/helpers.ts
14
+ function camelToSnakeCase(str) {
15
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
16
+ }
17
+ function camelToSnakeCaseNested(obj) {
18
+ if (Array.isArray(obj)) {
19
+ return obj.map(
20
+ (item) => camelToSnakeCaseNested(item)
21
+ );
22
+ } else if (typeof obj === "object" && obj !== null) {
23
+ const newObj = {};
24
+ for (const key in obj) {
25
+ if (obj.hasOwnProperty(key)) {
26
+ const newKey = camelToSnakeCase(key);
27
+ newObj[newKey] = camelToSnakeCaseNested(obj[key]);
28
+ }
29
+ }
30
+ return newObj;
31
+ } else {
32
+ return obj;
33
+ }
34
+ }
35
+
36
+ // src/server/types/tracer.generated.ts
37
+ import { z } from "zod";
38
+ var chatRoleSchema = z.union([
39
+ z.literal("system"),
40
+ z.literal("user"),
41
+ z.literal("assistant"),
42
+ z.literal("function"),
43
+ z.literal("tool"),
44
+ z.literal("unknown")
45
+ ]);
46
+ var functionCallSchema = z.object({
47
+ name: z.string().optional(),
48
+ arguments: z.string().optional()
49
+ });
50
+ var toolCallSchema = z.object({
51
+ id: z.string(),
52
+ type: z.string(),
53
+ function: functionCallSchema
54
+ });
55
+ var chatRichContentSchema = z.union([
56
+ z.object({
57
+ type: z.literal("text"),
58
+ text: z.string().optional()
59
+ }),
60
+ z.object({
61
+ type: z.literal("image_url"),
62
+ image_url: z.object({
63
+ url: z.string(),
64
+ detail: z.union([z.literal("auto"), z.literal("low"), z.literal("high")]).optional()
65
+ }).optional()
66
+ })
67
+ ]);
68
+ var typedValueTextSchema = z.object({
69
+ type: z.literal("text"),
70
+ value: z.string()
71
+ });
72
+ var typedValueRawSchema = z.object({
73
+ type: z.literal("raw"),
74
+ value: z.string()
75
+ });
76
+ var jSONSerializableSchema = z.union([
77
+ z.string(),
78
+ z.number(),
79
+ z.boolean(),
80
+ z.record(z.any()),
81
+ z.array(z.any())
82
+ ]).nullable();
83
+ var typedValueJsonSchema = z.object({
84
+ type: z.literal("json"),
85
+ value: jSONSerializableSchema
86
+ });
87
+ var moneySchema = z.object({
88
+ currency: z.string(),
89
+ amount: z.number()
90
+ });
91
+ var guardrailResultSchema = z.object({
92
+ status: z.union([
93
+ z.literal("processed"),
94
+ z.literal("skipped"),
95
+ z.literal("error")
96
+ ]),
97
+ passed: z.boolean(),
98
+ score: z.number().optional().nullable(),
99
+ details: z.string().optional().nullable(),
100
+ cost: moneySchema.optional().nullable()
101
+ });
102
+ var typedValueGuardrailResultSchema = z.object({
103
+ type: z.literal("guardrail_result"),
104
+ value: guardrailResultSchema
105
+ });
106
+ var errorCaptureSchema = z.object({
107
+ has_error: z.literal(true),
108
+ message: z.string(),
109
+ stacktrace: z.array(z.string())
110
+ });
111
+ var spanMetricsSchema = z.object({
112
+ prompt_tokens: z.number().optional().nullable(),
113
+ completion_tokens: z.number().optional().nullable(),
114
+ tokens_estimated: z.boolean().optional().nullable(),
115
+ cost: z.number().optional().nullable()
116
+ });
117
+ var spanParamsSchema = z.object({
118
+ temperature: z.number().optional(),
119
+ stream: z.boolean().optional(),
120
+ functions: z.array(z.record(z.any())).optional(),
121
+ tools: z.array(z.record(z.any())).optional(),
122
+ tool_choice: z.string().optional()
123
+ });
124
+ var spanTimestampsSchema = z.object({
125
+ started_at: z.number(),
126
+ first_token_at: z.number().optional().nullable(),
127
+ finished_at: z.number()
128
+ });
129
+ var spanTypesSchema = z.union([
130
+ z.literal("span"),
131
+ z.literal("llm"),
132
+ z.literal("chain"),
133
+ z.literal("tool"),
134
+ z.literal("agent"),
135
+ z.literal("rag"),
136
+ z.literal("guardrail"),
137
+ z.literal("unknown")
138
+ ]);
139
+ var rAGChunkSchema = z.object({
140
+ document_id: z.string().optional().nullable(),
141
+ chunk_id: z.string().optional().nullable(),
142
+ content: z.union([z.string(), z.record(z.any()), z.array(z.any())])
143
+ });
144
+ var traceInputSchema = z.object({
145
+ value: z.string(),
146
+ embeddings: z.object({
147
+ model: z.string(),
148
+ embeddings: z.array(z.number())
149
+ }).optional(),
150
+ satisfaction_score: z.number().optional()
151
+ });
152
+ var traceOutputSchema = z.object({
153
+ value: z.string(),
154
+ embeddings: z.object({
155
+ model: z.string(),
156
+ embeddings: z.array(z.number())
157
+ }).optional()
158
+ });
159
+ var traceSchema = z.object({
160
+ trace_id: z.string(),
161
+ project_id: z.string(),
162
+ metadata: z.object({
163
+ thread_id: z.string().optional(),
164
+ user_id: z.string().optional(),
165
+ customer_id: z.string().optional(),
166
+ labels: z.array(z.string()).optional(),
167
+ topic_id: z.string().optional(),
168
+ subtopic_id: z.string().optional()
169
+ }),
170
+ timestamps: z.object({
171
+ started_at: z.number(),
172
+ inserted_at: z.number(),
173
+ updated_at: z.number()
174
+ }),
175
+ input: traceInputSchema,
176
+ output: traceOutputSchema.optional(),
177
+ metrics: z.object({
178
+ first_token_ms: z.number().optional().nullable(),
179
+ total_time_ms: z.number().optional().nullable(),
180
+ prompt_tokens: z.number().optional().nullable(),
181
+ completion_tokens: z.number().optional().nullable(),
182
+ total_cost: z.number().optional().nullable(),
183
+ tokens_estimated: z.boolean().optional().nullable()
184
+ }),
185
+ error: errorCaptureSchema.optional().nullable(),
186
+ indexing_md5s: z.array(z.string()).optional()
187
+ });
188
+ var elasticSearchTraceSchema = traceSchema.and(
189
+ z.object({
190
+ timestamps: traceSchema.shape.timestamps.and(
191
+ z.object({
192
+ updated_at: z.number()
193
+ })
194
+ )
195
+ })
196
+ );
197
+ var traceCheckSchema = z.object({
198
+ trace_id: z.string(),
199
+ check_id: z.string(),
200
+ project_id: z.string(),
201
+ check_type: z.string(),
202
+ check_name: z.string(),
203
+ is_guardrail: z.boolean(),
204
+ status: z.union([
205
+ z.literal("scheduled"),
206
+ z.literal("in_progress"),
207
+ z.literal("error"),
208
+ z.literal("skipped"),
209
+ z.literal("processed")
210
+ ]),
211
+ passed: z.boolean().optional(),
212
+ score: z.number().optional(),
213
+ details: z.string().optional(),
214
+ error: errorCaptureSchema.optional().nullable(),
215
+ retries: z.number().optional(),
216
+ timestamps: z.object({
217
+ inserted_at: z.number().optional(),
218
+ started_at: z.number().optional(),
219
+ finished_at: z.number().optional(),
220
+ updated_at: z.number()
221
+ }),
222
+ trace_metadata: z.object({
223
+ thread_id: z.string().optional(),
224
+ user_id: z.string().optional(),
225
+ customer_id: z.string().optional(),
226
+ labels: z.array(z.string()).optional(),
227
+ topics: z.array(z.string()).optional()
228
+ })
229
+ });
230
+ var experimentSchema = z.object({
231
+ experiment_id: z.string(),
232
+ variant: z.number()
233
+ });
234
+ var eventSchema = z.object({
235
+ event_id: z.string(),
236
+ event_type: z.string(),
237
+ project_id: z.string(),
238
+ metrics: z.record(z.number()),
239
+ event_details: z.record(z.string()),
240
+ trace_id: z.string().optional(),
241
+ trace_metadata: z.object({
242
+ thread_id: z.string().optional(),
243
+ user_id: z.string().optional(),
244
+ customer_id: z.string().optional(),
245
+ labels: z.array(z.string()).optional(),
246
+ topics: z.array(z.string()).optional()
247
+ }),
248
+ timestamps: z.object({
249
+ started_at: z.number(),
250
+ inserted_at: z.number(),
251
+ updated_at: z.number()
252
+ })
253
+ });
254
+ var elasticSearchEventSchema = eventSchema.omit({ metrics: true, event_details: true }).and(
255
+ z.object({
256
+ metrics: z.array(
257
+ z.object({
258
+ key: z.string(),
259
+ value: z.number()
260
+ })
261
+ ),
262
+ event_details: z.array(
263
+ z.object({
264
+ key: z.string(),
265
+ value: z.string()
266
+ })
267
+ )
268
+ })
269
+ );
270
+ var trackEventRESTParamsValidatorSchema = eventSchema.omit({
271
+ event_id: true,
272
+ project_id: true,
273
+ timestamps: true,
274
+ event_details: true,
275
+ trace_metadata: true
276
+ }).and(
277
+ z.object({
278
+ event_id: z.string().optional(),
279
+ event_details: z.record(z.string()).optional(),
280
+ timestamp: z.number().optional()
281
+ })
282
+ );
283
+ var chatMessageSchema = z.object({
284
+ role: chatRoleSchema.optional(),
285
+ content: z.union([z.string(), z.array(chatRichContentSchema)]).optional().nullable(),
286
+ function_call: functionCallSchema.optional().nullable(),
287
+ tool_calls: z.array(toolCallSchema).optional().nullable(),
288
+ tool_call_id: z.string().optional().nullable()
289
+ });
290
+ var typedValueChatMessagesSchema = z.object({
291
+ type: z.literal("chat_messages"),
292
+ value: z.array(chatMessageSchema)
293
+ });
294
+ var spanInputOutputSchema = z.union([
295
+ typedValueTextSchema,
296
+ typedValueChatMessagesSchema,
297
+ typedValueGuardrailResultSchema,
298
+ typedValueJsonSchema,
299
+ typedValueRawSchema
300
+ ]);
301
+ var baseSpanSchema = z.object({
302
+ span_id: z.string(),
303
+ parent_id: z.string().optional().nullable(),
304
+ trace_id: z.string(),
305
+ type: spanTypesSchema,
306
+ name: z.string().optional().nullable(),
307
+ input: spanInputOutputSchema.optional().nullable(),
308
+ outputs: z.array(spanInputOutputSchema),
309
+ error: errorCaptureSchema.optional().nullable(),
310
+ timestamps: spanTimestampsSchema,
311
+ metrics: spanMetricsSchema.optional().nullable()
312
+ });
313
+ var lLMSpanSchema = baseSpanSchema.extend({
314
+ type: z.literal("llm"),
315
+ vendor: z.string().optional().nullable(),
316
+ model: z.string(),
317
+ params: spanParamsSchema
318
+ });
319
+ var rAGSpanSchema = baseSpanSchema.extend({
320
+ type: z.literal("rag"),
321
+ contexts: z.array(rAGChunkSchema)
322
+ });
323
+ var spanSchema = z.union([
324
+ lLMSpanSchema,
325
+ rAGSpanSchema,
326
+ baseSpanSchema
327
+ ]);
328
+ var spanInputOutputValidatorSchema = spanInputOutputSchema.and(
329
+ z.object({
330
+ value: z.any()
331
+ })
332
+ );
333
+ var spanValidatorSchema = z.union([
334
+ lLMSpanSchema.omit({ input: true, outputs: true }),
335
+ rAGSpanSchema.omit({ input: true, outputs: true }),
336
+ baseSpanSchema.omit({ input: true, outputs: true })
337
+ ]).and(
338
+ z.object({
339
+ input: spanInputOutputValidatorSchema.optional().nullable(),
340
+ outputs: z.array(spanInputOutputValidatorSchema)
341
+ })
342
+ );
343
+ var collectorRESTParamsSchema = z.object({
344
+ trace_id: z.union([z.string(), z.undefined()]).optional().nullable(),
345
+ spans: z.array(spanSchema),
346
+ metadata: z.object({
347
+ user_id: z.union([z.string(), z.undefined()]).optional().nullable(),
348
+ thread_id: z.union([z.string(), z.undefined()]).optional().nullable(),
349
+ customer_id: z.union([z.string(), z.undefined()]).optional().nullable(),
350
+ labels: z.union([z.array(z.string()), z.undefined()]).optional().nullable(),
351
+ experiments: z.union([z.array(experimentSchema), z.undefined()]).optional().nullable()
352
+ }).optional()
353
+ });
354
+ var collectorRESTParamsValidatorSchema = collectorRESTParamsSchema.omit({ spans: true });
355
+ var datasetSpanSchema = z.union([
356
+ baseSpanSchema.omit({
357
+ project_id: true,
358
+ trace_id: true,
359
+ id: true,
360
+ timestamps: true,
361
+ metrics: true
362
+ }),
363
+ lLMSpanSchema.omit({
364
+ project_id: true,
365
+ trace_id: true,
366
+ id: true,
367
+ timestamps: true,
368
+ metrics: true
369
+ }),
370
+ rAGSpanSchema.omit({
371
+ project_id: true,
372
+ trace_id: true,
373
+ id: true,
374
+ timestamps: true,
375
+ metrics: true
376
+ })
377
+ ]);
378
+
379
+ // src/index.ts
380
+ var LangWatch = class extends EventEmitter {
381
+ constructor({
382
+ apiKey,
383
+ endpoint = ((_a) => (_a = process.env.LANGWATCH_ENDPOINT) != null ? _a : "https://app.langwatch.ai")()
384
+ } = {}) {
385
+ super();
386
+ const apiKey_ = apiKey != null ? apiKey : process.env.LANGWATCH_API_KEY;
387
+ if (!apiKey_) {
388
+ console.warn(
389
+ "[LangWatch] \u26A0\uFE0F LangWatch API key is not set, please set the LANGWATCH_API_KEY environment variable or pass it in the constructor. Traces will not be captured."
390
+ );
391
+ }
392
+ this.apiKey = apiKey_;
393
+ this.endpoint = endpoint;
394
+ }
395
+ getTrace({
396
+ traceId,
397
+ metadata
398
+ } = {}) {
399
+ return new LangWatchTrace({
400
+ client: this,
401
+ traceId: traceId != null ? traceId : `trace_${nanoid()}`,
402
+ metadata
403
+ });
404
+ }
405
+ async sendTrace(params) {
406
+ const backoff = [1e3, 2e3, 4e3, 8e3, 16e3];
407
+ for (const backoffTime of backoff) {
408
+ try {
409
+ await this._sendTrace(params);
410
+ return;
411
+ } catch (e) {
412
+ console.warn(
413
+ `[LangWatch] \u26A0\uFE0F Failed to send trace, retrying in ${backoffTime / 1e3}s`
414
+ );
415
+ await new Promise((resolve) => setTimeout(resolve, backoffTime));
416
+ }
417
+ }
418
+ console.warn("[LangWatch] \u26A0\uFE0F Failed to send trace, giving up");
419
+ }
420
+ async _sendTrace(params) {
421
+ if (params.spans.length === 0) {
422
+ return;
423
+ }
424
+ if (!this.apiKey) {
425
+ const error = new Error(
426
+ "[LangWatch] \u26A0\uFE0F LangWatch API key is not set, LLMs traces will not be sent, go to https://langwatch.ai to set it up"
427
+ );
428
+ this.emit("error", error);
429
+ console.warn(error.message);
430
+ return;
431
+ }
432
+ const response = await fetch(`${this.endpoint}/api/collector`, {
433
+ method: "POST",
434
+ headers: {
435
+ "X-Auth-Token": this.apiKey,
436
+ "Content-Type": "application/json"
437
+ },
438
+ body: JSON.stringify(params)
439
+ });
440
+ if (response.status === 429) {
441
+ const error = new Error(
442
+ "[LangWatch] \u26A0\uFE0F Rate limit exceeded, dropping message from being sent to LangWatch. Please check your dashboard to upgrade your plan."
443
+ );
444
+ this.emit("error", error);
445
+ console.warn(error.message);
446
+ return;
447
+ }
448
+ if (!response.ok) {
449
+ const error = new Error(
450
+ `[LangWatch] \u26A0\uFE0F Failed to send trace, status: ${response.status}`
451
+ );
452
+ this.emit("error", error);
453
+ throw error;
454
+ }
455
+ }
456
+ };
457
+ var LangWatchTrace = class {
458
+ constructor({
459
+ client,
460
+ traceId,
461
+ metadata
462
+ }) {
463
+ this.finishedSpans = {};
464
+ this.client = client;
465
+ this.traceId = traceId;
466
+ this.metadata = metadata;
467
+ }
468
+ update({ metadata }) {
469
+ var _a, _b;
470
+ this.metadata = __spreadValues(__spreadValues(__spreadValues({}, this.metadata), metadata), typeof metadata.labels !== "undefined" ? { labels: [...(_b = (_a = this.metadata) == null ? void 0 : _a.labels) != null ? _b : [], ...metadata.labels] } : {});
471
+ }
472
+ startSpan(params) {
473
+ const span = new LangWatchSpan(__spreadValues({
474
+ trace: this
475
+ }, params));
476
+ return span;
477
+ }
478
+ startLLMSpan(params) {
479
+ const span = new LangWatchLLMSpan(__spreadValues({
480
+ trace: this
481
+ }, params));
482
+ return span;
483
+ }
484
+ startRAGSpan(params) {
485
+ const span = new LangWatchRAGSpan(__spreadValues({
486
+ trace: this
487
+ }, params));
488
+ return span;
489
+ }
490
+ onEnd(span) {
491
+ this.finishedSpans[span.span_id] = span;
492
+ this.delayedSendSpans();
493
+ }
494
+ delayedSendSpans() {
495
+ clearTimeout(this.timeoutRef);
496
+ this.timeoutRef = setTimeout(() => {
497
+ void this.sendSpans();
498
+ }, 1e3);
499
+ }
500
+ async sendSpans() {
501
+ clearTimeout(this.timeoutRef);
502
+ let trace = void 0;
503
+ try {
504
+ trace = collectorRESTParamsSchema.parse({
505
+ trace_id: this.traceId,
506
+ metadata: camelToSnakeCaseNested(this.metadata),
507
+ spans: Object.values(this.finishedSpans)
508
+ });
509
+ } catch (error) {
510
+ if (error instanceof ZodError) {
511
+ console.warn("[LangWatch] \u26A0\uFE0F Failed to parse trace");
512
+ console.warn(fromZodError(error).message);
513
+ } else {
514
+ console.warn(error);
515
+ }
516
+ this.client.emit("error", error);
517
+ }
518
+ if (trace) {
519
+ await this.client.sendTrace(trace);
520
+ }
521
+ }
522
+ };
523
+ var LangWatchSpan = class _LangWatchSpan {
524
+ constructor({
525
+ trace,
526
+ spanId,
527
+ parentId,
528
+ type,
529
+ name,
530
+ input,
531
+ outputs,
532
+ error,
533
+ timestamps,
534
+ metrics
535
+ }) {
536
+ this.spanId = spanId != null ? spanId : `span_${nanoid()}`;
537
+ this.parentId = parentId;
538
+ this.trace = trace;
539
+ this.type = type != null ? type : "span";
540
+ this.name = name;
541
+ this.input = input;
542
+ this.outputs = outputs != null ? outputs : [];
543
+ this.error = error;
544
+ this.timestamps = timestamps != null ? timestamps : {
545
+ startedAt: Date.now()
546
+ };
547
+ this.metrics = metrics;
548
+ }
549
+ update(params) {
550
+ if (params.type) {
551
+ this.type = params.type;
552
+ }
553
+ if ("name" in params) {
554
+ this.name = params.name;
555
+ }
556
+ if ("input" in params) {
557
+ this.input = params.input;
558
+ }
559
+ if (params.outputs) {
560
+ this.outputs = params.outputs;
561
+ }
562
+ if ("error" in params) {
563
+ this.error = params.error;
564
+ }
565
+ if (params.timestamps) {
566
+ this.timestamps = params.timestamps;
567
+ }
568
+ if ("metrics" in params) {
569
+ this.metrics = params.metrics;
570
+ }
571
+ }
572
+ startSpan(params) {
573
+ const span = new _LangWatchSpan(__spreadValues({
574
+ trace: this.trace,
575
+ parentId: this.spanId
576
+ }, params));
577
+ return span;
578
+ }
579
+ startLLMSpan(params) {
580
+ const span = new LangWatchLLMSpan(__spreadValues({
581
+ trace: this.trace,
582
+ parentId: this.spanId
583
+ }, params));
584
+ return span;
585
+ }
586
+ startRAGSpan(params) {
587
+ const span = new LangWatchRAGSpan(__spreadValues({
588
+ trace: this.trace,
589
+ parentId: this.spanId
590
+ }, params));
591
+ return span;
592
+ }
593
+ end(params) {
594
+ this.timestamps.finishedAt = Date.now();
595
+ if (params) {
596
+ this.update(params);
597
+ }
598
+ try {
599
+ const finalSpan = spanSchema.parse(
600
+ camelToSnakeCaseNested(__spreadProps(__spreadValues({}, this), {
601
+ trace: void 0,
602
+ traceId: this.trace.traceId,
603
+ timestamps: __spreadProps(__spreadValues({}, this.timestamps), {
604
+ finishedAt: this.timestamps.finishedAt
605
+ })
606
+ }))
607
+ );
608
+ this.trace.onEnd(finalSpan);
609
+ } catch (error) {
610
+ if (error instanceof ZodError) {
611
+ console.warn("[LangWatch] \u26A0\uFE0F Failed to parse span");
612
+ console.warn(fromZodError(error).message);
613
+ } else {
614
+ console.warn(error);
615
+ }
616
+ this.trace.client.emit("error", error);
617
+ }
618
+ }
619
+ };
620
+ var LangWatchLLMSpan = class extends LangWatchSpan {
621
+ constructor(params) {
622
+ var _a, _b;
623
+ super(__spreadValues({}, params));
624
+ this.type = "llm";
625
+ this.model = (_a = params.model) != null ? _a : "unknown";
626
+ this.params = (_b = params.params) != null ? _b : {};
627
+ }
628
+ update(params) {
629
+ super.update(params);
630
+ if (params.model) {
631
+ this.model = params.model;
632
+ }
633
+ if (params.params) {
634
+ this.params = params.params;
635
+ }
636
+ }
637
+ end(params) {
638
+ super.end(params);
639
+ }
640
+ };
641
+ var LangWatchRAGSpan = class extends LangWatchSpan {
642
+ constructor(params) {
643
+ var _a;
644
+ super(__spreadValues({}, params));
645
+ this.type = "rag";
646
+ this.contexts = (_a = params.contexts) != null ? _a : [];
647
+ }
648
+ update(params) {
649
+ super.update(params);
650
+ if (params.contexts) {
651
+ this.contexts = params.contexts;
652
+ }
653
+ }
654
+ end(params) {
655
+ super.end(params);
656
+ }
657
+ };
658
+ export {
659
+ LangWatch,
660
+ LangWatchLLMSpan,
661
+ LangWatchRAGSpan,
662
+ LangWatchSpan,
663
+ LangWatchTrace,
664
+ convertFromVercelAIMessages
665
+ };
666
+ //# sourceMappingURL=index.mjs.map