@agent-native/core 0.157.3 → 0.157.5

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 (211) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  3. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +21 -0
  4. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +40 -1
  5. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  6. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +21 -0
  7. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  8. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +21 -0
  9. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  10. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +21 -0
  11. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  12. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  13. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  14. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  15. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +7 -7
  16. package/corpus/templates/clips/actions/approve-recording-access-request.ts +147 -0
  17. package/corpus/templates/clips/actions/request-recording-access.ts +121 -23
  18. package/corpus/templates/clips/actions/view-screen.ts +1 -1
  19. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +34 -53
  20. package/corpus/templates/clips/app/components/player/request-access-dialog.tsx +104 -0
  21. package/corpus/templates/clips/app/components/player/share-dialog.tsx +36 -45
  22. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -6
  23. package/corpus/templates/clips/app/i18n/en-US.ts +26 -1
  24. package/corpus/templates/clips/app/lib/public-meeting.ts +1 -1
  25. package/corpus/templates/clips/app/routes/access-request.approve.tsx +250 -0
  26. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +9 -32
  27. package/corpus/templates/clips/app/routes/share.$shareId.tsx +123 -37
  28. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +41 -1
  29. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -0
  30. package/corpus/templates/clips/server/lib/emails.ts +40 -11
  31. package/corpus/templates/clips/shared/recording-link.ts +32 -1
  32. package/corpus/templates/clips/shared/share-attribution.ts +13 -0
  33. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  34. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +21 -0
  35. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +22 -10
  36. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +2 -1
  37. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +245 -9
  38. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +185 -134
  39. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +61 -45
  40. package/corpus/templates/content/app/components/editor/extensions/ImageNode.ts +6 -0
  41. package/corpus/templates/content/app/components/editor/image-upload.ts +137 -5
  42. package/corpus/templates/content/app/global.css +8 -0
  43. package/corpus/templates/content/changelog/2026-08-12-image-uploads-now-confirm-the-image-can-be-displayed-before-.md +6 -0
  44. package/corpus/templates/content/changelog/2026-08-14-images-fill-the-page-width-by-default-and-remain-visible-whe.md +6 -0
  45. package/corpus/templates/content/changelog/2026-08-14-images-inserted-from-the-slash-command-stay-saved-after-uplo.md +6 -0
  46. package/corpus/templates/content/changelog/2026-08-14-svg-files-can-be-selected-reliably-from-the-image-picker.md +6 -0
  47. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  48. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +21 -0
  49. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  50. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +21 -0
  51. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  52. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +21 -0
  53. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  54. package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +21 -0
  55. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  56. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +21 -0
  57. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  58. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +21 -0
  59. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  60. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +21 -0
  61. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -1
  62. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  63. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +21 -0
  64. package/corpus/templates/plan/app/pages/PlansPage.tsx +25 -30
  65. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  66. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +21 -0
  67. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +2 -1
  68. package/corpus/templates/slides/app/components/editor/ShareDialog.tsx +124 -180
  69. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +1 -0
  70. package/corpus/templates/slides/app/global.css +99 -3
  71. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  72. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  73. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +21 -0
  74. package/dist/chat-threads/schema.d.ts +1 -1
  75. package/dist/cli/code-agent-executor.js +318 -0
  76. package/dist/client/AgentPanel.d.ts +13 -1
  77. package/dist/client/AgentPanel.js +41 -3
  78. package/dist/client/AssistantChat.d.ts +9 -1
  79. package/dist/client/AssistantChat.js +26 -13
  80. package/dist/client/MultiTabAssistantChat.js +18 -5
  81. package/dist/client/agent-chat.d.ts +8 -0
  82. package/dist/client/agent-chat.js +15 -0
  83. package/dist/client/app-chat-sidebar.d.ts +23 -0
  84. package/dist/client/app-chat-sidebar.js +53 -0
  85. package/dist/client/app-providers.js +31 -2
  86. package/dist/client/frame-protocol.d.ts +20 -2
  87. package/dist/client/hooks/index.d.ts +1 -0
  88. package/dist/client/hooks/index.js +1 -0
  89. package/dist/client/sharing/AgentShareSection.d.ts +8 -0
  90. package/dist/client/sharing/AgentShareSection.js +50 -0
  91. package/dist/client/sharing/ShareButton.js +2 -1
  92. package/dist/client/sharing/ShareDialog.d.ts +2 -2
  93. package/dist/client/sharing/ShareDialog.js +21 -29
  94. package/dist/client/sharing/index.d.ts +1 -0
  95. package/dist/client/sharing/index.js +1 -0
  96. package/dist/client/sharing/useShareButtonController.d.ts +1 -0
  97. package/dist/client/sharing/useShareDialogController.d.ts +3 -0
  98. package/dist/client/sharing/useShareDialogController.js +2 -1
  99. package/dist/client/theme.d.ts +21 -0
  100. package/dist/client/theme.js +60 -0
  101. package/dist/client/ui/index.d.ts +1 -1
  102. package/dist/client/ui/index.js +1 -1
  103. package/dist/client/use-session.js +23 -0
  104. package/dist/collab/awareness.d.ts +2 -2
  105. package/dist/collab/struct-routes.d.ts +1 -1
  106. package/dist/dashboard-storage/schema.d.ts +1 -1
  107. package/dist/data-programs/schema.d.ts +1 -1
  108. package/dist/extensions/schema.d.ts +1 -1
  109. package/dist/localization/core-messages/ar-SA.js +6 -0
  110. package/dist/localization/core-messages/de-DE.js +6 -0
  111. package/dist/localization/core-messages/en-US.d.ts +6 -0
  112. package/dist/localization/core-messages/en-US.js +6 -0
  113. package/dist/localization/core-messages/es-ES.js +6 -0
  114. package/dist/localization/core-messages/fr-FR.js +6 -0
  115. package/dist/localization/core-messages/hi-IN.js +6 -0
  116. package/dist/localization/core-messages/ja-JP.js +6 -0
  117. package/dist/localization/core-messages/ko-KR.js +6 -0
  118. package/dist/localization/core-messages/pt-BR.js +6 -0
  119. package/dist/localization/core-messages/zh-CN.js +6 -0
  120. package/dist/localization/core-messages/zh-TW.js +6 -0
  121. package/dist/localization/core-messages.d.ts +6 -0
  122. package/dist/localization/default-messages.d.ts +1 -0
  123. package/dist/localization/default-messages.js +1 -0
  124. package/dist/notifications/routes.d.ts +3 -3
  125. package/dist/progress/routes.d.ts +1 -1
  126. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  127. package/dist/provider-api/actions/provider-api.d.ts +14 -14
  128. package/dist/server/auth.js +8 -5
  129. package/dist/server/identity-sso-store.d.ts +6 -1
  130. package/dist/server/identity-sso-store.js +57 -14
  131. package/dist/server/identity-sso.d.ts +7 -8
  132. package/dist/server/identity-sso.js +15 -12
  133. package/dist/sharing/actions/list-resource-shares.d.ts +2 -0
  134. package/dist/sharing/actions/list-resource-shares.js +1 -0
  135. package/dist/sharing/schema.d.ts +1 -1
  136. package/dist/sharing/schema.js +4 -1
  137. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  138. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  139. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  140. package/dist/templates/default/.agents/skills/sharing/SKILL.md +21 -0
  141. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  142. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  143. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
  144. package/docs/content/actions-access-control.mdx +226 -0
  145. package/docs/content/actions-advanced.mdx +152 -0
  146. package/docs/content/actions-defining.mdx +275 -0
  147. package/docs/content/actions-other-surfaces.mdx +167 -0
  148. package/docs/content/actions-overview.mdx +214 -0
  149. package/docs/content/actions-run-context.mdx +180 -0
  150. package/docs/content/agent-surfaces.mdx +1 -1
  151. package/docs/content/agent-teams.mdx +1 -1
  152. package/docs/content/agent-web-surfaces.mdx +1 -1
  153. package/docs/content/audit-log.mdx +1 -1
  154. package/docs/content/automation-connectors.mdx +1 -1
  155. package/docs/content/automations.mdx +1 -1
  156. package/docs/content/blueprint-installer.mdx +1 -1
  157. package/docs/content/cli-adapters.mdx +1 -1
  158. package/docs/content/client-agent-chat.mdx +1 -1
  159. package/docs/content/client-data.mdx +2 -2
  160. package/docs/content/client-overview.mdx +2 -2
  161. package/docs/content/components.mdx +1 -1
  162. package/docs/content/cross-app-sso.mdx +24 -17
  163. package/docs/content/data-programs.mdx +2 -2
  164. package/docs/content/database.mdx +1 -1
  165. package/docs/content/deployment.mdx +1 -1
  166. package/docs/content/docs-components.mdx +14 -3
  167. package/docs/content/drop-in-agent.mdx +2 -2
  168. package/docs/content/durable-resume.mdx +1 -1
  169. package/docs/content/evals.mdx +1 -1
  170. package/docs/content/extensions.mdx +1 -1
  171. package/docs/content/external-agents-catalog.mdx +2 -2
  172. package/docs/content/external-agents.mdx +1 -1
  173. package/docs/content/generative-ui.mdx +1 -1
  174. package/docs/content/getting-started.mdx +1 -1
  175. package/docs/content/http-api.mdx +4 -4
  176. package/docs/content/human-approval.mdx +1 -1
  177. package/docs/content/key-concepts.mdx +1 -1
  178. package/docs/content/mcp-apps.mdx +1 -1
  179. package/docs/content/mcp-clients.mdx +1 -1
  180. package/docs/content/mcp-protocol.mdx +1 -1
  181. package/docs/content/native-chat-ui.mdx +1 -1
  182. package/docs/content/observability.mdx +1 -1
  183. package/docs/content/organizations-teams-permissions.mdx +1 -1
  184. package/docs/content/processors.mdx +1 -1
  185. package/docs/content/pure-agent-apps.mdx +1 -1
  186. package/docs/content/recurring-jobs.mdx +1 -1
  187. package/docs/content/server-database.mdx +1 -1
  188. package/docs/content/server-overview.mdx +3 -3
  189. package/docs/content/server-routes.mdx +2 -2
  190. package/docs/content/template-analytics-developers.mdx +1 -1
  191. package/docs/content/template-assets-developers.mdx +1 -1
  192. package/docs/content/template-brain-developers.mdx +1 -1
  193. package/docs/content/template-calendar-developers.mdx +1 -1
  194. package/docs/content/template-chat-first-edits.mdx +1 -1
  195. package/docs/content/template-chat.mdx +1 -1
  196. package/docs/content/template-content-developers.mdx +1 -1
  197. package/docs/content/template-forms-developers.mdx +1 -1
  198. package/docs/content/template-forms.mdx +1 -1
  199. package/docs/content/template-mail-developers.mdx +2 -2
  200. package/docs/content/toolkit-org-team.mdx +1 -1
  201. package/docs/content/tracking.mdx +1 -1
  202. package/docs/content/what-is-agent-native.mdx +1 -1
  203. package/package.json +2 -2
  204. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  205. package/src/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  206. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  207. package/src/templates/default/.agents/skills/sharing/SKILL.md +21 -0
  208. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  209. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  210. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
  211. package/docs/content/actions.mdx +0 -750
