@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.js
CHANGED
|
@@ -10,11 +10,43 @@ import {
|
|
|
10
10
|
openAgentWebDB
|
|
11
11
|
} from "./chunk-V7COB2EA.js";
|
|
12
12
|
import {
|
|
13
|
+
AttachmentsNotSupportedError,
|
|
14
|
+
ContextWindowExceededError,
|
|
15
|
+
ImagesNotSupportedError,
|
|
16
|
+
TOOL_SEARCH_WINDOW_SHARE,
|
|
17
|
+
WEBLLM_DEFAULT_CONTEXT_WINDOW,
|
|
18
|
+
attachmentKind,
|
|
19
|
+
clip,
|
|
20
|
+
compactHistory,
|
|
21
|
+
compactSteps,
|
|
22
|
+
compressHistory,
|
|
23
|
+
contextOverflowOf,
|
|
24
|
+
contextWindowOf,
|
|
13
25
|
createWebLLMModel,
|
|
26
|
+
estimateTokens,
|
|
27
|
+
fitCompactionToWindow,
|
|
28
|
+
generate,
|
|
29
|
+
generateStructured,
|
|
30
|
+
isAttachmentRefusal,
|
|
31
|
+
isImageRefusal,
|
|
14
32
|
isWebGPUAvailable,
|
|
33
|
+
mediaTypeOf,
|
|
34
|
+
messageTokens,
|
|
35
|
+
modelLabel,
|
|
36
|
+
normalizeUsage,
|
|
15
37
|
preloadWebLLMModel,
|
|
16
|
-
|
|
17
|
-
|
|
38
|
+
promptOf,
|
|
39
|
+
resolveCompaction,
|
|
40
|
+
stream,
|
|
41
|
+
timeoutSignal,
|
|
42
|
+
toFilePart,
|
|
43
|
+
toImagePart,
|
|
44
|
+
toolDefinitionTokens,
|
|
45
|
+
unloadWebLLMModel,
|
|
46
|
+
unsupportedAttachment,
|
|
47
|
+
webLLMContextWindow,
|
|
48
|
+
withWebLLMContextWindow
|
|
49
|
+
} from "./chunk-YA6TQQ3Q.js";
|
|
18
50
|
|
|
19
51
|
// src/caching.ts
|
|
20
52
|
var resolveCaching = (s) => {
|
|
@@ -59,145 +91,6 @@ var withRollingBreakpoint = (messages, caching) => {
|
|
|
59
91
|
return out;
|
|
60
92
|
};
|
|
61
93
|
|
|
62
|
-
// src/llm/generate.ts
|
|
63
|
-
import {
|
|
64
|
-
generateObject,
|
|
65
|
-
generateText,
|
|
66
|
-
streamText
|
|
67
|
-
} from "ai";
|
|
68
|
-
|
|
69
|
-
// src/llm/util.ts
|
|
70
|
-
var clip = (s, max) => s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
71
|
-
var promptOf = (opts) => opts.messages ? { messages: opts.messages } : { prompt: opts.prompt ?? "" };
|
|
72
|
-
var normalizeUsage = (u) => {
|
|
73
|
-
const inputTokens = u?.inputTokens ?? 0;
|
|
74
|
-
const outputTokens = u?.outputTokens ?? 0;
|
|
75
|
-
return {
|
|
76
|
-
inputTokens,
|
|
77
|
-
outputTokens,
|
|
78
|
-
totalTokens: u?.totalTokens ?? inputTokens + outputTokens,
|
|
79
|
-
reasoningTokens: u?.outputTokenDetails?.reasoningTokens ?? u?.reasoningTokens ?? 0,
|
|
80
|
-
cachedInputTokens: u?.inputTokenDetails?.cacheReadTokens ?? u?.cachedInputTokens ?? 0,
|
|
81
|
-
cacheWriteTokens: u?.inputTokenDetails?.cacheWriteTokens ?? 0
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
var timeoutSignal = (signal, ms) => {
|
|
85
|
-
if (!ms || ms <= 0) return signal;
|
|
86
|
-
const timeout = AbortSignal.timeout(ms);
|
|
87
|
-
if (!signal) return timeout;
|
|
88
|
-
return typeof AbortSignal.any === "function" ? AbortSignal.any([signal, timeout]) : signal;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// src/llm/generate.ts
|
|
92
|
-
var callSettings = (opts) => ({
|
|
93
|
-
...opts.system !== void 0 ? { instructions: opts.system } : {},
|
|
94
|
-
maxOutputTokens: opts.maxOutputTokens,
|
|
95
|
-
temperature: opts.temperature,
|
|
96
|
-
...opts.reasoning ? { reasoning: opts.reasoning } : {},
|
|
97
|
-
...opts.providerOptions ? { providerOptions: opts.providerOptions } : {},
|
|
98
|
-
abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs)
|
|
99
|
-
});
|
|
100
|
-
var generate = (model, opts = {}) => generateText({
|
|
101
|
-
model,
|
|
102
|
-
...callSettings(opts),
|
|
103
|
-
...promptOf(opts),
|
|
104
|
-
tools: opts.tools
|
|
105
|
-
});
|
|
106
|
-
var stream = (model, opts = {}) => streamText({
|
|
107
|
-
model,
|
|
108
|
-
...callSettings(opts),
|
|
109
|
-
...promptOf(opts),
|
|
110
|
-
tools: opts.tools
|
|
111
|
-
});
|
|
112
|
-
var generateStructured = (model, schema, opts = {}) => generateObject({
|
|
113
|
-
model,
|
|
114
|
-
schema,
|
|
115
|
-
...callSettings(opts),
|
|
116
|
-
...promptOf(opts)
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// src/memory/compress.ts
|
|
120
|
-
var resolveCompaction = (c) => {
|
|
121
|
-
const contextWindowTokens = c?.contextWindowTokens ?? 128e3;
|
|
122
|
-
return {
|
|
123
|
-
auto: c?.auto ?? true,
|
|
124
|
-
contextWindowTokens,
|
|
125
|
-
thresholdTokens: c?.thresholdTokens ?? Math.floor(contextWindowTokens / 2),
|
|
126
|
-
keepRecentTurns: c?.keepRecentTurns ?? 4,
|
|
127
|
-
keepRecentSteps: c?.keepRecentSteps ?? 3,
|
|
128
|
-
summaryMaxTokens: c?.summaryMaxTokens ?? 1024,
|
|
129
|
-
maxToolOutputChars: c?.maxToolOutputChars ?? 2e4,
|
|
130
|
-
clearToolResultsAfterTokens: c?.clearToolResultsAfterTokens ?? Math.floor(contextWindowTokens / 4),
|
|
131
|
-
keepToolResults: c?.keepToolResults ?? 3
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
var estimateTokens = (text) => Math.ceil((text ?? "").length / 4);
|
|
135
|
-
var messageTokens = (msgs) => msgs.reduce((n, m) => n + estimateTokens(`${m.role}: ${m.content}
|
|
136
|
-
`), 0);
|
|
137
|
-
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.";
|
|
138
|
-
var compressHistory = async (messages, model, opts = {}) => {
|
|
139
|
-
const keepRecent = opts.keepRecent ?? 6;
|
|
140
|
-
if (messages.length <= keepRecent + 1) return messages;
|
|
141
|
-
if (!opts.force) {
|
|
142
|
-
if (opts.thresholdTokens !== void 0) {
|
|
143
|
-
if (opts.thresholdTokens <= 0 || messageTokens(messages) <= opts.thresholdTokens) {
|
|
144
|
-
return messages;
|
|
145
|
-
}
|
|
146
|
-
} else {
|
|
147
|
-
const maxChars = opts.maxChars ?? 12e3;
|
|
148
|
-
const chars = messages.reduce((n, m) => n + m.content.length, 0);
|
|
149
|
-
if (maxChars <= 0 || chars <= maxChars) return messages;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
const head = messages.slice(0, messages.length - keepRecent);
|
|
153
|
-
const tail = messages.slice(messages.length - keepRecent);
|
|
154
|
-
const transcript = head.map((m) => `${m.role}: ${m.content}`).join("\n").slice(-48e3);
|
|
155
|
-
try {
|
|
156
|
-
const result = await generate(model, {
|
|
157
|
-
system: SUMMARY_SYSTEM,
|
|
158
|
-
prompt: transcript,
|
|
159
|
-
maxOutputTokens: opts.summaryMaxTokens ?? 400,
|
|
160
|
-
timeoutMs: opts.timeoutMs,
|
|
161
|
-
abortSignal: opts.abortSignal
|
|
162
|
-
});
|
|
163
|
-
opts.onUsage?.(normalizeUsage(result.usage));
|
|
164
|
-
const clean = (result.text || "").trim();
|
|
165
|
-
if (!clean) return messages;
|
|
166
|
-
const summaryMsg = {
|
|
167
|
-
role: "system",
|
|
168
|
-
content: `Summary of earlier conversation:
|
|
169
|
-
${clean}`,
|
|
170
|
-
ts: head[0]?.ts
|
|
171
|
-
};
|
|
172
|
-
return [summaryMsg, ...tail];
|
|
173
|
-
} catch {
|
|
174
|
-
return messages;
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
var compactHistory = compressHistory;
|
|
178
|
-
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.";
|
|
179
|
-
var compactSteps = async (done, model, opts) => {
|
|
180
|
-
const keepRecent = opts.keepRecent ?? 3;
|
|
181
|
-
if (done.length <= keepRecent + 1) return done;
|
|
182
|
-
if (!opts.force && estimateTokens(done.join("\n")) <= opts.thresholdTokens) return done;
|
|
183
|
-
const head = done.slice(0, done.length - keepRecent);
|
|
184
|
-
try {
|
|
185
|
-
const result = await generate(model, {
|
|
186
|
-
system: TRACE_SYSTEM,
|
|
187
|
-
prompt: head.map((d, i) => `${i + 1}. ${d}`).join("\n"),
|
|
188
|
-
maxOutputTokens: opts.summaryMaxTokens ?? 600,
|
|
189
|
-
timeoutMs: opts.timeoutMs,
|
|
190
|
-
abortSignal: opts.abortSignal
|
|
191
|
-
});
|
|
192
|
-
opts.onUsage?.(normalizeUsage(result.usage));
|
|
193
|
-
const clean = (result.text || "").trim();
|
|
194
|
-
if (!clean) return done;
|
|
195
|
-
return [`Summary of ${head.length} earlier step(s): ${clean}`, ...done.slice(head.length)];
|
|
196
|
-
} catch {
|
|
197
|
-
return done;
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
|
|
201
94
|
// src/config.ts
|
|
202
95
|
var resolveConfig = (c) => ({
|
|
203
96
|
clientName: c.clientName ?? "agent-web",
|
|
@@ -361,7 +254,7 @@ var buildModelFromStage = async (resolved, credentials, clientName = "agent-web"
|
|
|
361
254
|
const apiKey = await resolveApiKey(spec, credentials);
|
|
362
255
|
switch (spec.providerType) {
|
|
363
256
|
case "web-llm": {
|
|
364
|
-
const { createWebLLMModel: createWebLLMModel2 } = await import("./webllm-
|
|
257
|
+
const { createWebLLMModel: createWebLLMModel2 } = await import("./webllm-QTJ3EGTG.js");
|
|
365
258
|
return createWebLLMModel2(spec.model, providerOptions);
|
|
366
259
|
}
|
|
367
260
|
case "gateway": {
|
|
@@ -1169,9 +1062,9 @@ var schemaHintOf = async (t) => {
|
|
|
1169
1062
|
|
|
1170
1063
|
// src/llm/tool-loop.ts
|
|
1171
1064
|
import {
|
|
1172
|
-
generateText
|
|
1065
|
+
generateText,
|
|
1173
1066
|
stepCountIs,
|
|
1174
|
-
streamText
|
|
1067
|
+
streamText
|
|
1175
1068
|
} from "ai";
|
|
1176
1069
|
|
|
1177
1070
|
// src/agent/loop-types.ts
|
|
@@ -1410,7 +1303,7 @@ var runNative = async (model, opts) => {
|
|
|
1410
1303
|
const caching = opts.caching?.enabled ? opts.caching : void 0;
|
|
1411
1304
|
const clear = opts.clearToolResults ? createToolResultClearer(opts.clearToolResults, opts.callbacks?.onToolResultsCleared) : void 0;
|
|
1412
1305
|
const editMessages = caching || clear;
|
|
1413
|
-
const result =
|
|
1306
|
+
const result = streamText({
|
|
1414
1307
|
model,
|
|
1415
1308
|
tools: opts.tools,
|
|
1416
1309
|
...initialActive ? { activeTools: initialActive } : {},
|
|
@@ -1517,7 +1410,7 @@ var runPrompted = async (model, opts) => {
|
|
|
1517
1410
|
break;
|
|
1518
1411
|
}
|
|
1519
1412
|
const before = new Set(Object.keys(callable()));
|
|
1520
|
-
const result = await
|
|
1413
|
+
const result = await generateText({
|
|
1521
1414
|
model,
|
|
1522
1415
|
...callExtras(opts),
|
|
1523
1416
|
messages: opts.caching ? withRollingBreakpoint(messages, opts.caching) : messages,
|
|
@@ -1566,7 +1459,8 @@ var resolveThinking = (setting) => {
|
|
|
1566
1459
|
const cfg = normalize(setting);
|
|
1567
1460
|
if (!cfg) return {};
|
|
1568
1461
|
const level = cfg.level ?? "medium";
|
|
1569
|
-
|
|
1462
|
+
const webllm = (on) => ({ "web-llm": { extra_body: { enable_thinking: on } } });
|
|
1463
|
+
if (level === "none") return { reasoning: "none", providerOptions: webllm(false) };
|
|
1570
1464
|
const includeThoughts = cfg.includeThoughts !== false;
|
|
1571
1465
|
const budget = cfg.budgetTokens;
|
|
1572
1466
|
if (typeof budget === "number" && budget > 0) {
|
|
@@ -1574,16 +1468,18 @@ var resolveThinking = (setting) => {
|
|
|
1574
1468
|
reasoning: level,
|
|
1575
1469
|
providerOptions: {
|
|
1576
1470
|
anthropic: { thinking: { type: "enabled", budgetTokens: budget } },
|
|
1577
|
-
google: { thinkingConfig: { thinkingBudget: budget, includeThoughts } }
|
|
1471
|
+
google: { thinkingConfig: { thinkingBudget: budget, includeThoughts } },
|
|
1472
|
+
...webllm(true)
|
|
1578
1473
|
}
|
|
1579
1474
|
};
|
|
1580
1475
|
}
|
|
1581
|
-
if (!includeThoughts) return { reasoning: level };
|
|
1476
|
+
if (!includeThoughts) return { reasoning: level, providerOptions: webllm(true) };
|
|
1582
1477
|
return {
|
|
1583
1478
|
reasoning: level,
|
|
1584
1479
|
providerOptions: {
|
|
1585
1480
|
google: { thinkingConfig: { includeThoughts: true } },
|
|
1586
|
-
openai: { reasoningSummary: "auto" }
|
|
1481
|
+
openai: { reasoningSummary: "auto" },
|
|
1482
|
+
...webllm(true)
|
|
1587
1483
|
}
|
|
1588
1484
|
};
|
|
1589
1485
|
};
|
|
@@ -1605,89 +1501,6 @@ var mergeProviderOptions = (...maps) => {
|
|
|
1605
1501
|
return out;
|
|
1606
1502
|
};
|
|
1607
1503
|
|
|
1608
|
-
// src/images.ts
|
|
1609
|
-
var DATA_URL_RE = /^data:([^;,]+)?;base64,(.*)$/s;
|
|
1610
|
-
var HTTP_RE = /^https?:\/\//i;
|
|
1611
|
-
var mediaTypeOf = (f) => {
|
|
1612
|
-
if (f.mediaType) return f.mediaType;
|
|
1613
|
-
if (typeof f.data === "string") {
|
|
1614
|
-
const m = DATA_URL_RE.exec(f.data);
|
|
1615
|
-
if (m?.[1]) return m[1];
|
|
1616
|
-
}
|
|
1617
|
-
const url = f.data instanceof URL ? f.data.href : typeof f.data === "string" ? f.data : "";
|
|
1618
|
-
if (HTTP_RE.test(url) || f.name) {
|
|
1619
|
-
const ext = (f.name ?? new URL(url, "http://x").pathname).split(".").pop()?.toLowerCase();
|
|
1620
|
-
if (ext === "pdf") return "application/pdf";
|
|
1621
|
-
if (ext && ["png", "jpg", "jpeg", "gif", "webp"].includes(ext)) {
|
|
1622
|
-
return `image/${ext === "jpg" ? "jpeg" : ext}`;
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
return void 0;
|
|
1626
|
-
};
|
|
1627
|
-
var attachmentKind = (f) => {
|
|
1628
|
-
const mt = mediaTypeOf(f) ?? "";
|
|
1629
|
-
if (mt.startsWith("image/")) return "image";
|
|
1630
|
-
if (mt === "application/pdf") return "pdf";
|
|
1631
|
-
return "file";
|
|
1632
|
-
};
|
|
1633
|
-
var KIND_LABEL = {
|
|
1634
|
-
image: "images",
|
|
1635
|
-
pdf: "PDF files",
|
|
1636
|
-
file: "file attachments"
|
|
1637
|
-
};
|
|
1638
|
-
var KIND_HINT = {
|
|
1639
|
-
image: "Remove the image, or switch to a vision-capable model such as Gemini, Claude or GPT-4o/GPT-5.",
|
|
1640
|
-
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.",
|
|
1641
|
-
file: "Paste its text instead, or switch to a model that accepts this file type."
|
|
1642
|
-
};
|
|
1643
|
-
var AttachmentsNotSupportedError = class extends Error {
|
|
1644
|
-
kind;
|
|
1645
|
-
constructor(model, kind, detail) {
|
|
1646
|
-
super(
|
|
1647
|
-
`The model "${model}" can't take ${KIND_LABEL[kind]}${detail ? ` (${detail})` : ""}. ${KIND_HINT[kind]}`
|
|
1648
|
-
);
|
|
1649
|
-
this.name = "AttachmentsNotSupportedError";
|
|
1650
|
-
this.kind = kind;
|
|
1651
|
-
}
|
|
1652
|
-
toJSON() {
|
|
1653
|
-
return this.message;
|
|
1654
|
-
}
|
|
1655
|
-
};
|
|
1656
|
-
var ImagesNotSupportedError = class extends AttachmentsNotSupportedError {
|
|
1657
|
-
constructor(model, detail) {
|
|
1658
|
-
super(model, "image", detail);
|
|
1659
|
-
this.name = "ImagesNotSupportedError";
|
|
1660
|
-
}
|
|
1661
|
-
};
|
|
1662
|
-
var unsupportedAttachment = (model, kind, detail) => kind === "image" ? new ImagesNotSupportedError(model, detail) : new AttachmentsNotSupportedError(model, kind, detail);
|
|
1663
|
-
var dataOf = (f) => {
|
|
1664
|
-
if (typeof f.data === "string") {
|
|
1665
|
-
const m = DATA_URL_RE.exec(f.data);
|
|
1666
|
-
if (m) return m[2];
|
|
1667
|
-
if (HTTP_RE.test(f.data)) return new URL(f.data);
|
|
1668
|
-
}
|
|
1669
|
-
return f.data;
|
|
1670
|
-
};
|
|
1671
|
-
var toFilePart = (f) => {
|
|
1672
|
-
const kind = attachmentKind(f);
|
|
1673
|
-
const mediaType = mediaTypeOf(f) ?? (kind === "image" ? "image" : "application/octet-stream");
|
|
1674
|
-
return {
|
|
1675
|
-
type: "file",
|
|
1676
|
-
data: dataOf(f),
|
|
1677
|
-
mediaType,
|
|
1678
|
-
...f.name ? { filename: f.name } : {}
|
|
1679
|
-
};
|
|
1680
|
-
};
|
|
1681
|
-
var toImagePart = toFilePart;
|
|
1682
|
-
var modelLabel = (model) => {
|
|
1683
|
-
if (typeof model === "string") return model;
|
|
1684
|
-
const m = model;
|
|
1685
|
-
return m?.modelId ? `${m.modelId}${m.provider ? ` (${m.provider})` : ""}` : "this model";
|
|
1686
|
-
};
|
|
1687
|
-
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;
|
|
1688
|
-
var isAttachmentRefusal = (err) => REFUSAL_RE.test(err instanceof Error ? `${err.name} ${err.message}` : String(err));
|
|
1689
|
-
var isImageRefusal = isAttachmentRefusal;
|
|
1690
|
-
|
|
1691
1504
|
// src/agent/internal.ts
|
|
1692
1505
|
var promptFor = (ctx, prompt) => ctx.images?.length ? {
|
|
1693
1506
|
messages: [
|
|
@@ -1811,7 +1624,7 @@ var executeStep = async (ctx, goal, step, index, total, done) => {
|
|
|
1811
1624
|
}
|
|
1812
1625
|
}
|
|
1813
1626
|
}).catch((err) => {
|
|
1814
|
-
throw imageRefusal(ctx, err, ctx.executorModel) ?? err;
|
|
1627
|
+
throw imageRefusal(ctx, err, ctx.executorModel) ?? contextOverflowOf(err, ctx.executorModel) ?? err;
|
|
1815
1628
|
});
|
|
1816
1629
|
ctx.log.debug("executor text:", loop.text);
|
|
1817
1630
|
const { summary, blocked } = splitBlocker(loop.text);
|
|
@@ -1935,12 +1748,14 @@ ${nudge}` : goal;
|
|
|
1935
1748
|
if (ctx.signal?.aborted) throw err;
|
|
1936
1749
|
const refused = imageRefusal(ctx, err, ctx.plannerModel);
|
|
1937
1750
|
if (refused) throw refused;
|
|
1751
|
+
const overflow = contextOverflowOf(err, ctx.plannerModel);
|
|
1752
|
+
if (overflow) throw overflow;
|
|
1938
1753
|
ctx.log.warn("planner: native structured output failed, salvaging:", asMessage(err));
|
|
1939
1754
|
ctx.emit({ type: "retry", phase: "plan", attempt: 1, error: asMessage(err) });
|
|
1940
1755
|
}
|
|
1941
1756
|
}
|
|
1942
1757
|
const result = await generate(ctx.plannerModel, commonFor("prompted")).catch((err) => {
|
|
1943
|
-
throw imageRefusal(ctx, err, ctx.plannerModel) ?? err;
|
|
1758
|
+
throw imageRefusal(ctx, err, ctx.plannerModel) ?? contextOverflowOf(err, ctx.plannerModel) ?? err;
|
|
1944
1759
|
});
|
|
1945
1760
|
const parsed = parsePlannerResponse(result.text);
|
|
1946
1761
|
ctx.log.debug("planner (prompted) raw:", result.text);
|
|
@@ -2035,7 +1850,7 @@ var synthesizeAnswer = async (ctx, goal, done, findings = []) => {
|
|
|
2035
1850
|
}
|
|
2036
1851
|
if (part.type === "error") {
|
|
2037
1852
|
const err = part.error instanceof Error ? part.error : new Error(String(part.error));
|
|
2038
|
-
throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? err;
|
|
1853
|
+
throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? contextOverflowOf(err, ctx.synthesizerModel) ?? err;
|
|
2039
1854
|
}
|
|
2040
1855
|
if (part.type !== "text-delta") continue;
|
|
2041
1856
|
const delta = part.text;
|
|
@@ -2093,10 +1908,11 @@ var CLOUD = /* @__PURE__ */ new Set([
|
|
|
2093
1908
|
]);
|
|
2094
1909
|
var supportsNativeTools = (p) => CLOUD.has(p);
|
|
2095
1910
|
var supportsStructuredOutput = (p) => CLOUD.has(p);
|
|
2096
|
-
var directBrowserOk = (p) => p
|
|
1911
|
+
var directBrowserOk = (p) => p !== "web-llm";
|
|
2097
1912
|
var LOCAL_RE2 = /web-?llm|mlc|browser-ai|transformers|built-?in/i;
|
|
1913
|
+
var LOCAL_VISION_RE = /vision|[-_]vl\b|[-_]vl[-_]|llava|smolvlm|moondream|gemma-?3n/i;
|
|
2098
1914
|
var TEXT_ONLY_MODEL_RE = /gpt-3\.5|o1-mini|o3-mini|deepseek|text-(davinci|embedding)|embedding|babbage|davinci|codestral/i;
|
|
2099
|
-
var VISION_PROVIDER_RE = /^(google|anthropic|openai|azure|xai|vertex|bedrock|gemini)/i;
|
|
1915
|
+
var VISION_PROVIDER_RE = /^(google|anthropic|openai|azure|xai|vertex|bedrock|gemini|moonshot|mistral)/i;
|
|
2100
1916
|
var PDF_PROVIDER_RE = /^(google|anthropic|openai|azure|vertex|bedrock|gemini)/i;
|
|
2101
1917
|
var supportsImages = (model) => {
|
|
2102
1918
|
if (typeof model === "string") {
|
|
@@ -2107,14 +1923,16 @@ var supportsImages = (model) => {
|
|
|
2107
1923
|
if (!model || typeof model !== "object") return void 0;
|
|
2108
1924
|
const provider = String(model.provider ?? "");
|
|
2109
1925
|
const id = String(model.modelId ?? "");
|
|
2110
|
-
if (LOCAL_RE2.test(provider)) return
|
|
2111
|
-
if (/deepseek/i.test(provider)
|
|
1926
|
+
if (LOCAL_RE2.test(provider)) return LOCAL_VISION_RE.test(id);
|
|
1927
|
+
if (/deepseek/i.test(provider)) return /flash/i.test(id);
|
|
1928
|
+
if (TEXT_ONLY_MODEL_RE.test(id)) return false;
|
|
2112
1929
|
return VISION_PROVIDER_RE.test(provider) ? true : void 0;
|
|
2113
1930
|
};
|
|
2114
1931
|
var supportsPdf = (model) => {
|
|
2115
1932
|
const vision = supportsImages(model);
|
|
2116
1933
|
if (vision === false) return false;
|
|
2117
1934
|
const provider = typeof model === "string" ? model.split("/")[0] ?? "" : String(model?.provider ?? "");
|
|
1935
|
+
if (LOCAL_RE2.test(provider) || /moonshot/i.test(provider)) return false;
|
|
2118
1936
|
return PDF_PROVIDER_RE.test(provider) ? true : void 0;
|
|
2119
1937
|
};
|
|
2120
1938
|
|
|
@@ -2151,6 +1969,10 @@ var createAgent = async (config) => {
|
|
|
2151
1969
|
]);
|
|
2152
1970
|
const plannerMode = selectToolMode(plannerModel, cfg.toolMode);
|
|
2153
1971
|
const executorMode = selectToolMode(executorModel, cfg.toolMode);
|
|
1972
|
+
const modelWindows = [executorModel, plannerModel, synthesizerModel].map(contextWindowOf).filter((w) => w !== void 0);
|
|
1973
|
+
const modelWindow = modelWindows.length ? Math.min(...modelWindows) : void 0;
|
|
1974
|
+
cfg.compaction = fitCompactionToWindow(cfg.compaction, config.compaction, modelWindow);
|
|
1975
|
+
const byTokens = Boolean(config.compaction) || modelWindow !== void 0;
|
|
2154
1976
|
const baseTools = filterTools(
|
|
2155
1977
|
config.tools ?? {},
|
|
2156
1978
|
config.availableTools,
|
|
@@ -2163,7 +1985,8 @@ var createAgent = async (config) => {
|
|
|
2163
1985
|
skillNames.add(s.name);
|
|
2164
1986
|
}
|
|
2165
1987
|
const catalog = toolCatalogOf(baseTools);
|
|
2166
|
-
const
|
|
1988
|
+
const toolTokens = cfg.toolSelectionStrategy === "auto" ? await toolDefinitionTokens(baseTools) : 0;
|
|
1989
|
+
const strategy = cfg.toolSelectionStrategy === "auto" ? catalog.length > cfg.toolSearchThreshold || toolTokens > cfg.compaction.contextWindowTokens * TOOL_SEARCH_WINDOW_SHARE ? "search" : "all" : cfg.toolSelectionStrategy;
|
|
2167
1990
|
const reserved = [
|
|
2168
1991
|
...skills.length ? SKILL_TOOL_NAMES : [],
|
|
2169
1992
|
...strategy === "search" ? [FIND_TOOLS_NAME] : []
|
|
@@ -2189,14 +2012,15 @@ var createAgent = async (config) => {
|
|
|
2189
2012
|
const caching = resolveCaching(config.promptCaching);
|
|
2190
2013
|
const textOnly = executorMode === "prompted";
|
|
2191
2014
|
const accepts = {
|
|
2192
|
-
|
|
2015
|
+
// A local vision model (the prompted path carries images too) says so by its id.
|
|
2016
|
+
image: config.inputs?.images ?? config.vision ?? (textOnly ? supportsImages(executorModel) === true : supportsImages(executorModel)),
|
|
2193
2017
|
pdf: config.inputs?.pdf ?? (textOnly ? false : supportsPdf(executorModel)),
|
|
2194
2018
|
file: config.inputs?.files ?? (textOnly ? false : void 0)
|
|
2195
2019
|
};
|
|
2196
2020
|
const approval = createApprovalState(config.toolApproval);
|
|
2197
2021
|
const log = createLogger(cfg.logLevel, config.logger);
|
|
2198
2022
|
log.info(
|
|
2199
|
-
`agent ready \u2014 ${catalog.length} tool(s) (${strategy}), skills: [${[...skillNames].join(", ") || "none"}], planner mode: ${plannerMode}, executor mode: ${executorMode}, approval: ${approval.mode}`
|
|
2023
|
+
`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}`
|
|
2200
2024
|
);
|
|
2201
2025
|
const run = async (goal, opts = {}) => {
|
|
2202
2026
|
const emit = (event) => {
|
|
@@ -2307,7 +2131,7 @@ var createAgent = async (config) => {
|
|
|
2307
2131
|
} catch {
|
|
2308
2132
|
}
|
|
2309
2133
|
}
|
|
2310
|
-
if (config.memory &&
|
|
2134
|
+
if (config.memory && byTokens && cfg.compaction.auto && history.length > 0) {
|
|
2311
2135
|
const before = messageTokens(history);
|
|
2312
2136
|
if (before > cfg.compaction.thresholdTokens) {
|
|
2313
2137
|
const compacted = await compressHistory(history, synthesizerModel, {
|
|
@@ -2519,7 +2343,8 @@ var createAgent = async (config) => {
|
|
|
2519
2343
|
}
|
|
2520
2344
|
}
|
|
2521
2345
|
if (isAborted()) return stop();
|
|
2522
|
-
|
|
2346
|
+
const stepWords = result.trace.map((r) => r.summary.trim()).filter((t) => t && !/^(Executed \d+ tool call\(s\)\.|Step produced no output\.)$/.test(t));
|
|
2347
|
+
let summary = stepWords.length ? stepWords.join("\n\n") : "Done \u2014 the changes have been applied.";
|
|
2523
2348
|
if (cfg.synthesize) {
|
|
2524
2349
|
try {
|
|
2525
2350
|
const synth = await synthesizeAnswer(ctx, text, done, findings);
|
|
@@ -2534,12 +2359,12 @@ var createAgent = async (config) => {
|
|
|
2534
2359
|
emit({ type: "final", text: summary });
|
|
2535
2360
|
await remember({ role: "assistant", content: summary });
|
|
2536
2361
|
result.final = summary;
|
|
2537
|
-
if (config.memory && (
|
|
2362
|
+
if (config.memory && (byTokens ? cfg.compaction.auto : cfg.compressAfterChars > 0)) {
|
|
2538
2363
|
try {
|
|
2539
2364
|
const transcript = await config.memory.load(sessionId);
|
|
2540
2365
|
const before = messageTokens(transcript);
|
|
2541
2366
|
const compacted = await compressHistory(transcript, synthesizerModel, {
|
|
2542
|
-
...
|
|
2367
|
+
...byTokens ? {
|
|
2543
2368
|
thresholdTokens: cfg.compaction.thresholdTokens,
|
|
2544
2369
|
keepRecent: cfg.compaction.keepRecentTurns,
|
|
2545
2370
|
summaryMaxTokens: cfg.budgets.compaction
|
|
@@ -2611,6 +2436,7 @@ var createAgent = async (config) => {
|
|
|
2611
2436
|
},
|
|
2612
2437
|
listTools: () => catalog.map((e) => ({ ...e })),
|
|
2613
2438
|
toolStrategy: strategy,
|
|
2439
|
+
contextWindowTokens: cfg.compaction.contextWindowTokens,
|
|
2614
2440
|
skills: skills.map((s) => ({ name: s.name, description: s.description })),
|
|
2615
2441
|
capabilities: { images: accepts.image, pdf: accepts.pdf, files: accepts.file },
|
|
2616
2442
|
models: { planner: plannerModel, executor: executorModel, synthesizer: synthesizerModel }
|
|
@@ -3270,6 +3096,7 @@ var IndexedDBStore = class {
|
|
|
3270
3096
|
};
|
|
3271
3097
|
export {
|
|
3272
3098
|
AttachmentsNotSupportedError,
|
|
3099
|
+
ContextWindowExceededError,
|
|
3273
3100
|
FILES_STORE,
|
|
3274
3101
|
FIND_TOOLS_NAME,
|
|
3275
3102
|
ImagesNotSupportedError,
|
|
@@ -3285,10 +3112,12 @@ export {
|
|
|
3285
3112
|
SESSIONS_STORE,
|
|
3286
3113
|
SKILL_TOOL_NAMES,
|
|
3287
3114
|
TOOL_APPROVAL_MODES,
|
|
3115
|
+
TOOL_SEARCH_WINDOW_SHARE,
|
|
3288
3116
|
ToolBudgetError,
|
|
3289
3117
|
ToolDeniedError,
|
|
3290
3118
|
VaultCredentialStore,
|
|
3291
3119
|
VirtualFileSystem,
|
|
3120
|
+
WEBLLM_DEFAULT_CONTEXT_WINDOW,
|
|
3292
3121
|
attachmentKind,
|
|
3293
3122
|
buildModelFromStage,
|
|
3294
3123
|
bytesToBase64,
|
|
@@ -3296,6 +3125,8 @@ export {
|
|
|
3296
3125
|
compactHistory,
|
|
3297
3126
|
compactSteps,
|
|
3298
3127
|
compressHistory,
|
|
3128
|
+
contextOverflowOf,
|
|
3129
|
+
contextWindowOf,
|
|
3299
3130
|
createAgent,
|
|
3300
3131
|
createFileTools,
|
|
3301
3132
|
createFindToolsTool,
|
|
@@ -3317,6 +3148,7 @@ export {
|
|
|
3317
3148
|
messageTokens as estimateMessagesTokens,
|
|
3318
3149
|
estimateTokens,
|
|
3319
3150
|
executeStep,
|
|
3151
|
+
fitCompactionToWindow,
|
|
3320
3152
|
generate,
|
|
3321
3153
|
generateStructured,
|
|
3322
3154
|
getOrCreateVaultKey,
|
|
@@ -3375,9 +3207,12 @@ export {
|
|
|
3375
3207
|
toImagePart,
|
|
3376
3208
|
tokenize,
|
|
3377
3209
|
toolCatalogOf,
|
|
3210
|
+
toolDefinitionTokens,
|
|
3378
3211
|
toolRunContextOf,
|
|
3379
3212
|
unloadWebLLMModel,
|
|
3213
|
+
webLLMContextWindow,
|
|
3380
3214
|
withRollingBreakpoint,
|
|
3381
|
-
withSystem
|
|
3215
|
+
withSystem,
|
|
3216
|
+
withWebLLMContextWindow
|
|
3382
3217
|
};
|
|
3383
3218
|
//# sourceMappingURL=index.js.map
|