@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/expo/index.cjs
CHANGED
|
@@ -6702,6 +6702,93 @@ function composeHooks(hooks) {
|
|
|
6702
6702
|
};
|
|
6703
6703
|
}
|
|
6704
6704
|
|
|
6705
|
+
// src/lib/chat/streamIdleTimeout.ts
|
|
6706
|
+
var StreamIdleTimeoutError = class extends Error {
|
|
6707
|
+
constructor(idleTimeoutMs) {
|
|
6708
|
+
super(`Stream timed out after ${idleTimeoutMs} ms without activity.`);
|
|
6709
|
+
this.name = "StreamIdleTimeoutError";
|
|
6710
|
+
this.idleTimeoutMs = idleTimeoutMs;
|
|
6711
|
+
}
|
|
6712
|
+
};
|
|
6713
|
+
function withStreamIdleTimeout(transport, idleTimeoutMs) {
|
|
6714
|
+
if (!(idleTimeoutMs > 0) || idleTimeoutMs === Infinity) return transport;
|
|
6715
|
+
return (options) => ({
|
|
6716
|
+
stream: (async function* () {
|
|
6717
|
+
const controller = new AbortController();
|
|
6718
|
+
let timer;
|
|
6719
|
+
let settled = false;
|
|
6720
|
+
let completed = false;
|
|
6721
|
+
let iterator;
|
|
6722
|
+
let interruption;
|
|
6723
|
+
let rejectPending;
|
|
6724
|
+
const disarm = () => {
|
|
6725
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
6726
|
+
timer = void 0;
|
|
6727
|
+
};
|
|
6728
|
+
const interrupt = (error) => {
|
|
6729
|
+
if (interruption) return;
|
|
6730
|
+
interruption = error;
|
|
6731
|
+
rejectPending?.(error);
|
|
6732
|
+
controller.abort();
|
|
6733
|
+
};
|
|
6734
|
+
const arm = () => {
|
|
6735
|
+
if (settled || controller.signal.aborted) return;
|
|
6736
|
+
disarm();
|
|
6737
|
+
timer = setTimeout(() => {
|
|
6738
|
+
interrupt(new StreamIdleTimeoutError(idleTimeoutMs));
|
|
6739
|
+
}, idleTimeoutMs);
|
|
6740
|
+
};
|
|
6741
|
+
const onAbort = () => {
|
|
6742
|
+
controller.abort();
|
|
6743
|
+
};
|
|
6744
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
6745
|
+
try {
|
|
6746
|
+
if (options.signal?.aborted) {
|
|
6747
|
+
const error = new Error("Request aborted");
|
|
6748
|
+
error.name = "AbortError";
|
|
6749
|
+
throw error;
|
|
6750
|
+
}
|
|
6751
|
+
arm();
|
|
6752
|
+
iterator = transport({
|
|
6753
|
+
...options,
|
|
6754
|
+
signal: controller.signal,
|
|
6755
|
+
onActivity: () => {
|
|
6756
|
+
arm();
|
|
6757
|
+
options.onActivity?.();
|
|
6758
|
+
}
|
|
6759
|
+
}).stream[Symbol.asyncIterator]();
|
|
6760
|
+
while (true) {
|
|
6761
|
+
if (interruption) throw interruption;
|
|
6762
|
+
const next = await new Promise((resolve, reject) => {
|
|
6763
|
+
rejectPending = reject;
|
|
6764
|
+
Promise.resolve(iterator.next()).then(resolve, reject);
|
|
6765
|
+
});
|
|
6766
|
+
rejectPending = void 0;
|
|
6767
|
+
if (next.done) {
|
|
6768
|
+
completed = true;
|
|
6769
|
+
break;
|
|
6770
|
+
}
|
|
6771
|
+
arm();
|
|
6772
|
+
yield next.value;
|
|
6773
|
+
}
|
|
6774
|
+
} finally {
|
|
6775
|
+
settled = true;
|
|
6776
|
+
rejectPending = void 0;
|
|
6777
|
+
disarm();
|
|
6778
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
6779
|
+
if (!completed) {
|
|
6780
|
+
controller.abort();
|
|
6781
|
+
try {
|
|
6782
|
+
void iterator?.return?.().catch(() => {
|
|
6783
|
+
});
|
|
6784
|
+
} catch {
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6787
|
+
}
|
|
6788
|
+
})()
|
|
6789
|
+
});
|
|
6790
|
+
}
|
|
6791
|
+
|
|
6705
6792
|
// src/lib/chat/useChat/utils.ts
|
|
6706
6793
|
var import_jsonrepair = require("jsonrepair");
|
|
6707
6794
|
init_logger();
|
|
@@ -8892,7 +8979,20 @@ var defaultTransport = (options) => {
|
|
|
8892
8979
|
} catch {
|
|
8893
8980
|
}
|
|
8894
8981
|
}
|
|
8895
|
-
return response;
|
|
8982
|
+
if (!response.body || !options.onActivity) return response;
|
|
8983
|
+
const body = response.body.pipeThrough(
|
|
8984
|
+
new TransformStream({
|
|
8985
|
+
transform(chunk, controller) {
|
|
8986
|
+
if (chunk.byteLength > 0) options.onActivity?.();
|
|
8987
|
+
controller.enqueue(chunk);
|
|
8988
|
+
}
|
|
8989
|
+
})
|
|
8990
|
+
);
|
|
8991
|
+
return new Response(body, {
|
|
8992
|
+
status: response.status,
|
|
8993
|
+
statusText: response.statusText,
|
|
8994
|
+
headers: response.headers
|
|
8995
|
+
});
|
|
8896
8996
|
};
|
|
8897
8997
|
return createSseClient({
|
|
8898
8998
|
method: options.method ?? "POST",
|
|
@@ -8949,6 +9049,7 @@ async function runToolLoop(options) {
|
|
|
8949
9049
|
conversationId,
|
|
8950
9050
|
smoothing,
|
|
8951
9051
|
signal,
|
|
9052
|
+
idleTimeoutMs = 12e4,
|
|
8952
9053
|
resumable,
|
|
8953
9054
|
detachSignal,
|
|
8954
9055
|
onStreamMeta,
|
|
@@ -8962,13 +9063,14 @@ async function runToolLoop(options) {
|
|
|
8962
9063
|
onStepFinish,
|
|
8963
9064
|
onRequest,
|
|
8964
9065
|
onStreamRetry,
|
|
8965
|
-
transport
|
|
9066
|
+
transport = defaultTransport,
|
|
8966
9067
|
preProcessors,
|
|
8967
9068
|
maxConnectorCalls = 2,
|
|
8968
9069
|
hooks: hooksOption,
|
|
8969
9070
|
piiRedaction,
|
|
8970
9071
|
onPiiRedacted
|
|
8971
9072
|
} = options;
|
|
9073
|
+
const makeStreamingRequest = withStreamIdleTimeout(transport, idleTimeoutMs);
|
|
8972
9074
|
const hooks = Array.isArray(hooksOption) ? composeHooks(hooksOption) : hooksOption;
|
|
8973
9075
|
const runId = generateRunId();
|
|
8974
9076
|
let messages = options.messages;
|
|
@@ -24607,6 +24709,7 @@ function useChat(options) {
|
|
|
24607
24709
|
apiType: defaultApiType = "auto",
|
|
24608
24710
|
smoothing,
|
|
24609
24711
|
preProcessors,
|
|
24712
|
+
hooks,
|
|
24610
24713
|
piiRedaction,
|
|
24611
24714
|
onPiiRedacted,
|
|
24612
24715
|
resumable = false,
|
|
@@ -24860,6 +24963,7 @@ function useChat(options) {
|
|
|
24860
24963
|
onToolCallArgumentsDelta,
|
|
24861
24964
|
onStepFinish,
|
|
24862
24965
|
preProcessors,
|
|
24966
|
+
hooks,
|
|
24863
24967
|
piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
|
|
24864
24968
|
onPiiRedacted
|
|
24865
24969
|
});
|
|
@@ -24899,6 +25003,7 @@ function useChat(options) {
|
|
|
24899
25003
|
defaultApiType,
|
|
24900
25004
|
smoothing,
|
|
24901
25005
|
preProcessors,
|
|
25006
|
+
hooks,
|
|
24902
25007
|
resolvedPiiRedaction,
|
|
24903
25008
|
onPiiRedacted,
|
|
24904
25009
|
resumable,
|
|
@@ -25869,6 +25974,7 @@ function useChatStorage(options) {
|
|
|
25869
25974
|
embeddingModel = DEFAULT_API_EMBEDDING_MODEL,
|
|
25870
25975
|
minContentLength = DEFAULT_MIN_CONTENT_LENGTH,
|
|
25871
25976
|
preProcessors,
|
|
25977
|
+
hooks,
|
|
25872
25978
|
smoothing,
|
|
25873
25979
|
resumable = false,
|
|
25874
25980
|
onCancelResult,
|
|
@@ -26328,6 +26434,7 @@ function useChatStorage(options) {
|
|
|
26328
26434
|
onError,
|
|
26329
26435
|
apiType,
|
|
26330
26436
|
preProcessors,
|
|
26437
|
+
hooks,
|
|
26331
26438
|
smoothing,
|
|
26332
26439
|
resumable,
|
|
26333
26440
|
onCancelResult,
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -2002,6 +2002,127 @@ declare function createStreamingDeAnonymizer(redactor: PiiRedactor, emit: (chunk
|
|
|
2002
2002
|
flush: () => void;
|
|
2003
2003
|
};
|
|
2004
2004
|
|
|
2005
|
+
type LlmTokenUsage = {
|
|
2006
|
+
inputTokens?: number;
|
|
2007
|
+
outputTokens?: number;
|
|
2008
|
+
};
|
|
2009
|
+
type ModelCallStartEvent = {
|
|
2010
|
+
runId: string;
|
|
2011
|
+
stepIndex: number;
|
|
2012
|
+
model: string;
|
|
2013
|
+
messages: Array<LlmapiMessage>;
|
|
2014
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2015
|
+
requestBody: Record<string, unknown>;
|
|
2016
|
+
};
|
|
2017
|
+
type ModelCallEndEvent = {
|
|
2018
|
+
runId: string;
|
|
2019
|
+
stepIndex: number;
|
|
2020
|
+
content: string;
|
|
2021
|
+
toolCalls: Array<{
|
|
2022
|
+
id: string;
|
|
2023
|
+
name: string;
|
|
2024
|
+
arguments: string;
|
|
2025
|
+
}>;
|
|
2026
|
+
usage?: LlmTokenUsage;
|
|
2027
|
+
finishReason?: string;
|
|
2028
|
+
error?: string;
|
|
2029
|
+
};
|
|
2030
|
+
type ToolUseStartEvent = {
|
|
2031
|
+
runId: string;
|
|
2032
|
+
stepIndex: number;
|
|
2033
|
+
toolCallId: string;
|
|
2034
|
+
name: string;
|
|
2035
|
+
rawArguments: string;
|
|
2036
|
+
parsedArguments?: Record<string, unknown>;
|
|
2037
|
+
};
|
|
2038
|
+
type ToolUseEndEvent = {
|
|
2039
|
+
runId: string;
|
|
2040
|
+
stepIndex: number;
|
|
2041
|
+
toolCallId: string;
|
|
2042
|
+
name: string;
|
|
2043
|
+
result?: unknown;
|
|
2044
|
+
error?: string;
|
|
2045
|
+
errorType?: "parse" | "timeout" | "execution" | "cancelled";
|
|
2046
|
+
};
|
|
2047
|
+
type RunStartEvent = {
|
|
2048
|
+
runId: string;
|
|
2049
|
+
model: string;
|
|
2050
|
+
messages: Array<LlmapiMessage>;
|
|
2051
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2052
|
+
};
|
|
2053
|
+
type RunEndEvent = {
|
|
2054
|
+
runId: string;
|
|
2055
|
+
finalContent: string;
|
|
2056
|
+
/** Number of LLM rounds executed. */
|
|
2057
|
+
totalSteps: number;
|
|
2058
|
+
};
|
|
2059
|
+
type RunErrorEvent = {
|
|
2060
|
+
runId: string;
|
|
2061
|
+
error: string;
|
|
2062
|
+
/**
|
|
2063
|
+
* Only `"model"` today. Tool failures surface on {@link RunHooks.afterToolUse}
|
|
2064
|
+
* with `errorType`, not on `onRunError`, so a tool stage isn't needed yet.
|
|
2065
|
+
* Left as a union to leave room for `"validation"` or `"tool"` later
|
|
2066
|
+
* without a breaking change.
|
|
2067
|
+
*/
|
|
2068
|
+
stage: "model";
|
|
2069
|
+
/**
|
|
2070
|
+
* The underlying `Error` when one is available. `RunErrorEvent` predates
|
|
2071
|
+
* this field, so `error` (a string message) is kept for backwards
|
|
2072
|
+
* compatibility; new consumers should prefer `errorObject` when present
|
|
2073
|
+
* for stack traces and `cause`.
|
|
2074
|
+
*/
|
|
2075
|
+
errorObject?: Error;
|
|
2076
|
+
};
|
|
2077
|
+
type RunHooks = {
|
|
2078
|
+
/**
|
|
2079
|
+
* Fires once per `runToolLoop` invocation, before any pre-processor or
|
|
2080
|
+
* model call. The `messages` payload is the raw caller-supplied
|
|
2081
|
+
* conversation — pre-processors that enrich it (e.g. web search context)
|
|
2082
|
+
* run afterwards, so `beforeModelCall.messages` reflects the
|
|
2083
|
+
* post-enrichment state.
|
|
2084
|
+
*/
|
|
2085
|
+
onRunStart?: (e: RunStartEvent) => Promise<void> | void;
|
|
2086
|
+
/**
|
|
2087
|
+
* Fires exactly once per run on clean completion. Mutually exclusive
|
|
2088
|
+
* with `onRunError` — a run that completes fires `onRunEnd`; a run that
|
|
2089
|
+
* errors or is aborted fires `onRunError`. Consumers can rely on
|
|
2090
|
+
* exactly one terminal hook per `onRunStart`.
|
|
2091
|
+
*/
|
|
2092
|
+
onRunEnd?: (e: RunEndEvent) => Promise<void> | void;
|
|
2093
|
+
/**
|
|
2094
|
+
* Fires exactly once per run when the loop errors or is aborted.
|
|
2095
|
+
* `stage` is `"model"` for stream/provider errors and for aborts;
|
|
2096
|
+
* tool execution failures surface as structured `{ error, errorType }`
|
|
2097
|
+
* results on `afterToolUse` rather than firing `onRunError`.
|
|
2098
|
+
* Mutually exclusive with `onRunEnd`.
|
|
2099
|
+
*/
|
|
2100
|
+
onRunError?: (e: RunErrorEvent) => Promise<void> | void;
|
|
2101
|
+
beforeModelCall?: (e: ModelCallStartEvent) => Promise<void> | void;
|
|
2102
|
+
afterModelCall?: (e: ModelCallEndEvent) => Promise<void> | void;
|
|
2103
|
+
/**
|
|
2104
|
+
* Fires before each tool the model invoked — including server-side
|
|
2105
|
+
* tools that have no client executor. Today this is observe-only.
|
|
2106
|
+
* TODO(follow-up PR): allow returning { args?, abort?: { reason } } to
|
|
2107
|
+
* mutate arguments or short-circuit the tool call.
|
|
2108
|
+
*
|
|
2109
|
+
* Pairing with {@link afterToolUse} is asymmetric: server-side tools
|
|
2110
|
+
* routed via `onToolCall` get `beforeToolUse` but no `afterToolUse`,
|
|
2111
|
+
* because they don't execute in-process. Tools blocked by a failed
|
|
2112
|
+
* dependency or a dependency cycle DO get `afterToolUse` with
|
|
2113
|
+
* `errorType: "execution"` — consumers tallying matched pairs should
|
|
2114
|
+
* filter on executor-backed tools to avoid spurious imbalances.
|
|
2115
|
+
*/
|
|
2116
|
+
beforeToolUse?: (e: ToolUseStartEvent) => Promise<void> | void;
|
|
2117
|
+
/**
|
|
2118
|
+
* Fires after each executor-backed tool finishes (success or failure)
|
|
2119
|
+
* and after each dependency-blocked tool is skipped (`errorType:
|
|
2120
|
+
* "execution"`). Does NOT fire for server-side tools routed via
|
|
2121
|
+
* `onToolCall`. See {@link beforeToolUse} for the pairing contract.
|
|
2122
|
+
*/
|
|
2123
|
+
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
2124
|
+
};
|
|
2125
|
+
|
|
2005
2126
|
/**
|
|
2006
2127
|
* Configuration for stream output smoothing.
|
|
2007
2128
|
*
|
|
@@ -2196,6 +2317,8 @@ type BaseSendMessageArgs = ResponsesApiOptions & {
|
|
|
2196
2317
|
type BaseUseChatOptions = {
|
|
2197
2318
|
getToken?: () => Promise<string | null>;
|
|
2198
2319
|
baseUrl?: string;
|
|
2320
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
2321
|
+
hooks?: RunHooks | RunHooks[];
|
|
2199
2322
|
/**
|
|
2200
2323
|
* Callback function to be called when a new data chunk is received.
|
|
2201
2324
|
*/
|
|
@@ -2469,12 +2592,10 @@ type StreamingTransportOptions = {
|
|
|
2469
2592
|
inferenceId: string;
|
|
2470
2593
|
}) => void;
|
|
2471
2594
|
/**
|
|
2472
|
-
* Fires
|
|
2473
|
-
*
|
|
2474
|
-
*
|
|
2475
|
-
*
|
|
2476
|
-
* apart from a dead connection (no bytes at all). Not every transport emits it
|
|
2477
|
-
* — the xhr transport does; treat its absence as "no extra liveness info".
|
|
2595
|
+
* Fires when the transport receives bytes, including SSE keep-alive comments.
|
|
2596
|
+
* Consumers can use this callback to reset the idle timeout.
|
|
2597
|
+
* The fetch and XHR transports emit it.
|
|
2598
|
+
* Custom transports can omit it if they cannot report byte activity.
|
|
2478
2599
|
*/
|
|
2479
2600
|
onActivity?: () => void;
|
|
2480
2601
|
};
|
|
@@ -7135,6 +7256,8 @@ interface CreateConversationOptions {
|
|
|
7135
7256
|
* @inline
|
|
7136
7257
|
*/
|
|
7137
7258
|
interface BaseUseChatStorageOptions {
|
|
7259
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
7260
|
+
hooks?: RunHooks | RunHooks[];
|
|
7138
7261
|
/** WatermelonDB database instance for storing conversations and messages */
|
|
7139
7262
|
database: Database;
|
|
7140
7263
|
/** 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/expo/index.d.ts
CHANGED
|
@@ -2002,6 +2002,127 @@ declare function createStreamingDeAnonymizer(redactor: PiiRedactor, emit: (chunk
|
|
|
2002
2002
|
flush: () => void;
|
|
2003
2003
|
};
|
|
2004
2004
|
|
|
2005
|
+
type LlmTokenUsage = {
|
|
2006
|
+
inputTokens?: number;
|
|
2007
|
+
outputTokens?: number;
|
|
2008
|
+
};
|
|
2009
|
+
type ModelCallStartEvent = {
|
|
2010
|
+
runId: string;
|
|
2011
|
+
stepIndex: number;
|
|
2012
|
+
model: string;
|
|
2013
|
+
messages: Array<LlmapiMessage>;
|
|
2014
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2015
|
+
requestBody: Record<string, unknown>;
|
|
2016
|
+
};
|
|
2017
|
+
type ModelCallEndEvent = {
|
|
2018
|
+
runId: string;
|
|
2019
|
+
stepIndex: number;
|
|
2020
|
+
content: string;
|
|
2021
|
+
toolCalls: Array<{
|
|
2022
|
+
id: string;
|
|
2023
|
+
name: string;
|
|
2024
|
+
arguments: string;
|
|
2025
|
+
}>;
|
|
2026
|
+
usage?: LlmTokenUsage;
|
|
2027
|
+
finishReason?: string;
|
|
2028
|
+
error?: string;
|
|
2029
|
+
};
|
|
2030
|
+
type ToolUseStartEvent = {
|
|
2031
|
+
runId: string;
|
|
2032
|
+
stepIndex: number;
|
|
2033
|
+
toolCallId: string;
|
|
2034
|
+
name: string;
|
|
2035
|
+
rawArguments: string;
|
|
2036
|
+
parsedArguments?: Record<string, unknown>;
|
|
2037
|
+
};
|
|
2038
|
+
type ToolUseEndEvent = {
|
|
2039
|
+
runId: string;
|
|
2040
|
+
stepIndex: number;
|
|
2041
|
+
toolCallId: string;
|
|
2042
|
+
name: string;
|
|
2043
|
+
result?: unknown;
|
|
2044
|
+
error?: string;
|
|
2045
|
+
errorType?: "parse" | "timeout" | "execution" | "cancelled";
|
|
2046
|
+
};
|
|
2047
|
+
type RunStartEvent = {
|
|
2048
|
+
runId: string;
|
|
2049
|
+
model: string;
|
|
2050
|
+
messages: Array<LlmapiMessage>;
|
|
2051
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
2052
|
+
};
|
|
2053
|
+
type RunEndEvent = {
|
|
2054
|
+
runId: string;
|
|
2055
|
+
finalContent: string;
|
|
2056
|
+
/** Number of LLM rounds executed. */
|
|
2057
|
+
totalSteps: number;
|
|
2058
|
+
};
|
|
2059
|
+
type RunErrorEvent = {
|
|
2060
|
+
runId: string;
|
|
2061
|
+
error: string;
|
|
2062
|
+
/**
|
|
2063
|
+
* Only `"model"` today. Tool failures surface on {@link RunHooks.afterToolUse}
|
|
2064
|
+
* with `errorType`, not on `onRunError`, so a tool stage isn't needed yet.
|
|
2065
|
+
* Left as a union to leave room for `"validation"` or `"tool"` later
|
|
2066
|
+
* without a breaking change.
|
|
2067
|
+
*/
|
|
2068
|
+
stage: "model";
|
|
2069
|
+
/**
|
|
2070
|
+
* The underlying `Error` when one is available. `RunErrorEvent` predates
|
|
2071
|
+
* this field, so `error` (a string message) is kept for backwards
|
|
2072
|
+
* compatibility; new consumers should prefer `errorObject` when present
|
|
2073
|
+
* for stack traces and `cause`.
|
|
2074
|
+
*/
|
|
2075
|
+
errorObject?: Error;
|
|
2076
|
+
};
|
|
2077
|
+
type RunHooks = {
|
|
2078
|
+
/**
|
|
2079
|
+
* Fires once per `runToolLoop` invocation, before any pre-processor or
|
|
2080
|
+
* model call. The `messages` payload is the raw caller-supplied
|
|
2081
|
+
* conversation — pre-processors that enrich it (e.g. web search context)
|
|
2082
|
+
* run afterwards, so `beforeModelCall.messages` reflects the
|
|
2083
|
+
* post-enrichment state.
|
|
2084
|
+
*/
|
|
2085
|
+
onRunStart?: (e: RunStartEvent) => Promise<void> | void;
|
|
2086
|
+
/**
|
|
2087
|
+
* Fires exactly once per run on clean completion. Mutually exclusive
|
|
2088
|
+
* with `onRunError` — a run that completes fires `onRunEnd`; a run that
|
|
2089
|
+
* errors or is aborted fires `onRunError`. Consumers can rely on
|
|
2090
|
+
* exactly one terminal hook per `onRunStart`.
|
|
2091
|
+
*/
|
|
2092
|
+
onRunEnd?: (e: RunEndEvent) => Promise<void> | void;
|
|
2093
|
+
/**
|
|
2094
|
+
* Fires exactly once per run when the loop errors or is aborted.
|
|
2095
|
+
* `stage` is `"model"` for stream/provider errors and for aborts;
|
|
2096
|
+
* tool execution failures surface as structured `{ error, errorType }`
|
|
2097
|
+
* results on `afterToolUse` rather than firing `onRunError`.
|
|
2098
|
+
* Mutually exclusive with `onRunEnd`.
|
|
2099
|
+
*/
|
|
2100
|
+
onRunError?: (e: RunErrorEvent) => Promise<void> | void;
|
|
2101
|
+
beforeModelCall?: (e: ModelCallStartEvent) => Promise<void> | void;
|
|
2102
|
+
afterModelCall?: (e: ModelCallEndEvent) => Promise<void> | void;
|
|
2103
|
+
/**
|
|
2104
|
+
* Fires before each tool the model invoked — including server-side
|
|
2105
|
+
* tools that have no client executor. Today this is observe-only.
|
|
2106
|
+
* TODO(follow-up PR): allow returning { args?, abort?: { reason } } to
|
|
2107
|
+
* mutate arguments or short-circuit the tool call.
|
|
2108
|
+
*
|
|
2109
|
+
* Pairing with {@link afterToolUse} is asymmetric: server-side tools
|
|
2110
|
+
* routed via `onToolCall` get `beforeToolUse` but no `afterToolUse`,
|
|
2111
|
+
* because they don't execute in-process. Tools blocked by a failed
|
|
2112
|
+
* dependency or a dependency cycle DO get `afterToolUse` with
|
|
2113
|
+
* `errorType: "execution"` — consumers tallying matched pairs should
|
|
2114
|
+
* filter on executor-backed tools to avoid spurious imbalances.
|
|
2115
|
+
*/
|
|
2116
|
+
beforeToolUse?: (e: ToolUseStartEvent) => Promise<void> | void;
|
|
2117
|
+
/**
|
|
2118
|
+
* Fires after each executor-backed tool finishes (success or failure)
|
|
2119
|
+
* and after each dependency-blocked tool is skipped (`errorType:
|
|
2120
|
+
* "execution"`). Does NOT fire for server-side tools routed via
|
|
2121
|
+
* `onToolCall`. See {@link beforeToolUse} for the pairing contract.
|
|
2122
|
+
*/
|
|
2123
|
+
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
2124
|
+
};
|
|
2125
|
+
|
|
2005
2126
|
/**
|
|
2006
2127
|
* Configuration for stream output smoothing.
|
|
2007
2128
|
*
|
|
@@ -2196,6 +2317,8 @@ type BaseSendMessageArgs = ResponsesApiOptions & {
|
|
|
2196
2317
|
type BaseUseChatOptions = {
|
|
2197
2318
|
getToken?: () => Promise<string | null>;
|
|
2198
2319
|
baseUrl?: string;
|
|
2320
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
2321
|
+
hooks?: RunHooks | RunHooks[];
|
|
2199
2322
|
/**
|
|
2200
2323
|
* Callback function to be called when a new data chunk is received.
|
|
2201
2324
|
*/
|
|
@@ -2469,12 +2592,10 @@ type StreamingTransportOptions = {
|
|
|
2469
2592
|
inferenceId: string;
|
|
2470
2593
|
}) => void;
|
|
2471
2594
|
/**
|
|
2472
|
-
* Fires
|
|
2473
|
-
*
|
|
2474
|
-
*
|
|
2475
|
-
*
|
|
2476
|
-
* apart from a dead connection (no bytes at all). Not every transport emits it
|
|
2477
|
-
* — the xhr transport does; treat its absence as "no extra liveness info".
|
|
2595
|
+
* Fires when the transport receives bytes, including SSE keep-alive comments.
|
|
2596
|
+
* Consumers can use this callback to reset the idle timeout.
|
|
2597
|
+
* The fetch and XHR transports emit it.
|
|
2598
|
+
* Custom transports can omit it if they cannot report byte activity.
|
|
2478
2599
|
*/
|
|
2479
2600
|
onActivity?: () => void;
|
|
2480
2601
|
};
|
|
@@ -7135,6 +7256,8 @@ interface CreateConversationOptions {
|
|
|
7135
7256
|
* @inline
|
|
7136
7257
|
*/
|
|
7137
7258
|
interface BaseUseChatStorageOptions {
|
|
7259
|
+
/** Run lifecycle hooks for telemetry and tracing, for example from `createMetricsHooks` */
|
|
7260
|
+
hooks?: RunHooks | RunHooks[];
|
|
7138
7261
|
/** WatermelonDB database instance for storing conversations and messages */
|
|
7139
7262
|
database: Database;
|
|
7140
7263
|
/** 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/expo/index.mjs
CHANGED
|
@@ -5115,6 +5115,93 @@ function composeHooks(hooks) {
|
|
|
5115
5115
|
};
|
|
5116
5116
|
}
|
|
5117
5117
|
|
|
5118
|
+
// src/lib/chat/streamIdleTimeout.ts
|
|
5119
|
+
var StreamIdleTimeoutError = class extends Error {
|
|
5120
|
+
constructor(idleTimeoutMs) {
|
|
5121
|
+
super(`Stream timed out after ${idleTimeoutMs} ms without activity.`);
|
|
5122
|
+
this.name = "StreamIdleTimeoutError";
|
|
5123
|
+
this.idleTimeoutMs = idleTimeoutMs;
|
|
5124
|
+
}
|
|
5125
|
+
};
|
|
5126
|
+
function withStreamIdleTimeout(transport, idleTimeoutMs) {
|
|
5127
|
+
if (!(idleTimeoutMs > 0) || idleTimeoutMs === Infinity) return transport;
|
|
5128
|
+
return (options) => ({
|
|
5129
|
+
stream: (async function* () {
|
|
5130
|
+
const controller = new AbortController();
|
|
5131
|
+
let timer;
|
|
5132
|
+
let settled = false;
|
|
5133
|
+
let completed = false;
|
|
5134
|
+
let iterator;
|
|
5135
|
+
let interruption;
|
|
5136
|
+
let rejectPending;
|
|
5137
|
+
const disarm = () => {
|
|
5138
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
5139
|
+
timer = void 0;
|
|
5140
|
+
};
|
|
5141
|
+
const interrupt = (error) => {
|
|
5142
|
+
if (interruption) return;
|
|
5143
|
+
interruption = error;
|
|
5144
|
+
rejectPending?.(error);
|
|
5145
|
+
controller.abort();
|
|
5146
|
+
};
|
|
5147
|
+
const arm = () => {
|
|
5148
|
+
if (settled || controller.signal.aborted) return;
|
|
5149
|
+
disarm();
|
|
5150
|
+
timer = setTimeout(() => {
|
|
5151
|
+
interrupt(new StreamIdleTimeoutError(idleTimeoutMs));
|
|
5152
|
+
}, idleTimeoutMs);
|
|
5153
|
+
};
|
|
5154
|
+
const onAbort = () => {
|
|
5155
|
+
controller.abort();
|
|
5156
|
+
};
|
|
5157
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
5158
|
+
try {
|
|
5159
|
+
if (options.signal?.aborted) {
|
|
5160
|
+
const error = new Error("Request aborted");
|
|
5161
|
+
error.name = "AbortError";
|
|
5162
|
+
throw error;
|
|
5163
|
+
}
|
|
5164
|
+
arm();
|
|
5165
|
+
iterator = transport({
|
|
5166
|
+
...options,
|
|
5167
|
+
signal: controller.signal,
|
|
5168
|
+
onActivity: () => {
|
|
5169
|
+
arm();
|
|
5170
|
+
options.onActivity?.();
|
|
5171
|
+
}
|
|
5172
|
+
}).stream[Symbol.asyncIterator]();
|
|
5173
|
+
while (true) {
|
|
5174
|
+
if (interruption) throw interruption;
|
|
5175
|
+
const next = await new Promise((resolve, reject) => {
|
|
5176
|
+
rejectPending = reject;
|
|
5177
|
+
Promise.resolve(iterator.next()).then(resolve, reject);
|
|
5178
|
+
});
|
|
5179
|
+
rejectPending = void 0;
|
|
5180
|
+
if (next.done) {
|
|
5181
|
+
completed = true;
|
|
5182
|
+
break;
|
|
5183
|
+
}
|
|
5184
|
+
arm();
|
|
5185
|
+
yield next.value;
|
|
5186
|
+
}
|
|
5187
|
+
} finally {
|
|
5188
|
+
settled = true;
|
|
5189
|
+
rejectPending = void 0;
|
|
5190
|
+
disarm();
|
|
5191
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
5192
|
+
if (!completed) {
|
|
5193
|
+
controller.abort();
|
|
5194
|
+
try {
|
|
5195
|
+
void iterator?.return?.().catch(() => {
|
|
5196
|
+
});
|
|
5197
|
+
} catch {
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
}
|
|
5201
|
+
})()
|
|
5202
|
+
});
|
|
5203
|
+
}
|
|
5204
|
+
|
|
5118
5205
|
// src/lib/chat/useChat/utils.ts
|
|
5119
5206
|
import { jsonrepair } from "jsonrepair";
|
|
5120
5207
|
function parseToolArguments(raw) {
|
|
@@ -7304,7 +7391,20 @@ var defaultTransport = (options) => {
|
|
|
7304
7391
|
} catch {
|
|
7305
7392
|
}
|
|
7306
7393
|
}
|
|
7307
|
-
return response;
|
|
7394
|
+
if (!response.body || !options.onActivity) return response;
|
|
7395
|
+
const body = response.body.pipeThrough(
|
|
7396
|
+
new TransformStream({
|
|
7397
|
+
transform(chunk, controller) {
|
|
7398
|
+
if (chunk.byteLength > 0) options.onActivity?.();
|
|
7399
|
+
controller.enqueue(chunk);
|
|
7400
|
+
}
|
|
7401
|
+
})
|
|
7402
|
+
);
|
|
7403
|
+
return new Response(body, {
|
|
7404
|
+
status: response.status,
|
|
7405
|
+
statusText: response.statusText,
|
|
7406
|
+
headers: response.headers
|
|
7407
|
+
});
|
|
7308
7408
|
};
|
|
7309
7409
|
return createSseClient({
|
|
7310
7410
|
method: options.method ?? "POST",
|
|
@@ -7361,6 +7461,7 @@ async function runToolLoop(options) {
|
|
|
7361
7461
|
conversationId,
|
|
7362
7462
|
smoothing,
|
|
7363
7463
|
signal,
|
|
7464
|
+
idleTimeoutMs = 12e4,
|
|
7364
7465
|
resumable,
|
|
7365
7466
|
detachSignal,
|
|
7366
7467
|
onStreamMeta,
|
|
@@ -7374,13 +7475,14 @@ async function runToolLoop(options) {
|
|
|
7374
7475
|
onStepFinish,
|
|
7375
7476
|
onRequest,
|
|
7376
7477
|
onStreamRetry,
|
|
7377
|
-
transport
|
|
7478
|
+
transport = defaultTransport,
|
|
7378
7479
|
preProcessors,
|
|
7379
7480
|
maxConnectorCalls = 2,
|
|
7380
7481
|
hooks: hooksOption,
|
|
7381
7482
|
piiRedaction,
|
|
7382
7483
|
onPiiRedacted
|
|
7383
7484
|
} = options;
|
|
7485
|
+
const makeStreamingRequest = withStreamIdleTimeout(transport, idleTimeoutMs);
|
|
7384
7486
|
const hooks = Array.isArray(hooksOption) ? composeHooks(hooksOption) : hooksOption;
|
|
7385
7487
|
const runId = generateRunId();
|
|
7386
7488
|
let messages = options.messages;
|
|
@@ -22960,6 +23062,7 @@ function useChat(options) {
|
|
|
22960
23062
|
apiType: defaultApiType = "auto",
|
|
22961
23063
|
smoothing,
|
|
22962
23064
|
preProcessors,
|
|
23065
|
+
hooks,
|
|
22963
23066
|
piiRedaction,
|
|
22964
23067
|
onPiiRedacted,
|
|
22965
23068
|
resumable = false,
|
|
@@ -23213,6 +23316,7 @@ function useChat(options) {
|
|
|
23213
23316
|
onToolCallArgumentsDelta,
|
|
23214
23317
|
onStepFinish,
|
|
23215
23318
|
preProcessors,
|
|
23319
|
+
hooks,
|
|
23216
23320
|
piiRedaction: requestPiiRedaction ?? resolvedPiiRedaction,
|
|
23217
23321
|
onPiiRedacted
|
|
23218
23322
|
});
|
|
@@ -23252,6 +23356,7 @@ function useChat(options) {
|
|
|
23252
23356
|
defaultApiType,
|
|
23253
23357
|
smoothing,
|
|
23254
23358
|
preProcessors,
|
|
23359
|
+
hooks,
|
|
23255
23360
|
resolvedPiiRedaction,
|
|
23256
23361
|
onPiiRedacted,
|
|
23257
23362
|
resumable,
|
|
@@ -24212,6 +24317,7 @@ function useChatStorage(options) {
|
|
|
24212
24317
|
embeddingModel = DEFAULT_API_EMBEDDING_MODEL,
|
|
24213
24318
|
minContentLength = DEFAULT_MIN_CONTENT_LENGTH,
|
|
24214
24319
|
preProcessors,
|
|
24320
|
+
hooks,
|
|
24215
24321
|
smoothing,
|
|
24216
24322
|
resumable = false,
|
|
24217
24323
|
onCancelResult,
|
|
@@ -24671,6 +24777,7 @@ function useChatStorage(options) {
|
|
|
24671
24777
|
onError,
|
|
24672
24778
|
apiType,
|
|
24673
24779
|
preProcessors,
|
|
24780
|
+
hooks,
|
|
24674
24781
|
smoothing,
|
|
24675
24782
|
resumable,
|
|
24676
24783
|
onCancelResult,
|