@uptimizr/agent-core 0.3.0 → 1.0.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.
@@ -12,5 +12,5 @@
12
12
  */
13
13
  export { BACKEND_CONFIG_STORAGE_KEY, clearBackendConfig, defaultBackendKind, isWebGpuAvailable, loadBackendConfig, saveBackendConfig, } from "./config.js";
14
14
  export { HostedProviderError, createHostedProvider } from "./hosted.js";
15
- export { CURATED_MODELS, SUPPORTED_TOOL_CALLING_MODELS, UnsupportedToolCallingModelError, WebGpuUnavailableError, WebLlmConsentError, WebLlmStorageError, createWebLlmProvider, isQuotaExceededError, } from "./webllm.js";
15
+ export { CURATED_MODELS, DEFAULT_CACHE_POLICY, SUPPORTED_TOOL_CALLING_MODELS, UnsupportedToolCallingModelError, WebGpuUnavailableError, WebLlmConsentError, WebLlmStorageError, clearCachedModels, createWebLlmProvider, isQuotaExceededError, } from "./webllm.js";
16
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAOL,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EAA6B,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnG,OAAO,EAOL,cAAc,EACd,6BAA6B,EAC7B,gCAAgC,EAChC,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAOL,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EAA6B,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnG,OAAO,EASL,cAAc,EACd,oBAAoB,EACpB,6BAA6B,EAC7B,gCAAgC,EAChC,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
@@ -50,4 +50,39 @@ export declare function toOpenAiTools(tools: readonly AgentToolSchema[]): OpenAi
50
50
  * take precedence; otherwise the message content is the final answer.
51
51
  */
52
52
  export declare function parseOpenAiCompletion(completion: OpenAiCompletion): ProviderResponse;
53
+ /**
54
+ * One streamed chat-completion chunk (`object: "chat.completion.chunk"`), the
55
+ * subset this module reads. Tool calls arrive as partial deltas keyed by
56
+ * `index`: the first delta for an index carries `id` + `function.name`, later
57
+ * ones append to `function.arguments`. WebLLM's streamed tool calls omit `id`.
58
+ */
59
+ export interface OpenAiStreamChunk {
60
+ choices?: Array<{
61
+ delta?: {
62
+ content?: string | null;
63
+ tool_calls?: Array<{
64
+ index?: number;
65
+ id?: string;
66
+ type?: "function";
67
+ function?: {
68
+ name?: string;
69
+ arguments?: string;
70
+ };
71
+ }> | null;
72
+ };
73
+ finish_reason?: string | null;
74
+ }>;
75
+ }
76
+ /**
77
+ * Accumulates streamed {@link OpenAiStreamChunk}s into a complete
78
+ * {@link OpenAiCompletion}. `push` returns the chunk's text delta (empty when
79
+ * the chunk carried none) so the caller can forward it to a token callback;
80
+ * `finish` yields the assembled completion for {@link parseOpenAiCompletion}.
81
+ */
82
+ export interface OpenAiStreamAssembler {
83
+ push(chunk: OpenAiStreamChunk): string;
84
+ finish(): OpenAiCompletion;
85
+ }
86
+ /** Create a fresh {@link OpenAiStreamAssembler}. Pure: no I/O, no regex. */
87
+ export declare function createOpenAiStreamAssembler(): OpenAiStreamAssembler;
53
88
  //# sourceMappingURL=openai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CACtF;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,OAAO,CAAC,EAAE;YACR,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACxB,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;SACtC,CAAC;KACH,CAAC,CAAC;CACJ;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,aAAa,EAAE,CAsBnF;AAUD,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,GAAG,UAAU,EAAE,CAK7E;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,CAkBpF"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CACtF;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,OAAO,CAAC,EAAE;YACR,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACxB,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;SACtC,CAAC;KACH,CAAC,CAAC;CACJ;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,aAAa,EAAE,CAsBnF;AAUD,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,GAAG,UAAU,EAAE,CAK7E;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,CAkBpF;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,KAAK,CAAC,EAAE;YACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACxB,UAAU,CAAC,EAAE,KAAK,CAAC;gBACjB,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,EAAE,CAAC,EAAE,MAAM,CAAC;gBACZ,IAAI,CAAC,EAAE,UAAU,CAAC;gBAClB,QAAQ,CAAC,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;oBAAC,SAAS,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAC;aAClD,CAAC,GAAG,IAAI,CAAC;SACX,CAAC;QACF,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,CAAC,CAAC;CACJ;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACvC,MAAM,IAAI,gBAAgB,CAAC;CAC5B;AAED,4EAA4E;AAC5E,wBAAgB,2BAA2B,IAAI,qBAAqB,CA6CnE"}
