@agent-native/core 0.107.0 → 0.107.2

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 (156) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +16 -0
  3. package/corpus/core/docs/content/integrations.mdx +27 -27
  4. package/corpus/core/package.json +1 -1
  5. package/corpus/core/src/a2a/artifact-response.ts +32 -10
  6. package/corpus/core/src/agent/production-agent.ts +19 -0
  7. package/corpus/core/src/agent/run-store.ts +98 -2
  8. package/corpus/core/src/client/AssistantChat.tsx +13 -0
  9. package/corpus/core/src/client/CommandMenu.tsx +5 -0
  10. package/corpus/core/src/client/active-run-state.ts +34 -0
  11. package/corpus/core/src/client/agent-chat-adapter.ts +4 -0
  12. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +41 -11
  13. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +27 -9
  14. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +45 -0
  15. package/corpus/core/src/client/sharing/ShareButton.tsx +30 -9
  16. package/corpus/core/src/client/use-agent-chat-home-handoff.ts +2 -2
  17. package/corpus/core/src/integrations/a2a-continuation-processor.ts +107 -3
  18. package/corpus/core/src/integrations/pending-tasks-store.ts +98 -1
  19. package/corpus/core/src/integrations/plugin.ts +129 -4
  20. package/corpus/core/src/integrations/webhook-handler.ts +339 -36
  21. package/corpus/core/src/localization/default-messages.ts +4 -1
  22. package/corpus/core/src/secrets/register-framework-secrets.ts +28 -0
  23. package/corpus/core/src/server/agent-chat-plugin.ts +122 -9
  24. package/corpus/core/src/vite/client.ts +24 -0
  25. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -21
  26. package/corpus/templates/analytics/AGENTS.md +8 -0
  27. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1 -1
  28. package/corpus/templates/analytics/actions/update-dashboard.ts +6 -2
  29. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +35 -7
  30. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -3
  31. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +11 -1
  32. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/extension-slot.ts +11 -0
  33. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +27 -0
  34. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +6 -0
  35. package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extension-boxes.md +6 -0
  36. package/corpus/templates/analytics/server/lib/agent-readable-resource-context.ts +8 -0
  37. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
  38. package/corpus/templates/assets/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  39. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +6 -1
  40. package/corpus/templates/brain/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  41. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
  42. package/corpus/templates/calendar/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  43. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +4 -1
  44. package/corpus/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  45. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  46. package/corpus/templates/clips/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  47. package/corpus/templates/content/actions/_content-space-access.ts +45 -2
  48. package/corpus/templates/content/actions/create-content-database.ts +41 -7
  49. package/corpus/templates/content/app/components/layout/Layout.tsx +1 -1
  50. package/corpus/templates/content/app/root.tsx +1 -10
  51. package/corpus/templates/content/changelog/2026-07-17-creating-a-database-now-completes-reliably-in-hosted-workspa.md +6 -0
  52. package/corpus/templates/content/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  53. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +4 -1
  54. package/corpus/templates/dispatch/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  55. package/corpus/templates/forms/app/components/layout/Layout.tsx +2 -4
  56. package/corpus/templates/forms/app/components/ui/popover.tsx +25 -1
  57. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +6 -1
  58. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +13 -10
  59. package/corpus/templates/forms/app/root.tsx +6 -1
  60. package/corpus/templates/forms/changelog/2026-07-17-form-builder-popovers-stay-within-the-viewport.md +6 -0
  61. package/corpus/templates/forms/changelog/2026-07-17-form-editor-loading-matches-current-sidebar-free-layout.md +6 -0
  62. package/corpus/templates/forms/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  63. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +1 -1
  64. package/corpus/templates/mail/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  65. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +14 -3
  66. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +8 -1
  67. package/corpus/templates/plan/app/root.tsx +0 -2
  68. package/corpus/templates/plan/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  69. package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
  70. package/corpus/templates/slides/app/context/DeckContext.tsx +23 -23
  71. package/corpus/templates/slides/changelog/2026-07-17-duplicated-slides-now-stay-in-the-deck.md +6 -0
  72. package/corpus/templates/slides/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  73. package/corpus/templates/tasks/app/components/layout/Layout.tsx +2 -13
  74. package/corpus/templates/tasks/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it.md +6 -0
  75. package/dist/a2a/artifact-response.d.ts +5 -1
  76. package/dist/a2a/artifact-response.d.ts.map +1 -1
  77. package/dist/a2a/artifact-response.js +18 -12
  78. package/dist/a2a/artifact-response.js.map +1 -1
  79. package/dist/agent/production-agent.d.ts.map +1 -1
  80. package/dist/agent/production-agent.js +13 -1
  81. package/dist/agent/production-agent.js.map +1 -1
  82. package/dist/agent/run-store.d.ts +17 -0
  83. package/dist/agent/run-store.d.ts.map +1 -1
  84. package/dist/agent/run-store.js +84 -2
  85. package/dist/agent/run-store.js.map +1 -1
  86. package/dist/client/AssistantChat.d.ts.map +1 -1
  87. package/dist/client/AssistantChat.js +10 -1
  88. package/dist/client/AssistantChat.js.map +1 -1
  89. package/dist/client/CommandMenu.d.ts.map +1 -1
  90. package/dist/client/CommandMenu.js +4 -0
  91. package/dist/client/CommandMenu.js.map +1 -1
  92. package/dist/client/active-run-state.d.ts +7 -0
  93. package/dist/client/active-run-state.d.ts.map +1 -1
  94. package/dist/client/active-run-state.js +28 -0
  95. package/dist/client/active-run-state.js.map +1 -1
  96. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  97. package/dist/client/agent-chat-adapter.js +4 -1
  98. package/dist/client/agent-chat-adapter.js.map +1 -1
  99. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  100. package/dist/client/resources/McpConnectionSuggestion.js +27 -8
  101. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  102. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  103. package/dist/client/resources/McpIntegrationDialog.js +4 -2
  104. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  105. package/dist/client/resources/mcp-integration-catalog.d.ts +6 -0
  106. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  107. package/dist/client/resources/mcp-integration-catalog.js +33 -0
  108. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  109. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  110. package/dist/client/sharing/ShareButton.js +15 -12
  111. package/dist/client/sharing/ShareButton.js.map +1 -1
  112. package/dist/client/use-agent-chat-home-handoff.d.ts +1 -1
  113. package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
  114. package/dist/client/use-agent-chat-home-handoff.js +1 -1
  115. package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
  116. package/dist/collab/awareness.d.ts +2 -2
  117. package/dist/collab/awareness.d.ts.map +1 -1
  118. package/dist/collab/routes.d.ts +1 -1
  119. package/dist/integrations/a2a-continuation-processor.js +62 -5
  120. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  121. package/dist/integrations/pending-tasks-store.d.ts +3 -0
  122. package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
  123. package/dist/integrations/pending-tasks-store.js +75 -1
  124. package/dist/integrations/pending-tasks-store.js.map +1 -1
  125. package/dist/integrations/plugin.d.ts.map +1 -1
  126. package/dist/integrations/plugin.js +81 -5
  127. package/dist/integrations/plugin.js.map +1 -1
  128. package/dist/integrations/webhook-handler.d.ts +23 -2
  129. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  130. package/dist/integrations/webhook-handler.js +257 -35
  131. package/dist/integrations/webhook-handler.js.map +1 -1
  132. package/dist/localization/default-messages.d.ts +2 -0
  133. package/dist/localization/default-messages.d.ts.map +1 -1
  134. package/dist/localization/default-messages.js +3 -1
  135. package/dist/localization/default-messages.js.map +1 -1
  136. package/dist/notifications/routes.d.ts +2 -2
  137. package/dist/observability/routes.d.ts +5 -5
  138. package/dist/resources/handlers.d.ts +1 -1
  139. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  140. package/dist/secrets/register-framework-secrets.js +25 -0
  141. package/dist/secrets/register-framework-secrets.js.map +1 -1
  142. package/dist/secrets/routes.d.ts +9 -9
  143. package/dist/server/agent-chat-plugin.d.ts +6 -0
  144. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  145. package/dist/server/agent-chat-plugin.js +94 -7
  146. package/dist/server/agent-chat-plugin.js.map +1 -1
  147. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  148. package/dist/templates/chat/app/hooks/use-navigation-state.ts +4 -1
  149. package/dist/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  150. package/dist/vite/client.d.ts.map +1 -1
  151. package/dist/vite/client.js +20 -0
  152. package/dist/vite/client.js.map +1 -1
  153. package/docs/content/integrations.mdx +27 -27
  154. package/package.json +1 -1
  155. package/src/templates/chat/app/hooks/use-navigation-state.ts +4 -1
  156. package/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
