@agent-native/core 0.53.0 → 0.54.1

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.
Files changed (106) hide show
  1. package/dist/action.d.ts +40 -1
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +69 -2
  4. package/dist/action.js.map +1 -1
  5. package/dist/agent/index.d.ts +1 -0
  6. package/dist/agent/index.d.ts.map +1 -1
  7. package/dist/agent/index.js +1 -0
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/agent/observational-memory/index.d.ts +6 -6
  10. package/dist/agent/observational-memory/index.js +6 -6
  11. package/dist/agent/observational-memory/index.js.map +1 -1
  12. package/dist/agent/observational-memory/read.d.ts +7 -9
  13. package/dist/agent/observational-memory/read.d.ts.map +1 -1
  14. package/dist/agent/observational-memory/read.js +7 -9
  15. package/dist/agent/observational-memory/read.js.map +1 -1
  16. package/dist/agent/processors.d.ts +146 -0
  17. package/dist/agent/processors.d.ts.map +1 -0
  18. package/dist/agent/processors.js +122 -0
  19. package/dist/agent/processors.js.map +1 -0
  20. package/dist/agent/production-agent.d.ts +10 -0
  21. package/dist/agent/production-agent.d.ts.map +1 -1
  22. package/dist/agent/production-agent.js +101 -0
  23. package/dist/agent/production-agent.js.map +1 -1
  24. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  25. package/dist/agent/run-loop-with-resume.js +4 -5
  26. package/dist/agent/run-loop-with-resume.js.map +1 -1
  27. package/dist/agent/tool-call-journal.d.ts +6 -8
  28. package/dist/agent/tool-call-journal.d.ts.map +1 -1
  29. package/dist/agent/tool-call-journal.js +6 -8
  30. package/dist/agent/tool-call-journal.js.map +1 -1
  31. package/dist/agent/types.d.ts +11 -0
  32. package/dist/agent/types.d.ts.map +1 -1
  33. package/dist/agent/types.js.map +1 -1
  34. package/dist/cli/gateway-helpers.d.ts +15 -0
  35. package/dist/cli/gateway-helpers.d.ts.map +1 -0
  36. package/dist/cli/gateway-helpers.js +51 -0
  37. package/dist/cli/gateway-helpers.js.map +1 -0
  38. package/dist/cli/plan-local.d.ts.map +1 -1
  39. package/dist/cli/plan-local.js +129 -4
  40. package/dist/cli/plan-local.js.map +1 -1
  41. package/dist/cli/skills.d.ts.map +1 -1
  42. package/dist/cli/skills.js +38 -3
  43. package/dist/cli/skills.js.map +1 -1
  44. package/dist/cli/workspace-dev.d.ts.map +1 -1
  45. package/dist/cli/workspace-dev.js +9 -27
  46. package/dist/cli/workspace-dev.js.map +1 -1
  47. package/dist/coding-tools/run-code.d.ts.map +1 -1
  48. package/dist/coding-tools/run-code.js +18 -2
  49. package/dist/coding-tools/run-code.js.map +1 -1
  50. package/dist/extensions/fetch-tool.d.ts.map +1 -1
  51. package/dist/extensions/fetch-tool.js +80 -15
  52. package/dist/extensions/fetch-tool.js.map +1 -1
  53. package/dist/extensions/web-content.d.ts +61 -0
  54. package/dist/extensions/web-content.d.ts.map +1 -0
  55. package/dist/extensions/web-content.js +468 -0
  56. package/dist/extensions/web-content.js.map +1 -0
  57. package/dist/extensions/web-search-tool.js +3 -3
  58. package/dist/extensions/web-search-tool.js.map +1 -1
  59. package/dist/mcp/build-server.d.ts.map +1 -1
  60. package/dist/mcp/build-server.js +4 -1
  61. package/dist/mcp/build-server.js.map +1 -1
  62. package/dist/provider-api/corpus-jobs.d.ts +80 -0
  63. package/dist/provider-api/corpus-jobs.d.ts.map +1 -1
  64. package/dist/provider-api/corpus-jobs.js +219 -22
  65. package/dist/provider-api/corpus-jobs.js.map +1 -1
  66. package/dist/provider-api/index.d.ts +24 -32
  67. package/dist/provider-api/index.d.ts.map +1 -1
  68. package/dist/provider-api/index.js +28 -1
  69. package/dist/provider-api/index.js.map +1 -1
  70. package/dist/server/agent-chat-plugin.js +1 -1
  71. package/dist/server/agent-chat-plugin.js.map +1 -1
  72. package/dist/server/better-auth-instance.d.ts +7 -0
  73. package/dist/server/better-auth-instance.d.ts.map +1 -1
  74. package/dist/server/better-auth-instance.js +90 -0
  75. package/dist/server/better-auth-instance.js.map +1 -1
  76. package/dist/server/deep-link.d.ts +7 -0
  77. package/dist/server/deep-link.d.ts.map +1 -1
  78. package/dist/server/deep-link.js +13 -2
  79. package/dist/server/deep-link.js.map +1 -1
  80. package/dist/server/index.d.ts +1 -1
  81. package/dist/server/index.d.ts.map +1 -1
  82. package/dist/server/index.js +1 -1
  83. package/dist/server/index.js.map +1 -1
  84. package/dist/templates/default/.agents/skills/actions/SKILL.md +52 -1
  85. package/dist/templates/default/.agents/skills/security/SKILL.md +22 -0
  86. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +52 -1
  87. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +6 -4
  88. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +11 -0
  89. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +22 -0
  90. package/docs/content/actions.md +50 -0
  91. package/docs/content/durable-resume.md +49 -0
  92. package/docs/content/external-agents.md +2 -2
  93. package/docs/content/human-approval.md +101 -0
  94. package/docs/content/observability.md +21 -0
  95. package/docs/content/observational-memory.md +63 -0
  96. package/docs/content/plan-plugin.md +5 -0
  97. package/docs/content/pr-visual-recap.md +4 -3
  98. package/docs/content/processors.md +99 -0
  99. package/docs/content/template-plan.md +78 -14
  100. package/package.json +6 -1
  101. package/src/templates/default/.agents/skills/actions/SKILL.md +52 -1
  102. package/src/templates/default/.agents/skills/security/SKILL.md +22 -0
  103. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +52 -1
  104. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +6 -4
  105. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +11 -0
  106. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +22 -0
