simple-ai-sdk 1.1.1 → 1.1.4

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,4 +1,4 @@
1
- import type { ChatSession, OnChatFinishCallback, SetMessagesOptions, StreamManagerListener, StreamManagerState } from "./types.js";
1
+ import type { ChatSession, OnChatFinishCallback, SetMessagesOptions, SetMessagesUpdater, 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;
@@ -33,10 +33,10 @@ export interface IStreamManager {
33
33
  */
34
34
  touchSession(sessionId: string): void;
35
35
  /**
36
- * API 呼び出しを行わず、指定セッションの messages を上書きする。
36
+ * API 呼び出しを行わず、指定セッションの messages を更新する。
37
37
  * - messagesVersion は内部でインクリメントされる。
38
38
  */
39
- setMessages(sessionId: string, messages: Message[], options?: SetMessagesOptions): void;
39
+ setMessages(sessionId: string, updater: SetMessagesUpdater, options?: SetMessagesOptions): void;
40
40
  streamChat(sessionId: string, messages: Message[], options: {
41
41
  api: string;
42
42
  body?: Record<string, JSONValue>;
@@ -117,7 +117,7 @@ declare class StreamManager implements IStreamManager {
117
117
  api: string;
118
118
  body?: Record<string, JSONValue>;
119
119
  }): Promise<void>;
120
- setMessages(sessionId: string, messages: Message[], options?: SetMessagesOptions): void;
120
+ setMessages(sessionId: string, updater: SetMessagesUpdater, options?: SetMessagesOptions): void;
121
121
  stopStream(sessionId: string): void;
122
122
  stopAllStreams(): void;
123
123
  /**
@@ -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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"}
@@ -1,5 +1,5 @@
1
1
  import { generateMessageId } from "../shared/generate-id.js";
2
- import { isAbortError, ChatError } from "../shared/error-utils.js";
2
+ import { isAbortError } from "../shared/error-utils.js";
3
3
  class StreamManager {
4
4
  state = {
5
5
  sessions: new Map(),
@@ -629,29 +629,15 @@ class StreamManager {
629
629
  let finishedReason = null;
630
630
  if (isDonePayload(parsed))
631
631
  finishedReason = toChatFinishReason(parsed.finished_reason);
632
- if (finishedReason === "content_filter") {
633
- // content_filter は完了ではなく既知エラーとして扱う
634
- const err = new ChatError("content_filter");
635
- this.updateSession(sessionId, {
636
- status: "error",
637
- error: err,
638
- abortController: null,
639
- finishedReason,
640
- nextAssistantMessageId: null,
641
- }, true);
642
- this.deliverOrQueueError(sessionId, err);
643
- }
644
- else {
645
- this.updateSession(sessionId, {
646
- status: "ready",
647
- abortController: null,
648
- finishedReason,
649
- nextAssistantMessageId: null,
650
- }, true);
651
- this.deliverOrQueueFinish(sessionId, {
652
- finishedReason,
653
- });
654
- }
632
+ this.updateSession(sessionId, {
633
+ status: "ready",
634
+ abortController: null,
635
+ finishedReason,
636
+ nextAssistantMessageId: null,
637
+ }, true);
638
+ this.deliverOrQueueFinish(sessionId, {
639
+ finishedReason,
640
+ });
655
641
  shouldTerminate = true;
656
642
  break;
657
643
  }
@@ -712,31 +698,13 @@ class StreamManager {
712
698
  // 意図: 正常完了(サーバが done を送らないケース)だけをここで処理。
713
699
  // failed=true(error)の場合は既に状態更新済みなので何もしない。
714
700
  if (!failed && !shouldTerminate) {
715
- const s = this.state.sessions.get(sessionId);
716
- const lastMsg = s?.messages.at(-1);
717
- const hasAssistantContent = lastMsg !== undefined &&
718
- lastMsg.role === "assistant" &&
719
- lastMsg.content.length > 0;
720
- if (!hasAssistantContent) {
721
- const err = new ChatError("no_response");
722
- this.updateSession(sessionId, {
723
- status: "error",
724
- error: err,
725
- abortController: null,
726
- finishedReason: null,
727
- nextAssistantMessageId: null,
728
- }, true);
729
- this.deliverOrQueueError(sessionId, err);
730
- }
731
- else {
732
- this.updateSession(sessionId, {
733
- status: "ready",
734
- abortController: null,
735
- finishedReason: null,
736
- nextAssistantMessageId: null,
737
- }, true); // Immediate for status change
738
- this.deliverOrQueueFinish(sessionId, { finishedReason: null }, "completion");
739
- }
701
+ this.updateSession(sessionId, {
702
+ status: "ready",
703
+ abortController: null,
704
+ finishedReason: null,
705
+ nextAssistantMessageId: null,
706
+ }, true); // Immediate for status change
707
+ this.deliverOrQueueFinish(sessionId, { finishedReason: null }, "completion");
740
708
  }
741
709
  }
742
710
  catch (error) {
@@ -747,7 +715,6 @@ class StreamManager {
747
715
  if (s?.status !== "aborted") {
748
716
  this.updateSession(sessionId, {
749
717
  status: "aborted",
750
- error: new ChatError("aborted"),
751
718
  abortController: null,
752
719
  nextAssistantMessageId: null,
753
720
  }, true); // Immediate for status change
@@ -772,13 +739,12 @@ class StreamManager {
772
739
  }
773
740
  }
774
741
  }
775
- setMessages(sessionId, messages, options) {
742
+ setMessages(sessionId, updater, options) {
776
743
  const session = this.state.sessions.get(sessionId);
777
744
  if (!session) {
778
- // セッションが未初期化の場合は初期化してから適用
779
- this.initSession(sessionId, messages);
780
- return;
745
+ throw new Error(`Session not initialized: ${sessionId}`);
781
746
  }
747
+ const messages = updater(session.messages);
782
748
  const shouldReset = options?.resetStatus &&
783
749
  session.status !== "streaming" &&
784
750
  session.status !== "submitted";
@@ -801,7 +767,6 @@ class StreamManager {
801
767
  // ユーザーによる中断を明示的に示すため status を "aborted" に更新
802
768
  this.updateSession(sessionId, {
803
769
  status: "aborted",
804
- error: new ChatError("aborted"),
805
770
  abortController: null,
806
771
  nextAssistantMessageId: null,
807
772
  }, true);
@@ -76,6 +76,7 @@ export type SetMessagesOptions = {
76
76
  */
77
77
  resetStatus?: boolean;
78
78
  };
79
+ export type SetMessagesUpdater = (prev: Message[]) => Message[];
79
80
  export type ReloadMessage = (params?: {
80
81
  body?: SendMessageReqBody;
81
82
  }) => Promise<void>;
@@ -102,10 +103,10 @@ export type UseChatSessionReturn = {
102
103
  status: ChatStatus;
103
104
  error: Error | null;
104
105
  /**
105
- * API 呼び出しを行わず、現在のセッションの messages を即時上書きする。
106
+ * API 呼び出しを行わず、現在のセッションの messages を即時更新する。
106
107
  * - 内部的に messagesVersion がインクリメントされる。
107
108
  */
108
- setMessages: (messages: Message[], options?: SetMessagesOptions) => void;
109
+ setMessages: (updater: SetMessagesUpdater, options?: SetMessagesOptions) => void;
109
110
  sendMessage: (content: string, params?: SendMessageOptions) => Promise<void>;
110
111
  reload: ReloadMessage;
111
112
  stop: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useChatSession.d.ts","sourceRoot":"","sources":["../../src/client/useChatSession.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAIrB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAiKtB"}
1
+ {"version":3,"file":"useChatSession.d.ts","sourceRoot":"","sources":["../../src/client/useChatSession.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAKrB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAgMtB"}
@@ -1,4 +1,5 @@
1
- import { useEffect, useSyncExternalStore, useCallback, useRef } from "react";
1
+ import { useEffect, useSyncExternalStore, useCallback, useRef, useMemo, } from "react";
2
+ import { ChatError } from "../shared/index.js";
2
3
  import { useAIStreamManager } from "./context.js";
3
4
  import { generateMessageId } from "../shared/generate-id.js";
4
5
  export function useChatSession(sessionId, options) {
@@ -105,9 +106,35 @@ export function useChatSession(sessionId, options) {
105
106
  const stopAll = useCallback(() => {
106
107
  manager.stopAllStreams();
107
108
  }, [manager]);
108
- const setMessages = useCallback((messages, options) => {
109
- manager.setMessages(sessionId, messages, options);
109
+ const setMessages = useCallback((updater, options) => {
110
+ manager.setMessages(sessionId, updater, options);
110
111
  }, [manager, sessionId]);
112
+ const lastMessage = session.messages.at(-1);
113
+ const lastMessageRole = lastMessage?.role;
114
+ const isLastMessageEmpty = !lastMessage?.content;
115
+ const error = useMemo(() => {
116
+ if (session.finishedReason === "content_filter") {
117
+ return new ChatError("content_filter");
118
+ }
119
+ if (session.status === "aborted") {
120
+ return new ChatError("aborted");
121
+ }
122
+ // 何らかの理由で readyなのに assistant の応答がないまま止まっている
123
+ if (session.status === "ready") {
124
+ if (!lastMessageRole ||
125
+ lastMessageRole === "user" ||
126
+ isLastMessageEmpty) {
127
+ return new ChatError("no_response");
128
+ }
129
+ }
130
+ return session.error;
131
+ }, [
132
+ session.error,
133
+ session.finishedReason,
134
+ session.status,
135
+ lastMessageRole,
136
+ isLastMessageEmpty,
137
+ ]);
111
138
  return {
112
139
  messages: session.messages,
113
140
  metadata: session.metadata ?? [],
@@ -115,7 +142,7 @@ export function useChatSession(sessionId, options) {
115
142
  finishedReason: session.finishedReason ?? null,
116
143
  messagesVersion: session.messagesVersion ?? 0,
117
144
  status: session.status,
118
- error: session.error,
145
+ error,
119
146
  setMessages,
120
147
  sendMessage,
121
148
  reload,
@@ -1,4 +1,9 @@
1
1
  export declare function isAbortError(e: unknown): boolean;
2
+ /**
3
+ * - `content_filter`: The content was filtered by the content filter.
4
+ * - `aborted`: The request was aborted, likely by the user.
5
+ * - `no_response`: The model did not return a response. (not loading or streaming && last message is by the user)
6
+ */
2
7
  export type ChatErrorCode = "content_filter" | "aborted" | "no_response";
3
8
  export declare class ChatError extends Error {
4
9
  readonly code: ChatErrorCode;
@@ -1 +1 @@
1
- {"version":3,"file":"error-utils.d.ts","sourceRoot":"","sources":["../../src/shared/error-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAYhD;AAED,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzE,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;gBAEjB,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM;CAKlD"}
1
+ {"version":3,"file":"error-utils.d.ts","sourceRoot":"","sources":["../../src/shared/error-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAYhD;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzE,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;gBAEjB,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM;CAKlD"}
package/dist/spec.md CHANGED
@@ -402,10 +402,13 @@ type UseChatSessionReturn = {
402
402
  */
403
403
  error: Error | null
404
404
  /**
405
- * API を呼ばずに現在のセッションの messages を即時上書きする。
405
+ * API を呼ばずに現在のセッションの messages を即時更新する。
406
406
  * 内部的に messagesVersion がインクリメントされる。
407
407
  */
408
- setMessages: (messages: Message[], options?: { resetStatus?: boolean }) => void
408
+ setMessages: (
409
+ updater: (prev: Message[]) => Message[],
410
+ options?: { resetStatus?: boolean }
411
+ ) => void
409
412
  sendMessage: (content: string, params?: { body?: Record<string, JSONValue>; dropFromMessageId?: string }) => Promise<void>
410
413
  reload: (params?: { body?: Record<string, JSONValue> }) => Promise<void>
411
414
  stop: () => void
@@ -438,9 +441,10 @@ await Promise.all([
438
441
  - `reload` は **最後の user 以降** を削除して再送します(再試行・プロンプト修正に有用)。
439
442
  - `stop` は現在のストリームを中断します。
440
443
  - `stopAll` はアクティブな全ストリーム(submitted/streaming 状態)を中断します。ページ離脱やグローバルなキャンセルボタンで利用できます。
441
- - `setMessages` は **API 呼び出しを行わず**、現在のセッションの `messages` を即時上書きします。UI に即時反映され、内部で `messagesVersion` がインクリメントされます。
444
+ - `setMessages` は **API 呼び出しを行わず**、現在のセッションの `messages` を即時更新します。`updater(prev)` は常にその時点の最新 `messages` を受け取り、戻り値が同一参照でも `messagesVersion` はインクリメントされます。UI に即時反映されます。
442
445
  - 通常は `status` を変更しません(例: ローカルでの編集や一時的な整形結果の反映に使用)。
443
446
  - `options.resetStatus` を指定すると `status/error/finishedReason/nextAssistantMessageId` を初期化します(`submitted/streaming` 中は無視)。
447
+ - 未初期化のセッションに対して呼ぶと `Error("Session not initialized: <sessionId>")` を投げます。自動初期化は行いません。
444
448
  - **SPA 内のページ遷移ではストリーム継続**。Provider 配下から外れても、再マウント時に最新スナップショットを購読し直します。
445
449
  - **セッション数制限**: メモリ使用量を抑えるため、最大セッション数を制限(デフォルト: 5)。上限に達すると LRU 方式で最も古いセッションを自動削除。ストリーミング中のセッションは削除対象から優先的に除外。
446
450
  - **メモ化のコツ**: ストリーミング中は各チャンクで `messages` 参照が更新されるため、`useMemo(..., [messages])` で確実に再評価されます。より厳密な制御が必要な場合は `messagesVersion` を依存に加えることもできます。
@@ -454,9 +458,7 @@ await Promise.all([
454
458
  - `onFinish` の `details.metadata` は、そのストリーム中に受信したメタデータの最新スナップショットです。
455
459
  - 複数購読時の優先: 同一 `sessionId` を複数コンポーネントが使用する場合、最後に登録された `onFinish` が有効です。
456
460
  - `onError` は per-call: `sendMessage`/`reload` 呼び出し時に渡されたハンドラが呼ばれます(最新保持は行いません)。
457
- - `content_filter` は完了ではなくエラー扱い: `status: "error"` になり、`onFinish` ではなく `onError` が呼ばれます(`error.code === "content_filter"`)。
458
- - ユーザー中断は既知エラー扱い: `stop()` または AbortError 由来の中断時は `status: "aborted"` かつ `error.code === "aborted"` になります。
459
- - サーバが `done` を送らずに終了し assistant 応答が空の場合は `status: "error"` になり、`onError` が呼ばれます(`error.code === "no_response"`)。
461
+
460
462
 
461
463
  ### ページ遷移前のセッション事前準備(`usePrefetchChatSession`)
462
464
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-ai-sdk",
3
- "version": "1.1.1",
3
+ "version": "1.1.4",
4
4
  "private": false,
5
5
  "description": "Simple AI SDK for Hono / React19+ / OpenAI",
6
6
  "type": "module",