@agent-native/core 0.131.9 → 0.132.0

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 (292) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +99 -0
  3. package/corpus/core/docs/content/durable-background-runs.mdx +15 -6
  4. package/corpus/core/docs/design/durable-agent-runs.md +15 -11
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/a2a/activity.ts +127 -10
  7. package/corpus/core/src/a2a/index.ts +3 -0
  8. package/corpus/core/src/agent/durable-background.ts +38 -28
  9. package/corpus/core/src/agent/harness/background.ts +12 -2
  10. package/corpus/core/src/agent/production-agent.ts +18 -15
  11. package/corpus/core/src/agent/run-store.ts +45 -3
  12. package/corpus/core/src/application-state/handlers.ts +45 -0
  13. package/corpus/core/src/application-state/index.ts +3 -0
  14. package/corpus/core/src/application-state/store.ts +28 -11
  15. package/corpus/core/src/audit/redact.ts +104 -18
  16. package/corpus/core/src/client/AgentPanel.tsx +2 -7
  17. package/corpus/core/src/client/MultiTabAssistantChat.tsx +3 -0
  18. package/corpus/core/src/client/RunStuckBanner.tsx +29 -6
  19. package/corpus/core/src/client/agent-chat.ts +4 -9
  20. package/corpus/core/src/client/application-state.ts +115 -12
  21. package/corpus/core/src/client/dynamic-suggestions.ts +4 -12
  22. package/corpus/core/src/client/guided-questions.tsx +12 -23
  23. package/corpus/core/src/db/client.ts +148 -28
  24. package/corpus/core/src/db/create-get-db.ts +39 -6
  25. package/corpus/core/src/db/runtime-diagnostics.ts +41 -6
  26. package/corpus/core/src/deploy/build.ts +26 -33
  27. package/corpus/core/src/feature-flags/store.ts +10 -5
  28. package/corpus/core/src/integrations/a2a-continuations-store.ts +11 -0
  29. package/corpus/core/src/integrations/config-store.ts +13 -0
  30. package/corpus/core/src/integrations/google-docs-poller.ts +26 -2
  31. package/corpus/core/src/mcp-client/routes.ts +33 -2
  32. package/corpus/core/src/onboarding/plugin.ts +31 -25
  33. package/corpus/core/src/org/accept-pending.ts +2 -0
  34. package/corpus/core/src/org/auto-join-domain.ts +2 -0
  35. package/corpus/core/src/org/context.ts +35 -10
  36. package/corpus/core/src/org/handlers.ts +6 -0
  37. package/corpus/core/src/org/request-org-cache.ts +71 -0
  38. package/corpus/core/src/resources/store.ts +10 -9
  39. package/corpus/core/src/scripts/runner.ts +6 -3
  40. package/corpus/core/src/secrets/storage.ts +97 -5
  41. package/corpus/core/src/server/action-change.ts +33 -0
  42. package/corpus/core/src/server/action-routes.ts +11 -9
  43. package/corpus/core/src/server/agent-teams.ts +10 -2
  44. package/corpus/core/src/server/better-auth-instance.ts +39 -12
  45. package/corpus/core/src/server/core-routes-plugin.ts +19 -2
  46. package/corpus/core/src/server/credential-provider.ts +57 -14
  47. package/corpus/core/src/server/http-response-telemetry.ts +1 -0
  48. package/corpus/core/src/server/poll.ts +95 -57
  49. package/corpus/core/src/server/voice-providers-status.ts +19 -4
  50. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -0
  51. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1 -1
  52. package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +299 -0
  53. package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +34 -0
  54. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +82 -0
  55. package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +2 -2
  56. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +40 -34
  57. package/corpus/templates/analytics/app/hooks/use-user-pref.ts +3 -3
  58. package/corpus/templates/analytics/app/i18n-data.ts +40 -0
  59. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +18 -10
  60. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +14 -0
  61. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +1 -0
  62. package/corpus/templates/analytics/app/routes/chart.tsx +3 -0
  63. package/corpus/templates/analytics/changelog/2026-07-30-analytics-dashboards-now-expose-native-funnel-heatmap-callou.md +6 -0
  64. package/corpus/templates/analytics/changelog/2026-07-30-analytics-now-ships-reusable-native-v2-dashboard-manifests-w.md +6 -0
  65. package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +81 -1
  66. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +457 -0
  67. package/corpus/templates/analytics/server/lib/report-chart-svg.ts +73 -2
  68. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
  69. package/corpus/templates/analytics/shared/dashboard-funnel.ts +83 -0
  70. package/corpus/templates/content/changelog/2026-07-30-long-running-delegated-requests-now-continue-reliably.md +6 -0
  71. package/corpus/templates/content/netlify.toml +3 -0
  72. package/corpus/templates/content/server/plugins/agent-chat.ts +1 -0
  73. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -1
  74. package/corpus/templates/slides/actions/patch-deck.ts +25 -1
  75. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +17 -4
  76. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +9 -1
  77. package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
  78. package/corpus/templates/slides/app/context/DeckContext.tsx +11 -3
  79. package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +39 -11
  80. package/corpus/templates/slides/app/pages/Index.tsx +2 -2
  81. package/corpus/templates/slides/changelog/2026-07-30-slide-previews-keep-their-aspect-ratio-isolate-embedded-styl.md +6 -0
  82. package/corpus/templates/slides/changelog/2026-07-30-slides-no-longer-lose-decks-while-organization-access-is-loa.md +6 -0
  83. package/corpus/toolkit/CHANGELOG.md +8 -0
  84. package/corpus/toolkit/package.json +1 -1
  85. package/corpus/toolkit/src/composer/runtime-adapters.tsx +16 -11
  86. package/dist/a2a/activity.d.ts +22 -4
  87. package/dist/a2a/activity.d.ts.map +1 -1
  88. package/dist/a2a/activity.js +97 -11
  89. package/dist/a2a/activity.js.map +1 -1
  90. package/dist/a2a/index.d.ts +1 -1
  91. package/dist/a2a/index.d.ts.map +1 -1
  92. package/dist/a2a/index.js +1 -1
  93. package/dist/a2a/index.js.map +1 -1
  94. package/dist/agent/durable-background.d.ts +13 -8
  95. package/dist/agent/durable-background.d.ts.map +1 -1
  96. package/dist/agent/durable-background.js +36 -28
  97. package/dist/agent/durable-background.js.map +1 -1
  98. package/dist/agent/harness/background.d.ts.map +1 -1
  99. package/dist/agent/harness/background.js +12 -2
  100. package/dist/agent/harness/background.js.map +1 -1
  101. package/dist/agent/production-agent.d.ts.map +1 -1
  102. package/dist/agent/production-agent.js +18 -15
  103. package/dist/agent/production-agent.js.map +1 -1
  104. package/dist/agent/run-store.d.ts +2 -0
  105. package/dist/agent/run-store.d.ts.map +1 -1
  106. package/dist/agent/run-store.js +44 -3
  107. package/dist/agent/run-store.js.map +1 -1
  108. package/dist/application-state/handlers.d.ts +15 -0
  109. package/dist/application-state/handlers.d.ts.map +1 -1
  110. package/dist/application-state/handlers.js +42 -2
  111. package/dist/application-state/handlers.js.map +1 -1
  112. package/dist/application-state/index.d.ts +2 -2
  113. package/dist/application-state/index.d.ts.map +1 -1
  114. package/dist/application-state/index.js +2 -2
  115. package/dist/application-state/index.js.map +1 -1
  116. package/dist/application-state/store.d.ts +11 -0
  117. package/dist/application-state/store.d.ts.map +1 -1
  118. package/dist/application-state/store.js +23 -10
  119. package/dist/application-state/store.js.map +1 -1
  120. package/dist/audit/redact.d.ts +25 -2
  121. package/dist/audit/redact.d.ts.map +1 -1
  122. package/dist/audit/redact.js +85 -21
  123. package/dist/audit/redact.js.map +1 -1
  124. package/dist/client/AgentPanel.d.ts.map +1 -1
  125. package/dist/client/AgentPanel.js +2 -7
  126. package/dist/client/AgentPanel.js.map +1 -1
  127. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  128. package/dist/client/MultiTabAssistantChat.js +1 -1
  129. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  130. package/dist/client/RunStuckBanner.d.ts +11 -1
  131. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  132. package/dist/client/RunStuckBanner.js +20 -7
  133. package/dist/client/RunStuckBanner.js.map +1 -1
  134. package/dist/client/agent-chat.d.ts.map +1 -1
  135. package/dist/client/agent-chat.js +4 -6
  136. package/dist/client/agent-chat.js.map +1 -1
  137. package/dist/client/application-state.d.ts +11 -0
  138. package/dist/client/application-state.d.ts.map +1 -1
  139. package/dist/client/application-state.js +87 -9
  140. package/dist/client/application-state.js.map +1 -1
  141. package/dist/client/dynamic-suggestions.d.ts.map +1 -1
  142. package/dist/client/dynamic-suggestions.js +4 -13
  143. package/dist/client/dynamic-suggestions.js.map +1 -1
  144. package/dist/client/guided-questions.d.ts.map +1 -1
  145. package/dist/client/guided-questions.js +6 -22
  146. package/dist/client/guided-questions.js.map +1 -1
  147. package/dist/collab/awareness.d.ts +2 -2
  148. package/dist/collab/awareness.d.ts.map +1 -1
  149. package/dist/db/client.d.ts +57 -10
  150. package/dist/db/client.d.ts.map +1 -1
  151. package/dist/db/client.js +122 -31
  152. package/dist/db/client.js.map +1 -1
  153. package/dist/db/create-get-db.d.ts.map +1 -1
  154. package/dist/db/create-get-db.js +31 -7
  155. package/dist/db/create-get-db.js.map +1 -1
  156. package/dist/db/runtime-diagnostics.d.ts +1 -0
  157. package/dist/db/runtime-diagnostics.d.ts.map +1 -1
  158. package/dist/db/runtime-diagnostics.js +31 -6
  159. package/dist/db/runtime-diagnostics.js.map +1 -1
  160. package/dist/deploy/build.d.ts +5 -20
  161. package/dist/deploy/build.d.ts.map +1 -1
  162. package/dist/deploy/build.js +18 -30
  163. package/dist/deploy/build.js.map +1 -1
  164. package/dist/feature-flags/store.d.ts.map +1 -1
  165. package/dist/feature-flags/store.js +10 -5
  166. package/dist/feature-flags/store.js.map +1 -1
  167. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  168. package/dist/integrations/a2a-continuations-store.js +12 -0
  169. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  170. package/dist/integrations/config-store.d.ts +1 -0
  171. package/dist/integrations/config-store.d.ts.map +1 -1
  172. package/dist/integrations/config-store.js +11 -0
  173. package/dist/integrations/config-store.js.map +1 -1
  174. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  175. package/dist/integrations/google-docs-poller.js +19 -2
  176. package/dist/integrations/google-docs-poller.js.map +1 -1
  177. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  178. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
  179. package/dist/mcp-client/routes.d.ts.map +1 -1
  180. package/dist/mcp-client/routes.js +30 -2
  181. package/dist/mcp-client/routes.js.map +1 -1
  182. package/dist/notifications/routes.d.ts +6 -6
  183. package/dist/observability/routes.d.ts +3 -3
  184. package/dist/onboarding/plugin.d.ts.map +1 -1
  185. package/dist/onboarding/plugin.js +12 -8
  186. package/dist/onboarding/plugin.js.map +1 -1
  187. package/dist/org/accept-pending.d.ts.map +1 -1
  188. package/dist/org/accept-pending.js +2 -0
  189. package/dist/org/accept-pending.js.map +1 -1
  190. package/dist/org/auto-join-domain.d.ts.map +1 -1
  191. package/dist/org/auto-join-domain.js +2 -0
  192. package/dist/org/auto-join-domain.js.map +1 -1
  193. package/dist/org/context.d.ts.map +1 -1
  194. package/dist/org/context.js +29 -9
  195. package/dist/org/context.js.map +1 -1
  196. package/dist/org/handlers.d.ts.map +1 -1
  197. package/dist/org/handlers.js +5 -0
  198. package/dist/org/handlers.js.map +1 -1
  199. package/dist/org/request-org-cache.d.ts +16 -0
  200. package/dist/org/request-org-cache.d.ts.map +1 -0
  201. package/dist/org/request-org-cache.js +62 -0
  202. package/dist/org/request-org-cache.js.map +1 -0
  203. package/dist/progress/routes.d.ts +1 -1
  204. package/dist/resources/handlers.d.ts +1 -1
  205. package/dist/resources/store.d.ts.map +1 -1
  206. package/dist/resources/store.js +11 -9
  207. package/dist/resources/store.js.map +1 -1
  208. package/dist/scripts/runner.d.ts.map +1 -1
  209. package/dist/scripts/runner.js +3 -3
  210. package/dist/scripts/runner.js.map +1 -1
  211. package/dist/secrets/storage.d.ts.map +1 -1
  212. package/dist/secrets/storage.js +82 -5
  213. package/dist/secrets/storage.js.map +1 -1
  214. package/dist/server/action-change.d.ts +20 -0
  215. package/dist/server/action-change.d.ts.map +1 -1
  216. package/dist/server/action-change.js +29 -0
  217. package/dist/server/action-change.js.map +1 -1
  218. package/dist/server/action-routes.d.ts.map +1 -1
  219. package/dist/server/action-routes.js +7 -8
  220. package/dist/server/action-routes.js.map +1 -1
  221. package/dist/server/agent-teams.d.ts.map +1 -1
  222. package/dist/server/agent-teams.js +10 -2
  223. package/dist/server/agent-teams.js.map +1 -1
  224. package/dist/server/better-auth-instance.d.ts.map +1 -1
  225. package/dist/server/better-auth-instance.js +31 -14
  226. package/dist/server/better-auth-instance.js.map +1 -1
  227. package/dist/server/core-routes-plugin.d.ts +1 -0
  228. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  229. package/dist/server/core-routes-plugin.js +18 -4
  230. package/dist/server/core-routes-plugin.js.map +1 -1
  231. package/dist/server/credential-provider.d.ts +16 -0
  232. package/dist/server/credential-provider.d.ts.map +1 -1
  233. package/dist/server/credential-provider.js +49 -13
  234. package/dist/server/credential-provider.js.map +1 -1
  235. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  236. package/dist/server/http-response-telemetry.js +1 -0
  237. package/dist/server/http-response-telemetry.js.map +1 -1
  238. package/dist/server/poll.d.ts +6 -0
  239. package/dist/server/poll.d.ts.map +1 -1
  240. package/dist/server/poll.js +84 -47
  241. package/dist/server/poll.js.map +1 -1
  242. package/dist/server/transcribe-voice.d.ts +1 -1
  243. package/dist/server/voice-providers-status.d.ts.map +1 -1
  244. package/dist/server/voice-providers-status.js +12 -3
  245. package/dist/server/voice-providers-status.js.map +1 -1
  246. package/docs/content/durable-background-runs.mdx +15 -6
  247. package/docs/design/durable-agent-runs.md +15 -11
  248. package/package.json +2 -2
  249. package/src/a2a/activity.ts +127 -10
  250. package/src/a2a/index.ts +3 -0
  251. package/src/agent/durable-background.ts +38 -28
  252. package/src/agent/harness/background.ts +12 -2
  253. package/src/agent/production-agent.ts +18 -15
  254. package/src/agent/run-store.ts +45 -3
  255. package/src/application-state/handlers.ts +45 -0
  256. package/src/application-state/index.ts +3 -0
  257. package/src/application-state/store.ts +28 -11
  258. package/src/audit/redact.ts +104 -18
  259. package/src/client/AgentPanel.tsx +2 -7
  260. package/src/client/MultiTabAssistantChat.tsx +3 -0
  261. package/src/client/RunStuckBanner.tsx +29 -6
  262. package/src/client/agent-chat.ts +4 -9
  263. package/src/client/application-state.ts +115 -12
  264. package/src/client/dynamic-suggestions.ts +4 -12
  265. package/src/client/guided-questions.tsx +12 -23
  266. package/src/db/client.ts +148 -28
  267. package/src/db/create-get-db.ts +39 -6
  268. package/src/db/runtime-diagnostics.ts +41 -6
  269. package/src/deploy/build.ts +26 -33
  270. package/src/feature-flags/store.ts +10 -5
  271. package/src/integrations/a2a-continuations-store.ts +11 -0
  272. package/src/integrations/config-store.ts +13 -0
  273. package/src/integrations/google-docs-poller.ts +26 -2
  274. package/src/mcp-client/routes.ts +33 -2
  275. package/src/onboarding/plugin.ts +31 -25
  276. package/src/org/accept-pending.ts +2 -0
  277. package/src/org/auto-join-domain.ts +2 -0
  278. package/src/org/context.ts +35 -10
  279. package/src/org/handlers.ts +6 -0
  280. package/src/org/request-org-cache.ts +71 -0
  281. package/src/resources/store.ts +10 -9
  282. package/src/scripts/runner.ts +6 -3
  283. package/src/secrets/storage.ts +97 -5
  284. package/src/server/action-change.ts +33 -0
  285. package/src/server/action-routes.ts +11 -9
  286. package/src/server/agent-teams.ts +10 -2
  287. package/src/server/better-auth-instance.ts +39 -12
  288. package/src/server/core-routes-plugin.ts +19 -2
  289. package/src/server/credential-provider.ts +57 -14
  290. package/src/server/http-response-telemetry.ts +1 -0
  291. package/src/server/poll.ts +95 -57
  292. package/src/server/voice-providers-status.ts +19 -4
