@agent-native/core 0.153.10 → 0.154.1

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 (149) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/AGENTS.md +20 -30
  3. package/corpus/templates/analytics/actions/search-dashboard-references.ts +58 -0
  4. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
  5. package/corpus/templates/analytics/app/lib/utils.ts +1 -1
  6. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewSqlPopover.tsx +1 -1
  7. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -0
  8. package/corpus/templates/analytics/server/lib/dashboards-store.ts +366 -3
  9. package/corpus/templates/analytics/server/lib/real-data-actions.ts +3 -1
  10. package/corpus/templates/analytics/server/plugins/agent-chat.ts +6 -2
  11. package/corpus/templates/calendar/app/components/calendar/EventDialog.tsx +1 -1
  12. package/corpus/templates/calendar/app/lib/utils.ts +1 -1
  13. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +32 -5
  14. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +15 -15
  15. package/corpus/templates/clips/app/i18n/en-US.ts +3 -3
  16. package/corpus/templates/clips/app/lib/utils.ts +5 -6
  17. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +43 -8
  18. package/corpus/templates/clips/desktop/src/app.tsx +26 -12
  19. package/corpus/templates/clips/desktop/src/lib/recorder.ts +23 -9
  20. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +261 -11
  21. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +21 -3
  22. package/corpus/templates/clips/shared/mic-audio-cleanup.ts +350 -0
  23. package/corpus/templates/content/actions/resolve-content-landing.ts +162 -32
  24. package/corpus/templates/content/app/i18n-data.ts +10 -10
  25. package/corpus/templates/content/scripts/check-native-deps.mjs +181 -15
  26. package/corpus/templates/content/shared/content-landing.ts +5 -0
  27. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +79 -7
  28. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +14 -2
  29. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +2 -2
  30. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +35 -11
  31. package/corpus/templates/design/actions/get-design-system.ts +103 -3
  32. package/corpus/templates/design/actions/import-design-tokens.ts +37 -8
  33. package/corpus/templates/design/actions/import-github.ts +32 -138
  34. package/corpus/templates/design/actions/index-design-system-with-builder.ts +49 -16
  35. package/corpus/templates/design/actions/present-design-variants.ts +93 -4
  36. package/corpus/templates/design/actions/run-design-audit.ts +229 -0
  37. package/corpus/templates/design/actions/sync-design-system-with-builder.ts +64 -0
  38. package/corpus/templates/design/app/components/design/code-workbench/commands.ts +2 -2
  39. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +17 -4
  40. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +5 -1
  41. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +5 -1
  42. package/corpus/templates/design/app/hooks/use-question-flow.ts +81 -5
  43. package/corpus/templates/design/app/i18n/en-US.ts +1 -1
  44. package/corpus/templates/design/app/i18n-data.ts +32 -1
  45. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +10 -10
  46. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +83 -11
  47. package/corpus/templates/design/app/pages/DesignSystems.tsx +14 -0
  48. package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +22 -0
  49. package/corpus/templates/design/changelog/2026-08-13-a-screen-that-would-render-behind-an-invisible-alpine-overla.md +6 -0
  50. package/corpus/templates/design/changelog/2026-08-13-attach-a-ui-screenshot-and-the-design-is-reproduced-not-rein.md +6 -0
  51. package/corpus/templates/design/changelog/2026-08-13-linking-a-design-system-means-you-never-get-generic-directio.md +6 -0
  52. package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-reports-when-a-screen-ignores-its-linke.md +6 -0
  53. package/corpus/templates/design/changelog/2026-08-13-the-design-system-preview-now-shows-how-many-named-tokens-we.md +6 -0
  54. package/corpus/templates/design/changelog/2026-08-13-your-design-system-prompt-and-reference-screenshots-now-reac.md +6 -0
  55. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +18 -2
  56. package/corpus/templates/design/shared/design-review.ts +1 -0
  57. package/corpus/templates/design/shared/html-integrity.ts +171 -0
  58. package/corpus/templates/mail/app/lib/utils.ts +1 -1
  59. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +10 -6
  60. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +41 -3
  61. package/corpus/templates/slides/actions/patch-deck.ts +12 -3
  62. package/corpus/templates/slides/actions/sync-design-system-with-builder.ts +64 -0
  63. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -1
  64. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +193 -20
  65. package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +73 -1
  66. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +64 -34
  67. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +34 -41
  68. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +119 -91
  69. package/corpus/templates/slides/app/components/editor/ImageOverlay.tsx +16 -0
  70. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +15 -0
  71. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +158 -31
  72. package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +30 -14
  73. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +2 -2
  74. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +4 -1
  75. package/corpus/templates/slides/app/components/editor/rich-text-selection.ts +14 -0
  76. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +24 -0
  77. package/corpus/templates/slides/app/context/DeckContext.tsx +19 -31
  78. package/corpus/templates/slides/app/global.css +24 -0
  79. package/corpus/templates/slides/app/hooks/use-navigation-state.ts +20 -17
  80. package/corpus/templates/slides/app/i18n/en-US.ts +19 -10
  81. package/corpus/templates/slides/app/lib/deck-filter.ts +47 -0
  82. package/corpus/templates/slides/app/lib/export-google-slides-client.ts +15 -4
  83. package/corpus/templates/slides/app/lib/export-pptx-client.ts +637 -1
  84. package/corpus/templates/slides/app/lib/image-download.ts +84 -0
  85. package/corpus/templates/slides/app/lib/utils.ts +1 -1
  86. package/corpus/templates/slides/app/pages/DeckEditor.tsx +9 -0
  87. package/corpus/templates/slides/app/pages/Index.tsx +25 -9
  88. package/corpus/templates/slides/changelog/2026-08-13-clicking-a-slide-thumbnail-now-focuses-it-so-the-slide-shortc.md +6 -0
  89. package/corpus/templates/slides/changelog/2026-08-13-duplicating-or-restoring-a-slide-now-keeps-its-transition-ani.md +6 -0
  90. package/corpus/templates/slides/changelog/2026-08-13-opening-presentation-mode-from-the-agent-now-starts-on-the-re.md +6 -0
  91. package/corpus/templates/slides/changelog/2026-08-13-slide-transitions-can-be-set-from-a-visible-control-in-the-sl.md +6 -0
  92. package/corpus/templates/slides/netlify.toml +1 -0
  93. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +14 -2
  94. package/dist/a2a/audience.d.ts +2 -0
  95. package/dist/a2a/audience.js +23 -0
  96. package/dist/a2a/client.d.ts +4 -0
  97. package/dist/a2a/client.js +32 -14
  98. package/dist/a2a/server.d.ts +9 -4
  99. package/dist/a2a/server.js +52 -25
  100. package/dist/a2a/types.d.ts +4 -4
  101. package/dist/agent/production-agent.js +1 -1
  102. package/dist/brand-kit/types.d.ts +10 -2
  103. package/dist/cli/code.js +1 -1
  104. package/dist/cli/index.js +30 -1
  105. package/dist/cli/native-dependencies.d.ts +24 -0
  106. package/dist/cli/native-dependencies.js +264 -0
  107. package/dist/cli/plan-local.js +1 -1
  108. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  109. package/dist/cli/skills-content/design-visual-edit-skill.js +2 -2
  110. package/dist/cli/visualize-repo.js +1 -1
  111. package/dist/client/FeedbackButton.js +12 -12
  112. package/dist/client/agent-chat-adapter.js +3 -4
  113. package/dist/client/assistant-ui-recovery.d.ts +1 -1
  114. package/dist/client/assistant-ui-recovery.js +4 -0
  115. package/dist/client/chat/message-components.d.ts +11 -3
  116. package/dist/client/chat/message-components.js +31 -5
  117. package/dist/client/chat/tool-call-display.d.ts +2 -1
  118. package/dist/client/chat/tool-call-display.js +33 -15
  119. package/dist/client/db-admin/SqlEditor.js +1 -1
  120. package/dist/client/dev-overlay/DevOverlay.js +2 -2
  121. package/dist/client/extensions/portable-extension.js +4 -0
  122. package/dist/client/guided-questions.d.ts +8 -0
  123. package/dist/client/guided-questions.js +12 -3
  124. package/dist/client/sharing/ShareButton.js +16 -24
  125. package/dist/client/sse-event-processor.js +35 -15
  126. package/dist/client/tool-display.d.ts +9 -0
  127. package/dist/client/tool-display.js +39 -0
  128. package/dist/client/vite-dev-recovery-script.js +1 -1
  129. package/dist/collab/awareness.d.ts +2 -2
  130. package/dist/collab/routes.d.ts +1 -1
  131. package/dist/collab/struct-routes.d.ts +1 -1
  132. package/dist/extensions/html-shell.js +5 -0
  133. package/dist/notifications/routes.d.ts +1 -1
  134. package/dist/observability/routes.d.ts +3 -3
  135. package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
  136. package/dist/server/agent-capabilities.js +0 -0
  137. package/dist/server/agent-chat/action-filters-a2a.d.ts +14 -13
  138. package/dist/server/agent-chat/action-filters-a2a.js +59 -23
  139. package/dist/server/agent-chat/prompt-resources.js +17 -16
  140. package/dist/server/agent-chat-plugin.d.ts +9 -0
  141. package/dist/server/agent-chat-plugin.js +29 -7
  142. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  143. package/dist/server/builder-design-systems.d.ts +33 -1
  144. package/dist/server/builder-design-systems.js +293 -11
  145. package/dist/server/design-token-utils.d.ts +11 -0
  146. package/dist/server/design-token-utils.js +68 -16
  147. package/dist/server/index.d.ts +1 -1
  148. package/dist/server/index.js +1 -1
  149. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "../agent/engine/credential-errors.js";