@@ -76,4 +76,54 @@ export function parseOpenAiCompletion(completion) {
76
76
  }
77
77
  return { kind: "final", content };
78
78
  }
79
+ /** Create a fresh {@link OpenAiStreamAssembler}. Pure: no I/O, no regex. */
80
+ export function createOpenAiStreamAssembler() {
81
+ let content = "";
82
+ // Keyed by `index` so gapped or out-of-order indices still assemble.
83
+ const calls = new Map();
84
+ return {
85
+ push(chunk) {
86
+ const delta = chunk.choices?.[0]?.delta;
87
+ if (!delta)
88
+ return "";
89
+ const text = typeof delta.content === "string" ? delta.content : "";
90
+ content += text;
91
+ (delta.tool_calls ?? []).forEach((partial, position) => {
92
+ const index = typeof partial.index === "number" ? partial.index : position;
93
+ let call = calls.get(index);
94
+ if (!call) {
95
+ // WebLLM omits `id` on streamed tool calls; mirror its non-streaming
96
+ // ids (the zero-based index as a string) so results echo back cleanly.
97
+ call = {
98
+ id: partial.id ?? String(index),
99
+ type: "function",
100
+ function: { name: "", arguments: "" },
101
+ };
102
+ calls.set(index, call);
103
+ }
104
+ else if (partial.id) {
105
+ call.id = partial.id;
106
+ }
107
+ if (partial.function?.name)
108
+ call.function.name += partial.function.name;
109
+ if (partial.function?.arguments)
110
+ call.function.arguments += partial.function.arguments;
111
+ });
112
+ return text;
113
+ },
114
+ finish() {
115
+ const tool_calls = [...calls.entries()].sort((a, b) => a[0] - b[0]).map(([, call]) => call);
116
+ return {
117
+ choices: [
118
+ {
119
+ message: {
120
+ content,
121
+ ...(tool_calls.length > 0 ? { tool_calls } : {}),
122
+ },
123
+ },
124
+ ],
125
+ };
126
+ },
127
+ };
128
+ }
79
129
  //# sourceMappingURL=openai.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * A minimal, allocation-light Server-Sent Events (SSE) parser for the hosted
