@agent-native/core 0.157.3 → 0.157.4
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.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +40 -1
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +7 -7
- package/corpus/templates/clips/actions/approve-recording-access-request.ts +147 -0
- package/corpus/templates/clips/actions/request-recording-access.ts +121 -23
- package/corpus/templates/clips/actions/view-screen.ts +1 -1
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +34 -53
- package/corpus/templates/clips/app/components/player/request-access-dialog.tsx +104 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +36 -45
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -6
- package/corpus/templates/clips/app/i18n/en-US.ts +26 -1
- package/corpus/templates/clips/app/lib/public-meeting.ts +1 -1
- package/corpus/templates/clips/app/routes/access-request.approve.tsx +250 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +9 -32
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +123 -37
- package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +41 -1
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -0
- package/corpus/templates/clips/server/lib/emails.ts +40 -11
- package/corpus/templates/clips/shared/recording-link.ts +32 -1
- package/corpus/templates/clips/shared/share-attribution.ts +13 -0
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +22 -10
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +2 -1
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +245 -9
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +185 -134
- package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +61 -45
- package/corpus/templates/content/app/components/editor/extensions/ImageNode.ts +6 -0
- package/corpus/templates/content/app/components/editor/image-upload.ts +137 -5
- package/corpus/templates/content/app/global.css +8 -0
- package/corpus/templates/content/changelog/2026-08-12-image-uploads-now-confirm-the-image-can-be-displayed-before-.md +6 -0
- package/corpus/templates/content/changelog/2026-08-14-images-fill-the-page-width-by-default-and-remain-visible-whe.md +6 -0
- package/corpus/templates/content/changelog/2026-08-14-images-inserted-from-the-slash-command-stay-saved-after-uplo.md +6 -0
- package/corpus/templates/content/changelog/2026-08-14-svg-files-can-be-selected-reliably-from-the-image-picker.md +6 -0
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/design/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -1
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +25 -30
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +2 -1
- package/corpus/templates/slides/app/components/editor/ShareDialog.tsx +124 -180
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +1 -0
- package/corpus/templates/slides/app/global.css +99 -3
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +21 -0
- package/dist/chat-threads/schema.d.ts +1 -1
- package/dist/cli/code-agent-executor.js +318 -0
- package/dist/client/AgentPanel.d.ts +13 -1
- package/dist/client/AgentPanel.js +41 -3
- package/dist/client/AssistantChat.d.ts +9 -1
- package/dist/client/AssistantChat.js +26 -13
- package/dist/client/MultiTabAssistantChat.js +18 -5
- package/dist/client/agent-chat.d.ts +8 -0
- package/dist/client/agent-chat.js +15 -0
- package/dist/client/app-chat-sidebar.d.ts +23 -0
- package/dist/client/app-chat-sidebar.js +53 -0
- package/dist/client/app-providers.js +31 -2
- package/dist/client/frame-protocol.d.ts +20 -2
- package/dist/client/hooks/index.d.ts +1 -0
- package/dist/client/hooks/index.js +1 -0
- package/dist/client/sharing/AgentShareSection.d.ts +8 -0
- package/dist/client/sharing/AgentShareSection.js +50 -0
- package/dist/client/sharing/ShareButton.js +2 -1
- package/dist/client/sharing/ShareDialog.d.ts +2 -2
- package/dist/client/sharing/ShareDialog.js +21 -29
- package/dist/client/sharing/index.d.ts +1 -0
- package/dist/client/sharing/index.js +1 -0
- package/dist/client/sharing/useShareButtonController.d.ts +1 -0
- package/dist/client/sharing/useShareDialogController.d.ts +3 -0
- package/dist/client/sharing/useShareDialogController.js +2 -1
- package/dist/client/theme.d.ts +21 -0
- package/dist/client/theme.js +60 -0
- package/dist/client/ui/index.d.ts +1 -1
- package/dist/client/ui/index.js +1 -1
- package/dist/client/use-session.js +23 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/dashboard-storage/schema.d.ts +1 -1
- package/dist/data-programs/schema.d.ts +1 -1
- package/dist/extensions/schema.d.ts +1 -1
- package/dist/localization/core-messages/ar-SA.js +6 -0
- package/dist/localization/core-messages/de-DE.js +6 -0
- package/dist/localization/core-messages/en-US.d.ts +6 -0
- package/dist/localization/core-messages/en-US.js +6 -0
- package/dist/localization/core-messages/es-ES.js +6 -0
- package/dist/localization/core-messages/fr-FR.js +6 -0
- package/dist/localization/core-messages/hi-IN.js +6 -0
- package/dist/localization/core-messages/ja-JP.js +6 -0
- package/dist/localization/core-messages/ko-KR.js +6 -0
- package/dist/localization/core-messages/pt-BR.js +6 -0
- package/dist/localization/core-messages/zh-CN.js +6 -0
- package/dist/localization/core-messages/zh-TW.js +6 -0
- package/dist/localization/core-messages.d.ts +6 -0
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.js +1 -0
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +14 -14
- package/dist/server/auth.js +8 -5
- package/dist/server/identity-sso-store.d.ts +6 -1
- package/dist/server/identity-sso-store.js +57 -14
- package/dist/server/identity-sso.d.ts +7 -8
- package/dist/server/identity-sso.js +15 -12
- package/dist/sharing/actions/list-resource-shares.d.ts +2 -0
- package/dist/sharing/actions/list-resource-shares.js +1 -0
- package/dist/sharing/schema.d.ts +1 -1
- package/dist/sharing/schema.js +4 -1
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/sharing/SKILL.md +21 -0
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
- package/docs/content/cross-app-sso.mdx +24 -17
- package/package.json +2 -2
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/sharing/SKILL.md +21 -0
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
|
@@ -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:
|
|
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
|
-
|
|
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
|
-
|
|
1598
|
-
|
|
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
|
-
|
|
1605
|
-
|
|
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
|
});
|