@@ -184,6 +184,27 @@ import { ShareButton } from "@agent-native/core/client/sharing";
184
184
 
185
185
  For list views, show `<VisibilityBadge visibility={row.visibility} />` next to each resource.
186
186
 
187
+ ## Standard share surface
188
+
189
+ All app share popovers should use the same compact surface contract:
190
+
191
+ - Use the text-only `ShareTrigger` from `@agent-native/toolkit/sharing`.
192
+ - Render ordinary links with `ShareCopyRow`, which exposes a Copy action without
193
+ printing the raw URL.
194
+ - Keep general access and individual people access in the standard Core sharing
195
+ flow. The people flow supports email invites, roles, notifications, and
196
+ removal through the shared share actions.
197
+ - Add `ShareAgentsSection` only when the resource has a real agent-readable
198
+ link or prompt. Keep it collapsed by default and supply domain-specific
199
+ content through the shared section shell.
200
+ - App-specific tabs or controls may remain when they represent a real domain
201
+ action (for example, an embed-code editor), but they should retain the same
202
+ trigger, copy-row, access, and spacing language.
203
+
204
+ `ShareDisclosureSection` is the toolkit-owned shell for optional expandable
205
+ share details; use its `ShareAgentsSection` or `SharePeopleSection` wrappers
206
+ instead of creating another collapsible share panel in a template.
207
+
187
208
  ## Actions available everywhere
188
209
 
189
210
  The framework auto-mounts these actions in every template — no per-template boilerplate:
@@ -463,7 +463,7 @@ export declare const chatThreadShares: import("drizzle-orm/sqlite-core").SQLiteT
463
463
  data: string;
464
464
  driverParam: string;
465
465
  notNull: true;
466
- hasDefault: false;
466
+ hasDefault: true;
467
467
  isPrimaryKey: false;
468
468
  isAutoincrement: false;
469
469
  hasRuntimeDefault: false;
@@ -23,6 +23,8 @@ const MAX_TOOL_OUTPUT_CHARS = 50_000;
23
23
  const MAX_FILE_READ_CHARS = 120_000;