3
+ * adapter's streamed completions (OpenAI-compatible and Anthropic both speak
4
+ * `text/event-stream`).
5
+ *
6
+ * Model output flows through here, so — per the project's CodeQL ReDoS rule —
7
+ * it uses **string membership and linear scans only**: `indexOf`, `startsWith`,
8
+ * `slice`, and a hand-rolled line splitter. No regular expression ever touches
9
+ * the payload. It handles the wire's edge cases explicitly:
10
+ * - a chunk boundary can fall anywhere (mid-line, mid-event); leftover bytes
11
+ * are carried over to the next `feed()`;
12
+ * - `\\n`, `\\r\\n` and bare `\\r` line endings;
13
+ * - multi-line `data:` fields (joined with `\\n`, per the SSE spec);
14
+ * - comment lines (`: keep-alive`) and unknown fields are ignored;
15
+ * - a trailing event with no blank line is flushed on `end()`.
16
+ */
17
+ /** One parsed SSE event: its optional `event:` name and the joined `data:` payload. */
18
+ export interface SseEvent {
19
+ event?: string;
20
+ data: string;
21
+ }
22
+ /** Incremental SSE parser: feed text chunks, receive complete events. */
23
+ export interface SseParser {
24
+ /** Feed the next decoded text chunk; complete events are dispatched in order. */
25
+ feed(chunk: string): void;
26
+ /** Signal end of stream: dispatches any buffered, unterminated event. */
27
+ end(): void;
28
+ }
29
+ /** Create an incremental {@link SseParser} dispatching to `onEvent`. */
30
+ export declare function createSseParser(onEvent: (event: SseEvent) => void): SseParser;
31
+ /**
32
+ * Read a `ReadableStream<Uint8Array>` (a `fetch` response body) to completion,
33
+ * decoding UTF-8 incrementally (multi-byte characters split across reads are
34
+ * handled by the streaming `TextDecoder`) and dispatching every SSE event to
35
+ * `onEvent`. Resolves when the stream ends; rejects on a read error or when
36
+ * `signal` aborts (the reader is cancelled so the connection is released).
37
+ */
38
+ export declare function readSseStream(body: ReadableStream<Uint8Array>, onEvent: (event: SseEvent) => void, signal?: AbortSignal): Promise<void>;
39
+ /** The `AbortError` a cancelled stream rejects with (matches `fetch`'s). */
40
+ export declare function abortError(): Error;
41
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/providers/sse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,uFAAuF;AACvF,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACxB,iFAAiF;IACjF,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,yEAAyE;IACzE,GAAG,IAAI,IAAI,CAAC;CACb;AAQD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,SAAS,CA8D7E;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,EAClC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,IAAI,KAAK,CAIlC"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * A minimal, allocation-light Server-Sent Events (SSE) parser for the hosted
3
+ * adapter's streamed completions (OpenAI-compatible and Anthropic both speak
4
+ * `text/event-stream`).
5
+ *
6
+ * Model output flows through here, so — per the project's CodeQL ReDoS rule —
7
+ * it uses **string membership and linear scans only**: `indexOf`, `startsWith`,
8
+ * `slice`, and a hand-rolled line splitter. No regular expression ever touches
9
+ * the payload. It handles the wire's edge cases explicitly:
10
+ * - a chunk boundary can fall anywhere (mid-line, mid-event); leftover bytes
11
+ * are carried over to the next `feed()`;
12
+ * - `\\n`, `\\r\\n` and bare `\\r` line endings;
13
+ * - multi-line `data:` fields (joined with `\\n`, per the SSE spec);
14
+ * - comment lines (`: keep-alive`) and unknown fields are ignored;
15
+ * - a trailing event with no blank line is flushed on `end()`.
16
+ */
17
+ /** Strip one leading space after the field colon, per the SSE spec. */
18
+ function fieldValue(line, colon) {
19
+ const start = colon + 1;
20
+ return line.charCodeAt(start) === 32 /* space */ ? line.slice(start + 1) : line.slice(start);
21
+ }
22
+ /** Create an incremental {@link SseParser} dispatching to `onEvent`. */
23
+ export function createSseParser(onEvent) {
24
+ let buffer = "";
25
+ let eventName;
26
+ let dataLines = [];
27
+ function dispatch() {
28
+ if (dataLines.length === 0 && eventName === undefined)
29
+ return;
30
+ if (dataLines.length > 0) {
31
+ onEvent(eventName === undefined
32
+ ? { data: dataLines.join("\n") }
33
+ : { event: eventName, data: dataLines.join("\n") });
34
+ }
35
+ eventName = undefined;
36
+ dataLines = [];
37
+ }
38
+ function handleLine(line) {
39
+ if (line.length === 0) {
40
+ dispatch();
41
+ return;
42
+ }
43
+ // Comment line: ignore (keep-alives).
44
+ if (line.charCodeAt(0) === 58 /* ':' */)
45
+ return;
46
+ const colon = line.indexOf(":");
47
+ const field = colon === -1 ? line : line.slice(0, colon);
48
+ const value = colon === -1 ? "" : fieldValue(line, colon);
49
+ if (field === "data")
50
+ dataLines.push(value);
51
+ else if (field === "event")
52
+ eventName = value;
53
+ // `id:` / `retry:` / unknown fields are irrelevant for a one-shot completion.
54
+ }
55
+ return {
56
+ feed(chunk) {
57
+ buffer += chunk;
58
+ let start = 0;
59
+ const len = buffer.length;
60
+ for (let i = 0; i < len; i++) {
61
+ const code = buffer.charCodeAt(i);
62
+ if (code === 10 /* \n */) {
63
+ handleLine(buffer.slice(start, i));
64
+ start = i + 1;
65
+ }
66
+ else if (code === 13 /* \r */) {
67
+ handleLine(buffer.slice(start, i));
68
+ // Treat "\r\n" as one terminator; a bare "\r" also ends the line.
69
+ if (i + 1 < len && buffer.charCodeAt(i + 1) === 10)
70
+ i++;
71
+ start = i + 1;
72
+ }
73
+ }
74
+ buffer = start === 0 ? buffer : buffer.slice(start);
75
+ // A trailing lone "\r" could be the first half of "\r\n" split across
76
+ // chunks; it is kept in the buffer and resolved on the next feed/end.
77
+ },
78
+ end() {
79
+ if (buffer.length > 0) {
80
+ handleLine(buffer);
81
+ buffer = "";
82
+ }
83
+ dispatch();
84
+ },
85
+ };
86
+ }
87
+ /**
88
+ * Read a `ReadableStream<Uint8Array>` (a `fetch` response body) to completion,
89
+ * decoding UTF-8 incrementally (multi-byte characters split across reads are
90
+ * handled by the streaming `TextDecoder`) and dispatching every SSE event to
91
+ * `onEvent`. Resolves when the stream ends; rejects on a read error or when
92
+ * `signal` aborts (the reader is cancelled so the connection is released).
93
+ */
94
+ export async function readSseStream(body, onEvent, signal) {
95
+ const reader = body.getReader();
96
+ const decoder = new TextDecoder("utf-8");
97
+ const parser = createSseParser(onEvent);
98
+ const onAbort = () => {
99
+ void reader.cancel().catch(() => { });
100
+ };
101
+ signal?.addEventListener("abort", onAbort, { once: true });
102
+ try {
103
+ for (;;) {
104
+ if (signal?.aborted)
105
+ throw abortError();
106
+ const { done, value } = await reader.read();
107
+ if (done)
108
+ break;
109
+ if (value)
110
+ parser.feed(decoder.decode(value, { stream: true }));
111
+ }
112
+ parser.feed(decoder.decode());
113
+ parser.end();
114
+ }
115
+ finally {
116
+ signal?.removeEventListener("abort", onAbort);
117
+ reader.releaseLock();
118
+ }
119
+ }
120
+ /** The `AbortError` a cancelled stream rejects with (matches `fetch`'s). */
121
+ export function abortError() {
122
+ return typeof DOMException !== "undefined"
123
+ ? new DOMException("The operation was aborted.", "AbortError")
124
+ : Object.assign(new Error("The operation was aborted."), { name: "AbortError" });
125
+ }
126
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/providers/sse.ts"],"names":[],"mappings":"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"}
@@ -7,10 +7,13 @@
7
7
  * the user actually runs the assistant, so `@uptimizr/agent-core` stays small