2
2
  import { emitChatFirstOpenApp } from "./chat-first.js";
3
3
  import { formatChatErrorText, normalizeChatError } from "./error-format.js";
4
- import { humanizeToolLabelText, humanizeToolName, runningToolLabel, } from "./tool-display.js";
4
+ import { humanizeToolLabelText, humanizeToolName, isToolCallActive, runningToolLabel, } from "./tool-display.js";
5
5
  /**
6
6
  * Kept verbatim in sync with `INTERRUPTED_TOOL_RESULT_MARKER`
7
7
  * (agent/production-agent.ts): the server matches this substring in replayed
@@ -13,16 +13,21 @@ const INTERRUPTED_ACTIVITY_RESULT = "Stopped before this action started.";
13
13
  /**
14
14
  * Maximum number of assistant-ui repository updates we deliver in one browser
15
15
  * event-loop turn. Durable-run replay can put hundreds of SSE frames into the
16
- * stream queue before the client attaches; draining all of them through
17
- * assistant-ui without a macrotask boundary synchronously nests React external
18
- * store notifications until React throws "Maximum update depth exceeded."
16
+ * stream queue before the client attaches; allowing even a small burst through
17
+ * assistant-ui can synchronously nest React external-store notifications until
18
+ * React throws "Maximum update depth exceeded."
19
19
  *
20
- * A timer scheduled on the first result resets the count when the stream is
20
+ * A task scheduled on the first result resets the count when the stream is
21
21
  * naturally idle between network chunks. We only await it when results are
22
22
  * arriving densely enough to hit this bound, so normal live token streaming
23
23
  * keeps its existing latency while replay bursts yield cooperatively.
24
24
  */