24
24
  const CODEX_CLI_ENGINE_NAME = "codex-cli";
25
25
  const CLAUDE_CLI_ENGINE_NAME = "claude-cli";
26
+ const PI_CLI_ENGINE_NAME = "pi-cli";
27
+ const OPENCODE_CLI_ENGINE_NAME = "opencode-cli";
26
28
  const CLAUDE_CLI_DEFAULT_MODEL = "claude-sonnet-5";
27
29
  const RECAP_SOURCE_TOOL_PROFILE = "recap-source";
28
30
  const RECAP_SOURCE_OUTPUT_FILE = "recap-source.json";
@@ -125,6 +127,30 @@ export async function executeCodeAgentRun(options) {
125
127
  signal: options.signal,
126
128
  });
127
129
  }
130
+ if (requestedEngine === PI_CLI_ENGINE_NAME) {
131
+ return executePiCliRun({
132
+ run: existing,
133
+ prompt: executionPrompt,
134
+ model: options.model ?? metadataString(existing, "model"),
135
+ reasoningEffort: options.reasoningEffort ?? metadataReasoningEffort(existing),
136
+ permissionMode: existing.permissionMode ?? "full-auto",
137
+ stdout: options.stdout,
138
+ streamToolOutputToStdout,
139
+ signal: options.signal,
140
+ });
141
+ }
142
+ if (requestedEngine === OPENCODE_CLI_ENGINE_NAME) {
143
+ return executeOpenCodeCliRun({
144
+ run: existing,
145
+ prompt: executionPrompt,
146
+ model: options.model ?? metadataString(existing, "model"),
147
+ reasoningEffort: options.reasoningEffort ?? metadataReasoningEffort(existing),
148
+ permissionMode: existing.permissionMode ?? "full-auto",
149
+ stdout: options.stdout,
150
+ streamToolOutputToStdout,
151
+ signal: options.signal,
152
+ });
153
+ }
128
154
  const engine = options.engine ?? (await resolveExecutorEngine(requestedEngine));
