langwatch 0.2.0 → 0.3.0-prerelease.2

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 (229) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +268 -1
  3. package/dist/chunk-4BZATFKJ.mjs +181 -0
  4. package/dist/chunk-4BZATFKJ.mjs.map +1 -0
  5. package/dist/chunk-CSC3CMIT.mjs +118 -0
  6. package/dist/chunk-CSC3CMIT.mjs.map +1 -0
  7. package/dist/chunk-F63YKTXA.mjs +47 -0
  8. package/dist/chunk-F63YKTXA.mjs.map +1 -0
  9. package/dist/chunk-G3AUABT7.js +4 -0
  10. package/dist/chunk-G3AUABT7.js.map +1 -0
  11. package/dist/chunk-HPC6Z7J4.js +118 -0
  12. package/dist/chunk-HPC6Z7J4.js.map +1 -0
  13. package/dist/chunk-KGDAENGD.js +50 -0
  14. package/dist/chunk-KGDAENGD.js.map +1 -0
  15. package/dist/chunk-LD74LVRU.js +47 -0
  16. package/dist/chunk-LD74LVRU.js.map +1 -0
  17. package/dist/chunk-OM7VY3XT.mjs +4 -0
  18. package/dist/chunk-PCQVQ7SB.js +45 -0
  19. package/dist/chunk-PCQVQ7SB.js.map +1 -0
  20. package/dist/chunk-PMBEK6YE.mjs +424 -0
  21. package/dist/chunk-PMBEK6YE.mjs.map +1 -0
  22. package/dist/chunk-PR3JDWC3.mjs +50 -0
  23. package/dist/chunk-PR3JDWC3.mjs.map +1 -0
  24. package/dist/chunk-PTJ6AAI7.js +360 -0
  25. package/dist/chunk-PTJ6AAI7.js.map +1 -0
  26. package/dist/chunk-QEWDG5QE.mjs +45 -0
  27. package/dist/chunk-QEWDG5QE.mjs.map +1 -0
  28. package/dist/chunk-REUCVT7A.mjs +39 -0
  29. package/dist/chunk-REUCVT7A.mjs.map +1 -0
  30. package/dist/chunk-SVJ7SCGB.js +424 -0
  31. package/dist/chunk-SVJ7SCGB.js.map +1 -0
  32. package/dist/chunk-VJSOCNPA.js +181 -0
  33. package/dist/chunk-VJSOCNPA.js.map +1 -0
  34. package/dist/chunk-WM2GRSRW.js +39 -0
  35. package/dist/chunk-WM2GRSRW.js.map +1 -0
  36. package/dist/chunk-Z5J5UI5E.mjs +360 -0
  37. package/dist/chunk-Z5J5UI5E.mjs.map +1 -0
  38. package/dist/client-B2HqIKg6.d.ts +51 -0
  39. package/dist/client-XyCqclCi.d.mts +51 -0
  40. package/dist/client-browser.d.mts +8 -0
  41. package/dist/client-browser.d.ts +8 -0
  42. package/dist/client-browser.js +83 -0
  43. package/dist/client-browser.js.map +1 -0
  44. package/dist/client-browser.mjs +83 -0
  45. package/dist/client-browser.mjs.map +1 -0
  46. package/dist/client-node.d.mts +8 -0
  47. package/dist/client-node.d.ts +8 -0
  48. package/dist/client-node.js +90 -0
  49. package/dist/client-node.js.map +1 -0
  50. package/dist/client-node.mjs +90 -0
  51. package/dist/client-node.mjs.map +1 -0
  52. package/dist/evaluation/index.d.mts +897 -0
  53. package/dist/evaluation/index.d.ts +897 -0
  54. package/dist/evaluation/index.js +13 -0
  55. package/dist/evaluation/index.js.map +1 -0
  56. package/dist/evaluation/index.mjs +13 -0
  57. package/dist/evaluation/index.mjs.map +1 -0
  58. package/dist/filterable-batch-span-processor-zO5kcjBY.d.mts +64 -0
  59. package/dist/filterable-batch-span-processor-zO5kcjBY.d.ts +64 -0
  60. package/dist/index.d.mts +45 -1027
  61. package/dist/index.d.ts +45 -1027
  62. package/dist/index.js +11 -27291
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +23 -956
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/observability/index.d.mts +260 -0
  67. package/dist/observability/index.d.ts +260 -0
  68. package/dist/observability/index.js +20 -0
  69. package/dist/observability/index.js.map +1 -0
  70. package/dist/observability/index.mjs +20 -0
  71. package/dist/observability/index.mjs.map +1 -0
  72. package/dist/observability/instrumentation/langchain/index.d.mts +40 -0
  73. package/dist/observability/instrumentation/langchain/index.d.ts +40 -0
  74. package/dist/observability/instrumentation/langchain/index.js +666 -0
  75. package/dist/observability/instrumentation/langchain/index.js.map +1 -0
  76. package/dist/observability/instrumentation/langchain/index.mjs +666 -0
  77. package/dist/observability/instrumentation/langchain/index.mjs.map +1 -0
  78. package/dist/prompt/index.d.mts +10 -0
  79. package/dist/prompt/index.d.ts +10 -0
  80. package/dist/prompt/index.js +18 -0
  81. package/dist/prompt/index.js.map +1 -0
  82. package/dist/prompt/index.mjs +18 -0
  83. package/dist/prompt/index.mjs.map +1 -0
  84. package/dist/prompt-BXJWdbQp.d.mts +1967 -0
  85. package/dist/prompt-BXJWdbQp.d.ts +1967 -0
  86. package/dist/record-evaluation-CmxMXa-3.d.mts +25 -0
  87. package/dist/record-evaluation-CmxMXa-3.d.ts +25 -0
  88. package/dist/trace-D-bZOuqb.d.mts +622 -0
  89. package/dist/trace-G2312klE.d.ts +622 -0
  90. package/package.json +86 -37
  91. package/.eslintrc.cjs +0 -37
  92. package/copy-types.sh +0 -17
  93. package/dist/chunk-LKD2K67J.mjs +0 -717
  94. package/dist/chunk-LKD2K67J.mjs.map +0 -1
  95. package/dist/utils-Cv-rUjJ1.d.mts +0 -313
  96. package/dist/utils-Cv-rUjJ1.d.ts +0 -313
  97. package/dist/utils.d.mts +0 -2
  98. package/dist/utils.d.ts +0 -2
  99. package/dist/utils.js +0 -709
  100. package/dist/utils.js.map +0 -1
  101. package/dist/utils.mjs +0 -11
  102. package/example/.env.example +0 -12
  103. package/example/.eslintrc.json +0 -26
  104. package/example/LICENSE +0 -13
  105. package/example/README.md +0 -12
  106. package/example/app/(chat)/chat/[id]/page.tsx +0 -60
  107. package/example/app/(chat)/layout.tsx +0 -14
  108. package/example/app/(chat)/page.tsx +0 -27
  109. package/example/app/actions.ts +0 -156
  110. package/example/app/globals.css +0 -76
  111. package/example/app/guardrails/page.tsx +0 -26
  112. package/example/app/langchain/page.tsx +0 -27
  113. package/example/app/langchain-rag/page.tsx +0 -28
  114. package/example/app/late-update/page.tsx +0 -27
  115. package/example/app/layout.tsx +0 -64
  116. package/example/app/login/actions.ts +0 -71
  117. package/example/app/login/page.tsx +0 -18
  118. package/example/app/manual/page.tsx +0 -27
  119. package/example/app/new/page.tsx +0 -5
  120. package/example/app/opengraph-image.png +0 -0
  121. package/example/app/share/[id]/page.tsx +0 -58
  122. package/example/app/signup/actions.ts +0 -111
  123. package/example/app/signup/page.tsx +0 -18
  124. package/example/app/twitter-image.png +0 -0
  125. package/example/auth.config.ts +0 -42
  126. package/example/auth.ts +0 -45
  127. package/example/components/button-scroll-to-bottom.tsx +0 -36
  128. package/example/components/chat-history.tsx +0 -49
  129. package/example/components/chat-list.tsx +0 -52
  130. package/example/components/chat-message-actions.tsx +0 -40
  131. package/example/components/chat-message.tsx +0 -80
  132. package/example/components/chat-panel.tsx +0 -139
  133. package/example/components/chat-share-dialog.tsx +0 -95
  134. package/example/components/chat.tsx +0 -84
  135. package/example/components/clear-history.tsx +0 -75
  136. package/example/components/empty-screen.tsx +0 -38
  137. package/example/components/external-link.tsx +0 -29
  138. package/example/components/footer.tsx +0 -19
  139. package/example/components/header.tsx +0 -114
  140. package/example/components/login-button.tsx +0 -42
  141. package/example/components/login-form.tsx +0 -97
  142. package/example/components/markdown.tsx +0 -9
  143. package/example/components/prompt-form.tsx +0 -115
  144. package/example/components/providers.tsx +0 -17
  145. package/example/components/sidebar-actions.tsx +0 -125
  146. package/example/components/sidebar-desktop.tsx +0 -19
  147. package/example/components/sidebar-footer.tsx +0 -16
  148. package/example/components/sidebar-item.tsx +0 -124
  149. package/example/components/sidebar-items.tsx +0 -42
  150. package/example/components/sidebar-list.tsx +0 -38
  151. package/example/components/sidebar-mobile.tsx +0 -31
  152. package/example/components/sidebar-toggle.tsx +0 -24
  153. package/example/components/sidebar.tsx +0 -21
  154. package/example/components/signup-form.tsx +0 -95
  155. package/example/components/stocks/events-skeleton.tsx +0 -31
  156. package/example/components/stocks/events.tsx +0 -30
  157. package/example/components/stocks/index.tsx +0 -36
  158. package/example/components/stocks/message.tsx +0 -134
  159. package/example/components/stocks/spinner.tsx +0 -16
  160. package/example/components/stocks/stock-purchase.tsx +0 -146
  161. package/example/components/stocks/stock-skeleton.tsx +0 -22
  162. package/example/components/stocks/stock.tsx +0 -210
  163. package/example/components/stocks/stocks-skeleton.tsx +0 -9
  164. package/example/components/stocks/stocks.tsx +0 -67
  165. package/example/components/tailwind-indicator.tsx +0 -14
  166. package/example/components/theme-toggle.tsx +0 -31
  167. package/example/components/ui/alert-dialog.tsx +0 -141
  168. package/example/components/ui/badge.tsx +0 -36
  169. package/example/components/ui/button.tsx +0 -57
  170. package/example/components/ui/codeblock.tsx +0 -148
  171. package/example/components/ui/dialog.tsx +0 -122
  172. package/example/components/ui/dropdown-menu.tsx +0 -205
  173. package/example/components/ui/icons.tsx +0 -507
  174. package/example/components/ui/input.tsx +0 -25
  175. package/example/components/ui/label.tsx +0 -26
  176. package/example/components/ui/select.tsx +0 -164
  177. package/example/components/ui/separator.tsx +0 -31
  178. package/example/components/ui/sheet.tsx +0 -140
  179. package/example/components/ui/sonner.tsx +0 -31
  180. package/example/components/ui/switch.tsx +0 -29
  181. package/example/components/ui/textarea.tsx +0 -24
  182. package/example/components/ui/tooltip.tsx +0 -30
  183. package/example/components/user-menu.tsx +0 -53
  184. package/example/components.json +0 -17
  185. package/example/instrumentation.ts +0 -11
  186. package/example/lib/chat/guardrails.tsx +0 -181
  187. package/example/lib/chat/langchain-rag.tsx +0 -191
  188. package/example/lib/chat/langchain.tsx +0 -112
  189. package/example/lib/chat/late-update.tsx +0 -208
  190. package/example/lib/chat/manual.tsx +0 -605
  191. package/example/lib/chat/vercel-ai.tsx +0 -576
  192. package/example/lib/hooks/use-copy-to-clipboard.tsx +0 -33
  193. package/example/lib/hooks/use-enter-submit.tsx +0 -23
  194. package/example/lib/hooks/use-local-storage.ts +0 -24
  195. package/example/lib/hooks/use-scroll-anchor.tsx +0 -86
  196. package/example/lib/hooks/use-sidebar.tsx +0 -60
  197. package/example/lib/hooks/use-streamable-text.ts +0 -25
  198. package/example/lib/types.ts +0 -41
  199. package/example/lib/utils.ts +0 -89
  200. package/example/middleware.ts +0 -8
  201. package/example/next-env.d.ts +0 -5
  202. package/example/next.config.js +0 -16
  203. package/example/package-lock.json +0 -10917
  204. package/example/package.json +0 -84
  205. package/example/pnpm-lock.yaml +0 -5712
  206. package/example/postcss.config.js +0 -6
  207. package/example/prettier.config.cjs +0 -34
  208. package/example/public/apple-touch-icon.png +0 -0
  209. package/example/public/favicon-16x16.png +0 -0
  210. package/example/public/favicon.ico +0 -0
  211. package/example/public/next.svg +0 -1
  212. package/example/public/thirteen.svg +0 -1
  213. package/example/public/vercel.svg +0 -1
  214. package/example/tailwind.config.ts +0 -81
  215. package/example/tsconfig.json +0 -35
  216. package/src/LangWatchExporter.ts +0 -96
  217. package/src/evaluations.ts +0 -219
  218. package/src/index.test.ts +0 -402
  219. package/src/index.ts +0 -596
  220. package/src/langchain.ts +0 -557
  221. package/src/server/types/.gitkeep +0 -0
  222. package/src/typeUtils.ts +0 -89
  223. package/src/types.ts +0 -82
  224. package/src/utils.ts +0 -205
  225. package/ts-to-zod.config.js +0 -24
  226. package/tsconfig.json +0 -32
  227. package/tsup.config.ts +0 -10
  228. package/vitest.config.ts +0 -8
  229. /package/dist/{utils.mjs.map → chunk-OM7VY3XT.mjs.map} +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
- });