@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
package/dist/action.js CHANGED
@@ -164,6 +164,9 @@ export function defineAction(options) {
164
164
  : {}),
165
165
  ...(typeof agentTool === "boolean" ? { agentTool } : {}),
166
166
  ...(typeof readOnly === "boolean" ? { readOnly } : {}),
167
+ ...(typeof options.grounding === "boolean"
168
+ ? { grounding: options.grounding }
169
+ : {}),
167
170
  ...(typeof options.allowInPlanMode === "boolean"
168
171
  ? { allowInPlanMode: options.allowInPlanMode }
169
172
  : {}),
@@ -12,9 +12,33 @@ export interface PriorTurnToolCallSummary {
12
12
  * `PriorTurnToolCallSummary` for why this is a local shape, not an import. */
13
13
  export interface PriorTurnToolResultSummary {
14
14
  name: string;
15
+ /**
16
+ * Input of the `tool_start` this result was matched to, so the caller can
17
+ * rebuild the same `(tool, arguments)` breaker key its live counters use.
18
+ * Legacy `tool_done` events carry no input; those keep the positional
19
+ * FIFO-per-tool pairing documented in `tool-call-journal.ts`, so this is
20
+ * absent only when neither event carried one.
21
+ */
22
+ input?: unknown;
15
23
  content: string;
16
24
  isError: boolean;
17
25
  }
26
+ /**
27
+ * Outcome of reading the per-turn ledger. `unreadable` is deliberately NOT the
28
+ * same value as a turn with no history: the repetition ledger, the read-only
29
+ * result cache and the write-replay hard block are all seeded from this read,
30
+ * so a swallowed ledger failure silently restores the per-chunk ceilings those
31
+ * mechanisms exist to remove.
32
+ */
33
+ export type PriorTurnToolCallJournalRead = {
34
+ status: "read";
35
+ toolCallJournal: ToolCallJournal | null;
36
+ priorToolCalls: PriorTurnToolCallSummary[];
37
+ priorToolResults: PriorTurnToolResultSummary[];
38
+ } | {
39
+ status: "unreadable";
40
+ error: string;
41
+ };
18
42
  /**
19
43
  * Tool-call journal hard-block (resume safety). Snapshot the per-turn journal
20
44
  * ONCE here, before any tool runs in this chunk, so it reflects only PRIOR
@@ -25,9 +49,8 @@ export interface PriorTurnToolResultSummary {
25
49
  *
26
50
  * Loaded eagerly (not lazily mid-loop) so the current chunk's own
27
51
  * asynchronously-persisted tool_done events can never leak in and make a
28
- * same-chunk call wrongly short-circuit. Best-effort: any ledger failure
29
- * leaves the journal empty and all calls run normally. Fresh first-turn calls
30
- * see an empty journal and are unaffected.
52
+ * same-chunk call wrongly short-circuit. Fresh first-turn calls see an empty
53
+ * journal and are unaffected.
31
54
  *
32
55
  * Also returns the prior chunks' tool calls/results so the caller can seed
33
56
  * its own `toolCallHistory` / `toolResultHistory` accumulators — final
@@ -35,11 +58,5 @@ export interface PriorTurnToolResultSummary {
35
58
  * tools executed after the latest handoff. Otherwise a guard can reject a
36
59
  * grounded answer (or a successfully-created artifact) after the
37
60
  * evidence-producing query completed in a predecessor run.
38
- *
39
- * Moved verbatim out of `runAgentLoop`'s per-turn setup — behavior unchanged.
40
61
  */
41
- export declare function loadPriorTurnToolCallJournal(threadId: string | undefined, turnId?: string): Promise<{
42
- toolCallJournal: ToolCallJournal | null;
43
- priorToolCalls: PriorTurnToolCallSummary[];
44
- priorToolResults: PriorTurnToolResultSummary[];
45
- }>;
62
+ export declare function loadPriorTurnToolCallJournal(threadId: string | undefined, turnId?: string): Promise<PriorTurnToolCallJournalRead>;
@@ -1,5 +1,22 @@
1
1
  import { getCurrentTurnEventsForThread } from "../run-store.js";
2
2
  import { classifyToolCallJournal, } from "../tool-call-journal.js";
3
+ const LEDGER_READ_RETRY_MS = 250;
4
+ /**
5
+ * `unreadable` ends the turn with a stop the user sees, so a single pool
6
+ * timeout or connection blip must not produce one. One retry, because the
7
+ * failures worth surviving are transient and the caller is holding the whole
8
+ * turn open while we wait.
9
+ */
10
+ async function readCurrentTurnEventsWithRetry(threadId, turnId) {
11
+ try {
12
+ return await getCurrentTurnEventsForThread(threadId, turnId);
13
+ }
14
+ catch (err) {
15
+ console.warn(`[tool-call-journal] per-turn ledger read failed for thread ${threadId}, retrying once: ${err instanceof Error ? err.message : String(err)}`);
16
+ await new Promise((resolve) => setTimeout(resolve, LEDGER_READ_RETRY_MS));
17
+ return await getCurrentTurnEventsForThread(threadId, turnId);
18
+ }
19
+ }
3
20
  /**
4
21
  * Tool-call journal hard-block (resume safety). Snapshot the per-turn journal
5
22
  * ONCE here, before any tool runs in this chunk, so it reflects only PRIOR
@@ -10,9 +27,8 @@ import { classifyToolCallJournal, } from "../tool-call-journal.js";
10
27
  *
11
28
  * Loaded eagerly (not lazily mid-loop) so the current chunk's own
12
29
  * asynchronously-persisted tool_done events can never leak in and make a
13
- * same-chunk call wrongly short-circuit. Best-effort: any ledger failure
14
- * leaves the journal empty and all calls run normally. Fresh first-turn calls
15
- * see an empty journal and are unaffected.
30
+ * same-chunk call wrongly short-circuit. Fresh first-turn calls see an empty
31
+ * journal and are unaffected.
16
32
  *
17
33
  * Also returns the prior chunks' tool calls/results so the caller can seed
18
34
  * its own `toolCallHistory` / `toolResultHistory` accumulators — final
@@ -20,40 +36,55 @@ import { classifyToolCallJournal, } from "../tool-call-journal.js";
20
36
  * tools executed after the latest handoff. Otherwise a guard can reject a
21
37
  * grounded answer (or a successfully-created artifact) after the
22
38
  * evidence-producing query completed in a predecessor run.
23
- *
24
- * Moved verbatim out of `runAgentLoop`'s per-turn setup — behavior unchanged.
25
39
  */
26
40
  export async function loadPriorTurnToolCallJournal(threadId, turnId) {
27
- const priorToolCalls = [];
28
- const priorToolResults = [];
29
- let toolCallJournal = null;
30
41
  if (!threadId) {
31
- return { toolCallJournal, priorToolCalls, priorToolResults };
42
+ // No thread means no durable ledger exists for this turn at all — a true
43
+ // "no prior history", not a read that failed.
44
+ return {
45
+ status: "read",
46
+ toolCallJournal: null,
47
+ priorToolCalls: [],
48
+ priorToolResults: [],
49
+ };
32
50
  }
51
+ let priorEvents;
33
52
  try {
34
- const priorEvents = await getCurrentTurnEventsForThread(threadId, turnId);
35
- if (priorEvents.length > 0) {
36
- for (const event of priorEvents) {
37
- if (event.type === "tool_start") {
38
- priorToolCalls.push({
39
- name: event.tool,
40
- input: event.input,
41
- });
42
- }
43
- else if (event.type === "tool_done") {
44
- priorToolResults.push({
45
- name: event.tool,
46
- content: event.result,
47
- isError: event.isError === true,
48
- });
49
- }
50
- }
51
- toolCallJournal = classifyToolCallJournal(priorEvents);
52
- }
53
+ priorEvents = await readCurrentTurnEventsWithRetry(threadId, turnId);
53
54
  }
54
- catch {
55
- // Journal is a hardening layer, never a gate — a failed ledger read just
56
- // means no hard-block this turn.
55
+ catch (err) {
56
+ const error = err instanceof Error ? err.message : String(err);
57
+ console.warn(`[tool-call-journal] per-turn ledger read failed for thread ${threadId}: ${error}`);
58
+ return { status: "unreadable", error };
59
+ }
60
+ const priorToolCalls = [];
61
+ const priorToolResults = [];
62
+ // Open `tool_start` inputs per tool, so a legacy `tool_done` with no input of
63
+ // its own can still be attributed to the arguments it ran with.
64
+ const openInputsByTool = new Map();
65
+ for (const event of priorEvents) {
66
+ if (event.type === "tool_start") {
67
+ priorToolCalls.push({ name: event.tool, input: event.input });
68
+ const queue = openInputsByTool.get(event.tool);
69
+ if (queue)
70
+ queue.push(event.input);
71
+ else
72
+ openInputsByTool.set(event.tool, [event.input]);
73
+ }
74
+ else if (event.type === "tool_done") {
75
+ const fifoInput = openInputsByTool.get(event.tool)?.shift();
76
+ priorToolResults.push({
77
+ name: event.tool,
78
+ input: event.input ?? fifoInput,
79
+ content: event.result,
80
+ isError: event.isError === true,
81
+ });
82
+ }
57
83
  }
58
- return { toolCallJournal, priorToolCalls, priorToolResults };
84
+ return {
85
+ status: "read",
86
+ toolCallJournal: priorEvents.length > 0 ? classifyToolCallJournal(priorEvents) : null,
87
+ priorToolCalls,
88
+ priorToolResults,
89
+ };
59
90
  }
@@ -183,6 +183,8 @@ export interface ActionEntry {
183
183
  /** If true, completion does NOT trigger a screen-refresh change event.
184
184
  * Set automatically by `defineAction` when `http.method === "GET"`. */
185
185
  readOnly?: boolean;
186
+ /** If true, a successful call returns evidence retrieved from a live source. */
187
+ grounding?: boolean;
186
188
  /** False keeps a read-only tool available in Act mode but hides/blocks it in
187
189
  * Plan mode. Use for tools that perform substantive work even without
188
190
  * mutating state. */
@@ -613,6 +615,21 @@ export declare const MAX_SAME_ERROR_ACROSS_ARGUMENTS = 6;
613
615
  * legitimate re-check after a write.
614
616
  */
615
617
  export declare const MAX_IDENTICAL_TOOL_CALLS = 8;
618
+ /**
619
+ * A stop that ends the turn from inside the tool loop.
620
+ *
621
+ * `message` is the last thing the user reads, so it names the remedy in plain
622
+ * words and does not quote a raw provider/tool error; the raw error goes in
623
+ * `details`. Both retry sniffers now honour the `recoverable: false` these
624
+ * stops are sent with, so a stop that happens to say "timeout" is no longer
625
+ * auto-continued — but the prose still has one reader who cannot ignore it,
626
+ * and a pasted stack trace is not a remedy.
627
+ */
628
+ export interface TerminalActionStop {
629
+ message: string;
630
+ errorCode?: string;
631
+ details?: string;
632
+ }
616
633
  /**
617
634
  * Convert ActionEntry registry to EngineTool array.
618
635
  */
@@ -687,9 +704,31 @@ export declare function findApprovedStructuredToolCall(history: AgentChatStructu
687
704
  input: unknown;
688
705
  callId: string;
689
706
  } | undefined;
707
+ /**
708
+ * Tool errors the model has no way to clear: the missing thing lives outside
709
+ * the turn (a credential, a role grant, a connected account, a runtime, the
710
+ * user's own approval). Every retry costs a full round-trip carrying the whole
711
+ * transcript and lands on the identical error, so these stop on the FIRST
712
+ * occurrence rather than after `MAX_SAME_ERROR_ACROSS_ARGUMENTS` of them.
713
+ *
714
+ * The distinction is the one `stopForBigQueryNotConfigured` draws in
715
+ * templates/analytics: a *configuration* gap is permanent for this turn, a
716
+ * *query* failure is not. Anything the model can act on — a stale read to
717
+ * rebase, a bad argument, a full quota it can free, a wrong dataset name, a
718
+ * statement timeout — must stay out of this list and keep its retries.
719
+ * Precision over recall: a wrong match kills a turn that would have succeeded,
720
+ * which is worse than one more retry.
721
+ */
722
+ export declare function permanentPreconditionRemedy(message: string): string | null;
723
+ /**
724
+ * Deliberately carries no running call count. This decline is recorded as a
725
+ * tool error, and the breakers key on that text: a message that reports its own
726
+ * tally ("already made 13 call(s)") mints a fresh key on every decline, so the
727
+ * decline that exists to stop a spiral becomes the one thing nothing can count.
728
+ * The fixed threshold below says the same thing without varying.
729
+ */
690
730
  export declare function repeatedSourceSweepGuardMessage(opts: {
691
731
  toolName: string;
692
- priorCalls: number;
693
732
  threshold?: number;
694
733
  scope?: "tool" | "aggregate";
695
734
  }): string;