129
155
  if (!engine) {
130
156
  const message = "No LLM provider key was found. Set ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, another supported provider key, or run `codex login` to use Codex CLI.";
@@ -669,6 +695,298 @@ function isRecordValue(value) {
669
695
  function asRecordValue(value) {
670
696
  return isRecordValue(value) ? value : null;
671
697
  }
698
+ async function executePiCliRun(options) {
699
+ const model = normalizeLocalCliModel(options.model, PI_CLI_ENGINE_NAME);
700
+ const thinking = normalizePiCliThinking(options.reasoningEffort);
701
+ const args = ["--print", "--mode", "text", "--no-session"];
702
+ if (options.permissionMode === "read-only") {
703
+ args.push("--tools", "read,grep,find,ls");
704
+ }
705
+ if (model)
706
+ args.push("--model", model);
707
+ if (thinking)
708
+ args.push("--thinking", thinking);
709
+ args.push(buildLocalCliPrompt(options.run, options.prompt));
710
+ return executeSimpleLocalCliRun({
711
+ ...options,
712
+ engine: PI_CLI_ENGINE_NAME,
713
+ label: "Pi",
714
+ command: "pi",
715
+ args,
716
+ model,
717
+ });
718
+ }
719
+ async function executeOpenCodeCliRun(options) {
720
+ const model = normalizeLocalCliModel(options.model, OPENCODE_CLI_ENGINE_NAME);
721
+ const variant = normalizeOpenCodeVariant(options.reasoningEffort);
722
+ const cwd = options.run.cwd || process.cwd();
723
+ const args = ["run", "--format", "default", "--dir", cwd];
724
+ if (options.permissionMode === "read-only") {
725
+ args.push("--agent", "plan");
726
+ }
727
+ if (model)
728
+ args.push("--model", model);
729
+ if (variant)
730
+ args.push("--variant", variant);
731
+ args.push(buildLocalCliPrompt(options.run, options.prompt));
732
+ return executeSimpleLocalCliRun({
733
+ ...options,
734
+ engine: OPENCODE_CLI_ENGINE_NAME,
735
+ label: "OpenCode",
736
+ command: "opencode",
737
+ args,
738
+ model,
739
+ });
740
+ }
741
+ async function executeSimpleLocalCliRun(options) {
742
+ const cwd = options.run.cwd || process.cwd();
743
+ const streamToolOutputToStdout = options.streamToolOutputToStdout ??
744
+ process.env.AGENT_NATIVE_CODE_AGENT_STRUCTURED_STDOUT !== "1";
745
+ appendCodeAgentTranscriptEvent({
746
+ runId: options.run.id,
747
+ kind: "status",
748
+ message: `Starting ${options.label} locally.`,
749
+ metadata: {
750
+ status: "running",
751
+ phase: "executing",
752
+ engine: options.engine,
753
+ },
754
+ });
755
+ try {
756
+ const result = await runLocalCliProcess({
757
+ command: options.command,
758
+ args: options.args,
759
+ cwd,
760
+ prompt: options.prompt,
761
+ stdout: options.stdout,
762
+ streamToolOutputToStdout,
763
+ signal: options.signal,
764
+ });
765
+ if (result.exitCode !== 0) {
766
+ const interrupted = options.signal?.aborted === true;
767
+ const message = result.error ||
768
+ result.stderr.trim() ||
769
+ `${options.label} exited with ${result.exitSignal ?? result.exitCode}.`;
770
+ const summary = interrupted
771
+ ? `${options.label} run paused.`
772
+ : `${options.label} run failed: ${message}`;
773
+ if (streamToolOutputToStdout)
774
+ options.stdout?.write(`\n${summary}\n`);
775
+ appendCodeAgentTranscriptEvent({
776
+ runId: options.run.id,
777
+ kind: "status",
778
+ message: summary,
779
+ metadata: {
780
+ status: interrupted ? "paused" : "errored",
781
+ phase: interrupted ? "paused" : "error",
782
+ engine: options.engine,
783
+ exitCode: result.exitCode,
784
+ exitSignal: result.exitSignal,
785
+ },
786
+ });
787
+ return updateCodeAgentRunRecord(options.run.id, {
788
+ status: interrupted ? "paused" : "errored",
789
+ phase: interrupted ? "paused" : "error",
790
+ progress: {
791
+ label: interrupted ? "Paused" : "Error",
792
+ completed: 0,
793
+ total: 1,
794
+ failed: interrupted ? 0 : 1,
795
+ percent: 0,
796
+ },
797
+ metadata: {
798
+ ...(interrupted
799
+ ? { executionPausedAt: new Date().toISOString() }
800
+ : {
801
+ executionError: message,
802
+ executionErroredAt: new Date().toISOString(),
803
+ }),
804
+ engine: options.engine,
805
+ ...(options.model ? { model: options.model } : {}),
806
+ },
807
+ });
808
+ }
809
+ const finalMessage = result.stdout.trim() || `${options.label} run completed.`;
810
+ appendCodeAgentTranscriptEvent({
811
+ runId: options.run.id,
812
+ kind: "system",
813
+ message: finalMessage,
814
+ metadata: {
815
+ role: "assistant",
816
+ engine: options.engine,
817
+ ...(options.model ? { model: options.model } : {}),
818
+ },
819
+ });
820
+ const pendingFollowUp = dequeueCodeAgentFollowUp(options.run.id);
821
+ if (pendingFollowUp) {
822
+ const message = pendingFollowUp.mode === "queued"
823
+ ? `${options.label} run completed; running queued follow-up.`
824
+ : `${options.label} run completed; applying steering follow-up.`;
825
+ appendCodeAgentTranscriptEvent({
826
+ runId: options.run.id,
827
+ kind: "status",
828
+ message,
829
+ metadata: {
830
+ status: "running",
831
+ phase: "follow-up",
832
+ followUpId: pendingFollowUp.id,
833
+ followUpMode: pendingFollowUp.mode,
834
+ engine: options.engine,
835
+ },
836
+ });
837
+ if (pendingFollowUp.permissionMode) {
838
+ updateCodeAgentRunRecord(options.run.id, {
839
+ permissionMode: pendingFollowUp.permissionMode,
840
+ });
841
+ }
842
+ return executeCodeAgentRun({
843
+ runId: options.run.id,
844
+ prompt: pendingFollowUp.prompt,
845
+ attachments: pendingFollowUp.attachments ??
846
+ userPromptAttachmentsForEvent(options.run.id, pendingFollowUp.eventId),
847
+ appendUserEvent: false,
848
+ stdout: options.stdout,
849
+ streamToolOutputToStdout: options.streamToolOutputToStdout,
850
+ signal: options.signal,
851
+ });
852
+ }
853
+ appendCodeAgentTranscriptEvent({
854
+ runId: options.run.id,
855
+ kind: "status",
856
+ message: `${options.label} run completed.`,
857
+ metadata: {
858
+ status: "completed",
859
+ phase: "complete",
860
+ engine: options.engine,
861
+ },
862
+ });
863
+ return updateCodeAgentRunRecord(options.run.id, {
864
+ status: "completed",
865
+ phase: "complete",
866
+ needsApproval: false,
867
+ progress: {
868
+ label: "Complete",
869
+ completed: 1,
870
+ total: 1,
871
+ percent: 100,
872
+ },
873
+ metadata: {
874
+ executionCompletedAt: new Date().toISOString(),
875
+ engine: options.engine,
876
+ ...(options.model ? { model: options.model } : {}),
877
+ permissionMode: options.permissionMode,
878
+ },
879
+ });
880
+ }
881
+ catch (error) {
882
+ const interrupted = options.signal?.aborted === true;
883
+ const message = error instanceof Error ? error.message : String(error);
884
+ const summary = interrupted
885
+ ? `${options.label} run paused.`
886
+ : `${options.label} run failed: ${message}`;
887
+ if (streamToolOutputToStdout)
888
+ options.stdout?.write(`\n${summary}\n`);
889
+ appendCodeAgentTranscriptEvent({
890
+ runId: options.run.id,
891
+ kind: "status",
892
+ message: summary,
893
+ metadata: {
894
+ status: interrupted ? "paused" : "errored",
895
+ phase: interrupted ? "paused" : "error",
896
+ engine: options.engine,
897
+ },
898
+ });
899
+ return updateCodeAgentRunRecord(options.run.id, {
900
+ status: interrupted ? "paused" : "errored",
901
+ phase: interrupted ? "paused" : "error",
902
+ progress: {
903
+ label: interrupted ? "Paused" : "Error",
904
+ completed: 0,
905
+ total: 1,
906
+ failed: interrupted ? 0 : 1,
907
+ percent: 0,
908
+ },
909
+ metadata: {
910
+ ...(interrupted
911
+ ? { executionPausedAt: new Date().toISOString() }
912
+ : {
913
+ executionError: message,
914
+ executionErroredAt: new Date().toISOString(),
915
+ }),
916
+ engine: options.engine,
917
+ ...(options.model ? { model: options.model } : {}),
918
+ },
919
+ });
920
+ }
921
+ }
922
+ function runLocalCliProcess(options) {
923
+ return new Promise((resolve) => {
924
+ let stdout = "";
925
+ let stderr = "";
926
+ let settled = false;
927
+ const child = spawn(options.command, options.args, {
928
+ cwd: options.cwd,
929
+ stdio: ["pipe", "pipe", "pipe"],
930
+ env: process.env,
931
+ });
932
+ const finish = (result) => {
933
+ if (settled)
934
+ return;
935
+ settled = true;
936
+ options.signal?.removeEventListener("abort", onAbort);
937
+ resolve({ ...result, stdout, stderr });
938
+ };
939
+ const onAbort = () => child.kill("SIGTERM");
940
+ if (options.signal) {
941
+ if (options.signal.aborted)
942
+ onAbort();
943
+ else
944
+ options.signal.addEventListener("abort", onAbort, { once: true });
945
+ }
946
+ child.stdout?.on("data", (chunk) => {
947
+ const text = chunk.toString();
948
+ stdout += text;
949
+ if (options.streamToolOutputToStdout ?? true) {
950
+ options.stdout?.write(text);
951
+ }
952
+ });
953
+ child.stderr?.on("data", (chunk) => {
954
+ const text = chunk.toString();
955
+ stderr += text;
956
+ if (options.streamToolOutputToStdout ?? true) {
957
+ options.stdout?.write(text);
958
+ }
959
+ });
960
+ child.on("error", (error) => finish({
961
+ exitCode: null,
962
+ exitSignal: null,
963
+ error: error.message,
964
+ }));
965
+ child.on("close", (exitCode, exitSignal) => finish({ exitCode, exitSignal }));
966
+ // Pi and OpenCode receive the prompt as a positional argument. Close the
967
+ // pipe without sending it a second time.
968
+ child.stdin?.end();
969
+ });
970
+ }
971
+ function buildLocalCliPrompt(run, prompt) {
972
+ return buildClaudeCliPrompt(run, prompt);
973
+ }
974
+ function normalizeLocalCliModel(model, engine) {
975
+ const trimmed = model?.trim();
976
+ if (!trimmed || trimmed === "auto" || trimmed === engine)
977
+ return undefined;
978
+ return trimmed;
979
+ }
980
+ function normalizePiCliThinking(effort) {
981
+ if (!effort || effort === "auto" || effort === "none")
982
+ return undefined;
983
+ return effort === "max" ? "xhigh" : effort;
984
+ }
985
+ function normalizeOpenCodeVariant(effort) {
986
+ if (!effort || effort === "auto" || effort === "none")
987
+ return undefined;
988
+ return effort;
989
+ }
672
990
  async function executeCodexCliRun(options) {
673
991
  const cwd = options.run.cwd || process.cwd();
674
992
  const outputDir = fs.mkdtempSync(path.join(os.tmpdir(), "agent-native-code-codex-"));
@@ -173,6 +173,18 @@ export interface AgentSidebarProps {
173
173
  onComposerTextChange?: AssistantChatProps["onComposerTextChange"];
174
174
  /** Optional secondary model menu shown inside the chat composer model picker. */
175
175
  imageModelMenu?: AssistantChatProps["imageModelMenu"];
176
+ /** Local or hosted agent runtimes shown above the model list. */
177
+ availableAgents?: AssistantChatProps["availableAgents"];
178
+ /** Selected agent runtime identifier. */
179
+ selectedAgent?: AssistantChatProps["selectedAgent"];
180
+ /** Callback when the user picks an agent runtime. */
181
+ onAgentChange?: AssistantChatProps["onAgentChange"];
182
+ /** Route local runtime setup through the host's native bridge. */
183
+ onConnectLocalRuntime?: AssistantChatProps["onConnectLocalRuntime"];
184
+ /** Bring-your-own runtime used by embedded hosts such as Electron. */
185
+ runtime?: AssistantChatProps["runtime"];
186
+ /** Explicit key for recreating an injected runtime adapter. */
187
+ adapterReloadKey?: AssistantChatProps["adapterReloadKey"];
176
188
  /** Optional content rendered at the bottom of the chat thread. */
177
189
  threadFooterSlot?: AssistantChatProps["threadFooterSlot"];
178
190
  /** Initial sidebar width in pixels. Mount-only; user resize and a saved
@@ -234,7 +246,7 @@ export interface AgentSidebarProps {
234
246
  * Wraps app content with a toggleable agent sidebar.
235
247
  * Use AgentToggleButton in your header to open/close it.
236
248
  */
237
- export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, chatViewTransitionHandoff, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding, }: AgentSidebarProps): React.JSX.Element;
249
+ export declare function AgentSidebar({ children, emptyStateText, suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position, defaultOpen, animateMobile, animateDesktop, chatViewTransition, chatViewTransitionHandoff, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding, }: AgentSidebarProps): React.JSX.Element;
238
250
  /**
239
251
  * Focus the agent chat composer input.
240
252
  * Opens the sidebar if closed, then focuses the text input.
@@ -44,6 +44,7 @@ import { withBuilderUtmTrackingParams } from "../shared/builder-link-tracking.js
44
44
  import { AGENT_SIDEBAR_MIN_WIDTH, consumeAgentSidebarUrlOpenOverride, clampAgentSidebarWidth, dispatchAgentSidebarStateChange, getAgentSidebarMaxWidth, getInitialAgentSidebarOpen, getAgentSidebarWideWidth, setAgentSidebarOpenPreference, subscribeAgentSidebarUrlChanges, SIDEBAR_STATE_CHANGE_EVENT, } from "./agent-sidebar-state.js";
45
45
  import { trackEvent } from "./analytics.js";
46
46
  import { agentNativePath, appPath, isWorkspaceAppPath } from "./api-path.js";
47
+ import { APP_CHAT_SIDEBAR_STATE_EVENT, APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE, buildAppChatSidebarStateMessage, isPerAppChatStorageKey, } from "./app-chat-sidebar.js";
47
48
  import { readClientAppState } from "./application-state.js";
48
49
  import { assistantUiRecoverableRenderErrorKind } from "./assistant-ui-recovery.js";
49
50
  import { shouldParentFrameOwnAgentPanel } from "./builder-frame.js";
@@ -65,6 +66,12 @@ const AgentTerminal = lazy(() => import("./terminal/index.js").then((m) => ({ de
65
66
  const AGENT_PANEL_PREPARE_EVENT = "agent-panel:prepare";
66
67
  const AGENT_PANEL_SET_MODE_EVENT = "agent-panel:set-mode";
67
68
  const AGENT_PANEL_OPEN_SETTINGS_EVENT = "agent-panel:open-settings";
69
+ function postPerAppChatSidebarStateToEmbeddedFrames(open) {
70
+ const message = buildAppChatSidebarStateMessage(open);
71
+ for (const frame of document.querySelectorAll("iframe")) {
72
+ frame.contentWindow?.postMessage(message, "*");
73
+ }
74
+ }
68
75
  function settingsRouteHashForSection(section) {
69
76
  const normalized = section?.replace(/^#/, "").toLowerCase() ?? "";
70
77
  if (normalized === "voice")
@@ -1407,8 +1414,9 @@ export function AgentChatSurface({ mode = "panel", className, defaultMode = "cha
1407
1414
  * Wraps app content with a toggleable agent sidebar.
1408
1415
  * Use AgentToggleButton in your header to open/close it.
1409
1416
  */
1410
- export function AgentSidebar({ children, emptyStateText = "How can I help you?", suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position = "right", defaultOpen = false, animateMobile = true, animateDesktop = true, chatViewTransition = false, chatViewTransitionHandoff = false, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar = true, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning = false, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding = false, }) {
1417
+ export function AgentSidebar({ children, emptyStateText = "How can I help you?", suggestions, dynamicSuggestions, composerToolbarSlot, composerSlot, onComposerTextChange, imageModelMenu, availableAgents, selectedAgent, onAgentChange, onConnectLocalRuntime, runtime, adapterReloadKey, threadFooterSlot, defaultSidebarWidth, sidebarWidth, position = "right", defaultOpen = false, animateMobile = true, animateDesktop = true, chatViewTransition = false, chatViewTransitionHandoff = false, storageKey, openStorageKey, apiUrl, agentChatSurface, showTabBar = true, suppressInlineOpenApp, composerPlaceholder, openOnChatRunning = false, onFullscreenRequest, scope, showScopeBadge, browserTabId, threadUrlSync, agentPageHref, suppressFirstRunOnboarding = false, }) {
1411
1418
  const sidebarOpenStorageKey = openStorageKey ?? storageKey;
1419
+ const isPerAppChatSidebar = isPerAppChatStorageKey(sidebarOpenStorageKey);
1412
1420
  const onboardingPreviewMode = useOnboardingPreviewMode();
1413
1421
  const firstRunOnboardingGateOwnsSurface = useFirstRunOnboardingGateOwnsSurface();
1414
1422
  const showFirstRunOnboarding = !firstRunOnboardingGateOwnsSurface &&
@@ -1537,6 +1545,36 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1537
1545
  presentationMode,
1538
1546
  hasFrameSidebarState,
1539
1547
  ]);
1548
+ useEffect(() => {
1549
+ if (!isPerAppChatSidebar)
1550
+ return;
1551
+ const frameOwned = frameCodeMode && shouldParentFrameOwnAgentPanel();
1552
+ if (frameOwned && !hasFrameSidebarState)
1553
+ return;
1554
+ const openState = !presentationMode && (frameOwned ? frameSidebarOpen : open);
1555
+ const message = buildAppChatSidebarStateMessage(openState);
1556
+ window.dispatchEvent(new CustomEvent(APP_CHAT_SIDEBAR_STATE_EVENT, {
1557
+ detail: message.data,
1558
+ }));
1559
+ postPerAppChatSidebarStateToEmbeddedFrames(openState);
1560
+ const handleStateRequest = (event) => {
1561
+ if (event.data?.type !== APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE)
1562
+ return;
1563
+ const frame = Array.from(document.querySelectorAll("iframe")).find((candidate) => candidate.contentWindow === event.source);
1564
+ if (!frame)
1565
+ return;
1566
+ frame.contentWindow?.postMessage(message, event.origin || "*");
1567
+ };
1568
+ window.addEventListener("message", handleStateRequest);
1569
+ return () => window.removeEventListener("message", handleStateRequest);
1570
+ }, [
1571
+ frameCodeMode,
1572
+ frameSidebarOpen,
1573
+ hasFrameSidebarState,
1574
+ isPerAppChatSidebar,
1575
+ open,
1576
+ presentationMode,
1577
+ ]);
1540
1578
  useEffect(() => {
1541
1579
  const preparePanel = () => setBackgroundPanelActive(true);
1542
1580
  const handleChatRunning = (event) => {
@@ -1924,9 +1962,9 @@ export function AgentSidebar({ children, emptyStateText = "How can I help you?",
1924
1962
  ? "mobile"
1925
1963
  : desktopAnimationEnabled
1926
1964
  ? "desktop"
1927
- : undefined, "data-agent-sidebar-layout": panelLayout, "data-agent-sidebar-position": position, "data-agent-sidebar-state": panelOpen ? "open" : "closed", "data-agent-sidebar-resizing": isResizing ? "true" : undefined, "data-agent-sidebar-chat-handoff": chatViewTransitionHandoff ? "true" : undefined, style: chatViewTransition
1965
+ : undefined, "data-agent-sidebar-layout": panelLayout, "data-agent-sidebar-position": position, "data-agent-sidebar-state": panelOpen ? "open" : "closed", "data-agent-sidebar-per-app-chat": isPerAppChatSidebar ? "true" : undefined, "data-agent-sidebar-resizing": isResizing ? "true" : undefined, "data-agent-sidebar-chat-handoff": chatViewTransitionHandoff ? "true" : undefined, style: chatViewTransition
1928
1966
  ? getAgentChatViewTransitionStyle(panelStyle)
1929
- : panelStyle, inert: sidebarAnimationEnabled && !panelOpen ? true : undefined, "aria-hidden": sidebarAnimationEnabled && !panelOpen ? true : undefined, children: _jsx("div", { className: "agent-sidebar-panel-inner flex min-h-0 flex-1 flex-col", children: _jsx(AgentPanel, { emptyStateText: emptyStateText, suggestions: suggestions, dynamicSuggestions: dynamicSuggestions, composerToolbarSlot: composerToolbarSlot, composerSlot: composerSlot, onComposerTextChange: onComposerTextChange, imageModelMenu: imageModelMenu, threadFooterSlot: threadFooterSlot, apiUrl: apiUrl, agentChatSurface: agentChatSurface, showTabBar: showTabBar, suppressInlineOpenApp: suppressInlineOpenApp, composerPlaceholder: composerPlaceholder, missingApiKeySetupLayout: "sidebar", onCollapse: () => setOpenPersisted(false), onSnapTo75Percent: isMobile ? undefined : snapTo75Percent, isWideDrawer: isMobile ? false : isWideDrawer, onExitWideDrawer: isMobile ? undefined : exitWideDrawer, onFullViewRequest: onFullscreenRequest, storageKey: storageKey, scope: scope, showScopeBadge: showScopeBadge, browserTabId: browserTabId, threadUrlSync: threadUrlSync, agentPageHref: agentPageHref, allowSettingsMode: false, chatOnly: true }) }) }), showResizeHandle && isLeft && (_jsx(ResizeHandle, { position: position, onDrag: handleDrag, onResizeStart: handleResizeStart, onResizeEnd: handleResizeEnd }))] })) : null;
1967
+ : panelStyle, inert: sidebarAnimationEnabled && !panelOpen ? true : undefined, "aria-hidden": sidebarAnimationEnabled && !panelOpen ? true : undefined, children: _jsx("div", { className: "agent-sidebar-panel-inner flex min-h-0 flex-1 flex-col", children: _jsx(AgentPanel, { emptyStateText: emptyStateText, suggestions: suggestions, dynamicSuggestions: dynamicSuggestions, composerToolbarSlot: composerToolbarSlot, composerSlot: composerSlot, onComposerTextChange: onComposerTextChange, imageModelMenu: imageModelMenu, availableAgents: availableAgents, selectedAgent: selectedAgent, onAgentChange: onAgentChange, onConnectLocalRuntime: onConnectLocalRuntime, runtime: runtime, adapterReloadKey: adapterReloadKey, threadFooterSlot: threadFooterSlot, apiUrl: apiUrl, agentChatSurface: agentChatSurface, showTabBar: showTabBar, suppressInlineOpenApp: suppressInlineOpenApp, composerPlaceholder: composerPlaceholder, missingApiKeySetupLayout: "sidebar", onCollapse: () => setOpenPersisted(false), onSnapTo75Percent: isMobile ? undefined : snapTo75Percent, isWideDrawer: isMobile ? false : isWideDrawer, onExitWideDrawer: isMobile ? undefined : exitWideDrawer, onFullViewRequest: onFullscreenRequest, storageKey: storageKey, scope: scope, showScopeBadge: showScopeBadge, browserTabId: browserTabId, threadUrlSync: threadUrlSync, agentPageHref: agentPageHref, allowSettingsMode: false, chatOnly: true }) }) }), showResizeHandle && isLeft && (_jsx(ResizeHandle, { position: position, onDrag: handleDrag, onResizeStart: handleResizeStart, onResizeEnd: handleResizeEnd }))] })) : null;
1930
1968
  const drawerPlaceholder = wideDrawerEnabled && !presentationMode && panelOpen ? (_jsx("div", { "aria-hidden": "true", className: "agent-sidebar-drawer-placeholder shrink-0", "data-agent-sidebar-placeholder": "true", style: { width: drawerPlaceholderWidth + 1 } })) : null;
