@dudko.dev/agent-web 0.0.21 → 0.0.22
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/README.md +14 -8
- package/dist/agent-web.js +93 -91
- package/dist/agent-web.js.map +1 -1
- package/dist/chunk-YA6TQQ3Q.js +425 -0
- package/dist/chunk-YA6TQQ3Q.js.map +1 -0
- package/dist/index.cjs +504 -270
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -9
- package/dist/index.d.ts +102 -9
- package/dist/index.js +76 -244
- package/dist/index.js.map +1 -1
- package/dist/{webllm-XUBUNKFN.js → webllm-QTJ3EGTG.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-IT65EW77.js +0 -38
- package/dist/chunk-IT65EW77.js.map +0 -1
- /package/dist/{webllm-XUBUNKFN.js.map → webllm-QTJ3EGTG.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,364 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
+
// src/llm/util.ts
|
|
34
|
+
var clip, promptOf, normalizeUsage, timeoutSignal;
|
|
35
|
+
var init_util = __esm({
|
|
36
|
+
"src/llm/util.ts"() {
|
|
37
|
+
"use strict";
|
|
38
|
+
clip = (s, max) => s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
39
|
+
promptOf = (opts) => opts.messages ? { messages: opts.messages } : { prompt: opts.prompt ?? "" };
|
|
40
|
+
normalizeUsage = (u) => {
|
|
41
|
+
const inputTokens = u?.inputTokens ?? 0;
|
|
42
|
+
const outputTokens = u?.outputTokens ?? 0;
|
|
43
|
+
return {
|
|
44
|
+
inputTokens,
|
|
45
|
+
outputTokens,
|
|
46
|
+
totalTokens: u?.totalTokens ?? inputTokens + outputTokens,
|
|
47
|
+
reasoningTokens: u?.outputTokenDetails?.reasoningTokens ?? u?.reasoningTokens ?? 0,
|
|
48
|
+
cachedInputTokens: u?.inputTokenDetails?.cacheReadTokens ?? u?.cachedInputTokens ?? 0,
|
|
49
|
+
cacheWriteTokens: u?.inputTokenDetails?.cacheWriteTokens ?? 0
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
timeoutSignal = (signal, ms) => {
|
|
53
|
+
if (!ms || ms <= 0) return signal;
|
|
54
|
+
const timeout = AbortSignal.timeout(ms);
|
|
55
|
+
if (!signal) return timeout;
|
|
56
|
+
return typeof AbortSignal.any === "function" ? AbortSignal.any([signal, timeout]) : signal;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// src/llm/generate.ts
|
|
62
|
+
var import_ai, callSettings, generate, stream, generateStructured;
|
|
63
|
+
var init_generate = __esm({
|
|
64
|
+
"src/llm/generate.ts"() {
|
|
65
|
+
"use strict";
|
|
66
|
+
import_ai = require("ai");
|
|
67
|
+
init_util();
|
|
68
|
+
callSettings = (opts) => ({
|
|
69
|
+
...opts.system !== void 0 ? { instructions: opts.system } : {},
|
|
70
|
+
maxOutputTokens: opts.maxOutputTokens,
|
|
71
|
+
temperature: opts.temperature,
|
|
72
|
+
...opts.reasoning ? { reasoning: opts.reasoning } : {},
|
|
73
|
+
...opts.providerOptions ? { providerOptions: opts.providerOptions } : {},
|
|
74
|
+
abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs)
|
|
75
|
+
});
|
|
76
|
+
generate = (model, opts = {}) => (0, import_ai.generateText)({
|
|
77
|
+
model,
|
|
78
|
+
...callSettings(opts),
|
|
79
|
+
...promptOf(opts),
|
|
80
|
+
tools: opts.tools
|
|
81
|
+
});
|
|
82
|
+
stream = (model, opts = {}) => (0, import_ai.streamText)({
|
|
83
|
+
model,
|
|
84
|
+
...callSettings(opts),
|
|
85
|
+
...promptOf(opts),
|
|
86
|
+
tools: opts.tools
|
|
87
|
+
});
|
|
88
|
+
generateStructured = (model, schema, opts = {}) => (0, import_ai.generateObject)({
|
|
89
|
+
model,
|
|
90
|
+
schema,
|
|
91
|
+
...callSettings(opts),
|
|
92
|
+
...promptOf(opts)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// src/memory/compress.ts
|
|
98
|
+
var resolveCompaction, estimateTokens, messageTokens, SUMMARY_SYSTEM, compressHistory, compactHistory, TRACE_SYSTEM, compactSteps;
|
|
99
|
+
var init_compress = __esm({
|
|
100
|
+
"src/memory/compress.ts"() {
|
|
101
|
+
"use strict";
|
|
102
|
+
init_generate();
|
|
103
|
+
init_util();
|
|
104
|
+
resolveCompaction = (c) => {
|
|
105
|
+
const contextWindowTokens = c?.contextWindowTokens ?? 128e3;
|
|
106
|
+
return {
|
|
107
|
+
auto: c?.auto ?? true,
|
|
108
|
+
contextWindowTokens,
|
|
109
|
+
thresholdTokens: c?.thresholdTokens ?? Math.floor(contextWindowTokens / 2),
|
|
110
|
+
keepRecentTurns: c?.keepRecentTurns ?? 4,
|
|
111
|
+
keepRecentSteps: c?.keepRecentSteps ?? 3,
|
|
112
|
+
summaryMaxTokens: c?.summaryMaxTokens ?? 1024,
|
|
113
|
+
maxToolOutputChars: c?.maxToolOutputChars ?? 2e4,
|
|
114
|
+
clearToolResultsAfterTokens: c?.clearToolResultsAfterTokens ?? Math.floor(contextWindowTokens / 4),
|
|
115
|
+
keepToolResults: c?.keepToolResults ?? 3
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
estimateTokens = (text) => Math.ceil((text ?? "").length / 4);
|
|
119
|
+
messageTokens = (msgs) => msgs.reduce((n, m) => n + estimateTokens(`${m.role}: ${m.content}
|
|
120
|
+
`), 0);
|
|
121
|
+
SUMMARY_SYSTEM = "Summarize the following conversation into a compact set of durable facts, decisions, identifiers, open tasks and user preferences. Keep names, numbers and IDs verbatim. Output plain text only.";
|
|
122
|
+
compressHistory = async (messages, model, opts = {}) => {
|
|
123
|
+
const keepRecent = opts.keepRecent ?? 6;
|
|
124
|
+
if (messages.length <= keepRecent + 1) return messages;
|
|
125
|
+
if (!opts.force) {
|
|
126
|
+
if (opts.thresholdTokens !== void 0) {
|
|
127
|
+
if (opts.thresholdTokens <= 0 || messageTokens(messages) <= opts.thresholdTokens) {
|
|
128
|
+
return messages;
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
const maxChars = opts.maxChars ?? 12e3;
|
|
132
|
+
const chars = messages.reduce((n, m) => n + m.content.length, 0);
|
|
133
|
+
if (maxChars <= 0 || chars <= maxChars) return messages;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const head = messages.slice(0, messages.length - keepRecent);
|
|
137
|
+
const tail = messages.slice(messages.length - keepRecent);
|
|
138
|
+
const transcript = head.map((m) => `${m.role}: ${m.content}`).join("\n").slice(-48e3);
|
|
139
|
+
try {
|
|
140
|
+
const result = await generate(model, {
|
|
141
|
+
system: SUMMARY_SYSTEM,
|
|
142
|
+
prompt: transcript,
|
|
143
|
+
maxOutputTokens: opts.summaryMaxTokens ?? 400,
|
|
144
|
+
timeoutMs: opts.timeoutMs,
|
|
145
|
+
abortSignal: opts.abortSignal
|
|
146
|
+
});
|
|
147
|
+
opts.onUsage?.(normalizeUsage(result.usage));
|
|
148
|
+
const clean = (result.text || "").trim();
|
|
149
|
+
if (!clean) return messages;
|
|
150
|
+
const summaryMsg = {
|
|
151
|
+
role: "system",
|
|
152
|
+
content: `Summary of earlier conversation:
|
|
153
|
+
${clean}`,
|
|
154
|
+
ts: head[0]?.ts
|
|
155
|
+
};
|
|
156
|
+
return [summaryMsg, ...tail];
|
|
157
|
+
} catch {
|
|
158
|
+
return messages;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
compactHistory = compressHistory;
|
|
162
|
+
TRACE_SYSTEM = "Summarize these completed agent steps into a compact progress note: what was done, what was found (keep names, numbers and IDs verbatim) and what failed. Plain text only.";
|
|
163
|
+
compactSteps = async (done, model, opts) => {
|
|
164
|
+
const keepRecent = opts.keepRecent ?? 3;
|
|
165
|
+
if (done.length <= keepRecent + 1) return done;
|
|
166
|
+
if (!opts.force && estimateTokens(done.join("\n")) <= opts.thresholdTokens) return done;
|
|
167
|
+
const head = done.slice(0, done.length - keepRecent);
|
|
168
|
+
try {
|
|
169
|
+
const result = await generate(model, {
|
|
170
|
+
system: TRACE_SYSTEM,
|
|
171
|
+
prompt: head.map((d, i) => `${i + 1}. ${d}`).join("\n"),
|
|
172
|
+
maxOutputTokens: opts.summaryMaxTokens ?? 600,
|
|
173
|
+
timeoutMs: opts.timeoutMs,
|
|
174
|
+
abortSignal: opts.abortSignal
|
|
175
|
+
});
|
|
176
|
+
opts.onUsage?.(normalizeUsage(result.usage));
|
|
177
|
+
const clean = (result.text || "").trim();
|
|
178
|
+
if (!clean) return done;
|
|
179
|
+
return [`Summary of ${head.length} earlier step(s): ${clean}`, ...done.slice(head.length)];
|
|
180
|
+
} catch {
|
|
181
|
+
return done;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// src/images.ts
|
|
188
|
+
var DATA_URL_RE, HTTP_RE, mediaTypeOf, attachmentKind, KIND_LABEL, KIND_HINT, AttachmentsNotSupportedError, ImagesNotSupportedError, unsupportedAttachment, dataOf, toFilePart, toImagePart, modelLabel, REFUSAL_RE, isAttachmentRefusal, isImageRefusal;
|
|
189
|
+
var init_images = __esm({
|
|
190
|
+
"src/images.ts"() {
|
|
191
|
+
"use strict";
|
|
192
|
+
DATA_URL_RE = /^data:([^;,]+)?;base64,(.*)$/s;
|
|
193
|
+
HTTP_RE = /^https?:\/\//i;
|
|
194
|
+
mediaTypeOf = (f) => {
|
|
195
|
+
if (f.mediaType) return f.mediaType;
|
|
196
|
+
if (typeof f.data === "string") {
|
|
197
|
+
const m = DATA_URL_RE.exec(f.data);
|
|
198
|
+
if (m?.[1]) return m[1];
|
|
199
|
+
}
|
|
200
|
+
const url = f.data instanceof URL ? f.data.href : typeof f.data === "string" ? f.data : "";
|
|
201
|
+
if (HTTP_RE.test(url) || f.name) {
|
|
202
|
+
const ext = (f.name ?? new URL(url, "http://x").pathname).split(".").pop()?.toLowerCase();
|
|
203
|
+
if (ext === "pdf") return "application/pdf";
|
|
204
|
+
if (ext && ["png", "jpg", "jpeg", "gif", "webp"].includes(ext)) {
|
|
205
|
+
return `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return void 0;
|
|
209
|
+
};
|
|
210
|
+
attachmentKind = (f) => {
|
|
211
|
+
const mt = mediaTypeOf(f) ?? "";
|
|
212
|
+
if (mt.startsWith("image/")) return "image";
|
|
213
|
+
if (mt === "application/pdf") return "pdf";
|
|
214
|
+
return "file";
|
|
215
|
+
};
|
|
216
|
+
KIND_LABEL = {
|
|
217
|
+
image: "images",
|
|
218
|
+
pdf: "PDF files",
|
|
219
|
+
file: "file attachments"
|
|
220
|
+
};
|
|
221
|
+
KIND_HINT = {
|
|
222
|
+
image: "Remove the image, or switch to a vision-capable model such as Gemini, Claude or GPT-4o/GPT-5.",
|
|
223
|
+
pdf: "Convert the PDF to text first (e.g. PDF \u2192 Markdown), or switch to a model that reads PDFs such as Gemini, Claude or GPT-4o/GPT-5.",
|
|
224
|
+
file: "Paste its text instead, or switch to a model that accepts this file type."
|
|
225
|
+
};
|
|
226
|
+
AttachmentsNotSupportedError = class extends Error {
|
|
227
|
+
kind;
|
|
228
|
+
constructor(model, kind, detail) {
|
|
229
|
+
super(
|
|
230
|
+
`The model "${model}" can't take ${KIND_LABEL[kind]}${detail ? ` (${detail})` : ""}. ${KIND_HINT[kind]}`
|
|
231
|
+
);
|
|
232
|
+
this.name = "AttachmentsNotSupportedError";
|
|
233
|
+
this.kind = kind;
|
|
234
|
+
}
|
|
235
|
+
toJSON() {
|
|
236
|
+
return this.message;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
ImagesNotSupportedError = class extends AttachmentsNotSupportedError {
|
|
240
|
+
constructor(model, detail) {
|
|
241
|
+
super(model, "image", detail);
|
|
242
|
+
this.name = "ImagesNotSupportedError";
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
unsupportedAttachment = (model, kind, detail) => kind === "image" ? new ImagesNotSupportedError(model, detail) : new AttachmentsNotSupportedError(model, kind, detail);
|
|
246
|
+
dataOf = (f) => {
|
|
247
|
+
if (typeof f.data === "string") {
|
|
248
|
+
const m = DATA_URL_RE.exec(f.data);
|
|
249
|
+
if (m) return m[2];
|
|
250
|
+
if (HTTP_RE.test(f.data)) return new URL(f.data);
|
|
251
|
+
}
|
|
252
|
+
return f.data;
|
|
253
|
+
};
|
|
254
|
+
toFilePart = (f) => {
|
|
255
|
+
const kind = attachmentKind(f);
|
|
256
|
+
const mediaType = mediaTypeOf(f) ?? (kind === "image" ? "image" : "application/octet-stream");
|
|
257
|
+
return {
|
|
258
|
+
type: "file",
|
|
259
|
+
data: dataOf(f),
|
|
260
|
+
mediaType,
|
|
261
|
+
...f.name ? { filename: f.name } : {}
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
toImagePart = toFilePart;
|
|
265
|
+
modelLabel = (model) => {
|
|
266
|
+
if (typeof model === "string") return model;
|
|
267
|
+
const m = model;
|
|
268
|
+
return m?.modelId ? `${m.modelId}${m.provider ? ` (${m.provider})` : ""}` : "this model";
|
|
269
|
+
};
|
|
270
|
+
REFUSAL_RE = /image|vision|multimodal|multi-modal|media type|mediatype|pdf|document|unsupported (file|content|part|mime)|does not support (file|content)|invalid content type|image_url|inline_?data|file_?data/i;
|
|
271
|
+
isAttachmentRefusal = (err) => REFUSAL_RE.test(err instanceof Error ? `${err.name} ${err.message}` : String(err));
|
|
272
|
+
isImageRefusal = isAttachmentRefusal;
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// src/context-window.ts
|
|
277
|
+
var import_ai2, WEBLLM_DEFAULT_CONTEXT_WINDOW, withWebLLMContextWindow, webLLMContextWindow, contextWindowOf, fitCompactionToWindow, toolDefinitionTokens, TOOL_SEARCH_WINDOW_SHARE, ContextWindowExceededError, OVERFLOW_RE, WEBLLM_SIZES_RE, contextOverflowOf;
|
|
278
|
+
var init_context_window = __esm({
|
|
279
|
+
"src/context-window.ts"() {
|
|
280
|
+
"use strict";
|
|
281
|
+
import_ai2 = require("ai");
|
|
282
|
+
init_images();
|
|
283
|
+
init_compress();
|
|
284
|
+
WEBLLM_DEFAULT_CONTEXT_WINDOW = 4096;
|
|
285
|
+
withWebLLMContextWindow = (appConfig, modelId, tokens) => ({
|
|
286
|
+
...appConfig,
|
|
287
|
+
model_list: appConfig.model_list.map(
|
|
288
|
+
(r) => r.model_id === modelId ? { ...r, overrides: { ...r.overrides, context_window_size: tokens } } : r
|
|
289
|
+
)
|
|
290
|
+
});
|
|
291
|
+
webLLMContextWindow = (model) => {
|
|
292
|
+
const m = model;
|
|
293
|
+
if (!m || typeof m !== "object" || m.provider !== "web-llm") return void 0;
|
|
294
|
+
const id = String(m.modelId ?? "");
|
|
295
|
+
try {
|
|
296
|
+
const live = m.engine?.loadedModelIdToPipeline?.get?.(id)?.contextWindowSize;
|
|
297
|
+
if (typeof live === "number" && live > 0) return live;
|
|
298
|
+
} catch {
|
|
299
|
+
}
|
|
300
|
+
const record = m.config?.options?.engineConfig?.appConfig?.model_list?.find(
|
|
301
|
+
(r) => r.model_id === id
|
|
302
|
+
);
|
|
303
|
+
const configured = record?.overrides?.context_window_size;
|
|
304
|
+
if (typeof configured === "number" && configured > 0) return configured;
|
|
305
|
+
return /-1k$/i.test(id) ? 1024 : WEBLLM_DEFAULT_CONTEXT_WINDOW;
|
|
306
|
+
};
|
|
307
|
+
contextWindowOf = (model) => {
|
|
308
|
+
const webllm = webLLMContextWindow(model);
|
|
309
|
+
if (webllm !== void 0) return webllm;
|
|
310
|
+
const m = model;
|
|
311
|
+
if (m && typeof m === "object" && m.provider === "browser-ai") {
|
|
312
|
+
try {
|
|
313
|
+
const w = m.getContextWindow?.();
|
|
314
|
+
return typeof w === "number" && w > 0 ? w : void 0;
|
|
315
|
+
} catch {
|
|
316
|
+
return void 0;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return void 0;
|
|
320
|
+
};
|
|
321
|
+
fitCompactionToWindow = (resolved, configured, modelWindow) => {
|
|
322
|
+
const window = Math.min(
|
|
323
|
+
configured?.contextWindowTokens ?? modelWindow ?? resolved.contextWindowTokens,
|
|
324
|
+
modelWindow ?? Infinity
|
|
325
|
+
);
|
|
326
|
+
if (window === resolved.contextWindowTokens && modelWindow === void 0) return resolved;
|
|
327
|
+
const half = Math.floor(window / 2);
|
|
328
|
+
const quarter = Math.floor(window / 4);
|
|
329
|
+
const clearAfter = configured?.clearToolResultsAfterTokens;
|
|
330
|
+
return {
|
|
331
|
+
...resolved,
|
|
332
|
+
contextWindowTokens: window,
|
|
333
|
+
thresholdTokens: Math.min(configured?.thresholdTokens ?? half, half),
|
|
334
|
+
// 0 = never stays never.
|
|
335
|
+
clearToolResultsAfterTokens: clearAfter === 0 ? 0 : Math.min(clearAfter ?? quarter, quarter),
|
|
336
|
+
// One result may take a quarter of the window (~4 chars per token).
|
|
337
|
+
maxToolOutputChars: configured?.maxToolOutputChars === 0 ? 0 : Math.min(configured?.maxToolOutputChars ?? 2e4, window),
|
|
338
|
+
// A small window holds fewer verbatim results.
|
|
339
|
+
keepToolResults: configured?.keepToolResults ?? Math.max(1, Math.min(3, Math.floor(window / 8192)))
|
|
340
|
+
};
|
|
341
|
+
};
|
|
342
|
+
toolDefinitionTokens = async (tools) => {
|
|
343
|
+
const sizes = await Promise.all(
|
|
344
|
+
Object.entries(tools).map(async ([name, t]) => {
|
|
345
|
+
let parameters;
|
|
346
|
+
try {
|
|
347
|
+
parameters = await (0, import_ai2.asSchema)(t.inputSchema).jsonSchema;
|
|
348
|
+
} catch {
|
|
349
|
+
parameters = void 0;
|
|
350
|
+
}
|
|
351
|
+
return estimateTokens(JSON.stringify({ name, description: t.description ?? "", parameters }));
|
|
352
|
+
})
|
|
353
|
+
);
|
|
354
|
+
return sizes.reduce((a, b) => a + b, 0);
|
|
355
|
+
};
|
|
356
|
+
TOOL_SEARCH_WINDOW_SHARE = 0.25;
|
|
357
|
+
ContextWindowExceededError = class extends Error {
|
|
358
|
+
/** The prompt's size as the provider counted it, when it said. */
|
|
359
|
+
promptTokens;
|
|
360
|
+
/** The model's window as the provider reported it, when it said. */
|
|
361
|
+
contextWindowTokens;
|
|
362
|
+
constructor(model, promptTokens, contextWindowTokens) {
|
|
363
|
+
const sizes = promptTokens && contextWindowTokens ? ` (${promptTokens} tokens; the window is ${contextWindowTokens})` : "";
|
|
364
|
+
super(
|
|
365
|
+
`The conversation no longer fits the context window of "${model}"${sizes}. Start a new chat or compact this one, connect fewer tools, or switch to a model with a larger window.`
|
|
366
|
+
);
|
|
367
|
+
this.name = "ContextWindowExceededError";
|
|
368
|
+
this.promptTokens = promptTokens;
|
|
369
|
+
this.contextWindowTokens = contextWindowTokens;
|
|
370
|
+
}
|
|
371
|
+
toJSON() {
|
|
372
|
+
return this.message;
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
OVERFLOW_RE = /prompt tokens exceed context window|context window size|context_length_exceeded|maximum context length|prompt is too long|input token count.*exceeds|exceeds the maximum number of tokens|exceeds the available context size|context length exceeded|too many tokens in (the )?(prompt|input)/i;
|
|
376
|
+
WEBLLM_SIZES_RE = /number of prompt tokens:\s*(\d+);\s*context window size:\s*(\d+)/i;
|
|
377
|
+
contextOverflowOf = (err, model) => {
|
|
378
|
+
if (err instanceof ContextWindowExceededError) return err;
|
|
379
|
+
const text = err instanceof Error ? `${err.name} ${err.message}` : String(err);
|
|
380
|
+
if (!OVERFLOW_RE.test(text)) return void 0;
|
|
381
|
+
const sizes = WEBLLM_SIZES_RE.exec(text);
|
|
382
|
+
return new ContextWindowExceededError(
|
|
383
|
+
modelLabel(model),
|
|
384
|
+
sizes ? Number(sizes[1]) : void 0,
|
|
385
|
+
sizes ? Number(sizes[2]) : webLLMContextWindow(model) ?? void 0
|
|
386
|
+
);
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
|
|
33
391
|
// src/providers/webllm.ts
|
|
34
392
|
var webllm_exports = {};
|
|
35
393
|
__export(webllm_exports, {
|
|
@@ -38,14 +396,15 @@ __export(webllm_exports, {
|
|
|
38
396
|
preloadWebLLMModel: () => preloadWebLLMModel,
|
|
39
397
|
unloadWebLLMModel: () => unloadWebLLMModel
|
|
40
398
|
});
|
|
41
|
-
var
|
|
399
|
+
var import_ai3, isWebGPUAvailable, preloadWebLLMModel, unloadWebLLMModel, createWebLLMModel;
|
|
42
400
|
var init_webllm = __esm({
|
|
43
401
|
"src/providers/webllm.ts"() {
|
|
44
402
|
"use strict";
|
|
45
|
-
|
|
403
|
+
import_ai3 = require("ai");
|
|
404
|
+
init_context_window();
|
|
46
405
|
isWebGPUAvailable = () => typeof navigator !== "undefined" && "gpu" in navigator;
|
|
47
406
|
preloadWebLLMModel = async (model) => {
|
|
48
|
-
await (0,
|
|
407
|
+
await (0, import_ai3.generateText)({ model, prompt: "ok", maxOutputTokens: 1 });
|
|
49
408
|
};
|
|
50
409
|
unloadWebLLMModel = async (model) => {
|
|
51
410
|
const engine = model.engine;
|
|
@@ -63,7 +422,29 @@ var init_webllm = __esm({
|
|
|
63
422
|
'Local models require "@browser-ai/web-llm" and its peer "@mlc-ai/web-llm". Install: npm install @browser-ai/web-llm @mlc-ai/web-llm'
|
|
64
423
|
);
|
|
65
424
|
}
|
|
66
|
-
const { preload = true, ...settings } = options ?? {};
|
|
425
|
+
const { preload = true, contextWindowTokens, ...settings } = options ?? {};
|
|
426
|
+
if (contextWindowTokens) {
|
|
427
|
+
const engineConfig = settings.engineConfig ?? {};
|
|
428
|
+
let base = engineConfig.appConfig;
|
|
429
|
+
if (!base) {
|
|
430
|
+
try {
|
|
431
|
+
const spec = "@mlc-ai/web-llm";
|
|
432
|
+
base = (await import(
|
|
433
|
+
/* webpackIgnore: true */
|
|
434
|
+
/* @vite-ignore */
|
|
435
|
+
spec
|
|
436
|
+
)).prebuiltAppConfig;
|
|
437
|
+
} catch {
|
|
438
|
+
throw new Error(
|
|
439
|
+
'contextWindowTokens needs "@mlc-ai/web-llm" (for its prebuilt model list), or pass engineConfig.appConfig yourself.'
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
settings.engineConfig = {
|
|
444
|
+
...engineConfig,
|
|
445
|
+
appConfig: withWebLLMContextWindow(base, model, contextWindowTokens)
|
|
446
|
+
};
|
|
447
|
+
}
|
|
67
448
|
const languageModel = mod.webLLM(
|
|
68
449
|
model,
|
|
69
450
|
settings
|
|
@@ -78,6 +459,7 @@ var init_webllm = __esm({
|
|
|
78
459
|
var src_exports = {};
|
|
79
460
|
__export(src_exports, {
|
|
80
461
|
AttachmentsNotSupportedError: () => AttachmentsNotSupportedError,
|
|
462
|
+
ContextWindowExceededError: () => ContextWindowExceededError,
|
|
81
463
|
FILES_STORE: () => FILES_STORE,
|
|
82
464
|
FIND_TOOLS_NAME: () => FIND_TOOLS_NAME,
|
|
83
465
|
ImagesNotSupportedError: () => ImagesNotSupportedError,
|
|
@@ -93,10 +475,12 @@ __export(src_exports, {
|
|
|
93
475
|
SESSIONS_STORE: () => SESSIONS_STORE,
|
|
94
476
|
SKILL_TOOL_NAMES: () => SKILL_TOOL_NAMES,
|
|
95
477
|
TOOL_APPROVAL_MODES: () => TOOL_APPROVAL_MODES,
|
|
478
|
+
TOOL_SEARCH_WINDOW_SHARE: () => TOOL_SEARCH_WINDOW_SHARE,
|
|
96
479
|
ToolBudgetError: () => ToolBudgetError,
|
|
97
480
|
ToolDeniedError: () => ToolDeniedError,
|
|
98
481
|
VaultCredentialStore: () => VaultCredentialStore,
|
|
99
482
|
VirtualFileSystem: () => VirtualFileSystem,
|
|
483
|
+
WEBLLM_DEFAULT_CONTEXT_WINDOW: () => WEBLLM_DEFAULT_CONTEXT_WINDOW,
|
|
100
484
|
attachmentKind: () => attachmentKind,
|
|
101
485
|
buildModelFromStage: () => buildModelFromStage,
|
|
102
486
|
bytesToBase64: () => bytesToBase64,
|
|
@@ -104,6 +488,8 @@ __export(src_exports, {
|
|
|
104
488
|
compactHistory: () => compactHistory,
|
|
105
489
|
compactSteps: () => compactSteps,
|
|
106
490
|
compressHistory: () => compressHistory,
|
|
491
|
+
contextOverflowOf: () => contextOverflowOf,
|
|
492
|
+
contextWindowOf: () => contextWindowOf,
|
|
107
493
|
createAgent: () => createAgent,
|
|
108
494
|
createFileTools: () => createFileTools,
|
|
109
495
|
createFindToolsTool: () => createFindToolsTool,
|
|
@@ -125,6 +511,7 @@ __export(src_exports, {
|
|
|
125
511
|
estimateMessagesTokens: () => messageTokens,
|
|
126
512
|
estimateTokens: () => estimateTokens,
|
|
127
513
|
executeStep: () => executeStep,
|
|
514
|
+
fitCompactionToWindow: () => fitCompactionToWindow,
|
|
128
515
|
generate: () => generate,
|
|
129
516
|
generateStructured: () => generateStructured,
|
|
130
517
|
getOrCreateVaultKey: () => getOrCreateVaultKey,
|
|
@@ -183,10 +570,13 @@ __export(src_exports, {
|
|
|
183
570
|
toImagePart: () => toImagePart,
|
|
184
571
|
tokenize: () => tokenize,
|
|
185
572
|
toolCatalogOf: () => toolCatalogOf,
|
|
573
|
+
toolDefinitionTokens: () => toolDefinitionTokens,
|
|
186
574
|
toolRunContextOf: () => toolRunContextOf,
|
|
187
575
|
unloadWebLLMModel: () => unloadWebLLMModel,
|
|
576
|
+
webLLMContextWindow: () => webLLMContextWindow,
|
|
188
577
|
withRollingBreakpoint: () => withRollingBreakpoint,
|
|
189
|
-
withSystem: () => withSystem
|
|
578
|
+
withSystem: () => withSystem,
|
|
579
|
+
withWebLLMContextWindow: () => withWebLLMContextWindow
|
|
190
580
|
});
|
|
191
581
|
module.exports = __toCommonJS(src_exports);
|
|
192
582
|
|
|
@@ -233,142 +623,8 @@ var withRollingBreakpoint = (messages, caching) => {
|
|
|
233
623
|
return out;
|
|
234
624
|
};
|
|
235
625
|
|
|
236
|
-
// src/llm/generate.ts
|
|
237
|
-
var import_ai = require("ai");
|
|
238
|
-
|
|
239
|
-
// src/llm/util.ts
|
|
240
|
-
var clip = (s, max) => s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
241
|
-
var promptOf = (opts) => opts.messages ? { messages: opts.messages } : { prompt: opts.prompt ?? "" };
|
|
242
|
-
var normalizeUsage = (u) => {
|
|
243
|
-
const inputTokens = u?.inputTokens ?? 0;
|
|
244
|
-
const outputTokens = u?.outputTokens ?? 0;
|
|
245
|
-
return {
|
|
246
|
-
inputTokens,
|
|
247
|
-
outputTokens,
|
|
248
|
-
totalTokens: u?.totalTokens ?? inputTokens + outputTokens,
|
|
249
|
-
reasoningTokens: u?.outputTokenDetails?.reasoningTokens ?? u?.reasoningTokens ?? 0,
|
|
250
|
-
cachedInputTokens: u?.inputTokenDetails?.cacheReadTokens ?? u?.cachedInputTokens ?? 0,
|
|
251
|
-
cacheWriteTokens: u?.inputTokenDetails?.cacheWriteTokens ?? 0
|
|
252
|
-
};
|
|
253
|
-
};
|
|
254
|
-
var timeoutSignal = (signal, ms) => {
|
|
255
|
-
if (!ms || ms <= 0) return signal;
|
|
256
|
-
const timeout = AbortSignal.timeout(ms);
|
|
257
|
-
if (!signal) return timeout;
|
|
258
|
-
return typeof AbortSignal.any === "function" ? AbortSignal.any([signal, timeout]) : signal;
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
// src/llm/generate.ts
|
|
262
|
-
var callSettings = (opts) => ({
|
|
263
|
-
...opts.system !== void 0 ? { instructions: opts.system } : {},
|
|
264
|
-
maxOutputTokens: opts.maxOutputTokens,
|
|
265
|
-
temperature: opts.temperature,
|
|
266
|
-
...opts.reasoning ? { reasoning: opts.reasoning } : {},
|
|
267
|
-
...opts.providerOptions ? { providerOptions: opts.providerOptions } : {},
|
|
268
|
-
abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs)
|
|
269
|
-
});
|
|
270
|
-
var generate = (model, opts = {}) => (0, import_ai.generateText)({
|
|
271
|
-
model,
|
|
272
|
-
...callSettings(opts),
|
|
273
|
-
...promptOf(opts),
|
|
274
|
-
tools: opts.tools
|
|
275
|
-
});
|
|
276
|
-
var stream = (model, opts = {}) => (0, import_ai.streamText)({
|
|
277
|
-
model,
|
|
278
|
-
...callSettings(opts),
|
|
279
|
-
...promptOf(opts),
|
|
280
|
-
tools: opts.tools
|
|
281
|
-
});
|
|
282
|
-
var generateStructured = (model, schema, opts = {}) => (0, import_ai.generateObject)({
|
|
283
|
-
model,
|
|
284
|
-
schema,
|
|
285
|
-
...callSettings(opts),
|
|
286
|
-
...promptOf(opts)
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
// src/memory/compress.ts
|
|
290
|
-
var resolveCompaction = (c) => {
|
|
291
|
-
const contextWindowTokens = c?.contextWindowTokens ?? 128e3;
|
|
292
|
-
return {
|
|
293
|
-
auto: c?.auto ?? true,
|
|
294
|
-
contextWindowTokens,
|
|
295
|
-
thresholdTokens: c?.thresholdTokens ?? Math.floor(contextWindowTokens / 2),
|
|
296
|
-
keepRecentTurns: c?.keepRecentTurns ?? 4,
|
|
297
|
-
keepRecentSteps: c?.keepRecentSteps ?? 3,
|
|
298
|
-
summaryMaxTokens: c?.summaryMaxTokens ?? 1024,
|
|
299
|
-
maxToolOutputChars: c?.maxToolOutputChars ?? 2e4,
|
|
300
|
-
clearToolResultsAfterTokens: c?.clearToolResultsAfterTokens ?? Math.floor(contextWindowTokens / 4),
|
|
301
|
-
keepToolResults: c?.keepToolResults ?? 3
|
|
302
|
-
};
|
|
303
|
-
};
|
|
304
|
-
var estimateTokens = (text) => Math.ceil((text ?? "").length / 4);
|
|
305
|
-
var messageTokens = (msgs) => msgs.reduce((n, m) => n + estimateTokens(`${m.role}: ${m.content}
|
|
306
|
-
`), 0);
|
|
307
|
-
var SUMMARY_SYSTEM = "Summarize the following conversation into a compact set of durable facts, decisions, identifiers, open tasks and user preferences. Keep names, numbers and IDs verbatim. Output plain text only.";
|
|
308
|
-
var compressHistory = async (messages, model, opts = {}) => {
|
|
309
|
-
const keepRecent = opts.keepRecent ?? 6;
|
|
310
|
-
if (messages.length <= keepRecent + 1) return messages;
|
|
311
|
-
if (!opts.force) {
|
|
312
|
-
if (opts.thresholdTokens !== void 0) {
|
|
313
|
-
if (opts.thresholdTokens <= 0 || messageTokens(messages) <= opts.thresholdTokens) {
|
|
314
|
-
return messages;
|
|
315
|
-
}
|
|
316
|
-
} else {
|
|
317
|
-
const maxChars = opts.maxChars ?? 12e3;
|
|
318
|
-
const chars = messages.reduce((n, m) => n + m.content.length, 0);
|
|
319
|
-
if (maxChars <= 0 || chars <= maxChars) return messages;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
const head = messages.slice(0, messages.length - keepRecent);
|
|
323
|
-
const tail = messages.slice(messages.length - keepRecent);
|
|
324
|
-
const transcript = head.map((m) => `${m.role}: ${m.content}`).join("\n").slice(-48e3);
|
|
325
|
-
try {
|
|
326
|
-
const result = await generate(model, {
|
|
327
|
-
system: SUMMARY_SYSTEM,
|
|
328
|
-
prompt: transcript,
|
|
329
|
-
maxOutputTokens: opts.summaryMaxTokens ?? 400,
|
|
330
|
-
timeoutMs: opts.timeoutMs,
|
|
331
|
-
abortSignal: opts.abortSignal
|
|
332
|
-
});
|
|
333
|
-
opts.onUsage?.(normalizeUsage(result.usage));
|
|
334
|
-
const clean = (result.text || "").trim();
|
|
335
|
-
if (!clean) return messages;
|
|
336
|
-
const summaryMsg = {
|
|
337
|
-
role: "system",
|
|
338
|
-
content: `Summary of earlier conversation:
|
|
339
|
-
${clean}`,
|
|
340
|
-
ts: head[0]?.ts
|
|
341
|
-
};
|
|
342
|
-
return [summaryMsg, ...tail];
|
|
343
|
-
} catch {
|
|
344
|
-
return messages;
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
var compactHistory = compressHistory;
|
|
348
|
-
var TRACE_SYSTEM = "Summarize these completed agent steps into a compact progress note: what was done, what was found (keep names, numbers and IDs verbatim) and what failed. Plain text only.";
|
|
349
|
-
var compactSteps = async (done, model, opts) => {
|
|
350
|
-
const keepRecent = opts.keepRecent ?? 3;
|
|
351
|
-
if (done.length <= keepRecent + 1) return done;
|
|
352
|
-
if (!opts.force && estimateTokens(done.join("\n")) <= opts.thresholdTokens) return done;
|
|
353
|
-
const head = done.slice(0, done.length - keepRecent);
|
|
354
|
-
try {
|
|
355
|
-
const result = await generate(model, {
|
|
356
|
-
system: TRACE_SYSTEM,
|
|
357
|
-
prompt: head.map((d, i) => `${i + 1}. ${d}`).join("\n"),
|
|
358
|
-
maxOutputTokens: opts.summaryMaxTokens ?? 600,
|
|
359
|
-
timeoutMs: opts.timeoutMs,
|
|
360
|
-
abortSignal: opts.abortSignal
|
|
361
|
-
});
|
|
362
|
-
opts.onUsage?.(normalizeUsage(result.usage));
|
|
363
|
-
const clean = (result.text || "").trim();
|
|
364
|
-
if (!clean) return done;
|
|
365
|
-
return [`Summary of ${head.length} earlier step(s): ${clean}`, ...done.slice(head.length)];
|
|
366
|
-
} catch {
|
|
367
|
-
return done;
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
|
|
371
626
|
// src/config.ts
|
|
627
|
+
init_compress();
|
|
372
628
|
var resolveConfig = (c) => ({
|
|
373
629
|
clientName: c.clientName ?? "agent-web",
|
|
374
630
|
sessionId: c.sessionId ?? "default",
|
|
@@ -432,6 +688,11 @@ var ToolBudgetError = class extends Error {
|
|
|
432
688
|
}
|
|
433
689
|
};
|
|
434
690
|
|
|
691
|
+
// src/agent/runner.ts
|
|
692
|
+
init_context_window();
|
|
693
|
+
init_util();
|
|
694
|
+
init_compress();
|
|
695
|
+
|
|
435
696
|
// src/providers/types.ts
|
|
436
697
|
var isDirectModel = (m) => typeof m === "string" || typeof m === "object" && m !== null && "specificationVersion" in m;
|
|
437
698
|
var isProviderSpec = (m) => typeof m === "object" && m !== null && !isDirectModel(m) && typeof m.providerType === "string";
|
|
@@ -620,6 +881,7 @@ var buildModelFromStage = async (resolved, credentials, clientName = "agent-web"
|
|
|
620
881
|
var resolveModel = (input, credentials, clientName) => buildModelFromStage(resolveStage(input, void 0, "model"), credentials, clientName);
|
|
621
882
|
|
|
622
883
|
// src/prompts.ts
|
|
884
|
+
init_util();
|
|
623
885
|
var numbered = (items, empty) => items.length ? items.map((s, i) => `${i + 1}. ${s}`).join("\n") : empty;
|
|
624
886
|
var stateBlock = (state) => state && state.trim() ? `
|
|
625
887
|
|
|
@@ -744,7 +1006,8 @@ var withSystem = (base, extra) => extra && extra.trim() ? `${extra.trim()}
|
|
|
744
1006
|
${base}` : base;
|
|
745
1007
|
|
|
746
1008
|
// src/skills.ts
|
|
747
|
-
var
|
|
1009
|
+
var import_ai4 = require("ai");
|
|
1010
|
+
init_util();
|
|
748
1011
|
var SKILL_NAME_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
749
1012
|
var SKILL_TOOL_NAMES = ["load_skill", "read_skill_file"];
|
|
750
1013
|
var defineSkill = (skill) => {
|
|
@@ -845,9 +1108,9 @@ ${s.content}${files}`, budget);
|
|
|
845
1108
|
var createSkillTools = (skills, onLoad) => {
|
|
846
1109
|
const byName = new Map(skills.map((s) => [s.name, s]));
|
|
847
1110
|
const known = skills.map((s) => s.name).join(", ");
|
|
848
|
-
const loadSkill = (0,
|
|
1111
|
+
const loadSkill = (0, import_ai4.tool)({
|
|
849
1112
|
description: "Load the full instructions of a skill from the SKILLS list before doing work it covers.",
|
|
850
|
-
inputSchema: (0,
|
|
1113
|
+
inputSchema: (0, import_ai4.jsonSchema)({
|
|
851
1114
|
type: "object",
|
|
852
1115
|
properties: { name: { type: "string", description: "The skill name" } },
|
|
853
1116
|
required: ["name"],
|
|
@@ -864,9 +1127,9 @@ var createSkillTools = (skills, onLoad) => {
|
|
|
864
1127
|
};
|
|
865
1128
|
}
|
|
866
1129
|
});
|
|
867
|
-
const readFile = (0,
|
|
1130
|
+
const readFile = (0, import_ai4.tool)({
|
|
868
1131
|
description: "Read one of a skill's bundled files (paths are listed by load_skill).",
|
|
869
|
-
inputSchema: (0,
|
|
1132
|
+
inputSchema: (0, import_ai4.jsonSchema)({
|
|
870
1133
|
type: "object",
|
|
871
1134
|
properties: {
|
|
872
1135
|
name: { type: "string", description: "The skill name" },
|
|
@@ -1100,7 +1363,7 @@ var dispatch = async (action, tools, ctx = {}) => {
|
|
|
1100
1363
|
};
|
|
1101
1364
|
|
|
1102
1365
|
// src/tools/search.ts
|
|
1103
|
-
var
|
|
1366
|
+
var import_ai5 = require("ai");
|
|
1104
1367
|
var FIND_TOOLS_NAME = "find_tools";
|
|
1105
1368
|
var toolCatalogOf = (tools) => Object.entries(tools).map(([name, t]) => {
|
|
1106
1369
|
const sep = name.indexOf("__");
|
|
@@ -1170,9 +1433,9 @@ var renderSearchCatalog = (catalog, budget = 12e3) => {
|
|
|
1170
1433
|
return lines.join("\n");
|
|
1171
1434
|
};
|
|
1172
1435
|
var createFindToolsTool = (catalog, onFound, hintOf) => {
|
|
1173
|
-
const t = (0,
|
|
1436
|
+
const t = (0, import_ai5.tool)({
|
|
1174
1437
|
description: "Search the full tool catalogue by keywords and make the matching tools callable from the next step on. Use it whenever the tool you need is not in your current tool list.",
|
|
1175
|
-
inputSchema: (0,
|
|
1438
|
+
inputSchema: (0, import_ai5.jsonSchema)({
|
|
1176
1439
|
type: "object",
|
|
1177
1440
|
properties: {
|
|
1178
1441
|
query: { type: "string", description: "Keywords: what the tool should do" },
|
|
@@ -1206,7 +1469,7 @@ var createFindToolsTool = (catalog, onFound, hintOf) => {
|
|
|
1206
1469
|
};
|
|
1207
1470
|
|
|
1208
1471
|
// src/tools/wrap.ts
|
|
1209
|
-
var
|
|
1472
|
+
var import_ai6 = require("ai");
|
|
1210
1473
|
var toolRunContextOf = (options) => options?.agentRun;
|
|
1211
1474
|
var truncated = (s, max) => s.length > max ? `${s.slice(0, max)}\u2026 [truncated ${s.length - max} chars]` : s;
|
|
1212
1475
|
var toText = (v) => {
|
|
@@ -1330,15 +1593,18 @@ var schemaHintOf = async (t) => {
|
|
|
1330
1593
|
const own = promptHintOf(t);
|
|
1331
1594
|
if (own) return own;
|
|
1332
1595
|
try {
|
|
1333
|
-
const schema = await (0,
|
|
1596
|
+
const schema = await (0, import_ai6.asSchema)(t.inputSchema).jsonSchema;
|
|
1334
1597
|
return schema && typeof schema === "object" ? objectHint(schema) : void 0;
|
|
1335
1598
|
} catch {
|
|
1336
1599
|
return void 0;
|
|
1337
1600
|
}
|
|
1338
1601
|
};
|
|
1339
1602
|
|
|
1603
|
+
// src/agent/executor.ts
|
|
1604
|
+
init_context_window();
|
|
1605
|
+
|
|
1340
1606
|
// src/llm/tool-loop.ts
|
|
1341
|
-
var
|
|
1607
|
+
var import_ai7 = require("ai");
|
|
1342
1608
|
|
|
1343
1609
|
// src/agent/loop-types.ts
|
|
1344
1610
|
var BLOCKER = "[BLOCKER]";
|
|
@@ -1504,6 +1770,7 @@ var parsePlainText = (raw) => {
|
|
|
1504
1770
|
};
|
|
1505
1771
|
|
|
1506
1772
|
// src/llm/context-editing.ts
|
|
1773
|
+
init_compress();
|
|
1507
1774
|
var STUB = (name) => `[${name} result cleared to save context \u2014 call the tool again if you still need it]`;
|
|
1508
1775
|
var estimate = (messages) => {
|
|
1509
1776
|
try {
|
|
@@ -1548,6 +1815,7 @@ var createToolResultClearer = (opts, onCleared) => {
|
|
|
1548
1815
|
};
|
|
1549
1816
|
|
|
1550
1817
|
// src/llm/tool-loop.ts
|
|
1818
|
+
init_util();
|
|
1551
1819
|
var runToolLoop = (model, opts) => opts.mode === "prompted" ? runPrompted(model, opts) : runNative(model, opts);
|
|
1552
1820
|
var activeOf = (opts) => typeof opts.activeTools === "function" ? opts.activeTools() : opts.activeTools;
|
|
1553
1821
|
var callExtras = (opts) => ({
|
|
@@ -1561,7 +1829,7 @@ var runNative = async (model, opts) => {
|
|
|
1561
1829
|
const toolCalls = [];
|
|
1562
1830
|
const pending = /* @__PURE__ */ new Map();
|
|
1563
1831
|
let stoppedByBudget = false;
|
|
1564
|
-
const stopWhen = [(0,
|
|
1832
|
+
const stopWhen = [(0, import_ai7.stepCountIs)(opts.maxSteps ?? 4)];
|
|
1565
1833
|
if (opts.shouldStop) {
|
|
1566
1834
|
const shouldStop = opts.shouldStop;
|
|
1567
1835
|
stopWhen.push(({ steps }) => {
|
|
@@ -1576,7 +1844,7 @@ var runNative = async (model, opts) => {
|
|
|
1576
1844
|
const caching = opts.caching?.enabled ? opts.caching : void 0;
|
|
1577
1845
|
const clear = opts.clearToolResults ? createToolResultClearer(opts.clearToolResults, opts.callbacks?.onToolResultsCleared) : void 0;
|
|
1578
1846
|
const editMessages = caching || clear;
|
|
1579
|
-
const result = (0,
|
|
1847
|
+
const result = (0, import_ai7.streamText)({
|
|
1580
1848
|
model,
|
|
1581
1849
|
tools: opts.tools,
|
|
1582
1850
|
...initialActive ? { activeTools: initialActive } : {},
|
|
@@ -1683,7 +1951,7 @@ var runPrompted = async (model, opts) => {
|
|
|
1683
1951
|
break;
|
|
1684
1952
|
}
|
|
1685
1953
|
const before = new Set(Object.keys(callable()));
|
|
1686
|
-
const result = await (0,
|
|
1954
|
+
const result = await (0, import_ai7.generateText)({
|
|
1687
1955
|
model,
|
|
1688
1956
|
...callExtras(opts),
|
|
1689
1957
|
messages: opts.caching ? withRollingBreakpoint(messages, opts.caching) : messages,
|
|
@@ -1721,6 +1989,9 @@ var runPrompted = async (model, opts) => {
|
|
|
1721
1989
|
return { text, toolCalls, usage, stoppedByBudget };
|
|
1722
1990
|
};
|
|
1723
1991
|
|
|
1992
|
+
// src/agent/executor.ts
|
|
1993
|
+
init_util();
|
|
1994
|
+
|
|
1724
1995
|
// src/thinking.ts
|
|
1725
1996
|
var normalize = (setting) => {
|
|
1726
1997
|
if (setting === void 0 || setting === false) return void 0;
|
|
@@ -1774,90 +2045,8 @@ var mergeProviderOptions = (...maps) => {
|
|
|
1774
2045
|
return out;
|
|
1775
2046
|
};
|
|
1776
2047
|
|
|
1777
|
-
// src/images.ts
|
|
1778
|
-
var DATA_URL_RE = /^data:([^;,]+)?;base64,(.*)$/s;
|
|
1779
|
-
var HTTP_RE = /^https?:\/\//i;
|
|
1780
|
-
var mediaTypeOf = (f) => {
|
|
1781
|
-
if (f.mediaType) return f.mediaType;
|
|
1782
|
-
if (typeof f.data === "string") {
|
|
1783
|
-
const m = DATA_URL_RE.exec(f.data);
|
|
1784
|
-
if (m?.[1]) return m[1];
|
|
1785
|
-
}
|
|
1786
|
-
const url = f.data instanceof URL ? f.data.href : typeof f.data === "string" ? f.data : "";
|
|
1787
|
-
if (HTTP_RE.test(url) || f.name) {
|
|
1788
|
-
const ext = (f.name ?? new URL(url, "http://x").pathname).split(".").pop()?.toLowerCase();
|
|
1789
|
-
if (ext === "pdf") return "application/pdf";
|
|
1790
|
-
if (ext && ["png", "jpg", "jpeg", "gif", "webp"].includes(ext)) {
|
|
1791
|
-
return `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
1792
|
-
}
|
|
1793
|
-
}
|
|
1794
|
-
return void 0;
|
|
1795
|
-
};
|
|
1796
|
-
var attachmentKind = (f) => {
|
|
1797
|
-
const mt = mediaTypeOf(f) ?? "";
|
|
1798
|
-
if (mt.startsWith("image/")) return "image";
|
|
1799
|
-
if (mt === "application/pdf") return "pdf";
|
|
1800
|
-
return "file";
|
|
1801
|
-
};
|
|
1802
|
-
var KIND_LABEL = {
|
|
1803
|
-
image: "images",
|
|
1804
|
-
pdf: "PDF files",
|
|
1805
|
-
file: "file attachments"
|
|
1806
|
-
};
|
|
1807
|
-
var KIND_HINT = {
|
|
1808
|
-
image: "Remove the image, or switch to a vision-capable model such as Gemini, Claude or GPT-4o/GPT-5.",
|
|
1809
|
-
pdf: "Convert the PDF to text first (e.g. PDF \u2192 Markdown), or switch to a model that reads PDFs such as Gemini, Claude or GPT-4o/GPT-5.",
|
|
1810
|
-
file: "Paste its text instead, or switch to a model that accepts this file type."
|
|
1811
|
-
};
|
|
1812
|
-
var AttachmentsNotSupportedError = class extends Error {
|
|
1813
|
-
kind;
|
|
1814
|
-
constructor(model, kind, detail) {
|
|
1815
|
-
super(
|
|
1816
|
-
`The model "${model}" can't take ${KIND_LABEL[kind]}${detail ? ` (${detail})` : ""}. ${KIND_HINT[kind]}`
|
|
1817
|
-
);
|
|
1818
|
-
this.name = "AttachmentsNotSupportedError";
|
|
1819
|
-
this.kind = kind;
|
|
1820
|
-
}
|
|
1821
|
-
toJSON() {
|
|
1822
|
-
return this.message;
|
|
1823
|
-
}
|
|
1824
|
-
};
|
|
1825
|
-
var ImagesNotSupportedError = class extends AttachmentsNotSupportedError {
|
|
1826
|
-
constructor(model, detail) {
|
|
1827
|
-
super(model, "image", detail);
|
|
1828
|
-
this.name = "ImagesNotSupportedError";
|
|
1829
|
-
}
|
|
1830
|
-
};
|
|
1831
|
-
var unsupportedAttachment = (model, kind, detail) => kind === "image" ? new ImagesNotSupportedError(model, detail) : new AttachmentsNotSupportedError(model, kind, detail);
|
|
1832
|
-
var dataOf = (f) => {
|
|
1833
|
-
if (typeof f.data === "string") {
|
|
1834
|
-
const m = DATA_URL_RE.exec(f.data);
|
|
1835
|
-
if (m) return m[2];
|
|
1836
|
-
if (HTTP_RE.test(f.data)) return new URL(f.data);
|
|
1837
|
-
}
|
|
1838
|
-
return f.data;
|
|
1839
|
-
};
|
|
1840
|
-
var toFilePart = (f) => {
|
|
1841
|
-
const kind = attachmentKind(f);
|
|
1842
|
-
const mediaType = mediaTypeOf(f) ?? (kind === "image" ? "image" : "application/octet-stream");
|
|
1843
|
-
return {
|
|
1844
|
-
type: "file",
|
|
1845
|
-
data: dataOf(f),
|
|
1846
|
-
mediaType,
|
|
1847
|
-
...f.name ? { filename: f.name } : {}
|
|
1848
|
-
};
|
|
1849
|
-
};
|
|
1850
|
-
var toImagePart = toFilePart;
|
|
1851
|
-
var modelLabel = (model) => {
|
|
1852
|
-
if (typeof model === "string") return model;
|
|
1853
|
-
const m = model;
|
|
1854
|
-
return m?.modelId ? `${m.modelId}${m.provider ? ` (${m.provider})` : ""}` : "this model";
|
|
1855
|
-
};
|
|
1856
|
-
var REFUSAL_RE = /image|vision|multimodal|multi-modal|media type|mediatype|pdf|document|unsupported (file|content|part|mime)|does not support (file|content)|invalid content type|image_url|inline_?data|file_?data/i;
|
|
1857
|
-
var isAttachmentRefusal = (err) => REFUSAL_RE.test(err instanceof Error ? `${err.name} ${err.message}` : String(err));
|
|
1858
|
-
var isImageRefusal = isAttachmentRefusal;
|
|
1859
|
-
|
|
1860
2048
|
// src/agent/internal.ts
|
|
2049
|
+
init_images();
|
|
1861
2050
|
var promptFor = (ctx, prompt) => ctx.images?.length ? {
|
|
1862
2051
|
messages: [
|
|
1863
2052
|
{
|
|
@@ -1980,7 +2169,7 @@ var executeStep = async (ctx, goal, step, index, total, done) => {
|
|
|
1980
2169
|
}
|
|
1981
2170
|
}
|
|
1982
2171
|
}).catch((err) => {
|
|
1983
|
-
throw imageRefusal(ctx, err, ctx.executorModel) ?? err;
|
|
2172
|
+
throw imageRefusal(ctx, err, ctx.executorModel) ?? contextOverflowOf(err, ctx.executorModel) ?? err;
|
|
1984
2173
|
});
|
|
1985
2174
|
ctx.log.debug("executor text:", loop.text);
|
|
1986
2175
|
const { summary, blocked } = splitBlocker(loop.text);
|
|
@@ -2025,6 +2214,11 @@ var replanWanted = async (trigger, result, opts = {}) => {
|
|
|
2025
2214
|
]);
|
|
2026
2215
|
};
|
|
2027
2216
|
|
|
2217
|
+
// src/agent/planner.ts
|
|
2218
|
+
init_context_window();
|
|
2219
|
+
init_generate();
|
|
2220
|
+
init_util();
|
|
2221
|
+
|
|
2028
2222
|
// src/agent/schemas.ts
|
|
2029
2223
|
var import_zod = require("zod");
|
|
2030
2224
|
var PlanStepSchema = import_zod.z.object({
|
|
@@ -2104,12 +2298,14 @@ ${nudge}` : goal;
|
|
|
2104
2298
|
if (ctx.signal?.aborted) throw err;
|
|
2105
2299
|
const refused = imageRefusal(ctx, err, ctx.plannerModel);
|
|
2106
2300
|
if (refused) throw refused;
|
|
2301
|
+
const overflow = contextOverflowOf(err, ctx.plannerModel);
|
|
2302
|
+
if (overflow) throw overflow;
|
|
2107
2303
|
ctx.log.warn("planner: native structured output failed, salvaging:", asMessage(err));
|
|
2108
2304
|
ctx.emit({ type: "retry", phase: "plan", attempt: 1, error: asMessage(err) });
|
|
2109
2305
|
}
|
|
2110
2306
|
}
|
|
2111
2307
|
const result = await generate(ctx.plannerModel, commonFor("prompted")).catch((err) => {
|
|
2112
|
-
throw imageRefusal(ctx, err, ctx.plannerModel) ?? err;
|
|
2308
|
+
throw imageRefusal(ctx, err, ctx.plannerModel) ?? contextOverflowOf(err, ctx.plannerModel) ?? err;
|
|
2113
2309
|
});
|
|
2114
2310
|
const parsed = parsePlannerResponse(result.text);
|
|
2115
2311
|
ctx.log.debug("planner (prompted) raw:", result.text);
|
|
@@ -2129,6 +2325,8 @@ ${nudge}` : goal;
|
|
|
2129
2325
|
var asMessage = (err) => err instanceof Error ? err.message : String(err);
|
|
2130
2326
|
|
|
2131
2327
|
// src/agent/replanner.ts
|
|
2328
|
+
init_generate();
|
|
2329
|
+
init_util();
|
|
2132
2330
|
var decideReplan = async (ctx, goal, done, remaining) => {
|
|
2133
2331
|
const state = await ctx.state();
|
|
2134
2332
|
const active = ctx.activeSkills?.() ?? [];
|
|
@@ -2177,6 +2375,9 @@ var decideReplan = async (ctx, goal, done, remaining) => {
|
|
|
2177
2375
|
};
|
|
2178
2376
|
|
|
2179
2377
|
// src/agent/synthesizer.ts
|
|
2378
|
+
init_context_window();
|
|
2379
|
+
init_generate();
|
|
2380
|
+
init_util();
|
|
2180
2381
|
var synthesizeAnswer = async (ctx, goal, done, findings = []) => {
|
|
2181
2382
|
const state = await ctx.state();
|
|
2182
2383
|
const active = ctx.activeSkills?.() ?? [];
|
|
@@ -2204,7 +2405,7 @@ var synthesizeAnswer = async (ctx, goal, done, findings = []) => {
|
|
|
2204
2405
|
}
|
|
2205
2406
|
if (part.type === "error") {
|
|
2206
2407
|
const err = part.error instanceof Error ? part.error : new Error(String(part.error));
|
|
2207
|
-
throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? err;
|
|
2408
|
+
throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? contextOverflowOf(err, ctx.synthesizerModel) ?? err;
|
|
2208
2409
|
}
|
|
2209
2410
|
if (part.type !== "text-delta") continue;
|
|
2210
2411
|
const delta = part.text;
|
|
@@ -2250,6 +2451,9 @@ var createLogger = (level = "warn", sink = console) => {
|
|
|
2250
2451
|
};
|
|
2251
2452
|
};
|
|
2252
2453
|
|
|
2454
|
+
// src/agent/runner.ts
|
|
2455
|
+
init_images();
|
|
2456
|
+
|
|
2253
2457
|
// src/providers/capabilities.ts
|
|
2254
2458
|
var CLOUD = /* @__PURE__ */ new Set([
|
|
2255
2459
|
"openai",
|
|
@@ -2262,10 +2466,11 @@ var CLOUD = /* @__PURE__ */ new Set([
|
|
|
2262
2466
|
]);
|
|
2263
2467
|
var supportsNativeTools = (p) => CLOUD.has(p);
|
|
2264
2468
|
var supportsStructuredOutput = (p) => CLOUD.has(p);
|
|
2265
|
-
var directBrowserOk = (p) => p
|
|
2469
|
+
var directBrowserOk = (p) => p !== "web-llm";
|
|
2266
2470
|
var LOCAL_RE2 = /web-?llm|mlc|browser-ai|transformers|built-?in/i;
|
|
2471
|
+
var LOCAL_VISION_RE = /vision|[-_]vl\b|[-_]vl[-_]|llava|smolvlm|moondream|gemma-?3n/i;
|
|
2267
2472
|
var TEXT_ONLY_MODEL_RE = /gpt-3\.5|o1-mini|o3-mini|deepseek|text-(davinci|embedding)|embedding|babbage|davinci|codestral/i;
|
|
2268
|
-
var VISION_PROVIDER_RE = /^(google|anthropic|openai|azure|xai|vertex|bedrock|gemini)/i;
|
|
2473
|
+
var VISION_PROVIDER_RE = /^(google|anthropic|openai|azure|xai|vertex|bedrock|gemini|moonshot|mistral)/i;
|
|
2269
2474
|
var PDF_PROVIDER_RE = /^(google|anthropic|openai|azure|vertex|bedrock|gemini)/i;
|
|
2270
2475
|
var supportsImages = (model) => {
|
|
2271
2476
|
if (typeof model === "string") {
|
|
@@ -2276,14 +2481,16 @@ var supportsImages = (model) => {
|
|
|
2276
2481
|
if (!model || typeof model !== "object") return void 0;
|
|
2277
2482
|
const provider = String(model.provider ?? "");
|
|
2278
2483
|
const id = String(model.modelId ?? "");
|
|
2279
|
-
if (LOCAL_RE2.test(provider)) return
|
|
2280
|
-
if (/deepseek/i.test(provider)
|
|
2484
|
+
if (LOCAL_RE2.test(provider)) return LOCAL_VISION_RE.test(id);
|
|
2485
|
+
if (/deepseek/i.test(provider)) return /flash/i.test(id);
|
|
2486
|
+
if (TEXT_ONLY_MODEL_RE.test(id)) return false;
|
|
2281
2487
|
return VISION_PROVIDER_RE.test(provider) ? true : void 0;
|
|
2282
2488
|
};
|
|
2283
2489
|
var supportsPdf = (model) => {
|
|
2284
2490
|
const vision = supportsImages(model);
|
|
2285
2491
|
if (vision === false) return false;
|
|
2286
2492
|
const provider = typeof model === "string" ? model.split("/")[0] ?? "" : String(model?.provider ?? "");
|
|
2493
|
+
if (LOCAL_RE2.test(provider) || /moonshot/i.test(provider)) return false;
|
|
2287
2494
|
return PDF_PROVIDER_RE.test(provider) ? true : void 0;
|
|
2288
2495
|
};
|
|
2289
2496
|
|
|
@@ -2320,6 +2527,10 @@ var createAgent = async (config) => {
|
|
|
2320
2527
|
]);
|
|
2321
2528
|
const plannerMode = selectToolMode(plannerModel, cfg.toolMode);
|
|
2322
2529
|
const executorMode = selectToolMode(executorModel, cfg.toolMode);
|
|
2530
|
+
const modelWindows = [executorModel, plannerModel, synthesizerModel].map(contextWindowOf).filter((w) => w !== void 0);
|
|
2531
|
+
const modelWindow = modelWindows.length ? Math.min(...modelWindows) : void 0;
|
|
2532
|
+
cfg.compaction = fitCompactionToWindow(cfg.compaction, config.compaction, modelWindow);
|
|
2533
|
+
const byTokens = Boolean(config.compaction) || modelWindow !== void 0;
|
|
2323
2534
|
const baseTools = filterTools(
|
|
2324
2535
|
config.tools ?? {},
|
|
2325
2536
|
config.availableTools,
|
|
@@ -2332,7 +2543,8 @@ var createAgent = async (config) => {
|
|
|
2332
2543
|
skillNames.add(s.name);
|
|
2333
2544
|
}
|
|
2334
2545
|
const catalog = toolCatalogOf(baseTools);
|
|
2335
|
-
const
|
|
2546
|
+
const toolTokens = cfg.toolSelectionStrategy === "auto" ? await toolDefinitionTokens(baseTools) : 0;
|
|
2547
|
+
const strategy = cfg.toolSelectionStrategy === "auto" ? catalog.length > cfg.toolSearchThreshold || toolTokens > cfg.compaction.contextWindowTokens * TOOL_SEARCH_WINDOW_SHARE ? "search" : "all" : cfg.toolSelectionStrategy;
|
|
2336
2548
|
const reserved = [
|
|
2337
2549
|
...skills.length ? SKILL_TOOL_NAMES : [],
|
|
2338
2550
|
...strategy === "search" ? [FIND_TOOLS_NAME] : []
|
|
@@ -2358,14 +2570,15 @@ var createAgent = async (config) => {
|
|
|
2358
2570
|
const caching = resolveCaching(config.promptCaching);
|
|
2359
2571
|
const textOnly = executorMode === "prompted";
|
|
2360
2572
|
const accepts = {
|
|
2361
|
-
|
|
2573
|
+
// A local vision model (the prompted path carries images too) says so by its id.
|
|
2574
|
+
image: config.inputs?.images ?? config.vision ?? (textOnly ? supportsImages(executorModel) === true : supportsImages(executorModel)),
|
|
2362
2575
|
pdf: config.inputs?.pdf ?? (textOnly ? false : supportsPdf(executorModel)),
|
|
2363
2576
|
file: config.inputs?.files ?? (textOnly ? false : void 0)
|
|
2364
2577
|
};
|
|
2365
2578
|
const approval = createApprovalState(config.toolApproval);
|
|
2366
2579
|
const log = createLogger(cfg.logLevel, config.logger);
|
|
2367
2580
|
log.info(
|
|
2368
|
-
`agent ready \u2014 ${catalog.length} tool(s) (${strategy}), skills: [${[...skillNames].join(", ") || "none"}], planner mode: ${plannerMode}, executor mode: ${executorMode}, approval: ${approval.mode}`
|
|
2581
|
+
`agent ready \u2014 ${catalog.length} tool(s) (${strategy}, ~${toolTokens || "?"} tokens), window ${cfg.compaction.contextWindowTokens}${modelWindow ? " (the model\u2019s)" : ""}, skills: [${[...skillNames].join(", ") || "none"}], planner mode: ${plannerMode}, executor mode: ${executorMode}, approval: ${approval.mode}`
|
|
2369
2582
|
);
|
|
2370
2583
|
const run = async (goal, opts = {}) => {
|
|
2371
2584
|
const emit = (event) => {
|
|
@@ -2476,7 +2689,7 @@ var createAgent = async (config) => {
|
|
|
2476
2689
|
} catch {
|
|
2477
2690
|
}
|
|
2478
2691
|
}
|
|
2479
|
-
if (config.memory &&
|
|
2692
|
+
if (config.memory && byTokens && cfg.compaction.auto && history.length > 0) {
|
|
2480
2693
|
const before = messageTokens(history);
|
|
2481
2694
|
if (before > cfg.compaction.thresholdTokens) {
|
|
2482
2695
|
const compacted = await compressHistory(history, synthesizerModel, {
|
|
@@ -2688,7 +2901,8 @@ var createAgent = async (config) => {
|
|
|
2688
2901
|
}
|
|
2689
2902
|
}
|
|
2690
2903
|
if (isAborted()) return stop();
|
|
2691
|
-
|
|
2904
|
+
const stepWords = result.trace.map((r) => r.summary.trim()).filter((t) => t && !/^(Executed \d+ tool call\(s\)\.|Step produced no output\.)$/.test(t));
|
|
2905
|
+
let summary = stepWords.length ? stepWords.join("\n\n") : "Done \u2014 the changes have been applied.";
|
|
2692
2906
|
if (cfg.synthesize) {
|
|
2693
2907
|
try {
|
|
2694
2908
|
const synth = await synthesizeAnswer(ctx, text, done, findings);
|
|
@@ -2703,12 +2917,12 @@ var createAgent = async (config) => {
|
|
|
2703
2917
|
emit({ type: "final", text: summary });
|
|
2704
2918
|
await remember({ role: "assistant", content: summary });
|
|
2705
2919
|
result.final = summary;
|
|
2706
|
-
if (config.memory && (
|
|
2920
|
+
if (config.memory && (byTokens ? cfg.compaction.auto : cfg.compressAfterChars > 0)) {
|
|
2707
2921
|
try {
|
|
2708
2922
|
const transcript = await config.memory.load(sessionId);
|
|
2709
2923
|
const before = messageTokens(transcript);
|
|
2710
2924
|
const compacted = await compressHistory(transcript, synthesizerModel, {
|
|
2711
|
-
...
|
|
2925
|
+
...byTokens ? {
|
|
2712
2926
|
thresholdTokens: cfg.compaction.thresholdTokens,
|
|
2713
2927
|
keepRecent: cfg.compaction.keepRecentTurns,
|
|
2714
2928
|
summaryMaxTokens: cfg.budgets.compaction
|
|
@@ -2780,6 +2994,7 @@ var createAgent = async (config) => {
|
|
|
2780
2994
|
},
|
|
2781
2995
|
listTools: () => catalog.map((e) => ({ ...e })),
|
|
2782
2996
|
toolStrategy: strategy,
|
|
2997
|
+
contextWindowTokens: cfg.compaction.contextWindowTokens,
|
|
2783
2998
|
skills: skills.map((s) => ({ name: s.name, description: s.description })),
|
|
2784
2999
|
capabilities: { images: accepts.image, pdf: accepts.pdf, files: accepts.file },
|
|
2785
3000
|
models: { planner: plannerModel, executor: executorModel, synthesizer: synthesizerModel }
|
|
@@ -2787,7 +3002,8 @@ var createAgent = async (config) => {
|
|
|
2787
3002
|
};
|
|
2788
3003
|
|
|
2789
3004
|
// src/subagent/tool.ts
|
|
2790
|
-
var
|
|
3005
|
+
var import_ai8 = require("ai");
|
|
3006
|
+
init_util();
|
|
2791
3007
|
|
|
2792
3008
|
// src/subagent/protocol.ts
|
|
2793
3009
|
var toCloneable = (value) => {
|
|
@@ -2889,7 +3105,7 @@ var createSubagentTool = (opts) => {
|
|
|
2889
3105
|
Object.entries(opts.tools ?? {}).map(async ([name, t2]) => ({
|
|
2890
3106
|
name,
|
|
2891
3107
|
description: typeof t2.description === "string" ? t2.description : "",
|
|
2892
|
-
inputSchema: toCloneable(await (0,
|
|
3108
|
+
inputSchema: toCloneable(await (0, import_ai8.asSchema)(t2.inputSchema).jsonSchema),
|
|
2893
3109
|
readOnly: isReadOnlyTool(t2)
|
|
2894
3110
|
}))
|
|
2895
3111
|
);
|
|
@@ -2962,9 +3178,9 @@ var createSubagentTool = (opts) => {
|
|
|
2962
3178
|
safePost(worker, { type: "run", task, config, proxied });
|
|
2963
3179
|
});
|
|
2964
3180
|
};
|
|
2965
|
-
const t = (0,
|
|
3181
|
+
const t = (0, import_ai8.tool)({
|
|
2966
3182
|
description: opts.description,
|
|
2967
|
-
inputSchema: (0,
|
|
3183
|
+
inputSchema: (0, import_ai8.jsonSchema)({
|
|
2968
3184
|
type: "object",
|
|
2969
3185
|
properties: {
|
|
2970
3186
|
task: {
|
|
@@ -3024,7 +3240,7 @@ var createSubagentTool = (opts) => {
|
|
|
3024
3240
|
};
|
|
3025
3241
|
|
|
3026
3242
|
// src/subagent/worker.ts
|
|
3027
|
-
var
|
|
3243
|
+
var import_ai9 = require("ai");
|
|
3028
3244
|
|
|
3029
3245
|
// src/storage/db.ts
|
|
3030
3246
|
var import_idb = require("idb");
|
|
@@ -3191,9 +3407,9 @@ var serveSubagentWorker = (opts = {}) => {
|
|
|
3191
3407
|
const pending = /* @__PURE__ */ new Map();
|
|
3192
3408
|
let callSeq = 0;
|
|
3193
3409
|
const proxy = (spec) => {
|
|
3194
|
-
const t = (0,
|
|
3410
|
+
const t = (0, import_ai9.dynamicTool)({
|
|
3195
3411
|
description: spec.description,
|
|
3196
|
-
inputSchema: (0,
|
|
3412
|
+
inputSchema: (0, import_ai9.jsonSchema)(spec.inputSchema),
|
|
3197
3413
|
execute: (input, options) => new Promise((resolve, reject) => {
|
|
3198
3414
|
const callId = `call-${callSeq += 1}`;
|
|
3199
3415
|
const signal = options?.abortSignal;
|
|
@@ -3271,6 +3487,9 @@ var serveSubagentWorker = (opts = {}) => {
|
|
|
3271
3487
|
});
|
|
3272
3488
|
};
|
|
3273
3489
|
|
|
3490
|
+
// src/index.ts
|
|
3491
|
+
init_images();
|
|
3492
|
+
|
|
3274
3493
|
// src/files/vfs.ts
|
|
3275
3494
|
var MIME = {
|
|
3276
3495
|
txt: "text/plain",
|
|
@@ -3420,15 +3639,15 @@ var VirtualFileSystem = class {
|
|
|
3420
3639
|
};
|
|
3421
3640
|
|
|
3422
3641
|
// src/files/tools.ts
|
|
3423
|
-
var
|
|
3642
|
+
var import_ai10 = require("ai");
|
|
3424
3643
|
var createFileTools = (vfs, opts = {}) => {
|
|
3425
3644
|
const p = opts.prefix ?? "fs_";
|
|
3426
3645
|
const maxRead = opts.maxReadChars ?? 5e4;
|
|
3427
3646
|
const tools = {
|
|
3428
3647
|
[`${p}list`]: markReadOnly(
|
|
3429
|
-
(0,
|
|
3648
|
+
(0, import_ai10.tool)({
|
|
3430
3649
|
description: "List the files in the workspace (attachments the user added, files you wrote). Optionally only under a directory prefix.",
|
|
3431
|
-
inputSchema: (0,
|
|
3650
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3432
3651
|
type: "object",
|
|
3433
3652
|
properties: { prefix: { type: "string", description: 'Directory prefix, e.g. "/docs"' } },
|
|
3434
3653
|
additionalProperties: false
|
|
@@ -3441,9 +3660,9 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3441
3660
|
})
|
|
3442
3661
|
),
|
|
3443
3662
|
[`${p}read`]: markReadOnly(
|
|
3444
|
-
(0,
|
|
3663
|
+
(0, import_ai10.tool)({
|
|
3445
3664
|
description: "Read a text file from the workspace by its path.",
|
|
3446
|
-
inputSchema: (0,
|
|
3665
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3447
3666
|
type: "object",
|
|
3448
3667
|
properties: { path: { type: "string", description: 'Absolute path, e.g. "/notes.md"' } },
|
|
3449
3668
|
required: ["path"],
|
|
@@ -3465,9 +3684,9 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3465
3684
|
)
|
|
3466
3685
|
};
|
|
3467
3686
|
if (opts.readOnly) return tools;
|
|
3468
|
-
tools[`${p}write`] = (0,
|
|
3687
|
+
tools[`${p}write`] = (0, import_ai10.tool)({
|
|
3469
3688
|
description: "Write a text file to the workspace (creates or replaces it). Use it for reports, drafts, data the user should be able to open.",
|
|
3470
|
-
inputSchema: (0,
|
|
3689
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3471
3690
|
type: "object",
|
|
3472
3691
|
properties: {
|
|
3473
3692
|
path: { type: "string", description: 'Absolute path, e.g. "/reports/summary.md"' },
|
|
@@ -3482,9 +3701,9 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3482
3701
|
return { written: info.path, size: info.size };
|
|
3483
3702
|
}
|
|
3484
3703
|
});
|
|
3485
|
-
tools[`${p}delete`] = (0,
|
|
3704
|
+
tools[`${p}delete`] = (0, import_ai10.tool)({
|
|
3486
3705
|
description: "Delete a file from the workspace.",
|
|
3487
|
-
inputSchema: (0,
|
|
3706
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3488
3707
|
type: "object",
|
|
3489
3708
|
properties: { path: { type: "string" } },
|
|
3490
3709
|
required: ["path"],
|
|
@@ -3497,12 +3716,15 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3497
3716
|
|
|
3498
3717
|
// src/index.ts
|
|
3499
3718
|
init_webllm();
|
|
3719
|
+
init_context_window();
|
|
3720
|
+
init_generate();
|
|
3721
|
+
init_util();
|
|
3500
3722
|
|
|
3501
3723
|
// src/tools/define.ts
|
|
3502
|
-
var
|
|
3724
|
+
var import_ai11 = require("ai");
|
|
3503
3725
|
var defineTool = (config) => {
|
|
3504
3726
|
const { promptHint, readOnly, ...rest } = config;
|
|
3505
|
-
const t = (0,
|
|
3727
|
+
const t = (0, import_ai11.tool)(rest);
|
|
3506
3728
|
if (promptHint) t.promptHint = promptHint;
|
|
3507
3729
|
if (readOnly) t.readOnly = true;
|
|
3508
3730
|
return t;
|
|
@@ -3557,9 +3779,13 @@ var IndexedDBStore = class {
|
|
|
3557
3779
|
return (await db.getAllKeys(SESSIONS_STORE)).map(String);
|
|
3558
3780
|
}
|
|
3559
3781
|
};
|
|
3782
|
+
|
|
3783
|
+
// src/index.ts
|
|
3784
|
+
init_compress();
|
|
3560
3785
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3561
3786
|
0 && (module.exports = {
|
|
3562
3787
|
AttachmentsNotSupportedError,
|
|
3788
|
+
ContextWindowExceededError,
|
|
3563
3789
|
FILES_STORE,
|
|
3564
3790
|
FIND_TOOLS_NAME,
|
|
3565
3791
|
ImagesNotSupportedError,
|
|
@@ -3575,10 +3801,12 @@ var IndexedDBStore = class {
|
|
|
3575
3801
|
SESSIONS_STORE,
|
|
3576
3802
|
SKILL_TOOL_NAMES,
|
|
3577
3803
|
TOOL_APPROVAL_MODES,
|
|
3804
|
+
TOOL_SEARCH_WINDOW_SHARE,
|
|
3578
3805
|
ToolBudgetError,
|
|
3579
3806
|
ToolDeniedError,
|
|
3580
3807
|
VaultCredentialStore,
|
|
3581
3808
|
VirtualFileSystem,
|
|
3809
|
+
WEBLLM_DEFAULT_CONTEXT_WINDOW,
|
|
3582
3810
|
attachmentKind,
|
|
3583
3811
|
buildModelFromStage,
|
|
3584
3812
|
bytesToBase64,
|
|
@@ -3586,6 +3814,8 @@ var IndexedDBStore = class {
|
|
|
3586
3814
|
compactHistory,
|
|
3587
3815
|
compactSteps,
|
|
3588
3816
|
compressHistory,
|
|
3817
|
+
contextOverflowOf,
|
|
3818
|
+
contextWindowOf,
|
|
3589
3819
|
createAgent,
|
|
3590
3820
|
createFileTools,
|
|
3591
3821
|
createFindToolsTool,
|
|
@@ -3607,6 +3837,7 @@ var IndexedDBStore = class {
|
|
|
3607
3837
|
estimateMessagesTokens,
|
|
3608
3838
|
estimateTokens,
|
|
3609
3839
|
executeStep,
|
|
3840
|
+
fitCompactionToWindow,
|
|
3610
3841
|
generate,
|
|
3611
3842
|
generateStructured,
|
|
3612
3843
|
getOrCreateVaultKey,
|
|
@@ -3665,9 +3896,12 @@ var IndexedDBStore = class {
|
|
|
3665
3896
|
toImagePart,
|
|
3666
3897
|
tokenize,
|
|
3667
3898
|
toolCatalogOf,
|
|
3899
|
+
toolDefinitionTokens,
|
|
3668
3900
|
toolRunContextOf,
|
|
3669
3901
|
unloadWebLLMModel,
|
|
3902
|
+
webLLMContextWindow,
|
|
3670
3903
|
withRollingBreakpoint,
|
|
3671
|
-
withSystem
|
|
3904
|
+
withSystem,
|
|
3905
|
+
withWebLLMContextWindow
|
|
3672
3906
|
});
|
|
3673
3907
|
//# sourceMappingURL=index.cjs.map
|