@anuma/sdk 6.39.1 → 6.39.3
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 +109 -2
- package/dist/expo/index.d.mts +129 -6
- package/dist/expo/index.d.ts +129 -6
- package/dist/expo/index.mjs +109 -2
- package/dist/react/index.cjs +109 -2
- package/dist/react/index.d.mts +129 -6
- package/dist/react/index.d.ts +129 -6
- package/dist/react/index.mjs +109 -2
- package/dist/server/index.cjs +104 -2
- package/dist/server/index.d.mts +10 -6
- package/dist/server/index.d.ts +10 -6
- package/dist/server/index.mjs +104 -2
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -8741,6 +8741,93 @@ function composeHooks(hooks) {
|
|
|
8741
8741
|
};
|
|
8742
8742
|
}
|
|
8743
8743
|
|
|
8744
|
+
// src/lib/chat/streamIdleTimeout.ts
|
|
8745
|
+
var StreamIdleTimeoutError = class extends Error {
|
|
8746
|
+
constructor(idleTimeoutMs) {
|
|
8747
|
+
super(`Stream timed out after ${idleTimeoutMs} ms without activity.`);
|
|
8748
|
+
this.name = "StreamIdleTimeoutError";
|
|
8749
|
+
this.idleTimeoutMs = idleTimeoutMs;
|
|
8750
|
+
}
|
|
8751
|
+
};
|
|
8752
|
+
function withStreamIdleTimeout(transport, idleTimeoutMs) {
|
|
8753
|
+
if (!(idleTimeoutMs > 0) || idleTimeoutMs === Infinity) return transport;
|
|
8754
|
+
return (options) => ({
|
|
8755
|
+
stream: (async function* () {
|
|
8756
|
+
const controller = new AbortController();
|
|
8757
|
+
let timer;
|
|
8758
|
+
let settled = false;
|
|
8759
|
+
let completed = false;
|
|
8760
|
+
let iterator;
|
|
8761
|
+
let interruption;
|
|
8762
|
+
let rejectPending;
|
|
8763
|
+
const disarm = () => {
|
|
8764
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
8765
|
+
timer = void 0;
|
|
8766
|
+
};
|
|
8767
|
+
const interrupt = (error) => {
|
|
8768
|
+
if (interruption) return;
|
|
8769
|
+
interruption = error;
|
|
8770
|
+
rejectPending?.(error);
|
|
8771
|
+
controller.abort();
|
|
8772
|
+
};
|
|
8773
|
+
const arm = () => {
|
|
8774
|
+
if (settled || controller.signal.aborted) return;
|
|
8775
|
+
disarm();
|
|
8776
|
+
timer = setTimeout(() => {
|
|
8777
|
+
interrupt(new StreamIdleTimeoutError(idleTimeoutMs));
|
|
8778
|
+
}, idleTimeoutMs);
|
|
8779
|
+
};
|
|
8780
|
+
const onAbort = () => {
|
|
8781
|
+
controller.abort();
|
|
8782
|
+
};
|
|
8783
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
8784
|
+
try {
|
|
8785
|
+
if (options.signal?.aborted) {
|
|
8786
|
+
const error = new Error("Request aborted");
|
|
8787
|
+
error.name = "AbortError";
|
|
8788
|
+
throw error;
|
|
8789
|
+
}
|
|
8790
|
+
arm();
|
|
8791
|
+
iterator = transport({
|
|
8792
|
+
...options,
|
|
8793
|
+
signal: controller.signal,
|
|
8794
|
+
onActivity: () => {
|
|
8795
|
+
arm();
|
|
8796
|
+
options.onActivity?.();
|
|
8797
|
+
}
|
|
8798
|
+
}).stream[Symbol.asyncIterator]();
|
|
8799
|
+
while (true) {
|
|
8800
|
+
if (interruption) throw interruption;
|
|
8801
|
+
const next = await new Promise((resolve, reject) => {
|
|
8802
|
+
rejectPending = reject;
|
|
8803
|
+
Promise.resolve(iterator.next()).then(resolve, reject);
|
|
8804
|
+
});
|
|
8805
|
+
rejectPending = void 0;
|
|
8806
|
+
if (next.done) {
|
|
8807
|
+
completed = true;
|
|
8808
|
+
break;
|
|
8809
|
+
}
|
|
8810
|
+
arm();
|
|
8811
|
+
yield next.value;
|
|
8812
|
+
}
|
|
8813
|
+
} finally {
|
|
8814
|
+
settled = true;
|
|
8815
|
+
rejectPending = void 0;
|
|
8816
|
+
disarm();
|
|
8817
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
8818
|
+
if (!completed) {
|
|
8819
|
+
controller.abort();
|
|
8820
|
+
try {
|
|
8821
|
+
void iterator?.return?.().catch(() => {
|
|
8822
|
+
});
|
|
8823
|
+
} catch {
|
|
8824
|
+
}
|
|
8825
|
+
}
|
|
8826
|
+
}
|
|
8827
|
+
})()
|
|
8828
|
+
});
|
|
8829
|
+
}
|
|
8830
|
+
|
|
8744
8831
|
// src/lib/chat/useChat/utils.ts
|
|
8745
8832
|
var import_jsonrepair = require("jsonrepair");
|
|
8746
8833
|
init_logger();
|
|
@@ -10931,7 +11018,20 @@ var defaultTransport = (options) => {
|
|
|
10931
11018
|
} catch {
|
|
10932
11019
|
}
|
|
10933
11020
|
}
|
|
10934
|
-
return response;
|
|
11021
|
+
if (!response.body || !options.onActivity) return response;
|
|
11022
|
+
const body = response.body.pipeThrough(
|
|
11023
|
+
new TransformStream({
|
|
11024
|
+
transform(chunk, controller) {
|
|
11025
|
+
if (chunk.byteLength > 0) options.onActivity?.();
|
|
11026
|
+
controller.enqueue(chunk);
|
|
11027
|
+
}
|
|
11028
|
+
})
|
|
11029
|
+
);
|
|
11030
|
+
return new Response(body, {
|
|
11031
|
+
status: response.status,
|
|
11032
|
+
statusText: response.statusText,
|
|
11033
|
+
headers: response.headers
|
|
11034
|
+
});
|
|
10935
11035
|
};
|
|
10936
11036
|
return createSseClient({
|
|
10937
11037
|
method: options.method ?? "POST",
|
|
@@ -10988,6 +11088,7 @@ async function runToolLoop(options) {
|
|
|
10988
11088
|
conversationId,
|
|
10989
11089
|
smoothing,
|
|
10990
11090
|
signal,
|
|
11091
|
+
idleTimeoutMs = 12e4,
|
|
10991
11092
|
resumable,
|
|
10992
11093
|
detachSignal,
|
|
10993
11094
|
onStreamMeta,
|
|
@@ -11001,13 +11102,14 @@ async function runToolLoop(options) {
|
|
|
11001
11102
|
onStepFinish,
|
|
11002
11103
|
onRequest,
|
|
11003
11104
|
onStreamRetry,
|
|
11004
|
-
transport
|
|
11105
|
+
transport = defaultTransport,
|
|
11005
11106
|
preProcessors,
|
|
11006
11107
|
maxConnectorCalls = 2,
|
|
11007
11108
|
hooks: hooksOption,
|
|
11008
11109
|
piiRedaction,
|
|
11009
11110
|
onPiiRedacted
|
|
11010
11111
|
} = options;
|
|
11112
|
+
const makeStreamingRequest = withStreamIdleTimeout(transport, idleTimeoutMs);
|
|
11011
11113
|
const hooks = Array.isArray(hooksOption) ? composeHooks(hooksOption) : hooksOption;
|
|
11012
11114
|
const runId = generateRunId();
|
|
11013
11115
|
let messages = options.messages;
|
|
@@ -32345,6 +32447,7 @@ function useChat(options) {
|
|
|
32345
32447
|
apiType: defaultApiType = "auto",
|
|
32346
32448
|
smoothing,
|
|
32347
32449
|
preProcessors,
|
|
32450
|
+
hooks,
|
|
32348
32451
|
piiRedaction,
|
|
32349
32452
|
onPiiRedacted
|
|
32350
32453
|
} = options || {};
|
|
@@ -32516,6 +32619,7 @@ function useChat(options) {
|
|
|
32516
32619
|
onToolCallArgumentsDelta,
|
|
32517
32620
|
onStepFinish,
|
|
32518
32621
|
preProcessors,
|
|
32622
|
+
hooks,
|
|
32519
32623
|
piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
|
|
32520
32624
|
onPiiRedacted
|
|
32521
32625
|
});
|
|
@@ -32553,6 +32657,7 @@ function useChat(options) {
|
|
|
32553
32657
|
defaultApiType,
|
|
32554
32658
|
smoothing,
|
|
32555
32659
|
preProcessors,
|
|
32660
|
+
hooks,
|
|
32556
32661
|
resolvedPiiRedaction,
|
|
32557
32662
|
onPiiRedacted
|
|
32558
32663
|
]
|
|
@@ -33767,6 +33872,7 @@ function useChatStorage(options) {
|
|
|
33767
33872
|
minContentLength = DEFAULT_MIN_CONTENT_LENGTH,
|
|
33768
33873
|
mcpR2Domain = MCP_R2_DOMAIN,
|
|
33769
33874
|
preProcessors,
|
|
33875
|
+
hooks,
|
|
33770
33876
|
smoothing,
|
|
33771
33877
|
piiRedaction,
|
|
33772
33878
|
onPiiRedacted,
|
|
@@ -34341,6 +34447,7 @@ function useChatStorage(options) {
|
|
|
34341
34447
|
onStreamMeta,
|
|
34342
34448
|
apiType,
|
|
34343
34449
|
preProcessors,
|
|
34450
|
+
hooks,
|
|
34344
34451
|
smoothing,
|
|
34345
34452
|
piiRedaction: resolvedPiiRedaction,
|
|
34346
34453
|
onPiiRedacted
|
package/dist/react/index.d.mts
CHANGED
|
@@ -2706,6 +2706,127 @@ declare class PiiRedactor {
|
|
|
2706
2706
|
clear(): void;
|
|
2707
2707
|
}
|
|
2708
2708
|
|
|
2709
|
+
type LlmTokenUsage = {
|
|
2710
|
+
inputTokens?: number;
|
|
2711
|
+
outputTokens?: number;
|
|
2712
|
+
};
|
|
2713
|
+
type ModelCallStartEvent = {
|
|
2714
|
+
runId: string;
|
|
2715
|
+
stepIndex: number;
|
|
2716
|
+
model: string;
|
|
2717
|
+
messages: Array<LlmapiMessage>;
|
|
2718
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2719
|
+
requestBody: Record<string, unknown>;
|
|
2720
|
+
};
|
|
2721
|
+
type ModelCallEndEvent = {
|
|
2722
|
+
runId: string;
|
|
2723
|
+
stepIndex: number;
|
|
2724
|
+
content: string;
|
|
2725
|
+
toolCalls: Array<{
|
|
2726
|
+
id: string;
|
|
2727
|
+
name: string;
|
|
2728
|
+
arguments: string;
|
|
2729
|
+
}>;
|
|
2730
|
+
usage?: LlmTokenUsage;
|
|
2731
|
+
finishReason?: string;
|
|
2732
|
+
error?: string;
|
|
2733
|
+
};
|
|
2734
|
+
type ToolUseStartEvent = {
|
|
2735
|
+
runId: string;
|
|
2736
|
+
stepIndex: number;
|
|
2737
|
+
toolCallId: string;
|
|
2738
|
+
name: string;
|
|
2739
|
+
rawArguments: string;
|
|
2740
|
+
parsedArguments?: Record<string, unknown>;
|
|
2741
|
+
};
|
|
2742
|
+
type ToolUseEndEvent = {
|
|
2743
|
+
runId: string;
|
|
2744
|
+
stepIndex: number;
|
|
2745
|
+
toolCallId: string;
|
|
2746
|
+
name: string;
|
|
2747
|
+
result?: unknown;
|
|
2748
|
+
error?: string;
|
|
2749
|
+
errorType?: "parse" | "timeout" | "execution" | "cancelled";
|
|
2750
|
+
};
|
|
2751
|
+
type RunStartEvent = {
|
|
2752
|
+
runId: string;
|
|
2753
|
+
model: string;
|
|
2754
|
+
messages: Array<LlmapiMessage>;
|
|
2755
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2756
|
+
};
|
|
2757
|
+
type RunEndEvent = {
|
|
2758
|
+
runId: string;
|
|
2759
|
+
finalContent: string;
|
|
2760
|
+
/** Number of LLM rounds executed. */
|
|
2761
|
+
totalSteps: number;
|
|
2762
|
+
};
|
|
2763
|
+
type RunErrorEvent = {
|
|
2764
|
+
runId: string;
|
|
2765
|
+
error: string;
|
|
2766
|
+
/**
|
|
2767
|
+
* Only `"model"` today. Tool failures surface on {@link RunHooks.afterToolUse}
|
|
2768
|
+
* with `errorType`, not on `onRunError`, so a tool stage isn't needed yet.
|
|
2769
|
+
* Left as a union to leave room for `"validation"` or `"tool"` later
|
|
2770
|
+
* without a breaking change.
|
|
2771
|
+
*/
|
|
2772
|
+
stage: "model";
|
|
2773
|
+
/**
|
|
2774
|
+
* The underlying `Error` when one is available. `RunErrorEvent` predates
|
|
2775
|
+
* this field, so `error` (a string message) is kept for backwards
|
|
2776
|
+
* compatibility; new consumers should prefer `errorObject` when present
|
|
2777
|
+
* for stack traces and `cause`.
|
|
2778
|
+
*/
|
|
2779
|
+
errorObject?: Error;
|
|
2780
|
+
};
|
|
2781
|
+
type RunHooks = {
|
|
2782
|
+
/**
|
|
2783
|
+
* Fires once per `runToolLoop` invocation, before any pre-processor or
|
|
2784
|
+
* model call. The `messages` payload is the raw caller-supplied
|
|
2785
|
+
* conversation — pre-processors that enrich it (e.g. web search context)
|
|
2786
|
+
* run afterwards, so `beforeModelCall.messages` reflects the
|
|
2787
|
+
* post-enrichment state.
|
|
2788
|
+
*/
|
|
2789
|
+
onRunStart?: (e: RunStartEvent) => Promise<void> | void;
|
|
2790
|
+
/**
|
|
2791
|
+
* Fires exactly once per run on clean completion. Mutually exclusive
|
|
2792
|
+
* with `onRunError` — a run that completes fires `onRunEnd`; a run that
|
|
2793
|
+
* errors or is aborted fires `onRunError`. Consumers can rely on
|
|
2794
|
+
* exactly one terminal hook per `onRunStart`.
|
|
2795
|
+
*/
|
|
2796
|
+
onRunEnd?: (e: RunEndEvent) => Promise<void> | void;
|
|
2797
|
+
/**
|
|
2798
|
+
* Fires exactly once per run when the loop errors or is aborted.
|
|
2799
|
+
* `stage` is `"model"` for stream/provider errors and for aborts;
|
|
2800
|
+
* tool execution failures surface as structured `{ error, errorType }`
|
|
2801
|
+
* results on `afterToolUse` rather than firing `onRunError`.
|
|
2802
|
+
* Mutually exclusive with `onRunEnd`.
|
|
2803
|
+
*/
|
|
2804
|
+
onRunError?: (e: RunErrorEvent) => Promise<void> | void;
|
|
2805
|
+
beforeModelCall?: (e: ModelCallStartEvent) => Promise<void> | void;
|
|
2806
|
+
afterModelCall?: (e: ModelCallEndEvent) => Promise<void> | void;
|
|
2807
|
+
/**
|
|
2808
|
+
* Fires before each tool the model invoked — including server-side
|
|
2809
|
+
* tools that have no client executor. Today this is observe-only.
|
|
2810
|
+
* TODO(follow-up PR): allow returning { args?, abort?: { reason } } to
|
|
2811
|
+
* mutate arguments or short-circuit the tool call.
|
|
2812
|
+
*
|
|
2813
|
+
* Pairing with {@link afterToolUse} is asymmetric: server-side tools
|
|
2814
|
+
* routed via `onToolCall` get `beforeToolUse` but no `afterToolUse`,
|
|
2815
|
+
* because they don't execute in-process. Tools blocked by a failed
|
|
2816
|
+
* dependency or a dependency cycle DO get `afterToolUse` with
|
|
2817
|
+
* `errorType: "execution"` — consumers tallying matched pairs should
|
|
2818
|
+
* filter on executor-backed tools to avoid spurious imbalances.
|
|
2819
|
+
*/
|
|
2820
|
+
beforeToolUse?: (e: ToolUseStartEvent) => Promise<void> | void;
|
|
2821
|
+
/**
|
|
2822
|
+
* Fires after each executor-backed tool finishes (success or failure)
|
|
2823
|
+
* and after each dependency-blocked tool is skipped (`errorType:
|
|
2824
|
+
* "execution"`). Does NOT fire for server-side tools routed via
|
|
2825
|
+
* `onToolCall`. See {@link beforeToolUse} for the pairing contract.
|
|
2826
|
+
*/
|
|
2827
|
+
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
2828
|
+
};
|
|
2829
|
+
|
|
2709
2830
|
/**
|
|
2710
2831
|
* Configuration for stream output smoothing.
|
|
2711
2832
|
*
|
|
@@ -2900,6 +3021,8 @@ type BaseSendMessageArgs = ResponsesApiOptions & {
|
|
|
2900
3021
|
type BaseUseChatOptions = {
|
|
2901
3022
|
getToken?: () => Promise<string | null>;
|
|
2902
3023
|
baseUrl?: string;
|
|
3024
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
3025
|
+
hooks?: RunHooks | RunHooks[];
|
|
2903
3026
|
/**
|
|
2904
3027
|
* Callback function to be called when a new data chunk is received.
|
|
2905
3028
|
*/
|
|
@@ -3124,12 +3247,10 @@ type StreamingTransportOptions = {
|
|
|
3124
3247
|
inferenceId: string;
|
|
3125
3248
|
}) => void;
|
|
3126
3249
|
/**
|
|
3127
|
-
* Fires
|
|
3128
|
-
*
|
|
3129
|
-
*
|
|
3130
|
-
*
|
|
3131
|
-
* apart from a dead connection (no bytes at all). Not every transport emits it
|
|
3132
|
-
* — the xhr transport does; treat its absence as "no extra liveness info".
|
|
3250
|
+
* Fires when the transport receives bytes, including SSE keep-alive comments.
|
|
3251
|
+
* Consumers can use this callback to reset the idle timeout.
|
|
3252
|
+
* The fetch and XHR transports emit it.
|
|
3253
|
+
* Custom transports can omit it if they cannot report byte activity.
|
|
3133
3254
|
*/
|
|
3134
3255
|
onActivity?: () => void;
|
|
3135
3256
|
};
|
|
@@ -8691,6 +8812,8 @@ interface CreateConversationOptions {
|
|
|
8691
8812
|
* @inline
|
|
8692
8813
|
*/
|
|
8693
8814
|
interface BaseUseChatStorageOptions {
|
|
8815
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
8816
|
+
hooks?: RunHooks | RunHooks[];
|
|
8694
8817
|
/** WatermelonDB database instance for storing conversations and messages */
|
|
8695
8818
|
database: Database;
|
|
8696
8819
|
/** Route memory reads, writes, recall and the memory tools through this store instead of the database's vault; folders are unsupported. With `piiRedaction` on, build the store with `embeddingOptions.maskInput` (e.g. `(text) => redactor.maskText(text)` with any `PiiRedactor`) or its memory calls throw. */
|
package/dist/react/index.d.ts
CHANGED
|
@@ -2706,6 +2706,127 @@ declare class PiiRedactor {
|
|
|
2706
2706
|
clear(): void;
|
|
2707
2707
|
}
|
|
2708
2708
|
|
|
2709
|
+
type LlmTokenUsage = {
|
|
2710
|
+
inputTokens?: number;
|
|
2711
|
+
outputTokens?: number;
|
|
2712
|
+
};
|
|
2713
|
+
type ModelCallStartEvent = {
|
|
2714
|
+
runId: string;
|
|
2715
|
+
stepIndex: number;
|
|
2716
|
+
model: string;
|
|
2717
|
+
messages: Array<LlmapiMessage>;
|
|
2718
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2719
|
+
requestBody: Record<string, unknown>;
|
|
2720
|
+
};
|
|
2721
|
+
type ModelCallEndEvent = {
|
|
2722
|
+
runId: string;
|
|
2723
|
+
stepIndex: number;
|
|
2724
|
+
content: string;
|
|
2725
|
+
toolCalls: Array<{
|
|
2726
|
+
id: string;
|
|
2727
|
+
name: string;
|
|
2728
|
+
arguments: string;
|
|
2729
|
+
}>;
|
|
2730
|
+
usage?: LlmTokenUsage;
|
|
2731
|
+
finishReason?: string;
|
|
2732
|
+
error?: string;
|
|
2733
|
+
};
|
|
2734
|
+
type ToolUseStartEvent = {
|
|
2735
|
+
runId: string;
|
|
2736
|
+
stepIndex: number;
|
|
2737
|
+
toolCallId: string;
|
|
2738
|
+
name: string;
|
|
2739
|
+
rawArguments: string;
|
|
2740
|
+
parsedArguments?: Record<string, unknown>;
|
|
2741
|
+
};
|
|
2742
|
+
type ToolUseEndEvent = {
|
|
2743
|
+
runId: string;
|
|
2744
|
+
stepIndex: number;
|
|
2745
|
+
toolCallId: string;
|
|
2746
|
+
name: string;
|
|
2747
|
+
result?: unknown;
|
|
2748
|
+
error?: string;
|
|
2749
|
+
errorType?: "parse" | "timeout" | "execution" | "cancelled";
|
|
2750
|
+
};
|
|
2751
|
+
type RunStartEvent = {
|
|
2752
|
+
runId: string;
|
|
2753
|
+
model: string;
|
|
2754
|
+
messages: Array<LlmapiMessage>;
|
|
2755
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2756
|
+
};
|
|
2757
|
+
type RunEndEvent = {
|
|
2758
|
+
runId: string;
|
|
2759
|
+
finalContent: string;
|
|
2760
|
+
/** Number of LLM rounds executed. */
|
|
2761
|
+
totalSteps: number;
|
|
2762
|
+
};
|
|
2763
|
+
type RunErrorEvent = {
|
|
2764
|
+
runId: string;
|
|
2765
|
+
error: string;
|
|
2766
|
+
/**
|
|
2767
|
+
* Only `"model"` today. Tool failures surface on {@link RunHooks.afterToolUse}
|
|
2768
|
+
* with `errorType`, not on `onRunError`, so a tool stage isn't needed yet.
|
|
2769
|
+
* Left as a union to leave room for `"validation"` or `"tool"` later
|
|
2770
|
+
* without a breaking change.
|
|
2771
|
+
*/
|
|
2772
|
+
stage: "model";
|
|
2773
|
+
/**
|
|
2774
|
+
* The underlying `Error` when one is available. `RunErrorEvent` predates
|
|
2775
|
+
* this field, so `error` (a string message) is kept for backwards
|
|
2776
|
+
* compatibility; new consumers should prefer `errorObject` when present
|
|
2777
|
+
* for stack traces and `cause`.
|
|
2778
|
+
*/
|
|
2779
|
+
errorObject?: Error;
|
|
2780
|
+
};
|
|
2781
|
+
type RunHooks = {
|
|
2782
|
+
/**
|
|
2783
|
+
* Fires once per `runToolLoop` invocation, before any pre-processor or
|
|
2784
|
+
* model call. The `messages` payload is the raw caller-supplied
|
|
2785
|
+
* conversation — pre-processors that enrich it (e.g. web search context)
|
|
2786
|
+
* run afterwards, so `beforeModelCall.messages` reflects the
|
|
2787
|
+
* post-enrichment state.
|
|
2788
|
+
*/
|
|
2789
|
+
onRunStart?: (e: RunStartEvent) => Promise<void> | void;
|
|
2790
|
+
/**
|
|
2791
|
+
* Fires exactly once per run on clean completion. Mutually exclusive
|
|
2792
|
+
* with `onRunError` — a run that completes fires `onRunEnd`; a run that
|
|
2793
|
+
* errors or is aborted fires `onRunError`. Consumers can rely on
|
|
2794
|
+
* exactly one terminal hook per `onRunStart`.
|
|
2795
|
+
*/
|
|
2796
|
+
onRunEnd?: (e: RunEndEvent) => Promise<void> | void;
|
|
2797
|
+
/**
|
|
2798
|
+
* Fires exactly once per run when the loop errors or is aborted.
|
|
2799
|
+
* `stage` is `"model"` for stream/provider errors and for aborts;
|
|
2800
|
+
* tool execution failures surface as structured `{ error, errorType }`
|
|
2801
|
+
* results on `afterToolUse` rather than firing `onRunError`.
|
|
2802
|
+
* Mutually exclusive with `onRunEnd`.
|
|
2803
|
+
*/
|
|
2804
|
+
onRunError?: (e: RunErrorEvent) => Promise<void> | void;
|
|
2805
|
+
beforeModelCall?: (e: ModelCallStartEvent) => Promise<void> | void;
|
|
2806
|
+
afterModelCall?: (e: ModelCallEndEvent) => Promise<void> | void;
|
|
2807
|
+
/**
|
|
2808
|
+
* Fires before each tool the model invoked — including server-side
|
|
2809
|
+
* tools that have no client executor. Today this is observe-only.
|
|
2810
|
+
* TODO(follow-up PR): allow returning { args?, abort?: { reason } } to
|
|
2811
|
+
* mutate arguments or short-circuit the tool call.
|
|
2812
|
+
*
|
|
2813
|
+
* Pairing with {@link afterToolUse} is asymmetric: server-side tools
|
|
2814
|
+
* routed via `onToolCall` get `beforeToolUse` but no `afterToolUse`,
|
|
2815
|
+
* because they don't execute in-process. Tools blocked by a failed
|
|
2816
|
+
* dependency or a dependency cycle DO get `afterToolUse` with
|
|
2817
|
+
* `errorType: "execution"` — consumers tallying matched pairs should
|
|
2818
|
+
* filter on executor-backed tools to avoid spurious imbalances.
|
|
2819
|
+
*/
|
|
2820
|
+
beforeToolUse?: (e: ToolUseStartEvent) => Promise<void> | void;
|
|
2821
|
+
/**
|
|
2822
|
+
* Fires after each executor-backed tool finishes (success or failure)
|
|
2823
|
+
* and after each dependency-blocked tool is skipped (`errorType:
|
|
2824
|
+
* "execution"`). Does NOT fire for server-side tools routed via
|
|
2825
|
+
* `onToolCall`. See {@link beforeToolUse} for the pairing contract.
|
|
2826
|
+
*/
|
|
2827
|
+
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
2828
|
+
};
|
|
2829
|
+
|
|
2709
2830
|
/**
|
|
2710
2831
|
* Configuration for stream output smoothing.
|
|
2711
2832
|
*
|
|
@@ -2900,6 +3021,8 @@ type BaseSendMessageArgs = ResponsesApiOptions & {
|
|
|
2900
3021
|
type BaseUseChatOptions = {
|
|
2901
3022
|
getToken?: () => Promise<string | null>;
|
|
2902
3023
|
baseUrl?: string;
|
|
3024
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
3025
|
+
hooks?: RunHooks | RunHooks[];
|
|
2903
3026
|
/**
|
|
2904
3027
|
* Callback function to be called when a new data chunk is received.
|
|
2905
3028
|
*/
|
|
@@ -3124,12 +3247,10 @@ type StreamingTransportOptions = {
|
|
|
3124
3247
|
inferenceId: string;
|
|
3125
3248
|
}) => void;
|
|
3126
3249
|
/**
|
|
3127
|
-
* Fires
|
|
3128
|
-
*
|
|
3129
|
-
*
|
|
3130
|
-
*
|
|
3131
|
-
* apart from a dead connection (no bytes at all). Not every transport emits it
|
|
3132
|
-
* — the xhr transport does; treat its absence as "no extra liveness info".
|
|
3250
|
+
* Fires when the transport receives bytes, including SSE keep-alive comments.
|
|
3251
|
+
* Consumers can use this callback to reset the idle timeout.
|
|
3252
|
+
* The fetch and XHR transports emit it.
|
|
3253
|
+
* Custom transports can omit it if they cannot report byte activity.
|
|
3133
3254
|
*/
|
|
3134
3255
|
onActivity?: () => void;
|
|
3135
3256
|
};
|
|
@@ -8691,6 +8812,8 @@ interface CreateConversationOptions {
|
|
|
8691
8812
|
* @inline
|
|
8692
8813
|
*/
|
|
8693
8814
|
interface BaseUseChatStorageOptions {
|
|
8815
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
8816
|
+
hooks?: RunHooks | RunHooks[];
|
|
8694
8817
|
/** WatermelonDB database instance for storing conversations and messages */
|
|
8695
8818
|
database: Database;
|
|
8696
8819
|
/** Route memory reads, writes, recall and the memory tools through this store instead of the database's vault; folders are unsupported. With `piiRedaction` on, build the store with `embeddingOptions.maskInput` (e.g. `(text) => redactor.maskText(text)` with any `PiiRedactor`) or its memory calls throw. */
|
package/dist/react/index.mjs
CHANGED
|
@@ -6889,6 +6889,93 @@ function composeHooks(hooks) {
|
|
|
6889
6889
|
};
|
|
6890
6890
|
}
|
|
6891
6891
|
|
|
6892
|
+
// src/lib/chat/streamIdleTimeout.ts
|
|
6893
|
+
var StreamIdleTimeoutError = class extends Error {
|
|
6894
|
+
constructor(idleTimeoutMs) {
|
|
6895
|
+
super(`Stream timed out after ${idleTimeoutMs} ms without activity.`);
|
|
6896
|
+
this.name = "StreamIdleTimeoutError";
|
|
6897
|
+
this.idleTimeoutMs = idleTimeoutMs;
|
|
6898
|
+
}
|
|
6899
|
+
};
|
|
6900
|
+
function withStreamIdleTimeout(transport, idleTimeoutMs) {
|
|
6901
|
+
if (!(idleTimeoutMs > 0) || idleTimeoutMs === Infinity) return transport;
|
|
6902
|
+
return (options) => ({
|
|
6903
|
+
stream: (async function* () {
|
|
6904
|
+
const controller = new AbortController();
|
|
6905
|
+
let timer;
|
|
6906
|
+
let settled = false;
|
|
6907
|
+
let completed = false;
|
|
6908
|
+
let iterator;
|
|
6909
|
+
let interruption;
|
|
6910
|
+
let rejectPending;
|
|
6911
|
+
const disarm = () => {
|
|
6912
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
6913
|
+
timer = void 0;
|
|
6914
|
+
};
|
|
6915
|
+
const interrupt = (error) => {
|
|
6916
|
+
if (interruption) return;
|
|
6917
|
+
interruption = error;
|
|
6918
|
+
rejectPending?.(error);
|
|
6919
|
+
controller.abort();
|
|
6920
|
+
};
|
|
6921
|
+
const arm = () => {
|
|
6922
|
+
if (settled || controller.signal.aborted) return;
|
|
6923
|
+
disarm();
|
|
6924
|
+
timer = setTimeout(() => {
|
|
6925
|
+
interrupt(new StreamIdleTimeoutError(idleTimeoutMs));
|
|
6926
|
+
}, idleTimeoutMs);
|
|
6927
|
+
};
|
|
6928
|
+
const onAbort = () => {
|
|
6929
|
+
controller.abort();
|
|
6930
|
+
};
|
|
6931
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
6932
|
+
try {
|
|
6933
|
+
if (options.signal?.aborted) {
|
|
6934
|
+
const error = new Error("Request aborted");
|
|
6935
|
+
error.name = "AbortError";
|
|
6936
|
+
throw error;
|
|
6937
|
+
}
|
|
6938
|
+
arm();
|
|
6939
|
+
iterator = transport({
|
|
6940
|
+
...options,
|
|
6941
|
+
signal: controller.signal,
|
|
6942
|
+
onActivity: () => {
|
|
6943
|
+
arm();
|
|
6944
|
+
options.onActivity?.();
|
|
6945
|
+
}
|
|
6946
|
+
}).stream[Symbol.asyncIterator]();
|
|
6947
|
+
while (true) {
|
|
6948
|
+
if (interruption) throw interruption;
|
|
6949
|
+
const next = await new Promise((resolve, reject) => {
|
|
6950
|
+
rejectPending = reject;
|
|
6951
|
+
Promise.resolve(iterator.next()).then(resolve, reject);
|
|
6952
|
+
});
|
|
6953
|
+
rejectPending = void 0;
|
|
6954
|
+
if (next.done) {
|
|
6955
|
+
completed = true;
|
|
6956
|
+
break;
|
|
6957
|
+
}
|
|
6958
|
+
arm();
|
|
6959
|
+
yield next.value;
|
|
6960
|
+
}
|
|
6961
|
+
} finally {
|
|
6962
|
+
settled = true;
|
|
6963
|
+
rejectPending = void 0;
|
|
6964
|
+
disarm();
|
|
6965
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
6966
|
+
if (!completed) {
|
|
6967
|
+
controller.abort();
|
|
6968
|
+
try {
|
|
6969
|
+
void iterator?.return?.().catch(() => {
|
|
6970
|
+
});
|
|
6971
|
+
} catch {
|
|
6972
|
+
}
|
|
6973
|
+
}
|
|
6974
|
+
}
|
|
6975
|
+
})()
|
|
6976
|
+
});
|
|
6977
|
+
}
|
|
6978
|
+
|
|
6892
6979
|
// src/lib/chat/useChat/utils.ts
|
|
6893
6980
|
import { jsonrepair } from "jsonrepair";
|
|
6894
6981
|
function parseToolArguments(raw) {
|
|
@@ -9078,7 +9165,20 @@ var defaultTransport = (options) => {
|
|
|
9078
9165
|
} catch {
|
|
9079
9166
|
}
|
|
9080
9167
|
}
|
|
9081
|
-
return response;
|
|
9168
|
+
if (!response.body || !options.onActivity) return response;
|
|
9169
|
+
const body = response.body.pipeThrough(
|
|
9170
|
+
new TransformStream({
|
|
9171
|
+
transform(chunk, controller) {
|
|
9172
|
+
if (chunk.byteLength > 0) options.onActivity?.();
|
|
9173
|
+
controller.enqueue(chunk);
|
|
9174
|
+
}
|
|
9175
|
+
})
|
|
9176
|
+
);
|
|
9177
|
+
return new Response(body, {
|
|
9178
|
+
status: response.status,
|
|
9179
|
+
statusText: response.statusText,
|
|
9180
|
+
headers: response.headers
|
|
9181
|
+
});
|
|
9082
9182
|
};
|
|
9083
9183
|
return createSseClient({
|
|
9084
9184
|
method: options.method ?? "POST",
|
|
@@ -9135,6 +9235,7 @@ async function runToolLoop(options) {
|
|
|
9135
9235
|
conversationId,
|
|
9136
9236
|
smoothing,
|
|
9137
9237
|
signal,
|
|
9238
|
+
idleTimeoutMs = 12e4,
|
|
9138
9239
|
resumable,
|
|
9139
9240
|
detachSignal,
|
|
9140
9241
|
onStreamMeta,
|
|
@@ -9148,13 +9249,14 @@ async function runToolLoop(options) {
|
|
|
9148
9249
|
onStepFinish,
|
|
9149
9250
|
onRequest,
|
|
9150
9251
|
onStreamRetry,
|
|
9151
|
-
transport
|
|
9252
|
+
transport = defaultTransport,
|
|
9152
9253
|
preProcessors,
|
|
9153
9254
|
maxConnectorCalls = 2,
|
|
9154
9255
|
hooks: hooksOption,
|
|
9155
9256
|
piiRedaction,
|
|
9156
9257
|
onPiiRedacted
|
|
9157
9258
|
} = options;
|
|
9259
|
+
const makeStreamingRequest = withStreamIdleTimeout(transport, idleTimeoutMs);
|
|
9158
9260
|
const hooks = Array.isArray(hooksOption) ? composeHooks(hooksOption) : hooksOption;
|
|
9159
9261
|
const runId = generateRunId();
|
|
9160
9262
|
let messages = options.messages;
|
|
@@ -30435,6 +30537,7 @@ function useChat(options) {
|
|
|
30435
30537
|
apiType: defaultApiType = "auto",
|
|
30436
30538
|
smoothing,
|
|
30437
30539
|
preProcessors,
|
|
30540
|
+
hooks,
|
|
30438
30541
|
piiRedaction,
|
|
30439
30542
|
onPiiRedacted
|
|
30440
30543
|
} = options || {};
|
|
@@ -30606,6 +30709,7 @@ function useChat(options) {
|
|
|
30606
30709
|
onToolCallArgumentsDelta,
|
|
30607
30710
|
onStepFinish,
|
|
30608
30711
|
preProcessors,
|
|
30712
|
+
hooks,
|
|
30609
30713
|
piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
|
|
30610
30714
|
onPiiRedacted
|
|
30611
30715
|
});
|
|
@@ -30643,6 +30747,7 @@ function useChat(options) {
|
|
|
30643
30747
|
defaultApiType,
|
|
30644
30748
|
smoothing,
|
|
30645
30749
|
preProcessors,
|
|
30750
|
+
hooks,
|
|
30646
30751
|
resolvedPiiRedaction,
|
|
30647
30752
|
onPiiRedacted
|
|
30648
30753
|
]
|
|
@@ -31847,6 +31952,7 @@ function useChatStorage(options) {
|
|
|
31847
31952
|
minContentLength = DEFAULT_MIN_CONTENT_LENGTH,
|
|
31848
31953
|
mcpR2Domain = MCP_R2_DOMAIN,
|
|
31849
31954
|
preProcessors,
|
|
31955
|
+
hooks,
|
|
31850
31956
|
smoothing,
|
|
31851
31957
|
piiRedaction,
|
|
31852
31958
|
onPiiRedacted,
|
|
@@ -32421,6 +32527,7 @@ function useChatStorage(options) {
|
|
|
32421
32527
|
onStreamMeta,
|
|
32422
32528
|
apiType,
|
|
32423
32529
|
preProcessors,
|
|
32530
|
+
hooks,
|
|
32424
32531
|
smoothing,
|
|
32425
32532
|
piiRedaction: resolvedPiiRedaction,
|
|
32426
32533
|
onPiiRedacted
|