@dudko.dev/agent-web 0.0.21 → 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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
- unloadWebLLMModel
17
- } from "./chunk-IT65EW77.js";
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-XUBUNKFN.js");
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 as generateText2,
1065
+ generateText,
1173
1066
  stepCountIs,
1174
- streamText as streamText2
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 = streamText2({
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 generateText2({
1413
+ const result = await generateText({
1521
1414
  model,
1522
1415
  ...callExtras(opts),
1523
1416
  messages: opts.caching ? withRollingBreakpoint(messages, opts.caching) : messages,
@@ -1608,89 +1501,6 @@ var mergeProviderOptions = (...maps) => {
1608
1501
  return out;
1609
1502
  };
1610
1503
 
1611
- // src/images.ts
1612
- var DATA_URL_RE = /^data:([^;,]+)?;base64,(.*)$/s;
1613
- var HTTP_RE = /^https?:\/\//i;
1614
- var mediaTypeOf = (f) => {
1615
- if (f.mediaType) return f.mediaType;
1616
- if (typeof f.data === "string") {
1617
- const m = DATA_URL_RE.exec(f.data);
1618
- if (m?.[1]) return m[1];
1619
- }
1620
- const url = f.data instanceof URL ? f.data.href : typeof f.data === "string" ? f.data : "";
1621
- if (HTTP_RE.test(url) || f.name) {
1622
- const ext = (f.name ?? new URL(url, "http://x").pathname).split(".").pop()?.toLowerCase();
1623
- if (ext === "pdf") return "application/pdf";
1624
- if (ext && ["png", "jpg", "jpeg", "gif", "webp"].includes(ext)) {
1625
- return `image/${ext === "jpg" ? "jpeg" : ext}`;
1626
- }
1627
- }
1628
- return void 0;
1629
- };
1630
- var attachmentKind = (f) => {
1631
- const mt = mediaTypeOf(f) ?? "";
1632
- if (mt.startsWith("image/")) return "image";
1633
- if (mt === "application/pdf") return "pdf";
1634
- return "file";
1635
- };
1636
- var KIND_LABEL = {
1637
- image: "images",
1638
- pdf: "PDF files",
1639
- file: "file attachments"
1640
- };
1641
- var KIND_HINT = {
1642
- image: "Remove the image, or switch to a vision-capable model such as Gemini, Claude or GPT-4o/GPT-5.",
1643
- 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.",
1644
- file: "Paste its text instead, or switch to a model that accepts this file type."
1645
- };
1646
- var AttachmentsNotSupportedError = class extends Error {
1647
- kind;
1648
- constructor(model, kind, detail) {
1649
- super(
1650
- `The model "${model}" can't take ${KIND_LABEL[kind]}${detail ? ` (${detail})` : ""}. ${KIND_HINT[kind]}`
1651
- );
1652
- this.name = "AttachmentsNotSupportedError";
1653
- this.kind = kind;
1654
- }
1655
- toJSON() {
1656
- return this.message;
1657
- }
1658
- };
1659
- var ImagesNotSupportedError = class extends AttachmentsNotSupportedError {
1660
- constructor(model, detail) {
1661
- super(model, "image", detail);
1662
- this.name = "ImagesNotSupportedError";
1663
- }
1664
- };
1665
- var unsupportedAttachment = (model, kind, detail) => kind === "image" ? new ImagesNotSupportedError(model, detail) : new AttachmentsNotSupportedError(model, kind, detail);
1666
- var dataOf = (f) => {
1667
- if (typeof f.data === "string") {
1668
- const m = DATA_URL_RE.exec(f.data);
1669
- if (m) return m[2];
1670
- if (HTTP_RE.test(f.data)) return new URL(f.data);
1671
- }
1672
- return f.data;
1673
- };
1674
- var toFilePart = (f) => {
1675
- const kind = attachmentKind(f);
1676
- const mediaType = mediaTypeOf(f) ?? (kind === "image" ? "image" : "application/octet-stream");
1677
- return {
1678
- type: "file",
1679
- data: dataOf(f),
1680
- mediaType,
1681
- ...f.name ? { filename: f.name } : {}
1682
- };
1683
- };
1684
- var toImagePart = toFilePart;
1685
- var modelLabel = (model) => {
1686
- if (typeof model === "string") return model;
1687
- const m = model;
1688
- return m?.modelId ? `${m.modelId}${m.provider ? ` (${m.provider})` : ""}` : "this model";
1689
- };
1690
- 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;
1691
- var isAttachmentRefusal = (err) => REFUSAL_RE.test(err instanceof Error ? `${err.name} ${err.message}` : String(err));
1692
- var isImageRefusal = isAttachmentRefusal;
1693
-
1694
1504
  // src/agent/internal.ts
1695
1505
  var promptFor = (ctx, prompt) => ctx.images?.length ? {
1696
1506
  messages: [
@@ -1814,7 +1624,7 @@ var executeStep = async (ctx, goal, step, index, total, done) => {
1814
1624
  }
1815
1625
  }
1816
1626
  }).catch((err) => {
1817
- throw imageRefusal(ctx, err, ctx.executorModel) ?? err;
1627
+ throw imageRefusal(ctx, err, ctx.executorModel) ?? contextOverflowOf(err, ctx.executorModel) ?? err;
1818
1628
  });
1819
1629
  ctx.log.debug("executor text:", loop.text);
1820
1630
  const { summary, blocked } = splitBlocker(loop.text);
@@ -1938,12 +1748,14 @@ ${nudge}` : goal;
1938
1748
  if (ctx.signal?.aborted) throw err;
1939
1749
  const refused = imageRefusal(ctx, err, ctx.plannerModel);
1940
1750
  if (refused) throw refused;
1751
+ const overflow = contextOverflowOf(err, ctx.plannerModel);
1752
+ if (overflow) throw overflow;
1941
1753
  ctx.log.warn("planner: native structured output failed, salvaging:", asMessage(err));
1942
1754
  ctx.emit({ type: "retry", phase: "plan", attempt: 1, error: asMessage(err) });
1943
1755
  }
1944
1756
  }
1945
1757
  const result = await generate(ctx.plannerModel, commonFor("prompted")).catch((err) => {
1946
- throw imageRefusal(ctx, err, ctx.plannerModel) ?? err;
1758
+ throw imageRefusal(ctx, err, ctx.plannerModel) ?? contextOverflowOf(err, ctx.plannerModel) ?? err;
1947
1759
  });
1948
1760
  const parsed = parsePlannerResponse(result.text);
1949
1761
  ctx.log.debug("planner (prompted) raw:", result.text);
@@ -2038,7 +1850,7 @@ var synthesizeAnswer = async (ctx, goal, done, findings = []) => {
2038
1850
  }
2039
1851
  if (part.type === "error") {
2040
1852
  const err = part.error instanceof Error ? part.error : new Error(String(part.error));
2041
- throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? err;
1853
+ throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? contextOverflowOf(err, ctx.synthesizerModel) ?? err;
2042
1854
  }
2043
1855
  if (part.type !== "text-delta") continue;
2044
1856
  const delta = part.text;
@@ -2096,10 +1908,11 @@ var CLOUD = /* @__PURE__ */ new Set([
2096
1908
  ]);
2097
1909
  var supportsNativeTools = (p) => CLOUD.has(p);
2098
1910
  var supportsStructuredOutput = (p) => CLOUD.has(p);
2099
- var directBrowserOk = (p) => p === "google" || p === "gateway" || p === "openai-compatible" || p === "anthropic";
1911
+ var directBrowserOk = (p) => p !== "web-llm";
2100
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;
2101
1914
  var TEXT_ONLY_MODEL_RE = /gpt-3\.5|o1-mini|o3-mini|deepseek|text-(davinci|embedding)|embedding|babbage|davinci|codestral/i;
2102
- 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;
2103
1916
  var PDF_PROVIDER_RE = /^(google|anthropic|openai|azure|vertex|bedrock|gemini)/i;
2104
1917
  var supportsImages = (model) => {
2105
1918
  if (typeof model === "string") {
@@ -2110,14 +1923,16 @@ var supportsImages = (model) => {
2110
1923
  if (!model || typeof model !== "object") return void 0;
2111
1924
  const provider = String(model.provider ?? "");
2112
1925
  const id = String(model.modelId ?? "");
2113
- if (LOCAL_RE2.test(provider)) return false;
2114
- if (/deepseek/i.test(provider) || TEXT_ONLY_MODEL_RE.test(id)) return false;
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;
2115
1929
  return VISION_PROVIDER_RE.test(provider) ? true : void 0;
2116
1930
  };
2117
1931
  var supportsPdf = (model) => {
2118
1932
  const vision = supportsImages(model);
2119
1933
  if (vision === false) return false;
2120
1934
  const provider = typeof model === "string" ? model.split("/")[0] ?? "" : String(model?.provider ?? "");
1935
+ if (LOCAL_RE2.test(provider) || /moonshot/i.test(provider)) return false;
2121
1936
  return PDF_PROVIDER_RE.test(provider) ? true : void 0;
2122
1937
  };
2123
1938
 
@@ -2154,6 +1969,10 @@ var createAgent = async (config) => {
2154
1969
  ]);
2155
1970
  const plannerMode = selectToolMode(plannerModel, cfg.toolMode);
2156
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;
2157
1976
  const baseTools = filterTools(
2158
1977
  config.tools ?? {},
2159
1978
  config.availableTools,
@@ -2166,7 +1985,8 @@ var createAgent = async (config) => {
2166
1985
  skillNames.add(s.name);
2167
1986
  }
2168
1987
  const catalog = toolCatalogOf(baseTools);
2169
- const strategy = cfg.toolSelectionStrategy === "auto" ? catalog.length > cfg.toolSearchThreshold ? "search" : "all" : cfg.toolSelectionStrategy;
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;
2170
1990
  const reserved = [
2171
1991
  ...skills.length ? SKILL_TOOL_NAMES : [],
2172
1992
  ...strategy === "search" ? [FIND_TOOLS_NAME] : []
@@ -2192,14 +2012,15 @@ var createAgent = async (config) => {
2192
2012
  const caching = resolveCaching(config.promptCaching);
2193
2013
  const textOnly = executorMode === "prompted";
2194
2014
  const accepts = {
2195
- image: config.inputs?.images ?? config.vision ?? (textOnly ? false : supportsImages(executorModel)),
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)),
2196
2017
  pdf: config.inputs?.pdf ?? (textOnly ? false : supportsPdf(executorModel)),
2197
2018
  file: config.inputs?.files ?? (textOnly ? false : void 0)
2198
2019
  };
2199
2020
  const approval = createApprovalState(config.toolApproval);
2200
2021
  const log = createLogger(cfg.logLevel, config.logger);
2201
2022
  log.info(
2202
- `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}`
2203
2024
  );
2204
2025
  const run = async (goal, opts = {}) => {
2205
2026
  const emit = (event) => {
@@ -2310,7 +2131,7 @@ var createAgent = async (config) => {
2310
2131
  } catch {
2311
2132
  }
2312
2133
  }
2313
- if (config.memory && config.compaction && cfg.compaction.auto && history.length > 0) {
2134
+ if (config.memory && byTokens && cfg.compaction.auto && history.length > 0) {
2314
2135
  const before = messageTokens(history);
2315
2136
  if (before > cfg.compaction.thresholdTokens) {
2316
2137
  const compacted = await compressHistory(history, synthesizerModel, {
@@ -2522,7 +2343,8 @@ var createAgent = async (config) => {
2522
2343
  }
2523
2344
  }
2524
2345
  if (isAborted()) return stop();
2525
- let summary = "Done \u2014 the changes have been applied.";
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.";
2526
2348
  if (cfg.synthesize) {
2527
2349
  try {
2528
2350
  const synth = await synthesizeAnswer(ctx, text, done, findings);
@@ -2537,12 +2359,12 @@ var createAgent = async (config) => {
2537
2359
  emit({ type: "final", text: summary });
2538
2360
  await remember({ role: "assistant", content: summary });
2539
2361
  result.final = summary;
2540
- if (config.memory && (config.compaction ? cfg.compaction.auto : cfg.compressAfterChars > 0)) {
2362
+ if (config.memory && (byTokens ? cfg.compaction.auto : cfg.compressAfterChars > 0)) {
2541
2363
  try {
2542
2364
  const transcript = await config.memory.load(sessionId);
2543
2365
  const before = messageTokens(transcript);
2544
2366
  const compacted = await compressHistory(transcript, synthesizerModel, {
2545
- ...config.compaction ? {
2367
+ ...byTokens ? {
2546
2368
  thresholdTokens: cfg.compaction.thresholdTokens,
2547
2369
  keepRecent: cfg.compaction.keepRecentTurns,
2548
2370
  summaryMaxTokens: cfg.budgets.compaction
@@ -2614,6 +2436,7 @@ var createAgent = async (config) => {
2614
2436
  },
2615
2437
  listTools: () => catalog.map((e) => ({ ...e })),
2616
2438
  toolStrategy: strategy,
2439
+ contextWindowTokens: cfg.compaction.contextWindowTokens,
2617
2440
  skills: skills.map((s) => ({ name: s.name, description: s.description })),
2618
2441
  capabilities: { images: accepts.image, pdf: accepts.pdf, files: accepts.file },
2619
2442
  models: { planner: plannerModel, executor: executorModel, synthesizer: synthesizerModel }
@@ -3273,6 +3096,7 @@ var IndexedDBStore = class {
3273
3096
  };
3274
3097
  export {
3275
3098
  AttachmentsNotSupportedError,
3099
+ ContextWindowExceededError,
3276
3100
  FILES_STORE,
3277
3101
  FIND_TOOLS_NAME,
3278
3102
  ImagesNotSupportedError,
@@ -3288,10 +3112,12 @@ export {
3288
3112
  SESSIONS_STORE,
3289
3113
  SKILL_TOOL_NAMES,
3290
3114
  TOOL_APPROVAL_MODES,
3115
+ TOOL_SEARCH_WINDOW_SHARE,
3291
3116
  ToolBudgetError,
3292
3117
  ToolDeniedError,
3293
3118
  VaultCredentialStore,
3294
3119
  VirtualFileSystem,
3120
+ WEBLLM_DEFAULT_CONTEXT_WINDOW,
3295
3121
  attachmentKind,
3296
3122
  buildModelFromStage,
3297
3123
  bytesToBase64,
@@ -3299,6 +3125,8 @@ export {
3299
3125
  compactHistory,
3300
3126
  compactSteps,
3301
3127
  compressHistory,
3128
+ contextOverflowOf,
3129
+ contextWindowOf,
3302
3130
  createAgent,
3303
3131
  createFileTools,
3304
3132
  createFindToolsTool,
@@ -3320,6 +3148,7 @@ export {
3320
3148
  messageTokens as estimateMessagesTokens,
3321
3149
  estimateTokens,
3322
3150
  executeStep,
3151
+ fitCompactionToWindow,
3323
3152
  generate,
3324
3153
  generateStructured,
3325
3154
  getOrCreateVaultKey,
@@ -3378,9 +3207,12 @@ export {
3378
3207
  toImagePart,
3379
3208
  tokenize,
3380
3209
  toolCatalogOf,
3210
+ toolDefinitionTokens,
3381
3211
  toolRunContextOf,
3382
3212
  unloadWebLLMModel,
3213
+ webLLMContextWindow,
3383
3214
  withRollingBreakpoint,
3384
- withSystem
3215
+ withSystem,
3216
+ withWebLLMContextWindow
3385
3217
  };
3386
3218
  //# sourceMappingURL=index.js.map