8
8
  * and browser-safe for everyone else. Model weights are downloaded on first use
9
9
  * (behind explicit consent) and cached by the runtime in the browser's Cache
10
- * Storage — never part of any precache.
10
+ * Storage — never part of any precache. By default only the **active** model
11
+ * stays cached: loading a model evicts the other curated models' weights so
12
+ * switching never stacks multiple ~4 GB caches (see {@link WebLlmCachePolicy}),
13
+ * and {@link clearCachedModels} reclaims everything on demand.
11
14
  */
12
15
  import type { AgentMessage, LlmProvider } from "../provider.js";
13
- import { type OpenAiCompletion, type OpenAiMessage, type OpenAiTool } from "./openai.js";
16
+ import { type OpenAiCompletion, type OpenAiMessage, type OpenAiStreamChunk, type OpenAiTool } from "./openai.js";
14
17
  /** A curated model the user may install (ADR 0050 §4). */
15
18
  export interface CuratedModel {
16
19
  /** MLC model id passed to the runtime. */
@@ -86,18 +89,28 @@ export interface InitProgress {
86
89
  /** Human-readable status text from the runtime. */
87
90
  text: string;
88
91
  }
92
+ /** The chat-completion request shape this adapter sends to the runtime. */
93
+ export interface WebLlmChatRequest {
94
+ messages: OpenAiMessage[];
95
+ tools?: OpenAiTool[];
96
+ tool_choice?: "auto";
97
+ stream?: boolean;
98
+ }
89
99
  /** The minimal slice of the `@mlc-ai/web-llm` runtime this adapter uses. */
90
100
  export interface WebLlmEngine {
91
101
  chat: {
92
102
  completions: {
93
- create(request: {
94
- messages: OpenAiMessage[];
95
- tools?: OpenAiTool[];
96
- tool_choice?: "auto";
97
- stream?: false;
98
- }): Promise<OpenAiCompletion>;
103
+ /**
104
+ * OpenAI-compatible completion. With `stream: true` the runtime resolves
105
+ * to an async iterable of `chat.completion.chunk`s; otherwise to one
106
+ * completion. Typed as a union (not overloads) so a fake engine in tests
107
+ * can return either.
108
+ */
109
+ create(request: WebLlmChatRequest): Promise<OpenAiCompletion | AsyncIterable<OpenAiStreamChunk>>;
99
110
  };
100
111
  };
112
+ /** Stop the in-flight streamed generation (WebLLM's `interruptGenerate`). */
113
+ interruptGenerate?(): void;
101
114
  unload?(): Promise<void>;
102
115
  }
103
116
  /** The subset of the `@mlc-ai/web-llm` module surface this adapter loads. */
@@ -108,7 +121,36 @@ export interface WebLlmRuntime {
108
121
  text: string;
109
122
  }) => void;
