@agent-native/core 0.51.4 → 0.51.6

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.
@@ -31,7 +31,7 @@ export const TEMPLATES = [
31
31
  {
32
32
  name: "content",
33
33
  label: "Content",
34
- hint: "Agent-native Notion/Google Docswrite and organize with agent assistance",
34
+ hint: "Open-source Obsidian for MDX edit local docs with agent assistance",
35
35
  icon: "FileText",
36
36
  color: "#10B981",
37
37
  colorRgb: "16 185 129",
@@ -1 +1 @@
1
- {"version":3,"file":"templates-meta.js","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party template metadata used by the `agent-native` CLI.\n *\n * This file is intentionally inlined here (rather than imported from a\n * separate workspace package) so that the published `@agent-native/core`\n * has no `workspace:*` runtime dependencies. Without this inlining, `npx\n * @agent-native/core create ...` fails on a fresh machine with:\n *\n * npm error code EUNSUPPORTEDPROTOCOL\n * npm error Unsupported URL Type \"workspace:\": workspace:*\n *\n * Keep this list in sync with `packages/shared-app-config/templates.ts`,\n * which serves the same metadata to the desktop / mobile / frame packages\n * that always run inside the workspace. Duplication is intentional: the\n * CLI must remain installable outside the monorepo.\n */\n\nexport interface TemplateMeta {\n /** Directory name under templates/ and package name */\n name: string;\n /** Display name in pickers */\n label: string;\n /** One-line description shown in the picker */\n hint: string;\n /** Longer description (optional) */\n description?: string;\n /** Tabler icon name used in the desktop sidebar */\n icon: string;\n /** Hex accent color */\n color: string;\n /** CSS-safe RGB triplet (e.g. \"59 130 246\") */\n colorRgb: string;\n /** Dev server port for desktop `pnpm dev` */\n devPort: number;\n /** Production URL when running as a first-party app on agent-native.com */\n prodUrl?: string;\n /** Default URL path when deployed in a workspace (defaults to \"/<name>\") */\n prodPath?: string;\n /** Default mode when added to desktop app */\n defaultMode?: \"dev\" | \"prod\";\n /** Hide from pickers but still scaffoldable via explicit --template */\n hidden?: boolean;\n /** Include as a built-in connected A2A agent even when hidden from pickers */\n defaultAgent?: boolean;\n /** Always scaffold without prompting (e.g. starter as fallback) */\n alwaysAvailable?: boolean;\n /** Internal workspace packages this template depends on (e.g. \"scheduling\") */\n requiredPackages?: string[];\n /** Core app — featured in the CLI picker, homepage, and docs gallery */\n core?: boolean;\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n name: \"calendar\",\n label: \"Calendar\",\n hint: \"Agent-native Google Calendar — manage events, sync, and public booking\",\n icon: \"CalendarDays\",\n color: \"#00B5FF\",\n colorRgb: \"0 181 255\",\n devPort: 8082,\n prodUrl: \"https://calendar.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n core: true,\n },\n {\n name: \"content\",\n label: \"Content\",\n hint: \"Agent-native Notion/Google Docs — write and organize with agent assistance\",\n icon: \"FileText\",\n color: \"#10B981\",\n colorRgb: \"16 185 129\",\n devPort: 8083,\n prodUrl: \"https://content.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"plan\",\n label: \"Plan\",\n hint: \"Structured visual plans and PR recaps with diagrams, wireframes, prototypes, annotations, and sharing\",\n icon: \"FileText\",\n color: \"#52525B\",\n colorRgb: \"82 82 91\",\n devPort: 8105,\n prodUrl: \"https://plan.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"slides\",\n label: \"Slides\",\n hint: \"Agent-native Google Slides — generate and edit React presentations\",\n icon: \"GalleryHorizontal\",\n color: \"#EC4899\",\n colorRgb: \"236 72 153\",\n devPort: 8086,\n prodUrl: \"https://slides.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n core: true,\n },\n {\n name: \"videos\",\n label: \"Video\",\n hint: \"Agent-native video editing with Remotion\",\n icon: \"Video\",\n color: \"#EF4444\",\n colorRgb: \"239 68 68\",\n devPort: 8087,\n prodUrl: \"https://videos.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n },\n {\n name: \"analytics\",\n label: \"Analytics\",\n hint: \"Agent-native Amplitude/Mixpanel — connect data sources, prompt for charts\",\n icon: \"BarChart2\",\n color: \"#F59E0B\",\n colorRgb: \"245 158 11\",\n devPort: 8088,\n prodUrl: \"https://analytics.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"mail\",\n label: \"Mail\",\n hint: \"Agent-native Superhuman — email client with keyboard shortcuts and AI triage\",\n icon: \"Mail\",\n color: \"#3B82F6\",\n colorRgb: \"59 130 246\",\n devPort: 8085,\n prodUrl: \"https://mail.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"dispatch\",\n label: \"Dispatch\",\n hint: \"Central Slack/Telegram router with jobs, memory, approvals, and A2A delegation\",\n icon: \"MessageCircle\",\n color: \"#14B8A6\",\n colorRgb: \"20 184 166\",\n devPort: 8092,\n prodUrl: \"https://dispatch.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"forms\",\n label: \"Forms\",\n hint: \"Agent-native form builder — create, edit, and manage forms\",\n icon: \"ClipboardList\",\n color: \"#06B6D4\",\n colorRgb: \"6 182 212\",\n devPort: 8084,\n prodUrl: \"https://forms.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"starter\",\n label: \"Starter\",\n hint: \"Minimal scaffold with the agent chat and core architecture wired up\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8089,\n prodUrl: \"https://starter.agent-native.com\",\n defaultMode: \"prod\",\n alwaysAvailable: true,\n core: true,\n hidden: true,\n },\n {\n name: \"clips\",\n label: \"Clips\",\n hint: \"Screen recording, meeting notes, and voice dictation — all with AI\",\n icon: \"ScreenShare\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8094,\n prodUrl: \"https://clips.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"brain\",\n label: \"Brain\",\n hint: \"Cited company knowledge from Slack, meetings, transcripts, and decisions\",\n icon: \"Brain\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8102,\n prodUrl: \"https://brain.agent-native.com\",\n defaultMode: \"prod\",\n defaultAgent: true,\n core: true,\n },\n {\n name: \"design\",\n label: \"Design\",\n hint: \"Agent-native design tool — create and edit visual designs with agent assistance\",\n icon: \"Brush\",\n color: \"#F472B6\",\n colorRgb: \"244 114 182\",\n devPort: 8099,\n prodUrl: \"https://design.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\", \"embedding\"],\n core: true,\n },\n {\n name: \"assets\",\n label: \"Assets\",\n hint: \"Digital asset manager — upload, organize, search, and generate on-brand images and videos\",\n icon: \"Photo\",\n color: \"#0F766E\",\n colorRgb: \"15 118 110\",\n devPort: 8100,\n prodUrl: \"https://assets.agent-native.com\",\n defaultMode: \"prod\",\n defaultAgent: true,\n core: true,\n },\n {\n name: \"macros\",\n label: \"Macros\",\n hint: \"Internal template — not shown in pickers\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8093,\n prodUrl: \"https://macros.agent-native.com\",\n hidden: true,\n defaultMode: \"dev\",\n },\n];\n\n/** Return templates visible in user-facing pickers (excludes hidden). */\nexport function visibleTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => !t.hidden);\n}\n\n/** Return core templates — the featured set shown in CLI pickers by default. */\nexport function coreTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => t.core);\n}\n\n/** Lookup by name. Returns undefined for unknown names. */\nexport function getTemplate(name: string): TemplateMeta | undefined {\n // Tolerate legacy / renamed aliases.\n if (name === \"video\") name = \"videos\";\n if (name === \"image\" || name === \"images\" || name === \"asset\") {\n name = \"assets\";\n }\n if (name === \"contracts\" || name === \"visual-plans\") name = \"plan\";\n return TEMPLATES.find((t) => t.name === name);\n}\n\n/** Names of all templates (including hidden) for validation. */\nexport function allTemplateNames(): string[] {\n return TEMPLATES.map((t) => t.name);\n}\n"]}
1
+ {"version":3,"file":"templates-meta.js","sourceRoot":"","sources":["../../src/cli/templates-meta.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party template metadata used by the `agent-native` CLI.\n *\n * This file is intentionally inlined here (rather than imported from a\n * separate workspace package) so that the published `@agent-native/core`\n * has no `workspace:*` runtime dependencies. Without this inlining, `npx\n * @agent-native/core create ...` fails on a fresh machine with:\n *\n * npm error code EUNSUPPORTEDPROTOCOL\n * npm error Unsupported URL Type \"workspace:\": workspace:*\n *\n * Keep this list in sync with `packages/shared-app-config/templates.ts`,\n * which serves the same metadata to the desktop / mobile / frame packages\n * that always run inside the workspace. Duplication is intentional: the\n * CLI must remain installable outside the monorepo.\n */\n\nexport interface TemplateMeta {\n /** Directory name under templates/ and package name */\n name: string;\n /** Display name in pickers */\n label: string;\n /** One-line description shown in the picker */\n hint: string;\n /** Longer description (optional) */\n description?: string;\n /** Tabler icon name used in the desktop sidebar */\n icon: string;\n /** Hex accent color */\n color: string;\n /** CSS-safe RGB triplet (e.g. \"59 130 246\") */\n colorRgb: string;\n /** Dev server port for desktop `pnpm dev` */\n devPort: number;\n /** Production URL when running as a first-party app on agent-native.com */\n prodUrl?: string;\n /** Default URL path when deployed in a workspace (defaults to \"/<name>\") */\n prodPath?: string;\n /** Default mode when added to desktop app */\n defaultMode?: \"dev\" | \"prod\";\n /** Hide from pickers but still scaffoldable via explicit --template */\n hidden?: boolean;\n /** Include as a built-in connected A2A agent even when hidden from pickers */\n defaultAgent?: boolean;\n /** Always scaffold without prompting (e.g. starter as fallback) */\n alwaysAvailable?: boolean;\n /** Internal workspace packages this template depends on (e.g. \"scheduling\") */\n requiredPackages?: string[];\n /** Core app — featured in the CLI picker, homepage, and docs gallery */\n core?: boolean;\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n {\n name: \"calendar\",\n label: \"Calendar\",\n hint: \"Agent-native Google Calendar — manage events, sync, and public booking\",\n icon: \"CalendarDays\",\n color: \"#00B5FF\",\n colorRgb: \"0 181 255\",\n devPort: 8082,\n prodUrl: \"https://calendar.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"scheduling\"],\n core: true,\n },\n {\n name: \"content\",\n label: \"Content\",\n hint: \"Open-source Obsidian for MDX — edit local docs with agent assistance\",\n icon: \"FileText\",\n color: \"#10B981\",\n colorRgb: \"16 185 129\",\n devPort: 8083,\n prodUrl: \"https://content.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"plan\",\n label: \"Plan\",\n hint: \"Structured visual plans and PR recaps with diagrams, wireframes, prototypes, annotations, and sharing\",\n icon: \"FileText\",\n color: \"#52525B\",\n colorRgb: \"82 82 91\",\n devPort: 8105,\n prodUrl: \"https://plan.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"slides\",\n label: \"Slides\",\n hint: \"Agent-native Google Slides — generate and edit React presentations\",\n icon: \"GalleryHorizontal\",\n color: \"#EC4899\",\n colorRgb: \"236 72 153\",\n devPort: 8086,\n prodUrl: \"https://slides.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n core: true,\n },\n {\n name: \"videos\",\n label: \"Video\",\n hint: \"Agent-native video editing with Remotion\",\n icon: \"Video\",\n color: \"#EF4444\",\n colorRgb: \"239 68 68\",\n devPort: 8087,\n prodUrl: \"https://videos.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\"],\n },\n {\n name: \"analytics\",\n label: \"Analytics\",\n hint: \"Agent-native Amplitude/Mixpanel — connect data sources, prompt for charts\",\n icon: \"BarChart2\",\n color: \"#F59E0B\",\n colorRgb: \"245 158 11\",\n devPort: 8088,\n prodUrl: \"https://analytics.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"mail\",\n label: \"Mail\",\n hint: \"Agent-native Superhuman — email client with keyboard shortcuts and AI triage\",\n icon: \"Mail\",\n color: \"#3B82F6\",\n colorRgb: \"59 130 246\",\n devPort: 8085,\n prodUrl: \"https://mail.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"dispatch\",\n label: \"Dispatch\",\n hint: \"Central Slack/Telegram router with jobs, memory, approvals, and A2A delegation\",\n icon: \"MessageCircle\",\n color: \"#14B8A6\",\n colorRgb: \"20 184 166\",\n devPort: 8092,\n prodUrl: \"https://dispatch.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"forms\",\n label: \"Forms\",\n hint: \"Agent-native form builder — create, edit, and manage forms\",\n icon: \"ClipboardList\",\n color: \"#06B6D4\",\n colorRgb: \"6 182 212\",\n devPort: 8084,\n prodUrl: \"https://forms.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"starter\",\n label: \"Starter\",\n hint: \"Minimal scaffold with the agent chat and core architecture wired up\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8089,\n prodUrl: \"https://starter.agent-native.com\",\n defaultMode: \"prod\",\n alwaysAvailable: true,\n core: true,\n hidden: true,\n },\n {\n name: \"clips\",\n label: \"Clips\",\n hint: \"Screen recording, meeting notes, and voice dictation — all with AI\",\n icon: \"ScreenShare\",\n color: \"#0EA5E9\",\n colorRgb: \"14 165 233\",\n devPort: 8094,\n prodUrl: \"https://clips.agent-native.com\",\n defaultMode: \"prod\",\n core: true,\n },\n {\n name: \"brain\",\n label: \"Brain\",\n hint: \"Cited company knowledge from Slack, meetings, transcripts, and decisions\",\n icon: \"Brain\",\n color: \"#8B5CF6\",\n colorRgb: \"139 92 246\",\n devPort: 8102,\n prodUrl: \"https://brain.agent-native.com\",\n defaultMode: \"prod\",\n defaultAgent: true,\n core: true,\n },\n {\n name: \"design\",\n label: \"Design\",\n hint: \"Agent-native design tool — create and edit visual designs with agent assistance\",\n icon: \"Brush\",\n color: \"#F472B6\",\n colorRgb: \"244 114 182\",\n devPort: 8099,\n prodUrl: \"https://design.agent-native.com\",\n defaultMode: \"prod\",\n requiredPackages: [\"pinpoint\", \"embedding\"],\n core: true,\n },\n {\n name: \"assets\",\n label: \"Assets\",\n hint: \"Digital asset manager — upload, organize, search, and generate on-brand images and videos\",\n icon: \"Photo\",\n color: \"#0F766E\",\n colorRgb: \"15 118 110\",\n devPort: 8100,\n prodUrl: \"https://assets.agent-native.com\",\n defaultMode: \"prod\",\n defaultAgent: true,\n core: true,\n },\n {\n name: \"macros\",\n label: \"Macros\",\n hint: \"Internal template — not shown in pickers\",\n icon: \"Code\",\n color: \"#71717A\",\n colorRgb: \"113 113 122\",\n devPort: 8093,\n prodUrl: \"https://macros.agent-native.com\",\n hidden: true,\n defaultMode: \"dev\",\n },\n];\n\n/** Return templates visible in user-facing pickers (excludes hidden). */\nexport function visibleTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => !t.hidden);\n}\n\n/** Return core templates — the featured set shown in CLI pickers by default. */\nexport function coreTemplates(): TemplateMeta[] {\n return TEMPLATES.filter((t) => t.core);\n}\n\n/** Lookup by name. Returns undefined for unknown names. */\nexport function getTemplate(name: string): TemplateMeta | undefined {\n // Tolerate legacy / renamed aliases.\n if (name === \"video\") name = \"videos\";\n if (name === \"image\" || name === \"images\" || name === \"asset\") {\n name = \"assets\";\n }\n if (name === \"contracts\" || name === \"visual-plans\") name = \"plan\";\n return TEMPLATES.find((t) => t.name === name);\n}\n\n/** Names of all templates (including hidden) for validation. */\nexport function allTemplateNames(): string[] {\n return TEMPLATES.map((t) => t.name);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA8DhE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC7C,IAAI,GAAE,cAAmB,GACxB,WAAW,CA2Mb"}
1
+ {"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA8DhE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC7C,IAAI,GAAE,cAAmB,GACxB,WAAW,CA4Mb"}
@@ -110,6 +110,7 @@ export function createRunCodeEntry(getActions, opts = {}) {
110
110
  " Example: `const data = await providerFetch('<provider-id>', '/records', { query: { limit: 100 } });`",
111
111
  " - `providerRequest(provider, path, init?)` — same authenticated call, but returns the full provider-api envelope with request, response status/headers, truncation, and body metadata.",
112
112
  " - `providerFetchAll(provider, path, init?)` — generic pagination helper for cursor, page, and offset APIs. Pass `pagination: { itemsPath, cursorPath or nextCursorPath, cursorParam or cursorBodyPath, pageParam, offsetParam, pageSize, maxPages }`. Returns `{ items, pages, pageCount, itemCount, hasMore, lastCursor, stoppedReason }`.",
113
+ " - `providerSearchAll(provider, path, init?, options?)` — streaming search helper for broad provider corpora such as transcripts, messages, tickets, issues, notes, events, or documents. Use this before hand-written loops when searching many provider records for terms/phrases/regexes or proving absence. Pass the same `pagination` config as `providerFetchAll`, plus options like `{ query, queries, terms, regex, textPaths, idPaths, metadataPaths, maxHits }`. Returns structured hits with item ids, paths, snippets, page/item indexes, and coverage fields (`pageCount`, `itemCount`, `hasMore`, `stoppedReason`).",
113
114
  " - `webFetch(url, init?)` — outbound HTTP request via the web-request action.",
114
115
  " Returns `{ status, body }` where body is the response text.",
115
116
  " Example: `const { body } = await webFetch('https://api.example.com/data');`",
@@ -376,8 +377,8 @@ function handleBridgeRequest(rawBody, actions, context, defaultTools, extraTools
376
377
  // ---------------------------------------------------------------------------
377
378
  /**
378
379
  * Wrap the user's code in an ESM module that:
379
- * 1. Defines `providerFetch`, `providerRequest`, `providerFetchAll`, and
380
- * `webFetch` helpers via the bridge.
380
+ * 1. Defines `providerFetch`, `providerRequest`, `providerFetchAll`,
381
+ * `providerSearchAll`, and `webFetch` helpers via the bridge.
381
382
  * 2. Runs the user's code as top-level await in an async IIFE.
382
383
  */
383
384
  function buildSandboxModule(userCode, bridgePort, bridgeToken) {
@@ -524,7 +525,7 @@ function _extractItems(page, itemsPath) {
524
525
  }
525
526
  if (Array.isArray(page)) return page;
526
527
  if (!page || typeof page !== "object") return [];
527
- for (const key of ["data", "results", "items", "records", "rows", "calls", "messages", "tickets", "issues", "deals"]) {
528
+ for (const key of ["data", "results", "items", "records", "rows", "calls", "callTranscripts", "transcripts", "messages", "tickets", "issues", "deals", "events", "notes", "documents", "entries", "objects"]) {
528
529
  if (Array.isArray(page[key])) return page[key];
529
530
  }
530
531
  return [];
@@ -542,6 +543,437 @@ function _withoutProviderFetchAllOptions(init) {
542
543
  return rest;
543
544
  }
544
545
 
546
+ function _asArray(value) {
547
+ if (value === undefined || value === null) return [];
548
+ return Array.isArray(value) ? value : [value];
549
+ }
550
+
551
+ function _stringifySearchValue(value) {
552
+ if (typeof value === "string") return value;
553
+ if (value === undefined || value === null) return "";
554
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
555
+ return String(value);
556
+ }
557
+ try {
558
+ return JSON.stringify(value);
559
+ } catch {
560
+ return String(value);
561
+ }
562
+ }
563
+
564
+ function _collectStrings(value, basePath = "", out = [], limit = 5000) {
565
+ if (out.length >= limit || value === undefined || value === null) return out;
566
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
567
+ out.push({ path: basePath || "$", text: String(value) });
568
+ return out;
569
+ }
570
+ if (Array.isArray(value)) {
571
+ for (let i = 0; i < value.length && out.length < limit; i++) {
572
+ _collectStrings(value[i], basePath ? basePath + "[" + i + "]" : "[" + i + "]", out, limit);
573
+ }
574
+ return out;
575
+ }
576
+ if (typeof value === "object") {
577
+ for (const key of Object.keys(value)) {
578
+ if (out.length >= limit) break;
579
+ _collectStrings(value[key], basePath ? basePath + "." + key : key, out, limit);
580
+ }
581
+ }
582
+ return out;
583
+ }
584
+
585
+ function _collectSearchStrings(item, textPaths, maxFieldsPerItem) {
586
+ const paths = _asArray(textPaths).filter((path) => typeof path === "string" && path.trim());
587
+ if (!paths.length) return _collectStrings(item, "", [], maxFieldsPerItem);
588
+ const out = [];
589
+ for (const path of paths) {
590
+ const value = _getByPath(item, path);
591
+ if (value !== undefined) _collectStrings(value, path, out, maxFieldsPerItem);
592
+ if (out.length >= maxFieldsPerItem) break;
593
+ }
594
+ return out;
595
+ }
596
+
597
+ function _firstValueByPath(value, paths) {
598
+ for (const path of paths) {
599
+ const found = _getByPath(value, path);
600
+ if (found !== undefined && found !== null && String(found) !== "") {
601
+ return { path, value: found };
602
+ }
603
+ }
604
+ return null;
605
+ }
606
+
607
+ const _DEFAULT_ID_PATHS = [
608
+ "id",
609
+ "callId",
610
+ "callID",
611
+ "call_id",
612
+ "call.id",
613
+ "call.metaData.id",
614
+ "metaData.id",
615
+ "metadata.id",
616
+ "recordId",
617
+ "record_id",
618
+ "objectId",
619
+ "object_id",
620
+ "ticketId",
621
+ "ticket_id",
622
+ "issueId",
623
+ "issue_id",
624
+ "messageId",
625
+ "message_id",
626
+ "conversationId",
627
+ "conversation_id",
628
+ "eventId",
629
+ "event_id",
630
+ "documentId",
631
+ "document_id",
632
+ "url",
633
+ "webUrl",
634
+ "permalink",
635
+ ];
636
+
637
+ function _extractItemIdentity(item, idPaths) {
638
+ const paths = [
639
+ ..._asArray(idPaths).filter((path) => typeof path === "string" && path.trim()),
640
+ ..._DEFAULT_ID_PATHS,
641
+ ];
642
+ const found = _firstValueByPath(item, paths);
643
+ if (!found) return { id: null, idPath: null };
644
+ return { id: _stringifySearchValue(found.value), idPath: found.path };
645
+ }
646
+
647
+ function _extractMetadata(item, metadataPaths) {
648
+ const metadata = {};
649
+ for (const path of _asArray(metadataPaths)) {
650
+ if (typeof path !== "string" || !path.trim()) continue;
651
+ const value = _getByPath(item, path);
652
+ if (value !== undefined) metadata[path] = value;
653
+ }
654
+ return metadata;
655
+ }
656
+
657
+ function _makeSnippet(text, index, contextChars) {
658
+ const source = String(text);
659
+ const context = Math.max(20, Math.min(Number(contextChars) || 180, 1000));
660
+ const start = Math.max(0, index - context);
661
+ const end = Math.min(source.length, Math.max(index, 0) + context);
662
+ const prefix = start > 0 ? "..." : "";
663
+ const suffix = end < source.length ? "..." : "";
664
+ return (prefix + source.slice(start, end) + suffix).replace(/\\s+/g, " ").trim();
665
+ }
666
+
667
+ function _normalizeFlags(flags, caseSensitive) {
668
+ const raw = typeof flags === "string" ? flags : "";
669
+ const allowed = raw.replace(/[^dgimsuvy]/g, "");
670
+ const withoutGlobalOrSticky = allowed.replace(/[gy]/g, "");
671
+ const withCase =
672
+ caseSensitive || /i/.test(withoutGlobalOrSticky)
673
+ ? withoutGlobalOrSticky
674
+ : withoutGlobalOrSticky + "i";
675
+ return withCase + "g";
676
+ }
677
+
678
+ function _normalizedSearchTerms(options) {
679
+ const explicitTerms = _asArray(options.terms)
680
+ .map((term) => String(term).trim())
681
+ .filter(Boolean);
682
+ if (explicitTerms.length) return explicitTerms;
683
+ if (options.matchMode === "allTerms" && typeof options.query === "string") {
684
+ return options.query
685
+ .split(/\\s+/)
686
+ .map((term) => term.trim())
687
+ .filter(Boolean);
688
+ }
689
+ return [];
690
+ }
691
+
692
+ function _findItemWideTermMatch(fields, options) {
693
+ const terms = _normalizedSearchTerms(options);
694
+ if (!terms.length || options.matchMode === "anyTerm") return null;
695
+ const caseSensitive = Boolean(options.caseSensitive);
696
+ const normalizedFields = fields.map((field) => ({
697
+ field,
698
+ haystack: caseSensitive ? String(field.text) : String(field.text).toLowerCase(),
699
+ }));
700
+ const termHits = terms.map((term) => {
701
+ const searchTerm = caseSensitive ? term : term.toLowerCase();
702
+ for (const entry of normalizedFields) {
703
+ const index = entry.haystack.indexOf(searchTerm);
704
+ if (index >= 0) return { term, field: entry.field, index };
705
+ }
706
+ return { term, field: null, index: -1 };
707
+ });
708
+ if (termHits.some((hit) => hit.index < 0 || !hit.field)) return null;
709
+ const first = termHits
710
+ .filter((hit) => hit.field)
711
+ .sort((a, b) => {
712
+ const fieldOrder = fields.indexOf(a.field) - fields.indexOf(b.field);
713
+ return fieldOrder || a.index - b.index;
714
+ })[0];
715
+ return {
716
+ field: first.field,
717
+ match: {
718
+ kind: "allTerms",
719
+ query: terms.join(" "),
720
+ index: first.index,
721
+ match: first.term,
722
+ },
723
+ };
724
+ }
725
+
726
+ function _findSearchMatches(text, options, includeTerms = true) {
727
+ const source = String(text);
728
+ const caseSensitive = Boolean(options.caseSensitive);
729
+ const haystack = caseSensitive ? source : source.toLowerCase();
730
+ const maxMatchesPerField = _boundedNumber(options.maxMatchesPerField, 1000, 1, 100000);
731
+ const matches = [];
732
+
733
+ const addSubstring = (needle, label, kind) => {
734
+ if (needle === undefined || needle === null) return;
735
+ const rawNeedle = String(needle);
736
+ if (!rawNeedle) return;
737
+ const searchNeedle = caseSensitive ? rawNeedle : rawNeedle.toLowerCase();
738
+ let from = 0;
739
+ while (from <= haystack.length) {
740
+ const index = haystack.indexOf(searchNeedle, from);
741
+ if (index < 0) break;
742
+ matches.push({ kind, query: label ?? rawNeedle, index, match: source.slice(index, index + rawNeedle.length) });
743
+ from = index + Math.max(1, searchNeedle.length);
744
+ if (matches.length >= maxMatchesPerField) break;
745
+ }
746
+ };
747
+
748
+ if (options.regex) {
749
+ try {
750
+ const regex = new RegExp(String(options.regex), _normalizeFlags(options.regexFlags, caseSensitive));
751
+ let match;
752
+ while ((match = regex.exec(source)) && typeof match.index === "number") {
753
+ matches.push({ kind: "regex", query: String(options.regex), index: match.index, match: match[0] });
754
+ if (matches.length >= maxMatchesPerField) break;
755
+ if (match[0] === "") regex.lastIndex += 1;
756
+ }
757
+ } catch (err) {
758
+ throw new Error("providerSearchAll invalid regex: " + (err?.message || err));
759
+ }
760
+ }
761
+
762
+ for (const query of _asArray(options.query).concat(_asArray(options.queries))) {
763
+ addSubstring(query, String(query), "query");
764
+ }
765
+
766
+ const terms = includeTerms ? _normalizedSearchTerms(options) : [];
767
+ if (terms.length) {
768
+ const termHits = terms
769
+ .map((term) => {
770
+ const searchTerm = caseSensitive ? term : term.toLowerCase();
771
+ const index = haystack.indexOf(searchTerm);
772
+ return { term, index };
773
+ })
774
+ .filter((hit) => hit.index >= 0);
775
+ const mode = options.matchMode === "anyTerm" ? "anyTerm" : "allTerms";
776
+ if ((mode === "allTerms" && termHits.length === terms.length) || (mode === "anyTerm" && termHits.length > 0)) {
777
+ const first = termHits.sort((a, b) => a.index - b.index)[0];
778
+ matches.push({ kind: mode, query: terms.join(" "), index: first.index, match: first.term });
779
+ }
780
+ }
781
+
782
+ return matches.sort((a, b) => a.index - b.index);
783
+ }
784
+
785
+ function _boundedNumber(value, defaultValue, min, max) {
786
+ const parsed = Number(value);
787
+ const finite = Number.isFinite(parsed) ? parsed : defaultValue;
788
+ return Math.max(min, Math.min(finite, max));
789
+ }
790
+
791
+ function _hitKey(identity, path, query, index, pageIndex, pageItemIndex) {
792
+ const itemKey =
793
+ identity.id !== null && identity.id !== undefined
794
+ ? "id:" + identity.id
795
+ : "page:" + String(pageIndex) + ":" + String(pageItemIndex);
796
+ return [itemKey, path ?? "", query ?? "", String(index ?? "")].join("\\n");
797
+ }
798
+
799
+ /**
800
+ * Stream pages from a provider API and search item text structurally. This is
801
+ * for broad mention searches and absence checks where keeping every raw page
802
+ * in memory or hand-parsing JSON strings is brittle.
803
+ */
804
+ async function providerSearchAll(provider, apiPath, init = {}, options = {}) {
805
+ const pagination = init.pagination || init.fetchAllPages || {};
806
+ const itemsPath = pagination.itemsPath || init.itemsPath || options.itemsPath;
807
+ const cursorPath = pagination.nextCursorPath || pagination.cursorPath;
808
+ const maxPagesRaw = Number(pagination.maxPages || init.maxPages || options.maxPages || 100);
809
+ const maxPages = Math.max(1, Math.min(Number.isFinite(maxPagesRaw) ? maxPagesRaw : 100, 500));
810
+ const maxHits = _boundedNumber(options.maxHits, 100, 1, 5000);
811
+ const maxHitsPerItem = _boundedNumber(options.maxHitsPerItem, 3, 1, 100);
812
+ const maxFieldsPerItem = _boundedNumber(options.maxFieldsPerItem, 5000, 1, 50000);
813
+ const contextChars = options.contextChars ?? options.snippetChars ?? 180;
814
+ const baseInit = _withoutProviderFetchAllOptions(init);
815
+ let query = _cloneJson(init.query || {});
816
+ let body = _cloneJson(init.body);
817
+ let pageNumber = Number(pagination.startPage || 1);
818
+ let offset = Number(pagination.startOffset || 0);
819
+ let lastCursor = null;
820
+ let stoppedReason = "completed";
821
+ let itemCount = 0;
822
+ let matchedItemCount = 0;
823
+ let totalHitCount = 0;
824
+ const hits = [];
825
+ const seenHitKeys = new Set();
826
+ let pageIndex = 0;
827
+
828
+ for (; pageIndex < maxPages; pageIndex++) {
829
+ if (pagination.pageParam) query = { ...(query || {}), [pagination.pageParam]: pageNumber };
830
+ if (pagination.offsetParam) query = { ...(query || {}), [pagination.offsetParam]: offset };
831
+
832
+ const page = await providerFetch(provider, apiPath, {
833
+ ...baseInit,
834
+ query,
835
+ ...(body !== undefined ? { body } : {}),
836
+ });
837
+ const nextCursor = cursorPath ? _getByPath(page, cursorPath) : undefined;
838
+ const hasNextCursor =
839
+ nextCursor !== undefined && nextCursor !== null && String(nextCursor) !== "";
840
+ if (hasNextCursor && lastCursor !== null && String(nextCursor) === String(lastCursor)) {
841
+ stoppedReason = "repeated-cursor";
842
+ break;
843
+ }
844
+
845
+ const pageItems = _extractItems(page, itemsPath);
846
+ itemCount += pageItems.length;
847
+
848
+ for (let pageItemIndex = 0; pageItemIndex < pageItems.length; pageItemIndex++) {
849
+ const item = pageItems[pageItemIndex];
850
+ const identity = _extractItemIdentity(item, options.idPaths);
851
+ const metadata = _extractMetadata(item, options.metadataPaths);
852
+ const fields = _collectSearchStrings(item, options.textPaths, maxFieldsPerItem);
853
+ let storedItemHitCount = 0;
854
+ let itemMatched = false;
855
+
856
+ const addHit = (field, match) => {
857
+ const key = _hitKey(identity, field.path, match.query, match.index, pageIndex, pageItemIndex);
858
+ if (seenHitKeys.has(key)) return false;
859
+ seenHitKeys.add(key);
860
+ totalHitCount += 1;
861
+ if (!itemMatched) {
862
+ matchedItemCount += 1;
863
+ itemMatched = true;
864
+ }
865
+ if (hits.length < maxHits && storedItemHitCount < maxHitsPerItem) {
866
+ storedItemHitCount += 1;
867
+ hits.push({
868
+ id: identity.id,
869
+ idPath: identity.idPath,
870
+ pageIndex,
871
+ pageItemIndex,
872
+ itemIndex: itemCount - pageItems.length + pageItemIndex,
873
+ path: field.path,
874
+ kind: match.kind,
875
+ query: match.query,
876
+ match: match.match,
877
+ snippet: _makeSnippet(field.text, match.index, contextChars),
878
+ ...(Object.keys(metadata).length ? { metadata } : {}),
879
+ });
880
+ }
881
+ return true;
882
+ };
883
+
884
+ const itemWideTermMatch = _findItemWideTermMatch(fields, options);
885
+ if (itemWideTermMatch) {
886
+ addHit(itemWideTermMatch.field, itemWideTermMatch.match);
887
+ }
888
+
889
+ for (const field of fields) {
890
+ const fieldMatches = _findSearchMatches(field.text, options, !itemWideTermMatch);
891
+ for (const match of fieldMatches) {
892
+ addHit(field, match);
893
+ }
894
+ }
895
+ }
896
+
897
+ if (hasNextCursor) {
898
+ lastCursor = nextCursor;
899
+ if (pagination.cursorBodyPath) {
900
+ body = _setByPath(body || {}, pagination.cursorBodyPath, nextCursor);
901
+ } else if (pagination.cursorParam) {
902
+ query = { ...(query || {}), [pagination.cursorParam]: nextCursor };
903
+ } else {
904
+ stoppedReason = "cursor-found-without-destination";
905
+ break;
906
+ }
907
+ continue;
908
+ }
909
+
910
+ lastCursor = null;
911
+ if (pagination.pageParam) {
912
+ if (pageItems.length === 0) {
913
+ stoppedReason = "empty-page";
914
+ break;
915
+ }
916
+ pageNumber += 1;
917
+ continue;
918
+ }
919
+ if (pagination.offsetParam) {
920
+ if (pageItems.length === 0) {
921
+ stoppedReason = "empty-page";
922
+ break;
923
+ }
924
+ const step = Number(pagination.pageSize || pageItems.length);
925
+ if (!Number.isFinite(step) || step <= 0) {
926
+ stoppedReason = "invalid-page-size";
927
+ break;
928
+ }
929
+ offset += step;
930
+ if (pagination.pageSize && pageItems.length < Number(pagination.pageSize)) {
931
+ stoppedReason = "short-page";
932
+ break;
933
+ }
934
+ continue;
935
+ }
936
+
937
+ break;
938
+ }
939
+
940
+ const pageCount = pageIndex + (pageIndex < maxPages ? 1 : 0);
941
+ const hitPageOrOffsetLimit =
942
+ Boolean(pagination.pageParam || pagination.offsetParam) &&
943
+ stoppedReason === "completed" &&
944
+ pageCount >= maxPages;
945
+ const hasMore =
946
+ stoppedReason === "cursor-found-without-destination" ||
947
+ (lastCursor !== null && pageCount >= maxPages) || hitPageOrOffsetLimit;
948
+ if (hasMore && stoppedReason === "completed") stoppedReason = "max-pages";
949
+
950
+ return {
951
+ hits,
952
+ hitCount: hits.length,
953
+ totalHitCount,
954
+ truncatedHits: totalHitCount > hits.length,
955
+ matchedItemCount,
956
+ itemCount,
957
+ pageCount,
958
+ hasMore,
959
+ lastCursor,
960
+ stoppedReason,
961
+ searched: {
962
+ provider,
963
+ path: apiPath,
964
+ itemsPath: itemsPath || null,
965
+ textPaths: _asArray(options.textPaths),
966
+ idPaths: _asArray(options.idPaths),
967
+ query: options.query ?? null,
968
+ queries: _asArray(options.queries),
969
+ terms: _asArray(options.terms),
970
+ regex: options.regex ?? null,
971
+ matchMode: options.matchMode || (options.terms ? "allTerms" : "query"),
972
+ caseSensitive: Boolean(options.caseSensitive),
973
+ },
974
+ };
975
+ }
976
+
545
977
  /**
546
978
  * Fetch every page from a provider API using generic cursor, page-number, or
547
979
  * offset pagination. Prefer this inside run-code when the answer depends on a