@anuma/sdk 10.9.0 → 10.10.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/{consolidate-7QUL3TOE.mjs → consolidate-QBV3DDHU.mjs} +1 -1
- package/dist/expo/index.cjs +2493 -2168
- package/dist/expo/index.d.mts +958 -868
- package/dist/expo/index.d.ts +958 -868
- package/dist/expo/index.mjs +2013 -1692
- package/dist/react/index.cjs +115 -85
- package/dist/react/index.d.mts +711 -710
- package/dist/react/index.d.ts +711 -710
- package/dist/react/index.mjs +115 -85
- package/dist/server/index.cjs +19 -13
- package/dist/server/index.d.mts +4 -2
- package/dist/server/index.d.ts +4 -2
- package/dist/server/index.mjs +19 -13
- package/package.json +1 -1
- package/dist/expo/{chunk-4SOUKJD5.mjs → chunk-VNTEHEGI.mjs} +957 -957
package/dist/react/index.d.mts
CHANGED
|
@@ -1894,6 +1894,127 @@ declare function buildAttachedFilesText(fileContext: string): string;
|
|
|
1894
1894
|
*/
|
|
1895
1895
|
declare function attachFileContextToLastUserMessage(messages: LlmapiMessage[], fileContext: string): LlmapiMessage[];
|
|
1896
1896
|
|
|
1897
|
+
type LlmTokenUsage = {
|
|
1898
|
+
inputTokens?: number;
|
|
1899
|
+
outputTokens?: number;
|
|
1900
|
+
};
|
|
1901
|
+
type ModelCallStartEvent = {
|
|
1902
|
+
runId: string;
|
|
1903
|
+
stepIndex: number;
|
|
1904
|
+
model: string;
|
|
1905
|
+
messages: Array<LlmapiMessage>;
|
|
1906
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
1907
|
+
requestBody: Record<string, unknown>;
|
|
1908
|
+
};
|
|
1909
|
+
type ModelCallEndEvent = {
|
|
1910
|
+
runId: string;
|
|
1911
|
+
stepIndex: number;
|
|
1912
|
+
content: string;
|
|
1913
|
+
toolCalls: Array<{
|
|
1914
|
+
id: string;
|
|
1915
|
+
name: string;
|
|
1916
|
+
arguments: string;
|
|
1917
|
+
}>;
|
|
1918
|
+
usage?: LlmTokenUsage;
|
|
1919
|
+
finishReason?: string;
|
|
1920
|
+
error?: string;
|
|
1921
|
+
};
|
|
1922
|
+
type ToolUseStartEvent = {
|
|
1923
|
+
runId: string;
|
|
1924
|
+
stepIndex: number;
|
|
1925
|
+
toolCallId: string;
|
|
1926
|
+
name: string;
|
|
1927
|
+
rawArguments: string;
|
|
1928
|
+
parsedArguments?: Record<string, unknown>;
|
|
1929
|
+
};
|
|
1930
|
+
type ToolUseEndEvent = {
|
|
1931
|
+
runId: string;
|
|
1932
|
+
stepIndex: number;
|
|
1933
|
+
toolCallId: string;
|
|
1934
|
+
name: string;
|
|
1935
|
+
result?: unknown;
|
|
1936
|
+
error?: string;
|
|
1937
|
+
errorType?: "parse" | "timeout" | "execution" | "cancelled";
|
|
1938
|
+
};
|
|
1939
|
+
type RunStartEvent = {
|
|
1940
|
+
runId: string;
|
|
1941
|
+
model: string;
|
|
1942
|
+
messages: Array<LlmapiMessage>;
|
|
1943
|
+
tools: Array<LlmapiChatCompletionTool>;
|
|
1944
|
+
};
|
|
1945
|
+
type RunEndEvent = {
|
|
1946
|
+
runId: string;
|
|
1947
|
+
finalContent: string;
|
|
1948
|
+
/** Number of LLM rounds executed. */
|
|
1949
|
+
totalSteps: number;
|
|
1950
|
+
};
|
|
1951
|
+
type RunErrorEvent = {
|
|
1952
|
+
runId: string;
|
|
1953
|
+
error: string;
|
|
1954
|
+
/**
|
|
1955
|
+
* Only `"model"` today. Tool failures surface on {@link RunHooks.afterToolUse}
|
|
1956
|
+
* with `errorType`, not on `onRunError`, so a tool stage isn't needed yet.
|
|
1957
|
+
* Left as a union to leave room for `"validation"` or `"tool"` later
|
|
1958
|
+
* without a breaking change.
|
|
1959
|
+
*/
|
|
1960
|
+
stage: "model";
|
|
1961
|
+
/**
|
|
1962
|
+
* The underlying `Error` when one is available. `RunErrorEvent` predates
|
|
1963
|
+
* this field, so `error` (a string message) is kept for backwards
|
|
1964
|
+
* compatibility; new consumers should prefer `errorObject` when present
|
|
1965
|
+
* for stack traces and `cause`.
|
|
1966
|
+
*/
|
|
1967
|
+
errorObject?: Error;
|
|
1968
|
+
};
|
|
1969
|
+
type RunHooks = {
|
|
1970
|
+
/**
|
|
1971
|
+
* Fires once per `runToolLoop` invocation, before any pre-processor or
|
|
1972
|
+
* model call. The `messages` payload is the raw caller-supplied
|
|
1973
|
+
* conversation — pre-processors that enrich it (e.g. web search context)
|
|
1974
|
+
* run afterwards, so `beforeModelCall.messages` reflects the
|
|
1975
|
+
* post-enrichment state.
|
|
1976
|
+
*/
|
|
1977
|
+
onRunStart?: (e: RunStartEvent) => Promise<void> | void;
|
|
1978
|
+
/**
|
|
1979
|
+
* Fires exactly once per run on clean completion. Mutually exclusive
|
|
1980
|
+
* with `onRunError` — a run that completes fires `onRunEnd`; a run that
|
|
1981
|
+
* errors or is aborted fires `onRunError`. Consumers can rely on
|
|
1982
|
+
* exactly one terminal hook per `onRunStart`.
|
|
1983
|
+
*/
|
|
1984
|
+
onRunEnd?: (e: RunEndEvent) => Promise<void> | void;
|
|
1985
|
+
/**
|
|
1986
|
+
* Fires exactly once per run when the loop errors or is aborted.
|
|
1987
|
+
* `stage` is `"model"` for stream/provider errors and for aborts;
|
|
1988
|
+
* tool execution failures surface as structured `{ error, errorType }`
|
|
1989
|
+
* results on `afterToolUse` rather than firing `onRunError`.
|
|
1990
|
+
* Mutually exclusive with `onRunEnd`.
|
|
1991
|
+
*/
|
|
1992
|
+
onRunError?: (e: RunErrorEvent) => Promise<void> | void;
|
|
1993
|
+
beforeModelCall?: (e: ModelCallStartEvent) => Promise<void> | void;
|
|
1994
|
+
afterModelCall?: (e: ModelCallEndEvent) => Promise<void> | void;
|
|
1995
|
+
/**
|
|
1996
|
+
* Fires before each tool the model invoked — including server-side
|
|
1997
|
+
* tools that have no client executor. Today this is observe-only.
|
|
1998
|
+
* TODO(follow-up PR): allow returning { args?, abort?: { reason } } to
|
|
1999
|
+
* mutate arguments or short-circuit the tool call.
|
|
2000
|
+
*
|
|
2001
|
+
* Pairing with {@link afterToolUse} is asymmetric: server-side tools
|
|
2002
|
+
* routed via `onToolCall` get `beforeToolUse` but no `afterToolUse`,
|
|
2003
|
+
* because they don't execute in-process. Tools blocked by a failed
|
|
2004
|
+
* dependency or a dependency cycle DO get `afterToolUse` with
|
|
2005
|
+
* `errorType: "execution"` — consumers tallying matched pairs should
|
|
2006
|
+
* filter on executor-backed tools to avoid spurious imbalances.
|
|
2007
|
+
*/
|
|
2008
|
+
beforeToolUse?: (e: ToolUseStartEvent) => Promise<void> | void;
|
|
2009
|
+
/**
|
|
2010
|
+
* Fires after each executor-backed tool finishes (success or failure)
|
|
2011
|
+
* and after each dependency-blocked tool is skipped (`errorType:
|
|
2012
|
+
* "execution"`). Does NOT fire for server-side tools routed via
|
|
2013
|
+
* `onToolCall`. See {@link beforeToolUse} for the pairing contract.
|
|
2014
|
+
*/
|
|
2015
|
+
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
2016
|
+
};
|
|
2017
|
+
|
|
1897
2018
|
/**
|
|
1898
2019
|
* PII detection patterns for structured data types.
|
|
1899
2020
|
*
|
|
@@ -2208,127 +2329,6 @@ declare class PiiRedactor {
|
|
|
2208
2329
|
dispose(): void;
|
|
2209
2330
|
}
|
|
2210
2331
|
|
|
2211
|
-
type LlmTokenUsage = {
|
|
2212
|
-
inputTokens?: number;
|
|
2213
|
-
outputTokens?: number;
|
|
2214
|
-
};
|
|
2215
|
-
type ModelCallStartEvent = {
|
|
2216
|
-
runId: string;
|
|
2217
|
-
stepIndex: number;
|
|
2218
|
-
model: string;
|
|
2219
|
-
messages: Array<LlmapiMessage>;
|
|
2220
|
-
tools: Array<LlmapiChatCompletionTool>;
|
|
2221
|
-
requestBody: Record<string, unknown>;
|
|
2222
|
-
};
|
|
2223
|
-
type ModelCallEndEvent = {
|
|
2224
|
-
runId: string;
|
|
2225
|
-
stepIndex: number;
|
|
2226
|
-
content: string;
|
|
2227
|
-
toolCalls: Array<{
|
|
2228
|
-
id: string;
|
|
2229
|
-
name: string;
|
|
2230
|
-
arguments: string;
|
|
2231
|
-
}>;
|
|
2232
|
-
usage?: LlmTokenUsage;
|
|
2233
|
-
finishReason?: string;
|
|
2234
|
-
error?: string;
|
|
2235
|
-
};
|
|
2236
|
-
type ToolUseStartEvent = {
|
|
2237
|
-
runId: string;
|
|
2238
|
-
stepIndex: number;
|
|
2239
|
-
toolCallId: string;
|
|
2240
|
-
name: string;
|
|
2241
|
-
rawArguments: string;
|
|
2242
|
-
parsedArguments?: Record<string, unknown>;
|
|
2243
|
-
};
|
|
2244
|
-
type ToolUseEndEvent = {
|
|
2245
|
-
runId: string;
|
|
2246
|
-
stepIndex: number;
|
|
2247
|
-
toolCallId: string;
|
|
2248
|
-
name: string;
|
|
2249
|
-
result?: unknown;
|
|
2250
|
-
error?: string;
|
|
2251
|
-
errorType?: "parse" | "timeout" | "execution" | "cancelled";
|
|
2252
|
-
};
|
|
2253
|
-
type RunStartEvent = {
|
|
2254
|
-
runId: string;
|
|
2255
|
-
model: string;
|
|
2256
|
-
messages: Array<LlmapiMessage>;
|
|
2257
|
-
tools: Array<LlmapiChatCompletionTool>;
|
|
2258
|
-
};
|
|
2259
|
-
type RunEndEvent = {
|
|
2260
|
-
runId: string;
|
|
2261
|
-
finalContent: string;
|
|
2262
|
-
/** Number of LLM rounds executed. */
|
|
2263
|
-
totalSteps: number;
|
|
2264
|
-
};
|
|
2265
|
-
type RunErrorEvent = {
|
|
2266
|
-
runId: string;
|
|
2267
|
-
error: string;
|
|
2268
|
-
/**
|
|
2269
|
-
* Only `"model"` today. Tool failures surface on {@link RunHooks.afterToolUse}
|
|
2270
|
-
* with `errorType`, not on `onRunError`, so a tool stage isn't needed yet.
|
|
2271
|
-
* Left as a union to leave room for `"validation"` or `"tool"` later
|
|
2272
|
-
* without a breaking change.
|
|
2273
|
-
*/
|
|
2274
|
-
stage: "model";
|
|
2275
|
-
/**
|
|
2276
|
-
* The underlying `Error` when one is available. `RunErrorEvent` predates
|
|
2277
|
-
* this field, so `error` (a string message) is kept for backwards
|
|
2278
|
-
* compatibility; new consumers should prefer `errorObject` when present
|
|
2279
|
-
* for stack traces and `cause`.
|
|
2280
|
-
*/
|
|
2281
|
-
errorObject?: Error;
|
|
2282
|
-
};
|
|
2283
|
-
type RunHooks = {
|
|
2284
|
-
/**
|
|
2285
|
-
* Fires once per `runToolLoop` invocation, before any pre-processor or
|
|
2286
|
-
* model call. The `messages` payload is the raw caller-supplied
|
|
2287
|
-
* conversation — pre-processors that enrich it (e.g. web search context)
|
|
2288
|
-
* run afterwards, so `beforeModelCall.messages` reflects the
|
|
2289
|
-
* post-enrichment state.
|
|
2290
|
-
*/
|
|
2291
|
-
onRunStart?: (e: RunStartEvent) => Promise<void> | void;
|
|
2292
|
-
/**
|
|
2293
|
-
* Fires exactly once per run on clean completion. Mutually exclusive
|
|
2294
|
-
* with `onRunError` — a run that completes fires `onRunEnd`; a run that
|
|
2295
|
-
* errors or is aborted fires `onRunError`. Consumers can rely on
|
|
2296
|
-
* exactly one terminal hook per `onRunStart`.
|
|
2297
|
-
*/
|
|
2298
|
-
onRunEnd?: (e: RunEndEvent) => Promise<void> | void;
|
|
2299
|
-
/**
|
|
2300
|
-
* Fires exactly once per run when the loop errors or is aborted.
|
|
2301
|
-
* `stage` is `"model"` for stream/provider errors and for aborts;
|
|
2302
|
-
* tool execution failures surface as structured `{ error, errorType }`
|
|
2303
|
-
* results on `afterToolUse` rather than firing `onRunError`.
|
|
2304
|
-
* Mutually exclusive with `onRunEnd`.
|
|
2305
|
-
*/
|
|
2306
|
-
onRunError?: (e: RunErrorEvent) => Promise<void> | void;
|
|
2307
|
-
beforeModelCall?: (e: ModelCallStartEvent) => Promise<void> | void;
|
|
2308
|
-
afterModelCall?: (e: ModelCallEndEvent) => Promise<void> | void;
|
|
2309
|
-
/**
|
|
2310
|
-
* Fires before each tool the model invoked — including server-side
|
|
2311
|
-
* tools that have no client executor. Today this is observe-only.
|
|
2312
|
-
* TODO(follow-up PR): allow returning { args?, abort?: { reason } } to
|
|
2313
|
-
* mutate arguments or short-circuit the tool call.
|
|
2314
|
-
*
|
|
2315
|
-
* Pairing with {@link afterToolUse} is asymmetric: server-side tools
|
|
2316
|
-
* routed via `onToolCall` get `beforeToolUse` but no `afterToolUse`,
|
|
2317
|
-
* because they don't execute in-process. Tools blocked by a failed
|
|
2318
|
-
* dependency or a dependency cycle DO get `afterToolUse` with
|
|
2319
|
-
* `errorType: "execution"` — consumers tallying matched pairs should
|
|
2320
|
-
* filter on executor-backed tools to avoid spurious imbalances.
|
|
2321
|
-
*/
|
|
2322
|
-
beforeToolUse?: (e: ToolUseStartEvent) => Promise<void> | void;
|
|
2323
|
-
/**
|
|
2324
|
-
* Fires after each executor-backed tool finishes (success or failure)
|
|
2325
|
-
* and after each dependency-blocked tool is skipped (`errorType:
|
|
2326
|
-
* "execution"`). Does NOT fire for server-side tools routed via
|
|
2327
|
-
* `onToolCall`. See {@link beforeToolUse} for the pairing contract.
|
|
2328
|
-
*/
|
|
2329
|
-
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
2330
|
-
};
|
|
2331
|
-
|
|
2332
2332
|
/**
|
|
2333
2333
|
* Configuration for stream output smoothing.
|
|
2334
2334
|
*
|
|
@@ -2367,8 +2367,6 @@ type ToolCallArgumentsDeltaEvent = {
|
|
|
2367
2367
|
argumentsDelta: string;
|
|
2368
2368
|
accumulatedArguments: string;
|
|
2369
2369
|
};
|
|
2370
|
-
type ToolExecutionErrorType = "parse" | "timeout" | "execution" | "cancelled";
|
|
2371
|
-
|
|
2372
2370
|
/**
|
|
2373
2371
|
* Error thrown when an upstream provider emits an in-stream error event.
|
|
2374
2372
|
* Carries the provider's code (e.g. `"timeout"`) so callers can match
|
|
@@ -2379,6 +2377,7 @@ declare class ProviderStreamError extends Error {
|
|
|
2379
2377
|
readonly code: string | undefined;
|
|
2380
2378
|
constructor(message: string, code?: string);
|
|
2381
2379
|
}
|
|
2380
|
+
type ToolExecutionErrorType = "parse" | "timeout" | "execution" | "cancelled";
|
|
2382
2381
|
|
|
2383
2382
|
/** A tool result from an auto-executed tool. */
|
|
2384
2383
|
type AutoExecutedToolResult = {
|
|
@@ -2434,6 +2433,8 @@ declare const INFERENCE_ID_HEADER = "X-Inference-ID";
|
|
|
2434
2433
|
*/
|
|
2435
2434
|
type StreamResumeHandle = {
|
|
2436
2435
|
inferenceId: string;
|
|
2436
|
+
/** The reply id the storage hook writes this turn's answer under, when it chose one. */
|
|
2437
|
+
assistantMessageId?: string;
|
|
2437
2438
|
/** The RESOLVED api type (never "auto") — resolveApiType() already ran inside runToolLoop. */
|
|
2438
2439
|
apiType: Exclude<ApiType, "auto">;
|
|
2439
2440
|
model?: string;
|
|
@@ -2787,481 +2788,6 @@ type ApiType = "auto" | "responses" | "completions";
|
|
|
2787
2788
|
*/
|
|
2788
2789
|
type ApiResponse = LlmapiResponseResponse | LlmapiChatCompletionResponse;
|
|
2789
2790
|
|
|
2790
|
-
/**
|
|
2791
|
-
* A finished background answer, as portal sealed it into the vault inbox.
|
|
2792
|
-
* @public
|
|
2793
|
-
*/
|
|
2794
|
-
type InboxPlaintext = {
|
|
2795
|
-
v: 1;
|
|
2796
|
-
inference_id: string;
|
|
2797
|
-
conversation_id: string;
|
|
2798
|
-
parent_message_id: string | null;
|
|
2799
|
-
assistant_message_id?: string | null;
|
|
2800
|
-
api_type: "responses" | "completions";
|
|
2801
|
-
model: string;
|
|
2802
|
-
status: "completed" | "tool_request";
|
|
2803
|
-
pending_tool: string | null;
|
|
2804
|
-
response: ApiResponse;
|
|
2805
|
-
finished_at: string;
|
|
2806
|
-
};
|
|
2807
|
-
/**
|
|
2808
|
-
* One sealed item in the vault inbox.
|
|
2809
|
-
* @public
|
|
2810
|
-
*/
|
|
2811
|
-
type InboxItem = {
|
|
2812
|
-
id: string;
|
|
2813
|
-
sealed: string;
|
|
2814
|
-
created_at: string;
|
|
2815
|
-
};
|
|
2816
|
-
/**
|
|
2817
|
-
* The account's vault inbox and the public key portal seals answers to.
|
|
2818
|
-
* @public
|
|
2819
|
-
*/
|
|
2820
|
-
interface VaultInbox {
|
|
2821
|
-
putPublicKey(publicKey: string): Promise<void>;
|
|
2822
|
-
list(): Promise<InboxItem[]>;
|
|
2823
|
-
remove(id: string): Promise<void>;
|
|
2824
|
-
}
|
|
2825
|
-
/**
|
|
2826
|
-
* The vault inbox client, under the same `/api/private-chats` routes as the chat store.
|
|
2827
|
-
* @public
|
|
2828
|
-
*/
|
|
2829
|
-
declare function createVaultInbox(options: {
|
|
2830
|
-
baseUrl: string;
|
|
2831
|
-
getToken: () => Promise<string | null>;
|
|
2832
|
-
fetch?: typeof globalThis.fetch;
|
|
2833
|
-
timeoutMs?: number;
|
|
2834
|
-
}): VaultInbox;
|
|
2835
|
-
/** The 65-byte uncompressed P-256 point, base64url, as vault stores it. */
|
|
2836
|
-
declare function exportInboxPublicKey(publicKey: CryptoKey): Promise<string>;
|
|
2837
|
-
/** Decrypt a sealed inbox item with the account's ECDH key pair. */
|
|
2838
|
-
declare function openInboxItem(item: Pick<InboxItem, "id" | "sealed">, keyPair: CryptoKeyPair): Promise<InboxPlaintext>;
|
|
2839
|
-
|
|
2840
|
-
/**
|
|
2841
|
-
* What became of a restaurant booking or cancellation in one turn, read from
|
|
2842
|
-
* the server's own tool result rather than from the model's reply.
|
|
2843
|
-
*/
|
|
2844
|
-
type ReservationReceipt = {
|
|
2845
|
-
kind: "booking" | "cancel";
|
|
2846
|
-
/**
|
|
2847
|
-
* `made`: the provider confirmed it. `not_made`: it did not happen.
|
|
2848
|
-
* `already_done`: an earlier call in the conversation had already done it.
|
|
2849
|
-
* `unknown`: the call reached the provider and its outcome is not known.
|
|
2850
|
-
*/
|
|
2851
|
-
status: "made" | "not_made" | "already_done" | "unknown";
|
|
2852
|
-
venueName: string;
|
|
2853
|
-
/** As the call sent it, e.g. `2026-10-23`. */
|
|
2854
|
-
day: string;
|
|
2855
|
-
/** As the call sent it, e.g. `9:00 PM`. */
|
|
2856
|
-
time: string;
|
|
2857
|
-
partySize?: number;
|
|
2858
|
-
reservationId?: string;
|
|
2859
|
-
/** Resy page where the user can see the reservation. */
|
|
2860
|
-
resyUrl?: string;
|
|
2861
|
-
/** The restaurant's own cancellation terms, when the booking result carries them. */
|
|
2862
|
-
feeSummary?: string;
|
|
2863
|
-
/** The provider's stated reason, when it did not happen. */
|
|
2864
|
-
reason?: string;
|
|
2865
|
-
};
|
|
2866
|
-
/** One receipt per kind for the turn's booking and cancel calls, holding the last attempt's outcome unless an earlier one was `made` or `unknown`. */
|
|
2867
|
-
declare function extractReservationReceipts(toolCallEvents?: LlmapiToolCallEvent[]): ReservationReceipt[];
|
|
2868
|
-
|
|
2869
|
-
/**
|
|
2870
|
-
* Build the replay path for a detached stream. The portal serves the buffered
|
|
2871
|
-
* stream from seq 0 on a GET to this path — no `starting_after`, no `id:`
|
|
2872
|
-
* cursor, no request body. Replay always starts from the first buffered byte
|
|
2873
|
-
* and the client rebuilds its own view with a fresh accumulator; partial
|
|
2874
|
-
* client state is never sent back to the server.
|
|
2875
|
-
*
|
|
2876
|
-
* Exported so client repos can mock the endpoint in E2E without string drift.
|
|
2877
|
-
*/
|
|
2878
|
-
declare function streamReplayPath(inferenceId: string): string;
|
|
2879
|
-
/**
|
|
2880
|
-
* Build the cancel path for a detached stream. A POST here tells the portal to
|
|
2881
|
-
* stop generating into the buffer and release it — the billing-safe teardown
|
|
2882
|
-
* for "the user pressed stop after we'd already detached".
|
|
2883
|
-
*
|
|
2884
|
-
* Exported so client repos can mock the endpoint in E2E without string drift.
|
|
2885
|
-
*/
|
|
2886
|
-
declare function streamCancelPath(inferenceId: string): string;
|
|
2887
|
-
/**
|
|
2888
|
-
* A generation still running on the portal for the caller.
|
|
2889
|
-
* @public
|
|
2890
|
-
*/
|
|
2891
|
-
type ActiveStream = {
|
|
2892
|
-
inferenceId: string;
|
|
2893
|
-
assistantMessageId: string | null;
|
|
2894
|
-
conversationId: string | null;
|
|
2895
|
-
parentMessageId: string | null;
|
|
2896
|
-
apiType: "responses" | "completions";
|
|
2897
|
-
model?: string;
|
|
2898
|
-
startedAt: string;
|
|
2899
|
-
};
|
|
2900
|
-
/** List the caller's generations still running on the portal. */
|
|
2901
|
-
declare function listActiveStreams(options: {
|
|
2902
|
-
token: string;
|
|
2903
|
-
baseUrl?: string;
|
|
2904
|
-
conversationId?: string;
|
|
2905
|
-
fetch?: typeof globalThis.fetch;
|
|
2906
|
-
}): Promise<ActiveStream[]>;
|
|
2907
|
-
/**
|
|
2908
|
-
* Thrown when the portal answers `410 Gone` to a replay GET: the buffered
|
|
2909
|
-
* stream is gone — expired (10-min sliding TTL), absent, not owned by the
|
|
2910
|
-
* caller, or already cancelled. There is nothing to replay; the answer is
|
|
2911
|
-
* permanently lost and the caller should fall back to a fresh send rather than
|
|
2912
|
-
* retry. A `stop()`-then-resume race lands here and finalizes as stopped, which
|
|
2913
|
-
* is correct.
|
|
2914
|
-
*
|
|
2915
|
-
* `resumeStream` throws this (it does not return it) and fires neither
|
|
2916
|
-
* `onFinish` nor `onError` — there is no body to deliver.
|
|
2917
|
-
* @public
|
|
2918
|
-
*/
|
|
2919
|
-
declare class StreamExpiredError extends Error {
|
|
2920
|
-
readonly name = "StreamExpiredError";
|
|
2921
|
-
readonly inferenceId: string;
|
|
2922
|
-
constructor(inferenceId: string, message?: string);
|
|
2923
|
-
}
|
|
2924
|
-
/**
|
|
2925
|
-
* Options for {@link resumeStream}.
|
|
2926
|
-
* @public
|
|
2927
|
-
*/
|
|
2928
|
-
interface ResumeStreamOptions {
|
|
2929
|
-
/** The handle captured from a detached `runToolLoop` result. */
|
|
2930
|
-
handle: StreamResumeHandle;
|
|
2931
|
-
/**
|
|
2932
|
-
* Fresh bearer token. The CALLER fetches it at resume time — a multi-minute
|
|
2933
|
-
* background gap expires the bearer, so a token captured when the original
|
|
2934
|
-
* stream started must never be reused (see `useChat.resumeStream`).
|
|
2935
|
-
*/
|
|
2936
|
-
token: string;
|
|
2937
|
-
/** Base URL for the portal. @default the SDK's configured BASE_URL. */
|
|
2938
|
-
baseUrl?: string;
|
|
2939
|
-
/**
|
|
2940
|
-
* Streaming transport. Defaults to the GET-capable fetch transport; Expo
|
|
2941
|
-
* passes `xhrTransport` (RN can't stream `fetch` bodies).
|
|
2942
|
-
*/
|
|
2943
|
-
transport?: StreamingTransport;
|
|
2944
|
-
/** Aborts the replay; the partial is returned as an interrupted result. */
|
|
2945
|
-
signal?: AbortSignal;
|
|
2946
|
-
/** Adaptive output smoothing for the replayed content. @default true */
|
|
2947
|
-
smoothing?: StreamSmoothingConfig | boolean;
|
|
2948
|
-
/**
|
|
2949
|
-
* Client-side watchdog for a dead live-tail. @default 120_000ms.
|
|
2950
|
-
*
|
|
2951
|
-
* Deliberately NOT ~30s: the portal tolerates >100s reasoning silences (no
|
|
2952
|
-
* `data:` frames on the replay connection during them) and its own liveness
|
|
2953
|
-
* rule (heartbeat stale >90s => SSE error + `[DONE]`) is the authoritative
|
|
2954
|
-
* guard. This client timer is a backstop for a half-open TCP connection and
|
|
2955
|
-
* must sit ABOVE the server's 90s rule so the server error always wins when
|
|
2956
|
-
* the portal is reachable. Set to 0 / Infinity to disable.
|
|
2957
|
-
*/
|
|
2958
|
-
idleTimeoutMs?: number;
|
|
2959
|
-
/** Content text deltas as they replay (always from seq 0 — reset accumulated text first). */
|
|
2960
|
-
onData?: (chunk: string) => void;
|
|
2961
|
-
/** Thinking/reasoning deltas as they replay. */
|
|
2962
|
-
onThinking?: (chunk: string) => void;
|
|
2963
|
-
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
2964
|
-
piiRedactor?: PiiRedactor;
|
|
2965
|
-
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
2966
|
-
onFinish?: (response: ApiResponse) => void;
|
|
2967
|
-
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
|
2968
|
-
onError?: (error: Error) => void;
|
|
2969
|
-
}
|
|
2970
|
-
/**
|
|
2971
|
-
* Result of {@link resumeStream}. A `410 Gone` is the only outcome that throws
|
|
2972
|
-
* ({@link StreamExpiredError}); every other terminal is returned.
|
|
2973
|
-
*
|
|
2974
|
-
* - clean completion → `{ data, error: null, interrupted: false, empty }`
|
|
2975
|
-
* - in-stream error / tool-request terminal / idle timeout → `{ data, error,
|
|
2976
|
-
* interrupted: true }` (finalize as a stopped/partial message)
|
|
2977
|
-
* - transient transport/HTTP failure (401, 5xx, network) → `{ data, error,
|
|
2978
|
-
* interrupted: false, statusCode? }` (retryable — keep the handle)
|
|
2979
|
-
*
|
|
2980
|
-
* `empty` is true when the clean terminal delivered ZERO content/thinking
|
|
2981
|
-
* deltas — a `[DONE]`-only replay. That is never a real completion (a
|
|
2982
|
-
* completed generation always buffered at least one content frame); it means
|
|
2983
|
-
* the buffered frames were lost server-side (evicted/trimmed) while the
|
|
2984
|
-
* terminal survived. Consumers must NOT persist `data` (an empty response)
|
|
2985
|
-
* over content they already hold — keep the detached partial instead. On the
|
|
2986
|
-
* empty terminal `onFinish` is NOT fired (there is no completion to deliver);
|
|
2987
|
-
* the flag is optional so existing constructors of the clean arm stay valid.
|
|
2988
|
-
* @public
|
|
2989
|
-
*/
|
|
2990
|
-
type ResumeStreamResult = {
|
|
2991
|
-
data: ApiResponse;
|
|
2992
|
-
error: null;
|
|
2993
|
-
interrupted: false;
|
|
2994
|
-
empty?: boolean;
|
|
2995
|
-
} | {
|
|
2996
|
-
data: ApiResponse | null;
|
|
2997
|
-
error: string;
|
|
2998
|
-
interrupted: boolean;
|
|
2999
|
-
statusCode?: number;
|
|
3000
|
-
};
|
|
3001
|
-
/**
|
|
3002
|
-
* Replay a detached stream from the portal's buffer.
|
|
3003
|
-
*
|
|
3004
|
-
* This is the reconnect primitive: after `runToolLoop` returns the detached
|
|
3005
|
-
* variant with a {@link StreamResumeHandle}, `resumeStream` issues a GET to the
|
|
3006
|
-
* portal's replay endpoint and rebuilds the response from seq 0 using a FRESH
|
|
3007
|
-
* accumulator and FRESH smoothers. Nothing from the original (detached) run is
|
|
3008
|
-
* reused — the completions strategy's reasoning-tag parser is stateful, so
|
|
3009
|
-
* replaying into reused state would double-count; replay-from-0 into fresh
|
|
3010
|
-
* state is the correctness mechanism, not just a simplification.
|
|
3011
|
-
*
|
|
3012
|
-
* Contract highlights:
|
|
3013
|
-
* - **No `starting_after`, no `id:` cursor, no body.** The GET carries the
|
|
3014
|
-
* inference id in the path only; replay is always whole-stream. (The server
|
|
3015
|
-
* reserves `starting_after` but does NOT honor it — sending it would silently
|
|
3016
|
-
* duplicate content.)
|
|
3017
|
-
* - **410 → throws {@link StreamExpiredError}.** No `onFinish`/`onError`.
|
|
3018
|
-
* - **In-stream error / tool-request terminal → `interrupted: true`.** Flushes
|
|
3019
|
-
* both smoothers and returns the partial; no throw, no `onError`, no `onFinish`.
|
|
3020
|
-
* - **token resolved by the caller at resume time** so a refresh during the
|
|
3021
|
-
* detach window is honored.
|
|
3022
|
-
*
|
|
3023
|
-
* @public
|
|
3024
|
-
*/
|
|
3025
|
-
declare function resumeStream(options: ResumeStreamOptions): Promise<ResumeStreamResult>;
|
|
3026
|
-
|
|
3027
|
-
interface StockPriceClassification {
|
|
3028
|
-
/** Whether the prompt likely asks for stock/ETF/FX quote data. */
|
|
3029
|
-
needsStockPrice: boolean;
|
|
3030
|
-
/** Cosine similarity to the "needs stock price" centroid. */
|
|
3031
|
-
stockPriceScore: number;
|
|
3032
|
-
/** Cosine similarity to the "no stock price" centroid. */
|
|
3033
|
-
noStockPriceScore: number;
|
|
3034
|
-
}
|
|
3035
|
-
interface StockPriceClassifierOptions extends EmbeddingOptions {
|
|
3036
|
-
/**
|
|
3037
|
-
* Score margin: the stock-price score must exceed the no-stock-price
|
|
3038
|
-
* score by at least this amount to classify as "needs stock price data".
|
|
3039
|
-
* @default 0.02
|
|
3040
|
-
*/
|
|
3041
|
-
margin?: number;
|
|
3042
|
-
}
|
|
3043
|
-
/**
|
|
3044
|
-
* Classify whether a prompt needs stock/ETF/index/FX price data.
|
|
3045
|
-
*
|
|
3046
|
-
* Domain: traditional financial instruments (equities, indices, ETFs, FX).
|
|
3047
|
-
* Crypto is handled by `classifyCryptoPrice`. Ambiguous prompts
|
|
3048
|
-
* (e.g. *"gold price"*) may fire both — that's expected; the caller can
|
|
3049
|
-
* inject both sets of results.
|
|
3050
|
-
*/
|
|
3051
|
-
declare function classifyStockPrice(prompt: string, options: StockPriceClassifierOptions): Promise<StockPriceClassification>;
|
|
3052
|
-
/**
|
|
3053
|
-
* Batch-classify multiple prompts. Embeds all prompts in one batch
|
|
3054
|
-
* call for efficiency.
|
|
3055
|
-
*/
|
|
3056
|
-
declare function classifyStockPriceBatch(prompts: string[], options: StockPriceClassifierOptions): Promise<StockPriceClassification[]>;
|
|
3057
|
-
interface StockPricePreProcessorOptions {
|
|
3058
|
-
/**
|
|
3059
|
-
* Called with the caller's stock-quote provider when the classifier
|
|
3060
|
-
* decides the prompt is asking for stock/ETF/FX data. Return either a
|
|
3061
|
-
* plain string (wrapped by the SDK in a default user message) or a
|
|
3062
|
-
* fully-formed `LlmapiMessage[]` (full control over role/shape). Omit
|
|
3063
|
-
* to run in observer mode — classification still fires but nothing is
|
|
3064
|
-
* injected.
|
|
3065
|
-
*
|
|
3066
|
-
* The `signal` argument is forwarded from the tool loop so long-running
|
|
3067
|
-
* provider requests can be aborted when the caller aborts.
|
|
3068
|
-
*/
|
|
3069
|
-
fetchStockPriceData?: (prompt: string, options: {
|
|
3070
|
-
signal?: AbortSignal;
|
|
3071
|
-
}) => Promise<string | LlmapiMessage[]>;
|
|
3072
|
-
/**
|
|
3073
|
-
* Score margin: `stockPriceScore` must exceed `noStockPriceScore` by at
|
|
3074
|
-
* least this amount to classify as "needs stock price data".
|
|
3075
|
-
* @default 0.02
|
|
3076
|
-
*/
|
|
3077
|
-
margin?: number;
|
|
3078
|
-
/** Observe the classification without injecting anything. */
|
|
3079
|
-
onClassification?: (result: StockPriceClassification) => void;
|
|
3080
|
-
}
|
|
3081
|
-
/**
|
|
3082
|
-
* Build a pre-processor that runs stock-price classification on the shared
|
|
3083
|
-
* embedding provided by `runToolLoop`, and — if the classifier decides the
|
|
3084
|
-
* prompt is asking for quotes — invokes the caller-supplied
|
|
3085
|
-
* `fetchStockPriceData` and injects the result into the conversation.
|
|
3086
|
-
*
|
|
3087
|
-
* Domain: stocks, ETFs, indices, FX. For crypto use
|
|
3088
|
-
* `createCryptoPricePreProcessor`. The SDK does not run the lookup itself;
|
|
3089
|
-
* the caller wires up whichever provider they want (Twelve Data, Alpha
|
|
3090
|
-
* Vantage, Finnhub, etc.).
|
|
3091
|
-
*/
|
|
3092
|
-
declare function createStockPricePreProcessor(options?: StockPricePreProcessorOptions): PromptPreProcessor;
|
|
3093
|
-
|
|
3094
|
-
/**
|
|
3095
|
-
* Value of the `origin` column on a row the SDK synthesised for a turn's tool results (v44, #866).
|
|
3096
|
-
*
|
|
3097
|
-
* `satisfies MessageOrigin` so this constant and the column's union cannot drift apart silently.
|
|
3098
|
-
*/
|
|
3099
|
-
declare const TOOL_RESULT_ORIGIN = "tool_result";
|
|
3100
|
-
|
|
3101
|
-
interface WeatherClassification {
|
|
3102
|
-
/** Whether the prompt likely asks for weather data. */
|
|
3103
|
-
needsWeather: boolean;
|
|
3104
|
-
/** Cosine similarity to the "needs weather" centroid. */
|
|
3105
|
-
weatherScore: number;
|
|
3106
|
-
/** Cosine similarity to the "no weather" centroid. */
|
|
3107
|
-
noWeatherScore: number;
|
|
3108
|
-
}
|
|
3109
|
-
interface WeatherClassifierOptions extends EmbeddingOptions {
|
|
3110
|
-
/**
|
|
3111
|
-
* Score margin: the weather score must exceed the no-weather score by at
|
|
3112
|
-
* least this amount to classify as "needs weather data".
|
|
3113
|
-
* @default 0.02
|
|
3114
|
-
*/
|
|
3115
|
-
margin?: number;
|
|
3116
|
-
}
|
|
3117
|
-
/**
|
|
3118
|
-
* Classify whether a prompt needs weather data.
|
|
3119
|
-
*
|
|
3120
|
-
* Covers forecasts, temperature, precipitation, wind, humidity, UV, AQI,
|
|
3121
|
-
* marine, flood, climate — anything OpenMeteo-shaped.
|
|
3122
|
-
*/
|
|
3123
|
-
declare function classifyWeather(prompt: string, options: WeatherClassifierOptions): Promise<WeatherClassification>;
|
|
3124
|
-
/**
|
|
3125
|
-
* Batch-classify multiple prompts. Embeds all prompts in one batch
|
|
3126
|
-
* call for efficiency.
|
|
3127
|
-
*/
|
|
3128
|
-
declare function classifyWeatherBatch(prompts: string[], options: WeatherClassifierOptions): Promise<WeatherClassification[]>;
|
|
3129
|
-
interface WeatherPreProcessorOptions {
|
|
3130
|
-
/**
|
|
3131
|
-
* Called with the caller's weather provider when the classifier decides
|
|
3132
|
-
* the prompt is asking for weather. Return either a plain string
|
|
3133
|
-
* (wrapped by the SDK in a default user message) or a fully-formed
|
|
3134
|
-
* `LlmapiMessage[]` (full control over role/shape). Omit to run in
|
|
3135
|
-
* observer mode — classification still fires but nothing is injected.
|
|
3136
|
-
*
|
|
3137
|
-
* The `signal` argument is forwarded from the tool loop so long-running
|
|
3138
|
-
* provider requests can be aborted when the caller aborts.
|
|
3139
|
-
*/
|
|
3140
|
-
fetchWeatherData?: (prompt: string, options: {
|
|
3141
|
-
signal?: AbortSignal;
|
|
3142
|
-
}) => Promise<string | LlmapiMessage[]>;
|
|
3143
|
-
/**
|
|
3144
|
-
* Score margin: `weatherScore` must exceed `noWeatherScore` by at least
|
|
3145
|
-
* this amount to classify as "needs weather data".
|
|
3146
|
-
* @default 0.02
|
|
3147
|
-
*/
|
|
3148
|
-
margin?: number;
|
|
3149
|
-
/** Observe the classification without injecting anything. */
|
|
3150
|
-
onClassification?: (result: WeatherClassification) => void;
|
|
3151
|
-
}
|
|
3152
|
-
/**
|
|
3153
|
-
* Build a pre-processor that runs weather classification on the shared
|
|
3154
|
-
* embedding provided by `runToolLoop`, and — if the classifier decides
|
|
3155
|
-
* the prompt is asking for weather — invokes the caller-supplied
|
|
3156
|
-
* `fetchWeatherData` and injects the result into the conversation.
|
|
3157
|
-
*
|
|
3158
|
-
* The SDK does not run the weather lookup itself; the caller wires up
|
|
3159
|
-
* whichever provider they want (OpenMeteo, AccuWeather, weather.gov, etc.).
|
|
3160
|
-
*/
|
|
3161
|
-
declare function createWeatherPreProcessor(options?: WeatherPreProcessorOptions): PromptPreProcessor;
|
|
3162
|
-
|
|
3163
|
-
interface WebSearchClassification {
|
|
3164
|
-
/** Whether the prompt likely needs a web search. */
|
|
3165
|
-
needsWebSearch: boolean;
|
|
3166
|
-
/** Cosine similarity to the "needs search" centroid. */
|
|
3167
|
-
searchScore: number;
|
|
3168
|
-
/** Cosine similarity to the "no search" centroid. */
|
|
3169
|
-
noSearchScore: number;
|
|
3170
|
-
}
|
|
3171
|
-
interface WebSearchClassifierOptions extends EmbeddingOptions {
|
|
3172
|
-
/**
|
|
3173
|
-
* Score margin: the search score must exceed the no-search score
|
|
3174
|
-
* by at least this amount to classify as "needs web search".
|
|
3175
|
-
* @default 0.02
|
|
3176
|
-
*/
|
|
3177
|
-
margin?: number;
|
|
3178
|
-
}
|
|
3179
|
-
/**
|
|
3180
|
-
* Classify whether a prompt needs a web search.
|
|
3181
|
-
*
|
|
3182
|
-
* Embeds the prompt and compares it against the pre-computed
|
|
3183
|
-
* search and no-search centroid vectors.
|
|
3184
|
-
*/
|
|
3185
|
-
declare function classifyWebSearch(prompt: string, options: WebSearchClassifierOptions): Promise<WebSearchClassification>;
|
|
3186
|
-
/**
|
|
3187
|
-
* Batch-classify multiple prompts. Embeds all prompts in one batch
|
|
3188
|
-
* call for efficiency.
|
|
3189
|
-
*/
|
|
3190
|
-
declare function classifyWebSearchBatch(prompts: string[], options: WebSearchClassifierOptions): Promise<WebSearchClassification[]>;
|
|
3191
|
-
interface WebSearchPreProcessorOptions {
|
|
3192
|
-
/**
|
|
3193
|
-
* Called with the caller's search provider when the classifier decides
|
|
3194
|
-
* a web search is needed. Return either a plain string (the SDK will
|
|
3195
|
-
* wrap it in a default user message) or a fully-formed message array
|
|
3196
|
-
* (full control over role/shape). Omit to run in observer mode —
|
|
3197
|
-
* classification still fires but no messages are injected.
|
|
3198
|
-
*
|
|
3199
|
-
* The `signal` argument is forwarded from the tool loop so long-running
|
|
3200
|
-
* search requests can be aborted when the caller aborts.
|
|
3201
|
-
*/
|
|
3202
|
-
fetchSearchResults?: (prompt: string, options: {
|
|
3203
|
-
signal?: AbortSignal;
|
|
3204
|
-
}) => Promise<string | LlmapiMessage[]>;
|
|
3205
|
-
/**
|
|
3206
|
-
* Score margin: `searchScore` must exceed `noSearchScore` by at least
|
|
3207
|
-
* this amount to classify as "needs web search".
|
|
3208
|
-
* @default 0.02
|
|
3209
|
-
*/
|
|
3210
|
-
margin?: number;
|
|
3211
|
-
/** Observe the classification without injecting anything. */
|
|
3212
|
-
onClassification?: (result: WebSearchClassification) => void;
|
|
3213
|
-
}
|
|
3214
|
-
/**
|
|
3215
|
-
* Build a pre-processor that runs web-search classification on the
|
|
3216
|
-
* shared embedding provided by `runToolLoop`, and — if the classifier
|
|
3217
|
-
* decides a search is warranted — invokes the caller-supplied
|
|
3218
|
-
* `fetchSearchResults` and injects the result into the conversation.
|
|
3219
|
-
*
|
|
3220
|
-
* @example Basic usage with a search provider
|
|
3221
|
-
* ```ts
|
|
3222
|
-
* import { runToolLoop, createWebSearchPreProcessor } from "@anuma/sdk/server";
|
|
3223
|
-
*
|
|
3224
|
-
* const webSearch = createWebSearchPreProcessor({
|
|
3225
|
-
* fetchSearchResults: async (prompt, { signal }) => {
|
|
3226
|
-
* const res = await mySearchProvider.query(prompt, { signal });
|
|
3227
|
-
* return res.results.map((r) => `- ${r.title}: ${r.snippet}`).join("\n");
|
|
3228
|
-
* },
|
|
3229
|
-
* });
|
|
3230
|
-
*
|
|
3231
|
-
* await runToolLoop({
|
|
3232
|
-
* messages,
|
|
3233
|
-
* model,
|
|
3234
|
-
* token,
|
|
3235
|
-
* preProcessors: [webSearch],
|
|
3236
|
-
* });
|
|
3237
|
-
* ```
|
|
3238
|
-
*
|
|
3239
|
-
* @example Observer mode — only log classification, inject nothing
|
|
3240
|
-
* ```ts
|
|
3241
|
-
* const observer = createWebSearchPreProcessor({
|
|
3242
|
-
* onClassification: ({ needsWebSearch, searchScore, noSearchScore }) => {
|
|
3243
|
-
* metrics.record({ needsWebSearch, searchScore, noSearchScore });
|
|
3244
|
-
* },
|
|
3245
|
-
* });
|
|
3246
|
-
* ```
|
|
3247
|
-
*
|
|
3248
|
-
* @example Full control — return a custom message shape
|
|
3249
|
-
* ```ts
|
|
3250
|
-
* const webSearch = createWebSearchPreProcessor({
|
|
3251
|
-
* fetchSearchResults: async (prompt, { signal }) => {
|
|
3252
|
-
* const results = await mySearchProvider.query(prompt, { signal });
|
|
3253
|
-
* return [
|
|
3254
|
-
* {
|
|
3255
|
-
* role: "system",
|
|
3256
|
-
* content: [{ type: "text", text: `Search results for "${prompt}":\n${formatResults(results)}` }],
|
|
3257
|
-
* },
|
|
3258
|
-
* ];
|
|
3259
|
-
* },
|
|
3260
|
-
* });
|
|
3261
|
-
* ```
|
|
3262
|
-
*/
|
|
3263
|
-
declare function createWebSearchPreProcessor(options?: WebSearchPreProcessorOptions): PromptPreProcessor;
|
|
3264
|
-
|
|
3265
2791
|
type ChatRecordKind = "conversation" | "message" | "summary" | "project" | "memory_links" | "setting";
|
|
3266
2792
|
type ChatJson = null | boolean | number | string | ChatJson[] | {
|
|
3267
2793
|
[key: string]: ChatJson;
|
|
@@ -5073,7 +4599,7 @@ interface ChatStorageAdapter {
|
|
|
5073
4599
|
createMessage(options: CreateMessageOptions): Promise<StoredMessage>;
|
|
5074
4600
|
updateMessageEmbedding(uniqueId: string, vector: number[], embeddingModel: string): Promise<StoredMessage | null>;
|
|
5075
4601
|
updateMessageChunks(uniqueId: string, chunks: MessageChunk[], embeddingModel: string): Promise<StoredMessage | null>;
|
|
5076
|
-
updateMessageError(uniqueId: string, error: string): Promise<StoredMessage | null>;
|
|
4602
|
+
updateMessageError(uniqueId: string, error: string | null): Promise<StoredMessage | null>;
|
|
5077
4603
|
updateMessageFeedback(uniqueId: string, feedback: MessageFeedback): Promise<StoredMessage | null>;
|
|
5078
4604
|
/**
|
|
5079
4605
|
* Replace a message's attached media ids (`fileIds`). Used to attach a
|
|
@@ -9293,132 +8819,618 @@ interface BaseSendMessageWithStorageArgs {
|
|
|
9293
8819
|
*/
|
|
9294
8820
|
thoughtProcess?: ActivityPhase[];
|
|
9295
8821
|
/**
|
|
9296
|
-
* Callback to get activity phases AFTER streaming completes.
|
|
9297
|
-
* Use this instead of `thoughtProcess` when phases are added dynamically during streaming
|
|
9298
|
-
* (e.g., via server tool call events like "Searching...", "Generating image...").
|
|
9299
|
-
*
|
|
9300
|
-
* If both `thoughtProcess` and `getThoughtProcess` are provided, `getThoughtProcess` takes precedence.
|
|
8822
|
+
* Callback to get activity phases AFTER streaming completes.
|
|
8823
|
+
* Use this instead of `thoughtProcess` when phases are added dynamically during streaming
|
|
8824
|
+
* (e.g., via server tool call events like "Searching...", "Generating image...").
|
|
8825
|
+
*
|
|
8826
|
+
* If both `thoughtProcess` and `getThoughtProcess` are provided, `getThoughtProcess` takes precedence.
|
|
8827
|
+
*/
|
|
8828
|
+
getThoughtProcess?: () => ActivityPhase[];
|
|
8829
|
+
/**
|
|
8830
|
+
* Controls randomness in the response (0.0 to 2.0).
|
|
8831
|
+
* Lower values make output more deterministic, higher values more creative.
|
|
8832
|
+
*/
|
|
8833
|
+
temperature?: number;
|
|
8834
|
+
/**
|
|
8835
|
+
* Maximum number of tokens to generate in the response.
|
|
8836
|
+
* Use this to limit response length and control costs.
|
|
8837
|
+
*/
|
|
8838
|
+
maxOutputTokens?: number;
|
|
8839
|
+
/**
|
|
8840
|
+
* Client-side tools with optional executors.
|
|
8841
|
+
* These tools run in the browser/app and can have JavaScript executor functions.
|
|
8842
|
+
*/
|
|
8843
|
+
clientTools?: LlmapiChatCompletionTool[];
|
|
8844
|
+
/**
|
|
8845
|
+
* Server-side tools to include from /api/v1/tools.
|
|
8846
|
+
* - undefined: Include all server-side tools (default)
|
|
8847
|
+
* - string[]: Include only tools with these names
|
|
8848
|
+
* - []: Include no server-side tools
|
|
8849
|
+
* - function: Dynamic filter that receives prompt embedding(s) and all tools,
|
|
8850
|
+
* returns tool names to include. Useful for semantic tool matching.
|
|
8851
|
+
*
|
|
8852
|
+
* @example
|
|
8853
|
+
* // Include only specific server tools
|
|
8854
|
+
* serverTools: ["anuma_create_image", "perplexity_search"]
|
|
8855
|
+
*
|
|
8856
|
+
* // Disable server tools for this request
|
|
8857
|
+
* serverTools: []
|
|
8858
|
+
*
|
|
8859
|
+
* // Semantic tool matching based on prompt
|
|
8860
|
+
* serverTools: (embeddings, tools) => {
|
|
8861
|
+
* const matches = findMatchingTools(embeddings, tools, { limit: 5 });
|
|
8862
|
+
* return matches.map(m => m.tool.name);
|
|
8863
|
+
* }
|
|
8864
|
+
*/
|
|
8865
|
+
serverTools?: ServerToolsFilter;
|
|
8866
|
+
/**
|
|
8867
|
+
* Dynamic filter for client-side tools based on prompt embeddings.
|
|
8868
|
+
* Receives the prompt embedding(s) (or null for short messages) and all client tools,
|
|
8869
|
+
* returns tool names to include. Tools not in the returned list are excluded from the request.
|
|
8870
|
+
*
|
|
8871
|
+
* @example
|
|
8872
|
+
* clientToolsFilter: (embeddings, tools) => {
|
|
8873
|
+
* if (!embeddings) return []; // Short message — no client tools
|
|
8874
|
+
* const matches = findMatchingTools(embeddings, pseudoServerTools);
|
|
8875
|
+
* return matches.map(m => m.tool.name);
|
|
8876
|
+
* }
|
|
8877
|
+
*/
|
|
8878
|
+
clientToolsFilter?: ClientToolsFilterFn;
|
|
8879
|
+
/**
|
|
8880
|
+
* Controls which tool the model should use:
|
|
8881
|
+
* - "auto": Model decides whether to use a tool (default)
|
|
8882
|
+
* - "any": Model must use one of the provided tools
|
|
8883
|
+
* - "none": Model cannot use any tools
|
|
8884
|
+
* - "required": Model must use a tool
|
|
8885
|
+
* - Specific tool name: Model must use that specific tool
|
|
8886
|
+
*/
|
|
8887
|
+
toolChoice?: string;
|
|
8888
|
+
/**
|
|
8889
|
+
* Maximum number of tool execution rounds before forcing the model to respond with text.
|
|
8890
|
+
* After this many rounds, `toolChoice` is set to `"none"` on the next continuation,
|
|
8891
|
+
* so the model produces a text answer using whatever tool results it has gathered.
|
|
8892
|
+
* @default 3
|
|
8893
|
+
*/
|
|
8894
|
+
maxToolRounds?: number;
|
|
8895
|
+
/**
|
|
8896
|
+
* Reasoning configuration for o-series and other reasoning models.
|
|
8897
|
+
* Controls reasoning effort level and whether to include reasoning summary.
|
|
8898
|
+
*/
|
|
8899
|
+
reasoning?: LlmapiResponseReasoning;
|
|
8900
|
+
/**
|
|
8901
|
+
* Extended thinking configuration for Anthropic models (Claude).
|
|
8902
|
+
* Enables the model to think through complex problems step by step
|
|
8903
|
+
* before generating the final response.
|
|
8904
|
+
*/
|
|
8905
|
+
thinking?: LlmapiThinkingOptions;
|
|
8906
|
+
/** User-selected image generation model for server-side enforcement. */
|
|
8907
|
+
imageModel?: string;
|
|
8908
|
+
/**
|
|
8909
|
+
* Per-request callback for thinking/reasoning chunks.
|
|
8910
|
+
* Called with delta chunks as the model "thinks" through a problem.
|
|
8911
|
+
* Use this to display thinking progress in the UI.
|
|
8912
|
+
*/
|
|
8913
|
+
onThinking?: (chunk: string) => void;
|
|
8914
|
+
/** Parent message ID for branching (edit/regenerate). Sets on the user message. */
|
|
8915
|
+
parentMessageId?: string;
|
|
8916
|
+
/**
|
|
8917
|
+
* Pre-generated unique ID for the assistant response message.
|
|
8918
|
+
* When provided, the persisted assistant message will use this ID instead of
|
|
8919
|
+
* an auto-generated one. This lets the consumer show an in-flight streaming
|
|
8920
|
+
* placeholder under the same React key, avoiding an unmount/remount flash
|
|
8921
|
+
* when streaming completes and the message is loaded from the database.
|
|
8922
|
+
*/
|
|
8923
|
+
assistantUniqueId?: string;
|
|
8924
|
+
}
|
|
8925
|
+
interface BaseUseChatStorageResult {
|
|
8926
|
+
isLoading: boolean;
|
|
8927
|
+
stop: () => void;
|
|
8928
|
+
conversationId: string | null;
|
|
8929
|
+
setConversationId: (id: string | null) => void;
|
|
8930
|
+
createConversation: (options?: CreateConversationOptions) => Promise<StoredConversation>;
|
|
8931
|
+
getConversation: (id: string) => Promise<StoredConversation | null>;
|
|
8932
|
+
getConversations: () => Promise<StoredConversation[]>;
|
|
8933
|
+
updateConversationTitle: (id: string, title: string) => Promise<boolean>;
|
|
8934
|
+
updateConversationPinned: (id: string, pinned: boolean) => Promise<boolean>;
|
|
8935
|
+
deleteConversation: (id: string) => Promise<boolean>;
|
|
8936
|
+
getMessages: (conversationId: string) => Promise<StoredMessage[]>;
|
|
8937
|
+
/**
|
|
8938
|
+
* Paginated display read: the newest `limit` messages (optionally below
|
|
8939
|
+
* `beforeMessageId`), ascending, with embedding columns skipped.
|
|
8940
|
+
*/
|
|
8941
|
+
getMessagesPage: (conversationId: string, options: GetMessagesPageOptions) => Promise<StoredMessage[]>;
|
|
8942
|
+
/** Whole-thread branch-tree skeleton — no field decryption. */
|
|
8943
|
+
getMessageSkeletons: (conversationId: string) => Promise<MessageSkeleton[]>;
|
|
8944
|
+
/** Total message count for a conversation. */
|
|
8945
|
+
getMessageCount: (conversationId: string) => Promise<number>;
|
|
8946
|
+
}
|
|
8947
|
+
declare function generateConversationId(): string;
|
|
8948
|
+
|
|
8949
|
+
/**
|
|
8950
|
+
* A finished background answer, as portal sealed it into the vault inbox.
|
|
8951
|
+
* @public
|
|
8952
|
+
*/
|
|
8953
|
+
type InboxPlaintext = {
|
|
8954
|
+
v: 1;
|
|
8955
|
+
inference_id: string;
|
|
8956
|
+
conversation_id: string;
|
|
8957
|
+
parent_message_id: string | null;
|
|
8958
|
+
assistant_message_id?: string | null;
|
|
8959
|
+
api_type: "responses" | "completions";
|
|
8960
|
+
model: string;
|
|
8961
|
+
status: "completed" | "tool_request";
|
|
8962
|
+
pending_tool: string | null;
|
|
8963
|
+
response: ApiResponse;
|
|
8964
|
+
finished_at: string;
|
|
8965
|
+
};
|
|
8966
|
+
/**
|
|
8967
|
+
* One sealed item in the vault inbox.
|
|
8968
|
+
* @public
|
|
8969
|
+
*/
|
|
8970
|
+
type InboxItem = {
|
|
8971
|
+
id: string;
|
|
8972
|
+
sealed: string;
|
|
8973
|
+
created_at: string;
|
|
8974
|
+
};
|
|
8975
|
+
/**
|
|
8976
|
+
* The account's vault inbox and the public key portal seals answers to.
|
|
8977
|
+
* @public
|
|
8978
|
+
*/
|
|
8979
|
+
interface VaultInbox {
|
|
8980
|
+
putPublicKey(publicKey: string): Promise<void>;
|
|
8981
|
+
list(): Promise<InboxItem[]>;
|
|
8982
|
+
remove(id: string): Promise<void>;
|
|
8983
|
+
}
|
|
8984
|
+
/**
|
|
8985
|
+
* The vault inbox client, under the same `/api/private-chats` routes as the chat store.
|
|
8986
|
+
* @public
|
|
8987
|
+
*/
|
|
8988
|
+
declare function createVaultInbox(options: {
|
|
8989
|
+
baseUrl: string;
|
|
8990
|
+
getToken: () => Promise<string | null>;
|
|
8991
|
+
fetch?: typeof globalThis.fetch;
|
|
8992
|
+
timeoutMs?: number;
|
|
8993
|
+
}): VaultInbox;
|
|
8994
|
+
/** The 65-byte uncompressed P-256 point, base64url, as vault stores it. */
|
|
8995
|
+
declare function exportInboxPublicKey(publicKey: CryptoKey): Promise<string>;
|
|
8996
|
+
/** Decrypt a sealed inbox item with the account's ECDH key pair. */
|
|
8997
|
+
declare function openInboxItem(item: Pick<InboxItem, "id" | "sealed">, keyPair: CryptoKeyPair): Promise<InboxPlaintext>;
|
|
8998
|
+
/**
|
|
8999
|
+
* Outcome of delivering one vault inbox item.
|
|
9000
|
+
* @public
|
|
9001
|
+
*/
|
|
9002
|
+
type InboxDeliveryResult = {
|
|
9003
|
+
id: string;
|
|
9004
|
+
conversationId: string | null;
|
|
9005
|
+
status: "stored" | "delivered" | "elsewhere" | "unreadable" | "retry";
|
|
9006
|
+
assistantMessage: StoredMessage | null;
|
|
9007
|
+
error?: string;
|
|
9008
|
+
};
|
|
9009
|
+
|
|
9010
|
+
/**
|
|
9011
|
+
* What became of a restaurant booking or cancellation in one turn, read from
|
|
9012
|
+
* the server's own tool result rather than from the model's reply.
|
|
9013
|
+
*/
|
|
9014
|
+
type ReservationReceipt = {
|
|
9015
|
+
kind: "booking" | "cancel";
|
|
9016
|
+
/**
|
|
9017
|
+
* `made`: the provider confirmed it. `not_made`: it did not happen.
|
|
9018
|
+
* `already_done`: an earlier call in the conversation had already done it.
|
|
9019
|
+
* `unknown`: the call reached the provider and its outcome is not known.
|
|
9301
9020
|
*/
|
|
9302
|
-
|
|
9021
|
+
status: "made" | "not_made" | "already_done" | "unknown";
|
|
9022
|
+
venueName: string;
|
|
9023
|
+
/** As the call sent it, e.g. `2026-10-23`. */
|
|
9024
|
+
day: string;
|
|
9025
|
+
/** As the call sent it, e.g. `9:00 PM`. */
|
|
9026
|
+
time: string;
|
|
9027
|
+
partySize?: number;
|
|
9028
|
+
reservationId?: string;
|
|
9029
|
+
/** Resy page where the user can see the reservation. */
|
|
9030
|
+
resyUrl?: string;
|
|
9031
|
+
/** The restaurant's own cancellation terms, when the booking result carries them. */
|
|
9032
|
+
feeSummary?: string;
|
|
9033
|
+
/** The provider's stated reason, when it did not happen. */
|
|
9034
|
+
reason?: string;
|
|
9035
|
+
};
|
|
9036
|
+
/** One receipt per kind for the turn's booking and cancel calls, holding the last attempt's outcome unless an earlier one was `made` or `unknown`. */
|
|
9037
|
+
declare function extractReservationReceipts(toolCallEvents?: LlmapiToolCallEvent[]): ReservationReceipt[];
|
|
9038
|
+
|
|
9039
|
+
/**
|
|
9040
|
+
* Build the replay path for a detached stream. The portal serves the buffered
|
|
9041
|
+
* stream from seq 0 on a GET to this path — no `starting_after`, no `id:`
|
|
9042
|
+
* cursor, no request body. Replay always starts from the first buffered byte
|
|
9043
|
+
* and the client rebuilds its own view with a fresh accumulator; partial
|
|
9044
|
+
* client state is never sent back to the server.
|
|
9045
|
+
*
|
|
9046
|
+
* Exported so client repos can mock the endpoint in E2E without string drift.
|
|
9047
|
+
*/
|
|
9048
|
+
declare function streamReplayPath(inferenceId: string): string;
|
|
9049
|
+
/**
|
|
9050
|
+
* Build the cancel path for a detached stream. A POST here tells the portal to
|
|
9051
|
+
* stop generating into the buffer and release it — the billing-safe teardown
|
|
9052
|
+
* for "the user pressed stop after we'd already detached".
|
|
9053
|
+
*
|
|
9054
|
+
* Exported so client repos can mock the endpoint in E2E without string drift.
|
|
9055
|
+
*/
|
|
9056
|
+
declare function streamCancelPath(inferenceId: string): string;
|
|
9057
|
+
/**
|
|
9058
|
+
* A generation still running on the portal for the caller.
|
|
9059
|
+
* @public
|
|
9060
|
+
*/
|
|
9061
|
+
type ActiveStream = {
|
|
9062
|
+
inferenceId: string;
|
|
9063
|
+
assistantMessageId: string | null;
|
|
9064
|
+
conversationId: string | null;
|
|
9065
|
+
parentMessageId: string | null;
|
|
9066
|
+
apiType: "responses" | "completions";
|
|
9067
|
+
model?: string;
|
|
9068
|
+
startedAt: string;
|
|
9069
|
+
};
|
|
9070
|
+
/** List the caller's generations still running on the portal. */
|
|
9071
|
+
declare function listActiveStreams(options: {
|
|
9072
|
+
token: string;
|
|
9073
|
+
baseUrl?: string;
|
|
9074
|
+
conversationId?: string;
|
|
9075
|
+
fetch?: typeof globalThis.fetch;
|
|
9076
|
+
}): Promise<ActiveStream[]>;
|
|
9077
|
+
/**
|
|
9078
|
+
* Thrown when the portal answers `410 Gone` to a replay GET: the buffered
|
|
9079
|
+
* stream is gone — expired (10-min sliding TTL), absent, not owned by the
|
|
9080
|
+
* caller, or already cancelled. There is nothing to replay; the answer is
|
|
9081
|
+
* permanently lost and the caller should fall back to a fresh send rather than
|
|
9082
|
+
* retry. A `stop()`-then-resume race lands here and finalizes as stopped, which
|
|
9083
|
+
* is correct.
|
|
9084
|
+
*
|
|
9085
|
+
* `resumeStream` throws this (it does not return it) and fires neither
|
|
9086
|
+
* `onFinish` nor `onError` — there is no body to deliver.
|
|
9087
|
+
* @public
|
|
9088
|
+
*/
|
|
9089
|
+
declare class StreamExpiredError extends Error {
|
|
9090
|
+
readonly name = "StreamExpiredError";
|
|
9091
|
+
readonly inferenceId: string;
|
|
9092
|
+
constructor(inferenceId: string, message?: string);
|
|
9093
|
+
}
|
|
9094
|
+
/**
|
|
9095
|
+
* Options for {@link resumeStream}.
|
|
9096
|
+
* @public
|
|
9097
|
+
*/
|
|
9098
|
+
interface ResumeStreamOptions {
|
|
9099
|
+
/** The handle captured from a detached `runToolLoop` result. */
|
|
9100
|
+
handle: StreamResumeHandle;
|
|
9303
9101
|
/**
|
|
9304
|
-
*
|
|
9305
|
-
*
|
|
9102
|
+
* Fresh bearer token. The CALLER fetches it at resume time — a multi-minute
|
|
9103
|
+
* background gap expires the bearer, so a token captured when the original
|
|
9104
|
+
* stream started must never be reused (see `useChat.resumeStream`).
|
|
9306
9105
|
*/
|
|
9307
|
-
|
|
9106
|
+
token: string;
|
|
9107
|
+
/** Base URL for the portal. @default the SDK's configured BASE_URL. */
|
|
9108
|
+
baseUrl?: string;
|
|
9308
9109
|
/**
|
|
9309
|
-
*
|
|
9310
|
-
*
|
|
9110
|
+
* Streaming transport. Defaults to the GET-capable fetch transport; Expo
|
|
9111
|
+
* passes `xhrTransport` (RN can't stream `fetch` bodies).
|
|
9311
9112
|
*/
|
|
9312
|
-
|
|
9113
|
+
transport?: StreamingTransport;
|
|
9114
|
+
/** Aborts the replay; the partial is returned as an interrupted result. */
|
|
9115
|
+
signal?: AbortSignal;
|
|
9116
|
+
/** Adaptive output smoothing for the replayed content. @default true */
|
|
9117
|
+
smoothing?: StreamSmoothingConfig | boolean;
|
|
9313
9118
|
/**
|
|
9314
|
-
* Client-side
|
|
9315
|
-
*
|
|
9119
|
+
* Client-side watchdog for a dead live-tail. @default 120_000ms.
|
|
9120
|
+
*
|
|
9121
|
+
* Deliberately NOT ~30s: the portal tolerates >100s reasoning silences (no
|
|
9122
|
+
* `data:` frames on the replay connection during them) and its own liveness
|
|
9123
|
+
* rule (heartbeat stale >90s => SSE error + `[DONE]`) is the authoritative
|
|
9124
|
+
* guard. This client timer is a backstop for a half-open TCP connection and
|
|
9125
|
+
* must sit ABOVE the server's 90s rule so the server error always wins when
|
|
9126
|
+
* the portal is reachable. Set to 0 / Infinity to disable.
|
|
9316
9127
|
*/
|
|
9317
|
-
|
|
9128
|
+
idleTimeoutMs?: number;
|
|
9129
|
+
/** Content text deltas as they replay (always from seq 0 — reset accumulated text first). */
|
|
9130
|
+
onData?: (chunk: string) => void;
|
|
9131
|
+
/** Thinking/reasoning deltas as they replay. */
|
|
9132
|
+
onThinking?: (chunk: string) => void;
|
|
9133
|
+
/** Restores the placeholders this redactor assigned when the original request was sent. */
|
|
9134
|
+
piiRedactor?: PiiRedactor;
|
|
9135
|
+
/** Called once on a clean completion. Never called for 410 nor interrupted terminals. */
|
|
9136
|
+
onFinish?: (response: ApiResponse) => void;
|
|
9137
|
+
/** Called on a transient/unexpected failure. Never called for 410 (throws) nor interrupted terminals. */
|
|
9138
|
+
onError?: (error: Error) => void;
|
|
9139
|
+
}
|
|
9140
|
+
/**
|
|
9141
|
+
* Result of {@link resumeStream}. A `410 Gone` is the only outcome that throws
|
|
9142
|
+
* ({@link StreamExpiredError}); every other terminal is returned.
|
|
9143
|
+
*
|
|
9144
|
+
* - clean completion → `{ data, error: null, interrupted: false, empty }`
|
|
9145
|
+
* - in-stream error / tool-request terminal / idle timeout → `{ data, error,
|
|
9146
|
+
* interrupted: true }` (finalize as a stopped/partial message)
|
|
9147
|
+
* - transient transport/HTTP failure (401, 5xx, network) → `{ data, error,
|
|
9148
|
+
* interrupted: false, statusCode? }` (retryable — keep the handle)
|
|
9149
|
+
*
|
|
9150
|
+
* `empty` is true when the clean terminal delivered ZERO content/thinking
|
|
9151
|
+
* deltas — a `[DONE]`-only replay. That is never a real completion (a
|
|
9152
|
+
* completed generation always buffered at least one content frame); it means
|
|
9153
|
+
* the buffered frames were lost server-side (evicted/trimmed) while the
|
|
9154
|
+
* terminal survived. Consumers must NOT persist `data` (an empty response)
|
|
9155
|
+
* over content they already hold — keep the detached partial instead. On the
|
|
9156
|
+
* empty terminal `onFinish` is NOT fired (there is no completion to deliver);
|
|
9157
|
+
* the flag is optional so existing constructors of the clean arm stay valid.
|
|
9158
|
+
* @public
|
|
9159
|
+
*/
|
|
9160
|
+
type ResumeStreamResult = {
|
|
9161
|
+
data: ApiResponse;
|
|
9162
|
+
error: null;
|
|
9163
|
+
interrupted: false;
|
|
9164
|
+
empty?: boolean;
|
|
9165
|
+
} | {
|
|
9166
|
+
data: ApiResponse | null;
|
|
9167
|
+
error: string;
|
|
9168
|
+
interrupted: boolean;
|
|
9169
|
+
statusCode?: number;
|
|
9170
|
+
};
|
|
9171
|
+
/**
|
|
9172
|
+
* Replay a detached stream from the portal's buffer.
|
|
9173
|
+
*
|
|
9174
|
+
* This is the reconnect primitive: after `runToolLoop` returns the detached
|
|
9175
|
+
* variant with a {@link StreamResumeHandle}, `resumeStream` issues a GET to the
|
|
9176
|
+
* portal's replay endpoint and rebuilds the response from seq 0 using a FRESH
|
|
9177
|
+
* accumulator and FRESH smoothers. Nothing from the original (detached) run is
|
|
9178
|
+
* reused — the completions strategy's reasoning-tag parser is stateful, so
|
|
9179
|
+
* replaying into reused state would double-count; replay-from-0 into fresh
|
|
9180
|
+
* state is the correctness mechanism, not just a simplification.
|
|
9181
|
+
*
|
|
9182
|
+
* Contract highlights:
|
|
9183
|
+
* - **No `starting_after`, no `id:` cursor, no body.** The GET carries the
|
|
9184
|
+
* inference id in the path only; replay is always whole-stream. (The server
|
|
9185
|
+
* reserves `starting_after` but does NOT honor it — sending it would silently
|
|
9186
|
+
* duplicate content.)
|
|
9187
|
+
* - **410 → throws {@link StreamExpiredError}.** No `onFinish`/`onError`.
|
|
9188
|
+
* - **In-stream error / tool-request terminal → `interrupted: true`.** Flushes
|
|
9189
|
+
* both smoothers and returns the partial; no throw, no `onError`, no `onFinish`.
|
|
9190
|
+
* - **token resolved by the caller at resume time** so a refresh during the
|
|
9191
|
+
* detach window is honored.
|
|
9192
|
+
*
|
|
9193
|
+
* @public
|
|
9194
|
+
*/
|
|
9195
|
+
declare function resumeStream(options: ResumeStreamOptions): Promise<ResumeStreamResult>;
|
|
9196
|
+
|
|
9197
|
+
interface StockPriceClassification {
|
|
9198
|
+
/** Whether the prompt likely asks for stock/ETF/FX quote data. */
|
|
9199
|
+
needsStockPrice: boolean;
|
|
9200
|
+
/** Cosine similarity to the "needs stock price" centroid. */
|
|
9201
|
+
stockPriceScore: number;
|
|
9202
|
+
/** Cosine similarity to the "no stock price" centroid. */
|
|
9203
|
+
noStockPriceScore: number;
|
|
9204
|
+
}
|
|
9205
|
+
interface StockPriceClassifierOptions extends EmbeddingOptions {
|
|
9318
9206
|
/**
|
|
9319
|
-
*
|
|
9320
|
-
*
|
|
9321
|
-
*
|
|
9322
|
-
* - []: Include no server-side tools
|
|
9323
|
-
* - function: Dynamic filter that receives prompt embedding(s) and all tools,
|
|
9324
|
-
* returns tool names to include. Useful for semantic tool matching.
|
|
9325
|
-
*
|
|
9326
|
-
* @example
|
|
9327
|
-
* // Include only specific server tools
|
|
9328
|
-
* serverTools: ["anuma_create_image", "perplexity_search"]
|
|
9329
|
-
*
|
|
9330
|
-
* // Disable server tools for this request
|
|
9331
|
-
* serverTools: []
|
|
9332
|
-
*
|
|
9333
|
-
* // Semantic tool matching based on prompt
|
|
9334
|
-
* serverTools: (embeddings, tools) => {
|
|
9335
|
-
* const matches = findMatchingTools(embeddings, tools, { limit: 5 });
|
|
9336
|
-
* return matches.map(m => m.tool.name);
|
|
9337
|
-
* }
|
|
9207
|
+
* Score margin: the stock-price score must exceed the no-stock-price
|
|
9208
|
+
* score by at least this amount to classify as "needs stock price data".
|
|
9209
|
+
* @default 0.02
|
|
9338
9210
|
*/
|
|
9339
|
-
|
|
9211
|
+
margin?: number;
|
|
9212
|
+
}
|
|
9213
|
+
/**
|
|
9214
|
+
* Classify whether a prompt needs stock/ETF/index/FX price data.
|
|
9215
|
+
*
|
|
9216
|
+
* Domain: traditional financial instruments (equities, indices, ETFs, FX).
|
|
9217
|
+
* Crypto is handled by `classifyCryptoPrice`. Ambiguous prompts
|
|
9218
|
+
* (e.g. *"gold price"*) may fire both — that's expected; the caller can
|
|
9219
|
+
* inject both sets of results.
|
|
9220
|
+
*/
|
|
9221
|
+
declare function classifyStockPrice(prompt: string, options: StockPriceClassifierOptions): Promise<StockPriceClassification>;
|
|
9222
|
+
/**
|
|
9223
|
+
* Batch-classify multiple prompts. Embeds all prompts in one batch
|
|
9224
|
+
* call for efficiency.
|
|
9225
|
+
*/
|
|
9226
|
+
declare function classifyStockPriceBatch(prompts: string[], options: StockPriceClassifierOptions): Promise<StockPriceClassification[]>;
|
|
9227
|
+
interface StockPricePreProcessorOptions {
|
|
9340
9228
|
/**
|
|
9341
|
-
*
|
|
9342
|
-
*
|
|
9343
|
-
*
|
|
9229
|
+
* Called with the caller's stock-quote provider when the classifier
|
|
9230
|
+
* decides the prompt is asking for stock/ETF/FX data. Return either a
|
|
9231
|
+
* plain string (wrapped by the SDK in a default user message) or a
|
|
9232
|
+
* fully-formed `LlmapiMessage[]` (full control over role/shape). Omit
|
|
9233
|
+
* to run in observer mode — classification still fires but nothing is
|
|
9234
|
+
* injected.
|
|
9344
9235
|
*
|
|
9345
|
-
*
|
|
9346
|
-
*
|
|
9347
|
-
* if (!embeddings) return []; // Short message — no client tools
|
|
9348
|
-
* const matches = findMatchingTools(embeddings, pseudoServerTools);
|
|
9349
|
-
* return matches.map(m => m.tool.name);
|
|
9350
|
-
* }
|
|
9236
|
+
* The `signal` argument is forwarded from the tool loop so long-running
|
|
9237
|
+
* provider requests can be aborted when the caller aborts.
|
|
9351
9238
|
*/
|
|
9352
|
-
|
|
9239
|
+
fetchStockPriceData?: (prompt: string, options: {
|
|
9240
|
+
signal?: AbortSignal;
|
|
9241
|
+
}) => Promise<string | LlmapiMessage[]>;
|
|
9353
9242
|
/**
|
|
9354
|
-
*
|
|
9355
|
-
*
|
|
9356
|
-
*
|
|
9357
|
-
* - "none": Model cannot use any tools
|
|
9358
|
-
* - "required": Model must use a tool
|
|
9359
|
-
* - Specific tool name: Model must use that specific tool
|
|
9243
|
+
* Score margin: `stockPriceScore` must exceed `noStockPriceScore` by at
|
|
9244
|
+
* least this amount to classify as "needs stock price data".
|
|
9245
|
+
* @default 0.02
|
|
9360
9246
|
*/
|
|
9361
|
-
|
|
9247
|
+
margin?: number;
|
|
9248
|
+
/** Observe the classification without injecting anything. */
|
|
9249
|
+
onClassification?: (result: StockPriceClassification) => void;
|
|
9250
|
+
}
|
|
9251
|
+
/**
|
|
9252
|
+
* Build a pre-processor that runs stock-price classification on the shared
|
|
9253
|
+
* embedding provided by `runToolLoop`, and — if the classifier decides the
|
|
9254
|
+
* prompt is asking for quotes — invokes the caller-supplied
|
|
9255
|
+
* `fetchStockPriceData` and injects the result into the conversation.
|
|
9256
|
+
*
|
|
9257
|
+
* Domain: stocks, ETFs, indices, FX. For crypto use
|
|
9258
|
+
* `createCryptoPricePreProcessor`. The SDK does not run the lookup itself;
|
|
9259
|
+
* the caller wires up whichever provider they want (Twelve Data, Alpha
|
|
9260
|
+
* Vantage, Finnhub, etc.).
|
|
9261
|
+
*/
|
|
9262
|
+
declare function createStockPricePreProcessor(options?: StockPricePreProcessorOptions): PromptPreProcessor;
|
|
9263
|
+
|
|
9264
|
+
/**
|
|
9265
|
+
* Value of the `origin` column on a row the SDK synthesised for a turn's tool results (v44, #866).
|
|
9266
|
+
*
|
|
9267
|
+
* `satisfies MessageOrigin` so this constant and the column's union cannot drift apart silently.
|
|
9268
|
+
*/
|
|
9269
|
+
declare const TOOL_RESULT_ORIGIN = "tool_result";
|
|
9270
|
+
|
|
9271
|
+
interface WeatherClassification {
|
|
9272
|
+
/** Whether the prompt likely asks for weather data. */
|
|
9273
|
+
needsWeather: boolean;
|
|
9274
|
+
/** Cosine similarity to the "needs weather" centroid. */
|
|
9275
|
+
weatherScore: number;
|
|
9276
|
+
/** Cosine similarity to the "no weather" centroid. */
|
|
9277
|
+
noWeatherScore: number;
|
|
9278
|
+
}
|
|
9279
|
+
interface WeatherClassifierOptions extends EmbeddingOptions {
|
|
9362
9280
|
/**
|
|
9363
|
-
*
|
|
9364
|
-
*
|
|
9365
|
-
*
|
|
9366
|
-
* @default 3
|
|
9281
|
+
* Score margin: the weather score must exceed the no-weather score by at
|
|
9282
|
+
* least this amount to classify as "needs weather data".
|
|
9283
|
+
* @default 0.02
|
|
9367
9284
|
*/
|
|
9368
|
-
|
|
9285
|
+
margin?: number;
|
|
9286
|
+
}
|
|
9287
|
+
/**
|
|
9288
|
+
* Classify whether a prompt needs weather data.
|
|
9289
|
+
*
|
|
9290
|
+
* Covers forecasts, temperature, precipitation, wind, humidity, UV, AQI,
|
|
9291
|
+
* marine, flood, climate — anything OpenMeteo-shaped.
|
|
9292
|
+
*/
|
|
9293
|
+
declare function classifyWeather(prompt: string, options: WeatherClassifierOptions): Promise<WeatherClassification>;
|
|
9294
|
+
/**
|
|
9295
|
+
* Batch-classify multiple prompts. Embeds all prompts in one batch
|
|
9296
|
+
* call for efficiency.
|
|
9297
|
+
*/
|
|
9298
|
+
declare function classifyWeatherBatch(prompts: string[], options: WeatherClassifierOptions): Promise<WeatherClassification[]>;
|
|
9299
|
+
interface WeatherPreProcessorOptions {
|
|
9369
9300
|
/**
|
|
9370
|
-
*
|
|
9371
|
-
*
|
|
9301
|
+
* Called with the caller's weather provider when the classifier decides
|
|
9302
|
+
* the prompt is asking for weather. Return either a plain string
|
|
9303
|
+
* (wrapped by the SDK in a default user message) or a fully-formed
|
|
9304
|
+
* `LlmapiMessage[]` (full control over role/shape). Omit to run in
|
|
9305
|
+
* observer mode — classification still fires but nothing is injected.
|
|
9306
|
+
*
|
|
9307
|
+
* The `signal` argument is forwarded from the tool loop so long-running
|
|
9308
|
+
* provider requests can be aborted when the caller aborts.
|
|
9372
9309
|
*/
|
|
9373
|
-
|
|
9310
|
+
fetchWeatherData?: (prompt: string, options: {
|
|
9311
|
+
signal?: AbortSignal;
|
|
9312
|
+
}) => Promise<string | LlmapiMessage[]>;
|
|
9374
9313
|
/**
|
|
9375
|
-
*
|
|
9376
|
-
*
|
|
9377
|
-
*
|
|
9314
|
+
* Score margin: `weatherScore` must exceed `noWeatherScore` by at least
|
|
9315
|
+
* this amount to classify as "needs weather data".
|
|
9316
|
+
* @default 0.02
|
|
9378
9317
|
*/
|
|
9379
|
-
|
|
9380
|
-
/**
|
|
9381
|
-
|
|
9318
|
+
margin?: number;
|
|
9319
|
+
/** Observe the classification without injecting anything. */
|
|
9320
|
+
onClassification?: (result: WeatherClassification) => void;
|
|
9321
|
+
}
|
|
9322
|
+
/**
|
|
9323
|
+
* Build a pre-processor that runs weather classification on the shared
|
|
9324
|
+
* embedding provided by `runToolLoop`, and — if the classifier decides
|
|
9325
|
+
* the prompt is asking for weather — invokes the caller-supplied
|
|
9326
|
+
* `fetchWeatherData` and injects the result into the conversation.
|
|
9327
|
+
*
|
|
9328
|
+
* The SDK does not run the weather lookup itself; the caller wires up
|
|
9329
|
+
* whichever provider they want (OpenMeteo, AccuWeather, weather.gov, etc.).
|
|
9330
|
+
*/
|
|
9331
|
+
declare function createWeatherPreProcessor(options?: WeatherPreProcessorOptions): PromptPreProcessor;
|
|
9332
|
+
|
|
9333
|
+
interface WebSearchClassification {
|
|
9334
|
+
/** Whether the prompt likely needs a web search. */
|
|
9335
|
+
needsWebSearch: boolean;
|
|
9336
|
+
/** Cosine similarity to the "needs search" centroid. */
|
|
9337
|
+
searchScore: number;
|
|
9338
|
+
/** Cosine similarity to the "no search" centroid. */
|
|
9339
|
+
noSearchScore: number;
|
|
9340
|
+
}
|
|
9341
|
+
interface WebSearchClassifierOptions extends EmbeddingOptions {
|
|
9382
9342
|
/**
|
|
9383
|
-
*
|
|
9384
|
-
*
|
|
9385
|
-
*
|
|
9343
|
+
* Score margin: the search score must exceed the no-search score
|
|
9344
|
+
* by at least this amount to classify as "needs web search".
|
|
9345
|
+
* @default 0.02
|
|
9386
9346
|
*/
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9347
|
+
margin?: number;
|
|
9348
|
+
}
|
|
9349
|
+
/**
|
|
9350
|
+
* Classify whether a prompt needs a web search.
|
|
9351
|
+
*
|
|
9352
|
+
* Embeds the prompt and compares it against the pre-computed
|
|
9353
|
+
* search and no-search centroid vectors.
|
|
9354
|
+
*/
|
|
9355
|
+
declare function classifyWebSearch(prompt: string, options: WebSearchClassifierOptions): Promise<WebSearchClassification>;
|
|
9356
|
+
/**
|
|
9357
|
+
* Batch-classify multiple prompts. Embeds all prompts in one batch
|
|
9358
|
+
* call for efficiency.
|
|
9359
|
+
*/
|
|
9360
|
+
declare function classifyWebSearchBatch(prompts: string[], options: WebSearchClassifierOptions): Promise<WebSearchClassification[]>;
|
|
9361
|
+
interface WebSearchPreProcessorOptions {
|
|
9390
9362
|
/**
|
|
9391
|
-
*
|
|
9392
|
-
*
|
|
9393
|
-
*
|
|
9394
|
-
*
|
|
9395
|
-
*
|
|
9363
|
+
* Called with the caller's search provider when the classifier decides
|
|
9364
|
+
* a web search is needed. Return either a plain string (the SDK will
|
|
9365
|
+
* wrap it in a default user message) or a fully-formed message array
|
|
9366
|
+
* (full control over role/shape). Omit to run in observer mode —
|
|
9367
|
+
* classification still fires but no messages are injected.
|
|
9368
|
+
*
|
|
9369
|
+
* The `signal` argument is forwarded from the tool loop so long-running
|
|
9370
|
+
* search requests can be aborted when the caller aborts.
|
|
9396
9371
|
*/
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
isLoading: boolean;
|
|
9401
|
-
stop: () => void;
|
|
9402
|
-
conversationId: string | null;
|
|
9403
|
-
setConversationId: (id: string | null) => void;
|
|
9404
|
-
createConversation: (options?: CreateConversationOptions) => Promise<StoredConversation>;
|
|
9405
|
-
getConversation: (id: string) => Promise<StoredConversation | null>;
|
|
9406
|
-
getConversations: () => Promise<StoredConversation[]>;
|
|
9407
|
-
updateConversationTitle: (id: string, title: string) => Promise<boolean>;
|
|
9408
|
-
updateConversationPinned: (id: string, pinned: boolean) => Promise<boolean>;
|
|
9409
|
-
deleteConversation: (id: string) => Promise<boolean>;
|
|
9410
|
-
getMessages: (conversationId: string) => Promise<StoredMessage[]>;
|
|
9372
|
+
fetchSearchResults?: (prompt: string, options: {
|
|
9373
|
+
signal?: AbortSignal;
|
|
9374
|
+
}) => Promise<string | LlmapiMessage[]>;
|
|
9411
9375
|
/**
|
|
9412
|
-
*
|
|
9413
|
-
*
|
|
9376
|
+
* Score margin: `searchScore` must exceed `noSearchScore` by at least
|
|
9377
|
+
* this amount to classify as "needs web search".
|
|
9378
|
+
* @default 0.02
|
|
9414
9379
|
*/
|
|
9415
|
-
|
|
9416
|
-
/**
|
|
9417
|
-
|
|
9418
|
-
/** Total message count for a conversation. */
|
|
9419
|
-
getMessageCount: (conversationId: string) => Promise<number>;
|
|
9380
|
+
margin?: number;
|
|
9381
|
+
/** Observe the classification without injecting anything. */
|
|
9382
|
+
onClassification?: (result: WebSearchClassification) => void;
|
|
9420
9383
|
}
|
|
9421
|
-
|
|
9384
|
+
/**
|
|
9385
|
+
* Build a pre-processor that runs web-search classification on the
|
|
9386
|
+
* shared embedding provided by `runToolLoop`, and — if the classifier
|
|
9387
|
+
* decides a search is warranted — invokes the caller-supplied
|
|
9388
|
+
* `fetchSearchResults` and injects the result into the conversation.
|
|
9389
|
+
*
|
|
9390
|
+
* @example Basic usage with a search provider
|
|
9391
|
+
* ```ts
|
|
9392
|
+
* import { runToolLoop, createWebSearchPreProcessor } from "@anuma/sdk/server";
|
|
9393
|
+
*
|
|
9394
|
+
* const webSearch = createWebSearchPreProcessor({
|
|
9395
|
+
* fetchSearchResults: async (prompt, { signal }) => {
|
|
9396
|
+
* const res = await mySearchProvider.query(prompt, { signal });
|
|
9397
|
+
* return res.results.map((r) => `- ${r.title}: ${r.snippet}`).join("\n");
|
|
9398
|
+
* },
|
|
9399
|
+
* });
|
|
9400
|
+
*
|
|
9401
|
+
* await runToolLoop({
|
|
9402
|
+
* messages,
|
|
9403
|
+
* model,
|
|
9404
|
+
* token,
|
|
9405
|
+
* preProcessors: [webSearch],
|
|
9406
|
+
* });
|
|
9407
|
+
* ```
|
|
9408
|
+
*
|
|
9409
|
+
* @example Observer mode — only log classification, inject nothing
|
|
9410
|
+
* ```ts
|
|
9411
|
+
* const observer = createWebSearchPreProcessor({
|
|
9412
|
+
* onClassification: ({ needsWebSearch, searchScore, noSearchScore }) => {
|
|
9413
|
+
* metrics.record({ needsWebSearch, searchScore, noSearchScore });
|
|
9414
|
+
* },
|
|
9415
|
+
* });
|
|
9416
|
+
* ```
|
|
9417
|
+
*
|
|
9418
|
+
* @example Full control — return a custom message shape
|
|
9419
|
+
* ```ts
|
|
9420
|
+
* const webSearch = createWebSearchPreProcessor({
|
|
9421
|
+
* fetchSearchResults: async (prompt, { signal }) => {
|
|
9422
|
+
* const results = await mySearchProvider.query(prompt, { signal });
|
|
9423
|
+
* return [
|
|
9424
|
+
* {
|
|
9425
|
+
* role: "system",
|
|
9426
|
+
* content: [{ type: "text", text: `Search results for "${prompt}":\n${formatResults(results)}` }],
|
|
9427
|
+
* },
|
|
9428
|
+
* ];
|
|
9429
|
+
* },
|
|
9430
|
+
* });
|
|
9431
|
+
* ```
|
|
9432
|
+
*/
|
|
9433
|
+
declare function createWebSearchPreProcessor(options?: WebSearchPreProcessorOptions): PromptPreProcessor;
|
|
9422
9434
|
|
|
9423
9435
|
/** Returns `value` as an {@link AnumaTurn} when it is one, otherwise `undefined`. */
|
|
9424
9436
|
declare function readAnumaTurn(value: unknown): AnumaTurn | undefined;
|
|
@@ -13819,7 +13831,7 @@ declare class WatermelonChatStorageAdapter implements ChatBackend {
|
|
|
13819
13831
|
createMessage(options: CreateMessageOptions): Promise<StoredMessage>;
|
|
13820
13832
|
updateMessageEmbedding(uniqueId: string, vector: number[], embeddingModel: string): Promise<StoredMessage | null>;
|
|
13821
13833
|
updateMessageChunks(uniqueId: string, chunks: MessageChunk[], embeddingModel: string): Promise<StoredMessage | null>;
|
|
13822
|
-
updateMessageError(uniqueId: string, error: string): Promise<StoredMessage | null>;
|
|
13834
|
+
updateMessageError(uniqueId: string, error: string | null): Promise<StoredMessage | null>;
|
|
13823
13835
|
updateMessageFeedback(uniqueId: string, feedback: MessageFeedback): Promise<StoredMessage | null>;
|
|
13824
13836
|
updateMessageFileIds(uniqueId: string, fileIds: string[]): Promise<StoredMessage | null>;
|
|
13825
13837
|
clearMessages(conversationId: string): Promise<void>;
|
|
@@ -15093,17 +15105,6 @@ type SendMessageWithStorageResult = {
|
|
|
15093
15105
|
userMessage: StoredMessage;
|
|
15094
15106
|
assistantMessage?: undefined;
|
|
15095
15107
|
};
|
|
15096
|
-
/**
|
|
15097
|
-
* Outcome of delivering one vault inbox item with `deliverInbox`.
|
|
15098
|
-
* @public
|
|
15099
|
-
*/
|
|
15100
|
-
type InboxDeliveryResult = {
|
|
15101
|
-
id: string;
|
|
15102
|
-
conversationId: string | null;
|
|
15103
|
-
status: "stored" | "delivered" | "elsewhere" | "unreadable" | "retry";
|
|
15104
|
-
assistantMessage: StoredMessage | null;
|
|
15105
|
-
error?: string;
|
|
15106
|
-
};
|
|
15107
15108
|
/**
|
|
15108
15109
|
* Options for searching messages
|
|
15109
15110
|
*/
|