110
123
  }, chatOpts?: WebLlmChatOptions): Promise<WebLlmEngine>;
124
+ /**
125
+ * Whether a model's weights are present in the browser's Cache Storage.
126
+ * Optional so an older/minimal runtime degrades to "no eviction" gracefully.
127
+ */
128
+ hasModelInCache?(modelId: string): Promise<boolean>;
129
+ /**
130
+ * Delete everything WebLLM cached for a model (weights, wasm, chat config).
131
+ * Optional for the same reason as {@link WebLlmRuntime.hasModelInCache}.
132
+ */
133
+ deleteModelAllInfoInCache?(modelId: string): Promise<void>;
111
134
  }
135
+ /**
136
+ * How the adapter treats **other** curated models' cached weights when it loads
137
+ * one (issue #216):
138
+ *
139
+ * - `"active-only"` (default) — when a model loads, every other known local
140
+ * model's cached weights are evicted first, so switching among the curated
141
+ * models never stacks multiple ~4 GB caches in the origin's storage (the root
142
+ * cause of the storage-quota errors). The user pays a re-download to switch back.
143
+ * - `"keep-all"` — never evict on load; every downloaded model stays cached for
144
+ * fast switching at the cost of disk. Users can still reclaim space explicitly
145
+ * via {@link clearCachedModels} / `WebLlmProvider.clearCachedModels()`.
146
+ *
147
+ * Eviction is scoped to the ids in {@link SUPPORTED_TOOL_CALLING_MODELS} — the
148
+ * only models this adapter can ever have loaded — and never touches any other
149
+ * cache on the origin.
150
+ */
151
+ export type WebLlmCachePolicy = "active-only" | "keep-all";
152
+ /** The default {@link WebLlmCachePolicy}: keep only the active model cached. */
153
+ export declare const DEFAULT_CACHE_POLICY: WebLlmCachePolicy;
112
154
  /** Options for {@link createWebLlmProvider}. */
