langwatch 0.2.0 → 0.3.0-prerelease.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 (235) hide show
  1. package/.editorconfig +16 -0
  2. package/LICENSE +7 -0
  3. package/README.md +268 -1
  4. package/copy-types.sh +19 -8
  5. package/examples/langchain/.env.example +2 -0
  6. package/examples/langchain/README.md +42 -0
  7. package/examples/langchain/package-lock.json +2930 -0
  8. package/examples/langchain/package.json +27 -0
  9. package/examples/langchain/src/cli-markdown.d.ts +137 -0
  10. package/examples/langchain/src/index.ts +109 -0
  11. package/examples/langchain/tsconfig.json +25 -0
  12. package/examples/langgraph/.env.example +2 -0
  13. package/examples/langgraph/README.md +42 -0
  14. package/examples/langgraph/package-lock.json +3031 -0
  15. package/examples/langgraph/package.json +28 -0
  16. package/examples/langgraph/src/cli-markdown.d.ts +137 -0
  17. package/examples/langgraph/src/index.ts +196 -0
  18. package/examples/langgraph/tsconfig.json +25 -0
  19. package/examples/mastra/.env.example +2 -0
  20. package/examples/mastra/README.md +57 -0
  21. package/examples/mastra/package-lock.json +5296 -0
  22. package/examples/mastra/package.json +32 -0
  23. package/examples/mastra/src/cli-markdown.d.ts +137 -0
  24. package/examples/mastra/src/index.ts +120 -0
  25. package/examples/mastra/src/mastra/agents/weather-agent.ts +30 -0
  26. package/examples/mastra/src/mastra/index.ts +21 -0
  27. package/examples/mastra/src/mastra/tools/weather-tool.ts +102 -0
  28. package/examples/mastra/tsconfig.json +25 -0
  29. package/examples/vercel-ai/.env.example +2 -0
  30. package/examples/vercel-ai/README.md +38 -0
  31. package/examples/vercel-ai/package-lock.json +2571 -0
  32. package/examples/vercel-ai/package.json +27 -0
  33. package/examples/vercel-ai/src/cli-markdown.d.ts +137 -0
  34. package/examples/vercel-ai/src/index.ts +110 -0
  35. package/examples/vercel-ai/src/instrumentation.ts +9 -0
  36. package/examples/vercel-ai/tsconfig.json +25 -0
  37. package/package.json +78 -34
  38. package/src/__tests__/client-browser.test.ts +92 -0
  39. package/src/__tests__/client-node.test.ts +76 -0
  40. package/src/__tests__/client.test.ts +71 -0
  41. package/src/__tests__/integration/client-browser.test.ts +46 -0
  42. package/src/__tests__/integration/client-node.test.ts +46 -0
  43. package/src/client-browser.ts +70 -0
  44. package/src/client-node.ts +82 -0
  45. package/src/client-shared.ts +72 -0
  46. package/src/client.ts +119 -0
  47. package/src/evaluation/__tests__/record-evaluation.test.ts +112 -0
  48. package/src/evaluation/__tests__/run-evaluation.test.ts +171 -0
  49. package/src/evaluation/index.ts +2 -0
  50. package/src/evaluation/record-evaluation.ts +101 -0
  51. package/src/evaluation/run-evaluation.ts +133 -0
  52. package/src/evaluation/tracer.ts +3 -0
  53. package/src/evaluation/types.ts +23 -0
  54. package/src/index.ts +10 -593
  55. package/src/internal/api/__tests__/errors.test.ts +98 -0
  56. package/src/internal/api/client.ts +30 -0
  57. package/src/internal/api/errors.ts +32 -0
  58. package/src/internal/generated/types/.gitkeep +0 -0
  59. package/src/observability/__tests__/integration/base.test.ts +74 -0
  60. package/src/observability/__tests__/integration/browser-setup-ordering.test.ts +60 -0
  61. package/src/observability/__tests__/integration/complex-nested-spans.test.ts +29 -0
  62. package/src/observability/__tests__/integration/error-handling.test.ts +24 -0
  63. package/src/observability/__tests__/integration/langwatch-disabled-otel.test.ts +24 -0
  64. package/src/observability/__tests__/integration/langwatch-first-then-vercel.test.ts +24 -0
  65. package/src/observability/__tests__/integration/multiple-setup-attempts.test.ts +27 -0
  66. package/src/observability/__tests__/integration/otel-ordering.test.ts +27 -0
  67. package/src/observability/__tests__/integration/vercel-configurations.test.ts +20 -0
  68. package/src/observability/__tests__/integration/vercel-first-then-langwatch.test.ts +27 -0
  69. package/src/observability/__tests__/span.test.ts +214 -0
  70. package/src/observability/__tests__/trace.test.ts +180 -0
  71. package/src/observability/exporters/index.ts +1 -0
  72. package/src/observability/exporters/langwatch-exporter.ts +53 -0
  73. package/src/observability/index.ts +4 -0
  74. package/src/observability/instrumentation/langchain/__tests__/integration/langchain-chatbot.test.ts +112 -0
  75. package/src/observability/instrumentation/langchain/__tests__/langchain.test.ts +284 -0
  76. package/src/observability/instrumentation/langchain/index.ts +624 -0
  77. package/src/observability/processors/__tests__/filterable-batch-span-exporter.test.ts +98 -0
  78. package/src/observability/processors/filterable-batch-span-processor.ts +99 -0
  79. package/src/observability/processors/index.ts +1 -0
  80. package/src/observability/semconv/attributes.ts +185 -0
  81. package/src/observability/semconv/events.ts +42 -0
  82. package/src/observability/semconv/index.ts +16 -0
  83. package/src/observability/semconv/values.ts +159 -0
  84. package/src/observability/span.ts +728 -0
  85. package/src/observability/trace.ts +301 -0
  86. package/src/prompt/__tests__/prompt.test.ts +139 -0
  87. package/src/prompt/get-prompt-version.ts +49 -0
  88. package/src/prompt/get-prompt.ts +44 -0
  89. package/src/prompt/index.ts +3 -0
  90. package/src/prompt/prompt.ts +133 -0
  91. package/src/prompt/service.ts +221 -0
  92. package/src/prompt/tracer.ts +3 -0
  93. package/src/prompt/types.ts +0 -0
  94. package/ts-to-zod.config.js +11 -0
  95. package/tsconfig.json +3 -9
  96. package/tsup.config.ts +11 -1
  97. package/vitest.config.ts +1 -0
  98. package/dist/chunk-LKD2K67J.mjs +0 -717
  99. package/dist/chunk-LKD2K67J.mjs.map +0 -1
  100. package/dist/index.d.mts +0 -1030
  101. package/dist/index.d.ts +0 -1030
  102. package/dist/index.js +0 -27310
  103. package/dist/index.js.map +0 -1
  104. package/dist/index.mjs +0 -963
  105. package/dist/index.mjs.map +0 -1
  106. package/dist/utils-Cv-rUjJ1.d.mts +0 -313
  107. package/dist/utils-Cv-rUjJ1.d.ts +0 -313
  108. package/dist/utils.d.mts +0 -2
  109. package/dist/utils.d.ts +0 -2
  110. package/dist/utils.js +0 -709
  111. package/dist/utils.js.map +0 -1
  112. package/dist/utils.mjs +0 -11
  113. package/dist/utils.mjs.map +0 -1
  114. package/example/.env.example +0 -12
  115. package/example/.eslintrc.json +0 -26
  116. package/example/LICENSE +0 -13
  117. package/example/README.md +0 -12
  118. package/example/app/(chat)/chat/[id]/page.tsx +0 -60
  119. package/example/app/(chat)/layout.tsx +0 -14
  120. package/example/app/(chat)/page.tsx +0 -27
  121. package/example/app/actions.ts +0 -156
  122. package/example/app/globals.css +0 -76
  123. package/example/app/guardrails/page.tsx +0 -26
  124. package/example/app/langchain/page.tsx +0 -27
  125. package/example/app/langchain-rag/page.tsx +0 -28
  126. package/example/app/late-update/page.tsx +0 -27
  127. package/example/app/layout.tsx +0 -64
  128. package/example/app/login/actions.ts +0 -71
  129. package/example/app/login/page.tsx +0 -18
  130. package/example/app/manual/page.tsx +0 -27
  131. package/example/app/new/page.tsx +0 -5
  132. package/example/app/opengraph-image.png +0 -0
  133. package/example/app/share/[id]/page.tsx +0 -58
  134. package/example/app/signup/actions.ts +0 -111
  135. package/example/app/signup/page.tsx +0 -18
  136. package/example/app/twitter-image.png +0 -0
  137. package/example/auth.config.ts +0 -42
  138. package/example/auth.ts +0 -45
  139. package/example/components/button-scroll-to-bottom.tsx +0 -36
  140. package/example/components/chat-history.tsx +0 -49
  141. package/example/components/chat-list.tsx +0 -52
  142. package/example/components/chat-message-actions.tsx +0 -40
  143. package/example/components/chat-message.tsx +0 -80
  144. package/example/components/chat-panel.tsx +0 -139
  145. package/example/components/chat-share-dialog.tsx +0 -95
  146. package/example/components/chat.tsx +0 -84
  147. package/example/components/clear-history.tsx +0 -75
  148. package/example/components/empty-screen.tsx +0 -38
  149. package/example/components/external-link.tsx +0 -29
  150. package/example/components/footer.tsx +0 -19
  151. package/example/components/header.tsx +0 -114
  152. package/example/components/login-button.tsx +0 -42
  153. package/example/components/login-form.tsx +0 -97
  154. package/example/components/markdown.tsx +0 -9
  155. package/example/components/prompt-form.tsx +0 -115
  156. package/example/components/providers.tsx +0 -17
  157. package/example/components/sidebar-actions.tsx +0 -125
  158. package/example/components/sidebar-desktop.tsx +0 -19
  159. package/example/components/sidebar-footer.tsx +0 -16
  160. package/example/components/sidebar-item.tsx +0 -124
  161. package/example/components/sidebar-items.tsx +0 -42
  162. package/example/components/sidebar-list.tsx +0 -38
  163. package/example/components/sidebar-mobile.tsx +0 -31
  164. package/example/components/sidebar-toggle.tsx +0 -24
  165. package/example/components/sidebar.tsx +0 -21
  166. package/example/components/signup-form.tsx +0 -95
  167. package/example/components/stocks/events-skeleton.tsx +0 -31
  168. package/example/components/stocks/events.tsx +0 -30
  169. package/example/components/stocks/index.tsx +0 -36
  170. package/example/components/stocks/message.tsx +0 -134
  171. package/example/components/stocks/spinner.tsx +0 -16
  172. package/example/components/stocks/stock-purchase.tsx +0 -146
  173. package/example/components/stocks/stock-skeleton.tsx +0 -22
  174. package/example/components/stocks/stock.tsx +0 -210
  175. package/example/components/stocks/stocks-skeleton.tsx +0 -9
  176. package/example/components/stocks/stocks.tsx +0 -67
  177. package/example/components/tailwind-indicator.tsx +0 -14
  178. package/example/components/theme-toggle.tsx +0 -31
  179. package/example/components/ui/alert-dialog.tsx +0 -141
  180. package/example/components/ui/badge.tsx +0 -36
  181. package/example/components/ui/button.tsx +0 -57
  182. package/example/components/ui/codeblock.tsx +0 -148
  183. package/example/components/ui/dialog.tsx +0 -122
  184. package/example/components/ui/dropdown-menu.tsx +0 -205
  185. package/example/components/ui/icons.tsx +0 -507
  186. package/example/components/ui/input.tsx +0 -25
  187. package/example/components/ui/label.tsx +0 -26
  188. package/example/components/ui/select.tsx +0 -164
  189. package/example/components/ui/separator.tsx +0 -31
  190. package/example/components/ui/sheet.tsx +0 -140
  191. package/example/components/ui/sonner.tsx +0 -31
  192. package/example/components/ui/switch.tsx +0 -29
  193. package/example/components/ui/textarea.tsx +0 -24
  194. package/example/components/ui/tooltip.tsx +0 -30
  195. package/example/components/user-menu.tsx +0 -53
  196. package/example/components.json +0 -17
  197. package/example/instrumentation.ts +0 -11
  198. package/example/lib/chat/guardrails.tsx +0 -181
  199. package/example/lib/chat/langchain-rag.tsx +0 -191
  200. package/example/lib/chat/langchain.tsx +0 -112
  201. package/example/lib/chat/late-update.tsx +0 -208
  202. package/example/lib/chat/manual.tsx +0 -605
  203. package/example/lib/chat/vercel-ai.tsx +0 -576
  204. package/example/lib/hooks/use-copy-to-clipboard.tsx +0 -33
  205. package/example/lib/hooks/use-enter-submit.tsx +0 -23
  206. package/example/lib/hooks/use-local-storage.ts +0 -24
  207. package/example/lib/hooks/use-scroll-anchor.tsx +0 -86
  208. package/example/lib/hooks/use-sidebar.tsx +0 -60
  209. package/example/lib/hooks/use-streamable-text.ts +0 -25
  210. package/example/lib/types.ts +0 -41
  211. package/example/lib/utils.ts +0 -89
  212. package/example/middleware.ts +0 -8
  213. package/example/next-env.d.ts +0 -5
  214. package/example/next.config.js +0 -16
  215. package/example/package-lock.json +0 -10917
  216. package/example/package.json +0 -84
  217. package/example/pnpm-lock.yaml +0 -5712
  218. package/example/postcss.config.js +0 -6
  219. package/example/prettier.config.cjs +0 -34
  220. package/example/public/apple-touch-icon.png +0 -0
  221. package/example/public/favicon-16x16.png +0 -0
  222. package/example/public/favicon.ico +0 -0
  223. package/example/public/next.svg +0 -1
  224. package/example/public/thirteen.svg +0 -1
  225. package/example/public/vercel.svg +0 -1
  226. package/example/tailwind.config.ts +0 -81
  227. package/example/tsconfig.json +0 -35
  228. package/src/LangWatchExporter.ts +0 -96
  229. package/src/evaluations.ts +0 -219
  230. package/src/index.test.ts +0 -402
  231. package/src/langchain.ts +0 -557
  232. package/src/typeUtils.ts +0 -89
  233. package/src/types.ts +0 -82
  234. package/src/utils.ts +0 -205
  235. /package/src/{server/types → internal/generated/openapi}/.gitkeep +0 -0