1931
1969
  return (_jsx(AgentSidebarOnboardingContext.Provider, { value: true, children: _jsxs(RealtimeVoiceModeProvider, { browserTabId: browserTabId, children: [showFirstRunOnboarding && (_jsx(Suspense, { fallback: null, children: _jsx(FirstRunOnboarding, {}) })), _jsxs("div", { className: "agent-sidebar-shell flex min-w-0 flex-1 h-screen overflow-hidden", "data-agent-sidebar-position": position, "data-agent-sidebar-resizing": isResizing ? "true" : undefined, children: [isMobile &&
1932
1970
  !presentationMode &&
@@ -1,4 +1,4 @@
1
- import type { ComposerImageModelMenu } from "@agent-native/toolkit/composer/TiptapComposer";
1
+ import type { ComposerAgentOption, ComposerImageModelMenu } from "@agent-native/toolkit/composer/TiptapComposer";
2
2
  import type { ChatModelAdapter, ExportedMessageRepository } from "@assistant-ui/react";
3
3
  import React from "react";
4
4
  import type { ReasoningEffort } from "../shared/reasoning-effort.js";
@@ -262,6 +262,8 @@ export interface AssistantChatProps {
262
262
  threadId?: string;
263
263
  /** Resource scope to include with chat requests for server-side context. */
264
264
  contextScope?: ChatThreadScope | null;
265
+ /** Namespace used to hide ambient composer context from other host surfaces. */
266
+ contextNamespace?: string;
265
267
  /** Whether this chat owns the active visible composer context snapshot. */
266
268
  isActiveComposer?: boolean;
267
269
  /**
@@ -363,6 +365,12 @@ export interface AssistantChatProps {
363
365
  onModelChange?: (model: string, engine: string) => void;
364
366
  /** Callback when user picks an effort from the picker */
365
367
  onEffortChange?: (effort: ReasoningEffort) => void;
368
+ /** Local or hosted agent runtimes shown above the model list. */
369
+ availableAgents?: ComposerAgentOption[];
370
+ /** Selected agent runtime identifier. */
371
+ selectedAgent?: string;
372
+ /** Callback when the user picks an agent runtime. */
373
+ onAgentChange?: (agent: string) => void;
366
374
  /**
367
375
  * Optional secondary model menu (e.g. an image-generation model) shown inside
368
376
  * the composer's model picker. Opt-in; chat-only apps omit it.
@@ -10,7 +10,7 @@ import { useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect, for
10
10
  import { createPollEngine } from "../shared/poll-engine.js";
11
11
  import { clearPendingTurnIfMatches, clearActiveRunIfMatches, getPendingTurn, getActiveRunActivityTool, getActiveRun, hasRecentActiveRunProgress, resolveReconnectAfterSeq, setActiveRun, updateActiveRunActivity, updateActiveRunSeq, } from "./active-run-state.js";
12
12
  import { activeRunLooksAlive, createAgentChatAdapter, hasInFlightToolCall, } from "./agent-chat-adapter.js";
13
- import { appendAgentChatContextToMessage, formatAgentChatContextItemsForPrompt, getAgentChatContextState, isAgentChatSubmitCancelled, normalizeAgentChatContextItem, publishAgentChatContextItems, refreshAgentChatContext, reportAgentChatSubmitResult, subscribeAgentChatContext, } from "./agent-chat.js";
13
+ import { appendAgentChatContextToMessage, filterAgentChatContextItems, formatAgentChatContextItemsForPrompt, getAgentChatContextState, isAgentChatSubmitCancelled, normalizeAgentChatContextItem, publishAgentChatContextItems, refreshAgentChatContext, reportAgentChatSubmitResult, subscribeAgentChatContext, } from "./agent-chat.js";
14
14
  import { captureError } from "./analytics.js";
15
15
  import { agentNativePath } from "./api-path.js";
16
16
  import { AssistantMessageListErrorBoundary, AssistantUiStaleIndexErrorBoundary, } from "./assistant-ui-recovery.js";
@@ -1375,7 +1375,7 @@ export function useAutoResumeStatus(tabId, forceStopped) {
1375
1375
  function approvalResolutionIdentity(approvalKey, toolCallId) {
1376
1376
  return `${toolCallId ?? ""}\u0000${approvalKey}`;
1377
1377
  }
1378
- const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, showModelSelector = true, composerDisabled = false, composerDisabledPlaceholder, isNewThread, isThreadStateLoading, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, modelListLoading, onModelChange, onEffortChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, agentChatSurface = "app", suppressInlineOpenApp = false, }, ref) {
1378
+ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, contextNamespace, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, showModelSelector = true, composerDisabled = false, composerDisabledPlaceholder, isNewThread, isThreadStateLoading, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, modelListLoading, onModelChange, onEffortChange, availableAgents, selectedAgent, onAgentChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, agentChatSurface = "app", suppressInlineOpenApp = false, }, ref) {
1379
1379
  const t = useT();
1380
1380
  const thread = useThread();
1381
1381
  const threadRuntime = useThreadRuntime();
@@ -1529,11 +1529,18 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1529
1529
  const composerContextItemsRef = useRef([]);
1530
1530
  const isActiveComposerRef = useRef(isActiveComposer);
1531
1531
  isActiveComposerRef.current = isActiveComposer;
1532
+ const normalizedContextNamespace = contextNamespace?.trim() || undefined;
1532
1533
  const publishComposerContextItems = useCallback((items) => {
1533
1534
  if (!isActiveComposerRef.current)
1534
1535
  return;
1535
- publishAgentChatContextItems(items);
1536
- }, []);
1536
+ const hiddenItems = normalizedContextNamespace
1537
+ ? getAgentChatContextState().items.filter((item) => {
1538
+ const itemNamespace = item.contextNamespace?.trim();
1539
+ return (itemNamespace && itemNamespace !== normalizedContextNamespace);
1540
+ })
1541
+ : [];
1542
+ publishAgentChatContextItems([...hiddenItems, ...items]);
1543
+ }, [normalizedContextNamespace]);
1537
1544
  const updateComposerContextItems = useCallback((updater) => {
1538
1545
  setComposerContextItems((previous) => {
1539
1546
  const next = updater(previous);
@@ -1556,6 +1563,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1556
1563
  const item = normalizeAgentChatContextItem(rawItem);
1557
1564
  if (!item)
1558
1565
  return;
1566
+ if (filterAgentChatContextItems([item], normalizedContextNamespace)
1567
+ .length === 0) {
1568
+ return;
1569
+ }
1559
1570
  updateComposerContextItems((previous) => {
1560
1571
  const index = previous.findIndex((current) => current.key === item.key);
1561
1572
  if (index === -1)
@@ -1594,21 +1605,23 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1594
1605
  void refreshAgentChatContext().then((state) => {
1595
1606
  if (cancelled || !isActiveComposerRef.current)
1596
1607
  return;
1597
- composerContextItemsRef.current = state.items;
1598
- setComposerContextItems(state.items);
1608
+ const visibleItems = filterAgentChatContextItems(state.items, normalizedContextNamespace);
1609
+ composerContextItemsRef.current = visibleItems;
1610
+ setComposerContextItems(visibleItems);
1599
1611
  });
1600
1612
  const unsubscribe = subscribeAgentChatContext(() => {
1601
1613
  if (cancelled || !isActiveComposerRef.current)
1602
1614
  return;
1603
1615
  const state = getAgentChatContextState();
1604
- composerContextItemsRef.current = state.items;
1605
- setComposerContextItems(state.items);
1616
+ const visibleItems = filterAgentChatContextItems(state.items, normalizedContextNamespace);
1617
+ composerContextItemsRef.current = visibleItems;
1618
+ setComposerContextItems(visibleItems);
1606
1619
  });
1607
1620
  return () => {
1608
1621
  cancelled = true;
1609
1622
  unsubscribe();
1610
1623
  };
1611
- }, [isActiveComposer]);
1624
+ }, [isActiveComposer, normalizedContextNamespace]);
1612
1625
  // Tracks the JSON of the last queue we successfully persisted so the
1613
1626
  // debounced save effect can skip no-op writes (e.g. restore-from-server
1614
1627
  // on mount, or queue state that hasn't actually changed).
@@ -4263,16 +4276,16 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
4263
4276
  isRunning,
4264
4277
  requestedIntent: options?.intent,
4265
4278
  }), undefined, true)
4266
- : undefined, willQueue: engineSetupRequired || isRunning, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange: shouldShowAssistantChatModelSelector(showModelSelector)
4279
+ : undefined, willQueue: engineSetupRequired || isRunning, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, availableAgents: availableAgents, selectedAgent: selectedAgent, modelListLoading: modelListLoading, onModelChange: shouldShowAssistantChatModelSelector(showModelSelector)
4267
4280
  ? onModelChange
4268
- : undefined, onEffortChange: onEffortChange, imageModelMenu: imageModelMenu, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, toolbarSlot: composerToolbarSlot, contextItems: composerContextItems, onRemoveContextItem: removeComposerContextItem, plusMenuMode: plusMenuMode, layoutVariant: composerLayoutVariant, providerConnectStatusEnabled: providerStatusChecksEnabled, voiceEnabled: true, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, onAttachmentError: setComposerError, extraActionButton: composerExtraActionButton, stopButton: showRunningInUI ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => stopActiveRun({
4281
+ : undefined, onEffortChange: onEffortChange, onAgentChange: onAgentChange, imageModelMenu: imageModelMenu, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, toolbarSlot: composerToolbarSlot, contextItems: composerContextItems, onRemoveContextItem: removeComposerContextItem, plusMenuMode: plusMenuMode, layoutVariant: composerLayoutVariant, providerConnectStatusEnabled: providerStatusChecksEnabled, voiceEnabled: true, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, onAttachmentError: setComposerError, extraActionButton: composerExtraActionButton, stopButton: showRunningInUI ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => stopActiveRun({
4269
4282
  preserveQueuedMessages: true,
4270
4283
  }), "aria-label": t("agentChat.composer.stopResponse"), "data-agent-composer-slot": "stop-button", className: "shrink-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: _jsx(IconPlayerStopFilled, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: t("agentChat.composer.stopResponse") })] })) : undefined })] })) }), showMissingKeySetup &&
4271
4284
  !showInlineMissingKeySetup ? (_jsx(PopoverContent, { side: missingApiKeySetupLayout === "sidebar"
4272
4285
  ? "top"
4273
4286
  : "bottom", align: "center", sideOffset: 8, collisionPadding: 12, "data-agent-native-composer-popover": "true", className: "z-[260] box-border w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,26rem),26rem)] rounded-lg border-border p-3 shadow-lg", children: _jsx(BuilderSetupContent, { onConnected: handleBuilderConnected, layout: missingApiKeySetupLayout }) })) : null] })] })] }) }) }) }) }) }) }) }) }) }) }));
4274
4287
  });
4275
- export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentNativePath("/_agent-native/agent-chat"), tabId, browserTabId, threadId, contextScope, isActiveComposer, ...props }, ref) {
4288
+ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentNativePath("/_agent-native/agent-chat"), tabId, browserTabId, threadId, contextScope, contextNamespace, isActiveComposer, ...props }, ref) {
4276
4289
  const modelRef = useRef(props.selectedModel);
4277
4290
  modelRef.current = props.selectedModel;
4278
4291
  const engineRef = useRef(props.selectedEngine);
@@ -4335,5 +4348,5 @@ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentN
4335
4348
  const runtime = useLocalRuntime(adapter, {
4336
4349
  adapters: { attachments: attachmentAdapter },
4337
4350
  });
4338
- return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(TooltipProvider, { delayDuration: 200, children: _jsx(ThreadPrimitive.Root, { className: "flex flex-1 flex-col h-full min-h-0 overflow-x-hidden", children: _jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: `${tabId ?? ""}:${threadId ?? ""}`, componentName: "AssistantChat", children: _jsx(AssistantChatInner, { ref: ref, ...props, browserTabId: browserTabId, contextScope: contextScope, isActiveComposer: isActiveComposer, apiUrl: apiUrl, tabId: tabId, threadId: threadId }) }) }) }) }));
4351
+ return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(TooltipProvider, { delayDuration: 200, children: _jsx(ThreadPrimitive.Root, { className: "flex flex-1 flex-col h-full min-h-0 overflow-x-hidden", children: _jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: `${tabId ?? ""}:${threadId ?? ""}`, componentName: "AssistantChat", children: _jsx(AssistantChatInner, { ref: ref, ...props, browserTabId: browserTabId, contextScope: contextScope, contextNamespace: contextNamespace, isActiveComposer: isActiveComposer, apiUrl: apiUrl, tabId: tabId, threadId: threadId }) }) }) }) }));
4339
4352
  });