@@ -0,0 +1,61 @@
1
+ export type WebResponseMode = "auto" | "raw" | "text" | "markdown" | "links" | "metadata" | "matches";
2
+ export type WebExtractMode = "readability" | "all-visible" | "none";
3
+ export type WebSearchSource = "extracted" | "raw";
4
+ export interface WebContentSearchOptions {
5
+ query?: string | string[];
6
+ queries?: string[];
7
+ terms?: string[];
8
+ regex?: string;
9
+ regexFlags?: string;
10
+ caseSensitive?: boolean;
11
+ source?: WebSearchSource;
12
+ maxMatches?: number;
13
+ contextChars?: number;
14
+ }
15
+ export interface WebContentProcessOptions {
16
+ url: string;
17
+ body: string;
18
+ contentType?: string | null;
19
+ responseMode?: string;
20
+ extract?: string;
21
+ includeLinks?: boolean;
22
+ search?: WebContentSearchOptions | null;
23
+ maxChars?: number;
24
+ }
25
+ export interface WebContentLink {
26
+ text: string;
27
+ url: string;
28
+ }
29
+ export interface WebContentMatch {
30
+ kind: "query" | "term" | "regex";
31
+ query: string;
32
+ match: string;
33
+ index: number;
34
+ snippet: string;
35
+ }
36
+ export interface WebContentResult {
37
+ mode: Exclude<WebResponseMode, "auto">;
38
+ extract: WebExtractMode;
39
+ contentType: string | null;
40
+ title?: string;
41
+ excerpt?: string;
42
+ byline?: string;
43
+ siteName?: string;
44
+ lang?: string;
45
+ publishedTime?: string;
46
+ content?: string;
47
+ links?: WebContentLink[];
48
+ matches?: WebContentMatch[];
49
+ totalMatches?: number;
50
+ omittedMatches?: number;
51
+ searchSource?: WebSearchSource;
52
+ truncated?: boolean;
53
+ searchTruncated?: boolean;
54
+ }
55
+ export declare function hasWebContentSearch(search: WebContentSearchOptions | null | undefined): boolean;
56
+ export declare function normalizeWebResponseMode(value: unknown, fallback?: WebResponseMode): WebResponseMode;
57
+ export declare function normalizeWebExtractMode(value: unknown, fallback?: WebExtractMode): WebExtractMode;
58
+ export declare function parseWebContentSearchOptions(value: unknown): WebContentSearchOptions | null;
59
+ export declare function processWebContent(options: WebContentProcessOptions): WebContentResult;
60
+ export declare function formatWebContentResult(result: WebContentResult): string;
61
+ //# sourceMappingURL=web-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-content.d.ts","sourceRoot":"","sources":["../../src/extensions/web-content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,468 @@
1
+ import { Readability } from "@mozilla/readability";
2
+ import { parseHTML } from "linkedom/worker";
3
+ import safeRegex from "safe-regex2";
4
+ import TurndownService from "turndown";
5
+ const DEFAULT_MAX_CONTENT_CHARS = 32_000;
6
+ const MAX_SEARCH_SOURCE_CHARS = 500_000;
7
+ const DEFAULT_MAX_MATCHES = 50;
8
+ const MAX_MATCHES = 500;
9
+ const DEFAULT_CONTEXT_CHARS = 160;
10
+ const MAX_CONTEXT_CHARS = 1_000;
11
+ const turndown = new TurndownService({
12
+ headingStyle: "atx",
13
+ bulletListMarker: "-",
14
+ codeBlockStyle: "fenced",
15
+ linkStyle: "inlined",
16
+ });
17
+ turndown.remove(["script", "style", "noscript"]);
18
+ export function hasWebContentSearch(search) {
19
+ if (!search)
20
+ return false;
21
+ return Boolean(normalizeSearchList(search.query).length ||
22
+ normalizeSearchList(search.queries).length ||
23
+ normalizeSearchList(search.terms).length ||
24
+ String(search.regex ?? "").trim());
25
+ }
26
+ export function normalizeWebResponseMode(value, fallback = "auto") {
27
+ const normalized = String(value || fallback).toLowerCase();
28
+ if (normalized === "auto" ||
29
+ normalized === "raw" ||
30
+ normalized === "text" ||
31
+ normalized === "markdown" ||
32
+ normalized === "links" ||
33
+ normalized === "metadata" ||
34
+ normalized === "matches") {
35
+ return normalized;
36
+ }
37
+ throw new Error(`Invalid responseMode "${String(value)}". Expected auto, raw, text, markdown, links, metadata, or matches.`);
38
+ }
39
+ export function normalizeWebExtractMode(value, fallback = "readability") {
40
+ const normalized = String(value || fallback).toLowerCase();
41
+ if (normalized === "readability" ||
42
+ normalized === "all-visible" ||
43
+ normalized === "none") {
44
+ return normalized;
45
+ }
46
+ throw new Error(`Invalid extract "${String(value)}". Expected readability, all-visible, or none.`);
47
+ }
48
+ export function parseWebContentSearchOptions(value) {
49
+ if (!value)
50
+ return null;
51
+ if (typeof value === "object" && !Array.isArray(value)) {
52
+ return value;
53
+ }
54
+ if (typeof value !== "string")
55
+ return null;
56
+ const trimmed = value.trim();
57
+ if (!trimmed)
58
+ return null;
59
+ try {
60
+ const parsed = JSON.parse(trimmed);
61
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
62
+ return parsed;
63
+ }
64
+ }
65
+ catch {
66
+ return { query: trimmed };
67
+ }
68
+ return null;
69
+ }
70
+ export function processWebContent(options) {
71
+ const contentType = options.contentType?.split(";")[0]?.trim() || null;
72
+ const extract = normalizeWebExtractMode(options.extract);
73
+ const requestedMode = normalizeWebResponseMode(options.responseMode);
74
+ const search = options.search ?? null;
75
+ const html = isHtmlResponse(contentType, options.body);
76
+ const mode = resolveMode(requestedMode, html, search);
77
+ const maxChars = normalizeBoundedNumber(options.maxChars, DEFAULT_MAX_CONTENT_CHARS, 1, 200_000);
78
+ const extracted = html && (mode !== "raw" || hasWebContentSearch(search))
79
+ ? extractHtml(options.body, options.url, extract)
80
+ : null;
81
+ const baseContent = contentForMode(mode, options.body, extracted);
82
+ const result = {
83
+ mode,
84
+ extract,
85
+ contentType,
86
+ ...metadataFromExtraction(extracted),
87
+ };
88
+ if (mode === "links") {
89
+ result.links = extracted?.links ?? [];
90
+ return result;
91
+ }
92
+ if (mode === "metadata") {
93
+ if (options.includeLinks)
94
+ result.links = extracted?.links ?? [];
95
+ return result;
96
+ }
97
+ if (mode === "matches") {
98
+ const matchResult = findWebContentMatches({
99
+ raw: options.body,
100
+ extracted: baseContent,
101
+ search,
102
+ fallbackSearchSource: html ? "extracted" : "raw",
103
+ });
104
+ Object.assign(result, matchResult);
105
+ if (options.includeLinks)
106
+ result.links = extracted?.links ?? [];
107
+ return result;
108
+ }
109
+ const truncated = baseContent.length > maxChars;
110
+ result.content = truncated
111
+ ? `${baseContent.slice(0, maxChars)}\n... (truncated)`
112
+ : baseContent;
113
+ result.truncated = truncated;
114
+ if (options.includeLinks)
115
+ result.links = extracted?.links ?? [];
116
+ if (hasWebContentSearch(search)) {
117
+ const matchResult = findWebContentMatches({
118
+ raw: options.body,
119
+ extracted: baseContent,
120
+ search,
121
+ fallbackSearchSource: html ? "extracted" : "raw",
122
+ });
123
+ result.matches = matchResult.matches;
124
+ result.totalMatches = matchResult.totalMatches;
125
+ result.omittedMatches = matchResult.omittedMatches;
126
+ result.searchSource = matchResult.searchSource;
127
+ result.searchTruncated = matchResult.searchTruncated;
128
+ }
129
+ return result;
130
+ }
131
+ export function formatWebContentResult(result) {
132
+ if (result.mode === "raw")
133
+ return result.content ?? "";
134
+ const lines = [];
135
+ if (result.title)
136
+ lines.push(`# ${result.title}`, "");
137
+ if (result.siteName)
138
+ lines.push(`Site: ${result.siteName}`);
139
+ if (result.publishedTime)
140
+ lines.push(`Published: ${result.publishedTime}`);
141
+ if (result.excerpt && result.mode !== "metadata") {
142
+ lines.push(`Excerpt: ${result.excerpt}`);
143
+ }
144
+ if (lines.length && lines[lines.length - 1] !== "")
145
+ lines.push("");
146
+ if (result.mode === "matches") {
147
+ lines.push(formatMatches(result));
148
+ }
149
+ else if (result.mode === "links") {
150
+ lines.push(formatLinks(result.links ?? []));
151
+ }
152
+ else if (result.mode === "metadata") {
153
+ lines.push(formatMetadata(result));
154
+ }
155
+ else if (result.content) {
156
+ lines.push(result.content);
157
+ }
158
+ if (result.mode !== "links" &&
159
+ result.mode !== "matches" &&
160
+ result.links?.length) {
161
+ lines.push("", "Links:", formatLinks(result.links));
162
+ }
163
+ if (result.matches?.length && result.mode !== "matches") {
164
+ lines.push("", formatMatches(result));
165
+ }
166
+ return lines.join("\n").trim();
167
+ }
168
+ function resolveMode(requestedMode, html, search) {
169
+ if (requestedMode === "auto") {
170
+ if (hasWebContentSearch(search))
171
+ return "matches";
172
+ return html ? "markdown" : "raw";
173
+ }
174
+ return requestedMode;
175
+ }
176
+ function isHtmlResponse(contentType, body) {
177
+ if (contentType) {
178
+ return (contentType === "text/html" ||
179
+ contentType === "application/xhtml+xml" ||
180
+ contentType.endsWith("+html"));
181
+ }
182
+ return /<!doctype html|<html[\s>]|<body[\s>]|<article[\s>]/i.test(body.slice(0, 2_000));
183
+ }
184
+ function extractHtml(body, url, extract) {
185
+ const document = parseFullDocument(body);
186
+ removeNonContentNodes(document);
187
+ const pageTitle = textOrUndefined(document.title);
188
+ const article = extract === "readability"
189
+ ? new Readability(document.cloneNode(true)).parse()
190
+ : null;
191
+ const sourceHtml = extract === "none"
192
+ ? body
193
+ : article?.content ||
194
+ document.body?.innerHTML ||
195
+ document.documentElement.innerHTML ||
196
+ body;
197
+ const absoluteHtml = absolutizeHtmlUrls(sourceHtml, url);
198
+ const sourceText = extract === "none"
199
+ ? htmlToPlainText(body)
200
+ : article?.textContent ||
201
+ document.body?.textContent ||
202
+ document.documentElement.textContent ||
203
+ "";
204
+ const markdown = htmlToMarkdown(absoluteHtml);
205
+ return {
206
+ html: absoluteHtml,
207
+ text: normalizeWhitespace(sourceText),
208
+ markdown,
209
+ links: collectLinks(absoluteHtml, url),
210
+ title: textOrUndefined(article?.title) ?? pageTitle,
211
+ excerpt: textOrUndefined(article?.excerpt),
212
+ byline: textOrUndefined(article?.byline),
213
+ siteName: textOrUndefined(article?.siteName),
214
+ lang: textOrUndefined(article?.lang),
215
+ publishedTime: textOrUndefined(article?.publishedTime),
216
+ };
217
+ }
218
+ function htmlToPlainText(html) {
219
+ const document = parseFullDocument(html);
220
+ removeNonContentNodes(document);
221
+ return normalizeWhitespace(document.body?.textContent ?? "");
222
+ }
223
+ function htmlToMarkdown(html) {
224
+ return normalizeMarkdown(turndown.turndown(html));
225
+ }
226
+ function removeNonContentNodes(document) {
227
+ for (const selector of [
228
+ "script",
229
+ "style",
230
+ "noscript",
231
+ "svg",
232
+ "template",
233
+ "iframe",
234
+ ]) {
235
+ for (const node of [...document.querySelectorAll(selector)]) {
236
+ node.remove();
237
+ }
238
+ }
239
+ }
240
+ function parseFullDocument(html) {
241
+ return parseHTML(html).document;
242
+ }
243
+ function parseHtmlFragment(html) {
244
+ return parseHTML(`<!doctype html><html><head></head><body>${html}</body></html>`).document;
245
+ }
246
+ function absolutizeHtmlUrls(html, url) {
247
+ const document = parseHtmlFragment(html);
248
+ for (const anchor of [...document.querySelectorAll("a[href]")]) {
249
+ const href = anchor.getAttribute("href");
250
+ if (!href)
251
+ continue;
252
+ try {
253
+ anchor.setAttribute("href", new URL(href, url).href);
254
+ }
255
+ catch { }
256
+ }
257
+ for (const image of [...document.querySelectorAll("img[src]")]) {
258
+ const src = image.getAttribute("src");
259
+ if (!src)
260
+ continue;
261
+ try {
262
+ image.setAttribute("src", new URL(src, url).href);
263
+ }
264
+ catch { }
265
+ }
266
+ return document.body?.innerHTML || html;
267
+ }
268
+ function collectLinks(html, url) {
269
+ const document = parseHtmlFragment(html);
270
+ const links = [];
271
+ const seen = new Set();
272
+ for (const anchor of [...document.querySelectorAll("a[href]")]) {
273
+ const href = anchor.getAttribute("href");
274
+ if (!href)
275
+ continue;
276
+ let absolute;
277
+ try {
278
+ absolute = new URL(href, url).href;
279
+ }
280
+ catch {
281
+ continue;
282
+ }
283
+ if (seen.has(absolute))
284
+ continue;
285
+ seen.add(absolute);
286
+ links.push({
287
+ text: normalizeWhitespace(anchor.textContent || absolute).slice(0, 200),
288
+ url: absolute,
289
+ });
290
+ if (links.length >= 200)
291
+ break;
292
+ }
293
+ return links;
294
+ }
295
+ function contentForMode(mode, raw, extracted) {
296
+ if (mode === "raw")
297
+ return raw;
298
+ if (mode === "text")
299
+ return extracted?.text ?? raw;
300
+ if (mode === "markdown" || mode === "matches") {
301
+ return extracted?.markdown || extracted?.text || raw;
302
+ }
303
+ return "";
304
+ }
305
+ function metadataFromExtraction(extracted) {
306
+ if (!extracted)
307
+ return {};
308
+ return {
309
+ ...(extracted.title ? { title: extracted.title } : {}),
310
+ ...(extracted.excerpt ? { excerpt: extracted.excerpt } : {}),
311
+ ...(extracted.byline ? { byline: extracted.byline } : {}),
312
+ ...(extracted.siteName ? { siteName: extracted.siteName } : {}),
313
+ ...(extracted.lang ? { lang: extracted.lang } : {}),
314
+ ...(extracted.publishedTime
315
+ ? { publishedTime: extracted.publishedTime }
316
+ : {}),
317
+ };
318
+ }
319
+ function findWebContentMatches(options) {
320
+ const search = options.search ?? {};
321
+ const sourceMode = search.source ?? options.fallbackSearchSource;
322
+ const source = sourceMode === "raw" ? options.raw : options.extracted;
323
+ const searchTruncated = source.length > MAX_SEARCH_SOURCE_CHARS;
324
+ const searchable = searchTruncated
325
+ ? source.slice(0, MAX_SEARCH_SOURCE_CHARS)
326
+ : source;
327
+ const maxMatches = normalizeBoundedNumber(search.maxMatches, DEFAULT_MAX_MATCHES, 1, MAX_MATCHES);
328
+ const contextChars = normalizeBoundedNumber(search.contextChars, DEFAULT_CONTEXT_CHARS, 0, MAX_CONTEXT_CHARS);
329
+ const matches = [];
330
+ let totalMatches = 0;
331
+ const caseSensitive = Boolean(search.caseSensitive);
332
+ const addMatch = (match) => {
333
+ totalMatches += 1;
334
+ if (matches.length >= maxMatches)
335
+ return;
336
+ matches.push({
337
+ ...match,
338
+ snippet: makeSnippet(searchable, match.index, contextChars),
339
+ });
340
+ };
341
+ for (const query of [
342
+ ...normalizeSearchList(search.query),
343
+ ...normalizeSearchList(search.queries),
344
+ ]) {
345
+ findLiteralMatches(searchable, query, caseSensitive, (index, match) => addMatch({ kind: "query", query, match, index }));
346
+ }
347
+ for (const term of normalizeSearchList(search.terms)) {
348
+ findLiteralMatches(searchable, term, caseSensitive, (index, match) => addMatch({ kind: "term", query: term, match, index }));
349
+ }
350
+ const regexPattern = String(search.regex ?? "").trim();
351
+ if (regexPattern) {
352
+ if (!safeRegex(regexPattern, { limit: 25 })) {
353
+ throw new Error("Unsafe regex rejected. Use a simpler literal query/terms search or a bounded run-code workflow.");
354
+ }
355
+ const regex = new RegExp(regexPattern, normalizeRegexFlags(search.regexFlags, caseSensitive));
356
+ let match;
357
+ while ((match = regex.exec(searchable)) &&
358
+ typeof match.index === "number") {
359
+ addMatch({
360
+ kind: "regex",
361
+ query: regexPattern,
362
+ match: match[0],
363
+ index: match.index,
364
+ });
365
+ if (match[0] === "")
366
+ regex.lastIndex += 1;
367
+ if (totalMatches >= MAX_MATCHES * 10)
368
+ break;
369
+ }
370
+ }
371
+ matches.sort((a, b) => a.index - b.index);
372
+ return {
373
+ matches,
374
+ totalMatches,
375
+ omittedMatches: Math.max(0, totalMatches - matches.length),
376
+ searchSource: sourceMode,
377
+ searchTruncated,
378
+ };
379
+ }
380
+ function findLiteralMatches(source, query, caseSensitive, onMatch) {
381
+ if (!query)
382
+ return;
383
+ const haystack = caseSensitive ? source : source.toLowerCase();
384
+ const needle = caseSensitive ? query : query.toLowerCase();
385
+ let from = 0;
386
+ while (from <= haystack.length) {
387
+ const index = haystack.indexOf(needle, from);
388
+ if (index < 0)
389
+ break;
390
+ onMatch(index, source.slice(index, index + query.length));
391
+ from = index + Math.max(1, needle.length);
392
+ }
393
+ }
394
+ function normalizeRegexFlags(flags, caseSensitive) {
395
+ const allowed = new Set(["d", "g", "i", "m", "s", "u", "v", "y"]);
396
+ const result = new Set(["g"]);
397
+ if (!caseSensitive)
398
+ result.add("i");
399
+ for (const flag of String(flags ?? "")) {
400
+ if (allowed.has(flag))
401
+ result.add(flag);
402
+ }
403
+ result.delete("y");
404
+ return [...result].join("");
405
+ }
406
+ function normalizeSearchList(value) {
407
+ if (value === undefined || value === null)
408
+ return [];
409
+ const values = Array.isArray(value) ? value : [value];
410
+ return values
411
+ .map((item) => String(item).trim())
412
+ .filter((item) => item.length > 0);
413
+ }
414
+ function normalizeBoundedNumber(value, fallback, min, max) {
415
+ const numeric = Number(value);
416
+ if (!Number.isFinite(numeric))
417
+ return fallback;
418
+ return Math.max(min, Math.min(Math.floor(numeric), max));
419
+ }
420
+ function makeSnippet(source, index, contextChars) {
421
+ const start = Math.max(0, index - contextChars);
422
+ const end = Math.min(source.length, index + contextChars);
423
+ const prefix = start > 0 ? "..." : "";
424
+ const suffix = end < source.length ? "..." : "";
425
+ return `${prefix}${normalizeWhitespace(source.slice(start, end))}${suffix}`;
426
+ }
427
+ function normalizeMarkdown(value) {
428
+ return value
429
+ .replace(/\n{3,}/g, "\n\n")
430
+ .replace(/[ \t]+\n/g, "\n")
431
+ .trim();
432
+ }
433
+ function normalizeWhitespace(value) {
434
+ return value.replace(/\s+/g, " ").trim();
435
+ }
436
+ function textOrUndefined(value) {
437
+ const normalized = normalizeWhitespace(value ?? "");
438
+ return normalized || undefined;
439
+ }
440
+ function formatMatches(result) {
441
+ const matches = result.matches ?? [];
442
+ const header = `Matches: ${matches.length}${result.totalMatches !== undefined ? ` shown of ${result.totalMatches}` : ""}${result.omittedMatches ? ` (${result.omittedMatches} omitted)` : ""}`;
443
+ if (!matches.length)
444
+ return header;
445
+ return [
446
+ header,
447
+ ...matches.map((match, index) => `${index + 1}. ${match.kind} ${JSON.stringify(match.query)} at ${match.index}: ${match.snippet}`),
448
+ ].join("\n");
449
+ }
450
+ function formatLinks(links) {
451
+ if (!links.length)
452
+ return "(none)";
453
+ return links
454
+ .map((link, index) => `${index + 1}. [${link.text || link.url}](${link.url})`)
455
+ .join("\n");
456
+ }
457
+ function formatMetadata(result) {
458
+ return JSON.stringify({
459
+ title: result.title,
460
+ excerpt: result.excerpt,
461
+ byline: result.byline,
462
+ siteName: result.siteName,
463
+ lang: result.lang,
464
+ publishedTime: result.publishedTime,
465
+ contentType: result.contentType,
466
+ }, null, 2);
467
+ }
468
+ //# sourceMappingURL=web-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-content.js","sourceRoot":"","sources":["../../src/extensions/web-content.ts"],"names":[],"mappings":"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","sourcesContent":["import { Readability } from \"@mozilla/readability\";\nimport { parseHTML } from \"linkedom/worker\";\nimport safeRegex from \"safe-regex2\";\nimport TurndownService from \"turndown\";\n\nexport type WebResponseMode =\n | \"auto\"\n | \"raw\"\n | \"text\"\n | \"markdown\"\n | \"links\"\n | \"metadata\"\n | \"matches\";\n\nexport type WebExtractMode = \"readability\" | \"all-visible\" | \"none\";\nexport type WebSearchSource = \"extracted\" | \"raw\";\n\nexport interface WebContentSearchOptions {\n query?: string | string[];\n queries?: string[];\n terms?: string[];\n regex?: string;\n regexFlags?: string;\n caseSensitive?: boolean;\n source?: WebSearchSource;\n maxMatches?: number;\n contextChars?: number;\n}\n\nexport interface WebContentProcessOptions {\n url: string;\n body: string;\n contentType?: string | null;\n responseMode?: string;\n extract?: string;\n includeLinks?: boolean;\n search?: WebContentSearchOptions | null;\n maxChars?: number;\n}\n\nexport interface WebContentLink {\n text: string;\n url: string;\n}\n\nexport interface WebContentMatch {\n kind: \"query\" | \"term\" | \"regex\";\n query: string;\n match: string;\n index: number;\n snippet: string;\n}\n\nexport interface WebContentResult {\n mode: Exclude<WebResponseMode, \"auto\">;\n extract: WebExtractMode;\n contentType: string | null;\n title?: string;\n excerpt?: string;\n byline?: string;\n siteName?: string;\n lang?: string;\n publishedTime?: string;\n content?: string;\n links?: WebContentLink[];\n matches?: WebContentMatch[];\n totalMatches?: number;\n omittedMatches?: number;\n searchSource?: WebSearchSource;\n truncated?: boolean;\n searchTruncated?: boolean;\n}\n\nconst DEFAULT_MAX_CONTENT_CHARS = 32_000;\nconst MAX_SEARCH_SOURCE_CHARS = 500_000;\nconst DEFAULT_MAX_MATCHES = 50;\nconst MAX_MATCHES = 500;\nconst DEFAULT_CONTEXT_CHARS = 160;\nconst MAX_CONTEXT_CHARS = 1_000;\n\nconst turndown = new TurndownService({\n headingStyle: \"atx\",\n bulletListMarker: \"-\",\n codeBlockStyle: \"fenced\",\n linkStyle: \"inlined\",\n});\nturndown.remove([\"script\", \"style\", \"noscript\"]);\n\nexport function hasWebContentSearch(\n search: WebContentSearchOptions | null | undefined,\n): boolean {\n if (!search) return false;\n return Boolean(\n normalizeSearchList(search.query).length ||\n normalizeSearchList(search.queries).length ||\n normalizeSearchList(search.terms).length ||\n String(search.regex ?? \"\").trim(),\n );\n}\n\nexport function normalizeWebResponseMode(\n value: unknown,\n fallback: WebResponseMode = \"auto\",\n): WebResponseMode {\n const normalized = String(value || fallback).toLowerCase();\n if (\n normalized === \"auto\" ||\n normalized === \"raw\" ||\n normalized === \"text\" ||\n normalized === \"markdown\" ||\n normalized === \"links\" ||\n normalized === \"metadata\" ||\n normalized === \"matches\"\n ) {\n return normalized;\n }\n throw new Error(\n `Invalid responseMode \"${String(value)}\". Expected auto, raw, text, markdown, links, metadata, or matches.`,\n );\n}\n\nexport function normalizeWebExtractMode(\n value: unknown,\n fallback: WebExtractMode = \"readability\",\n): WebExtractMode {\n const normalized = String(value || fallback).toLowerCase();\n if (\n normalized === \"readability\" ||\n normalized === \"all-visible\" ||\n normalized === \"none\"\n ) {\n return normalized;\n }\n throw new Error(\n `Invalid extract \"${String(value)}\". Expected readability, all-visible, or none.`,\n );\n}\n\nexport function parseWebContentSearchOptions(\n value: unknown,\n): WebContentSearchOptions | null {\n if (!value) return null;\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as WebContentSearchOptions;\n }\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n if (!trimmed) return null;\n try {\n const parsed = JSON.parse(trimmed);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as WebContentSearchOptions;\n }\n } catch {\n return { query: trimmed };\n }\n return null;\n}\n\nexport function processWebContent(\n options: WebContentProcessOptions,\n): WebContentResult {\n const contentType = options.contentType?.split(\";\")[0]?.trim() || null;\n const extract = normalizeWebExtractMode(options.extract);\n const requestedMode = normalizeWebResponseMode(options.responseMode);\n const search = options.search ?? null;\n const html = isHtmlResponse(contentType, options.body);\n const mode = resolveMode(requestedMode, html, search);\n const maxChars = normalizeBoundedNumber(\n options.maxChars,\n DEFAULT_MAX_CONTENT_CHARS,\n 1,\n 200_000,\n );\n\n const extracted =\n html && (mode !== \"raw\" || hasWebContentSearch(search))\n ? extractHtml(options.body, options.url, extract)\n : null;\n const baseContent = contentForMode(mode, options.body, extracted);\n const result: WebContentResult = {\n mode,\n extract,\n contentType,\n ...metadataFromExtraction(extracted),\n };\n\n if (mode === \"links\") {\n result.links = extracted?.links ?? [];\n return result;\n }\n\n if (mode === \"metadata\") {\n if (options.includeLinks) result.links = extracted?.links ?? [];\n return result;\n }\n\n if (mode === \"matches\") {\n const matchResult = findWebContentMatches({\n raw: options.body,\n extracted: baseContent,\n search,\n fallbackSearchSource: html ? \"extracted\" : \"raw\",\n });\n Object.assign(result, matchResult);\n if (options.includeLinks) result.links = extracted?.links ?? [];\n return result;\n }\n\n const truncated = baseContent.length > maxChars;\n result.content = truncated\n ? `${baseContent.slice(0, maxChars)}\\n... (truncated)`\n : baseContent;\n result.truncated = truncated;\n if (options.includeLinks) result.links = extracted?.links ?? [];\n\n if (hasWebContentSearch(search)) {\n const matchResult = findWebContentMatches({\n raw: options.body,\n extracted: baseContent,\n search,\n fallbackSearchSource: html ? \"extracted\" : \"raw\",\n });\n result.matches = matchResult.matches;\n result.totalMatches = matchResult.totalMatches;\n result.omittedMatches = matchResult.omittedMatches;\n result.searchSource = matchResult.searchSource;\n result.searchTruncated = matchResult.searchTruncated;\n }\n\n return result;\n}\n\nexport function formatWebContentResult(result: WebContentResult): string {\n if (result.mode === \"raw\") return result.content ?? \"\";\n\n const lines: string[] = [];\n if (result.title) lines.push(`# ${result.title}`, \"\");\n if (result.siteName) lines.push(`Site: ${result.siteName}`);\n if (result.publishedTime) lines.push(`Published: ${result.publishedTime}`);\n if (result.excerpt && result.mode !== \"metadata\") {\n lines.push(`Excerpt: ${result.excerpt}`);\n }\n if (lines.length && lines[lines.length - 1] !== \"\") lines.push(\"\");\n\n if (result.mode === \"matches\") {\n lines.push(formatMatches(result));\n } else if (result.mode === \"links\") {\n lines.push(formatLinks(result.links ?? []));\n } else if (result.mode === \"metadata\") {\n lines.push(formatMetadata(result));\n } else if (result.content) {\n lines.push(result.content);\n }\n\n if (\n result.mode !== \"links\" &&\n result.mode !== \"matches\" &&\n result.links?.length\n ) {\n lines.push(\"\", \"Links:\", formatLinks(result.links));\n }\n if (result.matches?.length && result.mode !== \"matches\") {\n lines.push(\"\", formatMatches(result));\n }\n\n return lines.join(\"\\n\").trim();\n}\n\nfunction resolveMode(\n requestedMode: WebResponseMode,\n html: boolean,\n search: WebContentSearchOptions | null,\n): Exclude<WebResponseMode, \"auto\"> {\n if (requestedMode === \"auto\") {\n if (hasWebContentSearch(search)) return \"matches\";\n return html ? \"markdown\" : \"raw\";\n }\n return requestedMode;\n}\n\nfunction isHtmlResponse(contentType: string | null, body: string): boolean {\n if (contentType) {\n return (\n contentType === \"text/html\" ||\n contentType === \"application/xhtml+xml\" ||\n contentType.endsWith(\"+html\")\n );\n }\n return /<!doctype html|<html[\\s>]|<body[\\s>]|<article[\\s>]/i.test(\n body.slice(0, 2_000),\n );\n}\n\nfunction extractHtml(\n body: string,\n url: string,\n extract: WebExtractMode,\n): {\n html: string;\n text: string;\n markdown: string;\n links: WebContentLink[];\n title?: string;\n excerpt?: string;\n byline?: string;\n siteName?: string;\n lang?: string;\n publishedTime?: string;\n} {\n const document = parseFullDocument(body);\n removeNonContentNodes(document);\n const pageTitle = textOrUndefined(document.title);\n const article =\n extract === \"readability\"\n ? new Readability(document.cloneNode(true) as Document).parse()\n : null;\n const sourceHtml =\n extract === \"none\"\n ? body\n : article?.content ||\n document.body?.innerHTML ||\n document.documentElement.innerHTML ||\n body;\n const absoluteHtml = absolutizeHtmlUrls(sourceHtml, url);\n const sourceText =\n extract === \"none\"\n ? htmlToPlainText(body)\n : article?.textContent ||\n document.body?.textContent ||\n document.documentElement.textContent ||\n \"\";\n const markdown = htmlToMarkdown(absoluteHtml);\n return {\n html: absoluteHtml,\n text: normalizeWhitespace(sourceText),\n markdown,\n links: collectLinks(absoluteHtml, url),\n title: textOrUndefined(article?.title) ?? pageTitle,\n excerpt: textOrUndefined(article?.excerpt),\n byline: textOrUndefined(article?.byline),\n siteName: textOrUndefined(article?.siteName),\n lang: textOrUndefined(article?.lang),\n publishedTime: textOrUndefined(article?.publishedTime),\n };\n}\n\nfunction htmlToPlainText(html: string): string {\n const document = parseFullDocument(html);\n removeNonContentNodes(document);\n return normalizeWhitespace(document.body?.textContent ?? \"\");\n}\n\nfunction htmlToMarkdown(html: string): string {\n return normalizeMarkdown(turndown.turndown(html));\n}\n\nfunction removeNonContentNodes(document: Document) {\n for (const selector of [\n \"script\",\n \"style\",\n \"noscript\",\n \"svg\",\n \"template\",\n \"iframe\",\n ]) {\n for (const node of [...document.querySelectorAll(selector)]) {\n node.remove();\n }\n }\n}\n\nfunction parseFullDocument(html: string): Document {\n return parseHTML(html).document as unknown as Document;\n}\n\nfunction parseHtmlFragment(html: string): Document {\n return parseHTML(\n `<!doctype html><html><head></head><body>${html}</body></html>`,\n ).document as unknown as Document;\n}\n\nfunction absolutizeHtmlUrls(html: string, url: string): string {\n const document = parseHtmlFragment(html);\n for (const anchor of [...document.querySelectorAll(\"a[href]\")]) {\n const href = anchor.getAttribute(\"href\");\n if (!href) continue;\n try {\n anchor.setAttribute(\"href\", new URL(href, url).href);\n } catch {}\n }\n for (const image of [...document.querySelectorAll(\"img[src]\")]) {\n const src = image.getAttribute(\"src\");\n if (!src) continue;\n try {\n image.setAttribute(\"src\", new URL(src, url).href);\n } catch {}\n }\n return document.body?.innerHTML || html;\n}\n\nfunction collectLinks(html: string, url: string): WebContentLink[] {\n const document = parseHtmlFragment(html);\n const links: WebContentLink[] = [];\n const seen = new Set<string>();\n for (const anchor of [...document.querySelectorAll(\"a[href]\")]) {\n const href = anchor.getAttribute(\"href\");\n if (!href) continue;\n let absolute: string;\n try {\n absolute = new URL(href, url).href;\n } catch {\n continue;\n }\n if (seen.has(absolute)) continue;\n seen.add(absolute);\n links.push({\n text: normalizeWhitespace(anchor.textContent || absolute).slice(0, 200),\n url: absolute,\n });\n if (links.length >= 200) break;\n }\n return links;\n}\n\nfunction contentForMode(\n mode: Exclude<WebResponseMode, \"auto\">,\n raw: string,\n extracted: ReturnType<typeof extractHtml> | null,\n): string {\n if (mode === \"raw\") return raw;\n if (mode === \"text\") return extracted?.text ?? raw;\n if (mode === \"markdown\" || mode === \"matches\") {\n return extracted?.markdown || extracted?.text || raw;\n }\n return \"\";\n}\n\nfunction metadataFromExtraction(\n extracted: ReturnType<typeof extractHtml> | null,\n) {\n if (!extracted) return {};\n return {\n ...(extracted.title ? { title: extracted.title } : {}),\n ...(extracted.excerpt ? { excerpt: extracted.excerpt } : {}),\n ...(extracted.byline ? { byline: extracted.byline } : {}),\n ...(extracted.siteName ? { siteName: extracted.siteName } : {}),\n ...(extracted.lang ? { lang: extracted.lang } : {}),\n ...(extracted.publishedTime\n ? { publishedTime: extracted.publishedTime }\n : {}),\n };\n}\n\nfunction findWebContentMatches(options: {\n raw: string;\n extracted: string;\n search: WebContentSearchOptions | null;\n fallbackSearchSource: WebSearchSource;\n}): Pick<\n WebContentResult,\n | \"matches\"\n | \"totalMatches\"\n | \"omittedMatches\"\n | \"searchSource\"\n | \"searchTruncated\"\n> {\n const search = options.search ?? {};\n const sourceMode = search.source ?? options.fallbackSearchSource;\n const source = sourceMode === \"raw\" ? options.raw : options.extracted;\n const searchTruncated = source.length > MAX_SEARCH_SOURCE_CHARS;\n const searchable = searchTruncated\n ? source.slice(0, MAX_SEARCH_SOURCE_CHARS)\n : source;\n const maxMatches = normalizeBoundedNumber(\n search.maxMatches,\n DEFAULT_MAX_MATCHES,\n 1,\n MAX_MATCHES,\n );\n const contextChars = normalizeBoundedNumber(\n search.contextChars,\n DEFAULT_CONTEXT_CHARS,\n 0,\n MAX_CONTEXT_CHARS,\n );\n const matches: WebContentMatch[] = [];\n let totalMatches = 0;\n const caseSensitive = Boolean(search.caseSensitive);\n\n const addMatch = (match: Omit<WebContentMatch, \"snippet\">) => {\n totalMatches += 1;\n if (matches.length >= maxMatches) return;\n matches.push({\n ...match,\n snippet: makeSnippet(searchable, match.index, contextChars),\n });\n };\n\n for (const query of [\n ...normalizeSearchList(search.query),\n ...normalizeSearchList(search.queries),\n ]) {\n findLiteralMatches(searchable, query, caseSensitive, (index, match) =>\n addMatch({ kind: \"query\", query, match, index }),\n );\n }\n\n for (const term of normalizeSearchList(search.terms)) {\n findLiteralMatches(searchable, term, caseSensitive, (index, match) =>\n addMatch({ kind: \"term\", query: term, match, index }),\n );\n }\n\n const regexPattern = String(search.regex ?? \"\").trim();\n if (regexPattern) {\n if (!safeRegex(regexPattern, { limit: 25 })) {\n throw new Error(\n \"Unsafe regex rejected. Use a simpler literal query/terms search or a bounded run-code workflow.\",\n );\n }\n const regex = new RegExp(\n regexPattern,\n normalizeRegexFlags(search.regexFlags, caseSensitive),\n );\n let match: RegExpExecArray | null;\n while (\n (match = regex.exec(searchable)) &&\n typeof match.index === \"number\"\n ) {\n addMatch({\n kind: \"regex\",\n query: regexPattern,\n match: match[0],\n index: match.index,\n });\n if (match[0] === \"\") regex.lastIndex += 1;\n if (totalMatches >= MAX_MATCHES * 10) break;\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n return {\n matches,\n totalMatches,\n omittedMatches: Math.max(0, totalMatches - matches.length),\n searchSource: sourceMode,\n searchTruncated,\n };\n}\n\nfunction findLiteralMatches(\n source: string,\n query: string,\n caseSensitive: boolean,\n onMatch: (index: number, match: string) => void,\n) {\n if (!query) return;\n const haystack = caseSensitive ? source : source.toLowerCase();\n const needle = caseSensitive ? query : query.toLowerCase();\n let from = 0;\n while (from <= haystack.length) {\n const index = haystack.indexOf(needle, from);\n if (index < 0) break;\n onMatch(index, source.slice(index, index + query.length));\n from = index + Math.max(1, needle.length);\n }\n}\n\nfunction normalizeRegexFlags(\n flags: string | undefined,\n caseSensitive: boolean,\n): string {\n const allowed = new Set([\"d\", \"g\", \"i\", \"m\", \"s\", \"u\", \"v\", \"y\"]);\n const result = new Set<string>([\"g\"]);\n if (!caseSensitive) result.add(\"i\");\n for (const flag of String(flags ?? \"\")) {\n if (allowed.has(flag)) result.add(flag);\n }\n result.delete(\"y\");\n return [...result].join(\"\");\n}\n\nfunction normalizeSearchList(value: unknown): string[] {\n if (value === undefined || value === null) return [];\n const values = Array.isArray(value) ? value : [value];\n return values\n .map((item) => String(item).trim())\n .filter((item) => item.length > 0);\n}\n\nfunction normalizeBoundedNumber(\n value: unknown,\n fallback: number,\n min: number,\n max: number,\n): number {\n const numeric = Number(value);\n if (!Number.isFinite(numeric)) return fallback;\n return Math.max(min, Math.min(Math.floor(numeric), max));\n}\n\nfunction makeSnippet(source: string, index: number, contextChars: number) {\n const start = Math.max(0, index - contextChars);\n const end = Math.min(source.length, index + contextChars);\n const prefix = start > 0 ? \"...\" : \"\";\n const suffix = end < source.length ? \"...\" : \"\";\n return `${prefix}${normalizeWhitespace(source.slice(start, end))}${suffix}`;\n}\n\nfunction normalizeMarkdown(value: string): string {\n return value\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .trim();\n}\n\nfunction normalizeWhitespace(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nfunction textOrUndefined(value: string | null | undefined): string | undefined {\n const normalized = normalizeWhitespace(value ?? \"\");\n return normalized || undefined;\n}\n\nfunction formatMatches(result: WebContentResult): string {\n const matches = result.matches ?? [];\n const header = `Matches: ${matches.length}${result.totalMatches !== undefined ? ` shown of ${result.totalMatches}` : \"\"}${result.omittedMatches ? ` (${result.omittedMatches} omitted)` : \"\"}`;\n if (!matches.length) return header;\n return [\n header,\n ...matches.map(\n (match, index) =>\n `${index + 1}. ${match.kind} ${JSON.stringify(match.query)} at ${match.index}: ${match.snippet}`,\n ),\n ].join(\"\\n\");\n}\n\nfunction formatLinks(links: WebContentLink[]): string {\n if (!links.length) return \"(none)\";\n return links\n .map(\n (link, index) => `${index + 1}. [${link.text || link.url}](${link.url})`,\n )\n .join(\"\\n\");\n}\n\nfunction formatMetadata(result: WebContentResult): string {\n return JSON.stringify(\n {\n title: result.title,\n excerpt: result.excerpt,\n byline: result.byline,\n siteName: result.siteName,\n lang: result.lang,\n publishedTime: result.publishedTime,\n contentType: result.contentType,\n },\n null,\n 2,\n );\n}\n"]}
@@ -183,7 +183,7 @@ export function createWebSearchToolEntry(opts = {}) {
183
183
  return {
184
184
  "web-search": {
185
185
  tool: {
186
- description: "Search the public web. Use to find API documentation, endpoints, current information, or any topic. Returns ranked results from BYOK providers or a grounded Builder-managed summary. Follow up with web-request or provider-api-docs to fetch the full content of promising URLs. Requires either Connect Builder.io or one of: BRAVE_SEARCH_API_KEY, TAVILY_API_KEY, or EXA_API_KEY.",
186
+ description: "Search the public web. Use to find API documentation, endpoints, current information, or any topic. Returns ranked results from BYOK providers or a grounded Builder-managed summary. Follow up with web-request or provider-api-docs using responseMode:'markdown' or responseMode:'matches' to fetch clean text, links, or compact snippets from promising URLs. Requires either Connect Builder.io or one of: BRAVE_SEARCH_API_KEY, TAVILY_API_KEY, or EXA_API_KEY.",
187
187
  parameters: {
188
188
  type: "object",
189
189
  properties: {
@@ -253,7 +253,7 @@ export function createWebSearchToolEntry(opts = {}) {
253
253
  "",
254
254
  managedText,
255
255
  "",
256
- "Use web-request or provider-api-docs to fetch full content from cited or promising URLs.",
256
+ "Use web-request or provider-api-docs with responseMode:'markdown' for readable docs or responseMode:'matches' plus search for compact snippets.",
257
257
  ].join("\n");
258
258
  }
259
259
  if (results.length === 0) {
@@ -273,7 +273,7 @@ export function createWebSearchToolEntry(opts = {}) {
273
273
  }
274
274
  lines.push("");
275
275
  }
276
- lines.push("Use web-request or provider-api-docs to fetch full content from promising URLs.");
276
+ lines.push("Use web-request or provider-api-docs with responseMode:'markdown' for readable docs or responseMode:'matches' plus search for compact snippets.");
277
277
  return lines.join("\n");
278
278
  },
279
279
  readOnly: true,