package/src/index.test.ts DELETED
@@ -1,402 +0,0 @@
1
- import { AzureOpenAI, OpenAI } from "openai";
2
- import { LangWatch, convertFromVercelAIMessages } from "./index";
3
- import {
4
- describe,
5
- it,
6
- expect,
7
- vi,
8
- beforeEach,
9
- type SpyInstanceFn,
10
- } from "vitest";
11
- import { openai } from "@ai-sdk/openai";
12
- import { generateText, LanguageModel, type CoreMessage } from "ai";
13
- import "dotenv/config";
14
- import { version } from "../package.json";
15
-
16
- describe("LangWatch tracer", () => {
17
- let mockFetch: SpyInstanceFn;
18
-
19
- beforeEach(() => {
20
- const originalFetch = global.fetch;
21
- // Mocking fetch to test the right data was sent to the server
22
- mockFetch = vi.fn((url, ...args) => {
23
- if (url.includes("localhost.test")) {
24
- return Promise.resolve({
25
- ok: true,
26
- status: 200,
27
- json: () => Promise.resolve({ message: "Trace sent" }),
28
- });
29
- }
30
- return originalFetch(url, ...args);
31
- });
32
- // @ts-ignore
33
- global.fetch = mockFetch;
34
- });
35
-
36
- it("captures traces correctly", async () => {
37
- const langwatch = new LangWatch({
38
- apiKey: "test",
39
- endpoint: "http://localhost.test",
40
- });
41
- const trace = langwatch.getTrace();
42
- trace.update({
43
- metadata: { threadId: "123", userId: "123", labels: ["foo"] },
44
- });
45
- trace.update({ metadata: { userId: "456", labels: ["bar"] } });
46
-
47
- const span = trace.startSpan({
48
- name: "weather_function",
49
- input: {
50
- type: "json",
51
- value: {
52
- city: "Tokyo",
53
- },
54
- },
55
- });
56
- span.end({
57
- output: {
58
- type: "json",
59
- value: {
60
- WEATHER: "sunny",
61
- },
62
- },
63
- });
64
-
65
- expect(trace.metadata).toEqual({
66
- threadId: "123",
67
- userId: "456",
68
- labels: ["foo", "bar"],
69
- sdkLanguage: "typescript",
70
- sdkVersion: version,
71
- });
72
- expect(span.timestamps.startedAt).toBeDefined();
73
- expect(span.timestamps.finishedAt).toBeDefined();
74
-
75
- const ragSpan = trace.startRAGSpan({
76
- name: "my-vectordb-retrieval",
77
- input: { type: "text", value: "search query" },
78
- });
79
- ragSpan.end({
80
- contexts: [
81
- {
82
- documentId: "doc1",
83
- content: "document chunk 1",
84
- },
85
- {
86
- documentId: "doc2",
87
- content: { FOO: "document chunk 2" },
88
- },
89
- ],
90
- });
91
-
92
- const llmSpan = ragSpan.startLLMSpan({
93
- name: "llm",
94
- model: "gpt-3.5-turbo",
95
- input: {
96
- type: "chat_messages",
97
- value: [
98
- { role: "system", content: "You are a helpful assistant." },
99
- { role: "user", content: "What is the weather in Tokyo?" },
100
- ],
101
- },
102
- });
103
- llmSpan.end({
104
- output: {
105
- type: "chat_messages",
106
- value: [
107
- {
108
- role: "assistant",
109
- content: "It's cloudy in Tokyo.",
110
- },
111
- ],
112
- },
113
- });
114
-
115
- ragSpan.end();
116
-
117
- await trace.sendSpans();
118
-
119
- expect(mockFetch).toHaveBeenCalled();
120
- expect(mockFetch).toHaveBeenCalledWith(
121
- "http://localhost.test/api/collector",
122
- expect.objectContaining({
123
- method: "POST",
124
- headers: {
125
- "X-Auth-Token": "test",
126
- "Content-Type": "application/json",
127
- },
128
- body: expect.any(String),
129
- })
130
- );
131
-
132
- const firstCall: any = mockFetch.mock.calls[0];
133
- const requestBody = JSON.parse(firstCall[1].body);
134
- expect(requestBody.trace_id).toBeDefined();
135
- expect(requestBody.metadata).toEqual({
136
- thread_id: "123",
137
- user_id: "456",
138
- labels: ["foo", "bar"],
139
- sdk_language: "typescript",
140
- sdk_version: version,
141
- });
142
- expect(requestBody.spans.length).toBe(3);
143
- expect(requestBody.spans[0]).toEqual({
144
- span_id: expect.any(String),
145
- trace_id: expect.any(String),
146
- type: "span",
147
- name: "weather_function",
148
- input: {
149
- type: "json",
150
- value: { city: "Tokyo" },
151
- },
152
- output: {
153
- type: "json",
154
- value: { WEATHER: "sunny" },
155
- },
156
- timestamps: {
157
- started_at: expect.any(Number),
158
- finished_at: expect.any(Number),
159
- },
160
- });
161
- expect(requestBody.spans[1]).toEqual({
162
- span_id: expect.any(String),
163
- trace_id: expect.any(String),
164
- type: "rag",
165
- name: "my-vectordb-retrieval",
166
- input: { type: "text", value: "search query" },
167
- contexts: [
168
- { document_id: "doc1", content: "document chunk 1" },
169
- { document_id: "doc2", content: { FOO: "document chunk 2" } },
170
- ],
171
- timestamps: {
172
- started_at: expect.any(Number),
173
- finished_at: expect.any(Number),
174
- },
175
- });
176
- });
177
-
178
- it("captures exceptions", async () => {
179
- const langwatch = new LangWatch({
180
- apiKey: "test",
181
- endpoint: "http://localhost.test",
182
- });
183
- const trace = langwatch.getTrace();
184
- trace.update({
185
- metadata: { threadId: "123", userId: "123", labels: ["foo"] },
186
- });
187
- trace.update({ metadata: { userId: "456", labels: ["bar"] } });
188
-
189
- const span = trace.startSpan({
190
- name: "weather_function",
191
- input: {
192
- type: "json",
193
- value: {
194
- city: "Tokyo",
195
- },
196
- },
197
- });
198
-
199
- try {
200
- throw new Error("unexpected error");
201
- } catch (error) {
202
- span.end({
203
- error: error,
204
- });
205
- }
206
-
207
- await trace.sendSpans();
208
-
209
- expect(mockFetch).toHaveBeenCalled();
210
- const firstCall: any = mockFetch.mock.calls[0];
211
- const requestBody = JSON.parse(firstCall[1].body);
212
- expect(requestBody.spans[0].error).toEqual({
213
- has_error: true,
214
- message: "unexpected error",
215
- stacktrace: expect.any(Array),
216
- });
217
- });
218
-
219
- it.skip("captures openai llm call", async () => {
220
- const langwatch = new LangWatch({
221
- apiKey: "test",
222
- endpoint: "http://localhost.test",
223
- });
224
- const trace = langwatch.getTrace();
225
-
226
- // Model to be used and messages that will be sent to the LLM
227
- const model = "gpt-4o";
228
- const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
229
- { role: "system", content: "You are a helpful assistant." },
230
- {
231
- role: "user",
232
- content: "Write a tweet-size vegetarian lasagna recipe for 4 people.",
233
- },
234
- ];
235
-
236
- // Capture the llm call with a span
237
- const span = trace.startLLMSpan({
238
- name: "llm",
239
- model: model,
240
- input: {
241
- type: "chat_messages",
242
- value: messages,
243
- },
244
- });
245
-
246
- // Continue with the LLM call normally
247
- const openai = new OpenAI();
248
- const chatCompletion = await openai.chat.completions.create({
249
- messages: messages,
250
- model: model,
251
- });
252
-
253
- span.end({
254
- output: {
255
- type: "chat_messages",
256
- value: [chatCompletion.choices[0]!.message],
257
- },
258
- metrics: {
259
- promptTokens: chatCompletion.usage?.prompt_tokens,
260
- completionTokens: chatCompletion.usage?.completion_tokens,
261
- },
262
- });
263
-
264
- await trace.sendSpans();
265
-
266
- expect(mockFetch).toHaveBeenCalled();
267
- expect(mockFetch).toHaveBeenCalledWith(
268
- "http://localhost.test/api/collector",
269
- expect.objectContaining({
270
- method: "POST",
271
- headers: {
272
- "X-Auth-Token": "test",
273
- "Content-Type": "application/json",
274
- },
275
- body: expect.any(String),
276
- })
277
- );
278
- });
279
-
280
- it.skip("captures azure openai llm call", async () => {
281
- const langwatch = new LangWatch({
282
- apiKey: "test",
283
- endpoint: "http://localhost.test",
284
- });
285
- const trace = langwatch.getTrace();
286
-
287
- // Model to be used and messages that will be sent to the LLM
288
- const model = "gpt-4-turbo-2024-04-09";
289
- const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
290
- { role: "system", content: "You are a helpful assistant." },
291
- {
292
- role: "user",
293
- content: "Write a tweet-size vegetarian lasagna recipe for 4 people.",
294
- },
295
- ];
296
-
297
- // Capture the llm call with a span
298
- const span = trace.startLLMSpan({
299
- name: "llm",
300
- model: model,
301
- input: {
302
- type: "chat_messages",
303
- value: messages,
304
- },
305
- });
306
-
307
- // Continue with the LLM call normally
308
- const openai = new AzureOpenAI({
309
- apiKey: process.env.AZURE_OPENAI_API_KEY,
310
- apiVersion: "2024-02-01",
311
- endpoint: process.env.AZURE_OPENAI_ENDPOINT,
312
- });
313
- const chatCompletion = await openai.chat.completions.create({
314
- messages: messages,
315
- model: model,
316
- });
317
-
318
- span.end({
319
- output: {
320
- type: "chat_messages",
321
- value: [chatCompletion.choices[0]!.message],
322
- },
323
- metrics: {
324
- promptTokens: chatCompletion.usage?.prompt_tokens,
325
- completionTokens: chatCompletion.usage?.completion_tokens,
326
- },
327
- });
328
-
329
- await trace.sendSpans();
330
-
331
- expect(mockFetch).toHaveBeenCalled();
332
- expect(mockFetch).toHaveBeenCalledWith(
333
- "http://localhost.test/api/collector",
334
- expect.objectContaining({
335
- method: "POST",
336
- headers: {
337
- "X-Auth-Token": "test",
338
- "Content-Type": "application/json",
339
- },
340
- body: expect.any(String),
341
- })
342
- );
343
- });
344
-
345
- it.skip("captures vercel ai sdk call", async () => {
346
- const langwatch = new LangWatch({
347
- apiKey: "test",
348
- endpoint: "http://localhost.test",
349
- });
350
- const trace = langwatch.getTrace();
351
-
352
- // Model to be used and messages that will be sent to the LLM
353
- const model = openai("gpt-4o");
354
- const messages: CoreMessage[] = [
355
- { role: "system", content: "You are a helpful assistant." },
356
- {
357
- role: "user",
358
- content: "Write a tweet-size vegetarian lasagna recipe for 4 people.",
359
- },
360
- ];
361
-
362
- const span = trace.startLLMSpan({
363
- name: "llm",
364
- model: model.modelId,
365
- input: {
366
- type: "chat_messages",
367
- value: convertFromVercelAIMessages(messages),
368
- },
369
- });
370
-
371
- const response = await generateText({
372
- model: model as LanguageModel,
373
- messages: messages,
374
- });
375
-
376
- span.end({
377
- output: {
378
- type: "chat_messages",
379
- value: convertFromVercelAIMessages(response.response.messages),
380
- },
381
- metrics: {
382
- promptTokens: response.usage?.promptTokens,
383
- completionTokens: response.usage?.completionTokens,
384
- },
385
- });
386
-
387
- await trace.sendSpans();
388
-
389
- expect(mockFetch).toHaveBeenCalled();
390
- expect(mockFetch).toHaveBeenCalledWith(
391
- "http://localhost.test/api/collector",
392
- expect.objectContaining({
393
- method: "POST",
394
- headers: {
395
- "X-Auth-Token": "test",
396
- "Content-Type": "application/json",
397
- },
398
- body: expect.any(String),
399
- })
400
- );
401
- });
402
- });