@agent-native/toolkit 0.204.0 → 0.204.1-nightly-20261008065100
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/agent-native.eject.json +2 -0
- package/dist/app/agent-page/AgentJobsTab.d.ts.map +1 -1
- package/dist/app/agent-page/AgentJobsTab.js +4 -2
- package/dist/app/agent-page/AgentJobsTab.js.map +1 -1
- package/dist/app/agent-page/AutomationDetailsDialog.d.ts +2 -1
- package/dist/app/agent-page/AutomationDetailsDialog.d.ts.map +1 -1
- package/dist/app/agent-page/AutomationDetailsDialog.js +8 -4
- package/dist/app/agent-page/AutomationDetailsDialog.js.map +1 -1
- package/dist/app/agent-page/ScheduledTriggerNotice.d.ts.map +1 -1
- package/dist/app/agent-page/ScheduledTriggerNotice.js +41 -19
- package/dist/app/agent-page/ScheduledTriggerNotice.js.map +1 -1
- package/dist/app/agent-page/use-jobs.d.ts +1 -1
- package/dist/app/agent-page/use-jobs.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +124 -45
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +22 -1
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +14 -1
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/root.d.ts +3 -2
- package/dist/app/agentkit/react/root.d.ts.map +1 -1
- package/dist/app/agentkit/react/root.js +2 -2
- package/dist/app/agentkit/react/root.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +32 -2
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +74 -7
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.js +1 -1
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +10 -9
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/RunStuckBanner.d.ts +8 -1
- package/dist/app/chat/RunStuckBanner.d.ts.map +1 -1
- package/dist/app/chat/RunStuckBanner.js +68 -6
- package/dist/app/chat/RunStuckBanner.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts +4 -2
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +3 -3
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +1 -0
- package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
- package/dist/app/chat/composer/use-mention-search.d.ts +1 -0
- package/dist/app/chat/composer/use-mention-search.d.ts.map +1 -1
- package/dist/app/chat/fallback-chat-title.d.ts +2 -0
- package/dist/app/chat/fallback-chat-title.d.ts.map +1 -0
- package/dist/app/chat/fallback-chat-title.js +11 -0
- package/dist/app/chat/fallback-chat-title.js.map +1 -0
- package/dist/app/chat/feedback-report.d.ts +12 -0
- package/dist/app/chat/feedback-report.d.ts.map +1 -0
- package/dist/app/chat/feedback-report.js +21 -0
- package/dist/app/chat/feedback-report.js.map +1 -0
- package/dist/app/chat/reconcile-settled-run.d.ts +15 -0
- package/dist/app/chat/reconcile-settled-run.d.ts.map +1 -0
- package/dist/app/chat/reconcile-settled-run.js +41 -0
- package/dist/app/chat/reconcile-settled-run.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +9 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +9 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +9 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +9 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +9 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +9 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +9 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +9 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +9 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +9 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +9 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +9 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +7 -1
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/settings/shell/pages/audit.d.ts.map +1 -1
- package/dist/app/settings/shell/pages/audit.js +11 -2
- package/dist/app/settings/shell/pages/audit.js.map +1 -1
- package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
- package/dist/app/shared/AppShellSkeleton.js +4 -0
- package/dist/app/shared/AppShellSkeleton.js.map +1 -1
- package/dist/composer/ComposerContextMenu.d.ts +14 -1
- package/dist/composer/ComposerContextMenu.d.ts.map +1 -1
- package/dist/composer/ComposerContextMenu.js +65 -19
- package/dist/composer/ComposerContextMenu.js.map +1 -1
- package/dist/composer/MentionPopover.d.ts.map +1 -1
- package/dist/composer/MentionPopover.js +3 -3
- package/dist/composer/MentionPopover.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +1 -1
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +2 -2
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +92 -36
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/use-mention-search.d.ts +1 -0
- package/dist/composer/use-mention-search.d.ts.map +1 -1
- package/dist/composer/use-mention-search.js +8 -1
- package/dist/composer/use-mention-search.js.map +1 -1
- package/package.json +4 -4
- package/src/app/agent-page/AgentJobsTab.blocked.spec.tsx +43 -0
- package/src/app/agent-page/AgentJobsTab.tsx +14 -5
- package/src/app/agent-page/AutomationDetailsDialog.tsx +22 -8
- package/src/app/agent-page/ScheduledTriggerNotice.spec.tsx +45 -3
- package/src/app/agent-page/ScheduledTriggerNotice.tsx +52 -31
- package/src/app/agent-page/use-jobs.ts +1 -1
- package/src/app/agentkit/react/components.interaction.spec.tsx +311 -1
- package/src/app/agentkit/react/components.spec.tsx +106 -2
- package/src/app/agentkit/react/components.tsx +217 -80
- package/src/app/agentkit/react/context.tsx +36 -0
- package/src/app/agentkit/react/root.tsx +4 -0
- package/src/app/agentkit/react/styles.css +32 -2
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +140 -18
- package/src/app/chat/AgentKitAssistantChat.tsx +123 -7
- package/src/app/chat/AgentPanel.header.spec.ts +43 -7
- package/src/app/chat/AgentPanel.tsx +1 -1
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +34 -0
- package/src/app/chat/MultiTabAssistantChat.tsx +10 -9
- package/src/app/chat/RunStuckBanner.spec.tsx +258 -17
- package/src/app/chat/RunStuckBanner.tsx +107 -5
- package/src/app/chat/chat/run-recovery.tsx +10 -2
- package/src/app/chat/chat/surface-types.ts +1 -0
- package/src/app/chat/fallback-chat-title.ts +10 -0
- package/src/app/chat/feedback-report.spec.ts +45 -0
- package/src/app/chat/feedback-report.ts +27 -0
- package/src/app/chat/reconcile-settled-run.spec.ts +112 -0
- package/src/app/chat/reconcile-settled-run.ts +57 -0
- package/src/app/i18n/catalogs/ar-SA.ts +12 -0
- package/src/app/i18n/catalogs/de-DE.ts +12 -0
- package/src/app/i18n/catalogs/en-US.ts +12 -0
- package/src/app/i18n/catalogs/es-ES.ts +12 -0
- package/src/app/i18n/catalogs/fr-FR.ts +12 -0
- package/src/app/i18n/catalogs/hi-IN.ts +12 -0
- package/src/app/i18n/catalogs/ja-JP.ts +12 -0
- package/src/app/i18n/catalogs/ko-KR.ts +12 -0
- package/src/app/i18n/catalogs/pt-BR.ts +12 -0
- package/src/app/i18n/catalogs/zh-CN.ts +10 -0
- package/src/app/i18n/catalogs/zh-TW.ts +10 -0
- package/src/app/providers/AppProviders.spec.tsx +29 -0
- package/src/app/providers/AppProviders.tsx +13 -0
- package/src/app/settings/shell/pages/audit.spec.tsx +30 -0
- package/src/app/settings/shell/pages/audit.tsx +12 -1
- package/src/app/shared/AppShellSkeleton.tsx +4 -0
- package/src/composer/ComposerContextMenu.tsx +94 -22
- package/src/composer/ComposerPlusMenu.parity.spec.tsx +218 -233
- package/src/composer/MentionPopover.tsx +12 -3
- package/src/composer/PromptComposer.context.spec.tsx +527 -195
- package/src/composer/PromptComposer.tsx +1 -1
- package/src/composer/TiptapComposer.tsx +105 -37
- package/src/composer/use-mention-search.ts +8 -1
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
isHumanReadableDocumentTitle,
|
|
20
20
|
normalizeDocumentTitle,
|
|
21
21
|
} from "@agent-native/core/shared/document-title";
|
|
22
|
+
import { getMcpAppWidgetEmbedBootScriptBody } from "@agent-native/core/shared/mcp-app-widget-embed";
|
|
22
23
|
import { getSsrBetaRedirectScriptBody } from "@agent-native/core/shared/ssr-beta-redirect";
|
|
23
24
|
import { getSsrSessionBootstrapScriptBody } from "@agent-native/core/shared/ssr-session-bootstrap";
|
|
24
25
|
import { Toaster } from "@agent-native/toolkit/ui/sonner";
|
|
@@ -98,6 +99,17 @@ function EarlyBetaRedirectScript() {
|
|
|
98
99
|
);
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
// Marks <html> as an MCP App widget before the server-rendered skeleton below
|
|
103
|
+
// paints, so the widget never flashes the app's own sidebar.
|
|
104
|
+
function McpAppWidgetBootScript() {
|
|
105
|
+
return (
|
|
106
|
+
<script
|
|
107
|
+
data-agent-native-mcp-widget-boot="1"
|
|
108
|
+
dangerouslySetInnerHTML={{ __html: getMcpAppWidgetEmbedBootScriptBody() }}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
101
113
|
function EarlySessionBootstrapScript() {
|
|
102
114
|
return (
|
|
103
115
|
<script
|
|
@@ -480,6 +492,7 @@ export function AppProviders({
|
|
|
480
492
|
|
|
481
493
|
return (
|
|
482
494
|
<>
|
|
495
|
+
<McpAppWidgetBootScript />
|
|
483
496
|
{!sessionBypass && (
|
|
484
497
|
<>
|
|
485
498
|
<EarlySessionBootstrapScript />
|
|
@@ -165,6 +165,7 @@ describe("Audit log page", () => {
|
|
|
165
165
|
event({ id: "human" }),
|
|
166
166
|
event({
|
|
167
167
|
id: "agent",
|
|
168
|
+
caller: "tool",
|
|
168
169
|
actorKind: "agent",
|
|
169
170
|
actorEmail: "member@example.com",
|
|
170
171
|
summary: "Turned on Require citations",
|
|
@@ -193,6 +194,35 @@ describe("Audit log page", () => {
|
|
|
193
194
|
expect(refused.textContent).toContain("Sep 23 · member@example.com");
|
|
194
195
|
});
|
|
195
196
|
|
|
197
|
+
it("names the protocol when an outside agent made the change", async () => {
|
|
198
|
+
callActionMock.mockResolvedValue(
|
|
199
|
+
page(
|
|
200
|
+
[
|
|
201
|
+
event({
|
|
202
|
+
caller: "mcp",
|
|
203
|
+
actorKind: "agent",
|
|
204
|
+
actorEmail: "bob@example.com",
|
|
205
|
+
summary: "Updated the form",
|
|
206
|
+
app: "forms",
|
|
207
|
+
}),
|
|
208
|
+
],
|
|
209
|
+
null,
|
|
210
|
+
),
|
|
211
|
+
);
|
|
212
|
+
await render();
|
|
213
|
+
|
|
214
|
+
const [row] = rows();
|
|
215
|
+
expect(row.textContent).toContain("Sep 23 · Forms · Agent via MCP");
|
|
216
|
+
expect(row.textContent).not.toContain("bob@example.com");
|
|
217
|
+
|
|
218
|
+
await act(async () => {
|
|
219
|
+
row.click();
|
|
220
|
+
});
|
|
221
|
+
const dialog = document.querySelector('[role="dialog"]');
|
|
222
|
+
expect(dialog?.textContent).toContain("Changed byAgent via MCP");
|
|
223
|
+
expect(dialog?.textContent).toContain("On behalf ofbob@example.com");
|
|
224
|
+
});
|
|
225
|
+
|
|
196
226
|
it("names the real count in Show N more and reveals the next page", async () => {
|
|
197
227
|
const first = Array.from({ length: 25 }, (_, index) =>
|
|
198
228
|
event({ id: `a-${index}` }),
|
|
@@ -67,8 +67,19 @@ export function auditAppLabel(app: string): string {
|
|
|
67
67
|
.join(" ");
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
const OUTSIDE_AGENT_PROTOCOLS: Record<string, string> = {
|
|
71
|
+
mcp: "MCP",
|
|
72
|
+
webmcp: "WebMCP",
|
|
73
|
+
a2a: "A2A",
|
|
74
|
+
};
|
|
75
|
+
|
|
70
76
|
function actorLabel(event: AuditEvent, t: Translate): string {
|
|
71
|
-
if (event.actorKind === "agent")
|
|
77
|
+
if (event.actorKind === "agent") {
|
|
78
|
+
const protocol = OUTSIDE_AGENT_PROTOCOLS[event.caller];
|
|
79
|
+
return protocol
|
|
80
|
+
? t("agentChat.settings.audit.agentVia", { protocol })
|
|
81
|
+
: t("agentChat.common.agent");
|
|
82
|
+
}
|
|
72
83
|
if (event.actorKind === "system" || !event.actorEmail) {
|
|
73
84
|
return t("agentChat.settings.audit.system");
|
|
74
85
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MCP_APP_WIDGET_EMBED_ATTRIBUTE } from "@agent-native/core/shared/mcp-app-widget-embed";
|
|
1
2
|
import type { CSSProperties, ReactNode } from "react";
|
|
2
3
|
|
|
3
4
|
const MUTED = "hsl(var(--muted, 240 5% 96.1%))";
|
|
@@ -1048,6 +1049,9 @@ export function AppShellSkeleton({
|
|
|
1048
1049
|
}}
|
|
1049
1050
|
>
|
|
1050
1051
|
<style>{`
|
|
1052
|
+
html[${MCP_APP_WIDGET_EMBED_ATTRIBUTE}] [data-agent-native-app-skeleton] > :not(style) {
|
|
1053
|
+
display: none !important;
|
|
1054
|
+
}
|
|
1051
1055
|
[data-agent-native-skeleton-block] {
|
|
1052
1056
|
animation: an-app-shell-skeleton-pulse 1.2s ease-in-out infinite;
|
|
1053
1057
|
}
|
|
@@ -95,6 +95,8 @@ export interface ComposerContextMenuProps {
|
|
|
95
95
|
onRestoreFocus?: () => void;
|
|
96
96
|
contextButtonTooltipDisabled?: boolean;
|
|
97
97
|
disabled?: boolean;
|
|
98
|
+
/** Runs this action or opens its picker as a dialog; each new object is a new request. */
|
|
99
|
+
openEntry?: { id: string } | null;
|
|
98
100
|
}
|
|
99
101
|
interface ComposerContextPage {
|
|
100
102
|
id: string;
|
|
@@ -106,6 +108,19 @@ interface ComposerContextDialogSession {
|
|
|
106
108
|
scopeKey?: string;
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
// Without a dialog presentation a picker selects one item through onSelect,
|
|
112
|
+
// which the dialog's single-select mode does too.
|
|
113
|
+
function asDialogPicker(
|
|
114
|
+
picker: ComposerContextPickerConfig,
|
|
115
|
+
): ComposerContextPickerConfig {
|
|
116
|
+
return typeof picker.presentation === "object"
|
|
117
|
+
? picker
|
|
118
|
+
: ({
|
|
119
|
+
...picker,
|
|
120
|
+
presentation: { type: "dialog", mode: "single" },
|
|
121
|
+
} as ComposerContextPickerConfig);
|
|
122
|
+
}
|
|
123
|
+
|
|
109
124
|
function findAction(
|
|
110
125
|
items: readonly ComposerContextMenuItem[],
|
|
111
126
|
id: string,
|
|
@@ -121,46 +136,73 @@ function findAction(
|
|
|
121
136
|
}
|
|
122
137
|
}
|
|
123
138
|
|
|
124
|
-
export
|
|
139
|
+
export interface ComposerContextActionMatch {
|
|
140
|
+
action: ComposerContextMenuAction;
|
|
141
|
+
/** Category ids from the searched items down to the action. */
|
|
142
|
+
path: string[];
|
|
143
|
+
/** Labels of those categories, outermost first. */
|
|
144
|
+
categories: string[];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Every action under `items` that matches `query`; an empty query matches all. */
|
|
148
|
+
export function searchComposerContextActions(
|
|
125
149
|
items: readonly ComposerContextMenuItem[],
|
|
126
|
-
path: readonly string[],
|
|
127
150
|
query: string,
|
|
128
|
-
):
|
|
129
|
-
let scope = items;
|
|
130
|
-
for (const id of path) {
|
|
131
|
-
const category = scope.find((item) => item.id === id);
|
|
132
|
-
if (!category?.children || category.disabled) return [];
|
|
133
|
-
scope = category.children;
|
|
134
|
-
}
|
|
151
|
+
): ComposerContextActionMatch[] {
|
|
135
152
|
const terms = query.trim().toLocaleLowerCase().split(/\s+/).filter(Boolean);
|
|
136
|
-
|
|
137
|
-
const matches: ComposerContextMenuItem[] = [];
|
|
153
|
+
const matches: ComposerContextActionMatch[] = [];
|
|
138
154
|
const visit = (
|
|
139
155
|
entries: readonly ComposerContextMenuItem[],
|
|
140
|
-
|
|
141
|
-
|
|
156
|
+
path: string[],
|
|
157
|
+
categories: string[],
|
|
158
|
+
searchable: string[],
|
|
159
|
+
disabled: boolean,
|
|
142
160
|
) => {
|
|
143
161
|
for (const entry of entries) {
|
|
144
|
-
const
|
|
145
|
-
...
|
|
162
|
+
const text = [
|
|
163
|
+
...searchable,
|
|
146
164
|
entry.label,
|
|
147
165
|
entry.description ?? "",
|
|
148
166
|
...(entry.keywords ?? []),
|
|
149
167
|
];
|
|
168
|
+
const entryDisabled = disabled || entry.disabled === true;
|
|
150
169
|
if (entry.children)
|
|
151
|
-
visit(
|
|
170
|
+
visit(
|
|
171
|
+
entry.children,
|
|
172
|
+
[...path, entry.id],
|
|
173
|
+
[...categories, entry.label],
|
|
174
|
+
text,
|
|
175
|
+
entryDisabled,
|
|
176
|
+
);
|
|
152
177
|
else if (
|
|
153
|
-
terms.every((term) =>
|
|
154
|
-
searchable.join(" ").toLocaleLowerCase().includes(term),
|
|
155
|
-
)
|
|
178
|
+
terms.every((term) => text.join(" ").toLocaleLowerCase().includes(term))
|
|
156
179
|
)
|
|
157
|
-
matches.push(
|
|
180
|
+
matches.push({
|
|
181
|
+
action: entryDisabled ? { ...entry, disabled: true } : entry,
|
|
182
|
+
path,
|
|
183
|
+
categories,
|
|
184
|
+
});
|
|
158
185
|
}
|
|
159
186
|
};
|
|
160
|
-
visit(
|
|
187
|
+
visit(items, [], [], [], false);
|
|
161
188
|
return matches;
|
|
162
189
|
}
|
|
163
190
|
|
|
191
|
+
export function getComposerContextMenuEntries(
|
|
192
|
+
items: readonly ComposerContextMenuItem[],
|
|
193
|
+
path: readonly string[],
|
|
194
|
+
query: string,
|
|
195
|
+
): ComposerContextMenuItem[] {
|
|
196
|
+
let scope = items;
|
|
197
|
+
for (const id of path) {
|
|
198
|
+
const category = scope.find((item) => item.id === id);
|
|
199
|
+
if (!category?.children || category.disabled) return [];
|
|
200
|
+
scope = category.children;
|
|
201
|
+
}
|
|
202
|
+
if (!query.trim()) return [...scope];
|
|
203
|
+
return searchComposerContextActions(scope, query).map(({ action }) => action);
|
|
204
|
+
}
|
|
205
|
+
|
|
164
206
|
function ContextSubmenu({
|
|
165
207
|
label,
|
|
166
208
|
icon,
|
|
@@ -263,6 +305,7 @@ export function ComposerContextMenu({
|
|
|
263
305
|
onRestoreFocus,
|
|
264
306
|
contextButtonTooltipDisabled = false,
|
|
265
307
|
disabled,
|
|
308
|
+
openEntry,
|
|
266
309
|
}: ComposerContextMenuProps) {
|
|
267
310
|
const t = useComposerRuntimeAdapters().translate!;
|
|
268
311
|
const allItems = [...menuActionItems, ...items];
|
|
@@ -399,6 +442,35 @@ export function ComposerContextMenu({
|
|
|
399
442
|
updatePath([...origin, action.id]);
|
|
400
443
|
if (select && !action.picker) selectAction(action);
|
|
401
444
|
};
|
|
445
|
+
const openRequestedEntry = (id: string) => {
|
|
446
|
+
if (disabled) return;
|
|
447
|
+
const action = findAction(allItems, id);
|
|
448
|
+
if (!action || action.disabled || action.render) {
|
|
449
|
+
reportError(
|
|
450
|
+
new Error(
|
|
451
|
+
t("agentChat.composer.contextActionFailed", {
|
|
452
|
+
defaultValue: "Could not add context.",
|
|
453
|
+
}),
|
|
454
|
+
),
|
|
455
|
+
);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
setError(null);
|
|
459
|
+
if (!action.picker) {
|
|
460
|
+
selectAction(action);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
// A request starts outside the menu, so its picker opens as a dialog: a
|
|
464
|
+
// submenu opened programmatically loses focus to its parents and closes.
|
|
465
|
+
const session = { id: action.id, scopeKey: action.picker.scopeKey };
|
|
466
|
+
dialogRef.current = session;
|
|
467
|
+
setDialog(session);
|
|
468
|
+
};
|
|
469
|
+
const openRequestedEntryRef = useRef(openRequestedEntry);
|
|
470
|
+
openRequestedEntryRef.current = openRequestedEntry;
|
|
471
|
+
useEffect(() => {
|
|
472
|
+
if (openEntry) openRequestedEntryRef.current(openEntry.id);
|
|
473
|
+
}, [openEntry]);
|
|
402
474
|
const currentAction = page ? findAction(allItems, page.id) : undefined;
|
|
403
475
|
useEffect(() => {
|
|
404
476
|
if (
|
|
@@ -718,7 +790,7 @@ export function ComposerContextMenu({
|
|
|
718
790
|
<ComposerContextPickerDialog
|
|
719
791
|
key={JSON.stringify([dialog.id, dialogAction.picker.scopeKey])}
|
|
720
792
|
title={dialogAction.label}
|
|
721
|
-
config={dialogAction.picker}
|
|
793
|
+
config={asDialogPicker(dialogAction.picker)}
|
|
722
794
|
onClose={() => {
|
|
723
795
|
if (dialogRef.current !== dialog) return;
|
|
724
796
|
dialogRef.current = null;
|