@@ -1920,39 +1920,39 @@ export function DeckProvider({ children }: { children: ReactNode }) {
1920
1920
 
1921
1921
  const duplicateSlide = useCallback(
1922
1922
  (deckId: string, slideId: string) => {
1923
- markDeckDirty(deckId);
1924
1923
  const before = decksRef.current.find((d) => d.id === deckId);
1925
- let copiedSlide: Slide | undefined;
1924
+ const original = before?.slides.find((slide) => slide.id === slideId);
1925
+ if (!before || !original) return;
1926
+
1927
+ markDeckDirty(deckId);
1928
+ const copiedSlide: Slide = { ...original, id: nanoid(8) };
1926
1929
  setDecksLocal((prev) =>
1927
1930
  prev.map((d) => {
1928
1931
  if (d.id !== deckId) return d;
1929
1932
  const idx = d.slides.findIndex((s) => s.id === slideId);
1930
1933
  if (idx === -1) return d;
1931
- const original = d.slides[idx];
1932
- const copy: Slide = { ...original, id: nanoid(8) };
1933
- copiedSlide = copy;
1934
1934
  const slides = [...d.slides];
1935
- slides.splice(idx + 1, 0, copy);
1935
+ slides.splice(idx + 1, 0, copiedSlide);
1936
1936
  return { ...d, slides, updatedAt: new Date().toISOString() };
1937
1937
  }),
1938
1938
  );
1939
- if (copiedSlide) {
1940
- // Granular add-slide op inserts the copy after the original.
1941
- const { id: newSlideId, ...rest } = copiedSlide;
1942
- const op: PatchDeckOp = {
1943
- op: "add-slide",
1944
- slideId: newSlideId,
1945
- afterSlideId: slideId,
1946
- fields: {
1947
- content: rest.content,
1948
- notes: rest.notes,
1949
- layout: rest.layout,
1950
- background: rest.background,
1951
- },
1952
- };
1953
- enqueueDeckOp(deckId, op);
1954
- if (before) recordUndo(before, op, { label: "Duplicate slide" });
1955
- }
1939
+ // Granular add-slide op — inserts the copy after the original. Build it
1940
+ // from the current deck before scheduling the React state update; the
1941
+ // functional updater runs later and cannot be used to produce the op.
1942
+ const { id: newSlideId, ...rest } = copiedSlide;
1943
+ const op: PatchDeckOp = {
1944
+ op: "add-slide",
1945
+ slideId: newSlideId,
1946
+ afterSlideId: slideId,
1947
+ fields: {
1948
+ content: rest.content,
1949
+ notes: rest.notes,
1950
+ layout: rest.layout,
1951
+ background: rest.background,
1952
+ },
1953
+ };
1954
+ enqueueDeckOp(deckId, op);
1955
+ recordUndo(before, op, { label: "Duplicate slide" });
1956
1956
  },
1957
1957
  [markDeckDirty, recordUndo, setDecksLocal],
1958
1958
  );
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ Duplicated slides now stay in the deck after the editor saves the change.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ The agent chat sidebar stays closed until you open it or start a chat handoff.
@@ -1,8 +1,4 @@
1
- import {
2
- AgentSidebar,
3
- focusAgentChat,
4
- useAgentChatHomeHandoff,
5
- } from "@agent-native/core/client";
1
+ import { AgentSidebar, focusAgentChat } from "@agent-native/core/client";
6
2
  import { IconMenu2 } from "@tabler/icons-react";
7
3
  import { useState, useEffect } from "react";
8
4
  import { useLocation } from "react-router";
@@ -39,12 +35,6 @@ export function Layout({ children }: LayoutProps) {
39
35
  const location = useLocation();
40
36
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
41
37
  const [sidebarCollapsed, setSidebarCollapsed] = useState(true);
42
- const chatHomeHandoffActive = useAgentChatHomeHandoff({
43
- storageKey: "chat",
44
- activePath: location.pathname,
45
- enabled: true,
46
- });
47
-
48
38
  useEffect(() => {
49
39
  setMobileSidebarOpen(false);
50
40
  }, [location.pathname]);
@@ -114,9 +104,8 @@ export function Layout({ children }: LayoutProps) {
114
104
  <AgentSidebar
115
105
  position="right"
116
106
  chatViewTransition
117
- storageKey="chat"
107
+ storageKey="tasks"
118
108
  browserTabId={TAB_ID}
119
- openOnChatRunning={chatHomeHandoffActive}
120
109
  onFullscreenRequest={() => focusAgentChat()}
121
110
  emptyStateText="Ask the agent to inspect or change this app."
122
111
  dynamicSuggestions={false}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ The agent chat sidebar stays closed until you open it.
@@ -8,6 +8,10 @@ export interface A2AArtifactResponseOptions {
8
8
  baseUrl?: string;
9
9
  includeReferencedArtifacts?: boolean;
10
10
  includePersistedArtifactMarker?: boolean;
11
+ persistedArtifactSecret?: string;
12
+ }
13
+ export interface A2AArtifactIdentityOptions {
14
+ persistedArtifactSecrets?: readonly string[];
11
15
  }
12
16
  export interface A2AArtifactIdentity {
13
17
  resourceType: "document" | "deck" | "dashboard" | "analysis" | "image" | "design" | "monitor" | "form";
@@ -22,7 +26,7 @@ export declare function stripA2APersistedArtifactMarkers(text: string): string;
22
26
  * The ledger deliberately excludes raw tool results so it is safe to retain in
23
27
  * long-lived thread context and stable even when a resource is later renamed.
24
28
  */
25
- export declare function extractA2AArtifactIdentities(results: A2AToolResultSummary[]): A2AArtifactIdentity[];
29
+ export declare function extractA2AArtifactIdentities(results: A2AToolResultSummary[], options?: A2AArtifactIdentityOptions): A2AArtifactIdentity[];
26
30
  export declare function appendA2AArtifactLinks(responseText: string, toolResults: A2AToolResultSummary[], options?: A2AArtifactResponseOptions): string;
27
31
  export declare function buildA2ARecoverableArtifactMessage(toolResults: A2AToolResultSummary[], options?: A2AArtifactResponseOptions): string | null;
28
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-response.d.ts","sourceRoot":"","sources":["../../src/a2a/artifact-response.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EACR,UAAU,GACV,MAAM,GACN,WAAW,GACX,UAAU,GACV,OAAO,GACP,QAAQ,GACR,SAAS,GACT,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAiGD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE;AA4uBD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,oBAAoB,EAAE,GAC9B,mBAAmB,EAAE,CAqGvB;AA2YD,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,oBAAoB,EAAE,EACnC,OAAO,GAAE,0BAA+B,GACvC,MAAM,CA8IR;AAED,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,oBAAoB,EAAE,EACnC,OAAO,GAAE,0BAA+B,GACvC,MAAM,GAAG,IAAI,CA8Bf;AAmCD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,oBAAoB,EAAE,EACnC,OAAO,GAAE,0BAA+B,GACvC,MAAM,GAAG,IAAI,CAqBf"}
1
+ {"version":3,"file":"artifact-response.d.ts","sourceRoot":"","sources":["../../src/a2a/artifact-response.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,wBAAwB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EACR,UAAU,GACV,MAAM,GACN,WAAW,GACX,UAAU,GACV,OAAO,GACP,QAAQ,GACR,SAAS,GACT,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA4GD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE;AA4uBD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,oBAAoB,EAAE,EAC/B,OAAO,GAAE,0BAA+B,GACvC,mBAAmB,EAAE,CAsGvB;AA2YD,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,oBAAoB,EAAE,EACnC,OAAO,GAAE,0BAA+B,GACvC,MAAM,CAkJR;AAED,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,oBAAoB,EAAE,EACnC,OAAO,GAAE,0BAA+B,GACvC,MAAM,GAAG,IAAI,CA8Bf;AAmCD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,oBAAoB,EAAE,EACnC,OAAO,GAAE,0BAA+B,GACvC,MAAM,GAAG,IAAI,CAqBf"}
@@ -39,19 +39,23 @@ const ARTIFACT_RESOURCE_TYPES = new Set([
39
39
  "monitor",
40
40
  "form",
41
41
  ]);
42
- function persistedArtifactIdentitiesFromMarker(result) {
43
- const secret = process.env.A2A_SECRET;
44
- if (!secret)
42
+ function persistedArtifactIdentitiesFromMarker(result, secrets = process.env.A2A_SECRET
43
+ ? [process.env.A2A_SECRET]
44
+ : []) {
45
+ if (secrets.length === 0)
45
46
  return [];
46
47
  const match = result.match(/<!--\s*agent-native:persisted-artifacts=([A-Za-z0-9_-]+)\.([a-f0-9]{64})\s*-->/);
47
48
  if (!match)
48
49
  return [];
49
50
  try {
50
51
  const payload = match[1];
51
- const expected = createHmac("sha256", secret).update(payload).digest();
52
52
  const supplied = Buffer.from(match[2], "hex");
53
- if (supplied.length !== expected.length ||
54
- !timingSafeEqual(supplied, expected)) {
53
+ const verified = secrets.some((secret) => {
54
+ const expected = createHmac("sha256", secret).update(payload).digest();
55
+ return (supplied.length === expected.length &&
56
+ timingSafeEqual(supplied, expected));
57
+ });
58
+ if (!verified) {
55
59
  return [];
56
60
  }
57
61
  const parsed = JSON.parse(Buffer.from(payload, "base64url").toString());
@@ -71,9 +75,11 @@ function persistedArtifactIdentitiesFromMarker(result) {
71
75
  return [];
72
76
  }
73
77
  }
74
- function withPersistedArtifactMarker(text, toolResults) {
75
- const identities = extractA2AArtifactIdentities(toolResults).slice(0, 12);
76
- const secret = process.env.A2A_SECRET;
78
+ function withPersistedArtifactMarker(text, toolResults, secret = process.env.A2A_SECRET) {
79
+ const verificationSecrets = [secret, process.env.A2A_SECRET].filter((value, index, values) => !!value && values.indexOf(value) === index);
80
+ const identities = extractA2AArtifactIdentities(toolResults, {
81
+ persistedArtifactSecrets: verificationSecrets,
82
+ }).slice(0, 12);
77
83
  if (identities.length === 0 || !secret)
78
84
  return text;
79
85
  const payload = Buffer.from(JSON.stringify(identities)).toString("base64url");
@@ -667,7 +673,7 @@ function collectArtifacts(results) {
667
673
  * The ledger deliberately excludes raw tool results so it is safe to retain in
668
674
  * long-lived thread context and stable even when a resource is later renamed.
669
675
  */
670
- export function extractA2AArtifactIdentities(results) {
676
+ export function extractA2AArtifactIdentities(results, options = {}) {
671
677
  const identities = new Map();
672
678
  const remember = (identity) => {
673
679
  identities.set(`${identity.resourceType}:${identity.id}`, identity);
@@ -676,7 +682,7 @@ export function extractA2AArtifactIdentities(results) {
676
682
  if (result.isError === true || result.completedSideEffect === false)
677
683
  continue;
678
684
  if (result.tool === "call-agent") {
679
- for (const identity of persistedArtifactIdentitiesFromMarker(result.result)) {
685
+ for (const identity of persistedArtifactIdentitiesFromMarker(result.result, options.persistedArtifactSecrets)) {
680
686
  remember({ ...identity, sourceAction: "call-agent" });
681
687
  }
682
688
  continue;
@@ -1070,7 +1076,7 @@ export function appendA2AArtifactLinks(responseText, toolResults, options = {})
1070
1076
  const baseUrl = normalizeBaseUrl(options.baseUrl);
1071
1077
  const includeReferencedArtifacts = options.includeReferencedArtifacts ?? false;
1072
1078
  const finalize = (value) => options.includePersistedArtifactMarker
1073
- ? withPersistedArtifactMarker(value, toolResults)
1079
+ ? withPersistedArtifactMarker(value, toolResults, options.persistedArtifactSecret ?? process.env.A2A_SECRET)
1074
1080
  : value;
1075
1081
  const { documents, decks, dashboards, analyses, images, designShells, generatedDesigns, monitors, forms, } = collectArtifacts(toolResults);
1076
1082
  const generatedDesignIds = new Set(generatedDesigns.map((design) => design.id));