@langinsight/ai-sdk 0.0.1 → 0.0.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.
- package/README.md +36 -10
- package/dist/index.cjs +77 -38
- package/dist/index.d.cts +134 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @langinsight/ai-sdk
|
|
2
2
|
|
|
3
|
-
LangInsight callback handler for Vercel AI SDK.
|
|
3
|
+
LangInsight callback handler for Vercel AI SDK. Sends input/output traces to LangInsight in parallel and supports feedback (thumbs up/down) via `score()`.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -26,8 +26,8 @@ const result = await generateText({
|
|
|
26
26
|
prompt,
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
// Report the result to LangInsight
|
|
30
|
-
await handler.report(result, { input: prompt });
|
|
29
|
+
// Report the result to LangInsight (returns output trace id or undefined)
|
|
30
|
+
const traceId = await handler.report(result, { input: prompt });
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
### streamText
|
|
@@ -43,6 +43,8 @@ const handler = new LangInsight.CallbackHandler({
|
|
|
43
43
|
apiKey: LANGINSIGHT_API_KEY,
|
|
44
44
|
endpoint: LANGINSIGHT_ENDPOINT,
|
|
45
45
|
metadata: { userId: "admin", sessionId: "admin" },
|
|
46
|
+
onSuccess: (trace) => console.log("Trace sent:", trace.id),
|
|
47
|
+
onFailure: (err) => console.error("Trace failed:", err),
|
|
46
48
|
});
|
|
47
49
|
|
|
48
50
|
const prompt = "Hello!";
|
|
@@ -50,7 +52,6 @@ const prompt = "Hello!";
|
|
|
50
52
|
const result = streamText({
|
|
51
53
|
model: openai("gpt-4o"),
|
|
52
54
|
prompt,
|
|
53
|
-
// Specify callback handler as onFinish
|
|
54
55
|
onFinish: handler.onFinish({ input: prompt }),
|
|
55
56
|
});
|
|
56
57
|
|
|
@@ -59,11 +60,36 @@ for await (const chunk of result.textStream) {
|
|
|
59
60
|
}
|
|
60
61
|
```
|
|
61
62
|
|
|
63
|
+
### Feedback (score)
|
|
64
|
+
|
|
65
|
+
After sending traces, you can submit feedback for the last output trace using `score()` or the trace id from `onSuccess` / `report()`.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Using lastTraceId (set after report() or onFinish)
|
|
69
|
+
await handler.score({ traceId: handler.lastTraceId, value: 1 }); // 👍
|
|
70
|
+
await handler.score({ traceId: handler.lastTraceId, value: -1 }); // 👎
|
|
71
|
+
|
|
72
|
+
// Or using the trace id from report() / onSuccess
|
|
73
|
+
await handler.score({ traceId, value: 1 });
|
|
74
|
+
```
|
|
75
|
+
|
|
62
76
|
## Options
|
|
63
77
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
| Option | Type | Required | Description |
|
|
79
|
+
| ----------- | --------------------------------- | -------- | --------------------------------------------------------------------------- |
|
|
80
|
+
| `apiKey` | `string` | Yes | LangInsight API key |
|
|
81
|
+
| `endpoint` | `string` | Yes | LangInsight API endpoint (e.g. `https://api.langinsight.example.com`) |
|
|
82
|
+
| `metadata` | `object` | Yes | Metadata attached to traces |
|
|
83
|
+
| `metadata.userId` | `string` | Yes | User ID |
|
|
84
|
+
| `metadata.sessionId`| `string` | Yes | Session ID (e.g. conversation id) |
|
|
85
|
+
| `metadata.modelName` | `string` | No | Model name (defaults to result response when not set) |
|
|
86
|
+
| `metadata.*` | `any` | No | Additional key-value pairs |
|
|
87
|
+
| `onSuccess` | `(trace: Trace) => void` | No | Callback invoked with the output trace when trace submission succeeds |
|
|
88
|
+
| `onFailure` | `(error: Error) => void` | No | Callback invoked with the error when trace submission fails |
|
|
89
|
+
|
|
90
|
+
## API
|
|
91
|
+
|
|
92
|
+
- **`report(result, { input })`** — Sends traces for a `generateText` result. Returns the output trace id, or `undefined` on failure.
|
|
93
|
+
- **`onFinish({ input })`** — Returns a function suitable for `streamText`’s `onFinish`. Sends traces when the stream finishes.
|
|
94
|
+
- **`score({ traceId, value })`** — Submits feedback (1 = thumbs up, -1 = thumbs down) for the given trace.
|
|
95
|
+
- **`lastTraceId`** — The id of the last output trace sent by this handler (set after `report()` or `onFinish()`).
|
package/dist/index.cjs
CHANGED
|
@@ -323,6 +323,8 @@ var LangInsight;
|
|
|
323
323
|
this.client = hc(options.endpoint, { fetch });
|
|
324
324
|
}
|
|
325
325
|
client;
|
|
326
|
+
/** 最後に送信した output trace の ID */
|
|
327
|
+
lastTraceId;
|
|
326
328
|
/**
|
|
327
329
|
* streamText の onFinish コールバックとして使用
|
|
328
330
|
*
|
|
@@ -348,6 +350,8 @@ var LangInsight;
|
|
|
348
350
|
/**
|
|
349
351
|
* generateText の結果を送信
|
|
350
352
|
*
|
|
353
|
+
* @returns output trace の traceId(送信失敗時は undefined)
|
|
354
|
+
*
|
|
351
355
|
* @example
|
|
352
356
|
* ```ts
|
|
353
357
|
* const handler = new LangInsight.CallbackHandler(options);
|
|
@@ -357,61 +361,96 @@ var LangInsight;
|
|
|
357
361
|
* prompt: "Hello!",
|
|
358
362
|
* });
|
|
359
363
|
*
|
|
360
|
-
* await handler.report(result, { input: "Hello!" });
|
|
364
|
+
* const traceId = await handler.report(result, { input: "Hello!" });
|
|
361
365
|
* ```
|
|
362
366
|
*/
|
|
363
367
|
// biome-ignore lint/suspicious/noExplicitAny: should accept any output
|
|
364
368
|
async report(result, params) {
|
|
365
|
-
await this.sendTraces({
|
|
369
|
+
return await this.sendTraces({
|
|
366
370
|
input: params.input,
|
|
367
371
|
result
|
|
368
372
|
});
|
|
369
373
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
374
|
+
/**
|
|
375
|
+
* フィードバック(👍/👎)を送信
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```ts
|
|
379
|
+
* await handler.score({ traceId, value: 1 }); // 👍
|
|
380
|
+
* await handler.score({ traceId, value: -1 }); // 👎
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
async score(params) {
|
|
384
|
+
const { userId, sessionId } = this.options.metadata;
|
|
385
|
+
const res = await this.client.feedbacks.external.$post({
|
|
377
386
|
header: {
|
|
378
387
|
"x-api-key": this.options.apiKey
|
|
379
388
|
},
|
|
380
389
|
json: {
|
|
381
|
-
|
|
390
|
+
traceId: params.traceId,
|
|
382
391
|
sessionId,
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
content: input,
|
|
386
|
-
type: "input",
|
|
387
|
-
meta: { ...rest },
|
|
388
|
-
startedAt: startedAt.toISOString(),
|
|
389
|
-
endedAt: endedAt.toISOString()
|
|
392
|
+
userId,
|
|
393
|
+
value: params.value
|
|
390
394
|
}
|
|
391
395
|
});
|
|
392
|
-
if (!
|
|
393
|
-
console.error(await
|
|
394
|
-
return;
|
|
396
|
+
if (!res.ok) {
|
|
397
|
+
console.error(await res.text());
|
|
395
398
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
399
|
+
}
|
|
400
|
+
async sendTraces(params) {
|
|
401
|
+
const { input, result } = params;
|
|
402
|
+
const { userId, sessionId, ...rest } = this.options.metadata;
|
|
403
|
+
const model = result.response.modelId ?? "unknown";
|
|
404
|
+
const startedAt = result.response.timestamp;
|
|
405
|
+
const endedAt = /* @__PURE__ */ new Date();
|
|
406
|
+
try {
|
|
407
|
+
const res = await Promise.all([
|
|
408
|
+
this.client.traces.external.$post({
|
|
409
|
+
header: {
|
|
410
|
+
"x-api-key": this.options.apiKey
|
|
411
|
+
},
|
|
412
|
+
json: {
|
|
413
|
+
userId,
|
|
414
|
+
sessionId,
|
|
415
|
+
model,
|
|
416
|
+
token: result.usage.inputTokens ?? 0,
|
|
417
|
+
content: input,
|
|
418
|
+
type: "input",
|
|
419
|
+
meta: { ...rest },
|
|
420
|
+
startedAt: startedAt.toISOString(),
|
|
421
|
+
endedAt: endedAt.toISOString()
|
|
422
|
+
}
|
|
423
|
+
}),
|
|
424
|
+
this.client.traces.external.$post({
|
|
425
|
+
header: {
|
|
426
|
+
"x-api-key": this.options.apiKey
|
|
427
|
+
},
|
|
428
|
+
json: {
|
|
429
|
+
userId,
|
|
430
|
+
sessionId,
|
|
431
|
+
model,
|
|
432
|
+
token: result.usage.outputTokens ?? 0,
|
|
433
|
+
content: result.text,
|
|
434
|
+
type: "output",
|
|
435
|
+
meta: { ...rest },
|
|
436
|
+
startedAt: startedAt.toISOString(),
|
|
437
|
+
endedAt: endedAt.toISOString()
|
|
438
|
+
}
|
|
439
|
+
})
|
|
440
|
+
]);
|
|
441
|
+
if (!res.every((r) => r.ok)) {
|
|
442
|
+
console.error(await Promise.all(res.map((r) => r.text())));
|
|
443
|
+
throw new Error("Failed to send traces");
|
|
410
444
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
445
|
+
const outputTrace = await res[1].json();
|
|
446
|
+
const traceId = outputTrace.id;
|
|
447
|
+
this.lastTraceId = traceId;
|
|
448
|
+
this.options.onSuccess?.(outputTrace);
|
|
449
|
+
return traceId;
|
|
450
|
+
} catch (error) {
|
|
451
|
+
console.error(error);
|
|
452
|
+
this.options.onFailure?.(error instanceof Error ? error : new Error(String(error)));
|
|
453
|
+
return void 0;
|
|
415
454
|
}
|
|
416
455
|
}
|
|
417
456
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,118 @@
|
|
|
1
1
|
import { StepResult, ToolSet, LanguageModelUsage, GenerateTextResult } from 'ai';
|
|
2
|
+
import { InferOutput, ObjectSchema, SchemaWithPipe, StringSchema, UuidAction, NumberSchema, PicklistSchema, RecordSchema, AnySchema, CustomSchema, StandardProps, UnknownDataset, Config, BaseIssue, OutputDataset, ObjectIssue, NumberIssue, StringIssue, PicklistIssue, RecordIssue, CustomIssue } from 'valibot';
|
|
3
|
+
|
|
4
|
+
declare const vTraceEntity: ObjectSchema<{
|
|
5
|
+
readonly id: SchemaWithPipe<readonly [StringSchema<undefined>, UuidAction<string, undefined>]>;
|
|
6
|
+
readonly userId: StringSchema<undefined>;
|
|
7
|
+
readonly sessionId: StringSchema<undefined>;
|
|
8
|
+
readonly model: StringSchema<undefined>;
|
|
9
|
+
readonly token: NumberSchema<undefined>;
|
|
10
|
+
readonly content: StringSchema<undefined>;
|
|
11
|
+
readonly type: PicklistSchema<["input", "output", "error"], undefined>;
|
|
12
|
+
readonly meta: RecordSchema<StringSchema<undefined>, AnySchema, undefined>;
|
|
13
|
+
readonly createdAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
14
|
+
readonly startedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
15
|
+
readonly endedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
16
|
+
}, undefined> & {
|
|
17
|
+
create: Omit<ObjectSchema<{
|
|
18
|
+
readonly id: SchemaWithPipe<readonly [StringSchema<undefined>, UuidAction<string, undefined>]>;
|
|
19
|
+
readonly userId: StringSchema<undefined>;
|
|
20
|
+
readonly sessionId: StringSchema<undefined>;
|
|
21
|
+
readonly model: StringSchema<undefined>;
|
|
22
|
+
readonly token: NumberSchema<undefined>;
|
|
23
|
+
readonly content: StringSchema<undefined>;
|
|
24
|
+
readonly type: PicklistSchema<["input", "output", "error"], undefined>;
|
|
25
|
+
readonly meta: RecordSchema<StringSchema<undefined>, AnySchema, undefined>;
|
|
26
|
+
readonly createdAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
27
|
+
readonly startedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
28
|
+
readonly endedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
29
|
+
}, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
|
|
30
|
+
readonly entries: Omit<{
|
|
31
|
+
readonly id: SchemaWithPipe<readonly [StringSchema<undefined>, UuidAction<string, undefined>]>;
|
|
32
|
+
readonly userId: StringSchema<undefined>;
|
|
33
|
+
readonly sessionId: StringSchema<undefined>;
|
|
34
|
+
readonly model: StringSchema<undefined>;
|
|
35
|
+
readonly token: NumberSchema<undefined>;
|
|
36
|
+
readonly content: StringSchema<undefined>;
|
|
37
|
+
readonly type: PicklistSchema<["input", "output", "error"], undefined>;
|
|
38
|
+
readonly meta: RecordSchema<StringSchema<undefined>, AnySchema, undefined>;
|
|
39
|
+
readonly createdAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
40
|
+
readonly startedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
41
|
+
readonly endedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
42
|
+
}, "id" | "createdAt">;
|
|
43
|
+
readonly "~standard": StandardProps<{
|
|
44
|
+
type: "output" | "input" | "error";
|
|
45
|
+
token: number;
|
|
46
|
+
content: string;
|
|
47
|
+
userId: string;
|
|
48
|
+
model: string;
|
|
49
|
+
meta: {
|
|
50
|
+
[x: string]: any;
|
|
51
|
+
};
|
|
52
|
+
sessionId: string;
|
|
53
|
+
startedAt: unknown;
|
|
54
|
+
endedAt: unknown;
|
|
55
|
+
}, {
|
|
56
|
+
type: "output" | "input" | "error";
|
|
57
|
+
token: number;
|
|
58
|
+
content: string;
|
|
59
|
+
userId: string;
|
|
60
|
+
model: string;
|
|
61
|
+
meta: {
|
|
62
|
+
[x: string]: any;
|
|
63
|
+
};
|
|
64
|
+
sessionId: string;
|
|
65
|
+
startedAt: string;
|
|
66
|
+
endedAt: string;
|
|
67
|
+
}>;
|
|
68
|
+
readonly "~run": (dataset: UnknownDataset, config: Config<BaseIssue<unknown>>) => OutputDataset<{
|
|
69
|
+
type: "output" | "input" | "error";
|
|
70
|
+
token: number;
|
|
71
|
+
content: string;
|
|
72
|
+
userId: string;
|
|
73
|
+
model: string;
|
|
74
|
+
meta: {
|
|
75
|
+
[x: string]: any;
|
|
76
|
+
};
|
|
77
|
+
sessionId: string;
|
|
78
|
+
startedAt: string;
|
|
79
|
+
endedAt: string;
|
|
80
|
+
}, ObjectIssue | NumberIssue | StringIssue | PicklistIssue | RecordIssue | CustomIssue>;
|
|
81
|
+
readonly "~types"?: {
|
|
82
|
+
readonly input: {
|
|
83
|
+
type: "output" | "input" | "error";
|
|
84
|
+
token: number;
|
|
85
|
+
content: string;
|
|
86
|
+
userId: string;
|
|
87
|
+
model: string;
|
|
88
|
+
meta: {
|
|
89
|
+
[x: string]: any;
|
|
90
|
+
};
|
|
91
|
+
sessionId: string;
|
|
92
|
+
startedAt: unknown;
|
|
93
|
+
endedAt: unknown;
|
|
94
|
+
};
|
|
95
|
+
readonly output: {
|
|
96
|
+
type: "output" | "input" | "error";
|
|
97
|
+
token: number;
|
|
98
|
+
content: string;
|
|
99
|
+
userId: string;
|
|
100
|
+
model: string;
|
|
101
|
+
meta: {
|
|
102
|
+
[x: string]: any;
|
|
103
|
+
};
|
|
104
|
+
sessionId: string;
|
|
105
|
+
startedAt: string;
|
|
106
|
+
endedAt: string;
|
|
107
|
+
};
|
|
108
|
+
readonly issue: ObjectIssue | NumberIssue | StringIssue | PicklistIssue | RecordIssue | CustomIssue;
|
|
109
|
+
} | undefined;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
type TraceEntity = InferOutput<typeof vTraceEntity>;
|
|
113
|
+
declare namespace TraceEntity {
|
|
114
|
+
type Create = InferOutput<typeof vTraceEntity.create>;
|
|
115
|
+
}
|
|
2
116
|
|
|
3
117
|
declare namespace LangInsight {
|
|
4
118
|
interface Options {
|
|
@@ -9,10 +123,14 @@ declare namespace LangInsight {
|
|
|
9
123
|
sessionId: string;
|
|
10
124
|
[key: string]: any;
|
|
11
125
|
};
|
|
126
|
+
onSuccess?: (trace: TraceEntity) => void;
|
|
127
|
+
onFailure?: (error: Error) => void;
|
|
12
128
|
}
|
|
13
129
|
class CallbackHandler {
|
|
14
130
|
private readonly options;
|
|
15
131
|
private readonly client;
|
|
132
|
+
/** 最後に送信した output trace の ID */
|
|
133
|
+
lastTraceId: string | undefined;
|
|
16
134
|
constructor(options: Options);
|
|
17
135
|
/**
|
|
18
136
|
* streamText の onFinish コールバックとして使用
|
|
@@ -37,6 +155,8 @@ declare namespace LangInsight {
|
|
|
37
155
|
/**
|
|
38
156
|
* generateText の結果を送信
|
|
39
157
|
*
|
|
158
|
+
* @returns output trace の traceId(送信失敗時は undefined)
|
|
159
|
+
*
|
|
40
160
|
* @example
|
|
41
161
|
* ```ts
|
|
42
162
|
* const handler = new LangInsight.CallbackHandler(options);
|
|
@@ -46,11 +166,24 @@ declare namespace LangInsight {
|
|
|
46
166
|
* prompt: "Hello!",
|
|
47
167
|
* });
|
|
48
168
|
*
|
|
49
|
-
* await handler.report(result, { input: "Hello!" });
|
|
169
|
+
* const traceId = await handler.report(result, { input: "Hello!" });
|
|
50
170
|
* ```
|
|
51
171
|
*/
|
|
52
172
|
report(result: GenerateTextResult<ToolSet, any>, params: {
|
|
53
173
|
input: string;
|
|
174
|
+
}): Promise<string | undefined>;
|
|
175
|
+
/**
|
|
176
|
+
* フィードバック(👍/👎)を送信
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* await handler.score({ traceId, value: 1 }); // 👍
|
|
181
|
+
* await handler.score({ traceId, value: -1 }); // 👎
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
score(params: {
|
|
185
|
+
traceId: string;
|
|
186
|
+
value: 1 | -1;
|
|
54
187
|
}): Promise<void>;
|
|
55
188
|
private sendTraces;
|
|
56
189
|
}
|