113
155
  export interface WebLlmProviderOptions {
114
156
  /** Curated model id to load. Defaults to the first curated model. */
@@ -128,6 +170,18 @@ export interface WebLlmProviderOptions {
128
170
  * only up to a value the selected model actually supports.
129
171
  */
130
172
  contextWindowSize?: number;
173
+ /**
174
+ * What to do with **other** curated models' cached weights when this model
175
+ * loads. Defaults to {@link DEFAULT_CACHE_POLICY} (`"active-only"`): evict them
176
+ * so a single active model never stacks caches. See {@link WebLlmCachePolicy}.
177
+ */
178
+ cachePolicy?: WebLlmCachePolicy;
179
+ /**
180
+ * Called after the load-time eviction under `"active-only"` with the ids that
181
+ * were actually removed from Cache Storage (possibly empty). Useful to tell the
182
+ * user which previously downloaded model was reclaimed.
183
+ */
184
+ onCacheEvicted?: (modelIds: readonly string[]) => void;
131
185
  /**
132
186
  * Injectable runtime loader (for tests / custom hosting). Defaults to a lazy
133
187
  * `import("@mlc-ai/web-llm")`.
@@ -136,10 +190,28 @@ export interface WebLlmProviderOptions {
136
190
  /** Injectable WebGPU check (for tests); defaults to real feature detection. */
137
191
  hasWebGpu?: () => boolean;
138
192
  }
139
- /** A WebLLM provider, plus a hook to release GPU resources. */
193
+ /** A WebLLM provider, plus hooks to release GPU resources and cached weights. */
140
194
  export interface WebLlmProvider extends LlmProvider {
141
195
  /** Release the loaded engine and its GPU memory. Safe to call repeatedly. */
142
196
  unload(): Promise<void>;
197
+ /**
198
+ * Delete **every** known local model's cached weights from the browser's
199
+ * Cache Storage — including the active model's — and return the ids that were
200
+ * actually removed. Reclaims the space that "clear site data" would, without
201
+ * touching anything else on the origin. An already-loaded engine keeps running
202
+ * from GPU memory; the next page load re-downloads (behind consent).
203
+ */
204
+ clearCachedModels(): Promise<string[]>;
205
+ }
206
+ /** Options for the standalone {@link clearCachedModels} helper. */
207
+ export interface ClearCachedModelsOptions {
208
+ /**
209
+ * Injectable runtime loader (for tests / custom hosting). Defaults to a lazy
210
+ * `import("@mlc-ai/web-llm")`.
211
+ */
212
+ loadRuntime?: () => Promise<WebLlmRuntime>;
213
+ /** Model ids to keep (skipped even when cached). Defaults to none. */
214
+ keep?: readonly string[];
143
215
  }
144
216
  /** Thrown when the local backend is used on a browser without WebGPU. */
145
217
  export declare class WebGpuUnavailableError extends Error {
@@ -205,6 +277,18 @@ export declare function isQuotaExceededError(err: unknown): boolean;
205
277
  * every loop step never reintroduces a `system` role.
206
278
  */
207
279
  export declare function foldSystemPromptForHermes(messages: readonly AgentMessage[]): AgentMessage[];
280
+ /**
281
+ * Delete every known local model's cached weights from the browser's Cache
282
+ * Storage and return the ids that were removed. The user-facing "Clear cached
283
+ * models" action: it reclaims the multi-GB space WebLLM accumulated (the same
284
+ * space the browser's "clear site data" would) without needing a provider
285
+ * instance and without touching any other cache on the origin. Errors from the
286
+ * runtime/Cache API propagate so the UI can report them.
287
+ *
288
+ * Loads the runtime lazily via `import("@mlc-ai/web-llm")` (or the injected
289
+ * `loadRuntime`); a runtime without the cache APIs resolves to `[]`.
290
+ */
291
+ export declare function clearCachedModels(options?: ClearCachedModelsOptions): Promise<string[]>;
208
292
  /**
209
293
  * Create a local WebLLM provider. The runtime and model weights load lazily on
210
294
  * the first {@link LlmProvider.complete} call — construction is cheap and has no
@@ -1 +1 @@
1
- {"version":3,"file":"webllm.d.ts","sourceRoot":"","sources":["../../src/providers/webllm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webllm.d.ts","sourceRoot":"","sources":["../../src/providers/webllm.ts"],"names":[],"mappings":"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"}