arkna-sdk 0.1.0
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/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +562 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +257 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +948 -0
- package/dist/client.js.map +1 -0
- package/dist/enforcement.d.ts +67 -0
- package/dist/enforcement.d.ts.map +1 -0
- package/dist/enforcement.js +303 -0
- package/dist/enforcement.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +74 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +333 -0
- package/dist/init.js.map +1 -0
- package/dist/instrumentations/langchain.d.ts +79 -0
- package/dist/instrumentations/langchain.d.ts.map +1 -0
- package/dist/instrumentations/langchain.js +398 -0
- package/dist/instrumentations/langchain.js.map +1 -0
- package/dist/instrumentations/vercel-ai.d.ts +40 -0
- package/dist/instrumentations/vercel-ai.d.ts.map +1 -0
- package/dist/instrumentations/vercel-ai.js +212 -0
- package/dist/instrumentations/vercel-ai.js.map +1 -0
- package/dist/license.d.ts +89 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +198 -0
- package/dist/license.js.map +1 -0
- package/dist/types.d.ts +402 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ARKNA LangChain Auto-Instrumentation
|
|
4
|
+
*
|
|
5
|
+
* Callback handler that automatically captures LangChain chain/agent
|
|
6
|
+
* executions as ARKNA observability runs — no manual SDK calls needed.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { ArknaClient, ArknaLangChainHandler } from '@arkna/sdk';
|
|
10
|
+
* const client = new ArknaClient();
|
|
11
|
+
* const handler = new ArknaLangChainHandler(client);
|
|
12
|
+
* const result = await chain.invoke(input, { callbacks: [handler] });
|
|
13
|
+
*
|
|
14
|
+
* Requires: langchain >= 0.2.0 (peer dependency, not bundled)
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.ArknaLangChainHandler = void 0;
|
|
18
|
+
/**
|
|
19
|
+
* LangChain callback handler that auto-captures runs into ARKNA observability.
|
|
20
|
+
*
|
|
21
|
+
* Event mapping:
|
|
22
|
+
* chain start → startRun() (top-level) or recordStep(reasoning) (nested)
|
|
23
|
+
* LLM start → recordStep(reasoning)
|
|
24
|
+
* LLM end → update step with output + token usage
|
|
25
|
+
* tool start → recordToolCall()
|
|
26
|
+
* tool end → (tool result captured)
|
|
27
|
+
* retriever → recordStep(retrieval)
|
|
28
|
+
* chain end → completeRun(completed)
|
|
29
|
+
* chain error → completeRun(failed)
|
|
30
|
+
*
|
|
31
|
+
* This class dynamically extends BaseCallbackHandler at runtime so that
|
|
32
|
+
* `@langchain/core` is only required at runtime (peer dependency).
|
|
33
|
+
*/
|
|
34
|
+
class ArknaLangChainHandler {
|
|
35
|
+
client;
|
|
36
|
+
sessionId;
|
|
37
|
+
trigger;
|
|
38
|
+
runMetadata;
|
|
39
|
+
// Track active runs: LangChain runId → ARKNA state
|
|
40
|
+
runs = new Map();
|
|
41
|
+
// Map LangChain parent runId → top-level ARKNA runId
|
|
42
|
+
parentToArknaRun = new Map();
|
|
43
|
+
// Track the root run ID
|
|
44
|
+
rootRunId = null;
|
|
45
|
+
// The actual LangChain BaseCallbackHandler instance (created lazily)
|
|
46
|
+
_handler = null;
|
|
47
|
+
constructor(client, options) {
|
|
48
|
+
this.client = client;
|
|
49
|
+
this.sessionId = options?.sessionId;
|
|
50
|
+
this.trigger = options?.trigger ?? 'langchain';
|
|
51
|
+
this.runMetadata = options?.metadata ?? {};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the LangChain-compatible callback handler instance.
|
|
55
|
+
* Lazily creates a BaseCallbackHandler subclass on first access.
|
|
56
|
+
* Pass this to LangChain's `callbacks` option.
|
|
57
|
+
*/
|
|
58
|
+
get handler() {
|
|
59
|
+
if (!this._handler) {
|
|
60
|
+
this._handler = this.createHandler();
|
|
61
|
+
}
|
|
62
|
+
return this._handler;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Also allow using the ArknaLangChainHandler directly as a callback
|
|
66
|
+
* by implementing the key callback methods on the instance itself.
|
|
67
|
+
* LangChain checks for method existence, so this works as a duck-typed handler.
|
|
68
|
+
*/
|
|
69
|
+
createHandler() {
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
71
|
+
const self = this;
|
|
72
|
+
try {
|
|
73
|
+
// Try to dynamically import and extend BaseCallbackHandler
|
|
74
|
+
const { BaseCallbackHandler } = require('@langchain/core/callbacks/base');
|
|
75
|
+
class ArknaHandler extends BaseCallbackHandler {
|
|
76
|
+
name = 'ArknaLangChainHandler';
|
|
77
|
+
async handleChainStart(chain, inputs, runId, parentRunId) {
|
|
78
|
+
return self.handleChainStart(chain, inputs, runId, parentRunId);
|
|
79
|
+
}
|
|
80
|
+
async handleChainEnd(outputs, runId) {
|
|
81
|
+
return self.handleChainEnd(outputs, runId);
|
|
82
|
+
}
|
|
83
|
+
async handleChainError(err, runId) {
|
|
84
|
+
return self.handleChainError(err, runId);
|
|
85
|
+
}
|
|
86
|
+
async handleLLMStart(llm, prompts, runId, parentRunId) {
|
|
87
|
+
return self.handleLLMStart(llm, prompts, runId, parentRunId);
|
|
88
|
+
}
|
|
89
|
+
async handleLLMEnd(output, runId) {
|
|
90
|
+
return self.handleLLMEnd(output, runId);
|
|
91
|
+
}
|
|
92
|
+
async handleLLMError(err, runId) {
|
|
93
|
+
return self.handleLLMError(err, runId);
|
|
94
|
+
}
|
|
95
|
+
async handleToolStart(tool, input, runId, parentRunId) {
|
|
96
|
+
return self.handleToolStart(tool, input, runId, parentRunId);
|
|
97
|
+
}
|
|
98
|
+
async handleToolEnd(_output, _runId) { }
|
|
99
|
+
async handleToolError(err, runId) {
|
|
100
|
+
return self.handleToolError(err, runId);
|
|
101
|
+
}
|
|
102
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId) {
|
|
103
|
+
return self.handleRetrieverStart(retriever, query, runId, parentRunId);
|
|
104
|
+
}
|
|
105
|
+
async handleRetrieverEnd(documents, runId) {
|
|
106
|
+
return self.handleRetrieverEnd(documents, runId);
|
|
107
|
+
}
|
|
108
|
+
async handleRetrieverError(err, runId) {
|
|
109
|
+
return self.handleRetrieverError(err, runId);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return new ArknaHandler();
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
throw new Error('@langchain/core is required for ArknaLangChainHandler. Install it: npm install @langchain/core');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async post(path, body) {
|
|
119
|
+
return this.client.ingestionRequest('POST', path, body);
|
|
120
|
+
}
|
|
121
|
+
async patch(path, body) {
|
|
122
|
+
return this.client.ingestionRequest('PATCH', path, body);
|
|
123
|
+
}
|
|
124
|
+
// ────────────────────────────────────────────────────────────
|
|
125
|
+
// Chain Events
|
|
126
|
+
// ────────────────────────────────────────────────────────────
|
|
127
|
+
async handleChainStart(chain, inputs, runId, parentRunId) {
|
|
128
|
+
try {
|
|
129
|
+
const chainName = chain.id?.[chain.id.length - 1] ?? 'chain';
|
|
130
|
+
if (!parentRunId || !this.rootRunId) {
|
|
131
|
+
const inputStr = typeof inputs === 'string' ? inputs : JSON.stringify(inputs);
|
|
132
|
+
const resp = await this.post('/runs', {
|
|
133
|
+
input: inputStr,
|
|
134
|
+
trigger_type: this.trigger,
|
|
135
|
+
session_id: this.sessionId,
|
|
136
|
+
metadata: {
|
|
137
|
+
...this.runMetadata,
|
|
138
|
+
chain_name: chainName,
|
|
139
|
+
framework: 'langchain',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
const arknaRunId = resp.run_id;
|
|
143
|
+
this.runs.set(runId, { runId: arknaRunId, currentStepId: null, depth: 0 });
|
|
144
|
+
this.parentToArknaRun.set(runId, arknaRunId);
|
|
145
|
+
this.rootRunId = runId;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const arknaRunId = this.getArknaRunId(parentRunId);
|
|
149
|
+
if (!arknaRunId)
|
|
150
|
+
return;
|
|
151
|
+
const resp = await this.post(`/runs/${arknaRunId}/steps`, {
|
|
152
|
+
step_type: 'reasoning',
|
|
153
|
+
input: JSON.stringify(inputs),
|
|
154
|
+
metadata: { chain_name: chainName, nested: true },
|
|
155
|
+
});
|
|
156
|
+
const depth = (this.runs.get(parentRunId)?.depth ?? 0) + 1;
|
|
157
|
+
this.runs.set(runId, { runId: arknaRunId, currentStepId: resp.step_id, depth });
|
|
158
|
+
this.parentToArknaRun.set(runId, arknaRunId);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Non-critical — don't break the chain execution
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async handleChainEnd(outputs, runId) {
|
|
166
|
+
try {
|
|
167
|
+
if (runId === this.rootRunId) {
|
|
168
|
+
const state = this.runs.get(runId);
|
|
169
|
+
if (!state)
|
|
170
|
+
return;
|
|
171
|
+
const outputStr = typeof outputs === 'string' ? outputs : JSON.stringify(outputs);
|
|
172
|
+
await this.patch(`/runs/${state.runId}`, { status: 'completed', output: outputStr });
|
|
173
|
+
this.cleanup();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Non-critical
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async handleChainError(err, runId) {
|
|
181
|
+
try {
|
|
182
|
+
if (runId === this.rootRunId) {
|
|
183
|
+
const state = this.runs.get(runId);
|
|
184
|
+
if (!state)
|
|
185
|
+
return;
|
|
186
|
+
await this.patch(`/runs/${state.runId}`, {
|
|
187
|
+
status: 'failed',
|
|
188
|
+
error_type: err.name || 'Error',
|
|
189
|
+
error_message: err.message,
|
|
190
|
+
});
|
|
191
|
+
this.cleanup();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Non-critical
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// ────────────────────────────────────────────────────────────
|
|
199
|
+
// LLM Events
|
|
200
|
+
// ────────────────────────────────────────────────────────────
|
|
201
|
+
async handleLLMStart(llm, prompts, runId, parentRunId) {
|
|
202
|
+
try {
|
|
203
|
+
const arknaRunId = this.getArknaRunId(parentRunId || runId);
|
|
204
|
+
if (!arknaRunId)
|
|
205
|
+
return;
|
|
206
|
+
const modelName = llm.id?.[llm.id.length - 1] ?? 'llm';
|
|
207
|
+
const resp = await this.post(`/runs/${arknaRunId}/steps`, {
|
|
208
|
+
step_type: 'reasoning',
|
|
209
|
+
input: prompts.length === 1 ? prompts[0] : JSON.stringify(prompts),
|
|
210
|
+
metadata: { model: modelName },
|
|
211
|
+
});
|
|
212
|
+
const state = this.runs.get(parentRunId || runId);
|
|
213
|
+
if (state) {
|
|
214
|
+
this.runs.set(runId, { ...state, currentStepId: resp.step_id });
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
this.runs.set(runId, { runId: arknaRunId, currentStepId: resp.step_id, depth: 0 });
|
|
218
|
+
}
|
|
219
|
+
this.parentToArknaRun.set(runId, arknaRunId);
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Non-critical
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async handleLLMEnd(output, runId) {
|
|
226
|
+
try {
|
|
227
|
+
const state = this.runs.get(runId);
|
|
228
|
+
if (!state?.currentStepId)
|
|
229
|
+
return;
|
|
230
|
+
const tokenUsage = output.llmOutput?.tokenUsage || output.llmOutput?.usage;
|
|
231
|
+
const totalTokens = tokenUsage?.totalTokens ?? tokenUsage?.total_tokens;
|
|
232
|
+
const generationText = output.generations?.[0]?.[0]?.text ?? '';
|
|
233
|
+
await this.post(`/runs/${state.runId}/steps`, {
|
|
234
|
+
step_type: 'reasoning',
|
|
235
|
+
output: generationText.substring(0, 10000),
|
|
236
|
+
reasoning: generationText.substring(0, 5000),
|
|
237
|
+
tokens_used: totalTokens ?? undefined,
|
|
238
|
+
metadata: {
|
|
239
|
+
llm_output: true,
|
|
240
|
+
...(tokenUsage ? {
|
|
241
|
+
prompt_tokens: tokenUsage.promptTokens ?? tokenUsage.prompt_tokens,
|
|
242
|
+
completion_tokens: tokenUsage.completionTokens ?? tokenUsage.completion_tokens,
|
|
243
|
+
} : {}),
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// Non-critical
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
async handleLLMError(err, runId) {
|
|
252
|
+
try {
|
|
253
|
+
const state = this.runs.get(runId);
|
|
254
|
+
if (!state)
|
|
255
|
+
return;
|
|
256
|
+
await this.post(`/runs/${state.runId}/steps`, {
|
|
257
|
+
step_type: 'reasoning',
|
|
258
|
+
output: `LLM Error: ${err.message}`,
|
|
259
|
+
metadata: { error: true, error_type: err.name },
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
// Non-critical
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// ────────────────────────────────────────────────────────────
|
|
267
|
+
// Tool Events
|
|
268
|
+
// ────────────────────────────────────────────────────────────
|
|
269
|
+
async handleToolStart(tool, input, runId, parentRunId) {
|
|
270
|
+
try {
|
|
271
|
+
const arknaRunId = this.getArknaRunId(parentRunId || runId);
|
|
272
|
+
if (!arknaRunId)
|
|
273
|
+
return;
|
|
274
|
+
const toolName = tool.id?.[tool.id.length - 1] ?? 'tool';
|
|
275
|
+
const parentState = this.runs.get(parentRunId || runId);
|
|
276
|
+
let stepId = parentState?.currentStepId ?? null;
|
|
277
|
+
if (!stepId) {
|
|
278
|
+
const stepResp = await this.post(`/runs/${arknaRunId}/steps`, {
|
|
279
|
+
step_type: 'action',
|
|
280
|
+
input: `Tool call: ${toolName}`,
|
|
281
|
+
});
|
|
282
|
+
stepId = stepResp.step_id;
|
|
283
|
+
}
|
|
284
|
+
let parsedArgs = {};
|
|
285
|
+
try {
|
|
286
|
+
parsedArgs = JSON.parse(input);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
parsedArgs = { input };
|
|
290
|
+
}
|
|
291
|
+
await this.post(`/runs/${arknaRunId}/tools`, {
|
|
292
|
+
step_id: stepId,
|
|
293
|
+
tool_name: toolName,
|
|
294
|
+
arguments: parsedArgs,
|
|
295
|
+
});
|
|
296
|
+
this.runs.set(runId, {
|
|
297
|
+
runId: arknaRunId,
|
|
298
|
+
currentStepId: stepId,
|
|
299
|
+
depth: parentState?.depth ?? 0,
|
|
300
|
+
});
|
|
301
|
+
this.parentToArknaRun.set(runId, arknaRunId);
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// Non-critical
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
async handleToolError(err, runId) {
|
|
308
|
+
try {
|
|
309
|
+
const state = this.runs.get(runId);
|
|
310
|
+
if (!state)
|
|
311
|
+
return;
|
|
312
|
+
await this.post(`/runs/${state.runId}/steps`, {
|
|
313
|
+
step_type: 'action',
|
|
314
|
+
output: `Tool Error: ${err.message}`,
|
|
315
|
+
metadata: { error: true, error_type: err.name },
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// Non-critical
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// ────────────────────────────────────────────────────────────
|
|
323
|
+
// Retriever Events
|
|
324
|
+
// ────────────────────────────────────────────────────────────
|
|
325
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId) {
|
|
326
|
+
try {
|
|
327
|
+
const arknaRunId = this.getArknaRunId(parentRunId || runId);
|
|
328
|
+
if (!arknaRunId)
|
|
329
|
+
return;
|
|
330
|
+
const retrieverName = retriever.id?.[retriever.id.length - 1] ?? 'retriever';
|
|
331
|
+
const resp = await this.post(`/runs/${arknaRunId}/steps`, {
|
|
332
|
+
step_type: 'retrieval',
|
|
333
|
+
input: query,
|
|
334
|
+
metadata: { retriever: retrieverName },
|
|
335
|
+
});
|
|
336
|
+
this.runs.set(runId, {
|
|
337
|
+
runId: arknaRunId,
|
|
338
|
+
currentStepId: resp.step_id,
|
|
339
|
+
depth: this.runs.get(parentRunId || runId)?.depth ?? 0,
|
|
340
|
+
});
|
|
341
|
+
this.parentToArknaRun.set(runId, arknaRunId);
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
// Non-critical
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
async handleRetrieverEnd(documents, runId) {
|
|
348
|
+
try {
|
|
349
|
+
const state = this.runs.get(runId);
|
|
350
|
+
if (!state)
|
|
351
|
+
return;
|
|
352
|
+
const docSummary = documents.map((d, i) => ({
|
|
353
|
+
index: i,
|
|
354
|
+
content_length: d.pageContent?.length ?? 0,
|
|
355
|
+
metadata: d.metadata,
|
|
356
|
+
}));
|
|
357
|
+
await this.post(`/runs/${state.runId}/steps`, {
|
|
358
|
+
step_type: 'retrieval',
|
|
359
|
+
output: JSON.stringify(docSummary).substring(0, 10000),
|
|
360
|
+
metadata: { documents_retrieved: documents.length },
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
// Non-critical
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
async handleRetrieverError(err, runId) {
|
|
368
|
+
try {
|
|
369
|
+
const state = this.runs.get(runId);
|
|
370
|
+
if (!state)
|
|
371
|
+
return;
|
|
372
|
+
await this.post(`/runs/${state.runId}/steps`, {
|
|
373
|
+
step_type: 'retrieval',
|
|
374
|
+
output: `Retriever Error: ${err.message}`,
|
|
375
|
+
metadata: { error: true },
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// Non-critical
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// ────────────────────────────────────────────────────────────
|
|
383
|
+
// Helpers
|
|
384
|
+
// ────────────────────────────────────────────────────────────
|
|
385
|
+
getArknaRunId(lcRunId) {
|
|
386
|
+
const direct = this.runs.get(lcRunId);
|
|
387
|
+
if (direct)
|
|
388
|
+
return direct.runId;
|
|
389
|
+
return this.parentToArknaRun.get(lcRunId) ?? null;
|
|
390
|
+
}
|
|
391
|
+
cleanup() {
|
|
392
|
+
this.runs.clear();
|
|
393
|
+
this.parentToArknaRun.clear();
|
|
394
|
+
this.rootRunId = null;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
exports.ArknaLangChainHandler = ArknaLangChainHandler;
|
|
398
|
+
//# sourceMappingURL=langchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langchain.js","sourceRoot":"","sources":["../../src/instrumentations/langchain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ARKNA Vercel AI SDK Auto-Instrumentation
|
|
3
|
+
*
|
|
4
|
+
* Wraps Vercel AI SDK's `generateText()` and `streamText()` to automatically
|
|
5
|
+
* capture runs in ARKNA observability — no manual SDK calls needed.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { ArknaClient, wrapVercelAI } from '@arkna/sdk';
|
|
9
|
+
* const client = new ArknaClient();
|
|
10
|
+
* const ai = wrapVercelAI(client);
|
|
11
|
+
* const result = await ai.generateText({ model, prompt });
|
|
12
|
+
*
|
|
13
|
+
* Requires: ai (Vercel AI SDK) as peer dependency
|
|
14
|
+
*/
|
|
15
|
+
import type { ArknaClient } from '../client';
|
|
16
|
+
/** Options for wrapping Vercel AI SDK */
|
|
17
|
+
export interface WrapVercelAIOptions {
|
|
18
|
+
/** Session ID to group related runs */
|
|
19
|
+
sessionId?: string;
|
|
20
|
+
/** How the run was triggered */
|
|
21
|
+
trigger?: string;
|
|
22
|
+
/** Additional metadata */
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
interface WrappedAI {
|
|
26
|
+
generateText: (params: any) => Promise<any>;
|
|
27
|
+
streamText: (params: any) => Promise<any>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Wrap Vercel AI SDK functions with ARKNA auto-instrumentation.
|
|
31
|
+
*
|
|
32
|
+
* Returns wrapped `generateText` and `streamText` that automatically capture:
|
|
33
|
+
* - Run start/end
|
|
34
|
+
* - LLM reasoning steps
|
|
35
|
+
* - Tool calls and results
|
|
36
|
+
* - Token usage (final response only, not streaming tokens)
|
|
37
|
+
*/
|
|
38
|
+
export declare function wrapVercelAI(client: ArknaClient, options?: WrapVercelAIOptions): WrappedAI;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=vercel-ai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-ai.d.ts","sourceRoot":"","sources":["../../src/instrumentations/vercel-ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,yCAAyC;AACzC,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,UAAU,SAAS;IACjB,YAAY,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CAC3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,WAAW,EACnB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,SAAS,CAyMX"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ARKNA Vercel AI SDK Auto-Instrumentation
|
|
4
|
+
*
|
|
5
|
+
* Wraps Vercel AI SDK's `generateText()` and `streamText()` to automatically
|
|
6
|
+
* capture runs in ARKNA observability — no manual SDK calls needed.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { ArknaClient, wrapVercelAI } from '@arkna/sdk';
|
|
10
|
+
* const client = new ArknaClient();
|
|
11
|
+
* const ai = wrapVercelAI(client);
|
|
12
|
+
* const result = await ai.generateText({ model, prompt });
|
|
13
|
+
*
|
|
14
|
+
* Requires: ai (Vercel AI SDK) as peer dependency
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.wrapVercelAI = wrapVercelAI;
|
|
18
|
+
/**
|
|
19
|
+
* Wrap Vercel AI SDK functions with ARKNA auto-instrumentation.
|
|
20
|
+
*
|
|
21
|
+
* Returns wrapped `generateText` and `streamText` that automatically capture:
|
|
22
|
+
* - Run start/end
|
|
23
|
+
* - LLM reasoning steps
|
|
24
|
+
* - Tool calls and results
|
|
25
|
+
* - Token usage (final response only, not streaming tokens)
|
|
26
|
+
*/
|
|
27
|
+
function wrapVercelAI(client, options) {
|
|
28
|
+
const sessionId = options?.sessionId;
|
|
29
|
+
const trigger = options?.trigger ?? 'vercel-ai';
|
|
30
|
+
const meta = options?.metadata ?? {};
|
|
31
|
+
async function post(path, body) {
|
|
32
|
+
return client.ingestionRequest('POST', path, body);
|
|
33
|
+
}
|
|
34
|
+
async function patch(path, body) {
|
|
35
|
+
return client.ingestionRequest('PATCH', path, body);
|
|
36
|
+
}
|
|
37
|
+
async function wrappedGenerateText(params) {
|
|
38
|
+
// Dynamically require — ai is a peer dependency
|
|
39
|
+
const { generateText: originalGenerateText } = require('ai');
|
|
40
|
+
const modelId = params.model?.modelId ?? params.model?.constructor?.name ?? 'unknown';
|
|
41
|
+
let runId = null;
|
|
42
|
+
try {
|
|
43
|
+
// Start run
|
|
44
|
+
const runResp = await post('/runs', {
|
|
45
|
+
input: typeof params.prompt === 'string' ? params.prompt : JSON.stringify(params.messages ?? params.prompt),
|
|
46
|
+
trigger_type: trigger,
|
|
47
|
+
session_id: sessionId,
|
|
48
|
+
metadata: { ...meta, model: modelId, framework: 'vercel-ai', mode: 'generate' },
|
|
49
|
+
});
|
|
50
|
+
runId = runResp.run_id;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// If we can't start the run, just execute without instrumentation
|
|
54
|
+
return originalGenerateText(params);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const result = await originalGenerateText(params);
|
|
58
|
+
// Record LLM step
|
|
59
|
+
try {
|
|
60
|
+
const stepResp = await post(`/runs/${runId}/steps`, {
|
|
61
|
+
step_type: 'reasoning',
|
|
62
|
+
input: typeof params.prompt === 'string' ? params.prompt : JSON.stringify(params.messages ?? params.prompt),
|
|
63
|
+
output: result.text,
|
|
64
|
+
reasoning: result.reasoning ?? undefined,
|
|
65
|
+
tokens_used: result.usage?.totalTokens ?? undefined,
|
|
66
|
+
metadata: {
|
|
67
|
+
model: modelId,
|
|
68
|
+
prompt_tokens: result.usage?.promptTokens,
|
|
69
|
+
completion_tokens: result.usage?.completionTokens,
|
|
70
|
+
finish_reason: result.finishReason,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
// Record tool calls if any
|
|
74
|
+
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
75
|
+
for (const tc of result.toolCalls) {
|
|
76
|
+
await post(`/runs/${runId}/tools`, {
|
|
77
|
+
step_id: stepResp.step_id,
|
|
78
|
+
tool_name: tc.toolName,
|
|
79
|
+
arguments: tc.args ?? {},
|
|
80
|
+
}).catch(() => { });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Record tool results if multi-step
|
|
84
|
+
if (result.steps) {
|
|
85
|
+
for (const step of result.steps) {
|
|
86
|
+
if (step.toolCalls?.length) {
|
|
87
|
+
const sResp = await post(`/runs/${runId}/steps`, {
|
|
88
|
+
step_type: 'action',
|
|
89
|
+
input: JSON.stringify(step.toolCalls.map((t) => ({ name: t.toolName, args: t.args }))),
|
|
90
|
+
output: JSON.stringify(step.toolResults ?? []),
|
|
91
|
+
}).catch(() => null);
|
|
92
|
+
if (sResp) {
|
|
93
|
+
for (const tc of step.toolCalls) {
|
|
94
|
+
await post(`/runs/${runId}/tools`, {
|
|
95
|
+
step_id: sResp.step_id,
|
|
96
|
+
tool_name: tc.toolName,
|
|
97
|
+
arguments: tc.args ?? {},
|
|
98
|
+
}).catch(() => { });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Non-critical
|
|
107
|
+
}
|
|
108
|
+
// Complete run
|
|
109
|
+
await patch(`/runs/${runId}`, { status: 'completed', output: result.text }).catch(() => { });
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
// Fail run
|
|
114
|
+
if (runId) {
|
|
115
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
116
|
+
await patch(`/runs/${runId}`, {
|
|
117
|
+
status: 'failed',
|
|
118
|
+
error_type: error.name || 'Error',
|
|
119
|
+
error_message: error.message,
|
|
120
|
+
}).catch(() => { });
|
|
121
|
+
}
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function wrappedStreamText(params) {
|
|
126
|
+
const { streamText: originalStreamText } = require('ai');
|
|
127
|
+
const modelId = params.model?.modelId ?? params.model?.constructor?.name ?? 'unknown';
|
|
128
|
+
let runId = null;
|
|
129
|
+
try {
|
|
130
|
+
const runResp = await post('/runs', {
|
|
131
|
+
input: typeof params.prompt === 'string' ? params.prompt : JSON.stringify(params.messages ?? params.prompt),
|
|
132
|
+
trigger_type: trigger,
|
|
133
|
+
session_id: sessionId,
|
|
134
|
+
metadata: { ...meta, model: modelId, framework: 'vercel-ai', mode: 'stream' },
|
|
135
|
+
});
|
|
136
|
+
runId = runResp.run_id;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return originalStreamText(params);
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const result = await originalStreamText(params);
|
|
143
|
+
// We don't capture streaming tokens — only the final response.
|
|
144
|
+
// Wrap the result to capture completion.
|
|
145
|
+
const capturedRunId = runId;
|
|
146
|
+
// Use the response promise to capture the final result
|
|
147
|
+
if (!result.response || typeof result.response.then !== 'function') {
|
|
148
|
+
// Vercel AI SDK version doesn't support .response promise — skip capture
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
result.response.then(async (_response) => {
|
|
152
|
+
try {
|
|
153
|
+
const usage = await result.usage;
|
|
154
|
+
const text = await result.text;
|
|
155
|
+
const toolCalls = result.toolCalls;
|
|
156
|
+
const stepResp = await post(`/runs/${capturedRunId}/steps`, {
|
|
157
|
+
step_type: 'reasoning',
|
|
158
|
+
output: text,
|
|
159
|
+
tokens_used: usage?.totalTokens ?? undefined,
|
|
160
|
+
metadata: {
|
|
161
|
+
model: modelId,
|
|
162
|
+
prompt_tokens: usage?.promptTokens,
|
|
163
|
+
completion_tokens: usage?.completionTokens,
|
|
164
|
+
streaming: true,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
// Capture tool calls from the stream result
|
|
168
|
+
if (toolCalls) {
|
|
169
|
+
const resolvedTools = await toolCalls;
|
|
170
|
+
if (Array.isArray(resolvedTools)) {
|
|
171
|
+
for (const tc of resolvedTools) {
|
|
172
|
+
await post(`/runs/${capturedRunId}/tools`, {
|
|
173
|
+
step_id: stepResp.step_id,
|
|
174
|
+
tool_name: tc.toolName,
|
|
175
|
+
arguments: tc.args ?? {},
|
|
176
|
+
}).catch(() => { });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
await patch(`/runs/${capturedRunId}`, { status: 'completed', output: text }).catch(() => { });
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Non-critical
|
|
184
|
+
}
|
|
185
|
+
}).catch(async (err) => {
|
|
186
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
187
|
+
await patch(`/runs/${capturedRunId}`, {
|
|
188
|
+
status: 'failed',
|
|
189
|
+
error_type: error.name || 'Error',
|
|
190
|
+
error_message: error.message,
|
|
191
|
+
}).catch(() => { });
|
|
192
|
+
});
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
if (runId) {
|
|
197
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
198
|
+
await patch(`/runs/${runId}`, {
|
|
199
|
+
status: 'failed',
|
|
200
|
+
error_type: error.name || 'Error',
|
|
201
|
+
error_message: error.message,
|
|
202
|
+
}).catch(() => { });
|
|
203
|
+
}
|
|
204
|
+
throw err;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
generateText: wrappedGenerateText,
|
|
209
|
+
streamText: wrappedStreamText,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=vercel-ai.js.map
|