@@ -1,13 +1,23 @@
1
1
  import { sanitizeToolErrorText } from "../agent/tool-error-redaction.js";
2
+ import { redactArgsToJson, redactTextToSummary } from "../audit/redact.js";
2
3
  export const A2A_AGENT_ACTIVITY_KIND = "agent-native/agent-activity";
3
4
  export const A2A_AGENT_ACTIVITY_VERSION = 1;
4
5
  export const MAX_A2A_ACTIVITY_REASONING_CHARS = 32_768;
5
6
  export const MAX_A2A_ACTIVITY_RESPONSE_CHARS = 32_768;
6
- export const MAX_A2A_ACTIVITY_TOTAL_CHARS = 98_304;
7
7
  export const MAX_A2A_ACTIVITY_REASONING_SEGMENTS = 128;
8
8
  export const MAX_A2A_ACTIVITY_TOOL_CALLS = 64;
9
9
  export const MAX_A2A_ACTIVITY_TOOL_NAME_CHARS = 96;
10
10
  export const MAX_A2A_ACTIVITY_TOOL_ID_CHARS = 128;
11
+ export const MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS = 1024;
12
+ export const MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS = 512;
13
+ /**
14
+ * Shared ceiling for every recorded tool input/result across the snapshot. The
15
+ * per-call caps alone allow 64 × 1536 chars, which would push a busy run past
16
+ * `MAX_A2A_ACTIVITY_TOTAL_CHARS` and make `parseA2AAgentActivityPart` reject
17
+ * the whole snapshot — trading missing arguments for a missing trace.
18
+ */
19
+ export const MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS = 16_384;
20
+ export const MAX_A2A_ACTIVITY_TOTAL_CHARS = 98_304 + MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS;
11
21
  export function createA2AAgentActivityState(startedAt = Date.now()) {
12
22
  return {
13
23
  sequence: 0,
@@ -20,9 +30,11 @@ export function createA2AAgentActivityState(startedAt = Date.now()) {
20
30
  };
21
31
  }
22
32
  /**
23
- * Converts internal loop events into a bounded activity snapshot. It carries
24
- * only reasoning text already emitted to the local chat, never tool inputs or
25
- * results.
33
+ * Converts internal loop events into a bounded activity snapshot. Reasoning
34
+ * text is carried verbatim (it was already emitted to the local chat); tool
35
+ * arguments and results are carried only in redacted, size-capped form so the
36
+ * delegated run stays diagnosable without the snapshot becoming a secondary
37
+ * store of secrets or payloads.
26
38
  */
27
39
  export function applyA2AAgentActivityEvent(state, event, updatedAt = Date.now()) {
28
40
  const next = { ...state, updatedAt: normalizeTimestamp(updatedAt) };
@@ -33,14 +45,19 @@ export function applyA2AAgentActivityEvent(state, event, updatedAt = Date.now())
33
45
  next.reasoning = appendBoundedSegment(next.reasoning, event.text, MAX_A2A_ACTIVITY_REASONING_CHARS, next.toolCalls.length);
34
46
  changed = true;
35
47
  break;
36
- case "tool_start":
48
+ case "tool_start": {
37
49
  next.activePhase = "tool";
38
- next.toolCalls = appendToolCall(next.toolCalls, toolFromEvent(event));
50
+ const input = captureToolInput(event.input, remainingPayloadBudget(next.toolCalls));
51
+ next.toolCalls = appendToolCall(next.toolCalls, {
52
+ ...toolFromEvent(event),
53
+ ...(input ? { input } : {}),
54
+ });
39
55
  changed = true;
40
56
  break;
57
+ }
41
58
  case "tool_done":
42
59
  next.activePhase = "tool";
43
- next.toolCalls = settleToolCall(next.toolCalls, toolFromEvent(event));
60
+ next.toolCalls = settleToolCall(next.toolCalls, toolFromEvent(event), event);
44
61
  changed = true;
45
62
  break;
46
63
  case "text":
@@ -123,6 +140,38 @@ function toolFromEvent(event) {
123
140
  : "completed",
124
141
  };
125
142
  }
143
+ function payloadChars(tool) {
144
+ return (tool.input?.length ?? 0) + (tool.result?.length ?? 0);
145
+ }
146
+ function remainingPayloadBudget(current, excludeIndex = -1) {
147
+ const used = current.reduce((total, tool, index) => index === excludeIndex ? total : total + payloadChars(tool), 0);
148
+ return Math.max(0, MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS - used);
149
+ }
150
+ /**
151
+ * Redacted, capped JSON of the arguments, or `undefined` when there is nothing
152
+ * to record or the shared budget cannot fit a whole (still-parseable) capture.
153
+ * A partial JSON string would be worse than none — the reader could not tell a
154
+ * clipped object from a different one.
155
+ */
156
+ function captureToolInput(input, budget) {
157
+ const cap = Math.min(MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS, budget);
158
+ if (cap < MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS / 8)
159
+ return undefined;
160
+ const json = redactArgsToJson(input, { maxJson: cap, maxString: 256 });
161
+ // JSON.stringify escapes control characters, so the result is already safe
162
+ // for the snapshot without a `sanitizeText` pass — which would rewrite
163
+ // `"token":"[redacted]"` into unparseable JSON.
164
+ if (!json || json === "{}" || json.length > cap)
165
+ return undefined;
166
+ return json;
167
+ }
168
+ function captureToolResult(result, budget) {
169
+ const cap = Math.min(MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS, budget);
170
+ if (!result || cap <= 0)
171
+ return undefined;
172
+ const summary = redactTextToSummary(result, cap);
173
+ return summary ? sanitizeText(summary, cap) || undefined : undefined;
174
+ }
126
175
  function appendBoundedSegment(current, addition, maxChars, precedingToolCount) {
127
176
  const used = current.reduce((total, text) => total + text.length, 0);
128
177
  if (used >= maxChars ||
@@ -148,15 +197,34 @@ function appendToolCall(current, tool) {
148
197
  ? [...current, tool]
149
198
  : current;
150
199
  }
151
- function settleToolCall(current, tool) {
200
+ function settleToolCall(current, tool, event) {
152
201
  for (let index = current.length - 1; index >= 0; index -= 1) {
153
202
  const existing = current[index];
154
203
  if ((tool.id && tool.id === existing.id) ||
155
204
  (!tool.id && tool.name === existing.name)) {
156
- return current.map((value, itemIndex) => itemIndex === index ? tool : value);
205
+ // The matching `tool_start` already paid for its input; reuse it rather
206
+ // than re-capturing (and re-charging) the same arguments.
207
+ let budget = remainingPayloadBudget(current, index);
208
+ const input = existing.input ?? captureToolInput(event.input, budget) ?? undefined;
209
+ budget -= input?.length ?? 0;
210
+ const result = captureToolResult(event.result, budget);
211
+ const settled = {
212
+ ...tool,
213
+ ...(input ? { input } : {}),
214
+ ...(result ? { result } : {}),
215
+ };
216
+ return current.map((value, itemIndex) => itemIndex === index ? settled : value);
157
217
  }
158
218
  }
159
- return appendToolCall(current, tool);
219
+ let budget = remainingPayloadBudget(current);
220
+ const input = captureToolInput(event.input, budget);
221
+ budget -= input?.length ?? 0;
222
+ const result = captureToolResult(event.result, budget);
223
+ return appendToolCall(current, {
224
+ ...tool,
225
+ ...(input ? { input } : {}),
226
+ ...(result ? { result } : {}),
227
+ });
160
228
  }
161
229
  function sanitizeText(value, maxChars) {
162
230
  return sanitizeToolErrorText(value)
@@ -200,10 +268,26 @@ function isSafeToolCall(value) {
200
268
  if (!isRecord(value) || !isSafeToolName(value.name))
201
269
  return false;
202
270
  return ((value.id === undefined || isSafeToolId(value.id)) &&
271
+ (value.input === undefined ||
272
+ isSafeCapturedText(value.input, MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS)) &&
273
+ (value.result === undefined ||
274
+ isSafeCapturedText(value.result, MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS)) &&
203
275
  (value.status === "running" ||
204
276
  value.status === "completed" ||
205
277
  value.status === "failed"));
206
278
  }
279
+ /**
280
+ * Captured input/result are producer-side redacted strings. Unlike reasoning
281
+ * text they are NOT re-sanitized on read: `sanitizeToolErrorText` rewrites
282
+ * `"token":"…"` into unparseable JSON, so a round-trip equality check would
283
+ * reject every legitimate capture. Bound the length and reject raw control
284
+ * characters instead.
285
+ */
286
+ function isSafeCapturedText(value, maxChars) {
287
+ return (typeof value === "string" &&
288
+ value.length <= maxChars &&
289
+ !/[\u0000-\u0008\u000b-\u001f\u007f]/.test(value));
290
+ }
207
291
  function isSafeText(value, maxChars) {
208
292
  return (typeof value === "string" &&
209
293
  value.length <= maxChars &&
@@ -234,7 +318,9 @@ function activityCharacterCount(data) {
234
318
  return total;
235
319
  return (total +
236
320
  (typeof tool.name === "string" ? tool.name.length : 0) +
237
- (typeof tool.id === "string" ? tool.id.length : 0));
321
+ (typeof tool.id === "string" ? tool.id.length : 0) +
322
+ (typeof tool.input === "string" ? tool.input.length : 0) +
323
+ (typeof tool.result === "string" ? tool.result.length : 0));
238
324
  }, 0)
239
325
  : 0;
240
326
  return reasoning + response + tools;
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/a2a/activity.ts"],"names":[],"mappings":"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","sourcesContent":["import { sanitizeToolErrorText } from \"../agent/tool-error-redaction.js\";\nimport type { AgentChatEvent } from \"../agent/types.js\";\nimport type { DataPart, Part } from \"./types.js\";\n\nexport const A2A_AGENT_ACTIVITY_KIND = \"agent-native/agent-activity\";\nexport const A2A_AGENT_ACTIVITY_VERSION = 1;\nexport const MAX_A2A_ACTIVITY_REASONING_CHARS = 32_768;\nexport const MAX_A2A_ACTIVITY_RESPONSE_CHARS = 32_768;\nexport const MAX_A2A_ACTIVITY_TOTAL_CHARS = 98_304;\nexport const MAX_A2A_ACTIVITY_REASONING_SEGMENTS = 128;\nexport const MAX_A2A_ACTIVITY_TOOL_CALLS = 64;\nexport const MAX_A2A_ACTIVITY_TOOL_NAME_CHARS = 96;\nexport const MAX_A2A_ACTIVITY_TOOL_ID_CHARS = 128;\n\nexport type A2AAgentActivityPhase =\n | \"reasoning\"\n | \"tool\"\n | \"responding\"\n | \"complete\"\n | \"error\";\n\nexport type A2AAgentActivityToolStatus = \"running\" | \"completed\" | \"failed\";\n\nexport interface A2AAgentActivityToolCall {\n name: string;\n id?: string;\n status: A2AAgentActivityToolStatus;\n}\n\nexport interface A2AAgentActivitySnapshot extends Record<string, unknown> {\n kind: typeof A2A_AGENT_ACTIVITY_KIND;\n version: typeof A2A_AGENT_ACTIVITY_VERSION;\n sequence: number;\n startedAt: number;\n updatedAt: number;\n durationMs: number;\n activePhase: A2AAgentActivityPhase;\n reasoning: string[];\n toolCalls: A2AAgentActivityToolCall[];\n /** Response text segments, indexed by how many tool calls preceded them. */\n response?: string[];\n /** Tail segment only. Kept so peers predating `response` still render. */\n responseText?: string;\n}\n\nexport interface A2AAgentActivityState {\n sequence: number;\n startedAt: number;\n updatedAt: number;\n activePhase: A2AAgentActivityPhase;\n reasoning: string[];\n toolCalls: A2AAgentActivityToolCall[];\n response: string[];\n}\n\nexport function createA2AAgentActivityState(\n startedAt = Date.now(),\n): A2AAgentActivityState {\n return {\n sequence: 0,\n startedAt,\n updatedAt: startedAt,\n activePhase: \"reasoning\",\n reasoning: [],\n toolCalls: [],\n response: [],\n };\n}\n\n/**\n * Converts internal loop events into a bounded activity snapshot. It carries\n * only reasoning text already emitted to the local chat, never tool inputs or\n * results.\n */\nexport function applyA2AAgentActivityEvent(\n state: A2AAgentActivityState,\n event: AgentChatEvent,\n updatedAt = Date.now(),\n): A2AAgentActivityState {\n const next = { ...state, updatedAt: normalizeTimestamp(updatedAt) };\n let changed = false;\n\n switch (event.type) {\n case \"thinking\":\n next.activePhase = \"reasoning\";\n next.reasoning = appendBoundedSegment(\n next.reasoning,\n event.text,\n MAX_A2A_ACTIVITY_REASONING_CHARS,\n next.toolCalls.length,\n );\n changed = true;\n break;\n case \"tool_start\":\n next.activePhase = \"tool\";\n next.toolCalls = appendToolCall(next.toolCalls, toolFromEvent(event));\n changed = true;\n break;\n case \"tool_done\":\n next.activePhase = \"tool\";\n next.toolCalls = settleToolCall(next.toolCalls, toolFromEvent(event));\n changed = true;\n break;\n case \"text\":\n next.activePhase = \"responding\";\n next.response = appendBoundedSegment(\n next.response,\n event.text,\n MAX_A2A_ACTIVITY_RESPONSE_CHARS,\n next.toolCalls.length,\n );\n changed = true;\n break;\n case \"done\":\n next.activePhase = \"complete\";\n changed = true;\n break;\n case \"error\":\n next.activePhase = \"error\";\n changed = true;\n break;\n case \"clear\":\n next.response = [];\n changed = true;\n break;\n }\n\n return changed ? { ...next, sequence: state.sequence + 1 } : state;\n}\n\nexport function buildA2AAgentActivitySnapshot(\n state: A2AAgentActivityState,\n): A2AAgentActivitySnapshot {\n return {\n kind: A2A_AGENT_ACTIVITY_KIND,\n version: A2A_AGENT_ACTIVITY_VERSION,\n sequence: state.sequence,\n startedAt: state.startedAt,\n updatedAt: state.updatedAt,\n durationMs: Math.max(0, state.updatedAt - state.startedAt),\n activePhase: state.activePhase,\n reasoning: state.reasoning,\n toolCalls: state.toolCalls,\n ...(state.response.length ? { response: state.response } : {}),\n ...(tailSegment(state) ? { responseText: tailSegment(state) } : {}),\n };\n}\n\nfunction tailSegment(state: A2AAgentActivityState): string {\n return state.response[state.toolCalls.length] ?? \"\";\n}\n\nexport function buildA2AAgentActivityPart(\n state: A2AAgentActivityState,\n): DataPart {\n return { type: \"data\", data: buildA2AAgentActivitySnapshot(state) };\n}\n\nexport function parseA2AAgentActivityPart(\n part: Part | unknown,\n): A2AAgentActivitySnapshot | null {\n if (!part || typeof part !== \"object\") return null;\n const candidate = part as { type?: unknown; data?: unknown };\n if (candidate.type !== \"data\" || !isRecord(candidate.data)) return null;\n const data = candidate.data;\n if (\n data.kind !== A2A_AGENT_ACTIVITY_KIND ||\n data.version !== A2A_AGENT_ACTIVITY_VERSION ||\n !isSafeInteger(data.sequence) ||\n !isSafeInteger(data.startedAt) ||\n !isSafeInteger(data.updatedAt) ||\n !isSafeInteger(data.durationMs) ||\n !isPhase(data.activePhase) ||\n data.updatedAt < data.startedAt ||\n data.durationMs !== data.updatedAt - data.startedAt ||\n !isSafeSegments(data.reasoning, MAX_A2A_ACTIVITY_REASONING_CHARS) ||\n !isSafeToolCalls(data.toolCalls) ||\n (data.response !== undefined &&\n !isSafeSegments(data.response, MAX_A2A_ACTIVITY_RESPONSE_CHARS)) ||\n (data.responseText !== undefined &&\n !isSafeText(data.responseText, MAX_A2A_ACTIVITY_RESPONSE_CHARS)) ||\n activityCharacterCount(data) > MAX_A2A_ACTIVITY_TOTAL_CHARS\n ) {\n return null;\n }\n\n return data as unknown as A2AAgentActivitySnapshot;\n}\n\nfunction toolFromEvent(\n event: Extract<AgentChatEvent, { type: \"tool_start\" | \"tool_done\" }>,\n): A2AAgentActivityToolCall {\n const id = sanitizeToolId(event.id);\n return {\n name: sanitizeToolName(event.tool),\n ...(id ? { id } : {}),\n status:\n event.type === \"tool_start\"\n ? \"running\"\n : event.isError\n ? \"failed\"\n : \"completed\",\n };\n}\n\nfunction appendBoundedSegment(\n current: string[],\n addition: string,\n maxChars: number,\n precedingToolCount: number,\n): string[] {\n const used = current.reduce((total, text) => total + text.length, 0);\n if (\n used >= maxChars ||\n current.length >= MAX_A2A_ACTIVITY_REASONING_SEGMENTS\n ) {\n return current;\n }\n const text = sanitizeText(addition, maxChars - used);\n if (!text) return current;\n const next = [...current];\n while (\n next.length < precedingToolCount &&\n next.length < MAX_A2A_ACTIVITY_REASONING_SEGMENTS\n ) {\n next.push(\"\");\n }\n if (next.length === precedingToolCount) {\n return [...next, text];\n }\n next[precedingToolCount] = `${next[precedingToolCount] ?? \"\"}${text}`;\n return next;\n}\n\nfunction appendToolCall(\n current: A2AAgentActivityToolCall[],\n tool: A2AAgentActivityToolCall,\n): A2AAgentActivityToolCall[] {\n return current.length < MAX_A2A_ACTIVITY_TOOL_CALLS\n ? [...current, tool]\n : current;\n}\n\nfunction settleToolCall(\n current: A2AAgentActivityToolCall[],\n tool: A2AAgentActivityToolCall,\n): A2AAgentActivityToolCall[] {\n for (let index = current.length - 1; index >= 0; index -= 1) {\n const existing = current[index];\n if (\n (tool.id && tool.id === existing.id) ||\n (!tool.id && tool.name === existing.name)\n ) {\n return current.map((value, itemIndex) =>\n itemIndex === index ? tool : value,\n );\n }\n }\n return appendToolCall(current, tool);\n}\n\nfunction sanitizeText(value: string, maxChars: number): string {\n return sanitizeToolErrorText(value)\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g, \"\")\n .slice(0, maxChars);\n}\n\nfunction sanitizeToolName(value: string): string {\n return sanitizeText(value, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS) || \"tool\";\n}\n\nfunction sanitizeToolId(value: string | undefined): string | undefined {\n const sanitized = value\n ? sanitizeText(value, MAX_A2A_ACTIVITY_TOOL_ID_CHARS)\n : \"\";\n return sanitized || undefined;\n}\n\nfunction normalizeTimestamp(value: number): number {\n return isSafeInteger(value) ? value : Date.now();\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isSafeInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction isPhase(value: unknown): value is A2AAgentActivityPhase {\n return [\"reasoning\", \"tool\", \"responding\", \"complete\", \"error\"].includes(\n value as string,\n );\n}\n\nfunction isSafeSegments(value: unknown, maxChars: number): value is string[] {\n return (\n Array.isArray(value) &&\n value.length <= MAX_A2A_ACTIVITY_REASONING_SEGMENTS &&\n value.reduce(\n (total, text) =>\n total + (typeof text === \"string\" ? text.length : Infinity),\n 0,\n ) <= maxChars &&\n value.every((text) => isSafeText(text, maxChars))\n );\n}\n\nfunction isSafeToolCalls(value: unknown): value is A2AAgentActivityToolCall[] {\n return (\n Array.isArray(value) &&\n value.length <= MAX_A2A_ACTIVITY_TOOL_CALLS &&\n value.every(isSafeToolCall)\n );\n}\n\nfunction isSafeToolCall(value: unknown): value is A2AAgentActivityToolCall {\n if (!isRecord(value) || !isSafeToolName(value.name)) return false;\n return (\n (value.id === undefined || isSafeToolId(value.id)) &&\n (value.status === \"running\" ||\n value.status === \"completed\" ||\n value.status === \"failed\")\n );\n}\n\nfunction isSafeText(value: unknown, maxChars: number): value is string {\n return (\n typeof value === \"string\" &&\n value.length <= maxChars &&\n value === sanitizeText(value, maxChars)\n );\n}\n\nfunction isSafeToolName(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length <= MAX_A2A_ACTIVITY_TOOL_NAME_CHARS &&\n value === sanitizeToolName(value)\n );\n}\n\nfunction isSafeToolId(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length <= MAX_A2A_ACTIVITY_TOOL_ID_CHARS &&\n value === sanitizeToolId(value)\n );\n}\n\nfunction activityCharacterCount(data: Record<string, unknown>): number {\n const reasoning = segmentCharacterCount(data.reasoning);\n // `responseText` duplicates the tail of `response`; counting both would\n // reject a snapshot that is within budget.\n const response = Array.isArray(data.response)\n ? segmentCharacterCount(data.response)\n : typeof data.responseText === \"string\"\n ? data.responseText.length\n : 0;\n const tools = Array.isArray(data.toolCalls)\n ? data.toolCalls.reduce((total, tool) => {\n if (!isRecord(tool)) return total;\n return (\n total +\n (typeof tool.name === \"string\" ? tool.name.length : 0) +\n (typeof tool.id === \"string\" ? tool.id.length : 0)\n );\n }, 0)\n : 0;\n return reasoning + response + tools;\n}\n\nfunction segmentCharacterCount(value: unknown): number {\n return Array.isArray(value)\n ? value.reduce(\n (total, text) => total + (typeof text === \"string\" ? text.length : 0),\n 0,\n )\n : 0;\n}\n"]}
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/a2a/activity.ts"],"names":[],"mappings":"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","sourcesContent":["import { sanitizeToolErrorText } from \"../agent/tool-error-redaction.js\";\nimport type { AgentChatEvent } from \"../agent/types.js\";\nimport { redactArgsToJson, redactTextToSummary } from \"../audit/redact.js\";\nimport type { DataPart, Part } from \"./types.js\";\n\nexport const A2A_AGENT_ACTIVITY_KIND = \"agent-native/agent-activity\";\nexport const A2A_AGENT_ACTIVITY_VERSION = 1;\nexport const MAX_A2A_ACTIVITY_REASONING_CHARS = 32_768;\nexport const MAX_A2A_ACTIVITY_RESPONSE_CHARS = 32_768;\nexport const MAX_A2A_ACTIVITY_REASONING_SEGMENTS = 128;\nexport const MAX_A2A_ACTIVITY_TOOL_CALLS = 64;\nexport const MAX_A2A_ACTIVITY_TOOL_NAME_CHARS = 96;\nexport const MAX_A2A_ACTIVITY_TOOL_ID_CHARS = 128;\nexport const MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS = 1024;\nexport const MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS = 512;\n/**\n * Shared ceiling for every recorded tool input/result across the snapshot. The\n * per-call caps alone allow 64 × 1536 chars, which would push a busy run past\n * `MAX_A2A_ACTIVITY_TOTAL_CHARS` and make `parseA2AAgentActivityPart` reject\n * the whole snapshot — trading missing arguments for a missing trace.\n */\nexport const MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS = 16_384;\nexport const MAX_A2A_ACTIVITY_TOTAL_CHARS =\n 98_304 + MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS;\n\nexport type A2AAgentActivityPhase =\n | \"reasoning\"\n | \"tool\"\n | \"responding\"\n | \"complete\"\n | \"error\";\n\nexport type A2AAgentActivityToolStatus = \"running\" | \"completed\" | \"failed\";\n\nexport interface A2AAgentActivityToolCall {\n name: string;\n id?: string;\n status: A2AAgentActivityToolStatus;\n /**\n * Redacted, size-capped JSON of the call's arguments. Absent when the call\n * had none, or when the snapshot's shared payload budget was already spent.\n */\n input?: string;\n /** Redacted, size-capped head of the tool result (`tool_done` only). */\n result?: string;\n}\n\nexport interface A2AAgentActivitySnapshot extends Record<string, unknown> {\n kind: typeof A2A_AGENT_ACTIVITY_KIND;\n version: typeof A2A_AGENT_ACTIVITY_VERSION;\n sequence: number;\n startedAt: number;\n updatedAt: number;\n durationMs: number;\n activePhase: A2AAgentActivityPhase;\n reasoning: string[];\n toolCalls: A2AAgentActivityToolCall[];\n /** Response text segments, indexed by how many tool calls preceded them. */\n response?: string[];\n /** Tail segment only. Kept so peers predating `response` still render. */\n responseText?: string;\n}\n\nexport interface A2AAgentActivityState {\n sequence: number;\n startedAt: number;\n updatedAt: number;\n activePhase: A2AAgentActivityPhase;\n reasoning: string[];\n toolCalls: A2AAgentActivityToolCall[];\n response: string[];\n}\n\nexport function createA2AAgentActivityState(\n startedAt = Date.now(),\n): A2AAgentActivityState {\n return {\n sequence: 0,\n startedAt,\n updatedAt: startedAt,\n activePhase: \"reasoning\",\n reasoning: [],\n toolCalls: [],\n response: [],\n };\n}\n\n/**\n * Converts internal loop events into a bounded activity snapshot. Reasoning\n * text is carried verbatim (it was already emitted to the local chat); tool\n * arguments and results are carried only in redacted, size-capped form so the\n * delegated run stays diagnosable without the snapshot becoming a secondary\n * store of secrets or payloads.\n */\nexport function applyA2AAgentActivityEvent(\n state: A2AAgentActivityState,\n event: AgentChatEvent,\n updatedAt = Date.now(),\n): A2AAgentActivityState {\n const next = { ...state, updatedAt: normalizeTimestamp(updatedAt) };\n let changed = false;\n\n switch (event.type) {\n case \"thinking\":\n next.activePhase = \"reasoning\";\n next.reasoning = appendBoundedSegment(\n next.reasoning,\n event.text,\n MAX_A2A_ACTIVITY_REASONING_CHARS,\n next.toolCalls.length,\n );\n changed = true;\n break;\n case \"tool_start\": {\n next.activePhase = \"tool\";\n const input = captureToolInput(\n event.input,\n remainingPayloadBudget(next.toolCalls),\n );\n next.toolCalls = appendToolCall(next.toolCalls, {\n ...toolFromEvent(event),\n ...(input ? { input } : {}),\n });\n changed = true;\n break;\n }\n case \"tool_done\":\n next.activePhase = \"tool\";\n next.toolCalls = settleToolCall(\n next.toolCalls,\n toolFromEvent(event),\n event,\n );\n changed = true;\n break;\n case \"text\":\n next.activePhase = \"responding\";\n next.response = appendBoundedSegment(\n next.response,\n event.text,\n MAX_A2A_ACTIVITY_RESPONSE_CHARS,\n next.toolCalls.length,\n );\n changed = true;\n break;\n case \"done\":\n next.activePhase = \"complete\";\n changed = true;\n break;\n case \"error\":\n next.activePhase = \"error\";\n changed = true;\n break;\n case \"clear\":\n next.response = [];\n changed = true;\n break;\n }\n\n return changed ? { ...next, sequence: state.sequence + 1 } : state;\n}\n\nexport function buildA2AAgentActivitySnapshot(\n state: A2AAgentActivityState,\n): A2AAgentActivitySnapshot {\n return {\n kind: A2A_AGENT_ACTIVITY_KIND,\n version: A2A_AGENT_ACTIVITY_VERSION,\n sequence: state.sequence,\n startedAt: state.startedAt,\n updatedAt: state.updatedAt,\n durationMs: Math.max(0, state.updatedAt - state.startedAt),\n activePhase: state.activePhase,\n reasoning: state.reasoning,\n toolCalls: state.toolCalls,\n ...(state.response.length ? { response: state.response } : {}),\n ...(tailSegment(state) ? { responseText: tailSegment(state) } : {}),\n };\n}\n\nfunction tailSegment(state: A2AAgentActivityState): string {\n return state.response[state.toolCalls.length] ?? \"\";\n}\n\nexport function buildA2AAgentActivityPart(\n state: A2AAgentActivityState,\n): DataPart {\n return { type: \"data\", data: buildA2AAgentActivitySnapshot(state) };\n}\n\nexport function parseA2AAgentActivityPart(\n part: Part | unknown,\n): A2AAgentActivitySnapshot | null {\n if (!part || typeof part !== \"object\") return null;\n const candidate = part as { type?: unknown; data?: unknown };\n if (candidate.type !== \"data\" || !isRecord(candidate.data)) return null;\n const data = candidate.data;\n if (\n data.kind !== A2A_AGENT_ACTIVITY_KIND ||\n data.version !== A2A_AGENT_ACTIVITY_VERSION ||\n !isSafeInteger(data.sequence) ||\n !isSafeInteger(data.startedAt) ||\n !isSafeInteger(data.updatedAt) ||\n !isSafeInteger(data.durationMs) ||\n !isPhase(data.activePhase) ||\n data.updatedAt < data.startedAt ||\n data.durationMs !== data.updatedAt - data.startedAt ||\n !isSafeSegments(data.reasoning, MAX_A2A_ACTIVITY_REASONING_CHARS) ||\n !isSafeToolCalls(data.toolCalls) ||\n (data.response !== undefined &&\n !isSafeSegments(data.response, MAX_A2A_ACTIVITY_RESPONSE_CHARS)) ||\n (data.responseText !== undefined &&\n !isSafeText(data.responseText, MAX_A2A_ACTIVITY_RESPONSE_CHARS)) ||\n activityCharacterCount(data) > MAX_A2A_ACTIVITY_TOTAL_CHARS\n ) {\n return null;\n }\n\n return data as unknown as A2AAgentActivitySnapshot;\n}\n\nfunction toolFromEvent(\n event: Extract<AgentChatEvent, { type: \"tool_start\" | \"tool_done\" }>,\n): A2AAgentActivityToolCall {\n const id = sanitizeToolId(event.id);\n return {\n name: sanitizeToolName(event.tool),\n ...(id ? { id } : {}),\n status:\n event.type === \"tool_start\"\n ? \"running\"\n : event.isError\n ? \"failed\"\n : \"completed\",\n };\n}\n\nfunction payloadChars(tool: A2AAgentActivityToolCall): number {\n return (tool.input?.length ?? 0) + (tool.result?.length ?? 0);\n}\n\nfunction remainingPayloadBudget(\n current: A2AAgentActivityToolCall[],\n excludeIndex = -1,\n): number {\n const used = current.reduce(\n (total, tool, index) =>\n index === excludeIndex ? total : total + payloadChars(tool),\n 0,\n );\n return Math.max(0, MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS - used);\n}\n\n/**\n * Redacted, capped JSON of the arguments, or `undefined` when there is nothing\n * to record or the shared budget cannot fit a whole (still-parseable) capture.\n * A partial JSON string would be worse than none — the reader could not tell a\n * clipped object from a different one.\n */\nfunction captureToolInput(input: unknown, budget: number): string | undefined {\n const cap = Math.min(MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS, budget);\n if (cap < MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS / 8) return undefined;\n const json = redactArgsToJson(input, { maxJson: cap, maxString: 256 });\n // JSON.stringify escapes control characters, so the result is already safe\n // for the snapshot without a `sanitizeText` pass — which would rewrite\n // `\"token\":\"[redacted]\"` into unparseable JSON.\n if (!json || json === \"{}\" || json.length > cap) return undefined;\n return json;\n}\n\nfunction captureToolResult(\n result: string | undefined,\n budget: number,\n): string | undefined {\n const cap = Math.min(MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS, budget);\n if (!result || cap <= 0) return undefined;\n const summary = redactTextToSummary(result, cap);\n return summary ? sanitizeText(summary, cap) || undefined : undefined;\n}\n\nfunction appendBoundedSegment(\n current: string[],\n addition: string,\n maxChars: number,\n precedingToolCount: number,\n): string[] {\n const used = current.reduce((total, text) => total + text.length, 0);\n if (\n used >= maxChars ||\n current.length >= MAX_A2A_ACTIVITY_REASONING_SEGMENTS\n ) {\n return current;\n }\n const text = sanitizeText(addition, maxChars - used);\n if (!text) return current;\n const next = [...current];\n while (\n next.length < precedingToolCount &&\n next.length < MAX_A2A_ACTIVITY_REASONING_SEGMENTS\n ) {\n next.push(\"\");\n }\n if (next.length === precedingToolCount) {\n return [...next, text];\n }\n next[precedingToolCount] = `${next[precedingToolCount] ?? \"\"}${text}`;\n return next;\n}\n\nfunction appendToolCall(\n current: A2AAgentActivityToolCall[],\n tool: A2AAgentActivityToolCall,\n): A2AAgentActivityToolCall[] {\n return current.length < MAX_A2A_ACTIVITY_TOOL_CALLS\n ? [...current, tool]\n : current;\n}\n\nfunction settleToolCall(\n current: A2AAgentActivityToolCall[],\n tool: A2AAgentActivityToolCall,\n event: Extract<AgentChatEvent, { type: \"tool_done\" }>,\n): A2AAgentActivityToolCall[] {\n for (let index = current.length - 1; index >= 0; index -= 1) {\n const existing = current[index];\n if (\n (tool.id && tool.id === existing.id) ||\n (!tool.id && tool.name === existing.name)\n ) {\n // The matching `tool_start` already paid for its input; reuse it rather\n // than re-capturing (and re-charging) the same arguments.\n let budget = remainingPayloadBudget(current, index);\n const input =\n existing.input ?? captureToolInput(event.input, budget) ?? undefined;\n budget -= input?.length ?? 0;\n const result = captureToolResult(event.result, budget);\n const settled: A2AAgentActivityToolCall = {\n ...tool,\n ...(input ? { input } : {}),\n ...(result ? { result } : {}),\n };\n return current.map((value, itemIndex) =>\n itemIndex === index ? settled : value,\n );\n }\n }\n let budget = remainingPayloadBudget(current);\n const input = captureToolInput(event.input, budget);\n budget -= input?.length ?? 0;\n const result = captureToolResult(event.result, budget);\n return appendToolCall(current, {\n ...tool,\n ...(input ? { input } : {}),\n ...(result ? { result } : {}),\n });\n}\n\nfunction sanitizeText(value: string, maxChars: number): string {\n return sanitizeToolErrorText(value)\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g, \"\")\n .slice(0, maxChars);\n}\n\nfunction sanitizeToolName(value: string): string {\n return sanitizeText(value, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS) || \"tool\";\n}\n\nfunction sanitizeToolId(value: string | undefined): string | undefined {\n const sanitized = value\n ? sanitizeText(value, MAX_A2A_ACTIVITY_TOOL_ID_CHARS)\n : \"\";\n return sanitized || undefined;\n}\n\nfunction normalizeTimestamp(value: number): number {\n return isSafeInteger(value) ? value : Date.now();\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isSafeInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction isPhase(value: unknown): value is A2AAgentActivityPhase {\n return [\"reasoning\", \"tool\", \"responding\", \"complete\", \"error\"].includes(\n value as string,\n );\n}\n\nfunction isSafeSegments(value: unknown, maxChars: number): value is string[] {\n return (\n Array.isArray(value) &&\n value.length <= MAX_A2A_ACTIVITY_REASONING_SEGMENTS &&\n value.reduce(\n (total, text) =>\n total + (typeof text === \"string\" ? text.length : Infinity),\n 0,\n ) <= maxChars &&\n value.every((text) => isSafeText(text, maxChars))\n );\n}\n\nfunction isSafeToolCalls(value: unknown): value is A2AAgentActivityToolCall[] {\n return (\n Array.isArray(value) &&\n value.length <= MAX_A2A_ACTIVITY_TOOL_CALLS &&\n value.every(isSafeToolCall)\n );\n}\n\nfunction isSafeToolCall(value: unknown): value is A2AAgentActivityToolCall {\n if (!isRecord(value) || !isSafeToolName(value.name)) return false;\n return (\n (value.id === undefined || isSafeToolId(value.id)) &&\n (value.input === undefined ||\n isSafeCapturedText(value.input, MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS)) &&\n (value.result === undefined ||\n isSafeCapturedText(value.result, MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS)) &&\n (value.status === \"running\" ||\n value.status === \"completed\" ||\n value.status === \"failed\")\n );\n}\n\n/**\n * Captured input/result are producer-side redacted strings. Unlike reasoning\n * text they are NOT re-sanitized on read: `sanitizeToolErrorText` rewrites\n * `\"token\":\"…\"` into unparseable JSON, so a round-trip equality check would\n * reject every legitimate capture. Bound the length and reject raw control\n * characters instead.\n */\nfunction isSafeCapturedText(value: unknown, maxChars: number): value is string {\n return (\n typeof value === \"string\" &&\n value.length <= maxChars &&\n !/[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/.test(value)\n );\n}\n\nfunction isSafeText(value: unknown, maxChars: number): value is string {\n return (\n typeof value === \"string\" &&\n value.length <= maxChars &&\n value === sanitizeText(value, maxChars)\n );\n}\n\nfunction isSafeToolName(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length <= MAX_A2A_ACTIVITY_TOOL_NAME_CHARS &&\n value === sanitizeToolName(value)\n );\n}\n\nfunction isSafeToolId(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length <= MAX_A2A_ACTIVITY_TOOL_ID_CHARS &&\n value === sanitizeToolId(value)\n );\n}\n\nfunction activityCharacterCount(data: Record<string, unknown>): number {\n const reasoning = segmentCharacterCount(data.reasoning);\n // `responseText` duplicates the tail of `response`; counting both would\n // reject a snapshot that is within budget.\n const response = Array.isArray(data.response)\n ? segmentCharacterCount(data.response)\n : typeof data.responseText === \"string\"\n ? data.responseText.length\n : 0;\n const tools = Array.isArray(data.toolCalls)\n ? data.toolCalls.reduce((total, tool) => {\n if (!isRecord(tool)) return total;\n return (\n total +\n (typeof tool.name === \"string\" ? tool.name.length : 0) +\n (typeof tool.id === \"string\" ? tool.id.length : 0) +\n (typeof tool.input === \"string\" ? tool.input.length : 0) +\n (typeof tool.result === \"string\" ? tool.result.length : 0)\n );\n }, 0)\n : 0;\n return reasoning + response + tools;\n}\n\nfunction segmentCharacterCount(value: unknown): number {\n return Array.isArray(value)\n ? value.reduce(\n (total, text) => total + (typeof text === \"string\" ? text.length : 0),\n 0,\n )\n : 0;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  export { mountA2A, verifyA2AToken } from "./server.js";
2
2
  export type { A2ATokenPayload } from "./server.js";
3
3
  export { generateAgentCard } from "./agent-card.js";
4
- export { A2A_AGENT_ACTIVITY_KIND, A2A_AGENT_ACTIVITY_VERSION, MAX_A2A_ACTIVITY_REASONING_CHARS, MAX_A2A_ACTIVITY_REASONING_SEGMENTS, MAX_A2A_ACTIVITY_RESPONSE_CHARS, MAX_A2A_ACTIVITY_TOOL_CALLS, MAX_A2A_ACTIVITY_TOTAL_CHARS, MAX_A2A_ACTIVITY_TOOL_ID_CHARS, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS, applyA2AAgentActivityEvent, buildA2AAgentActivityPart, buildA2AAgentActivitySnapshot, createA2AAgentActivityState, parseA2AAgentActivityPart, } from "./activity.js";
4
+ export { A2A_AGENT_ACTIVITY_KIND, A2A_AGENT_ACTIVITY_VERSION, MAX_A2A_ACTIVITY_REASONING_CHARS, MAX_A2A_ACTIVITY_REASONING_SEGMENTS, MAX_A2A_ACTIVITY_RESPONSE_CHARS, MAX_A2A_ACTIVITY_TOOL_CALLS, MAX_A2A_ACTIVITY_TOTAL_CHARS, MAX_A2A_ACTIVITY_TOOL_ID_CHARS, MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS, MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS, MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS, applyA2AAgentActivityEvent, buildA2AAgentActivityPart, buildA2AAgentActivitySnapshot, createA2AAgentActivityState, parseA2AAgentActivityPart, } from "./activity.js";
5
5
  export { A2AClient, callAction, callAgent, signA2AToken } from "./client.js";
6
6
  export { resolveA2ACallerAuth } from "./caller-auth.js";
7
7
  export type { A2ACallerAuth } from "./caller-auth.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gCAAgC,EAChC,mCAAmC,EACnC,+BAA+B,EAC/B,2BAA2B,EAC3B,4BAA4B,EAC5B,8BAA8B,EAC9B,gCAAgC,EAChC,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,IAAI,EACJ,SAAS,EACT,UAAU,EACV,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,2BAA2B,EAC3B,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,kBAAkB,EAClB,mCAAmC,EACnC,6BAA6B,GAC9B,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gCAAgC,EAChC,mCAAmC,EACnC,+BAA+B,EAC/B,2BAA2B,EAC3B,4BAA4B,EAC5B,8BAA8B,EAC9B,iCAAiC,EACjC,gCAAgC,EAChC,mCAAmC,EACnC,kCAAkC,EAClC,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,IAAI,EACJ,SAAS,EACT,UAAU,EACV,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,2BAA2B,EAC3B,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,kBAAkB,EAClB,mCAAmC,EACnC,6BAA6B,GAC9B,MAAM,aAAa,CAAC"}
package/dist/a2a/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Server (H3/Nitro)
2
2
  export { mountA2A, verifyA2AToken } from "./server.js";
3
3
  export { generateAgentCard } from "./agent-card.js";
4
- export { A2A_AGENT_ACTIVITY_KIND, A2A_AGENT_ACTIVITY_VERSION, MAX_A2A_ACTIVITY_REASONING_CHARS, MAX_A2A_ACTIVITY_REASONING_SEGMENTS, MAX_A2A_ACTIVITY_RESPONSE_CHARS, MAX_A2A_ACTIVITY_TOOL_CALLS, MAX_A2A_ACTIVITY_TOTAL_CHARS, MAX_A2A_ACTIVITY_TOOL_ID_CHARS, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS, applyA2AAgentActivityEvent, buildA2AAgentActivityPart, buildA2AAgentActivitySnapshot, createA2AAgentActivityState, parseA2AAgentActivityPart, } from "./activity.js";
4
+ export { A2A_AGENT_ACTIVITY_KIND, A2A_AGENT_ACTIVITY_VERSION, MAX_A2A_ACTIVITY_REASONING_CHARS, MAX_A2A_ACTIVITY_REASONING_SEGMENTS, MAX_A2A_ACTIVITY_RESPONSE_CHARS, MAX_A2A_ACTIVITY_TOOL_CALLS, MAX_A2A_ACTIVITY_TOTAL_CHARS, MAX_A2A_ACTIVITY_TOOL_ID_CHARS, MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS, MAX_A2A_ACTIVITY_TOOL_NAME_CHARS, MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS, MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS, applyA2AAgentActivityEvent, buildA2AAgentActivityPart, buildA2AAgentActivitySnapshot, createA2AAgentActivityState, parseA2AAgentActivityPart, } from "./activity.js";
5
5
  // Client
6
6
  export { A2AClient, callAction, callAgent, signA2AToken } from "./client.js";
7
7
  export { resolveA2ACallerAuth } from "./caller-auth.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gCAAgC,EAChC,mCAAmC,EACnC,+BAA+B,EAC/B,2BAA2B,EAC3B,4BAA4B,EAC5B,8BAA8B,EAC9B,gCAAgC,EAChC,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAEvB,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,aAAa,CAAC","sourcesContent":["// Server (H3/Nitro)\nexport { mountA2A, verifyA2AToken } from \"./server.js\";\nexport type { A2ATokenPayload } from \"./server.js\";\nexport { generateAgentCard } from \"./agent-card.js\";\nexport {\n A2A_AGENT_ACTIVITY_KIND,\n A2A_AGENT_ACTIVITY_VERSION,\n MAX_A2A_ACTIVITY_REASONING_CHARS,\n MAX_A2A_ACTIVITY_REASONING_SEGMENTS,\n MAX_A2A_ACTIVITY_RESPONSE_CHARS,\n MAX_A2A_ACTIVITY_TOOL_CALLS,\n MAX_A2A_ACTIVITY_TOTAL_CHARS,\n MAX_A2A_ACTIVITY_TOOL_ID_CHARS,\n MAX_A2A_ACTIVITY_TOOL_NAME_CHARS,\n applyA2AAgentActivityEvent,\n buildA2AAgentActivityPart,\n buildA2AAgentActivitySnapshot,\n createA2AAgentActivityState,\n parseA2AAgentActivityPart,\n} from \"./activity.js\";\n\n// Client\nexport { A2AClient, callAction, callAgent, signA2AToken } from \"./client.js\";\nexport { resolveA2ACallerAuth } from \"./caller-auth.js\";\nexport type { A2ACallerAuth } from \"./caller-auth.js\";\nexport {\n AgentInvocationError,\n buildAgentInvocationPrompt,\n invokeAgent,\n invokeAgentAction,\n looksLikeAgentUrl,\n resolveAgentInvocationTarget,\n} from \"./invoke.js\";\n\n// Types\nexport type {\n A2AConfig,\n A2AHandler,\n A2AHandlerContext,\n A2AHandlerResult,\n A2ASourceContext,\n AgentCard,\n AgentSkill,\n AgentCapabilities,\n Task,\n TaskState,\n TaskStatus,\n Message,\n Part,\n TextPart,\n FilePart,\n DataPart,\n Artifact,\n JsonRpcRequest,\n JsonRpcResponse,\n A2ACorrelationMetadata,\n A2AReadOnlyActionInvocation,\n A2AReadOnlyActionResult,\n A2AAgentActivityPhase,\n A2AAgentActivitySnapshot,\n A2AAgentActivityState,\n A2AAgentActivityToolCall,\n A2AAgentActivityToolStatus,\n} from \"./types.js\";\nexport type {\n AgentInvocationErrorCode,\n AgentActionInvocationResult,\n AgentInvocationResult,\n AgentInvocationRuntime,\n InvokeAgentActionOptions,\n InvokeAgentOptions,\n ResolveAgentInvocationTargetOptions,\n ResolvedAgentInvocationTarget,\n} from \"./invoke.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gCAAgC,EAChC,mCAAmC,EACnC,+BAA+B,EAC/B,2BAA2B,EAC3B,4BAA4B,EAC5B,8BAA8B,EAC9B,iCAAiC,EACjC,gCAAgC,EAChC,mCAAmC,EACnC,kCAAkC,EAClC,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAEvB,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,aAAa,CAAC","sourcesContent":["// Server (H3/Nitro)\nexport { mountA2A, verifyA2AToken } from \"./server.js\";\nexport type { A2ATokenPayload } from \"./server.js\";\nexport { generateAgentCard } from \"./agent-card.js\";\nexport {\n A2A_AGENT_ACTIVITY_KIND,\n A2A_AGENT_ACTIVITY_VERSION,\n MAX_A2A_ACTIVITY_REASONING_CHARS,\n MAX_A2A_ACTIVITY_REASONING_SEGMENTS,\n MAX_A2A_ACTIVITY_RESPONSE_CHARS,\n MAX_A2A_ACTIVITY_TOOL_CALLS,\n MAX_A2A_ACTIVITY_TOTAL_CHARS,\n MAX_A2A_ACTIVITY_TOOL_ID_CHARS,\n MAX_A2A_ACTIVITY_TOOL_INPUT_CHARS,\n MAX_A2A_ACTIVITY_TOOL_NAME_CHARS,\n MAX_A2A_ACTIVITY_TOOL_PAYLOAD_CHARS,\n MAX_A2A_ACTIVITY_TOOL_RESULT_CHARS,\n applyA2AAgentActivityEvent,\n buildA2AAgentActivityPart,\n buildA2AAgentActivitySnapshot,\n createA2AAgentActivityState,\n parseA2AAgentActivityPart,\n} from \"./activity.js\";\n\n// Client\nexport { A2AClient, callAction, callAgent, signA2AToken } from \"./client.js\";\nexport { resolveA2ACallerAuth } from \"./caller-auth.js\";\nexport type { A2ACallerAuth } from \"./caller-auth.js\";\nexport {\n AgentInvocationError,\n buildAgentInvocationPrompt,\n invokeAgent,\n invokeAgentAction,\n looksLikeAgentUrl,\n resolveAgentInvocationTarget,\n} from \"./invoke.js\";\n\n// Types\nexport type {\n A2AConfig,\n A2AHandler,\n A2AHandlerContext,\n A2AHandlerResult,\n A2ASourceContext,\n AgentCard,\n AgentSkill,\n AgentCapabilities,\n Task,\n TaskState,\n TaskStatus,\n Message,\n Part,\n TextPart,\n FilePart,\n DataPart,\n Artifact,\n JsonRpcRequest,\n JsonRpcResponse,\n A2ACorrelationMetadata,\n A2AReadOnlyActionInvocation,\n A2AReadOnlyActionResult,\n A2AAgentActivityPhase,\n A2AAgentActivitySnapshot,\n A2AAgentActivityState,\n A2AAgentActivityToolCall,\n A2AAgentActivityToolStatus,\n} from \"./types.js\";\nexport type {\n AgentInvocationErrorCode,\n AgentActionInvocationResult,\n AgentInvocationResult,\n AgentInvocationRuntime,\n InvokeAgentActionOptions,\n InvokeAgentOptions,\n ResolveAgentInvocationTargetOptions,\n ResolvedAgentInvocationTarget,\n} from \"./invoke.js\";\n"]}
@@ -71,8 +71,9 @@ export declare function resolveAgentChatProcessRunDispatchPath(): string;
71
71
  export declare function resolveDurableBackgroundDispatchPath(fallbackPath: string): string;
72
72
  export declare function dispatchPathTargetsNetlifyBackgroundFunction(dispatchPath: string): boolean;
73
73
  /**
74
- * Env flag for durable background runs. DEFAULT-OFF (opt-in): unset means
75
- * disabled; an app opts IN with an explicit truthy value (`true`/`1`/`yes`/`on`).
74
+ * Env flag for durable background runs. On Netlify, unset means enabled and an
75
+ * explicit falsy value opts out. On other hosted platforms, apps still opt in
76
+ * with an explicit truthy value (`true`/`1`/`yes`/`on`).
76
77
  */
77
78
  export declare const AGENT_CHAT_DURABLE_BACKGROUND_ENV = "AGENT_CHAT_DURABLE_BACKGROUND";
78
79
  /**
@@ -89,6 +90,12 @@ export declare const AGENT_CHAT_BACKGROUND_RUN_FIELD = "__backgroundRun";
89
90
  * what "hosted" means.
90
91
  */
91
92
  export declare function isHostedRuntimeForDurableBackground(): boolean;
93
+ /**
94
+ * Netlify is the only host with the emitted 15-minute background function.
95
+ * Keep the framework-wide default scoped to deployed Netlify rather than
96
+ * silently enabling it on other hosted runtimes that may not have that worker.
97
+ */
98
+ export declare function isNetlifyHostedRuntimeForDurableBackground(): boolean;
92
99
  /**
93
100
  * True when THIS process is actually executing inside a Netlify *background*
94
101
  * function (the long, 15-min-budget async function whose deployed name ends in
@@ -126,12 +133,10 @@ export declare const BACKGROUND_FUNCTION_UNREACHABLE_NOTICE_KEY = "__AGENT_NATIV
126
133
  export declare function isDurableBackgroundFlagEnabled(): boolean;
127
134
  export declare function isDurableBackgroundFlagExplicitlyDisabled(): boolean;
128
135
  /**
129
- * The single gate. True when the env flag is explicitly enabled, or a workspace
130
- * app opted in and has a per-app background-function target, AND the runtime is
131
- * hosted AND A2A_SECRET is configured. False otherwise and false means the
132
- * current synchronous behavior is used unchanged. Single-template Netlify app
133
- * opt-ins deliberately require the env flag too because that flag controls
134
- * whether the `server-agent-background` function exists in the deploy output.
136
+ * The single gate. On deployed Netlify, durable runs are enabled unless the env
137
+ * flag is explicitly falsy. Other hosted runtimes retain the explicit env/app
138
+ * opt-in path. In every case the runtime must be hosted and have A2A_SECRET.
139
+ * False means the current synchronous behavior is used unchanged.
135
140
  */
136
141
  export declare function isAgentChatDurableBackgroundEnabled(options?: {
137
142
  appOptIn?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"durable-background.d.ts","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2CACE,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,4BAA4B,CAAC;AAExE;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,gDAA0D,CAAC;AAE1G;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AACzE,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AACpD,eAAO,MAAM,sCAAsC,gBAAgB,CAAC;AACpE,eAAO,MAAM,gCAAgC,UAAU,CAAC;AACxD,eAAO,MAAM,sCAAsC,gCACpB,CAAC;AAsChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAQ/D;AAED,wBAAgB,oCAAoC,CAClD,YAAY,EAAE,MAAM,GACnB,MAAM,CAQR;AAED,wBAAgB,4CAA4C,CAC1D,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;;GAGG;AACH,eAAO,MAAM,iCAAiC,kCACb,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,OAAO,CAyB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,OAAO,GACd,OAAO,CAOT;AAED,wBAAgB,2CAA2C,CACzD,OAAO,EAAE,OAAO,GACf,OAAO,CAKT;AAED,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAUzE;AAED,eAAO,MAAM,0CAA0C,mDACL,CAAC;AA6BnD;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAwBxD;AAED,wBAAgB,yCAAyC,IAAI,OAAO,CAUnE;AAED;;;;;;;GAOG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,CAAC,EAAE;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAiBV;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,qCACb,CAAC;AAiBrC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qCAAqC,IAAI,OAAO,CAM/D;AAED,uDAAuD;AACvD,MAAM,MAAM,qBAAqB,GAC7B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAahE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,GAAE,OAAe,GACxB,qBAAqB,CAqDvB"}
1
+ {"version":3,"file":"durable-background.d.ts","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2CACE,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,4BAA4B,CAAC;AAExE;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,gDAA0D,CAAC;AAE1G;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AACzE,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AACpD,eAAO,MAAM,sCAAsC,gBAAgB,CAAC;AACpE,eAAO,MAAM,gCAAgC,UAAU,CAAC;AACxD,eAAO,MAAM,sCAAsC,gCACpB,CAAC;AAsChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAQ/D;AAED,wBAAgB,oCAAoC,CAClD,YAAY,EAAE,MAAM,GACnB,MAAM,CAQR;AAED,wBAAgB,4CAA4C,CAC1D,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,kCACb,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,OAAO,CAyB7D;AAED;;;;GAIG;AACH,wBAAgB,0CAA0C,IAAI,OAAO,CAOpE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,OAAO,GACd,OAAO,CAOT;AAED,wBAAgB,2CAA2C,CACzD,OAAO,EAAE,OAAO,GACf,OAAO,CAKT;AAED,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAUzE;AAED,eAAO,MAAM,0CAA0C,mDACL,CAAC;AA6BnD;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAkBxD;AAED,wBAAgB,yCAAyC,IAAI,OAAO,CAUnE;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,CAAC,EAAE;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAoBV;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,qCACb,CAAC;AAiBrC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qCAAqC,IAAI,OAAO,CAM/D;AAED,uDAAuD;AACvD,MAAM,MAAM,qBAAqB,GAC7B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAahE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,GAAE,OAAe,GACxB,qBAAqB,CAqDvB"}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Durable background agent-chat runs (Netlify background functions).
3
3
  *
4
- * Off by default. When enabled, a long in-app agent-chat turn is dispatched
4
+ * Enabled by default on deployed Netlify apps. When enabled, a long in-app
5
+ * agent-chat turn is dispatched
5
6
  * into a Netlify *background* function (15-min budget) instead of completing
6
7
  * synchronously under the ~40s soft-timeout. The foreground POST claims the
7
8
  * run slot, inserts the run row, fires an HMAC-signed self-dispatch to
@@ -18,18 +19,17 @@
18
19
  * GUARDRAIL: when `isAgentChatDurableBackgroundEnabled()` returns false, the
19
20
  * agent-chat handler must behave byte-for-byte like the current synchronous
20
21
  * path. The gate is true only when ALL of these hold:
21
- * 1. `AGENT_CHAT_DURABLE_BACKGROUND` env is explicitly enabled, or a
22
- * workspace app's agent-chat plugin opts in with `durableBackgroundRuns`
23
- * where the workspace deploy emits a per-app background function by
24
- * default. Single-template Netlify deploys must set the env flag because
25
- * that same flag controls whether `server-agent-background` is emitted.
22
+ * 1. The runtime is a deployed Netlify app and
23
+ * `AGENT_CHAT_DURABLE_BACKGROUND` is not explicitly disabled, or the
24
+ * existing env/app opt-in path is used on another hosted platform. Netlify
25
+ * deploys emit the background function by default; `false`, `0`, `no`, or
26
+ * `off` disables it.
26
27
  * 2. The runtime is hosted/serverless (local dev keeps the inline path so SSE
27
28
  * stays a single live stream and no second function is needed).
28
29
  * 3. `A2A_SECRET` is configured (the HMAC handoff is required to authenticate
29
30
  * the background dispatch; without it the dispatch can't be trusted).
30
31
  *
31
- * Opt-in keeps the blast radius small while the worker path is still being
32
- * proven. And even when enabled, a *dispatch failure degrades to an inline run*:
32
+ * Even when enabled, a *dispatch failure degrades to an inline run*:
33
33
  * if the self-dispatch self-POST can't be delivered (fast connection error or
34
34
  * fast non-2xx), the foreground handler runs the turn synchronously instead of
35
35
  * erroring (see `production-agent.ts` — the inline fallback claims the run row
@@ -112,7 +112,7 @@ function isNetlifyHostedRuntimeForDispatch() {
112
112
  // deploys. Without either check a modern Netlify Function silently selects the
113
113
  // portable framework route even though the emitted background function exists.
114
114
  if (process.env.SITE_ID)
115
- return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
115
+ return true; // guard:allow-env-credential - Netlify's read-only public site identifier is a runtime host marker, not a user credential.
116
116
  // Non-Netlify AWS falls back inline if the /.netlify/functions dispatch
117
117
  // fast-fails.
118
118
  return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);
@@ -166,8 +166,9 @@ export function dispatchPathTargetsNetlifyBackgroundFunction(dispatchPath) {
166
166
  return dispatchPath.startsWith("/.netlify/functions/");
167
167
  }
168
168
  /**
169
- * Env flag for durable background runs. DEFAULT-OFF (opt-in): unset means
170
- * disabled; an app opts IN with an explicit truthy value (`true`/`1`/`yes`/`on`).
169
+ * Env flag for durable background runs. On Netlify, unset means enabled and an
170
+ * explicit falsy value opts out. On other hosted platforms, apps still opt in
171
+ * with an explicit truthy value (`true`/`1`/`yes`/`on`).
171
172
  */
172
173
  export const AGENT_CHAT_DURABLE_BACKGROUND_ENV = "AGENT_CHAT_DURABLE_BACKGROUND";
173
174
  /**
@@ -206,6 +207,19 @@ export function isHostedRuntimeForDurableBackground() {
206
207
  process.env.FLY_APP_NAME ||
207
208
  process.env.K_SERVICE);
208
209
  }
210
+ /**
211
+ * Netlify is the only host with the emitted 15-minute background function.
212
+ * Keep the framework-wide default scoped to deployed Netlify rather than
213
+ * silently enabling it on other hosted runtimes that may not have that worker.
214
+ */
215
+ export function isNetlifyHostedRuntimeForDurableBackground() {
216
+ if (process.env.NETLIFY_LOCAL === "true")
217
+ return false;
218
+ if (process.env.NETLIFY === "false")
219
+ return false;
220
+ return Boolean((process.env.NETLIFY && process.env.NETLIFY !== "false") ||
221
+ process.env.SITE_ID);
222
+ }
209
223
  /**
210
224
  * True when THIS process is actually executing inside a Netlify *background*
211
225
  * function (the long, 15-min-budget async function whose deployed name ends in
@@ -307,16 +321,10 @@ export function isDurableBackgroundFlagEnabled() {
307
321
  // can statically verify it against the allowlisted `AGENT_*` prefix. Keep this
308
322
  // in sync with AGENT_CHAT_DURABLE_BACKGROUND_ENV.
309
323
  //
310
- // DEFAULT-OFF (opt-in): durable background runs are still being hardened. A
311
- // premature fleet-wide default-on caused real-user incidents (Assets/Analytics
312
- // hit "Failed to dispatch" + stalls, 2026-06-24) because the async background
313
- // worker path is not yet proven end-to-end and the deploy-time env opt-out is
314
- // not reliably baked into a given deploy. So an unset/empty/unknown flag means
315
- // OFF; an app opts IN only with an explicit truthy value
316
- // (AGENT_CHAT_DURABLE_BACKGROUND=true). This still composes with the hosted +
317
- // A2A_SECRET gates below. Flip back to default-on only after the 15-min
318
- // background-function worker is verified live in production (see the
319
- // project_durable_bg_prod_verified memory).
324
+ // This parses only the explicit opt-in signal. Netlify's default-on behavior
325
+ // is composed separately in isAgentChatDurableBackgroundEnabled, while other
326
+ // hosted runtimes still require this truthy value. Empty and unknown values
327
+ // remain false so an explicit host opt-in cannot be inferred accidentally.
320
328
  const raw = process.env.AGENT_CHAT_DURABLE_BACKGROUND;
321
329
  if (raw == null)
322
330
  return false;
@@ -337,12 +345,10 @@ export function isDurableBackgroundFlagExplicitlyDisabled() {
337
345
  normalized === "off");
338
346
  }
339
347
  /**
340
- * The single gate. True when the env flag is explicitly enabled, or a workspace
341
- * app opted in and has a per-app background-function target, AND the runtime is
342
- * hosted AND A2A_SECRET is configured. False otherwise and false means the
343
- * current synchronous behavior is used unchanged. Single-template Netlify app
344
- * opt-ins deliberately require the env flag too because that flag controls
345
- * whether the `server-agent-background` function exists in the deploy output.
348
+ * The single gate. On deployed Netlify, durable runs are enabled unless the env
349
+ * flag is explicitly falsy. Other hosted runtimes retain the explicit env/app
350
+ * opt-in path. In every case the runtime must be hosted and have A2A_SECRET.
351
+ * False means the current synchronous behavior is used unchanged.
346
352
  */
347
353
  export function isAgentChatDurableBackgroundEnabled(options) {
348
354
  // An app-level opt-out must win over a stale deploy-wide env flag. Netlify
@@ -353,10 +359,12 @@ export function isAgentChatDurableBackgroundEnabled(options) {
353
359
  if (options?.appOptIn === false)
354
360
  return false;
355
361
  const envOptIn = isDurableBackgroundFlagEnabled();
362
+ const netlifyDefaultOptIn = isNetlifyHostedRuntimeForDurableBackground() &&
363
+ !isDurableBackgroundFlagExplicitlyDisabled();
356
364
  const workspaceAppOptIn = options?.appOptIn === true &&
357
365
  !isDurableBackgroundFlagExplicitlyDisabled() &&
358
366
  resolveWorkspaceBackgroundFunctionUrlPath() !== null;
359
- return ((envOptIn || workspaceAppOptIn) &&
367
+ return ((envOptIn || netlifyDefaultOptIn || workspaceAppOptIn) &&
360
368
  isHostedRuntimeForDurableBackground() &&
361
369
  hasConfiguredA2ASecret());
362
370
  }