25
- const SSE_RENDER_UPDATES_PER_EVENT_LOOP_TURN = 20;
25
+ const SSE_RENDER_UPDATES_PER_EVENT_LOOP_TURN = 1;
26
+ function waitForNextEventLoopTurn() {
27
+ return new Promise((resolve) => {
28
+ setTimeout(resolve, 0);
29
+ });
30
+ }
26
31
  export function settleInterruptedToolCalls(content, result = INTERRUPTED_TOOL_RESULT, options) {
27
32
  let changed = false;
28
33
  for (const part of content) {
@@ -825,6 +830,8 @@ function hasCompletedCustomUi(content) {
825
830
  return hasCompletedTool && lastCompletedToolIsCustomUi;
826
831
  }
827
832
  export function appendMissingFinalResponseWarning(content, completedToolNames) {
833
+ if (content.some((part) => isToolCallActive(part)))
834
+ return null;
828
835
  const lastTextIndex = lastAssistantTextIndex(content);
829
836
  const successfulToolNames = [
830
837
  ...new Set(completedToolNames ?? completedToolNamesAfterLastAssistantText(content)),
@@ -1245,6 +1252,7 @@ export function processEvent(ev, content, toolCallCounter, tabId, state) {
1245
1252
  : "Done";
1246
1253
  part.structuredMeta = {
1247
1254
  ...part.structuredMeta,
1255
+ ...(ev.status === "pending" ? { agentPending: true } : {}),
1248
1256
  ...(ev.durationMs != null
1249
1257
  ? { agentDurationMs: ev.durationMs }
1250
1258
  : {}),
@@ -1618,15 +1626,19 @@ export async function* readSSEStream(body, content, toolCallCounter, tabId, onSe
1618
1626
  const currentNoProgressTimeoutMs = () => inFlightWork > 0
1619
1627
  ? Math.max(noProgressTimeoutMs, SSE_IN_FLIGHT_WORK_TIMEOUT_MS)
1620
1628
  : noProgressTimeoutMs;
1621
- const paceRenderUpdate = async () => {
1629
+ const paceRenderUpdate = async (hasBufferedEvent) => {
1630
+ // A single event in a network chunk already has a natural read boundary.
1631
+ // Avoid inserting a task into quiet streams so watchdogs and fake-clock
1632
+ // consumers can continue to observe their own timers normally.
1633
+ if (!hasBufferedEvent) {
1634
+ renderUpdatesThisTurn = 0;
1635
+ return;
1636
+ }
1622
1637
  renderUpdatesThisTurn += 1;
1623
1638
  if (!nextEventLoopTurn) {
1624
- nextEventLoopTurn = new Promise((resolve) => {
1625
- setTimeout(() => {
1626
- renderUpdatesThisTurn = 0;
1627
- nextEventLoopTurn = null;
1628
- resolve();
1629
- }, 0);
1639
+ nextEventLoopTurn = waitForNextEventLoopTurn().then(() => {
1640
+ renderUpdatesThisTurn = 0;
1641
+ nextEventLoopTurn = null;
1630
1642
  });
1631
1643
  }
1632
1644
  if (renderUpdatesThisTurn >= SSE_RENDER_UPDATES_PER_EVENT_LOOP_TURN) {
@@ -1686,12 +1698,19 @@ export async function* readSSEStream(body, content, toolCallCounter, tabId, onSe
1686
1698
  const lines = buf.split("\n");
1687
1699
  buf = lines.pop() ?? "";
1688
1700
  let sawProgressEvent = false;
1689
- for (const line of lines) {
1701
+ let bufferedDataEvents = lines.reduce((count, pendingLine) => count +
1702
+ (pendingLine.startsWith("data: ") &&
1703
+ pendingLine.slice(6).trim().length > 0
1704
+ ? 1
1705
+ : 0), 0);
1706
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
1707
+ const line = lines[lineIndex];
1690
1708
  if (!line.startsWith("data: "))
1691
1709
  continue;
1692
1710
  const raw = line.slice(6).trim();
1693
1711
  if (!raw)
1694
1712
  continue;
1713
+ bufferedDataEvents -= 1;
1695
1714
  let ev;
1696
1715
  try {
1697
1716
  ev = JSON.parse(raw);
@@ -1751,7 +1770,8 @@ export async function* readSSEStream(body, content, toolCallCounter, tabId, onSe
1751
1770
  }
1752
1771
  : result;
1753
1772
  if (terminalResult) {
1754
- await paceRenderUpdate();
1773
+ const hasBufferedEvent = bufferedDataEvents > 0;
1774
+ await paceRenderUpdate(hasBufferedEvent);
1755
1775
  yield withStreamMetadata(terminalResult);
1756
1776
  }
1757
1777
  if (hasStalledPreparingAction(preparingActionState, Date.now(), preparationStallTimeoutMs)) {
@@ -7,7 +7,16 @@ type ToolDisplayPart = {
7
7
  toolName?: string;
8
8
  argsText?: string;
9
9
  args?: Record<string, unknown>;
10
+ result?: unknown;
11
+ outcome?: "unknown";
12
+ activity?: boolean;
13
+ structuredMeta?: Record<string, unknown>;
10
14
  };
15
+ export declare function isDelegatedAgentToolCall(part: ToolDisplayPart): boolean;
16
+ /** True when a tool has not reported a result and the stream did not mark it unknown. */
17
+ export declare function isToolCallInFlight(part: ToolDisplayPart): boolean;
18
+ /** True when the UI must not present this tool as finished. */
19
+ export declare function isToolCallActive(part: ToolDisplayPart): boolean;
11
20
  /**
12
21
  * `call-agent` emits both its ordinary tool row and a richer `agent:<name>`
13
22
  * progress row. Keep the ordinary part in message state for tool completion
@@ -33,6 +33,45 @@ export function humanizeToolLabelText(label, toolName) {
33
33
  return text;
34
34
  return text.split(tool).join(humanizeToolName(tool));
35
35
  }
36
+ const ACTIVE_AGENT_ACTIVITY_PHASES = new Set([
37
+ "reasoning",
38
+ "tool",
39
+ "responding",
40
+ ]);
41
+ export function isDelegatedAgentToolCall(part) {
42
+ return (part.type === "tool-call" && part.toolName?.startsWith("agent:") === true);
43
+ }
44
+ function hasActiveDelegatedAgentActivity(part) {
45
+ const snapshot = part.structuredMeta?.agentActivity;
46
+ if (!snapshot || typeof snapshot !== "object")
47
+ return false;
48
+ const record = snapshot;
49
+ if (typeof record.activePhase === "string" &&
50
+ ACTIVE_AGENT_ACTIVITY_PHASES.has(record.activePhase)) {
51
+ return true;
52
+ }
53
+ return (Array.isArray(record.toolCalls) &&
54
+ record.toolCalls.some((tool) => tool != null &&
55
+ typeof tool === "object" &&
56
+ tool.status === "running"));
57
+ }
58
+ /** True when a tool has not reported a result and the stream did not mark it unknown. */
59
+ export function isToolCallInFlight(part) {
60
+ if (part.type !== "tool-call")
61
+ return false;
62
+ if (part.result !== undefined || part.outcome === "unknown")
63
+ return false;
64
+ return part.activity !== true || isDelegatedAgentToolCall(part);
65
+ }
66
+ /** True when the UI must not present this tool as finished. */
67
+ export function isToolCallActive(part) {
68
+ if (isToolCallInFlight(part))
69
+ return true;
70
+ return (isDelegatedAgentToolCall(part) &&
71
+ part.outcome !== "unknown" &&
72
+ (part.structuredMeta?.agentPending === true ||
73
+ hasActiveDelegatedAgentActivity(part)));
74
+ }
36
75
  function normalizedAgentName(value) {
37
76
  if (typeof value !== "string")
38
77
  return null;
@@ -87,7 +87,7 @@ export function getViteDevRecoveryScript() {
87
87
  console.warn("[agent-native] Dev server keeps re-bundling. Manual refresh needed.", reason);
88
88
  showOverlay(
89
89
  "Dev server out of sync",
90
- "Auto-reload gave up after " + MAX_RELOADS + " tries. Refresh the page (\\u2318R / Ctrl+R)."
90
+ "Auto-reload gave up after " + MAX_RELOADS + " tries. Refresh the page (\\u2318R / Ctrl R)."
91
91
  );
92
92
  return;
93
93
  }
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
62
62
  error: string;
63
63
  states?: undefined;
64
64
  } | {
65
- error?: undefined;
66
65
  states: {
67
66
  clientId: number;
68
67
  state: string;
69
68
  }[];
69
+ error?: undefined;
70
70
  }>>;
71
71
  /**
72
72
  * GET /_agent-native/collab/:docId/users
@@ -77,9 +77,9 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
77
77
  error: string;
78
78
  users?: undefined;
79
79
  } | {
80
- error?: undefined;
81
80
  users: {
82
81
  clientId: number;
83
82
  lastSeen: number;
84
83
  }[];
84
+ error?: undefined;
85
85
  }>>;
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- error: string;
17
16
  ok?: undefined;
17
+ error: string;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -147,6 +147,11 @@ export function buildExtensionHtml(content, themeVars, isDark, extensionId, bind
147
147
  </style>
148
148
  <style>
149
149
  *, *::before, *::after { border-color: hsl(var(--border)); }
150
+ /* Alpine only honours x-cloak when a stylesheet hides it, and extension
151
+ content is a body snippet that cannot supply one. Without this, an
152
+ x-cloak overlay paints over the whole extension until Alpine boots —
153
+ and forever if it never does. */
154
+ [x-cloak] { display: none !important; }
150
155
  html, body {
151
156
  /* Transparent so the iframe inherits the host surface (dashboard panel,
152
157
  sidebar, chat) instead of painting the browser's default white canvas.
@@ -28,6 +28,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- error?: undefined;
32
31
  ok: boolean;
32
+ error?: undefined;
33
33
  }>>;
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
- error?: undefined;
45
44
  summary: import("./types.js").TraceSummary;
46
45
  spans: import("./types.js").TraceSpan[];
47
46
  id?: undefined;
47
+ error?: undefined;
48
48
  ok?: undefined;
49
49
  } | {
50
- error?: undefined;
51
50
  summary?: undefined;
52
51
  spans?: undefined;
53
52
  id: string;
53
+ error?: undefined;
54
54
  ok?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
@@ -59,9 +59,9 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
59
59
  error: any;
60
60
  ok?: undefined;
61
61
  } | {
62
- error?: undefined;
63
62
  summary?: undefined;
64
63
  spans?: undefined;
65
64
  id?: undefined;
66
65
  ok: boolean;
66
+ error?: undefined;
67
67
  }>>;
@@ -75,8 +75,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
- id?: undefined;
79
78
  deleted?: undefined;
79
+ id?: undefined;
80
80
  provider?: undefined;
81
81
  providers: {
82
82
  id: string;
@@ -93,8 +93,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
93
93
  label?: undefined;
94
94
  message?: undefined;
95
95
  } | {
96
- id?: undefined;
97
96
  deleted?: undefined;
97
+ id?: undefined;
98
98
  providers?: undefined;
99
99
  count?: undefined;
100
100
  found: boolean;
Binary file
@@ -1,4 +1,5 @@
1
1
  import { type A2AArtifactResponseOptions, type A2AToolResultSummary } from "../../a2a/artifact-response.js";
2
+ import type { AgentSkill } from "../../a2a/types.js";
2
3
  import type { EngineTool } from "../../agent/engine/types.js";
3
4
  import { type ActionEntry, type AgentLoopOutcome } from "../../agent/production-agent.js";
4
5
  import { runAgentLoopDirectWithSoftTimeout } from "../../agent/run-loop-with-resume.js";
@@ -44,6 +45,13 @@ export interface A2AExternalAgentSurface {
44
45
  * query the caller wrote.
45
46
  */
46
47
  export declare function filterDirectA2AActions(actions: Record<string, ActionEntry>, options: A2AExternalAgentSurface): Record<string, ActionEntry>;
48
+ /**
49
+ * Authenticated write capabilities that a sibling may delegate to this app's
50
+ * agent, but never invoke directly. `publicAgent` is the action-owned opt-in;
51
+ * keeping this projection independent of `connectorCatalog` avoids making apps
52
+ * maintain a second capability registry. The deny list remains a final veto.
53
+ */
54
+ export declare function filterDelegatedA2ACapabilityActions(actions: Record<string, ActionEntry>, options: A2AExternalAgentSurface): Record<string, ActionEntry>;
47
55
  export declare function buildPublicAgentA2ASkills(actions: Record<string, ActionEntry>): Array<{
48
56
  id: string;
49
57
  name: string;
@@ -52,20 +60,13 @@ export declare function buildPublicAgentA2ASkills(actions: Record<string, Action
52
60
  inputSchema?: Record<string, unknown>;
53
61
  }>;
54
62
  /**
55
- * Skills for a caller with a verified A2A identity: exactly what
56
- * `filterDirectA2AActions` will execute. Kept separate from
57
- * `buildPublicAgentA2ASkills` because the public card may only name actions
58
- * with `requiresAuth !== true` while direct invocation requires
59
- * `requiresAuth === true` — advertising the public set alone tells siblings
60
- * an app has nothing callable when it does.
63
+ * Skills for a caller with a verified A2A identity. Exact bounded reads carry
64
+ * schemas and may be invoked directly; explicitly exposed writes carry no
65
+ * schema and are discoverable only as natural-language delegation targets.
66
+ * Kept separate from `buildPublicAgentA2ASkills` because neither authenticated
67
+ * surface may be disclosed by the anonymous card.
61
68
  */
62
- export declare function buildAuthenticatedAgentA2ASkills(actions: Record<string, ActionEntry>, options: A2AExternalAgentSurface): Array<{
63
- id: string;
64
- name: string;
65
- description: string;
66
- publicAgent: ActionEntry["publicAgent"];
67
- inputSchema?: Record<string, unknown>;
68
- }>;
69
+ export declare function buildAuthenticatedAgentA2ASkills(actions: Record<string, ActionEntry>, options: A2AExternalAgentSurface): AgentSkill[];
69
70
  export declare function resolveArtifactBaseUrl(event: any | undefined): string | undefined;
70
71
  export declare function assembleA2AFinalResponse(events: readonly AgentChatEvent[], toolResults: readonly A2AToolResultSummary[], options?: A2AArtifactResponseOptions & {
71
72
  event?: any;
@@ -96,6 +96,24 @@ export function filterDirectA2AActions(actions, options) {
96
96
  exposure.isConsequential !== true);
97
97
  }));
98
98
  }
99
+ /**
100
+ * Authenticated write capabilities that a sibling may delegate to this app's
101
+ * agent, but never invoke directly. `publicAgent` is the action-owned opt-in;
102
+ * keeping this projection independent of `connectorCatalog` avoids making apps
103
+ * maintain a second capability registry. The deny list remains a final veto.
104
+ */
105
+ export function filterDelegatedA2ACapabilityActions(actions, options) {
106
+ const denied = new Set(options.externalAgents?.denyActions ?? []);
107
+ return Object.fromEntries(Object.entries(actions).filter(([name, entry]) => {
108
+ const exposure = entry.publicAgent;
109
+ return (!denied.has(name) &&
110
+ entry.agentTool !== false &&
111
+ entry.readOnly !== true &&
112
+ exposure?.expose === true &&
113
+ exposure.readOnly === false &&
114
+ exposure.requiresAuth === true);
115
+ }));
116
+ }
99
117
  export function buildPublicAgentA2ASkills(actions) {
100
118
  return Object.entries(filterPublicAgentActions(actions)).map(([name, entry]) => ({
101
119
  id: name,
@@ -110,31 +128,49 @@ export function buildPublicAgentA2ASkills(actions) {
110
128
  }));
111
129
  }
112
130
  /**
113
- * Skills for a caller with a verified A2A identity: exactly what
114
- * `filterDirectA2AActions` will execute. Kept separate from
115
- * `buildPublicAgentA2ASkills` because the public card may only name actions
116
- * with `requiresAuth !== true` while direct invocation requires
117
- * `requiresAuth === true` — advertising the public set alone tells siblings
118
- * an app has nothing callable when it does.
131
+ * Skills for a caller with a verified A2A identity. Exact bounded reads carry
132
+ * schemas and may be invoked directly; explicitly exposed writes carry no
133
+ * schema and are discoverable only as natural-language delegation targets.
134
+ * Kept separate from `buildPublicAgentA2ASkills` because neither authenticated
135
+ * surface may be disclosed by the anonymous card.
119
136
  */
120
137
  export function buildAuthenticatedAgentA2ASkills(actions, options) {
121
- return Object.entries(filterDirectA2AActions(actions, options)).map(([name, entry]) => ({
122
- id: name,
123
- name,
124
- description: entry.tool.description,
125
- publicAgent: entry.publicAgent,
126
- // Every action in this set is read-only by construction. Omitting the
127
- // flag made discovery label all of them "(mutating)", which pushes a
128
- // caller away from invoking them and back into open-ended delegation.
129
- readOnly: true,
130
- // Naming an action without its parameters is what makes a caller invoke
131
- // it with `{}` and fail on a required field.
132
- ...(entry.tool.parameters
133
- ? {
134
- inputSchema: entry.tool.parameters,
135
- }
136
- : {}),
137
- }));
138
+ const directActions = filterDirectA2AActions(actions, options);
139
+ const delegatedActions = filterDelegatedA2ACapabilityActions(actions, options);
140
+ return Object.entries(actions).flatMap(([name, entry]) => {
141
+ const directEntry = directActions[name];
142
+ const delegatedEntry = delegatedActions[name];
143
+ if (!directEntry && !delegatedEntry)
144
+ return [];
145
+ if (directEntry) {
146
+ return {
147
+ id: name,
148
+ name,
149
+ description: entry.tool.description,
150
+ publicAgent: entry.publicAgent,
151
+ // Every action in this set is read-only by construction. Omitting the
152
+ // flag made discovery label all of them "(mutating)", which pushes a
153
+ // caller away from invoking them and back into open-ended delegation.
154
+ readOnly: true,
155
+ // Naming a directly callable action without its parameters is what
156
+ // makes a caller invoke it with `{}` and fail on a required field.
157
+ ...(entry.tool.parameters
158
+ ? {
159
+ inputSchema: entry.tool.parameters,
160
+ }
161
+ : {}),
162
+ };
163
+ }
164
+ return {
165
+ id: name,
166
+ name,
167
+ description: entry.tool.description,
168
+ publicAgent: entry.publicAgent,
169
+ // No input schema: the sibling sends an objective to the receiving app,
170
+ // whose agent chooses and validates its own local actions.
171
+ readOnly: false,
172
+ };
173
+ });
138
174
  }
139
175
  export function resolveArtifactBaseUrl(event) {
140
176
  const fromEnv = process.env.APP_URL ||
@@ -416,21 +416,22 @@ export function resourceScopeForOwner(owner, currentOwner) {
416
416
  return "resource";
417
417
  }
418
418
  async function loadAgentsResourceForPrompt(owner, scope, maxChars = SHARED_PROMPT_RESOURCE_MAX_CHARS) {
419
+ let agents;
419
420
  try {
420
- const agents = await resourceGetByPath(owner, "AGENTS.md");
421
- if (!agents?.content?.trim())
422
- return null;
423
- return promptResourceBlock({
424
- name: "AGENTS.md",
425
- scope,
426
- path: "AGENTS.md",
427
- content: agents.content,
428
- maxChars,
429
- });
421
+ agents = await resourceGetByPath(owner, "AGENTS.md");
430
422
  }
431
- catch {
432
- return null;
423
+ catch (error) {
424
+ throw new Error(`Unable to read durable AGENTS.md instructions for ${scope} (${owner}). The run cannot safely continue without them.`, { cause: error });
433
425
  }
426
+ if (!agents?.content?.trim())
427
+ return null;
428
+ return promptResourceBlock({
429
+ name: "AGENTS.md",
430
+ scope,
431
+ path: "AGENTS.md",
432
+ content: agents.content,
433
+ maxChars,
434
+ });
434
435
  }
435
436
  async function loadInstructionResourcesForPrompt(owner, scope, maxChars = SHARED_PROMPT_RESOURCE_MAX_CHARS, summaryOnly = false) {
436
437
  try {
@@ -671,14 +672,14 @@ export async function loadResourcesForPrompt(owner, compact = false, selfAppId,
671
672
  // every app in the workspace, not copied into app scopes. They may come from
672
673
  // SQL, Dispatch, or local file mode.
673
674
  const workspaceAgents = await loadAgentsResourceForPrompt(WORKSPACE_OWNER, "workspace", promptResourceMaxChars);
674
- addSection(workspaceAgents);
675
+ addSection(workspaceAgents, "required");
675
676
  addSections(await loadInstructionResourcesForPrompt(WORKSPACE_OWNER, "workspace-instruction", promptResourceMaxChars, compact));
676
677
  const organizationOwner = sharedResourceOwner(orgId);
677
678
  // 4. Legacy app-wide defaults. Existing deployments keep their seeded
678
679
  // shared guidance as an inherited fallback; organization writes never
679
680
  // mutate this owner.
680
681
  const appDefaultAgents = await loadAgentsResourceForPrompt(SHARED_OWNER, organizationOwner === SHARED_OWNER ? "shared" : "app-default", promptResourceMaxChars);
681
- addSection(appDefaultAgents);
682
+ addSection(appDefaultAgents, "required");
682
683
  addSections(await loadInstructionResourcesForPrompt(SHARED_OWNER, organizationOwner === SHARED_OWNER
683
684
  ? "shared-instruction"
684
685
  : "app-default-instruction", promptResourceMaxChars, compact));
@@ -686,14 +687,14 @@ export async function loadResourcesForPrompt(owner, compact = false, selfAppId,
686
687
  // learnings that Slack/integration runs share with interactive app chat.
687
688
  if (organizationOwner !== SHARED_OWNER) {
688
689
  const organizationAgents = await loadAgentsResourceForPrompt(organizationOwner, "organization", promptResourceMaxChars);
689
- addSection(organizationAgents);
690
+ addSection(organizationAgents, "required");
690
691
  addSections(await loadInstructionResourcesForPrompt(organizationOwner, "organization-instruction", promptResourceMaxChars, compact));
691
692
  }
692
693
  // 6. Personal SQL resources. These come last in the instruction stack so a
693
694
  // user can narrow or override organization/app and workspace defaults.
694
695
  if (owner !== SHARED_OWNER && owner !== WORKSPACE_OWNER) {
695
696
  const personalAgents = await loadAgentsResourceForPrompt(owner, "personal", promptResourceMaxChars);
696
- addSection(personalAgents, "user");
697
+ addSection(personalAgents, "required");
697
698
  addSections(await loadInstructionResourcesForPrompt(owner, "personal-instruction", promptResourceMaxChars, compact), "user");
698
699
  }
699
700
  const resourceSkillsBlock = await loadResourceSkillsPromptBlock(owner, orgId);
@@ -16,6 +16,15 @@ export { loadResourcesForPrompt };
16
16
  export { _agentChatPromptSectionsForTests };
17
17
  export { buildPublicAgentA2ASkills };
18
18
  export { assembleA2AFinalResponse };
19
+ export declare function buildLeanSystemPrompt(input: {
20
+ basePrompt: string;
21
+ resources: string;
22
+ additionalFramework?: string;
23
+ cacheSplit?: string;
24
+ extra?: string;
25
+ modelOverlay?: string;
26
+ runtimeContext?: string;
27
+ }): string;
19
28
  export type { AgentChatPluginOptions };
20
29
  export { runA2AAgentLoop };
21
30
  export { runMCPAgentLoop };
@@ -125,6 +125,15 @@ export { loadResourcesForPrompt };
125
125
  export { _agentChatPromptSectionsForTests };
126
126
  export { buildPublicAgentA2ASkills };
127
127
  export { assembleA2AFinalResponse };
128
+ export function buildLeanSystemPrompt(input) {
129
+ return (input.basePrompt +
130
+ (input.additionalFramework ?? "") +
131
+ (input.cacheSplit ?? "") +
132
+ input.resources +
133
+ (input.extra ?? "") +
134
+ (input.modelOverlay ?? "") +
135
+ (input.runtimeContext ?? ""));
136
+ }
128
137
  export { runA2AAgentLoop };
129
138
  export { runMCPAgentLoop };
130
139
  export { createA2AEngineToolSurface };
@@ -2601,20 +2610,25 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
2601
2610
  // so everything after it can change without a cache write.
2602
2611
  if (leanPrompt) {
2603
2612
  const leanRunPolicyPrompt = buildLeanRunPolicyPrompt(codeEditingSurfaceRestriction, prodCodeExecPromptNote);
2613
+ const resources = await loadResourcesForPrompt(owner, true, options?.appId, undefined, { disabledFrameworkGroups });
2604
2614
  await emitContextXraySystemSections(event, {
2605
2615
  frameworkPrompt: leanBasePrompt.slice(0, Math.max(0, leanBasePrompt.length - leanActionsPrompt.length)),
2606
2616
  actionsPrompt: leanActionsPrompt,
2607
2617
  additionalFramework: leanRunPolicyPrompt,
2618
+ resources,
2608
2619
  extra,
2609
2620
  modelOverlay,
2610
2621
  runtimeContext,
2611
2622
  });
2612
- return setSystemPromptOnContext(leanBasePrompt +
2613
- leanRunPolicyPrompt +
2614
- SYSTEM_PROMPT_CACHE_SPLIT +
2615
- extra +
2616
- modelOverlay +
2617
- runtimeContext);
2623
+ return setSystemPromptOnContext(buildLeanSystemPrompt({
2624
+ basePrompt: leanBasePrompt,
2625
+ additionalFramework: leanRunPolicyPrompt,
2626
+ cacheSplit: SYSTEM_PROMPT_CACHE_SPLIT,
2627
+ resources,
2628
+ extra,
2629
+ modelOverlay,
2630
+ runtimeContext,
2631
+ }));
2618
2632
  }
2619
2633
  const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
2620
2634
  // In lazy context mode, skip embedding the full schema. When database
@@ -2840,14 +2854,22 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
2840
2854
  // cached prompt prefix as possible. See the prod handler above
2841
2855
  // for the same pattern.
2842
2856
  if (leanPrompt) {
2857
+ const resources = await loadResourcesForPrompt(owner, true, options?.appId, undefined, { disabledFrameworkGroups });
2843
2858
  await emitContextXraySystemSections(event, {
2844
2859
  frameworkPrompt: leanBasePrompt.slice(0, Math.max(0, leanBasePrompt.length - leanActionsPrompt.length)),
2845
2860
  actionsPrompt: leanActionsPrompt,
2861
+ resources,
2846
2862
  extra,
2847
2863
  modelOverlay,
2848
2864
  runtimeContext,
2849
2865
  });
2850
- return setSystemPromptOnContext(leanBasePrompt + extra + modelOverlay + runtimeContext);
2866
+ return setSystemPromptOnContext(buildLeanSystemPrompt({
2867
+ basePrompt: leanBasePrompt,
2868
+ resources,
2869
+ extra,
2870
+ modelOverlay,
2871
+ runtimeContext,
2872
+ }));
2851
2873
  }
2852
2874
  const resources = await loadResourcesForPrompt(owner, lazyContext, options?.appId, undefined, { disabledFrameworkGroups });
2853
2875
  const schemaBlock = lazyContext || !databaseToolsEnabled
@@ -27,10 +27,10 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
- error?: undefined;
31
30
  ok: boolean;
32
31
  key: string;
33
32
  baseUrlKey?: string;
34
33
  scope: AgentEngineApiKeyScope;
34
+ error?: undefined;
35
35
  }>>;
36
36
  export {};