simple-ai-sdk 1.0.19 → 1.0.21
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,
|
|
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
|
// これによりストリーミングはバックグラウンドで継続される
|
package/dist/client/manager.d.ts
CHANGED
|
@@ -72,6 +72,8 @@ 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;
|
|
@@ -81,6 +83,9 @@ declare class StreamManager implements IStreamManager {
|
|
|
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":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI7D,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,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,GACnD,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,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC1D,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;KAClC,GACA,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,cAAM,aAAc,YAAW,cAAc;IAC3C,OAAO,CAAC,KAAK,CAEX;IAEF,OAAO,CAAC,SAAS,CAAoC;IAGrD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,gBAAgB,CAA8C;IAEtE,OAAO,CAAC,MAAM;IAsBd,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,UAAU,CAA+C;IAEjE,OAAO,CAAC,iBAAiB,CAA6B;IAEtD,OAAO,CAAC,cAAc,CAAoD;IAE1E,OAAO,CAAC,aAAa,CAA6C;
|
|
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
|
@@ -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);
|
|
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,53 @@ 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, 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);
|
|
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, finalMessages);
|
|
241
|
+
}
|
|
242
|
+
this.pendingOnError.delete(sessionId);
|
|
243
|
+
}
|
|
244
|
+
deliverOrQueueError(sessionId, error) {
|
|
245
|
+
// エラー版:ハンドラが無いときは保留し、マウント時に即発火させる
|
|
246
|
+
const handler = this.latestOnError.get(sessionId);
|
|
247
|
+
this.pendingOnFinish.delete(sessionId);
|
|
248
|
+
if (handler) {
|
|
249
|
+
this.pendingOnError.delete(sessionId);
|
|
250
|
+
try {
|
|
251
|
+
handler(error);
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
console.error("[SM] Failed to call onError handler");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.pendingOnError.set(sessionId, error);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
187
261
|
initSession(sessionId, initialMessages = []) {
|
|
188
262
|
const existingSession = this.state.sessions.get(sessionId);
|
|
189
263
|
// streaming中のセッションが存在する場合は、initialMessagesで上書きしない
|
|
@@ -210,6 +284,8 @@ class StreamManager {
|
|
|
210
284
|
return;
|
|
211
285
|
}
|
|
212
286
|
}
|
|
287
|
+
this.pendingOnFinish.delete(sessionId);
|
|
288
|
+
this.pendingOnError.delete(sessionId);
|
|
213
289
|
this.state.sessions.set(sessionId, {
|
|
214
290
|
id: sessionId,
|
|
215
291
|
messages: initialMessages,
|
|
@@ -293,6 +369,8 @@ class StreamManager {
|
|
|
293
369
|
this.latestOnError.delete(oldestSessionId);
|
|
294
370
|
// 意図: streamId も破棄してメモリリーク・誤判定を防止
|
|
295
371
|
this.streamIds.delete(oldestSessionId);
|
|
372
|
+
this.pendingOnFinish.delete(oldestSessionId);
|
|
373
|
+
this.pendingOnError.delete(oldestSessionId);
|
|
296
374
|
if (this.debug) {
|
|
297
375
|
this.logSessionInfo(`Session removed: ${oldestSessionId} (LRU eviction)`);
|
|
298
376
|
}
|
|
@@ -361,6 +439,10 @@ class StreamManager {
|
|
|
361
439
|
console.warn(`[SM] streamChat called for non-existing session: ${sessionId}`);
|
|
362
440
|
return;
|
|
363
441
|
}
|
|
442
|
+
// 新しいストリーム開始時は保留中のライフサイクル通知を破棄する
|
|
443
|
+
// (最新ストリームで再計算されるため、古い結果は破棄してよい)
|
|
444
|
+
this.pendingOnFinish.delete(sessionId);
|
|
445
|
+
this.pendingOnError.delete(sessionId);
|
|
364
446
|
// 既存のストリームがあれば中断してから新規ストリームを開始する
|
|
365
447
|
// (同一セッションでの重複ストリーミングを防止)
|
|
366
448
|
if (session.abortController) {
|
|
@@ -413,13 +495,7 @@ class StreamManager {
|
|
|
413
495
|
error: err,
|
|
414
496
|
abortController: null,
|
|
415
497
|
}, true);
|
|
416
|
-
|
|
417
|
-
try {
|
|
418
|
-
this.latestOnError.get(sessionId)?.(err);
|
|
419
|
-
}
|
|
420
|
-
catch {
|
|
421
|
-
console.error("[SM] Failed to call onError handler");
|
|
422
|
-
}
|
|
498
|
+
this.deliverOrQueueError(sessionId, err);
|
|
423
499
|
return;
|
|
424
500
|
}
|
|
425
501
|
const reader = response.body?.getReader();
|
|
@@ -517,12 +593,7 @@ class StreamManager {
|
|
|
517
593
|
error: err,
|
|
518
594
|
abortController: null,
|
|
519
595
|
}, true);
|
|
520
|
-
|
|
521
|
-
this.latestOnError.get(sessionId)?.(err);
|
|
522
|
-
}
|
|
523
|
-
catch {
|
|
524
|
-
console.error("[SM] Failed to call onError handler");
|
|
525
|
-
}
|
|
596
|
+
this.deliverOrQueueError(sessionId, err);
|
|
526
597
|
failed = true;
|
|
527
598
|
shouldTerminate = true;
|
|
528
599
|
break;
|
|
@@ -535,13 +606,7 @@ class StreamManager {
|
|
|
535
606
|
status: "ready",
|
|
536
607
|
abortController: null,
|
|
537
608
|
}, true);
|
|
538
|
-
|
|
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
|
-
}
|
|
609
|
+
this.deliverOrQueueFinish(sessionId);
|
|
545
610
|
shouldTerminate = true;
|
|
546
611
|
break;
|
|
547
612
|
}
|
|
@@ -606,12 +671,7 @@ class StreamManager {
|
|
|
606
671
|
status: "ready",
|
|
607
672
|
abortController: null,
|
|
608
673
|
}, true); // Immediate for status change
|
|
609
|
-
|
|
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
|
-
}
|
|
674
|
+
this.deliverOrQueueFinish(sessionId, "completion");
|
|
615
675
|
}
|
|
616
676
|
}
|
|
617
677
|
catch (error) {
|
|
@@ -640,13 +700,7 @@ class StreamManager {
|
|
|
640
700
|
error: err,
|
|
641
701
|
abortController: null,
|
|
642
702
|
}, true); // Immediate for error status
|
|
643
|
-
|
|
644
|
-
try {
|
|
645
|
-
this.latestOnError.get(sessionId)?.(err);
|
|
646
|
-
}
|
|
647
|
-
catch {
|
|
648
|
-
console.error("[SM] Failed to call onError handler");
|
|
649
|
-
}
|
|
703
|
+
this.deliverOrQueueError(sessionId, err);
|
|
650
704
|
}
|
|
651
705
|
}
|
|
652
706
|
}
|
|
@@ -709,6 +763,8 @@ class StreamManager {
|
|
|
709
763
|
this.latestOnFinish.delete(id);
|
|
710
764
|
this.latestOnError.delete(id);
|
|
711
765
|
this.streamIds.delete(id);
|
|
766
|
+
this.pendingOnFinish.delete(id);
|
|
767
|
+
this.pendingOnError.delete(id);
|
|
712
768
|
removed = true;
|
|
713
769
|
if (this.debug) {
|
|
714
770
|
this.logSessionInfo(`Session removed by TTL GC: ${id}`);
|
|
@@ -754,6 +810,8 @@ class StreamManager {
|
|
|
754
810
|
this.latestOnFinish.clear();
|
|
755
811
|
this.latestOnError.clear();
|
|
756
812
|
this.streamIds.clear();
|
|
813
|
+
this.pendingOnFinish.clear();
|
|
814
|
+
this.pendingOnError.clear();
|
|
757
815
|
}
|
|
758
816
|
}
|
|
759
817
|
// Export the StreamManager class for custom initialization
|