simple-ai-sdk 1.0.20 → 1.0.22

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.
@@ -1 +1 @@
1
- {"version":3,"file":"chat-session-utils.d.ts","sourceRoot":"","sources":["../../src/client/chat-session-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,oBAAoB,CAAC;AAGhE,MAAM,MAAM,0BAA0B,GAAG;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjC;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,sBAAsB,gBAItB,MAAM,WAAW,0BAA0B,UAqC1D"}
1
+ {"version":3,"file":"chat-session-utils.d.ts","sourceRoot":"","sources":["../../src/client/chat-session-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,oBAAoB,CAAC;AAGhE,MAAM,MAAM,0BAA0B,GAAG;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjC;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,sBAAsB,gBAItB,MAAM,WAAW,0BAA0B,UAoC1D"}
@@ -12,7 +12,6 @@ export function usePrefetchChatSession() {
12
12
  const prefetchChatSession = useCallback((sessionId, options) => {
13
13
  // セッションの初期化(すでに存在する場合はスキップされる)
14
14
  manager.initSession(sessionId);
15
- // startStreamがtrueの場合、ストリーミングを開始(完了を待たない)
16
15
  if (options.streamMessageContent) {
17
16
  // streamChatを呼び出すが、awaitせずに即座に返す
18
17
  // これによりストリーミングはバックグラウンドで継続される
@@ -1,4 +1,4 @@
1
- import type { ChatSession, StreamManagerListener, StreamManagerState } from "./types.js";
1
+ import type { ChatSession, OnChatFinishCallback, StreamManagerListener, StreamManagerState } from "./types.js";
2
2
  import type { Message, JSONValue } from "../shared/index.js";
3
3
  export interface IStreamManager {
4
4
  subscribe(listener: StreamManagerListener): () => void;
@@ -14,7 +14,7 @@ export interface IStreamManager {
14
14
  * - ストリーム完了時は常にこの最新ハンドラを呼び出す。
15
15
  * - コンポーネントがアンマウントされても保持され、完了時に呼ばれる。
16
16
  */
17
- setOnFinishHandler(sessionId: string, handler: ((messages: Message[]) => void) | undefined): void;
17
+ setOnFinishHandler(sessionId: string, handler: OnChatFinishCallback | undefined): void;
18
18
  /**
19
19
  * セッション単位で最新の onError ハンドラを登録する。
20
20
  */
@@ -72,15 +72,20 @@ declare class StreamManager implements IStreamManager {
72
72
  private activeSubscribers;
73
73
  private latestOnFinish;
74
74
  private latestOnError;
75
+ private pendingOnFinish;
76
+ private pendingOnError;
75
77
  private streamIds;
76
78
  constructor(options?: StreamManagerOptions);
77
79
  subscribe(listener: StreamManagerListener): () => void;
78
- setOnFinishHandler(sessionId: string, handler: ((messages: Message[]) => void) | undefined): void;
80
+ setOnFinishHandler(sessionId: string, handler: OnChatFinishCallback | undefined): void;
79
81
  setOnErrorHandler(sessionId: string, handler: ((error: Error) => void) | undefined): void;
80
82
  getSnapshot(): StreamManagerState;
81
83
  private notify;
82
84
  getSession(sessionId: string): ChatSession | undefined;
83
85
  touchSession(sessionId: string): void;
86
+ private getMessagesSnapshot;
87
+ private deliverOrQueueFinish;
88
+ private deliverOrQueueError;
84
89
  initSession(sessionId: string, initialMessages?: Message[]): void;
85
90
  retainSession(sessionId: string): void;
86
91
  releaseSession(sessionId: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/client/manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/client/manager.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,11 @@ class StreamManager {
47
47
  latestOnFinish = new Map();
48
48
  // セッション単位で「最新の onError」を保持
49
49
  latestOnError = new Map();
50
+ // usePrefetchChatSession() でuseChatSession()がマウントされる前にストリーミングが完了した場合、
51
+ // onFinish や onError を呼び出せないため、保留しておく仕組み
52
+ // これにより、すでにストリーミングが完了している場合でも、useChatSession()マウント時にonFinish/onErrorが呼ばれる
53
+ pendingOnFinish = new Map();
54
+ pendingOnError = new Map();
50
55
  // 意図: 各セッションの最新ストリームIDを保持し、古いストリームの遅延イベントを無視する
51
56
  streamIds = new Map();
52
57
  constructor(options = {}) {
@@ -76,6 +81,17 @@ class StreamManager {
76
81
  setOnFinishHandler(sessionId, handler) {
77
82
  if (handler) {
78
83
  this.latestOnFinish.set(sessionId, handler);
84
+ const pending = this.pendingOnFinish.get(sessionId);
85
+ if (pending) {
86
+ // プレフェッチ完了時に溜め込んだデータをマウント直後に流す
87
+ this.pendingOnFinish.delete(sessionId);
88
+ try {
89
+ handler(pending.messages, pending.details);
90
+ }
91
+ catch {
92
+ console.error("[SM] Failed to call onFinish handler");
93
+ }
94
+ }
79
95
  }
80
96
  else {
81
97
  this.latestOnFinish.delete(sessionId);
@@ -84,6 +100,17 @@ class StreamManager {
84
100
  setOnErrorHandler(sessionId, handler) {
85
101
  if (handler) {
86
102
  this.latestOnError.set(sessionId, handler);
103
+ const pending = this.pendingOnError.get(sessionId);
104
+ if (pending) {
105
+ // 完了時と同様、マウント前に発生したエラーを直ちに伝える
106
+ this.pendingOnError.delete(sessionId);
107
+ try {
108
+ handler(pending);
109
+ }
110
+ catch {
111
+ console.error("[SM] Failed to call onError handler");
112
+ }
113
+ }
87
114
  }
88
115
  else {
89
116
  this.latestOnError.delete(sessionId);
@@ -184,6 +211,56 @@ class StreamManager {
184
211
  session.lastAccessed = Date.now();
185
212
  }
186
213
  }
214
+ getMessagesSnapshot(sessionId) {
215
+ const session = this.state.sessions.get(sessionId);
216
+ if (!session)
217
+ return [];
218
+ // Shallow copy to avoid later mutations affecting pending callbacks
219
+ return session.messages.map((message) => ({ ...message }));
220
+ }
221
+ deliverOrQueueFinish(sessionId, details, context = "default") {
222
+ // useChatSession() マウント前に完了した場合は pending に積んで後から呼び出す
223
+ const finalMessages = this.getMessagesSnapshot(sessionId);
224
+ const handler = this.latestOnFinish.get(sessionId);
225
+ if (handler) {
226
+ this.pendingOnFinish.delete(sessionId);
227
+ try {
228
+ handler(finalMessages, details);
229
+ }
230
+ catch {
231
+ if (context === "completion") {
232
+ console.error("[SM] Failed to call onFinish handler on completion");
233
+ }
234
+ else {
235
+ console.error("[SM] Failed to call onFinish handler");
236
+ }
237
+ }
238
+ }
239
+ else {
240
+ this.pendingOnFinish.set(sessionId, {
241
+ messages: finalMessages,
242
+ details,
243
+ });
244
+ }
245
+ this.pendingOnError.delete(sessionId);
246
+ }
247
+ deliverOrQueueError(sessionId, error) {
248
+ // エラー版:ハンドラが無いときは保留し、マウント時に即発火させる
249
+ const handler = this.latestOnError.get(sessionId);
250
+ this.pendingOnFinish.delete(sessionId);
251
+ if (handler) {
252
+ this.pendingOnError.delete(sessionId);
253
+ try {
254
+ handler(error);
255
+ }
256
+ catch {
257
+ console.error("[SM] Failed to call onError handler");
258
+ }
259
+ }
260
+ else {
261
+ this.pendingOnError.set(sessionId, error);
262
+ }
263
+ }
187
264
  initSession(sessionId, initialMessages = []) {
188
265
  const existingSession = this.state.sessions.get(sessionId);
189
266
  // streaming中のセッションが存在する場合は、initialMessagesで上書きしない
@@ -210,10 +287,13 @@ class StreamManager {
210
287
  return;
211
288
  }
212
289
  }
290
+ this.pendingOnFinish.delete(sessionId);
291
+ this.pendingOnError.delete(sessionId);
213
292
  this.state.sessions.set(sessionId, {
214
293
  id: sessionId,
215
294
  messages: initialMessages,
216
295
  metadata: [],
296
+ finishedReason: null,
217
297
  messagesVersion: 0,
218
298
  status: "ready",
219
299
  error: null,
@@ -293,6 +373,8 @@ class StreamManager {
293
373
  this.latestOnError.delete(oldestSessionId);
294
374
  // 意図: streamId も破棄してメモリリーク・誤判定を防止
295
375
  this.streamIds.delete(oldestSessionId);
376
+ this.pendingOnFinish.delete(oldestSessionId);
377
+ this.pendingOnError.delete(oldestSessionId);
296
378
  if (this.debug) {
297
379
  this.logSessionInfo(`Session removed: ${oldestSessionId} (LRU eviction)`);
298
380
  }
@@ -355,12 +437,22 @@ class StreamManager {
355
437
  const isErrorPayload = (v) => isObject(v) &&
356
438
  (typeof v.message === "undefined" ||
357
439
  typeof v.message === "string");
440
+ const isDonePayload = (v) => isObject(v) &&
441
+ (typeof v.finished_reason ===
442
+ "undefined" ||
443
+ typeof v.finished_reason ===
444
+ "string" ||
445
+ v.finished_reason === null);
358
446
  const session = this.state.sessions.get(sessionId);
359
447
  if (!session) {
360
448
  if (this.debug)
361
449
  console.warn(`[SM] streamChat called for non-existing session: ${sessionId}`);
362
450
  return;
363
451
  }
452
+ // 新しいストリーム開始時は保留中のライフサイクル通知を破棄する
453
+ // (最新ストリームで再計算されるため、古い結果は破棄してよい)
454
+ this.pendingOnFinish.delete(sessionId);
455
+ this.pendingOnError.delete(sessionId);
364
456
  // 既存のストリームがあれば中断してから新規ストリームを開始する
365
457
  // (同一セッションでの重複ストリーミングを防止)
366
458
  if (session.abortController) {
@@ -383,6 +475,7 @@ class StreamManager {
383
475
  abortController,
384
476
  // 新規ストリーム開始時にメタデータはリセット(current stream のみ保持)
385
477
  metadata: [],
478
+ finishedReason: null,
386
479
  }, true); // Immediate for status change
387
480
  try {
388
481
  const requestBody = {
@@ -413,13 +506,7 @@ class StreamManager {
413
506
  error: err,
414
507
  abortController: null,
415
508
  }, true);
416
- // セッションに登録された最新の onError を使用
417
- try {
418
- this.latestOnError.get(sessionId)?.(err);
419
- }
420
- catch {
421
- console.error("[SM] Failed to call onError handler");
422
- }
509
+ this.deliverOrQueueError(sessionId, err);
423
510
  return;
424
511
  }
425
512
  const reader = response.body?.getReader();
@@ -517,12 +604,7 @@ class StreamManager {
517
604
  error: err,
518
605
  abortController: null,
519
606
  }, true);
520
- try {
521
- this.latestOnError.get(sessionId)?.(err);
522
- }
523
- catch {
524
- console.error("[SM] Failed to call onError handler");
525
- }
607
+ this.deliverOrQueueError(sessionId, err);
526
608
  failed = true;
527
609
  shouldTerminate = true;
528
610
  break;
@@ -531,17 +613,20 @@ class StreamManager {
531
613
  const latestId = this.streamIds.get(sessionId);
532
614
  if (latestId !== streamId)
533
615
  return; // 中断済みのストリームからの遅延イベントを破棄
616
+ let finishedReason = null;
617
+ if (isDonePayload(parsed)) {
618
+ if (typeof parsed.finished_reason === "string") {
619
+ finishedReason = parsed.finished_reason;
620
+ }
621
+ }
534
622
  this.updateSession(sessionId, {
535
623
  status: "ready",
536
624
  abortController: null,
625
+ finishedReason,
537
626
  }, true);
538
- try {
539
- this.latestOnFinish.get(sessionId)?.((this.state.sessions.get(sessionId)?.messages ||
540
- []));
541
- }
542
- catch {
543
- console.error("[SM] Failed to call onFinish handler");
544
- }
627
+ this.deliverOrQueueFinish(sessionId, {
628
+ finishedReason,
629
+ });
545
630
  shouldTerminate = true;
546
631
  break;
547
632
  }
@@ -605,13 +690,9 @@ class StreamManager {
605
690
  this.updateSession(sessionId, {
606
691
  status: "ready",
607
692
  abortController: null,
693
+ finishedReason: null,
608
694
  }, true); // Immediate for status change
609
- try {
610
- this.latestOnFinish.get(sessionId)?.((this.state.sessions.get(sessionId)?.messages || []));
611
- }
612
- catch {
613
- console.error("[SM] Failed to call onFinish handler on completion");
614
- }
695
+ this.deliverOrQueueFinish(sessionId, { finishedReason: null }, "completion");
615
696
  }
616
697
  }
617
698
  catch (error) {
@@ -640,13 +721,7 @@ class StreamManager {
640
721
  error: err,
641
722
  abortController: null,
642
723
  }, true); // Immediate for error status
643
- // セッションに登録された最新の onError を使用
644
- try {
645
- this.latestOnError.get(sessionId)?.(err);
646
- }
647
- catch {
648
- console.error("[SM] Failed to call onError handler");
649
- }
724
+ this.deliverOrQueueError(sessionId, err);
650
725
  }
651
726
  }
652
727
  }
@@ -709,6 +784,8 @@ class StreamManager {
709
784
  this.latestOnFinish.delete(id);
710
785
  this.latestOnError.delete(id);
711
786
  this.streamIds.delete(id);
787
+ this.pendingOnFinish.delete(id);
788
+ this.pendingOnError.delete(id);
712
789
  removed = true;
713
790
  if (this.debug) {
714
791
  this.logSessionInfo(`Session removed by TTL GC: ${id}`);
@@ -754,6 +831,8 @@ class StreamManager {
754
831
  this.latestOnFinish.clear();
755
832
  this.latestOnError.clear();
756
833
  this.streamIds.clear();
834
+ this.pendingOnFinish.clear();
835
+ this.pendingOnError.clear();
757
836
  }
758
837
  }
759
838
  // Export the StreamManager class for custom initialization
@@ -1,3 +1,4 @@
1
+ import { ChatFinishReason } from "../server/types.js";
1
2
  import type { Message, JSONValue } from "../shared/index.js";
2
3
  export type ChatStatus = "ready" | "submitted" | "streaming" | "error" | "aborted";
3
4
  export type ChatSession = {
@@ -8,6 +9,10 @@ export type ChatSession = {
8
9
  * Newer items append to the end.
9
10
  */
10
11
  metadata: Array<Record<string, JSONValue>>;
12
+ /**
13
+ * Streamed completion reason reported by the server once the session finishes.
14
+ */
15
+ finishedReason: ChatFinishReason | null;
11
16
  /**
12
17
  * messages の内容が更新されるたびにインクリメントされるバージョン番号。
13
18
  * - ストリーミング中は配列参照を再生成しない最適化を行っているため、
@@ -21,7 +26,10 @@ export type ChatSession = {
21
26
  lastAccessed: number;
22
27
  };
23
28
  export type OnChatErrorCallback = (error: Error) => void;
24
- export type OnChatFinishCallback = (messages: Message[]) => void;
29
+ export type OnChatFinishDetails = {
30
+ finishedReason: ChatFinishReason;
31
+ };
32
+ export type OnChatFinishCallback = (messages: Message[], details: OnChatFinishDetails) => void;
25
33
  export type UseChatSessionOptions = {
26
34
  api: string;
27
35
  initialMessages?: Message[];
@@ -36,6 +44,7 @@ export type UseChatSessionOptions = {
36
44
  * チャット完了時のコールバック
37
45
  * memo化された関数を渡すこと
38
46
  * @param messages 完了時のメッセージ一覧
47
+ * @param details 完了時の追加情報(finishReason 等)
39
48
  * @returns
40
49
  */
41
50
  onFinish?: OnChatFinishCallback;
@@ -50,6 +59,10 @@ export type UseChatSessionReturn = {
50
59
  * Latest list of metadata payloads received during streaming.
51
60
  */
52
61
  metadata: Array<Record<string, JSONValue>>;
62
+ /**
63
+ * 最後に受け取った finish_reason(完了時のみ定義される)。
64
+ */
65
+ finishedReason: ChatFinishReason;
53
66
  /**
54
67
  * messages の内容更新を検知するためのバージョン番号。
55
68
  * useMemo の依存などに利用できる。
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,WAAW,GACX,WAAW,GACX,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3C;;;;;OAKG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAEjE,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,EAAE;IACpC,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC3B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3C;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB;;;OAGG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAC3C,WAAW,EAAE,CACX,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,kBAAkB,CAAA;KAAE,KACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,MAAM,IAAI,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACpC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,WAAW,GACX,WAAW,GACX,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3C;;OAEG;IACH,cAAc,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC;;;;;OAKG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAEzD,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,gBAAgB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CACjC,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,mBAAmB,KACzB,IAAI,CAAC;AAEV,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,EAAE;IACpC,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC3B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3C;;OAEG;IACH,cAAc,EAAE,gBAAgB,CAAC;IACjC;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB;;;OAGG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAC3C,WAAW,EAAE,CACX,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,kBAAkB,CAAA;KAAE,KACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,MAAM,IAAI,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACpC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useChatSession.d.ts","sourceRoot":"","sources":["../../src/client/useChatSession.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CA8ItB"}
1
+ {"version":3,"file":"useChatSession.d.ts","sourceRoot":"","sources":["../../src/client/useChatSession.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAgJtB"}
@@ -51,6 +51,7 @@ export function useChatSession(sessionId, options) {
51
51
  id: sessionId,
52
52
  messages: initialMessages,
53
53
  metadata: [],
54
+ finishedReason: null,
54
55
  messagesVersion: 0,
55
56
  status: "ready",
56
57
  error: null,
@@ -98,6 +99,7 @@ export function useChatSession(sessionId, options) {
98
99
  return {
99
100
  messages: session.messages,
100
101
  metadata: session.metadata ?? [],
102
+ finishedReason: session.finishedReason ?? null,
101
103
  messagesVersion: session.messagesVersion ?? 0,
102
104
  status: session.status,
103
105
  error: session.error,
@@ -1 +1 @@
1
- {"version":3,"file":"createChatHandler.d.ts","sourceRoot":"","sources":["../../src/server/createChatHandler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EAGb,iBAAiB,EAGlB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,iBAAiB,CAob3E"}
1
+ {"version":3,"file":"createChatHandler.d.ts","sourceRoot":"","sources":["../../src/server/createChatHandler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EAGb,iBAAiB,EAIlB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,iBAAiB,CA8b3E"}
@@ -1,4 +1,5 @@
1
1
  import { isAbortError } from "../shared/error-utils.js";
2
+ import { normalizeFinishReason } from "./server-utils.js";
2
3
  // Implemented for usage inside Hono's `streamText()` callback.
3
4
  export function createChatHandler(options) {
4
5
  const { providers, transforms = [], throttle, onFinish, onError, messages, timeoutMs = 60000, temperature, maxOutputTokens, debug = false, } = options;
@@ -36,6 +37,7 @@ export function createChatHandler(options) {
36
37
  let abortNotified = false; // onError('aborted') の多重呼び出し防止
37
38
  let currentModel = "";
38
39
  let currentProvider = "openai";
40
+ let overallFinishReason = null;
39
41
  // Content send control for throttling
40
42
  let lastContentSendTime = 0;
41
43
  // Tracks the accText length at last send. Used to compute delta size when sending chunks.
@@ -168,6 +170,7 @@ export function createChatHandler(options) {
168
170
  // Local attempt state
169
171
  let localAccText = "";
170
172
  let localUsage;
173
+ let lastFinishReason = null;
171
174
  lastContentSendTime = 0;
172
175
  lastContentSendLength = 0;
173
176
  // geminiでは"none"を指定することでreasoning_effortを無効化できる
@@ -202,6 +205,9 @@ export function createChatHandler(options) {
202
205
  break;
203
206
  const delta = chunk.choices[0]?.delta;
204
207
  const finishReason = chunk.choices[0]?.finish_reason;
208
+ if (typeof finishReason === "string") {
209
+ lastFinishReason = normalizeFinishReason(finishReason);
210
+ }
205
211
  if (chunk.usage) {
206
212
  localUsage = {
207
213
  prompt_tokens: chunk.usage.prompt_tokens,
@@ -275,6 +281,7 @@ export function createChatHandler(options) {
275
281
  }
276
282
  }
277
283
  if (!isAborted) {
284
+ overallFinishReason = lastFinishReason;
278
285
  // Send final content if there are unsent updates
279
286
  if (localAccText.length > lastContentSendLength) {
280
287
  const deltaToSend = localAccText.slice(lastContentSendLength);
@@ -289,7 +296,10 @@ export function createChatHandler(options) {
289
296
  }
290
297
  // If any metadata remain, flush them as a final meta-only chunk
291
298
  await flushMetaOnly();
292
- await sendEvent("done", null);
299
+ const donePayload = {
300
+ finished_reason: overallFinishReason,
301
+ };
302
+ await sendEvent("done", donePayload);
293
303
  }
294
304
  // 正常終了時もタイマーはクリア(次のattemptへは到達しない)
295
305
  clearTimeoutSafe();
@@ -298,6 +308,7 @@ export function createChatHandler(options) {
298
308
  model: currentModel,
299
309
  provider: currentProvider,
300
310
  text: localAccText,
311
+ finishReason: overallFinishReason,
301
312
  usage: localUsage,
302
313
  durationMs: Date.now() - startTime,
303
314
  };
@@ -0,0 +1,6 @@
1
+ import type { ChatCompletionChunk } from "openai/resources/index";
2
+ import type { ChatFinishReason } from "./types";
3
+ type OpenaiFinishReason = ChatCompletionChunk["choices"][0]["finish_reason"];
4
+ export declare function normalizeFinishReason(openaiFinishReason: OpenaiFinishReason): ChatFinishReason | null;
5
+ export {};
6
+ //# sourceMappingURL=server-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-utils.d.ts","sourceRoot":"","sources":["../../src/server/server-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,KAAK,kBAAkB,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;AAE7E,wBAAgB,qBAAqB,CACnC,kBAAkB,EAAE,kBAAkB,GACrC,gBAAgB,GAAG,IAAI,CASzB"}
@@ -0,0 +1,8 @@
1
+ export function normalizeFinishReason(openaiFinishReason) {
2
+ if (openaiFinishReason === "content_filter" ||
3
+ openaiFinishReason === "length" ||
4
+ openaiFinishReason === "stop") {
5
+ return openaiFinishReason;
6
+ }
7
+ return null;
8
+ }
@@ -3,6 +3,7 @@ import type { JSONValue, Message } from "../shared/index.js";
3
3
  import type { StreamingApi } from "hono/utils/stream.js";
4
4
  export type HonoStreamType = StreamingApi;
5
5
  export type AIProvider = "openai" | "gemini";
6
+ export type ChatFinishReason = null | "length" | "stop" | "content_filter";
6
7
  export type AIProviderConfig = {
7
8
  openai: OpenAI;
8
9
  provider: AIProvider;
@@ -13,6 +14,7 @@ export type FinishInfo = {
13
14
  model: string;
14
15
  provider: AIProvider;
15
16
  text: string;
17
+ finishReason: ChatFinishReason;
16
18
  usage?: {
17
19
  prompt_tokens?: number;
18
20
  completion_tokens?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC;AAE1C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE7C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QACN,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;KACjC,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAC5B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,sBAAsB,KACxB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9B,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE;IACP,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,KACE,MAAM,CAAC;AAEZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACjD,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,gBAAgB,GAAG,CAAC,CAAC,aAAa,EAAE,MAAM,KAAK,gBAAgB,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,9 @@ export type SSEErrorData = {
15
15
  message: string;
16
16
  code?: string;
17
17
  };
18
- export type SSEDoneData = null;
18
+ export type SSEDoneData = {
19
+ finished_reason: string | null;
20
+ };
19
21
  export type SSEEvent = {
20
22
  event: "chunk";
21
23
  data: SSEChunkData;
@@ -1 +1 @@
1
- {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../src/shared/wire.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,MAAM,YAAY,GACpB,OAAO,GACP,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC;AAE/B,MAAM,MAAM,QAAQ,GAChB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GACtC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GACtC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../src/shared/wire.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,MAAM,YAAY,GACpB,OAAO,GACP,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAChB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GACtC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GACtC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-ai-sdk",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "private": false,
5
5
  "description": "Simple AI SDK for Hono / React19+ / OpenAI",
6
6
  "type": "module",