@anuma/sdk 10.5.3 → 10.6.0
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/expo/index.cjs +42 -15
- package/dist/expo/index.d.mts +2 -0
- package/dist/expo/index.d.ts +2 -0
- package/dist/expo/index.mjs +41 -15
- package/dist/react/index.cjs +184 -27
- package/dist/react/index.d.mts +24 -5
- package/dist/react/index.d.ts +24 -5
- package/dist/react/index.mjs +183 -27
- package/dist/server/index.cjs +30 -12
- package/dist/server/index.d.mts +2 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.mjs +29 -12
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -6818,6 +6818,7 @@ function count(value) {
|
|
|
6818
6818
|
|
|
6819
6819
|
// src/lib/chat/resumeStream.ts
|
|
6820
6820
|
init_clientConfig();
|
|
6821
|
+
init_redactor();
|
|
6821
6822
|
|
|
6822
6823
|
// src/lib/chat/toolLoop.ts
|
|
6823
6824
|
init_clientConfig();
|
|
@@ -11164,16 +11165,34 @@ async function resumeStream(options) {
|
|
|
11164
11165
|
onData,
|
|
11165
11166
|
onThinking,
|
|
11166
11167
|
onFinish,
|
|
11167
|
-
onError
|
|
11168
|
+
onError,
|
|
11169
|
+
piiRedactor
|
|
11168
11170
|
} = options;
|
|
11169
11171
|
const strategy = getStrategy(handle.apiType);
|
|
11170
11172
|
const accumulator = createStreamAccumulator(handle.model || void 0);
|
|
11173
|
+
const contentDeAnon = piiRedactor && onData ? createStreamingDeAnonymizer(piiRedactor, onData) : null;
|
|
11174
|
+
const thinkingDeAnon = piiRedactor && onThinking ? createStreamingDeAnonymizer(piiRedactor, onThinking) : null;
|
|
11171
11175
|
const contentSmoother = new StreamSmoother((text16) => {
|
|
11172
|
-
if (
|
|
11176
|
+
if (contentDeAnon) contentDeAnon.push(text16);
|
|
11177
|
+
else if (onData) onData(text16);
|
|
11173
11178
|
}, smoothing);
|
|
11174
11179
|
const thinkingSmoother = new StreamSmoother((text16) => {
|
|
11175
|
-
if (
|
|
11180
|
+
if (thinkingDeAnon) thinkingDeAnon.push(text16);
|
|
11181
|
+
else if (onThinking) onThinking(text16);
|
|
11176
11182
|
}, smoothing);
|
|
11183
|
+
const flushOutput = () => {
|
|
11184
|
+
contentSmoother.flush();
|
|
11185
|
+
thinkingSmoother.flush();
|
|
11186
|
+
contentDeAnon?.flush();
|
|
11187
|
+
thinkingDeAnon?.flush();
|
|
11188
|
+
};
|
|
11189
|
+
const buildFinal = () => strategy.buildFinalResponse(
|
|
11190
|
+
piiRedactor ? {
|
|
11191
|
+
...accumulator,
|
|
11192
|
+
content: piiRedactor.deAnonymize(accumulator.content),
|
|
11193
|
+
thinking: piiRedactor.deAnonymize(accumulator.thinking)
|
|
11194
|
+
} : accumulator
|
|
11195
|
+
);
|
|
11177
11196
|
const idleController = new AbortController();
|
|
11178
11197
|
let watchdog;
|
|
11179
11198
|
let idleFired = false;
|
|
@@ -11218,9 +11237,8 @@ async function resumeStream(options) {
|
|
|
11218
11237
|
if (signal) signal.removeEventListener("abort", onCallerAbort);
|
|
11219
11238
|
};
|
|
11220
11239
|
const buildInterrupted = (message) => {
|
|
11221
|
-
|
|
11222
|
-
|
|
11223
|
-
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(strategy.buildFinalResponse(accumulator)) : strategy.buildFinalResponse(accumulator);
|
|
11240
|
+
flushOutput();
|
|
11241
|
+
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(buildFinal()) : buildFinal();
|
|
11224
11242
|
return { data, error: message, interrupted: true };
|
|
11225
11243
|
};
|
|
11226
11244
|
if (combinedSignal.aborted) {
|
|
@@ -11268,18 +11286,16 @@ async function resumeStream(options) {
|
|
|
11268
11286
|
const err = replayErr instanceof Error ? replayErr : new Error(String(replayErr));
|
|
11269
11287
|
const statusCode = parseSseStatusCode(err);
|
|
11270
11288
|
if (statusCode === 410) {
|
|
11271
|
-
|
|
11272
|
-
thinkingSmoother.flush();
|
|
11289
|
+
flushOutput();
|
|
11273
11290
|
throw new StreamExpiredError(handle.inferenceId);
|
|
11274
11291
|
}
|
|
11275
11292
|
if (err.name === "AbortError" || combinedSignal.aborted) {
|
|
11276
11293
|
return buildInterrupted(abortMessage());
|
|
11277
11294
|
}
|
|
11278
|
-
|
|
11279
|
-
thinkingSmoother.flush();
|
|
11295
|
+
flushOutput();
|
|
11280
11296
|
if (onError) onError(err);
|
|
11281
11297
|
return {
|
|
11282
|
-
data:
|
|
11298
|
+
data: buildFinal(),
|
|
11283
11299
|
error: err.message,
|
|
11284
11300
|
interrupted: false,
|
|
11285
11301
|
statusCode
|
|
@@ -11295,7 +11311,9 @@ async function resumeStream(options) {
|
|
|
11295
11311
|
draining = true;
|
|
11296
11312
|
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
11297
11313
|
if (playbackAborted) return buildInterrupted(abortMessage());
|
|
11298
|
-
|
|
11314
|
+
contentDeAnon?.flush();
|
|
11315
|
+
thinkingDeAnon?.flush();
|
|
11316
|
+
const response = buildFinal();
|
|
11299
11317
|
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
11300
11318
|
if (onFinish && deliveredOutput) onFinish(response);
|
|
11301
11319
|
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|
|
@@ -12448,7 +12466,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
12448
12466
|
...item,
|
|
12449
12467
|
memory: {
|
|
12450
12468
|
...item.memory,
|
|
12451
|
-
content: await decrypt(item.memory.content),
|
|
12469
|
+
content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
|
|
12452
12470
|
...item.memory.kind_value !== void 0 && {
|
|
12453
12471
|
kind_value: await decrypt(item.memory.kind_value)
|
|
12454
12472
|
}
|
|
@@ -12542,7 +12560,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
12542
12560
|
}
|
|
12543
12561
|
if (existing && existing.version !== expectedVersion) throw conflict();
|
|
12544
12562
|
const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
|
|
12545
|
-
const
|
|
12563
|
+
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
12564
|
+
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
12546
12565
|
const kindValue = memory.kind_value === void 0 ? void 0 : (snapshot?.kindValue ?? decoded?.memory.kind_value) === memory.kind_value ? snapshot?.encryptedKindValue ?? existing.memory.kind_value : await encryptField2(memory.kind_value);
|
|
12547
12566
|
return {
|
|
12548
12567
|
body: {
|
|
@@ -25859,6 +25878,13 @@ var METADATA_FIELDS = [
|
|
|
25859
25878
|
"published_at",
|
|
25860
25879
|
"geohash"
|
|
25861
25880
|
];
|
|
25881
|
+
var TOMBSTONE_FIELDS = [
|
|
25882
|
+
"scope",
|
|
25883
|
+
"is_deleted",
|
|
25884
|
+
"embedding_model",
|
|
25885
|
+
"topics_updated_at",
|
|
25886
|
+
"last_observed_at"
|
|
25887
|
+
];
|
|
25862
25888
|
function text15(value) {
|
|
25863
25889
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
25864
25890
|
}
|
|
@@ -26006,7 +26032,8 @@ async function embedMissing(prepared, options, model, signal) {
|
|
|
26006
26032
|
}
|
|
26007
26033
|
function sameMetadata2(local, remote, model) {
|
|
26008
26034
|
const mine = metadata2(local, model);
|
|
26009
|
-
|
|
26035
|
+
const fields = bool(local.is_deleted) ? TOMBSTONE_FIELDS : METADATA_FIELDS;
|
|
26036
|
+
return fields.every((field10) => {
|
|
26010
26037
|
const a = mine[field10] ?? null;
|
|
26011
26038
|
const b = remote[field10] ?? null;
|
|
26012
26039
|
if (field10 === "embedding_model" && a === null) return true;
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -2753,6 +2753,8 @@ interface ResumeStreamOptions {
|
|
|
2753
2753
|
onData?: (chunk: string) => void;
|
|
2754
2754
|
/** Thinking/reasoning deltas as they replay. */
|
|
2755
2755
|
onThinking?: (chunk: string) => void;
|
|
2756
|
+
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
2757
|
+
piiRedactor?: PiiRedactor;
|
|
2756
2758
|
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
2757
2759
|
onFinish?: (response: ApiResponse) => void;
|
|
2758
2760
|
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -2753,6 +2753,8 @@ interface ResumeStreamOptions {
|
|
|
2753
2753
|
onData?: (chunk: string) => void;
|
|
2754
2754
|
/** Thinking/reasoning deltas as they replay. */
|
|
2755
2755
|
onThinking?: (chunk: string) => void;
|
|
2756
|
+
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
2757
|
+
piiRedactor?: PiiRedactor;
|
|
2756
2758
|
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
2757
2759
|
onFinish?: (response: ApiResponse) => void;
|
|
2758
2760
|
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
package/dist/expo/index.mjs
CHANGED
|
@@ -9497,16 +9497,34 @@ async function resumeStream(options) {
|
|
|
9497
9497
|
onData,
|
|
9498
9498
|
onThinking,
|
|
9499
9499
|
onFinish,
|
|
9500
|
-
onError
|
|
9500
|
+
onError,
|
|
9501
|
+
piiRedactor
|
|
9501
9502
|
} = options;
|
|
9502
9503
|
const strategy = getStrategy(handle.apiType);
|
|
9503
9504
|
const accumulator = createStreamAccumulator(handle.model || void 0);
|
|
9505
|
+
const contentDeAnon = piiRedactor && onData ? createStreamingDeAnonymizer(piiRedactor, onData) : null;
|
|
9506
|
+
const thinkingDeAnon = piiRedactor && onThinking ? createStreamingDeAnonymizer(piiRedactor, onThinking) : null;
|
|
9504
9507
|
const contentSmoother = new StreamSmoother((text16) => {
|
|
9505
|
-
if (
|
|
9508
|
+
if (contentDeAnon) contentDeAnon.push(text16);
|
|
9509
|
+
else if (onData) onData(text16);
|
|
9506
9510
|
}, smoothing);
|
|
9507
9511
|
const thinkingSmoother = new StreamSmoother((text16) => {
|
|
9508
|
-
if (
|
|
9512
|
+
if (thinkingDeAnon) thinkingDeAnon.push(text16);
|
|
9513
|
+
else if (onThinking) onThinking(text16);
|
|
9509
9514
|
}, smoothing);
|
|
9515
|
+
const flushOutput = () => {
|
|
9516
|
+
contentSmoother.flush();
|
|
9517
|
+
thinkingSmoother.flush();
|
|
9518
|
+
contentDeAnon?.flush();
|
|
9519
|
+
thinkingDeAnon?.flush();
|
|
9520
|
+
};
|
|
9521
|
+
const buildFinal = () => strategy.buildFinalResponse(
|
|
9522
|
+
piiRedactor ? {
|
|
9523
|
+
...accumulator,
|
|
9524
|
+
content: piiRedactor.deAnonymize(accumulator.content),
|
|
9525
|
+
thinking: piiRedactor.deAnonymize(accumulator.thinking)
|
|
9526
|
+
} : accumulator
|
|
9527
|
+
);
|
|
9510
9528
|
const idleController = new AbortController();
|
|
9511
9529
|
let watchdog;
|
|
9512
9530
|
let idleFired = false;
|
|
@@ -9551,9 +9569,8 @@ async function resumeStream(options) {
|
|
|
9551
9569
|
if (signal) signal.removeEventListener("abort", onCallerAbort);
|
|
9552
9570
|
};
|
|
9553
9571
|
const buildInterrupted = (message) => {
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(strategy.buildFinalResponse(accumulator)) : strategy.buildFinalResponse(accumulator);
|
|
9572
|
+
flushOutput();
|
|
9573
|
+
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(buildFinal()) : buildFinal();
|
|
9557
9574
|
return { data, error: message, interrupted: true };
|
|
9558
9575
|
};
|
|
9559
9576
|
if (combinedSignal.aborted) {
|
|
@@ -9601,18 +9618,16 @@ async function resumeStream(options) {
|
|
|
9601
9618
|
const err = replayErr instanceof Error ? replayErr : new Error(String(replayErr));
|
|
9602
9619
|
const statusCode = parseSseStatusCode(err);
|
|
9603
9620
|
if (statusCode === 410) {
|
|
9604
|
-
|
|
9605
|
-
thinkingSmoother.flush();
|
|
9621
|
+
flushOutput();
|
|
9606
9622
|
throw new StreamExpiredError(handle.inferenceId);
|
|
9607
9623
|
}
|
|
9608
9624
|
if (err.name === "AbortError" || combinedSignal.aborted) {
|
|
9609
9625
|
return buildInterrupted(abortMessage());
|
|
9610
9626
|
}
|
|
9611
|
-
|
|
9612
|
-
thinkingSmoother.flush();
|
|
9627
|
+
flushOutput();
|
|
9613
9628
|
if (onError) onError(err);
|
|
9614
9629
|
return {
|
|
9615
|
-
data:
|
|
9630
|
+
data: buildFinal(),
|
|
9616
9631
|
error: err.message,
|
|
9617
9632
|
interrupted: false,
|
|
9618
9633
|
statusCode
|
|
@@ -9628,7 +9643,9 @@ async function resumeStream(options) {
|
|
|
9628
9643
|
draining = true;
|
|
9629
9644
|
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
9630
9645
|
if (playbackAborted) return buildInterrupted(abortMessage());
|
|
9631
|
-
|
|
9646
|
+
contentDeAnon?.flush();
|
|
9647
|
+
thinkingDeAnon?.flush();
|
|
9648
|
+
const response = buildFinal();
|
|
9632
9649
|
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
9633
9650
|
if (onFinish && deliveredOutput) onFinish(response);
|
|
9634
9651
|
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|
|
@@ -10776,7 +10793,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
10776
10793
|
...item,
|
|
10777
10794
|
memory: {
|
|
10778
10795
|
...item.memory,
|
|
10779
|
-
content: await decrypt(item.memory.content),
|
|
10796
|
+
content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
|
|
10780
10797
|
...item.memory.kind_value !== void 0 && {
|
|
10781
10798
|
kind_value: await decrypt(item.memory.kind_value)
|
|
10782
10799
|
}
|
|
@@ -10870,7 +10887,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
10870
10887
|
}
|
|
10871
10888
|
if (existing && existing.version !== expectedVersion) throw conflict();
|
|
10872
10889
|
const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
|
|
10873
|
-
const
|
|
10890
|
+
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
10891
|
+
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
10874
10892
|
const kindValue = memory.kind_value === void 0 ? void 0 : (snapshot?.kindValue ?? decoded?.memory.kind_value) === memory.kind_value ? snapshot?.encryptedKindValue ?? existing.memory.kind_value : await encryptField2(memory.kind_value);
|
|
10875
10893
|
return {
|
|
10876
10894
|
body: {
|
|
@@ -24140,6 +24158,13 @@ var METADATA_FIELDS = [
|
|
|
24140
24158
|
"published_at",
|
|
24141
24159
|
"geohash"
|
|
24142
24160
|
];
|
|
24161
|
+
var TOMBSTONE_FIELDS = [
|
|
24162
|
+
"scope",
|
|
24163
|
+
"is_deleted",
|
|
24164
|
+
"embedding_model",
|
|
24165
|
+
"topics_updated_at",
|
|
24166
|
+
"last_observed_at"
|
|
24167
|
+
];
|
|
24143
24168
|
function text15(value) {
|
|
24144
24169
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
24145
24170
|
}
|
|
@@ -24287,7 +24312,8 @@ async function embedMissing(prepared, options, model, signal) {
|
|
|
24287
24312
|
}
|
|
24288
24313
|
function sameMetadata2(local, remote, model) {
|
|
24289
24314
|
const mine = metadata2(local, model);
|
|
24290
|
-
|
|
24315
|
+
const fields = bool(local.is_deleted) ? TOMBSTONE_FIELDS : METADATA_FIELDS;
|
|
24316
|
+
return fields.every((field10) => {
|
|
24291
24317
|
const a = mine[field10] ?? null;
|
|
24292
24318
|
const b = remote[field10] ?? null;
|
|
24293
24319
|
if (field10 === "embedding_model" && a === null) return true;
|
package/dist/react/index.cjs
CHANGED
|
@@ -7605,6 +7605,7 @@ function count(value) {
|
|
|
7605
7605
|
|
|
7606
7606
|
// src/lib/chat/resumeStream.ts
|
|
7607
7607
|
init_clientConfig();
|
|
7608
|
+
init_redactor();
|
|
7608
7609
|
|
|
7609
7610
|
// src/lib/chat/toolLoop.ts
|
|
7610
7611
|
init_clientConfig();
|
|
@@ -12076,16 +12077,34 @@ async function resumeStream(options) {
|
|
|
12076
12077
|
onData,
|
|
12077
12078
|
onThinking,
|
|
12078
12079
|
onFinish,
|
|
12079
|
-
onError
|
|
12080
|
+
onError,
|
|
12081
|
+
piiRedactor
|
|
12080
12082
|
} = options;
|
|
12081
12083
|
const strategy = getStrategy(handle.apiType);
|
|
12082
12084
|
const accumulator = createStreamAccumulator(handle.model || void 0);
|
|
12085
|
+
const contentDeAnon = piiRedactor && onData ? createStreamingDeAnonymizer(piiRedactor, onData) : null;
|
|
12086
|
+
const thinkingDeAnon = piiRedactor && onThinking ? createStreamingDeAnonymizer(piiRedactor, onThinking) : null;
|
|
12083
12087
|
const contentSmoother = new StreamSmoother((text16) => {
|
|
12084
|
-
if (
|
|
12088
|
+
if (contentDeAnon) contentDeAnon.push(text16);
|
|
12089
|
+
else if (onData) onData(text16);
|
|
12085
12090
|
}, smoothing);
|
|
12086
12091
|
const thinkingSmoother = new StreamSmoother((text16) => {
|
|
12087
|
-
if (
|
|
12092
|
+
if (thinkingDeAnon) thinkingDeAnon.push(text16);
|
|
12093
|
+
else if (onThinking) onThinking(text16);
|
|
12088
12094
|
}, smoothing);
|
|
12095
|
+
const flushOutput = () => {
|
|
12096
|
+
contentSmoother.flush();
|
|
12097
|
+
thinkingSmoother.flush();
|
|
12098
|
+
contentDeAnon?.flush();
|
|
12099
|
+
thinkingDeAnon?.flush();
|
|
12100
|
+
};
|
|
12101
|
+
const buildFinal = () => strategy.buildFinalResponse(
|
|
12102
|
+
piiRedactor ? {
|
|
12103
|
+
...accumulator,
|
|
12104
|
+
content: piiRedactor.deAnonymize(accumulator.content),
|
|
12105
|
+
thinking: piiRedactor.deAnonymize(accumulator.thinking)
|
|
12106
|
+
} : accumulator
|
|
12107
|
+
);
|
|
12089
12108
|
const idleController = new AbortController();
|
|
12090
12109
|
let watchdog;
|
|
12091
12110
|
let idleFired = false;
|
|
@@ -12130,9 +12149,8 @@ async function resumeStream(options) {
|
|
|
12130
12149
|
if (signal) signal.removeEventListener("abort", onCallerAbort);
|
|
12131
12150
|
};
|
|
12132
12151
|
const buildInterrupted = (message) => {
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(strategy.buildFinalResponse(accumulator)) : strategy.buildFinalResponse(accumulator);
|
|
12152
|
+
flushOutput();
|
|
12153
|
+
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(buildFinal()) : buildFinal();
|
|
12136
12154
|
return { data, error: message, interrupted: true };
|
|
12137
12155
|
};
|
|
12138
12156
|
if (combinedSignal.aborted) {
|
|
@@ -12180,18 +12198,16 @@ async function resumeStream(options) {
|
|
|
12180
12198
|
const err = replayErr instanceof Error ? replayErr : new Error(String(replayErr));
|
|
12181
12199
|
const statusCode = parseSseStatusCode(err);
|
|
12182
12200
|
if (statusCode === 410) {
|
|
12183
|
-
|
|
12184
|
-
thinkingSmoother.flush();
|
|
12201
|
+
flushOutput();
|
|
12185
12202
|
throw new StreamExpiredError(handle.inferenceId);
|
|
12186
12203
|
}
|
|
12187
12204
|
if (err.name === "AbortError" || combinedSignal.aborted) {
|
|
12188
12205
|
return buildInterrupted(abortMessage());
|
|
12189
12206
|
}
|
|
12190
|
-
|
|
12191
|
-
thinkingSmoother.flush();
|
|
12207
|
+
flushOutput();
|
|
12192
12208
|
if (onError) onError(err);
|
|
12193
12209
|
return {
|
|
12194
|
-
data:
|
|
12210
|
+
data: buildFinal(),
|
|
12195
12211
|
error: err.message,
|
|
12196
12212
|
interrupted: false,
|
|
12197
12213
|
statusCode
|
|
@@ -12207,7 +12223,9 @@ async function resumeStream(options) {
|
|
|
12207
12223
|
draining = true;
|
|
12208
12224
|
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
12209
12225
|
if (playbackAborted) return buildInterrupted(abortMessage());
|
|
12210
|
-
|
|
12226
|
+
contentDeAnon?.flush();
|
|
12227
|
+
thinkingDeAnon?.flush();
|
|
12228
|
+
const response = buildFinal();
|
|
12211
12229
|
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
12212
12230
|
if (onFinish && deliveredOutput) onFinish(response);
|
|
12213
12231
|
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|
|
@@ -13218,7 +13236,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
13218
13236
|
...item,
|
|
13219
13237
|
memory: {
|
|
13220
13238
|
...item.memory,
|
|
13221
|
-
content: await decrypt(item.memory.content),
|
|
13239
|
+
content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
|
|
13222
13240
|
...item.memory.kind_value !== void 0 && {
|
|
13223
13241
|
kind_value: await decrypt(item.memory.kind_value)
|
|
13224
13242
|
}
|
|
@@ -13312,7 +13330,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
13312
13330
|
}
|
|
13313
13331
|
if (existing && existing.version !== expectedVersion) throw conflict();
|
|
13314
13332
|
const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
|
|
13315
|
-
const
|
|
13333
|
+
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
13334
|
+
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
13316
13335
|
const kindValue = memory.kind_value === void 0 ? void 0 : (snapshot?.kindValue ?? decoded?.memory.kind_value) === memory.kind_value ? snapshot?.encryptedKindValue ?? existing.memory.kind_value : await encryptField2(memory.kind_value);
|
|
13317
13336
|
return {
|
|
13318
13337
|
body: {
|
|
@@ -28192,6 +28211,13 @@ var METADATA_FIELDS = [
|
|
|
28192
28211
|
"published_at",
|
|
28193
28212
|
"geohash"
|
|
28194
28213
|
];
|
|
28214
|
+
var TOMBSTONE_FIELDS = [
|
|
28215
|
+
"scope",
|
|
28216
|
+
"is_deleted",
|
|
28217
|
+
"embedding_model",
|
|
28218
|
+
"topics_updated_at",
|
|
28219
|
+
"last_observed_at"
|
|
28220
|
+
];
|
|
28195
28221
|
function text15(value) {
|
|
28196
28222
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
28197
28223
|
}
|
|
@@ -28339,7 +28365,8 @@ async function embedMissing(prepared, options, model, signal) {
|
|
|
28339
28365
|
}
|
|
28340
28366
|
function sameMetadata2(local, remote, model) {
|
|
28341
28367
|
const mine = metadata2(local, model);
|
|
28342
|
-
|
|
28368
|
+
const fields = bool(local.is_deleted) ? TOMBSTONE_FIELDS : METADATA_FIELDS;
|
|
28369
|
+
return fields.every((field10) => {
|
|
28343
28370
|
const a = mine[field10] ?? null;
|
|
28344
28371
|
const b = remote[field10] ?? null;
|
|
28345
28372
|
if (field10 === "embedding_model" && a === null) return true;
|
|
@@ -36357,6 +36384,7 @@ function useChat(options) {
|
|
|
36357
36384
|
onToolCallArgumentsDelta,
|
|
36358
36385
|
onStepFinish,
|
|
36359
36386
|
resumable,
|
|
36387
|
+
background = false,
|
|
36360
36388
|
onStreamMeta,
|
|
36361
36389
|
apiType: defaultApiType = "auto",
|
|
36362
36390
|
smoothing,
|
|
@@ -36365,12 +36393,12 @@ function useChat(options) {
|
|
|
36365
36393
|
piiRedaction,
|
|
36366
36394
|
onPiiRedacted
|
|
36367
36395
|
} = options || {};
|
|
36396
|
+
const keepAlive = resumable === true && background;
|
|
36368
36397
|
const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
|
|
36369
36398
|
const abortControllerRef = (0, import_react4.useRef)(null);
|
|
36370
36399
|
const requestIdRef = (0, import_react4.useRef)(0);
|
|
36371
|
-
const
|
|
36372
|
-
|
|
36373
|
-
);
|
|
36400
|
+
const detachControllerRef = (0, import_react4.useRef)(null);
|
|
36401
|
+
const pendingInferenceRef = (0, import_react4.useRef)(null);
|
|
36374
36402
|
const cancelInference = (0, import_react4.useCallback)(
|
|
36375
36403
|
(inferenceId, requestToken) => {
|
|
36376
36404
|
void (async () => {
|
|
@@ -36398,7 +36426,95 @@ function useChat(options) {
|
|
|
36398
36426
|
abortControllerRef.current = null;
|
|
36399
36427
|
}
|
|
36400
36428
|
}, []);
|
|
36401
|
-
(0, import_react4.
|
|
36429
|
+
const keepAliveRef = (0, import_react4.useRef)(keepAlive);
|
|
36430
|
+
keepAliveRef.current = keepAlive;
|
|
36431
|
+
(0, import_react4.useEffect)(
|
|
36432
|
+
() => () => {
|
|
36433
|
+
if (keepAliveRef.current) {
|
|
36434
|
+
if (detachControllerRef.current) {
|
|
36435
|
+
detachControllerRef.current.abort();
|
|
36436
|
+
return;
|
|
36437
|
+
}
|
|
36438
|
+
pendingInferenceRef.current = null;
|
|
36439
|
+
abortControllerRef.current?.abort();
|
|
36440
|
+
abortControllerRef.current = null;
|
|
36441
|
+
return;
|
|
36442
|
+
}
|
|
36443
|
+
stop();
|
|
36444
|
+
},
|
|
36445
|
+
[stop]
|
|
36446
|
+
);
|
|
36447
|
+
const resumeStream2 = (0, import_react4.useCallback)(
|
|
36448
|
+
async (handle, opts) => {
|
|
36449
|
+
const getterValidation = validateTokenGetter(getToken);
|
|
36450
|
+
if (!getterValidation.valid) {
|
|
36451
|
+
return { data: null, error: getterValidation.message, interrupted: false };
|
|
36452
|
+
}
|
|
36453
|
+
const { headless, ...resumeOpts } = opts ?? {};
|
|
36454
|
+
if (!headless && abortControllerRef.current) {
|
|
36455
|
+
return { data: null, error: "A request is already in progress", interrupted: false };
|
|
36456
|
+
}
|
|
36457
|
+
const abortController = new AbortController();
|
|
36458
|
+
const requestId = headless ? null : ++requestIdRef.current;
|
|
36459
|
+
if (!headless) {
|
|
36460
|
+
abortControllerRef.current = abortController;
|
|
36461
|
+
pendingInferenceRef.current = {
|
|
36462
|
+
id: handle.inferenceId,
|
|
36463
|
+
round: -1,
|
|
36464
|
+
cancel: () => cancelInference(handle.inferenceId),
|
|
36465
|
+
handle
|
|
36466
|
+
};
|
|
36467
|
+
setIsLoading(true);
|
|
36468
|
+
}
|
|
36469
|
+
const ownsForeground = () => requestId !== null && requestIdRef.current === requestId;
|
|
36470
|
+
try {
|
|
36471
|
+
let token;
|
|
36472
|
+
try {
|
|
36473
|
+
token = await getToken();
|
|
36474
|
+
} catch (err) {
|
|
36475
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
36476
|
+
if (!headless) onError?.(error);
|
|
36477
|
+
return { data: null, error: error.message, interrupted: false };
|
|
36478
|
+
}
|
|
36479
|
+
const tokenValidation = validateToken(token);
|
|
36480
|
+
if (!tokenValidation.valid) {
|
|
36481
|
+
return { data: null, error: tokenValidation.message, interrupted: false };
|
|
36482
|
+
}
|
|
36483
|
+
return await resumeStream({
|
|
36484
|
+
handle,
|
|
36485
|
+
token,
|
|
36486
|
+
baseUrl,
|
|
36487
|
+
smoothing,
|
|
36488
|
+
signal: abortController.signal,
|
|
36489
|
+
piiRedactor: typeof resolvedPiiRedaction === "object" ? resolvedPiiRedaction : void 0,
|
|
36490
|
+
...headless ? {} : {
|
|
36491
|
+
onData: (chunk) => globalOnData?.(chunk),
|
|
36492
|
+
onThinking: (chunk) => globalOnThinking?.(chunk),
|
|
36493
|
+
onFinish,
|
|
36494
|
+
onError
|
|
36495
|
+
},
|
|
36496
|
+
...resumeOpts
|
|
36497
|
+
});
|
|
36498
|
+
} finally {
|
|
36499
|
+
if (ownsForeground()) {
|
|
36500
|
+
setIsLoading(false);
|
|
36501
|
+
if (abortControllerRef.current === abortController) abortControllerRef.current = null;
|
|
36502
|
+
if (pendingInferenceRef.current?.round === -1) pendingInferenceRef.current = null;
|
|
36503
|
+
}
|
|
36504
|
+
}
|
|
36505
|
+
},
|
|
36506
|
+
[
|
|
36507
|
+
getToken,
|
|
36508
|
+
baseUrl,
|
|
36509
|
+
smoothing,
|
|
36510
|
+
cancelInference,
|
|
36511
|
+
resolvedPiiRedaction,
|
|
36512
|
+
globalOnData,
|
|
36513
|
+
globalOnThinking,
|
|
36514
|
+
onFinish,
|
|
36515
|
+
onError
|
|
36516
|
+
]
|
|
36517
|
+
);
|
|
36402
36518
|
const sendMessage = (0, import_react4.useCallback)(
|
|
36403
36519
|
async ({
|
|
36404
36520
|
messages,
|
|
@@ -36426,9 +36542,12 @@ function useChat(options) {
|
|
|
36426
36542
|
stop();
|
|
36427
36543
|
const abortController = new AbortController();
|
|
36428
36544
|
abortControllerRef.current = abortController;
|
|
36545
|
+
const detachController = keepAlive ? new AbortController() : null;
|
|
36546
|
+
detachControllerRef.current = detachController;
|
|
36429
36547
|
const requestId = ++requestIdRef.current;
|
|
36430
36548
|
setIsLoading(true);
|
|
36431
|
-
let
|
|
36549
|
+
let keepServerStream = false;
|
|
36550
|
+
const deferredErrors = [];
|
|
36432
36551
|
try {
|
|
36433
36552
|
const tokenGetterValidation = validateTokenGetter(getToken);
|
|
36434
36553
|
if (!tokenGetterValidation.valid) {
|
|
@@ -36492,6 +36611,7 @@ function useChat(options) {
|
|
|
36492
36611
|
apiType: requestApiType ?? defaultApiType,
|
|
36493
36612
|
endpointOverride,
|
|
36494
36613
|
resumable,
|
|
36614
|
+
detachSignal: detachController?.signal,
|
|
36495
36615
|
onStreamMeta: resumable || onStreamMeta ? (meta) => {
|
|
36496
36616
|
if (requestId !== requestIdRef.current || abortController.signal.aborted) {
|
|
36497
36617
|
if (resumable) cancelInference(meta.inferenceId, token);
|
|
@@ -36500,12 +36620,19 @@ function useChat(options) {
|
|
|
36500
36620
|
const previous = pendingInferenceRef.current;
|
|
36501
36621
|
if (previous && previous.round === meta.round && previous.id !== meta.inferenceId)
|
|
36502
36622
|
previous.cancel();
|
|
36623
|
+
const handle2 = {
|
|
36624
|
+
inferenceId: meta.inferenceId,
|
|
36625
|
+
apiType: resolveApiType(requestApiType ?? defaultApiType, model),
|
|
36626
|
+
model,
|
|
36627
|
+
conversationId
|
|
36628
|
+
};
|
|
36503
36629
|
pendingInferenceRef.current = {
|
|
36504
36630
|
id: meta.inferenceId,
|
|
36505
36631
|
round: meta.round,
|
|
36506
|
-
cancel: resumable ? () => cancelInference(meta.inferenceId, token) : () => void 0
|
|
36632
|
+
cancel: resumable ? () => cancelInference(meta.inferenceId, token) : () => void 0,
|
|
36633
|
+
handle: handle2
|
|
36507
36634
|
};
|
|
36508
|
-
onStreamMeta?.(meta);
|
|
36635
|
+
onStreamMeta?.({ ...handle2, round: meta.round });
|
|
36509
36636
|
} : void 0,
|
|
36510
36637
|
temperature,
|
|
36511
36638
|
maxOutputTokens,
|
|
@@ -36527,17 +36654,44 @@ function useChat(options) {
|
|
|
36527
36654
|
if (globalOnThinking) globalOnThinking(chunk);
|
|
36528
36655
|
},
|
|
36529
36656
|
onFinish,
|
|
36530
|
-
onError,
|
|
36657
|
+
onError: keepAlive ? (error) => deferredErrors.push(error) : onError,
|
|
36531
36658
|
onToolCall,
|
|
36532
36659
|
onServerToolCall,
|
|
36533
36660
|
onToolCallArgumentsDelta,
|
|
36534
|
-
onStepFinish
|
|
36661
|
+
onStepFinish: keepAlive || onStepFinish ? (event) => {
|
|
36662
|
+
const pending2 = pendingInferenceRef.current;
|
|
36663
|
+
if (keepAlive && pending2 && requestIdRef.current === requestId) {
|
|
36664
|
+
pendingInferenceRef.current = { ...pending2, settled: true };
|
|
36665
|
+
}
|
|
36666
|
+
onStepFinish?.(event);
|
|
36667
|
+
} : void 0,
|
|
36535
36668
|
preProcessors,
|
|
36536
36669
|
hooks,
|
|
36537
36670
|
piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
|
|
36538
36671
|
onPiiRedacted
|
|
36539
36672
|
});
|
|
36540
|
-
|
|
36673
|
+
const pending = pendingInferenceRef.current;
|
|
36674
|
+
const handle = pending && !pending.settled ? pending.handle : null;
|
|
36675
|
+
const detach = result.error !== null && keepAlive && handle && result.error !== "Request aborted";
|
|
36676
|
+
if (!detach) deferredErrors.forEach((error) => onError?.(error));
|
|
36677
|
+
if (result.error === null) {
|
|
36678
|
+
keepServerStream = true;
|
|
36679
|
+
return result;
|
|
36680
|
+
}
|
|
36681
|
+
if (detach) {
|
|
36682
|
+
keepServerStream = true;
|
|
36683
|
+
return {
|
|
36684
|
+
data: result.data,
|
|
36685
|
+
error: "Request detached",
|
|
36686
|
+
detached: true,
|
|
36687
|
+
resume: handle,
|
|
36688
|
+
toolsChecksum: result.toolsChecksum
|
|
36689
|
+
};
|
|
36690
|
+
}
|
|
36691
|
+
if ("detached" in result && result.detached) {
|
|
36692
|
+
keepServerStream = true;
|
|
36693
|
+
return { ...result, resume: null };
|
|
36694
|
+
}
|
|
36541
36695
|
return result;
|
|
36542
36696
|
} catch (err) {
|
|
36543
36697
|
return createErrorResult(
|
|
@@ -36548,7 +36702,8 @@ function useChat(options) {
|
|
|
36548
36702
|
if (requestIdRef.current === requestId) {
|
|
36549
36703
|
setIsLoading(false);
|
|
36550
36704
|
abortControllerRef.current = null;
|
|
36551
|
-
if (
|
|
36705
|
+
if (detachControllerRef.current === detachController) detachControllerRef.current = null;
|
|
36706
|
+
if (!keepServerStream) pendingInferenceRef.current?.cancel();
|
|
36552
36707
|
pendingInferenceRef.current = null;
|
|
36553
36708
|
}
|
|
36554
36709
|
}
|
|
@@ -36567,6 +36722,7 @@ function useChat(options) {
|
|
|
36567
36722
|
onToolCallArgumentsDelta,
|
|
36568
36723
|
onStepFinish,
|
|
36569
36724
|
resumable,
|
|
36725
|
+
keepAlive,
|
|
36570
36726
|
onStreamMeta,
|
|
36571
36727
|
defaultApiType,
|
|
36572
36728
|
smoothing,
|
|
@@ -36579,7 +36735,8 @@ function useChat(options) {
|
|
|
36579
36735
|
return {
|
|
36580
36736
|
isLoading,
|
|
36581
36737
|
sendMessage,
|
|
36582
|
-
stop
|
|
36738
|
+
stop,
|
|
36739
|
+
resumeStream: resumeStream2
|
|
36583
36740
|
};
|
|
36584
36741
|
}
|
|
36585
36742
|
|
package/dist/react/index.d.mts
CHANGED
|
@@ -2890,6 +2890,8 @@ interface ResumeStreamOptions {
|
|
|
2890
2890
|
onData?: (chunk: string) => void;
|
|
2891
2891
|
/** Thinking/reasoning deltas as they replay. */
|
|
2892
2892
|
onThinking?: (chunk: string) => void;
|
|
2893
|
+
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
2894
|
+
piiRedactor?: PiiRedactor;
|
|
2893
2895
|
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
2894
2896
|
onFinish?: (response: ApiResponse) => void;
|
|
2895
2897
|
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
|
@@ -14633,6 +14635,10 @@ type SendMessageResult = {
|
|
|
14633
14635
|
error: string;
|
|
14634
14636
|
/** Checksum of tools used to generate this response */
|
|
14635
14637
|
toolsChecksum?: string;
|
|
14638
|
+
/** True when a background stream was left running; `error` is "Request detached". */
|
|
14639
|
+
detached?: true;
|
|
14640
|
+
/** Pass to `resumeStream`; null when no inference id was issued before the detach. */
|
|
14641
|
+
resume?: StreamResumeHandle | null;
|
|
14636
14642
|
};
|
|
14637
14643
|
/**
|
|
14638
14644
|
* @inline
|
|
@@ -14640,11 +14646,13 @@ type SendMessageResult = {
|
|
|
14640
14646
|
interface UseChatOptions extends BaseUseChatOptions {
|
|
14641
14647
|
/** Buffer streamed rounds so a service can verify their canonical output. */
|
|
14642
14648
|
resumable?: boolean;
|
|
14643
|
-
/**
|
|
14644
|
-
|
|
14645
|
-
|
|
14646
|
-
|
|
14647
|
-
|
|
14649
|
+
/**
|
|
14650
|
+
* Keep a resumable generation running server-side when the request fails or
|
|
14651
|
+
* the hook unmounts; only `stop()` cancels it. Replay it with `resumeStream`.
|
|
14652
|
+
*/
|
|
14653
|
+
background?: boolean;
|
|
14654
|
+
/** Stream handle for each HTTP round, including client-tool continuations. */
|
|
14655
|
+
onStreamMeta?: (meta: StreamMeta) => void;
|
|
14648
14656
|
/**
|
|
14649
14657
|
* Which API endpoint to use. Default: "auto"
|
|
14650
14658
|
* - "auto": automatically selects the best API based on model support
|
|
@@ -14653,8 +14661,19 @@ interface UseChatOptions extends BaseUseChatOptions {
|
|
|
14653
14661
|
*/
|
|
14654
14662
|
apiType?: ApiType;
|
|
14655
14663
|
}
|
|
14664
|
+
/**
|
|
14665
|
+
* A resumable stream handle plus the tool-loop round that issued it.
|
|
14666
|
+
* @inline
|
|
14667
|
+
*/
|
|
14668
|
+
type StreamMeta = StreamResumeHandle & {
|
|
14669
|
+
round: number;
|
|
14670
|
+
};
|
|
14656
14671
|
type UseChatResult = BaseUseChatResult & {
|
|
14657
14672
|
sendMessage: (args: SendMessageArgs) => Promise<SendMessageResult>;
|
|
14673
|
+
/** Replay a resumable stream from the portal buffer, from its first frame. */
|
|
14674
|
+
resumeStream: (handle: StreamResumeHandle, opts?: Pick<ResumeStreamOptions, "idleTimeoutMs" | "smoothing"> & {
|
|
14675
|
+
headless?: boolean;
|
|
14676
|
+
}) => Promise<ResumeStreamResult>;
|
|
14658
14677
|
};
|
|
14659
14678
|
/**
|
|
14660
14679
|
* A React hook for managing chat completions with authentication.
|
package/dist/react/index.d.ts
CHANGED
|
@@ -2890,6 +2890,8 @@ interface ResumeStreamOptions {
|
|
|
2890
2890
|
onData?: (chunk: string) => void;
|
|
2891
2891
|
/** Thinking/reasoning deltas as they replay. */
|
|
2892
2892
|
onThinking?: (chunk: string) => void;
|
|
2893
|
+
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
2894
|
+
piiRedactor?: PiiRedactor;
|
|
2893
2895
|
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
2894
2896
|
onFinish?: (response: ApiResponse) => void;
|
|
2895
2897
|
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
|
@@ -14633,6 +14635,10 @@ type SendMessageResult = {
|
|
|
14633
14635
|
error: string;
|
|
14634
14636
|
/** Checksum of tools used to generate this response */
|
|
14635
14637
|
toolsChecksum?: string;
|
|
14638
|
+
/** True when a background stream was left running; `error` is "Request detached". */
|
|
14639
|
+
detached?: true;
|
|
14640
|
+
/** Pass to `resumeStream`; null when no inference id was issued before the detach. */
|
|
14641
|
+
resume?: StreamResumeHandle | null;
|
|
14636
14642
|
};
|
|
14637
14643
|
/**
|
|
14638
14644
|
* @inline
|
|
@@ -14640,11 +14646,13 @@ type SendMessageResult = {
|
|
|
14640
14646
|
interface UseChatOptions extends BaseUseChatOptions {
|
|
14641
14647
|
/** Buffer streamed rounds so a service can verify their canonical output. */
|
|
14642
14648
|
resumable?: boolean;
|
|
14643
|
-
/**
|
|
14644
|
-
|
|
14645
|
-
|
|
14646
|
-
|
|
14647
|
-
|
|
14649
|
+
/**
|
|
14650
|
+
* Keep a resumable generation running server-side when the request fails or
|
|
14651
|
+
* the hook unmounts; only `stop()` cancels it. Replay it with `resumeStream`.
|
|
14652
|
+
*/
|
|
14653
|
+
background?: boolean;
|
|
14654
|
+
/** Stream handle for each HTTP round, including client-tool continuations. */
|
|
14655
|
+
onStreamMeta?: (meta: StreamMeta) => void;
|
|
14648
14656
|
/**
|
|
14649
14657
|
* Which API endpoint to use. Default: "auto"
|
|
14650
14658
|
* - "auto": automatically selects the best API based on model support
|
|
@@ -14653,8 +14661,19 @@ interface UseChatOptions extends BaseUseChatOptions {
|
|
|
14653
14661
|
*/
|
|
14654
14662
|
apiType?: ApiType;
|
|
14655
14663
|
}
|
|
14664
|
+
/**
|
|
14665
|
+
* A resumable stream handle plus the tool-loop round that issued it.
|
|
14666
|
+
* @inline
|
|
14667
|
+
*/
|
|
14668
|
+
type StreamMeta = StreamResumeHandle & {
|
|
14669
|
+
round: number;
|
|
14670
|
+
};
|
|
14656
14671
|
type UseChatResult = BaseUseChatResult & {
|
|
14657
14672
|
sendMessage: (args: SendMessageArgs) => Promise<SendMessageResult>;
|
|
14673
|
+
/** Replay a resumable stream from the portal buffer, from its first frame. */
|
|
14674
|
+
resumeStream: (handle: StreamResumeHandle, opts?: Pick<ResumeStreamOptions, "idleTimeoutMs" | "smoothing"> & {
|
|
14675
|
+
headless?: boolean;
|
|
14676
|
+
}) => Promise<ResumeStreamResult>;
|
|
14658
14677
|
};
|
|
14659
14678
|
/**
|
|
14660
14679
|
* A React hook for managing chat completions with authentication.
|
package/dist/react/index.mjs
CHANGED
|
@@ -10208,16 +10208,34 @@ async function resumeStream(options) {
|
|
|
10208
10208
|
onData,
|
|
10209
10209
|
onThinking,
|
|
10210
10210
|
onFinish,
|
|
10211
|
-
onError
|
|
10211
|
+
onError,
|
|
10212
|
+
piiRedactor
|
|
10212
10213
|
} = options;
|
|
10213
10214
|
const strategy = getStrategy(handle.apiType);
|
|
10214
10215
|
const accumulator = createStreamAccumulator(handle.model || void 0);
|
|
10216
|
+
const contentDeAnon = piiRedactor && onData ? createStreamingDeAnonymizer(piiRedactor, onData) : null;
|
|
10217
|
+
const thinkingDeAnon = piiRedactor && onThinking ? createStreamingDeAnonymizer(piiRedactor, onThinking) : null;
|
|
10215
10218
|
const contentSmoother = new StreamSmoother((text16) => {
|
|
10216
|
-
if (
|
|
10219
|
+
if (contentDeAnon) contentDeAnon.push(text16);
|
|
10220
|
+
else if (onData) onData(text16);
|
|
10217
10221
|
}, smoothing);
|
|
10218
10222
|
const thinkingSmoother = new StreamSmoother((text16) => {
|
|
10219
|
-
if (
|
|
10223
|
+
if (thinkingDeAnon) thinkingDeAnon.push(text16);
|
|
10224
|
+
else if (onThinking) onThinking(text16);
|
|
10220
10225
|
}, smoothing);
|
|
10226
|
+
const flushOutput = () => {
|
|
10227
|
+
contentSmoother.flush();
|
|
10228
|
+
thinkingSmoother.flush();
|
|
10229
|
+
contentDeAnon?.flush();
|
|
10230
|
+
thinkingDeAnon?.flush();
|
|
10231
|
+
};
|
|
10232
|
+
const buildFinal = () => strategy.buildFinalResponse(
|
|
10233
|
+
piiRedactor ? {
|
|
10234
|
+
...accumulator,
|
|
10235
|
+
content: piiRedactor.deAnonymize(accumulator.content),
|
|
10236
|
+
thinking: piiRedactor.deAnonymize(accumulator.thinking)
|
|
10237
|
+
} : accumulator
|
|
10238
|
+
);
|
|
10221
10239
|
const idleController = new AbortController();
|
|
10222
10240
|
let watchdog;
|
|
10223
10241
|
let idleFired = false;
|
|
@@ -10262,9 +10280,8 @@ async function resumeStream(options) {
|
|
|
10262
10280
|
if (signal) signal.removeEventListener("abort", onCallerAbort);
|
|
10263
10281
|
};
|
|
10264
10282
|
const buildInterrupted = (message) => {
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(strategy.buildFinalResponse(accumulator)) : strategy.buildFinalResponse(accumulator);
|
|
10283
|
+
flushOutput();
|
|
10284
|
+
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(buildFinal()) : buildFinal();
|
|
10268
10285
|
return { data, error: message, interrupted: true };
|
|
10269
10286
|
};
|
|
10270
10287
|
if (combinedSignal.aborted) {
|
|
@@ -10312,18 +10329,16 @@ async function resumeStream(options) {
|
|
|
10312
10329
|
const err = replayErr instanceof Error ? replayErr : new Error(String(replayErr));
|
|
10313
10330
|
const statusCode = parseSseStatusCode(err);
|
|
10314
10331
|
if (statusCode === 410) {
|
|
10315
|
-
|
|
10316
|
-
thinkingSmoother.flush();
|
|
10332
|
+
flushOutput();
|
|
10317
10333
|
throw new StreamExpiredError(handle.inferenceId);
|
|
10318
10334
|
}
|
|
10319
10335
|
if (err.name === "AbortError" || combinedSignal.aborted) {
|
|
10320
10336
|
return buildInterrupted(abortMessage());
|
|
10321
10337
|
}
|
|
10322
|
-
|
|
10323
|
-
thinkingSmoother.flush();
|
|
10338
|
+
flushOutput();
|
|
10324
10339
|
if (onError) onError(err);
|
|
10325
10340
|
return {
|
|
10326
|
-
data:
|
|
10341
|
+
data: buildFinal(),
|
|
10327
10342
|
error: err.message,
|
|
10328
10343
|
interrupted: false,
|
|
10329
10344
|
statusCode
|
|
@@ -10339,7 +10354,9 @@ async function resumeStream(options) {
|
|
|
10339
10354
|
draining = true;
|
|
10340
10355
|
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
10341
10356
|
if (playbackAborted) return buildInterrupted(abortMessage());
|
|
10342
|
-
|
|
10357
|
+
contentDeAnon?.flush();
|
|
10358
|
+
thinkingDeAnon?.flush();
|
|
10359
|
+
const response = buildFinal();
|
|
10343
10360
|
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
10344
10361
|
if (onFinish && deliveredOutput) onFinish(response);
|
|
10345
10362
|
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|
|
@@ -11345,7 +11362,7 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
11345
11362
|
...item,
|
|
11346
11363
|
memory: {
|
|
11347
11364
|
...item.memory,
|
|
11348
|
-
content: await decrypt(item.memory.content),
|
|
11365
|
+
content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
|
|
11349
11366
|
...item.memory.kind_value !== void 0 && {
|
|
11350
11367
|
kind_value: await decrypt(item.memory.kind_value)
|
|
11351
11368
|
}
|
|
@@ -11439,7 +11456,8 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
11439
11456
|
}
|
|
11440
11457
|
if (existing && existing.version !== expectedVersion) throw conflict();
|
|
11441
11458
|
const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
|
|
11442
|
-
const
|
|
11459
|
+
const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
|
|
11460
|
+
const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
|
|
11443
11461
|
const kindValue = memory.kind_value === void 0 ? void 0 : (snapshot?.kindValue ?? decoded?.memory.kind_value) === memory.kind_value ? snapshot?.encryptedKindValue ?? existing.memory.kind_value : await encryptField2(memory.kind_value);
|
|
11444
11462
|
return {
|
|
11445
11463
|
body: {
|
|
@@ -26266,6 +26284,13 @@ var METADATA_FIELDS = [
|
|
|
26266
26284
|
"published_at",
|
|
26267
26285
|
"geohash"
|
|
26268
26286
|
];
|
|
26287
|
+
var TOMBSTONE_FIELDS = [
|
|
26288
|
+
"scope",
|
|
26289
|
+
"is_deleted",
|
|
26290
|
+
"embedding_model",
|
|
26291
|
+
"topics_updated_at",
|
|
26292
|
+
"last_observed_at"
|
|
26293
|
+
];
|
|
26269
26294
|
function text15(value) {
|
|
26270
26295
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
26271
26296
|
}
|
|
@@ -26413,7 +26438,8 @@ async function embedMissing(prepared, options, model, signal) {
|
|
|
26413
26438
|
}
|
|
26414
26439
|
function sameMetadata2(local, remote, model) {
|
|
26415
26440
|
const mine = metadata2(local, model);
|
|
26416
|
-
|
|
26441
|
+
const fields = bool(local.is_deleted) ? TOMBSTONE_FIELDS : METADATA_FIELDS;
|
|
26442
|
+
return fields.every((field10) => {
|
|
26417
26443
|
const a = mine[field10] ?? null;
|
|
26418
26444
|
const b = remote[field10] ?? null;
|
|
26419
26445
|
if (field10 === "embedding_model" && a === null) return true;
|
|
@@ -34429,6 +34455,7 @@ function useChat(options) {
|
|
|
34429
34455
|
onToolCallArgumentsDelta,
|
|
34430
34456
|
onStepFinish,
|
|
34431
34457
|
resumable,
|
|
34458
|
+
background = false,
|
|
34432
34459
|
onStreamMeta,
|
|
34433
34460
|
apiType: defaultApiType = "auto",
|
|
34434
34461
|
smoothing,
|
|
@@ -34437,12 +34464,12 @@ function useChat(options) {
|
|
|
34437
34464
|
piiRedaction,
|
|
34438
34465
|
onPiiRedacted
|
|
34439
34466
|
} = options || {};
|
|
34467
|
+
const keepAlive = resumable === true && background;
|
|
34440
34468
|
const [isLoading, setIsLoading] = useState4(false);
|
|
34441
34469
|
const abortControllerRef = useRef3(null);
|
|
34442
34470
|
const requestIdRef = useRef3(0);
|
|
34443
|
-
const
|
|
34444
|
-
|
|
34445
|
-
);
|
|
34471
|
+
const detachControllerRef = useRef3(null);
|
|
34472
|
+
const pendingInferenceRef = useRef3(null);
|
|
34446
34473
|
const cancelInference = useCallback3(
|
|
34447
34474
|
(inferenceId, requestToken) => {
|
|
34448
34475
|
void (async () => {
|
|
@@ -34470,7 +34497,95 @@ function useChat(options) {
|
|
|
34470
34497
|
abortControllerRef.current = null;
|
|
34471
34498
|
}
|
|
34472
34499
|
}, []);
|
|
34473
|
-
|
|
34500
|
+
const keepAliveRef = useRef3(keepAlive);
|
|
34501
|
+
keepAliveRef.current = keepAlive;
|
|
34502
|
+
useEffect3(
|
|
34503
|
+
() => () => {
|
|
34504
|
+
if (keepAliveRef.current) {
|
|
34505
|
+
if (detachControllerRef.current) {
|
|
34506
|
+
detachControllerRef.current.abort();
|
|
34507
|
+
return;
|
|
34508
|
+
}
|
|
34509
|
+
pendingInferenceRef.current = null;
|
|
34510
|
+
abortControllerRef.current?.abort();
|
|
34511
|
+
abortControllerRef.current = null;
|
|
34512
|
+
return;
|
|
34513
|
+
}
|
|
34514
|
+
stop();
|
|
34515
|
+
},
|
|
34516
|
+
[stop]
|
|
34517
|
+
);
|
|
34518
|
+
const resumeStream2 = useCallback3(
|
|
34519
|
+
async (handle, opts) => {
|
|
34520
|
+
const getterValidation = validateTokenGetter(getToken);
|
|
34521
|
+
if (!getterValidation.valid) {
|
|
34522
|
+
return { data: null, error: getterValidation.message, interrupted: false };
|
|
34523
|
+
}
|
|
34524
|
+
const { headless, ...resumeOpts } = opts ?? {};
|
|
34525
|
+
if (!headless && abortControllerRef.current) {
|
|
34526
|
+
return { data: null, error: "A request is already in progress", interrupted: false };
|
|
34527
|
+
}
|
|
34528
|
+
const abortController = new AbortController();
|
|
34529
|
+
const requestId = headless ? null : ++requestIdRef.current;
|
|
34530
|
+
if (!headless) {
|
|
34531
|
+
abortControllerRef.current = abortController;
|
|
34532
|
+
pendingInferenceRef.current = {
|
|
34533
|
+
id: handle.inferenceId,
|
|
34534
|
+
round: -1,
|
|
34535
|
+
cancel: () => cancelInference(handle.inferenceId),
|
|
34536
|
+
handle
|
|
34537
|
+
};
|
|
34538
|
+
setIsLoading(true);
|
|
34539
|
+
}
|
|
34540
|
+
const ownsForeground = () => requestId !== null && requestIdRef.current === requestId;
|
|
34541
|
+
try {
|
|
34542
|
+
let token;
|
|
34543
|
+
try {
|
|
34544
|
+
token = await getToken();
|
|
34545
|
+
} catch (err) {
|
|
34546
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
34547
|
+
if (!headless) onError?.(error);
|
|
34548
|
+
return { data: null, error: error.message, interrupted: false };
|
|
34549
|
+
}
|
|
34550
|
+
const tokenValidation = validateToken(token);
|
|
34551
|
+
if (!tokenValidation.valid) {
|
|
34552
|
+
return { data: null, error: tokenValidation.message, interrupted: false };
|
|
34553
|
+
}
|
|
34554
|
+
return await resumeStream({
|
|
34555
|
+
handle,
|
|
34556
|
+
token,
|
|
34557
|
+
baseUrl,
|
|
34558
|
+
smoothing,
|
|
34559
|
+
signal: abortController.signal,
|
|
34560
|
+
piiRedactor: typeof resolvedPiiRedaction === "object" ? resolvedPiiRedaction : void 0,
|
|
34561
|
+
...headless ? {} : {
|
|
34562
|
+
onData: (chunk) => globalOnData?.(chunk),
|
|
34563
|
+
onThinking: (chunk) => globalOnThinking?.(chunk),
|
|
34564
|
+
onFinish,
|
|
34565
|
+
onError
|
|
34566
|
+
},
|
|
34567
|
+
...resumeOpts
|
|
34568
|
+
});
|
|
34569
|
+
} finally {
|
|
34570
|
+
if (ownsForeground()) {
|
|
34571
|
+
setIsLoading(false);
|
|
34572
|
+
if (abortControllerRef.current === abortController) abortControllerRef.current = null;
|
|
34573
|
+
if (pendingInferenceRef.current?.round === -1) pendingInferenceRef.current = null;
|
|
34574
|
+
}
|
|
34575
|
+
}
|
|
34576
|
+
},
|
|
34577
|
+
[
|
|
34578
|
+
getToken,
|
|
34579
|
+
baseUrl,
|
|
34580
|
+
smoothing,
|
|
34581
|
+
cancelInference,
|
|
34582
|
+
resolvedPiiRedaction,
|
|
34583
|
+
globalOnData,
|
|
34584
|
+
globalOnThinking,
|
|
34585
|
+
onFinish,
|
|
34586
|
+
onError
|
|
34587
|
+
]
|
|
34588
|
+
);
|
|
34474
34589
|
const sendMessage = useCallback3(
|
|
34475
34590
|
async ({
|
|
34476
34591
|
messages,
|
|
@@ -34498,9 +34613,12 @@ function useChat(options) {
|
|
|
34498
34613
|
stop();
|
|
34499
34614
|
const abortController = new AbortController();
|
|
34500
34615
|
abortControllerRef.current = abortController;
|
|
34616
|
+
const detachController = keepAlive ? new AbortController() : null;
|
|
34617
|
+
detachControllerRef.current = detachController;
|
|
34501
34618
|
const requestId = ++requestIdRef.current;
|
|
34502
34619
|
setIsLoading(true);
|
|
34503
|
-
let
|
|
34620
|
+
let keepServerStream = false;
|
|
34621
|
+
const deferredErrors = [];
|
|
34504
34622
|
try {
|
|
34505
34623
|
const tokenGetterValidation = validateTokenGetter(getToken);
|
|
34506
34624
|
if (!tokenGetterValidation.valid) {
|
|
@@ -34564,6 +34682,7 @@ function useChat(options) {
|
|
|
34564
34682
|
apiType: requestApiType ?? defaultApiType,
|
|
34565
34683
|
endpointOverride,
|
|
34566
34684
|
resumable,
|
|
34685
|
+
detachSignal: detachController?.signal,
|
|
34567
34686
|
onStreamMeta: resumable || onStreamMeta ? (meta) => {
|
|
34568
34687
|
if (requestId !== requestIdRef.current || abortController.signal.aborted) {
|
|
34569
34688
|
if (resumable) cancelInference(meta.inferenceId, token);
|
|
@@ -34572,12 +34691,19 @@ function useChat(options) {
|
|
|
34572
34691
|
const previous = pendingInferenceRef.current;
|
|
34573
34692
|
if (previous && previous.round === meta.round && previous.id !== meta.inferenceId)
|
|
34574
34693
|
previous.cancel();
|
|
34694
|
+
const handle2 = {
|
|
34695
|
+
inferenceId: meta.inferenceId,
|
|
34696
|
+
apiType: resolveApiType(requestApiType ?? defaultApiType, model),
|
|
34697
|
+
model,
|
|
34698
|
+
conversationId
|
|
34699
|
+
};
|
|
34575
34700
|
pendingInferenceRef.current = {
|
|
34576
34701
|
id: meta.inferenceId,
|
|
34577
34702
|
round: meta.round,
|
|
34578
|
-
cancel: resumable ? () => cancelInference(meta.inferenceId, token) : () => void 0
|
|
34703
|
+
cancel: resumable ? () => cancelInference(meta.inferenceId, token) : () => void 0,
|
|
34704
|
+
handle: handle2
|
|
34579
34705
|
};
|
|
34580
|
-
onStreamMeta?.(meta);
|
|
34706
|
+
onStreamMeta?.({ ...handle2, round: meta.round });
|
|
34581
34707
|
} : void 0,
|
|
34582
34708
|
temperature,
|
|
34583
34709
|
maxOutputTokens,
|
|
@@ -34599,17 +34725,44 @@ function useChat(options) {
|
|
|
34599
34725
|
if (globalOnThinking) globalOnThinking(chunk);
|
|
34600
34726
|
},
|
|
34601
34727
|
onFinish,
|
|
34602
|
-
onError,
|
|
34728
|
+
onError: keepAlive ? (error) => deferredErrors.push(error) : onError,
|
|
34603
34729
|
onToolCall,
|
|
34604
34730
|
onServerToolCall,
|
|
34605
34731
|
onToolCallArgumentsDelta,
|
|
34606
|
-
onStepFinish
|
|
34732
|
+
onStepFinish: keepAlive || onStepFinish ? (event) => {
|
|
34733
|
+
const pending2 = pendingInferenceRef.current;
|
|
34734
|
+
if (keepAlive && pending2 && requestIdRef.current === requestId) {
|
|
34735
|
+
pendingInferenceRef.current = { ...pending2, settled: true };
|
|
34736
|
+
}
|
|
34737
|
+
onStepFinish?.(event);
|
|
34738
|
+
} : void 0,
|
|
34607
34739
|
preProcessors,
|
|
34608
34740
|
hooks,
|
|
34609
34741
|
piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
|
|
34610
34742
|
onPiiRedacted
|
|
34611
34743
|
});
|
|
34612
|
-
|
|
34744
|
+
const pending = pendingInferenceRef.current;
|
|
34745
|
+
const handle = pending && !pending.settled ? pending.handle : null;
|
|
34746
|
+
const detach = result.error !== null && keepAlive && handle && result.error !== "Request aborted";
|
|
34747
|
+
if (!detach) deferredErrors.forEach((error) => onError?.(error));
|
|
34748
|
+
if (result.error === null) {
|
|
34749
|
+
keepServerStream = true;
|
|
34750
|
+
return result;
|
|
34751
|
+
}
|
|
34752
|
+
if (detach) {
|
|
34753
|
+
keepServerStream = true;
|
|
34754
|
+
return {
|
|
34755
|
+
data: result.data,
|
|
34756
|
+
error: "Request detached",
|
|
34757
|
+
detached: true,
|
|
34758
|
+
resume: handle,
|
|
34759
|
+
toolsChecksum: result.toolsChecksum
|
|
34760
|
+
};
|
|
34761
|
+
}
|
|
34762
|
+
if ("detached" in result && result.detached) {
|
|
34763
|
+
keepServerStream = true;
|
|
34764
|
+
return { ...result, resume: null };
|
|
34765
|
+
}
|
|
34613
34766
|
return result;
|
|
34614
34767
|
} catch (err) {
|
|
34615
34768
|
return createErrorResult(
|
|
@@ -34620,7 +34773,8 @@ function useChat(options) {
|
|
|
34620
34773
|
if (requestIdRef.current === requestId) {
|
|
34621
34774
|
setIsLoading(false);
|
|
34622
34775
|
abortControllerRef.current = null;
|
|
34623
|
-
if (
|
|
34776
|
+
if (detachControllerRef.current === detachController) detachControllerRef.current = null;
|
|
34777
|
+
if (!keepServerStream) pendingInferenceRef.current?.cancel();
|
|
34624
34778
|
pendingInferenceRef.current = null;
|
|
34625
34779
|
}
|
|
34626
34780
|
}
|
|
@@ -34639,6 +34793,7 @@ function useChat(options) {
|
|
|
34639
34793
|
onToolCallArgumentsDelta,
|
|
34640
34794
|
onStepFinish,
|
|
34641
34795
|
resumable,
|
|
34796
|
+
keepAlive,
|
|
34642
34797
|
onStreamMeta,
|
|
34643
34798
|
defaultApiType,
|
|
34644
34799
|
smoothing,
|
|
@@ -34651,7 +34806,8 @@ function useChat(options) {
|
|
|
34651
34806
|
return {
|
|
34652
34807
|
isLoading,
|
|
34653
34808
|
sendMessage,
|
|
34654
|
-
stop
|
|
34809
|
+
stop,
|
|
34810
|
+
resumeStream: resumeStream2
|
|
34655
34811
|
};
|
|
34656
34812
|
}
|
|
34657
34813
|
|
package/dist/server/index.cjs
CHANGED
|
@@ -21163,6 +21163,7 @@ function createCryptoPricePreProcessor(options = {}) {
|
|
|
21163
21163
|
|
|
21164
21164
|
// src/lib/chat/resumeStream.ts
|
|
21165
21165
|
init_clientConfig();
|
|
21166
|
+
init_redactor();
|
|
21166
21167
|
|
|
21167
21168
|
// src/lib/chat/toolLoop.ts
|
|
21168
21169
|
init_clientConfig();
|
|
@@ -25385,16 +25386,34 @@ async function resumeStream(options) {
|
|
|
25385
25386
|
onData,
|
|
25386
25387
|
onThinking,
|
|
25387
25388
|
onFinish,
|
|
25388
|
-
onError
|
|
25389
|
+
onError,
|
|
25390
|
+
piiRedactor
|
|
25389
25391
|
} = options;
|
|
25390
25392
|
const strategy = getStrategy(handle.apiType);
|
|
25391
25393
|
const accumulator = createStreamAccumulator(handle.model || void 0);
|
|
25394
|
+
const contentDeAnon = piiRedactor && onData ? createStreamingDeAnonymizer(piiRedactor, onData) : null;
|
|
25395
|
+
const thinkingDeAnon = piiRedactor && onThinking ? createStreamingDeAnonymizer(piiRedactor, onThinking) : null;
|
|
25392
25396
|
const contentSmoother = new StreamSmoother((text12) => {
|
|
25393
|
-
if (
|
|
25397
|
+
if (contentDeAnon) contentDeAnon.push(text12);
|
|
25398
|
+
else if (onData) onData(text12);
|
|
25394
25399
|
}, smoothing);
|
|
25395
25400
|
const thinkingSmoother = new StreamSmoother((text12) => {
|
|
25396
|
-
if (
|
|
25401
|
+
if (thinkingDeAnon) thinkingDeAnon.push(text12);
|
|
25402
|
+
else if (onThinking) onThinking(text12);
|
|
25397
25403
|
}, smoothing);
|
|
25404
|
+
const flushOutput = () => {
|
|
25405
|
+
contentSmoother.flush();
|
|
25406
|
+
thinkingSmoother.flush();
|
|
25407
|
+
contentDeAnon?.flush();
|
|
25408
|
+
thinkingDeAnon?.flush();
|
|
25409
|
+
};
|
|
25410
|
+
const buildFinal = () => strategy.buildFinalResponse(
|
|
25411
|
+
piiRedactor ? {
|
|
25412
|
+
...accumulator,
|
|
25413
|
+
content: piiRedactor.deAnonymize(accumulator.content),
|
|
25414
|
+
thinking: piiRedactor.deAnonymize(accumulator.thinking)
|
|
25415
|
+
} : accumulator
|
|
25416
|
+
);
|
|
25398
25417
|
const idleController = new AbortController();
|
|
25399
25418
|
let watchdog;
|
|
25400
25419
|
let idleFired = false;
|
|
@@ -25439,9 +25458,8 @@ async function resumeStream(options) {
|
|
|
25439
25458
|
if (signal) signal.removeEventListener("abort", onCallerAbort);
|
|
25440
25459
|
};
|
|
25441
25460
|
const buildInterrupted = (message) => {
|
|
25442
|
-
|
|
25443
|
-
|
|
25444
|
-
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(strategy.buildFinalResponse(accumulator)) : strategy.buildFinalResponse(accumulator);
|
|
25461
|
+
flushOutput();
|
|
25462
|
+
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(buildFinal()) : buildFinal();
|
|
25445
25463
|
return { data, error: message, interrupted: true };
|
|
25446
25464
|
};
|
|
25447
25465
|
if (combinedSignal.aborted) {
|
|
@@ -25489,18 +25507,16 @@ async function resumeStream(options) {
|
|
|
25489
25507
|
const err = replayErr instanceof Error ? replayErr : new Error(String(replayErr));
|
|
25490
25508
|
const statusCode = parseSseStatusCode(err);
|
|
25491
25509
|
if (statusCode === 410) {
|
|
25492
|
-
|
|
25493
|
-
thinkingSmoother.flush();
|
|
25510
|
+
flushOutput();
|
|
25494
25511
|
throw new StreamExpiredError(handle.inferenceId);
|
|
25495
25512
|
}
|
|
25496
25513
|
if (err.name === "AbortError" || combinedSignal.aborted) {
|
|
25497
25514
|
return buildInterrupted(abortMessage());
|
|
25498
25515
|
}
|
|
25499
|
-
|
|
25500
|
-
thinkingSmoother.flush();
|
|
25516
|
+
flushOutput();
|
|
25501
25517
|
if (onError) onError(err);
|
|
25502
25518
|
return {
|
|
25503
|
-
data:
|
|
25519
|
+
data: buildFinal(),
|
|
25504
25520
|
error: err.message,
|
|
25505
25521
|
interrupted: false,
|
|
25506
25522
|
statusCode
|
|
@@ -25516,7 +25532,9 @@ async function resumeStream(options) {
|
|
|
25516
25532
|
draining = true;
|
|
25517
25533
|
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
25518
25534
|
if (playbackAborted) return buildInterrupted(abortMessage());
|
|
25519
|
-
|
|
25535
|
+
contentDeAnon?.flush();
|
|
25536
|
+
thinkingDeAnon?.flush();
|
|
25537
|
+
const response = buildFinal();
|
|
25520
25538
|
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
25521
25539
|
if (onFinish && deliveredOutput) onFinish(response);
|
|
25522
25540
|
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|
package/dist/server/index.d.mts
CHANGED
|
@@ -2470,6 +2470,8 @@ interface ResumeStreamOptions {
|
|
|
2470
2470
|
onData?: (chunk: string) => void;
|
|
2471
2471
|
/** Thinking/reasoning deltas as they replay. */
|
|
2472
2472
|
onThinking?: (chunk: string) => void;
|
|
2473
|
+
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
2474
|
+
piiRedactor?: PiiRedactor;
|
|
2473
2475
|
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
2474
2476
|
onFinish?: (response: ApiResponse) => void;
|
|
2475
2477
|
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
package/dist/server/index.d.ts
CHANGED
|
@@ -2470,6 +2470,8 @@ interface ResumeStreamOptions {
|
|
|
2470
2470
|
onData?: (chunk: string) => void;
|
|
2471
2471
|
/** Thinking/reasoning deltas as they replay. */
|
|
2472
2472
|
onThinking?: (chunk: string) => void;
|
|
2473
|
+
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
2474
|
+
piiRedactor?: PiiRedactor;
|
|
2473
2475
|
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
2474
2476
|
onFinish?: (response: ApiResponse) => void;
|
|
2475
2477
|
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
package/dist/server/index.mjs
CHANGED
|
@@ -23655,16 +23655,34 @@ async function resumeStream(options) {
|
|
|
23655
23655
|
onData,
|
|
23656
23656
|
onThinking,
|
|
23657
23657
|
onFinish,
|
|
23658
|
-
onError
|
|
23658
|
+
onError,
|
|
23659
|
+
piiRedactor
|
|
23659
23660
|
} = options;
|
|
23660
23661
|
const strategy = getStrategy(handle.apiType);
|
|
23661
23662
|
const accumulator = createStreamAccumulator(handle.model || void 0);
|
|
23663
|
+
const contentDeAnon = piiRedactor && onData ? createStreamingDeAnonymizer(piiRedactor, onData) : null;
|
|
23664
|
+
const thinkingDeAnon = piiRedactor && onThinking ? createStreamingDeAnonymizer(piiRedactor, onThinking) : null;
|
|
23662
23665
|
const contentSmoother = new StreamSmoother((text12) => {
|
|
23663
|
-
if (
|
|
23666
|
+
if (contentDeAnon) contentDeAnon.push(text12);
|
|
23667
|
+
else if (onData) onData(text12);
|
|
23664
23668
|
}, smoothing);
|
|
23665
23669
|
const thinkingSmoother = new StreamSmoother((text12) => {
|
|
23666
|
-
if (
|
|
23670
|
+
if (thinkingDeAnon) thinkingDeAnon.push(text12);
|
|
23671
|
+
else if (onThinking) onThinking(text12);
|
|
23667
23672
|
}, smoothing);
|
|
23673
|
+
const flushOutput = () => {
|
|
23674
|
+
contentSmoother.flush();
|
|
23675
|
+
thinkingSmoother.flush();
|
|
23676
|
+
contentDeAnon?.flush();
|
|
23677
|
+
thinkingDeAnon?.flush();
|
|
23678
|
+
};
|
|
23679
|
+
const buildFinal = () => strategy.buildFinalResponse(
|
|
23680
|
+
piiRedactor ? {
|
|
23681
|
+
...accumulator,
|
|
23682
|
+
content: piiRedactor.deAnonymize(accumulator.content),
|
|
23683
|
+
thinking: piiRedactor.deAnonymize(accumulator.thinking)
|
|
23684
|
+
} : accumulator
|
|
23685
|
+
);
|
|
23668
23686
|
const idleController = new AbortController();
|
|
23669
23687
|
let watchdog;
|
|
23670
23688
|
let idleFired = false;
|
|
@@ -23709,9 +23727,8 @@ async function resumeStream(options) {
|
|
|
23709
23727
|
if (signal) signal.removeEventListener("abort", onCallerAbort);
|
|
23710
23728
|
};
|
|
23711
23729
|
const buildInterrupted = (message) => {
|
|
23712
|
-
|
|
23713
|
-
|
|
23714
|
-
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(strategy.buildFinalResponse(accumulator)) : strategy.buildFinalResponse(accumulator);
|
|
23730
|
+
flushOutput();
|
|
23731
|
+
const data = accumulator.toolCalls.size > 0 ? stripToolCalls(buildFinal()) : buildFinal();
|
|
23715
23732
|
return { data, error: message, interrupted: true };
|
|
23716
23733
|
};
|
|
23717
23734
|
if (combinedSignal.aborted) {
|
|
@@ -23759,18 +23776,16 @@ async function resumeStream(options) {
|
|
|
23759
23776
|
const err = replayErr instanceof Error ? replayErr : new Error(String(replayErr));
|
|
23760
23777
|
const statusCode = parseSseStatusCode(err);
|
|
23761
23778
|
if (statusCode === 410) {
|
|
23762
|
-
|
|
23763
|
-
thinkingSmoother.flush();
|
|
23779
|
+
flushOutput();
|
|
23764
23780
|
throw new StreamExpiredError(handle.inferenceId);
|
|
23765
23781
|
}
|
|
23766
23782
|
if (err.name === "AbortError" || combinedSignal.aborted) {
|
|
23767
23783
|
return buildInterrupted(abortMessage());
|
|
23768
23784
|
}
|
|
23769
|
-
|
|
23770
|
-
thinkingSmoother.flush();
|
|
23785
|
+
flushOutput();
|
|
23771
23786
|
if (onError) onError(err);
|
|
23772
23787
|
return {
|
|
23773
|
-
data:
|
|
23788
|
+
data: buildFinal(),
|
|
23774
23789
|
error: err.message,
|
|
23775
23790
|
interrupted: false,
|
|
23776
23791
|
statusCode
|
|
@@ -23786,7 +23801,9 @@ async function resumeStream(options) {
|
|
|
23786
23801
|
draining = true;
|
|
23787
23802
|
await Promise.all([contentSmoother.drain(), thinkingSmoother.drain()]);
|
|
23788
23803
|
if (playbackAborted) return buildInterrupted(abortMessage());
|
|
23789
|
-
|
|
23804
|
+
contentDeAnon?.flush();
|
|
23805
|
+
thinkingDeAnon?.flush();
|
|
23806
|
+
const response = buildFinal();
|
|
23790
23807
|
const deliveredOutput = emittedOutput || (accumulator.toolCallEvents?.length ?? 0) > 0;
|
|
23791
23808
|
if (onFinish && deliveredOutput) onFinish(response);
|
|
23792
23809
|
return { data: response, error: null, interrupted: false, empty: !deliveredOutput };
|