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.
- package/dist/client/manager.d.ts +4 -4
- package/dist/client/manager.d.ts.map +1 -1
- package/dist/client/manager.js +20 -55
- package/dist/client/types.d.ts +3 -2
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/useChatSession.d.ts.map +1 -1
- package/dist/client/useChatSession.js +31 -4
- package/dist/shared/error-utils.d.ts +5 -0
- package/dist/shared/error-utils.d.ts.map +1 -1
- package/dist/spec.md +8 -6
- package/package.json +1 -1
package/dist/client/manager.d.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
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":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,oBAAoB,EAEpB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAEV,OAAO,EACP,SAAS,EAEV,MAAM,oBAAoB,CAAC;AAK5B,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAAC;IACvD,WAAW,IAAI,kBAAkB,CAAC;IAClC;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IACvD,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAClE;;;;OAIG;IACH,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,oBAAoB,GAAG,SAAS,GACxC,IAAI,CAAC;IACR;;OAEG;IACH,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,GAC5C,IAAI,CAAC;IACR;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;OAGG;IACH,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/client/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/client/manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { generateMessageId } from "../shared/generate-id.js";
|
|
2
|
-
import { isAbortError
|
|
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
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
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
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
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,
|
|
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);
|
package/dist/client/types.d.ts
CHANGED
|
@@ -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: (
|
|
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":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE9E,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,eAAe,CAAC,CAAC;IACjC;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;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;IACjC;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC,eAAe,CAAC,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;CAMjC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE3D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,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,eAAe,CAAC,CAAC;IACjC;;;OAGG;IACH,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;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,
|
|
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":"
|
|
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((
|
|
109
|
-
manager.setMessages(sessionId,
|
|
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
|
|
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: (
|
|
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`
|
|
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
|
-
|
|
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
|
|