@agent-native/core 0.153.4 → 0.153.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.
Files changed (70) hide show
  1. package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
  2. package/corpus/templates/analytics/actions/bigquery-query.ts +1 -0
  3. package/corpus/templates/analytics/actions/bigquery.ts +1 -0
  4. package/corpus/templates/analytics/actions/content-calendar-schema.ts +1 -0
  5. package/corpus/templates/analytics/actions/content-calendar.ts +1 -0
  6. package/corpus/templates/analytics/actions/gcloud.ts +1 -0
  7. package/corpus/templates/analytics/actions/get-data-program.ts +4 -0
  8. package/corpus/templates/analytics/actions/get-error-issue.ts +1 -0
  9. package/corpus/templates/analytics/actions/get-monitor-stats.ts +1 -0
  10. package/corpus/templates/analytics/actions/get-monitor.ts +1 -0
  11. package/corpus/templates/analytics/actions/get-session-replay-events.ts +1 -0
  12. package/corpus/templates/analytics/actions/get-session-replay-summary.ts +1 -0
  13. package/corpus/templates/analytics/actions/get-session-replay-timeline.ts +1 -0
  14. package/corpus/templates/analytics/actions/gong-calls.ts +1 -0
  15. package/corpus/templates/analytics/actions/gong-native-insights.ts +1 -0
  16. package/corpus/templates/analytics/actions/grafana.ts +1 -0
  17. package/corpus/templates/analytics/actions/hubspot-deals.ts +1 -0
  18. package/corpus/templates/analytics/actions/hubspot-metrics.ts +1 -0
  19. package/corpus/templates/analytics/actions/hubspot-pipelines.ts +1 -0
  20. package/corpus/templates/analytics/actions/hubspot-records.ts +1 -0
  21. package/corpus/templates/analytics/actions/jira-search.ts +1 -0
  22. package/corpus/templates/analytics/actions/jira.ts +1 -0
  23. package/corpus/templates/analytics/actions/list-error-issues.ts +1 -0
  24. package/corpus/templates/analytics/actions/list-monitors.ts +1 -0
  25. package/corpus/templates/analytics/actions/list-session-recordings.ts +1 -0
  26. package/corpus/templates/analytics/actions/match-error-issues.ts +1 -0
  27. package/corpus/templates/analytics/actions/prometheus.ts +1 -0
  28. package/corpus/templates/analytics/actions/pylon-issues.ts +1 -0
  29. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -0
  30. package/corpus/templates/analytics/actions/query-dashboard-panel.ts +1 -0
  31. package/corpus/templates/analytics/actions/query-inbound-forms.ts +1 -0
  32. package/corpus/templates/analytics/actions/run-monitor-check.ts +1 -0
  33. package/corpus/templates/analytics/actions/sentry.ts +1 -0
  34. package/corpus/templates/analytics/actions/seo-blog-pages.ts +1 -0
  35. package/corpus/templates/analytics/actions/seo-page-keywords.ts +1 -0
  36. package/corpus/templates/analytics/actions/seo-top-keywords.ts +1 -0
  37. package/corpus/templates/analytics/actions/slack-messages.ts +1 -0
  38. package/corpus/templates/analytics/actions/stripe.ts +1 -0
  39. package/corpus/templates/analytics/actions/test-custom-api-connection.ts +1 -0
  40. package/corpus/templates/analytics/server/lib/real-data-actions.ts +62 -47
  41. package/corpus/templates/analytics/server/plugins/agent-chat.ts +27 -34
  42. package/dist/action.d.ts +13 -0
  43. package/dist/action.js +3 -0
  44. package/dist/agent/engine/tool-call-journal-seed.d.ts +27 -10
  45. package/dist/agent/engine/tool-call-journal-seed.js +63 -32
  46. package/dist/agent/production-agent.d.ts +40 -1
  47. package/dist/agent/production-agent.js +201 -62
  48. package/dist/agent/run-loop-with-resume.d.ts +1 -1
  49. package/dist/agent/run-loop-with-resume.js +49 -35
  50. package/dist/agent/run-manager.js +17 -11
  51. package/dist/agent/run-store.d.ts +16 -0
  52. package/dist/agent/run-store.js +51 -9
  53. package/dist/agent/thread-data-builder.d.ts +1 -0
  54. package/dist/agent/thread-data-builder.js +15 -2
  55. package/dist/client/RouteTransitionIndicator.js +1 -1
  56. package/dist/client/agent-chat-adapter.js +242 -282
  57. package/dist/client/sse-event-processor.d.ts +7 -0
  58. package/dist/client/sse-event-processor.js +28 -1
  59. package/dist/collab/routes.d.ts +1 -1
  60. package/dist/db/client.js +2 -2
  61. package/dist/notifications/routes.d.ts +1 -1
  62. package/dist/progress/routes.d.ts +1 -1
  63. package/dist/provider-api/actions/github-repo-files.js +1 -0
  64. package/dist/provider-api/actions/provider-api.js +1 -0
  65. package/dist/provider-api/actions/staged-datasets.js +1 -0
  66. package/dist/provider-api/corpus-jobs.js +1 -0
  67. package/dist/server/action-discovery.js +2 -0
  68. package/dist/server/agent-chat-plugin.js +35 -3
  69. package/dist/server/realtime-token.d.ts +1 -1
  70. package/package.json +1 -1
