@langinsight/ai-sdk 0.0.5 → 0.1.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.
- package/README.md +5 -13
- package/dist/index.cjs +172 -107
- package/dist/index.d.cts +114 -100
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -65,25 +65,17 @@ for await (const chunk of result.textStream) {
|
|
|
65
65
|
|
|
66
66
|
### Feedback (score)
|
|
67
67
|
|
|
68
|
-
Trace ID
|
|
68
|
+
Trace ID は `handler.result` で取得し、その `output.id` を `score()` に渡してフィードバックを送信する。DB 永続化などは `onSuccess` コールバックでも行える。
|
|
69
69
|
|
|
70
70
|
```typescript
|
|
71
|
-
let lastOutputTraceId: string | undefined;
|
|
72
|
-
|
|
73
71
|
const handler = new LangInsight.CallbackHandler({
|
|
74
72
|
...options,
|
|
75
|
-
onSuccess: (input, output) => {
|
|
76
|
-
lastOutputTraceId = output.id; // DB 永続化などもここで
|
|
77
|
-
},
|
|
78
73
|
});
|
|
79
74
|
|
|
80
|
-
// report() または onFinish
|
|
81
|
-
await handler.score({ traceId: lastOutputTraceId!, value: 1 }); // 👍
|
|
82
|
-
await handler.score({ traceId: lastOutputTraceId!, value: -1 }); // 👎
|
|
83
|
-
|
|
84
|
-
// または handler.result を使用
|
|
75
|
+
// report() または onFinish の後に
|
|
85
76
|
const { input, output } = await handler.result;
|
|
86
|
-
|
|
77
|
+
await handler.score({ traceId: output.id, value: 1 }); // 👍
|
|
78
|
+
await handler.score({ traceId: output.id, value: -1 }); // 👎
|
|
87
79
|
```
|
|
88
80
|
|
|
89
81
|
## Options
|
|
@@ -104,5 +96,5 @@ console.log("Input trace:", input.id, "Output trace:", output.id);
|
|
|
104
96
|
|
|
105
97
|
- **`report(result, { input })`** — Sends traces for a `generateText` result. Both input and output traces are passed to `onSuccess` on success.
|
|
106
98
|
- **`onFinish({ input })`** — Returns a function suitable for `streamText`'s `onFinish`. Sends traces when the stream finishes; both traces are passed to `onSuccess`.
|
|
107
|
-
- **`score({ traceId, value })`** — Submits feedback (1 = thumbs up, -1 = thumbs down) for the given trace. Use
|
|
99
|
+
- **`score({ traceId, value })`** — Submits feedback (1 = thumbs up, -1 = thumbs down) for the given trace. Use `(await handler.result).output.id` as `traceId`.
|
|
108
100
|
- **`result`** — A promise that resolves with `{ input: Trace, output: Trace }` when traces are sent successfully.
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -96,24 +106,24 @@ var mergePath = (base, path) => {
|
|
|
96
106
|
return base + path;
|
|
97
107
|
};
|
|
98
108
|
var replaceUrlParam = (urlString, params) => {
|
|
99
|
-
for (const [k,
|
|
109
|
+
for (const [k, v2] of Object.entries(params)) {
|
|
100
110
|
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??");
|
|
101
|
-
urlString = urlString.replace(reg,
|
|
111
|
+
urlString = urlString.replace(reg, v2 ? `/${v2}` : "");
|
|
102
112
|
}
|
|
103
113
|
return urlString;
|
|
104
114
|
};
|
|
105
115
|
var buildSearchParams = (query) => {
|
|
106
116
|
const searchParams = new URLSearchParams();
|
|
107
|
-
for (const [k,
|
|
108
|
-
if (
|
|
117
|
+
for (const [k, v2] of Object.entries(query)) {
|
|
118
|
+
if (v2 === void 0) {
|
|
109
119
|
continue;
|
|
110
120
|
}
|
|
111
|
-
if (Array.isArray(
|
|
112
|
-
for (const
|
|
113
|
-
searchParams.append(k,
|
|
121
|
+
if (Array.isArray(v2)) {
|
|
122
|
+
for (const v22 of v2) {
|
|
123
|
+
searchParams.append(k, v22);
|
|
114
124
|
}
|
|
115
125
|
} else {
|
|
116
|
-
searchParams.set(k,
|
|
126
|
+
searchParams.set(k, v2);
|
|
117
127
|
}
|
|
118
128
|
}
|
|
119
129
|
return searchParams;
|
|
@@ -190,13 +200,13 @@ var ClientRequestImpl = class {
|
|
|
190
200
|
}
|
|
191
201
|
if (args.form) {
|
|
192
202
|
const form = new FormData();
|
|
193
|
-
for (const [k,
|
|
194
|
-
if (Array.isArray(
|
|
195
|
-
for (const
|
|
196
|
-
form.append(k,
|
|
203
|
+
for (const [k, v2] of Object.entries(args.form)) {
|
|
204
|
+
if (Array.isArray(v2)) {
|
|
205
|
+
for (const v22 of v2) {
|
|
206
|
+
form.append(k, v22);
|
|
197
207
|
}
|
|
198
208
|
} else {
|
|
199
|
-
form.append(k,
|
|
209
|
+
form.append(k, v2);
|
|
200
210
|
}
|
|
201
211
|
}
|
|
202
212
|
this.rBody = form;
|
|
@@ -315,132 +325,165 @@ var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
|
315
325
|
}, []);
|
|
316
326
|
|
|
317
327
|
// src/index.ts
|
|
328
|
+
var v = __toESM(require("valibot"), 1);
|
|
318
329
|
var LangInsight;
|
|
319
330
|
((LangInsight2) => {
|
|
320
331
|
class CallbackHandler {
|
|
321
332
|
constructor(options) {
|
|
322
333
|
this.options = options;
|
|
323
334
|
this.client = hc(options.endpoint, { fetch });
|
|
324
|
-
this.result = new Promise((resolve
|
|
335
|
+
this.result = new Promise((resolve) => {
|
|
325
336
|
this.resolve = resolve;
|
|
326
|
-
this.reject = reject;
|
|
327
337
|
});
|
|
328
338
|
}
|
|
329
339
|
client;
|
|
330
340
|
resolve = null;
|
|
331
|
-
reject = null;
|
|
332
341
|
result;
|
|
342
|
+
extract({ steps }) {
|
|
343
|
+
const result = v.safeParse(
|
|
344
|
+
v.object({
|
|
345
|
+
contents: v.array(
|
|
346
|
+
v.partial(
|
|
347
|
+
v.looseObject({
|
|
348
|
+
role: v.string(),
|
|
349
|
+
parts: v.array(v.partial(v.looseObject({ type: v.string(), text: v.string() })))
|
|
350
|
+
})
|
|
351
|
+
)
|
|
352
|
+
)
|
|
353
|
+
}),
|
|
354
|
+
steps[steps.length - 1]?.request.body
|
|
355
|
+
);
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
333
358
|
/**
|
|
334
|
-
* streamText の onFinish
|
|
359
|
+
* streamText の onFinish コールバック。
|
|
360
|
+
* ストリーミング完了時に入力・出力のトレースを Core API に送信する。
|
|
335
361
|
*
|
|
336
362
|
* @example
|
|
337
363
|
* ```ts
|
|
338
|
-
* const handler = new LangInsight.CallbackHandler(
|
|
339
|
-
*
|
|
364
|
+
* const handler = new LangInsight.CallbackHandler({ cookie, metadata: { userId, sessionId } });
|
|
340
365
|
* const result = streamText({
|
|
341
|
-
* model
|
|
342
|
-
*
|
|
343
|
-
* onFinish: handler.onFinish
|
|
366
|
+
* model,
|
|
367
|
+
* messages,
|
|
368
|
+
* onFinish: handler.onFinish,
|
|
344
369
|
* });
|
|
345
370
|
* ```
|
|
346
371
|
*/
|
|
347
|
-
onFinish(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
372
|
+
onFinish = async (event) => {
|
|
373
|
+
try {
|
|
374
|
+
const { userId, sessionId, ...rest } = this.options.metadata;
|
|
375
|
+
const model = event.response.modelId ?? "unknown";
|
|
376
|
+
const usage = event.usage;
|
|
377
|
+
const startedAt = event.response.timestamp;
|
|
378
|
+
const endedAt = /* @__PURE__ */ new Date();
|
|
379
|
+
const { success, output, issues } = this.extract(event);
|
|
380
|
+
if (!success) {
|
|
381
|
+
console.error(issues);
|
|
382
|
+
throw new Error("Failed to parse request body");
|
|
383
|
+
}
|
|
384
|
+
const input = output.contents.at(-1)?.parts?.map((part) => part.text).join("") ?? "";
|
|
385
|
+
const body = {
|
|
386
|
+
userId,
|
|
387
|
+
sessionId,
|
|
388
|
+
model,
|
|
389
|
+
meta: { ...rest },
|
|
390
|
+
startedAt: startedAt.toISOString(),
|
|
391
|
+
endedAt: endedAt.toISOString()
|
|
392
|
+
};
|
|
393
|
+
const res = await Promise.all([
|
|
394
|
+
this.client.traces.external.$post({
|
|
395
|
+
json: {
|
|
396
|
+
...body,
|
|
397
|
+
type: "input",
|
|
398
|
+
token: usage.inputTokens ?? 0,
|
|
399
|
+
content: input
|
|
400
|
+
},
|
|
401
|
+
header: {
|
|
402
|
+
"x-api-key": this.options.apiKey
|
|
403
|
+
}
|
|
404
|
+
}),
|
|
405
|
+
this.client.traces.external.$post({
|
|
406
|
+
json: {
|
|
407
|
+
...body,
|
|
408
|
+
type: "output",
|
|
409
|
+
token: usage.outputTokens ?? 0,
|
|
410
|
+
content: event.text
|
|
411
|
+
},
|
|
412
|
+
header: {
|
|
413
|
+
"x-api-key": this.options.apiKey
|
|
414
|
+
}
|
|
415
|
+
})
|
|
416
|
+
]);
|
|
417
|
+
if (!res.every((r) => r.ok)) {
|
|
418
|
+
const [a, b] = await Promise.all(res.map((r) => r.text()));
|
|
419
|
+
console.error(a, b);
|
|
420
|
+
throw new Error("Failed to send traces");
|
|
421
|
+
}
|
|
422
|
+
const trace = { input: await res[0].json(), output: await res[1].json() };
|
|
423
|
+
this.resolve?.(trace);
|
|
424
|
+
this.options.onSuccess?.(trace.input, trace.output);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
427
|
+
this.resolve?.(null);
|
|
428
|
+
console.error(err);
|
|
429
|
+
this.options.onFailure?.(err);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
355
432
|
/**
|
|
356
|
-
* generateText
|
|
357
|
-
*
|
|
433
|
+
* generateText の結果からトレースを送信する。
|
|
434
|
+
* 非ストリーミング生成時に入力・出力のトレースを Core API に送信する。
|
|
358
435
|
*
|
|
359
|
-
* @
|
|
360
|
-
* ```ts
|
|
361
|
-
* const handler = new LangInsight.CallbackHandler({
|
|
362
|
-
* ...options,
|
|
363
|
-
* onSuccess: (input, output) => {
|
|
364
|
-
* saveTraceToDb(output); // traceId = output.id
|
|
365
|
-
* },
|
|
366
|
-
* });
|
|
367
|
-
* const result = await generateText({ model: openai("gpt-4o"), prompt: "Hello!" });
|
|
368
|
-
* await handler.report(result, { input: "Hello!" });
|
|
369
|
-
* ```
|
|
370
|
-
*/
|
|
371
|
-
// biome-ignore lint/suspicious/noExplicitAny: should accept any output
|
|
372
|
-
async report(result, params) {
|
|
373
|
-
await this.sendTraces({
|
|
374
|
-
input: params.input,
|
|
375
|
-
result
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* フィードバック(👍/👎)を送信
|
|
380
|
-
* traceId は onSuccess コールバックで受け取った output.id を使用する。
|
|
436
|
+
* @param result - generateText の戻り値
|
|
381
437
|
*
|
|
382
438
|
* @example
|
|
383
439
|
* ```ts
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
* await handler.
|
|
440
|
+
* const handler = new LangInsight.CallbackHandler({ cookie, metadata: { userId, sessionId } });
|
|
441
|
+
* const result = await generateText({ model, messages });
|
|
442
|
+
* await handler.report(result);
|
|
387
443
|
* ```
|
|
388
444
|
*/
|
|
389
|
-
async
|
|
390
|
-
const { userId, sessionId } = this.options.metadata;
|
|
391
|
-
const res = await this.client.feedbacks.external.$post({
|
|
392
|
-
header: {
|
|
393
|
-
"x-api-key": this.options.apiKey
|
|
394
|
-
},
|
|
395
|
-
json: {
|
|
396
|
-
traceId: params.traceId,
|
|
397
|
-
sessionId,
|
|
398
|
-
userId,
|
|
399
|
-
value: params.value
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
if (!res.ok) {
|
|
403
|
-
console.error(await res.text());
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
async sendTraces(params) {
|
|
407
|
-
const { input, result } = params;
|
|
408
|
-
const { userId, sessionId, ...rest } = this.options.metadata;
|
|
409
|
-
const model = result.response.modelId ?? "unknown";
|
|
410
|
-
const startedAt = result.response.timestamp;
|
|
411
|
-
const endedAt = /* @__PURE__ */ new Date();
|
|
445
|
+
async report(result) {
|
|
412
446
|
try {
|
|
447
|
+
const { userId, sessionId, ...rest } = this.options.metadata;
|
|
448
|
+
const model = result.response.modelId ?? "unknown";
|
|
449
|
+
const usage = result.usage;
|
|
450
|
+
const startedAt = result.response.timestamp;
|
|
451
|
+
const endedAt = /* @__PURE__ */ new Date();
|
|
452
|
+
const { success, output, issues } = this.extract(result);
|
|
453
|
+
if (!success) {
|
|
454
|
+
console.error(issues);
|
|
455
|
+
throw new Error("Failed to parse request body");
|
|
456
|
+
}
|
|
457
|
+
const input = output.contents.at(-1)?.parts?.map((part) => part.text).join("") ?? "";
|
|
458
|
+
const body = {
|
|
459
|
+
userId,
|
|
460
|
+
sessionId,
|
|
461
|
+
model,
|
|
462
|
+
meta: { ...rest },
|
|
463
|
+
startedAt: startedAt.toISOString(),
|
|
464
|
+
endedAt: endedAt.toISOString()
|
|
465
|
+
};
|
|
413
466
|
const res = await Promise.all([
|
|
414
467
|
this.client.traces.external.$post({
|
|
415
|
-
header: {
|
|
416
|
-
"x-api-key": this.options.apiKey
|
|
417
|
-
},
|
|
418
468
|
json: {
|
|
419
|
-
|
|
420
|
-
sessionId,
|
|
421
|
-
model,
|
|
422
|
-
token: result.usage.inputTokens ?? 0,
|
|
423
|
-
content: input,
|
|
469
|
+
...body,
|
|
424
470
|
type: "input",
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
471
|
+
token: usage.inputTokens ?? 0,
|
|
472
|
+
content: input
|
|
473
|
+
},
|
|
474
|
+
header: {
|
|
475
|
+
"x-api-key": this.options.apiKey
|
|
428
476
|
}
|
|
429
477
|
}),
|
|
430
478
|
this.client.traces.external.$post({
|
|
431
|
-
header: {
|
|
432
|
-
"x-api-key": this.options.apiKey
|
|
433
|
-
},
|
|
434
479
|
json: {
|
|
435
|
-
|
|
436
|
-
sessionId,
|
|
437
|
-
model,
|
|
438
|
-
token: result.usage.outputTokens ?? 0,
|
|
439
|
-
content: result.text,
|
|
480
|
+
...body,
|
|
440
481
|
type: "output",
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
482
|
+
token: usage.outputTokens ?? 0,
|
|
483
|
+
content: result.text
|
|
484
|
+
},
|
|
485
|
+
header: {
|
|
486
|
+
"x-api-key": this.options.apiKey
|
|
444
487
|
}
|
|
445
488
|
})
|
|
446
489
|
]);
|
|
@@ -449,17 +492,39 @@ var LangInsight;
|
|
|
449
492
|
console.error(a, b);
|
|
450
493
|
throw new Error("Failed to send traces");
|
|
451
494
|
}
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
this.
|
|
455
|
-
this.options.onSuccess?.(inputTrace, outputTrace);
|
|
495
|
+
const trace = { input: await res[0].json(), output: await res[1].json() };
|
|
496
|
+
this.resolve?.(trace);
|
|
497
|
+
this.options.onSuccess?.(trace.input, trace.output);
|
|
456
498
|
} catch (error) {
|
|
457
499
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
458
|
-
this.
|
|
500
|
+
this.resolve?.(null);
|
|
459
501
|
console.error(err);
|
|
460
502
|
this.options.onFailure?.(err);
|
|
461
503
|
}
|
|
462
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* フィードバック(👍/👎)を送信
|
|
507
|
+
* traceId は onSuccess コールバックで受け取った output.id を使用する。
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```ts
|
|
511
|
+
* onSuccess: (input, output) => { lastOutputTraceId = output.id; },
|
|
512
|
+
* // ...
|
|
513
|
+
* await handler.score({ traceId: lastOutputTraceId, value: 1 }); // 👍
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
async score(params) {
|
|
517
|
+
const { userId, sessionId } = this.options.metadata;
|
|
518
|
+
const res = await this.client.feedbacks.external.$post({
|
|
519
|
+
json: { traceId: params.traceId, sessionId, userId, value: params.value },
|
|
520
|
+
header: {
|
|
521
|
+
"x-api-key": this.options.apiKey
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
if (!res.ok) {
|
|
525
|
+
console.error(await res.text());
|
|
526
|
+
}
|
|
527
|
+
}
|
|
463
528
|
}
|
|
464
529
|
LangInsight2.CallbackHandler = CallbackHandler;
|
|
465
530
|
})(LangInsight || (LangInsight = {}));
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StreamTextOnFinishCallback, ToolSet, generateText } from 'ai';
|
|
2
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
3
|
|
|
4
|
-
declare const vTraceEntity: ObjectSchema<
|
|
4
|
+
declare const vTraceEntity: ObjectSchema<
|
|
5
|
+
{
|
|
5
6
|
readonly id: SchemaWithPipe<readonly [StringSchema<undefined>, UuidAction<string, undefined>]>;
|
|
6
7
|
readonly userId: StringSchema<undefined>;
|
|
7
8
|
readonly sessionId: StringSchema<undefined>;
|
|
@@ -13,8 +14,12 @@ declare const vTraceEntity: ObjectSchema<{
|
|
|
13
14
|
readonly createdAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
14
15
|
readonly startedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
15
16
|
readonly endedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
16
|
-
},
|
|
17
|
-
|
|
17
|
+
},
|
|
18
|
+
undefined
|
|
19
|
+
> & {
|
|
20
|
+
create: Omit<
|
|
21
|
+
ObjectSchema<
|
|
22
|
+
{
|
|
18
23
|
readonly id: SchemaWithPipe<readonly [StringSchema<undefined>, UuidAction<string, undefined>]>;
|
|
19
24
|
readonly userId: StringSchema<undefined>;
|
|
20
25
|
readonly sessionId: StringSchema<undefined>;
|
|
@@ -26,96 +31,114 @@ declare const vTraceEntity: ObjectSchema<{
|
|
|
26
31
|
readonly createdAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
27
32
|
readonly startedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
28
33
|
readonly endedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
readonly
|
|
34
|
+
},
|
|
35
|
+
undefined
|
|
36
|
+
>,
|
|
37
|
+
"~types" | "~run" | "~standard" | "entries"
|
|
38
|
+
> & {
|
|
39
|
+
readonly entries: Omit<
|
|
40
|
+
{
|
|
41
|
+
readonly id: SchemaWithPipe<readonly [StringSchema<undefined>, UuidAction<string, undefined>]>;
|
|
42
|
+
readonly userId: StringSchema<undefined>;
|
|
43
|
+
readonly sessionId: StringSchema<undefined>;
|
|
44
|
+
readonly model: StringSchema<undefined>;
|
|
45
|
+
readonly token: NumberSchema<undefined>;
|
|
46
|
+
readonly content: StringSchema<undefined>;
|
|
47
|
+
readonly type: PicklistSchema<["input", "output", "error"], undefined>;
|
|
48
|
+
readonly meta: RecordSchema<StringSchema<undefined>, AnySchema, undefined>;
|
|
49
|
+
readonly createdAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
50
|
+
readonly startedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
51
|
+
readonly endedAt: SchemaWithPipe<readonly [CustomSchema<unknown, undefined>, StringSchema<undefined>]>;
|
|
52
|
+
},
|
|
53
|
+
"id" | "createdAt"
|
|
54
|
+
>;
|
|
55
|
+
readonly "~standard": StandardProps<
|
|
56
|
+
{
|
|
57
|
+
type: "output" | "input" | "error";
|
|
58
|
+
token: number;
|
|
59
|
+
content: string;
|
|
60
|
+
userId: string;
|
|
61
|
+
model: string;
|
|
62
|
+
meta: {
|
|
63
|
+
[x: string]: any;
|
|
64
|
+
};
|
|
65
|
+
sessionId: string;
|
|
66
|
+
startedAt: unknown;
|
|
67
|
+
endedAt: unknown;
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: "output" | "input" | "error";
|
|
71
|
+
token: number;
|
|
72
|
+
content: string;
|
|
73
|
+
userId: string;
|
|
74
|
+
model: string;
|
|
75
|
+
meta: {
|
|
76
|
+
[x: string]: any;
|
|
77
|
+
};
|
|
78
|
+
sessionId: string;
|
|
79
|
+
startedAt: string;
|
|
80
|
+
endedAt: string;
|
|
81
|
+
}
|
|
82
|
+
>;
|
|
83
|
+
readonly "~run": (
|
|
84
|
+
dataset: UnknownDataset,
|
|
85
|
+
config: Config<BaseIssue<unknown>>,
|
|
86
|
+
) => OutputDataset<
|
|
87
|
+
{
|
|
88
|
+
type: "output" | "input" | "error";
|
|
89
|
+
token: number;
|
|
90
|
+
content: string;
|
|
91
|
+
userId: string;
|
|
92
|
+
model: string;
|
|
93
|
+
meta: {
|
|
94
|
+
[x: string]: any;
|
|
95
|
+
};
|
|
96
|
+
sessionId: string;
|
|
97
|
+
startedAt: string;
|
|
98
|
+
endedAt: string;
|
|
99
|
+
},
|
|
100
|
+
ObjectIssue | NumberIssue | StringIssue | PicklistIssue | RecordIssue | CustomIssue
|
|
101
|
+
>;
|
|
102
|
+
readonly "~types"?:
|
|
103
|
+
| {
|
|
104
|
+
readonly input: {
|
|
44
105
|
type: "output" | "input" | "error";
|
|
45
106
|
token: number;
|
|
46
107
|
content: string;
|
|
47
108
|
userId: string;
|
|
48
109
|
model: string;
|
|
49
110
|
meta: {
|
|
50
|
-
|
|
111
|
+
[x: string]: any;
|
|
51
112
|
};
|
|
52
113
|
sessionId: string;
|
|
53
114
|
startedAt: unknown;
|
|
54
115
|
endedAt: unknown;
|
|
55
|
-
|
|
56
|
-
|
|
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<{
|
|
116
|
+
};
|
|
117
|
+
readonly output: {
|
|
69
118
|
type: "output" | "input" | "error";
|
|
70
119
|
token: number;
|
|
71
120
|
content: string;
|
|
72
121
|
userId: string;
|
|
73
122
|
model: string;
|
|
74
123
|
meta: {
|
|
75
|
-
|
|
124
|
+
[x: string]: any;
|
|
76
125
|
};
|
|
77
126
|
sessionId: string;
|
|
78
127
|
startedAt: string;
|
|
79
128
|
endedAt: string;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
};
|
|
129
|
+
};
|
|
130
|
+
readonly issue: ObjectIssue | NumberIssue | StringIssue | PicklistIssue | RecordIssue | CustomIssue;
|
|
131
|
+
}
|
|
132
|
+
| undefined;
|
|
133
|
+
};
|
|
111
134
|
};
|
|
112
135
|
type TraceEntity = InferOutput<typeof vTraceEntity>;
|
|
113
136
|
declare namespace TraceEntity {
|
|
114
|
-
|
|
137
|
+
type Create = InferOutput<typeof vTraceEntity.create>;
|
|
115
138
|
}
|
|
116
139
|
|
|
117
140
|
declare namespace LangInsight {
|
|
118
|
-
interface Options {
|
|
141
|
+
export interface Options {
|
|
119
142
|
apiKey: string;
|
|
120
143
|
endpoint: string;
|
|
121
144
|
metadata: {
|
|
@@ -126,55 +149,46 @@ declare namespace LangInsight {
|
|
|
126
149
|
onSuccess?: (input: TraceEntity, output: TraceEntity) => void;
|
|
127
150
|
onFailure?: (error: Error) => void;
|
|
128
151
|
}
|
|
129
|
-
|
|
152
|
+
type TraceValue = {
|
|
153
|
+
input: TraceEntity;
|
|
154
|
+
output: TraceEntity;
|
|
155
|
+
} | null;
|
|
156
|
+
export class CallbackHandler {
|
|
130
157
|
private readonly options;
|
|
131
158
|
private readonly client;
|
|
132
159
|
private resolve;
|
|
133
|
-
|
|
134
|
-
readonly result: Promise<{
|
|
135
|
-
input: TraceEntity;
|
|
136
|
-
output: TraceEntity;
|
|
137
|
-
}>;
|
|
160
|
+
readonly result: Promise<TraceValue>;
|
|
138
161
|
constructor(options: Options);
|
|
162
|
+
private extract;
|
|
139
163
|
/**
|
|
140
|
-
* streamText の onFinish
|
|
164
|
+
* streamText の onFinish コールバック。
|
|
165
|
+
* ストリーミング完了時に入力・出力のトレースを Core API に送信する。
|
|
141
166
|
*
|
|
142
167
|
* @example
|
|
143
168
|
* ```ts
|
|
144
|
-
* const handler = new LangInsight.CallbackHandler(
|
|
145
|
-
*
|
|
169
|
+
* const handler = new LangInsight.CallbackHandler({ cookie, metadata: { userId, sessionId } });
|
|
146
170
|
* const result = streamText({
|
|
147
|
-
* model
|
|
148
|
-
*
|
|
149
|
-
* onFinish: handler.onFinish
|
|
171
|
+
* model,
|
|
172
|
+
* messages,
|
|
173
|
+
* onFinish: handler.onFinish,
|
|
150
174
|
* });
|
|
151
175
|
* ```
|
|
152
176
|
*/
|
|
153
|
-
onFinish
|
|
154
|
-
input: string;
|
|
155
|
-
}): (event: StepResult<ToolSet> & {
|
|
156
|
-
readonly steps: StepResult<ToolSet>[];
|
|
157
|
-
readonly totalUsage: LanguageModelUsage;
|
|
158
|
-
}) => Promise<void>;
|
|
177
|
+
onFinish: StreamTextOnFinishCallback<ToolSet>;
|
|
159
178
|
/**
|
|
160
|
-
* generateText
|
|
161
|
-
*
|
|
179
|
+
* generateText の結果からトレースを送信する。
|
|
180
|
+
* 非ストリーミング生成時に入力・出力のトレースを Core API に送信する。
|
|
181
|
+
*
|
|
182
|
+
* @param result - generateText の戻り値
|
|
162
183
|
*
|
|
163
184
|
* @example
|
|
164
185
|
* ```ts
|
|
165
|
-
* const handler = new LangInsight.CallbackHandler({
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* saveTraceToDb(output); // traceId = output.id
|
|
169
|
-
* },
|
|
170
|
-
* });
|
|
171
|
-
* const result = await generateText({ model: openai("gpt-4o"), prompt: "Hello!" });
|
|
172
|
-
* await handler.report(result, { input: "Hello!" });
|
|
186
|
+
* const handler = new LangInsight.CallbackHandler({ cookie, metadata: { userId, sessionId } });
|
|
187
|
+
* const result = await generateText({ model, messages });
|
|
188
|
+
* await handler.report(result);
|
|
173
189
|
* ```
|
|
174
190
|
*/
|
|
175
|
-
report(result:
|
|
176
|
-
input: string;
|
|
177
|
-
}): Promise<void>;
|
|
191
|
+
report(result: Awaited<ReturnType<typeof generateText>>): Promise<void>;
|
|
178
192
|
/**
|
|
179
193
|
* フィードバック(👍/👎)を送信
|
|
180
194
|
* traceId は onSuccess コールバックで受け取った output.id を使用する。
|
|
@@ -190,8 +204,8 @@ declare namespace LangInsight {
|
|
|
190
204
|
traceId: string;
|
|
191
205
|
value: 1 | -1;
|
|
192
206
|
}): Promise<void>;
|
|
193
|
-
private sendTraces;
|
|
194
207
|
}
|
|
208
|
+
export { };
|
|
195
209
|
}
|
|
196
210
|
|
|
197
211
|
export { LangInsight };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@langinsight/ai-sdk",
|
|
3
3
|
"module": "dist/index.js",
|
|
4
4
|
"types": "dist/index.d.ts",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.1.1",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -16,14 +16,15 @@
|
|
|
16
16
|
"build": "tsup src/index.ts --dts --out-dir dist"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@hono/client": "^0.0.3"
|
|
19
|
+
"@hono/client": "^0.0.3",
|
|
20
|
+
"valibot": "^1.2.0"
|
|
20
21
|
},
|
|
21
22
|
"peerDependencies": {
|
|
22
23
|
"ai": ">=5.0.0"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
|
-
"@types/bun": "1.3.
|
|
26
|
-
"ai": "^6.0.
|
|
26
|
+
"@types/bun": "1.3.9",
|
|
27
|
+
"ai": "^6.0.86",
|
|
27
28
|
"tsup": "^8.5.1",
|
|
28
29
|
"typescript": "^5.9.3"
|
|
29
30
|
}
|