@dudko.dev/agent-web 0.0.20 → 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 +511 -274
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +105 -9
- package/dist/index.d.ts +105 -9
- package/dist/index.js +83 -248
- 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;
|
|
@@ -1732,7 +2003,8 @@ var resolveThinking = (setting) => {
|
|
|
1732
2003
|
const cfg = normalize(setting);
|
|
1733
2004
|
if (!cfg) return {};
|
|
1734
2005
|
const level = cfg.level ?? "medium";
|
|
1735
|
-
|
|
2006
|
+
const webllm = (on) => ({ "web-llm": { extra_body: { enable_thinking: on } } });
|
|
2007
|
+
if (level === "none") return { reasoning: "none", providerOptions: webllm(false) };
|
|
1736
2008
|
const includeThoughts = cfg.includeThoughts !== false;
|
|
1737
2009
|
const budget = cfg.budgetTokens;
|
|
1738
2010
|
if (typeof budget === "number" && budget > 0) {
|
|
@@ -1740,16 +2012,18 @@ var resolveThinking = (setting) => {
|
|
|
1740
2012
|
reasoning: level,
|
|
1741
2013
|
providerOptions: {
|
|
1742
2014
|
anthropic: { thinking: { type: "enabled", budgetTokens: budget } },
|
|
1743
|
-
google: { thinkingConfig: { thinkingBudget: budget, includeThoughts } }
|
|
2015
|
+
google: { thinkingConfig: { thinkingBudget: budget, includeThoughts } },
|
|
2016
|
+
...webllm(true)
|
|
1744
2017
|
}
|
|
1745
2018
|
};
|
|
1746
2019
|
}
|
|
1747
|
-
if (!includeThoughts) return { reasoning: level };
|
|
2020
|
+
if (!includeThoughts) return { reasoning: level, providerOptions: webllm(true) };
|
|
1748
2021
|
return {
|
|
1749
2022
|
reasoning: level,
|
|
1750
2023
|
providerOptions: {
|
|
1751
2024
|
google: { thinkingConfig: { includeThoughts: true } },
|
|
1752
|
-
openai: { reasoningSummary: "auto" }
|
|
2025
|
+
openai: { reasoningSummary: "auto" },
|
|
2026
|
+
...webllm(true)
|
|
1753
2027
|
}
|
|
1754
2028
|
};
|
|
1755
2029
|
};
|
|
@@ -1771,90 +2045,8 @@ var mergeProviderOptions = (...maps) => {
|
|
|
1771
2045
|
return out;
|
|
1772
2046
|
};
|
|
1773
2047
|
|
|
1774
|
-
// src/images.ts
|
|
1775
|
-
var DATA_URL_RE = /^data:([^;,]+)?;base64,(.*)$/s;
|
|
1776
|
-
var HTTP_RE = /^https?:\/\//i;
|
|
1777
|
-
var mediaTypeOf = (f) => {
|
|
1778
|
-
if (f.mediaType) return f.mediaType;
|
|
1779
|
-
if (typeof f.data === "string") {
|
|
1780
|
-
const m = DATA_URL_RE.exec(f.data);
|
|
1781
|
-
if (m?.[1]) return m[1];
|
|
1782
|
-
}
|
|
1783
|
-
const url = f.data instanceof URL ? f.data.href : typeof f.data === "string" ? f.data : "";
|
|
1784
|
-
if (HTTP_RE.test(url) || f.name) {
|
|
1785
|
-
const ext = (f.name ?? new URL(url, "http://x").pathname).split(".").pop()?.toLowerCase();
|
|
1786
|
-
if (ext === "pdf") return "application/pdf";
|
|
1787
|
-
if (ext && ["png", "jpg", "jpeg", "gif", "webp"].includes(ext)) {
|
|
1788
|
-
return `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
return void 0;
|
|
1792
|
-
};
|
|
1793
|
-
var attachmentKind = (f) => {
|
|
1794
|
-
const mt = mediaTypeOf(f) ?? "";
|
|
1795
|
-
if (mt.startsWith("image/")) return "image";
|
|
1796
|
-
if (mt === "application/pdf") return "pdf";
|
|
1797
|
-
return "file";
|
|
1798
|
-
};
|
|
1799
|
-
var KIND_LABEL = {
|
|
1800
|
-
image: "images",
|
|
1801
|
-
pdf: "PDF files",
|
|
1802
|
-
file: "file attachments"
|
|
1803
|
-
};
|
|
1804
|
-
var KIND_HINT = {
|
|
1805
|
-
image: "Remove the image, or switch to a vision-capable model such as Gemini, Claude or GPT-4o/GPT-5.",
|
|
1806
|
-
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.",
|
|
1807
|
-
file: "Paste its text instead, or switch to a model that accepts this file type."
|
|
1808
|
-
};
|
|
1809
|
-
var AttachmentsNotSupportedError = class extends Error {
|
|
1810
|
-
kind;
|
|
1811
|
-
constructor(model, kind, detail) {
|
|
1812
|
-
super(
|
|
1813
|
-
`The model "${model}" can't take ${KIND_LABEL[kind]}${detail ? ` (${detail})` : ""}. ${KIND_HINT[kind]}`
|
|
1814
|
-
);
|
|
1815
|
-
this.name = "AttachmentsNotSupportedError";
|
|
1816
|
-
this.kind = kind;
|
|
1817
|
-
}
|
|
1818
|
-
toJSON() {
|
|
1819
|
-
return this.message;
|
|
1820
|
-
}
|
|
1821
|
-
};
|
|
1822
|
-
var ImagesNotSupportedError = class extends AttachmentsNotSupportedError {
|
|
1823
|
-
constructor(model, detail) {
|
|
1824
|
-
super(model, "image", detail);
|
|
1825
|
-
this.name = "ImagesNotSupportedError";
|
|
1826
|
-
}
|
|
1827
|
-
};
|
|
1828
|
-
var unsupportedAttachment = (model, kind, detail) => kind === "image" ? new ImagesNotSupportedError(model, detail) : new AttachmentsNotSupportedError(model, kind, detail);
|
|
1829
|
-
var dataOf = (f) => {
|
|
1830
|
-
if (typeof f.data === "string") {
|
|
1831
|
-
const m = DATA_URL_RE.exec(f.data);
|
|
1832
|
-
if (m) return m[2];
|
|
1833
|
-
if (HTTP_RE.test(f.data)) return new URL(f.data);
|
|
1834
|
-
}
|
|
1835
|
-
return f.data;
|
|
1836
|
-
};
|
|
1837
|
-
var toFilePart = (f) => {
|
|
1838
|
-
const kind = attachmentKind(f);
|
|
1839
|
-
const mediaType = mediaTypeOf(f) ?? (kind === "image" ? "image" : "application/octet-stream");
|
|
1840
|
-
return {
|
|
1841
|
-
type: "file",
|
|
1842
|
-
data: dataOf(f),
|
|
1843
|
-
mediaType,
|
|
1844
|
-
...f.name ? { filename: f.name } : {}
|
|
1845
|
-
};
|
|
1846
|
-
};
|
|
1847
|
-
var toImagePart = toFilePart;
|
|
1848
|
-
var modelLabel = (model) => {
|
|
1849
|
-
if (typeof model === "string") return model;
|
|
1850
|
-
const m = model;
|
|
1851
|
-
return m?.modelId ? `${m.modelId}${m.provider ? ` (${m.provider})` : ""}` : "this model";
|
|
1852
|
-
};
|
|
1853
|
-
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;
|
|
1854
|
-
var isAttachmentRefusal = (err) => REFUSAL_RE.test(err instanceof Error ? `${err.name} ${err.message}` : String(err));
|
|
1855
|
-
var isImageRefusal = isAttachmentRefusal;
|
|
1856
|
-
|
|
1857
2048
|
// src/agent/internal.ts
|
|
2049
|
+
init_images();
|
|
1858
2050
|
var promptFor = (ctx, prompt) => ctx.images?.length ? {
|
|
1859
2051
|
messages: [
|
|
1860
2052
|
{
|
|
@@ -1977,7 +2169,7 @@ var executeStep = async (ctx, goal, step, index, total, done) => {
|
|
|
1977
2169
|
}
|
|
1978
2170
|
}
|
|
1979
2171
|
}).catch((err) => {
|
|
1980
|
-
throw imageRefusal(ctx, err, ctx.executorModel) ?? err;
|
|
2172
|
+
throw imageRefusal(ctx, err, ctx.executorModel) ?? contextOverflowOf(err, ctx.executorModel) ?? err;
|
|
1981
2173
|
});
|
|
1982
2174
|
ctx.log.debug("executor text:", loop.text);
|
|
1983
2175
|
const { summary, blocked } = splitBlocker(loop.text);
|
|
@@ -2022,6 +2214,11 @@ var replanWanted = async (trigger, result, opts = {}) => {
|
|
|
2022
2214
|
]);
|
|
2023
2215
|
};
|
|
2024
2216
|
|
|
2217
|
+
// src/agent/planner.ts
|
|
2218
|
+
init_context_window();
|
|
2219
|
+
init_generate();
|
|
2220
|
+
init_util();
|
|
2221
|
+
|
|
2025
2222
|
// src/agent/schemas.ts
|
|
2026
2223
|
var import_zod = require("zod");
|
|
2027
2224
|
var PlanStepSchema = import_zod.z.object({
|
|
@@ -2101,12 +2298,14 @@ ${nudge}` : goal;
|
|
|
2101
2298
|
if (ctx.signal?.aborted) throw err;
|
|
2102
2299
|
const refused = imageRefusal(ctx, err, ctx.plannerModel);
|
|
2103
2300
|
if (refused) throw refused;
|
|
2301
|
+
const overflow = contextOverflowOf(err, ctx.plannerModel);
|
|
2302
|
+
if (overflow) throw overflow;
|
|
2104
2303
|
ctx.log.warn("planner: native structured output failed, salvaging:", asMessage(err));
|
|
2105
2304
|
ctx.emit({ type: "retry", phase: "plan", attempt: 1, error: asMessage(err) });
|
|
2106
2305
|
}
|
|
2107
2306
|
}
|
|
2108
2307
|
const result = await generate(ctx.plannerModel, commonFor("prompted")).catch((err) => {
|
|
2109
|
-
throw imageRefusal(ctx, err, ctx.plannerModel) ?? err;
|
|
2308
|
+
throw imageRefusal(ctx, err, ctx.plannerModel) ?? contextOverflowOf(err, ctx.plannerModel) ?? err;
|
|
2110
2309
|
});
|
|
2111
2310
|
const parsed = parsePlannerResponse(result.text);
|
|
2112
2311
|
ctx.log.debug("planner (prompted) raw:", result.text);
|
|
@@ -2126,6 +2325,8 @@ ${nudge}` : goal;
|
|
|
2126
2325
|
var asMessage = (err) => err instanceof Error ? err.message : String(err);
|
|
2127
2326
|
|
|
2128
2327
|
// src/agent/replanner.ts
|
|
2328
|
+
init_generate();
|
|
2329
|
+
init_util();
|
|
2129
2330
|
var decideReplan = async (ctx, goal, done, remaining) => {
|
|
2130
2331
|
const state = await ctx.state();
|
|
2131
2332
|
const active = ctx.activeSkills?.() ?? [];
|
|
@@ -2174,6 +2375,9 @@ var decideReplan = async (ctx, goal, done, remaining) => {
|
|
|
2174
2375
|
};
|
|
2175
2376
|
|
|
2176
2377
|
// src/agent/synthesizer.ts
|
|
2378
|
+
init_context_window();
|
|
2379
|
+
init_generate();
|
|
2380
|
+
init_util();
|
|
2177
2381
|
var synthesizeAnswer = async (ctx, goal, done, findings = []) => {
|
|
2178
2382
|
const state = await ctx.state();
|
|
2179
2383
|
const active = ctx.activeSkills?.() ?? [];
|
|
@@ -2201,7 +2405,7 @@ var synthesizeAnswer = async (ctx, goal, done, findings = []) => {
|
|
|
2201
2405
|
}
|
|
2202
2406
|
if (part.type === "error") {
|
|
2203
2407
|
const err = part.error instanceof Error ? part.error : new Error(String(part.error));
|
|
2204
|
-
throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? err;
|
|
2408
|
+
throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? contextOverflowOf(err, ctx.synthesizerModel) ?? err;
|
|
2205
2409
|
}
|
|
2206
2410
|
if (part.type !== "text-delta") continue;
|
|
2207
2411
|
const delta = part.text;
|
|
@@ -2247,6 +2451,9 @@ var createLogger = (level = "warn", sink = console) => {
|
|
|
2247
2451
|
};
|
|
2248
2452
|
};
|
|
2249
2453
|
|
|
2454
|
+
// src/agent/runner.ts
|
|
2455
|
+
init_images();
|
|
2456
|
+
|
|
2250
2457
|
// src/providers/capabilities.ts
|
|
2251
2458
|
var CLOUD = /* @__PURE__ */ new Set([
|
|
2252
2459
|
"openai",
|
|
@@ -2259,10 +2466,11 @@ var CLOUD = /* @__PURE__ */ new Set([
|
|
|
2259
2466
|
]);
|
|
2260
2467
|
var supportsNativeTools = (p) => CLOUD.has(p);
|
|
2261
2468
|
var supportsStructuredOutput = (p) => CLOUD.has(p);
|
|
2262
|
-
var directBrowserOk = (p) => p
|
|
2469
|
+
var directBrowserOk = (p) => p !== "web-llm";
|
|
2263
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;
|
|
2264
2472
|
var TEXT_ONLY_MODEL_RE = /gpt-3\.5|o1-mini|o3-mini|deepseek|text-(davinci|embedding)|embedding|babbage|davinci|codestral/i;
|
|
2265
|
-
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;
|
|
2266
2474
|
var PDF_PROVIDER_RE = /^(google|anthropic|openai|azure|vertex|bedrock|gemini)/i;
|
|
2267
2475
|
var supportsImages = (model) => {
|
|
2268
2476
|
if (typeof model === "string") {
|
|
@@ -2273,14 +2481,16 @@ var supportsImages = (model) => {
|
|
|
2273
2481
|
if (!model || typeof model !== "object") return void 0;
|
|
2274
2482
|
const provider = String(model.provider ?? "");
|
|
2275
2483
|
const id = String(model.modelId ?? "");
|
|
2276
|
-
if (LOCAL_RE2.test(provider)) return
|
|
2277
|
-
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;
|
|
2278
2487
|
return VISION_PROVIDER_RE.test(provider) ? true : void 0;
|
|
2279
2488
|
};
|
|
2280
2489
|
var supportsPdf = (model) => {
|
|
2281
2490
|
const vision = supportsImages(model);
|
|
2282
2491
|
if (vision === false) return false;
|
|
2283
2492
|
const provider = typeof model === "string" ? model.split("/")[0] ?? "" : String(model?.provider ?? "");
|
|
2493
|
+
if (LOCAL_RE2.test(provider) || /moonshot/i.test(provider)) return false;
|
|
2284
2494
|
return PDF_PROVIDER_RE.test(provider) ? true : void 0;
|
|
2285
2495
|
};
|
|
2286
2496
|
|
|
@@ -2317,6 +2527,10 @@ var createAgent = async (config) => {
|
|
|
2317
2527
|
]);
|
|
2318
2528
|
const plannerMode = selectToolMode(plannerModel, cfg.toolMode);
|
|
2319
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;
|
|
2320
2534
|
const baseTools = filterTools(
|
|
2321
2535
|
config.tools ?? {},
|
|
2322
2536
|
config.availableTools,
|
|
@@ -2329,7 +2543,8 @@ var createAgent = async (config) => {
|
|
|
2329
2543
|
skillNames.add(s.name);
|
|
2330
2544
|
}
|
|
2331
2545
|
const catalog = toolCatalogOf(baseTools);
|
|
2332
|
-
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;
|
|
2333
2548
|
const reserved = [
|
|
2334
2549
|
...skills.length ? SKILL_TOOL_NAMES : [],
|
|
2335
2550
|
...strategy === "search" ? [FIND_TOOLS_NAME] : []
|
|
@@ -2355,14 +2570,15 @@ var createAgent = async (config) => {
|
|
|
2355
2570
|
const caching = resolveCaching(config.promptCaching);
|
|
2356
2571
|
const textOnly = executorMode === "prompted";
|
|
2357
2572
|
const accepts = {
|
|
2358
|
-
|
|
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)),
|
|
2359
2575
|
pdf: config.inputs?.pdf ?? (textOnly ? false : supportsPdf(executorModel)),
|
|
2360
2576
|
file: config.inputs?.files ?? (textOnly ? false : void 0)
|
|
2361
2577
|
};
|
|
2362
2578
|
const approval = createApprovalState(config.toolApproval);
|
|
2363
2579
|
const log = createLogger(cfg.logLevel, config.logger);
|
|
2364
2580
|
log.info(
|
|
2365
|
-
`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}`
|
|
2366
2582
|
);
|
|
2367
2583
|
const run = async (goal, opts = {}) => {
|
|
2368
2584
|
const emit = (event) => {
|
|
@@ -2473,7 +2689,7 @@ var createAgent = async (config) => {
|
|
|
2473
2689
|
} catch {
|
|
2474
2690
|
}
|
|
2475
2691
|
}
|
|
2476
|
-
if (config.memory &&
|
|
2692
|
+
if (config.memory && byTokens && cfg.compaction.auto && history.length > 0) {
|
|
2477
2693
|
const before = messageTokens(history);
|
|
2478
2694
|
if (before > cfg.compaction.thresholdTokens) {
|
|
2479
2695
|
const compacted = await compressHistory(history, synthesizerModel, {
|
|
@@ -2685,7 +2901,8 @@ var createAgent = async (config) => {
|
|
|
2685
2901
|
}
|
|
2686
2902
|
}
|
|
2687
2903
|
if (isAborted()) return stop();
|
|
2688
|
-
|
|
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.";
|
|
2689
2906
|
if (cfg.synthesize) {
|
|
2690
2907
|
try {
|
|
2691
2908
|
const synth = await synthesizeAnswer(ctx, text, done, findings);
|
|
@@ -2700,12 +2917,12 @@ var createAgent = async (config) => {
|
|
|
2700
2917
|
emit({ type: "final", text: summary });
|
|
2701
2918
|
await remember({ role: "assistant", content: summary });
|
|
2702
2919
|
result.final = summary;
|
|
2703
|
-
if (config.memory && (
|
|
2920
|
+
if (config.memory && (byTokens ? cfg.compaction.auto : cfg.compressAfterChars > 0)) {
|
|
2704
2921
|
try {
|
|
2705
2922
|
const transcript = await config.memory.load(sessionId);
|
|
2706
2923
|
const before = messageTokens(transcript);
|
|
2707
2924
|
const compacted = await compressHistory(transcript, synthesizerModel, {
|
|
2708
|
-
...
|
|
2925
|
+
...byTokens ? {
|
|
2709
2926
|
thresholdTokens: cfg.compaction.thresholdTokens,
|
|
2710
2927
|
keepRecent: cfg.compaction.keepRecentTurns,
|
|
2711
2928
|
summaryMaxTokens: cfg.budgets.compaction
|
|
@@ -2777,6 +2994,7 @@ var createAgent = async (config) => {
|
|
|
2777
2994
|
},
|
|
2778
2995
|
listTools: () => catalog.map((e) => ({ ...e })),
|
|
2779
2996
|
toolStrategy: strategy,
|
|
2997
|
+
contextWindowTokens: cfg.compaction.contextWindowTokens,
|
|
2780
2998
|
skills: skills.map((s) => ({ name: s.name, description: s.description })),
|
|
2781
2999
|
capabilities: { images: accepts.image, pdf: accepts.pdf, files: accepts.file },
|
|
2782
3000
|
models: { planner: plannerModel, executor: executorModel, synthesizer: synthesizerModel }
|
|
@@ -2784,7 +3002,8 @@ var createAgent = async (config) => {
|
|
|
2784
3002
|
};
|
|
2785
3003
|
|
|
2786
3004
|
// src/subagent/tool.ts
|
|
2787
|
-
var
|
|
3005
|
+
var import_ai8 = require("ai");
|
|
3006
|
+
init_util();
|
|
2788
3007
|
|
|
2789
3008
|
// src/subagent/protocol.ts
|
|
2790
3009
|
var toCloneable = (value) => {
|
|
@@ -2886,7 +3105,7 @@ var createSubagentTool = (opts) => {
|
|
|
2886
3105
|
Object.entries(opts.tools ?? {}).map(async ([name, t2]) => ({
|
|
2887
3106
|
name,
|
|
2888
3107
|
description: typeof t2.description === "string" ? t2.description : "",
|
|
2889
|
-
inputSchema: toCloneable(await (0,
|
|
3108
|
+
inputSchema: toCloneable(await (0, import_ai8.asSchema)(t2.inputSchema).jsonSchema),
|
|
2890
3109
|
readOnly: isReadOnlyTool(t2)
|
|
2891
3110
|
}))
|
|
2892
3111
|
);
|
|
@@ -2959,9 +3178,9 @@ var createSubagentTool = (opts) => {
|
|
|
2959
3178
|
safePost(worker, { type: "run", task, config, proxied });
|
|
2960
3179
|
});
|
|
2961
3180
|
};
|
|
2962
|
-
const t = (0,
|
|
3181
|
+
const t = (0, import_ai8.tool)({
|
|
2963
3182
|
description: opts.description,
|
|
2964
|
-
inputSchema: (0,
|
|
3183
|
+
inputSchema: (0, import_ai8.jsonSchema)({
|
|
2965
3184
|
type: "object",
|
|
2966
3185
|
properties: {
|
|
2967
3186
|
task: {
|
|
@@ -3021,7 +3240,7 @@ var createSubagentTool = (opts) => {
|
|
|
3021
3240
|
};
|
|
3022
3241
|
|
|
3023
3242
|
// src/subagent/worker.ts
|
|
3024
|
-
var
|
|
3243
|
+
var import_ai9 = require("ai");
|
|
3025
3244
|
|
|
3026
3245
|
// src/storage/db.ts
|
|
3027
3246
|
var import_idb = require("idb");
|
|
@@ -3188,9 +3407,9 @@ var serveSubagentWorker = (opts = {}) => {
|
|
|
3188
3407
|
const pending = /* @__PURE__ */ new Map();
|
|
3189
3408
|
let callSeq = 0;
|
|
3190
3409
|
const proxy = (spec) => {
|
|
3191
|
-
const t = (0,
|
|
3410
|
+
const t = (0, import_ai9.dynamicTool)({
|
|
3192
3411
|
description: spec.description,
|
|
3193
|
-
inputSchema: (0,
|
|
3412
|
+
inputSchema: (0, import_ai9.jsonSchema)(spec.inputSchema),
|
|
3194
3413
|
execute: (input, options) => new Promise((resolve, reject) => {
|
|
3195
3414
|
const callId = `call-${callSeq += 1}`;
|
|
3196
3415
|
const signal = options?.abortSignal;
|
|
@@ -3268,6 +3487,9 @@ var serveSubagentWorker = (opts = {}) => {
|
|
|
3268
3487
|
});
|
|
3269
3488
|
};
|
|
3270
3489
|
|
|
3490
|
+
// src/index.ts
|
|
3491
|
+
init_images();
|
|
3492
|
+
|
|
3271
3493
|
// src/files/vfs.ts
|
|
3272
3494
|
var MIME = {
|
|
3273
3495
|
txt: "text/plain",
|
|
@@ -3417,15 +3639,15 @@ var VirtualFileSystem = class {
|
|
|
3417
3639
|
};
|
|
3418
3640
|
|
|
3419
3641
|
// src/files/tools.ts
|
|
3420
|
-
var
|
|
3642
|
+
var import_ai10 = require("ai");
|
|
3421
3643
|
var createFileTools = (vfs, opts = {}) => {
|
|
3422
3644
|
const p = opts.prefix ?? "fs_";
|
|
3423
3645
|
const maxRead = opts.maxReadChars ?? 5e4;
|
|
3424
3646
|
const tools = {
|
|
3425
3647
|
[`${p}list`]: markReadOnly(
|
|
3426
|
-
(0,
|
|
3648
|
+
(0, import_ai10.tool)({
|
|
3427
3649
|
description: "List the files in the workspace (attachments the user added, files you wrote). Optionally only under a directory prefix.",
|
|
3428
|
-
inputSchema: (0,
|
|
3650
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3429
3651
|
type: "object",
|
|
3430
3652
|
properties: { prefix: { type: "string", description: 'Directory prefix, e.g. "/docs"' } },
|
|
3431
3653
|
additionalProperties: false
|
|
@@ -3438,9 +3660,9 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3438
3660
|
})
|
|
3439
3661
|
),
|
|
3440
3662
|
[`${p}read`]: markReadOnly(
|
|
3441
|
-
(0,
|
|
3663
|
+
(0, import_ai10.tool)({
|
|
3442
3664
|
description: "Read a text file from the workspace by its path.",
|
|
3443
|
-
inputSchema: (0,
|
|
3665
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3444
3666
|
type: "object",
|
|
3445
3667
|
properties: { path: { type: "string", description: 'Absolute path, e.g. "/notes.md"' } },
|
|
3446
3668
|
required: ["path"],
|
|
@@ -3462,9 +3684,9 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3462
3684
|
)
|
|
3463
3685
|
};
|
|
3464
3686
|
if (opts.readOnly) return tools;
|
|
3465
|
-
tools[`${p}write`] = (0,
|
|
3687
|
+
tools[`${p}write`] = (0, import_ai10.tool)({
|
|
3466
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.",
|
|
3467
|
-
inputSchema: (0,
|
|
3689
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3468
3690
|
type: "object",
|
|
3469
3691
|
properties: {
|
|
3470
3692
|
path: { type: "string", description: 'Absolute path, e.g. "/reports/summary.md"' },
|
|
@@ -3479,9 +3701,9 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3479
3701
|
return { written: info.path, size: info.size };
|
|
3480
3702
|
}
|
|
3481
3703
|
});
|
|
3482
|
-
tools[`${p}delete`] = (0,
|
|
3704
|
+
tools[`${p}delete`] = (0, import_ai10.tool)({
|
|
3483
3705
|
description: "Delete a file from the workspace.",
|
|
3484
|
-
inputSchema: (0,
|
|
3706
|
+
inputSchema: (0, import_ai10.jsonSchema)({
|
|
3485
3707
|
type: "object",
|
|
3486
3708
|
properties: { path: { type: "string" } },
|
|
3487
3709
|
required: ["path"],
|
|
@@ -3494,12 +3716,15 @@ var createFileTools = (vfs, opts = {}) => {
|
|
|
3494
3716
|
|
|
3495
3717
|
// src/index.ts
|
|
3496
3718
|
init_webllm();
|
|
3719
|
+
init_context_window();
|
|
3720
|
+
init_generate();
|
|
3721
|
+
init_util();
|
|
3497
3722
|
|
|
3498
3723
|
// src/tools/define.ts
|
|
3499
|
-
var
|
|
3724
|
+
var import_ai11 = require("ai");
|
|
3500
3725
|
var defineTool = (config) => {
|
|
3501
3726
|
const { promptHint, readOnly, ...rest } = config;
|
|
3502
|
-
const t = (0,
|
|
3727
|
+
const t = (0, import_ai11.tool)(rest);
|
|
3503
3728
|
if (promptHint) t.promptHint = promptHint;
|
|
3504
3729
|
if (readOnly) t.readOnly = true;
|
|
3505
3730
|
return t;
|
|
@@ -3554,9 +3779,13 @@ var IndexedDBStore = class {
|
|
|
3554
3779
|
return (await db.getAllKeys(SESSIONS_STORE)).map(String);
|
|
3555
3780
|
}
|
|
3556
3781
|
};
|
|
3782
|
+
|
|
3783
|
+
// src/index.ts
|
|
3784
|
+
init_compress();
|
|
3557
3785
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3558
3786
|
0 && (module.exports = {
|
|
3559
3787
|
AttachmentsNotSupportedError,
|
|
3788
|
+
ContextWindowExceededError,
|
|
3560
3789
|
FILES_STORE,
|
|
3561
3790
|
FIND_TOOLS_NAME,
|
|
3562
3791
|
ImagesNotSupportedError,
|
|
@@ -3572,10 +3801,12 @@ var IndexedDBStore = class {
|
|
|
3572
3801
|
SESSIONS_STORE,
|
|
3573
3802
|
SKILL_TOOL_NAMES,
|
|
3574
3803
|
TOOL_APPROVAL_MODES,
|
|
3804
|
+
TOOL_SEARCH_WINDOW_SHARE,
|
|
3575
3805
|
ToolBudgetError,
|
|
3576
3806
|
ToolDeniedError,
|
|
3577
3807
|
VaultCredentialStore,
|
|
3578
3808
|
VirtualFileSystem,
|
|
3809
|
+
WEBLLM_DEFAULT_CONTEXT_WINDOW,
|
|
3579
3810
|
attachmentKind,
|
|
3580
3811
|
buildModelFromStage,
|
|
3581
3812
|
bytesToBase64,
|
|
@@ -3583,6 +3814,8 @@ var IndexedDBStore = class {
|
|
|
3583
3814
|
compactHistory,
|
|
3584
3815
|
compactSteps,
|
|
3585
3816
|
compressHistory,
|
|
3817
|
+
contextOverflowOf,
|
|
3818
|
+
contextWindowOf,
|
|
3586
3819
|
createAgent,
|
|
3587
3820
|
createFileTools,
|
|
3588
3821
|
createFindToolsTool,
|
|
@@ -3604,6 +3837,7 @@ var IndexedDBStore = class {
|
|
|
3604
3837
|
estimateMessagesTokens,
|
|
3605
3838
|
estimateTokens,
|
|
3606
3839
|
executeStep,
|
|
3840
|
+
fitCompactionToWindow,
|
|
3607
3841
|
generate,
|
|
3608
3842
|
generateStructured,
|
|
3609
3843
|
getOrCreateVaultKey,
|
|
@@ -3662,9 +3896,12 @@ var IndexedDBStore = class {
|
|
|
3662
3896
|
toImagePart,
|
|
3663
3897
|
tokenize,
|
|
3664
3898
|
toolCatalogOf,
|
|
3899
|
+
toolDefinitionTokens,
|
|
3665
3900
|
toolRunContextOf,
|
|
3666
3901
|
unloadWebLLMModel,
|
|
3902
|
+
webLLMContextWindow,
|
|
3667
3903
|
withRollingBreakpoint,
|
|
3668
|
-
withSystem
|
|
3904
|
+
withSystem,
|
|
3905
|
+
withWebLLMContextWindow
|
|
3669
3906
|
});
|
|
3670
3907
|
//# sourceMappingURL=index.cjs.map
|