@@ -110,6 +110,13 @@ export interface AgentAutoContinueErrorInfo {
110
110
  recoverable?: boolean;
111
111
  upgradeUrl?: string;
112
112
  }
113
+ /**
114
+ * Kept verbatim in sync with `INTERRUPTED_TOOL_RESULT_MARKER`
115
+ * (agent/production-agent.ts): the server matches this substring in replayed
116
+ * history to count how many times a write tool was interrupted, which is the
117
+ * only thing that tells "we do not know if it landed" apart from "it failed".
118
+ */
119
+ export declare const INTERRUPTED_TOOL_RESULT = "Interrupted before this tool returned a result.";
113
120
  export declare function settleInterruptedToolCalls(content: ContentPart[], result?: string, options?: {
114
121
  includeActivity?: boolean;
115
122
  activityResult?: string;
@@ -2,7 +2,13 @@ import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, }
2
2
  import { emitChatFirstOpenApp } from "./chat-first.js";
3
3
  import { formatChatErrorText, normalizeChatError } from "./error-format.js";
4
4
  import { humanizeToolLabelText, humanizeToolName, runningToolLabel, } from "./tool-display.js";
5
- const INTERRUPTED_TOOL_RESULT = "Interrupted before this tool returned a result.";
5
+ /**
6
+ * Kept verbatim in sync with `INTERRUPTED_TOOL_RESULT_MARKER`
7
+ * (agent/production-agent.ts): the server matches this substring in replayed
8
+ * history to count how many times a write tool was interrupted, which is the
9
+ * only thing that tells "we do not know if it landed" apart from "it failed".
10
+ */
11
+ export const INTERRUPTED_TOOL_RESULT = "Interrupted before this tool returned a result.";
6
12
  const INTERRUPTED_ACTIVITY_RESULT = "Stopped before this action started.";
7
13
  /**
8
14
  * Maximum number of assistant-ui repository updates we deliver in one browser
@@ -528,6 +534,13 @@ function isAutoRecoverableError(ev, errMsg) {
528
534
  }
529
535
  if (ev.recoverable === true)
530
536
  return true;
537
+ // An explicit flag outranks the message sniff below, which exists only for
538
+ // events that carry no flag at all. The repeat guards stop a turn with
539
+ // `recoverable: false` and a message that names the looping tool, so a stop
540
+ // on `list-workspace-connections` matched the "connection" sniff and
541
+ // auto-continued the very loop it was emitted to break.
542
+ if (ev.recoverable === false)
543
+ return false;
531
544
  if (msg.includes("daily gateway request cap"))
532
545
  return false;
533
546
  // "gateway error" intentionally absent — that's the no-detail Builder
@@ -1542,11 +1555,25 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
1542
1555
  }
1543
1556
  return { action: "continue" };
1544
1557
  }
1558
+ /**
1559
+ * Drop the draft the server is about to re-emit — the narration since the last
1560
+ * completed tool, not the whole turn. A `clear` arrives on a final-answer-guard
1561
+ * retry or a continuation, both of which resume AFTER the last completed tool
1562
+ * call, so anything before that boundary is settled multi-step narration the
1563
+ * retry will never re-send. Wiping it read to users as "it deleted its reply
1564
+ * and started over", and `thread-data-builder` replays this same scoping on
1565
+ * rebuild, so the loss survived a reload.
1566
+ */
1545
1567
  function clearAssistantDraftContent(content) {
1546
1568
  for (let index = content.length - 1; index >= 0; index--) {
1547
1569
  const part = content[index];
1548
1570
  if (!part)
1549
1571
  continue;
1572
+ if (part.type === "tool-call" &&
1573
+ part.activity !== true &&
1574
+ part.result !== undefined) {
1575
+ return;
1576
+ }
1550
1577
  if (part.type === "text" || part.type === "reasoning") {
1551
1578
  content.splice(index, 1);
1552
1579
  continue;
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
package/dist/db/client.js CHANGED
@@ -1091,7 +1091,7 @@ const _sharedDbPoolReplacementHooks = new Map();
1091
1091
  * database access down with it.
1092
1092
  */
1093
1093
  export function sharedDbPool(driver, url, create) {
1094
- const key = `${driver}${url}`;
1094
+ const key = `${driver}\u0000${url}`;
1095
1095
  const existing = _sharedDbPools.get(key);
1096
1096
  if (existing)
1097
1097
  return existing;
@@ -1105,7 +1105,7 @@ export function sharedDbPool(driver, url, create) {
1105
1105
  * handing out the discarded pool.
1106
1106
  */
1107
1107
  export function replaceSharedDbPool(driver, url, previous, next) {
1108
- const key = `${driver}${url}`;
1108
+ const key = `${driver}\u0000${url}`;
1109
1109
  if (_sharedDbPools.get(key) !== previous)
1110
1110
  return;
1111
1111
  _sharedDbPools.set(key, next);
@@ -28,6 +28,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- error?: undefined;
32
31
  ok: boolean;
32
+ error?: undefined;
33
33
  }>>;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- error?: undefined;
19
18
  ok: boolean;
19
+ error?: undefined;
20
20
  }>>;
@@ -130,6 +130,7 @@ export function createGitHubRepoFilesAction(runtime, options = {}) {
130
130
  needsApproval: requireApprovalForWrites
131
131
  ? (args) => args.operation === "write" || args.operation === "delete"
132
132
  : false,
133
+ grounding: true,
133
134
  run: async (args) => {
134
135
  if (args.operation === "list") {
135
136
  return runtime.listGitHubRepositoryFiles({
@@ -231,6 +231,7 @@ export function createProviderApiRequestAction(runtime, options = {}) {
231
231
  }),
232
232
  summary: (args) => buildProviderApiAuditSummary(args),
233
233
  },
234
+ grounding: true,
234
235
  run: async (rawArgs) => {
235
236
  const args = rawArgs;
236
237
  if (args.stageAs) {
@@ -120,6 +120,7 @@ export function createQueryStagedDatasetAction(options = {}) {
120
120
  schema,
121
121
  http: options.http ?? false,
122
122
  readOnly: true,
123
+ grounding: true,
123
124
  run: async (rawArgs) => {
124
125
  const args = rawArgs;
125
126
  const scope = resolveScope("query-staged-dataset", args, options);
@@ -205,6 +205,7 @@ export function createProviderCorpusJobAction(options) {
205
205
  "When status is paused or quota_wait, call operation=continue with the jobId after the indicated time/budget. Report coverage counts, paginationComplete, and any remaining gaps; a max-pages stop is not exhaustive.",
206
206
  schema: ProviderCorpusJobSchema,
207
207
  http: false,
208
+ grounding: true,
208
209
  run: async (args) => runProviderCorpusJobAction(args, options),
209
210
  });
210
211
  }
@@ -168,6 +168,8 @@ function preserveActionFlags(entry) {
168
168
  }
169
169
  if (typeof entry.readOnly === "boolean")
170
170
  out.readOnly = entry.readOnly;
171
+ if (typeof entry.grounding === "boolean")
172
+ out.grounding = entry.grounding;
171
173
  if (typeof entry.allowInPlanMode === "boolean") {
172
174
  out.allowInPlanMode = entry.allowInPlanMode;
173
175
  }
@@ -4890,18 +4890,41 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4890
4890
  error: "Recurring-job sweep reached the synchronous server instead of the durable background worker.",
4891
4891
  };
4892
4892
  }
4893
+ // Stale reaping runs FIRST and site-wide, before the open-ended job
4894
+ // sweep can spend the platform wall. It is the durable driver the
4895
+ // in-process fast sweep below cannot be on serverless: that timer is
4896
+ // off wherever `shouldDisableInProcessSweeps` is on — i.e. every
4897
+ // production Lambda — and nothing replaced it, so a claimed run
4898
+ // whose producer died was only reaped when an unrelated request path
4899
+ // happened to look (prod: 1,216 runs, 12% of all runs, sitting
4900
+ // "running" for up to 59 minutes against a 15s window).
4901
+ //
4902
+ // One reap per site-tick instead of one per warm container is also
4903
+ // the point: the per-container timers are what issued 237k queries
4904
+ // in two minutes and earned that kill switch. `reapAllStaleRuns`
4905
+ // short-circuits on `hasRunningRuns()` (negative-cached), so an idle
4906
+ // app pays one probe.
4907
+ //
4908
+ // Reported, never swallowed, and never fatal to the job sweep: a
4909
+ // reap failure must not take recurring jobs down with it, and
4910
+ // `null` must stay distinguishable from "reaped nothing".
4911
+ const { reapAllStaleRuns } = await import("../agent/run-store.js");
4912
+ const staleRunsReaped = await reapAllStaleRuns().catch((error) => {
4913
+ console.error("[agent-chat] durable stale-run reap failed:", error);
4914
+ return null;
4915
+ });
4893
4916
  try {
4894
4917
  // Jobs may request MCP tools, and `getActions` is synchronous —
4895
4918
  // hydrate before the sweep so a serverless container that never
4896
4919
  // eagerly initialized still resolves them.
4897
4920
  await ensureMcpInitialized();
4898
4921
  await processRecurringJobs(schedulerDeps);
4899
- return { ok: true };
4922
+ return { ok: true, staleRunsReaped };
4900
4923
  }
4901
4924
  catch (error) {
4902
4925
  console.error("[recurring-jobs] Sweep route failed:", error);
4903
4926
  setResponseStatus(event, 500);
4904
- return { error: "Recurring-job sweep failed" };
4927
+ return { error: "Recurring-job sweep failed", staleRunsReaped };
4905
4928
  }
4906
4929
  }));
4907
4930
  if (disableRecurringJobsRuntime) {
@@ -5139,7 +5162,16 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5139
5162
  // against a 45s window). `reapAllStaleRuns` is per-row,
5140
5163
  // idempotent, re-checks staleness at UPDATE time and honours
5141
5164
  // the in-flight grace, so it is safe on this cadence.
5142
- await reapAllStaleRuns().catch(() => { });
5165
+ //
5166
+ // This timer is the driver only where it actually runs — a
5167
+ // long-lived Node host. Wherever `sweepsDisabled` turns it off
5168
+ // (every production serverless function) the signed
5169
+ // RECURRING_JOBS_SWEEP_PATH route above owns the same reap,
5170
+ // driven by the platform scheduler. The two never both fire on
5171
+ // one host, which is why neither needs to coordinate.
5172
+ await reapAllStaleRuns().catch((error) => {
5173
+ console.error("[agent-chat] in-process stale-run reap failed:", error);
5174
+ });
5143
5175
  let rows;
5144
5176
  try {
5145
5177
  rows = await listUnclaimedBackgroundRunRows();
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
26
26
  expiresAt?: undefined;
27
27
  ttlSeconds?: undefined;
28
28
  } | {
29
- error?: undefined;
30
29
  token: string;
31
30
  expiresAt: string;
32
31
  ttlSeconds: number;
32
+ error?: undefined;
33
33
  }>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.153.4",
3
+ "version": "0.153.6",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {