@agent-native/toolkit 0.198.3 → 0.198.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/dist/app/agentkit/react/components.d.ts +4 -1
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +12 -4
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +43 -21
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
- package/dist/app/chat/AgentSidebar.js +2 -0
- package/dist/app/chat/AgentSidebar.js.map +1 -1
- package/dist/app/chat/FileStorageSetupPopover.js +2 -2
- package/dist/app/chat/FileStorageSetupPopover.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +1 -1
- package/dist/app/chat/agentkit-chat/connections.d.ts +1 -4
- package/dist/app/chat/agentkit-chat/connections.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/connections.js +1 -26
- package/dist/app/chat/agentkit-chat/connections.js.map +1 -1
- package/dist/app/chat/agentkit-chat/history.d.ts +4 -1
- package/dist/app/chat/agentkit-chat/history.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/history.js +17 -5
- package/dist/app/chat/agentkit-chat/history.js.map +1 -1
- package/dist/app/chat/chat/history-types.d.ts +1 -1
- package/dist/app/chat/chat/history-types.d.ts.map +1 -1
- package/dist/app/chat/chat-first/copy.d.ts +1 -2
- package/dist/app/chat/chat-first/copy.d.ts.map +1 -1
- package/dist/app/chat/chat-first/copy.js +1 -121
- package/dist/app/chat/chat-first/copy.js.map +1 -1
- package/dist/app/chat/chat-first-copy.d.ts +3 -0
- package/dist/app/chat/chat-first-copy.d.ts.map +1 -0
- package/dist/app/chat/chat-first-copy.js +122 -0
- package/dist/app/chat/chat-first-copy.js.map +1 -0
- package/dist/app/feature-flags/FeatureFlagsPanel.d.ts.map +1 -1
- package/dist/app/feature-flags/FeatureFlagsPanel.js +1 -0
- package/dist/app/feature-flags/FeatureFlagsPanel.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +2 -1
- 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 +2 -1
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +2 -1
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/labs/LabsSettings.d.ts.map +1 -1
- package/dist/app/labs/LabsSettings.js +7 -3
- package/dist/app/labs/LabsSettings.js.map +1 -1
- package/dist/app/org/OrgGeneralSection.d.ts.map +1 -1
- package/dist/app/org/OrgGeneralSection.js +21 -18
- package/dist/app/org/OrgGeneralSection.js.map +1 -1
- package/dist/app/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/app/org/OrgSwitcher.js +3 -2
- package/dist/app/org/OrgSwitcher.js.map +1 -1
- package/dist/app/org/workspace-app-links.d.ts +1 -0
- package/dist/app/org/workspace-app-links.d.ts.map +1 -1
- package/dist/app/org/workspace-app-links.js +3 -0
- package/dist/app/org/workspace-app-links.js.map +1 -1
- package/dist/app/resources/McpAgentKitConnectionRequest.d.ts +7 -2
- package/dist/app/resources/McpAgentKitConnectionRequest.d.ts.map +1 -1
- package/dist/app/resources/McpAgentKitConnectionRequest.js +132 -13
- package/dist/app/resources/McpAgentKitConnectionRequest.js.map +1 -1
- package/dist/icons/ResourceIconPicker.d.ts +6 -1
- package/dist/icons/ResourceIconPicker.d.ts.map +1 -1
- package/dist/icons/ResourceIconPicker.js +45 -6
- package/dist/icons/ResourceIconPicker.js.map +1 -1
- package/package.json +6 -4
- package/src/app/agentkit/react/components.spec.tsx +3 -3
- package/src/app/agentkit/react/components.tsx +22 -4
- package/src/app/agentkit/react/lifecycle.spec.tsx +42 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +114 -11
- package/src/app/chat/AgentKitAssistantChat.tsx +78 -17
- package/src/app/chat/AgentPanel.header.spec.ts +59 -22
- package/src/app/chat/AgentSidebar.tsx +2 -0
- package/src/app/chat/FileStorageSetupPopover.tsx +2 -2
- package/src/app/chat/MultiTabAssistantChat.messageCount.spec.tsx +3 -1
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +8 -4
- package/src/app/chat/MultiTabAssistantChat.tsx +1 -1
- package/src/app/chat/agentkit-chat/action-widget.spec.tsx +5 -17
- package/src/app/chat/agentkit-chat/connections.spec.tsx +137 -0
- package/src/app/chat/agentkit-chat/connections.ts +2 -37
- package/src/app/chat/agentkit-chat/history.tsx +23 -8
- package/src/app/chat/chat/history-types.ts +1 -1
- package/src/app/chat/chat/tool-call-display.spec.tsx +2 -2
- package/src/app/chat/chat/widgets/record-change-widget.spec.tsx +20 -29
- package/src/app/chat/chat-first/copy.ts +1 -133
- package/src/app/chat/chat-first-copy.ts +133 -0
- package/src/app/chat/composer/use-agentkit-capabilities.hardening.spec.tsx +3 -2
- package/src/app/feature-flags/FeatureFlagsPanel.tsx +1 -0
- package/src/app/i18n/catalogs/ar-SA.ts +2 -1
- package/src/app/i18n/catalogs/de-DE.ts +3 -1
- package/src/app/i18n/catalogs/en-US.ts +2 -1
- package/src/app/i18n/catalogs/es-ES.ts +2 -1
- package/src/app/i18n/catalogs/fr-FR.ts +3 -1
- package/src/app/i18n/catalogs/hi-IN.ts +2 -1
- package/src/app/i18n/catalogs/ja-JP.ts +2 -1
- package/src/app/i18n/catalogs/ko-KR.ts +2 -1
- package/src/app/i18n/catalogs/pt-BR.ts +3 -1
- package/src/app/i18n/catalogs/zh-CN.ts +2 -1
- package/src/app/i18n/catalogs/zh-TW.ts +2 -1
- package/src/app/integrations/IntegrationDetailPage.spec.tsx +1 -1
- package/src/app/labs/LabsSettings.tsx +46 -10
- package/src/app/observability/ThumbsFeedback.spec.tsx +15 -0
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +4 -0
- package/src/app/org/OrgGeneralSection.tsx +32 -22
- package/src/app/org/OrgSwitcher.tsx +3 -2
- package/src/app/org/workspace-app-links.spec.ts +4 -0
- package/src/app/org/workspace-app-links.ts +8 -1
- package/src/app/resources/McpAgentKitConnectionRequest.spec.tsx +371 -2
- package/src/app/resources/McpAgentKitConnectionRequest.tsx +171 -11
- package/src/app/settings/SettingsTabsPage.spec.tsx +4 -2
- package/src/app/settings/shell/SettingsShell.spec.tsx +14 -8
- package/src/app/settings/shell/pages/app-group-pages.spec.tsx +35 -5
- package/src/app/settings/shell/pages/resource-pages.spec.tsx +3 -0
- package/src/app/settings/usage/UsagePage.spec.tsx +3 -3
- package/src/app/shared/lazy-chunk-error-boundary.spec.tsx +2 -0
- package/src/app-shell/sidebar-overflow.spec.tsx +4 -1
- package/src/design-tweaks/visual-style-controls.spec.tsx +38 -0
- package/src/editor/useCollabReconcile.concurrent.spec.ts +2 -1
- package/src/icons/ResourceIconPicker.spec.tsx +270 -0
- package/src/icons/ResourceIconPicker.tsx +72 -4
|
@@ -3090,7 +3090,7 @@ export function MultiTabAssistantChat({
|
|
|
3090
3090
|
<div
|
|
3091
3091
|
className={cn(
|
|
3092
3092
|
"relative flex-1 flex flex-col min-h-0",
|
|
3093
|
-
renderOverlay && "pt-
|
|
3093
|
+
renderOverlay && "pt-12",
|
|
3094
3094
|
)}
|
|
3095
3095
|
data-agent-page-chat-topbar={renderOverlay ? "" : undefined}
|
|
3096
3096
|
data-agent-page-chat-scrolled={
|
|
@@ -11,10 +11,7 @@ import {
|
|
|
11
11
|
ACTION_CHAT_UI_DATA_WIDGET_RENDERER,
|
|
12
12
|
ACTION_CHAT_UI_RECORD_CHANGE_RENDERER,
|
|
13
13
|
} from "@agent-native/core/action-ui";
|
|
14
|
-
import {
|
|
15
|
-
AgentNativeI18nProvider as CoreAgentNativeI18nProvider,
|
|
16
|
-
type AgentNativeI18nProviderProps,
|
|
17
|
-
} from "@agent-native/core/client/i18n";
|
|
14
|
+
import { AgentNativeI18nProvider } from "@agent-native/core/client/i18n";
|
|
18
15
|
import {
|
|
19
16
|
createDataInsightsWidgetResult,
|
|
20
17
|
createDataTableWidgetResult,
|
|
@@ -32,16 +29,7 @@ import {
|
|
|
32
29
|
} from "../chat/tool-render-registry.js";
|
|
33
30
|
import { AgentKitActionWidget } from "./action-widget.js";
|
|
34
31
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
function AgentNativeI18nProvider(props: AgentNativeI18nProviderProps) {
|
|
38
|
-
return (
|
|
39
|
-
<CoreAgentNativeI18nProvider
|
|
40
|
-
{...props}
|
|
41
|
-
catalog={props.catalog ?? toolkitI18nCatalog}
|
|
42
|
-
/>
|
|
43
|
-
);
|
|
44
|
-
}
|
|
32
|
+
const catalog = createToolkitI18nCatalog({ messages: {} });
|
|
45
33
|
|
|
46
34
|
describe("AgentKitActionWidget", () => {
|
|
47
35
|
it("resolves the renderer with stored action args and structured result", async () => {
|
|
@@ -229,7 +217,7 @@ describe("AgentKitActionWidget", () => {
|
|
|
229
217
|
try {
|
|
230
218
|
await act(async () => {
|
|
231
219
|
root.render(
|
|
232
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
220
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
233
221
|
<AgentKitProvider controller={client} threadId="thread-1">
|
|
234
222
|
<>
|
|
235
223
|
<AgentKitActionWidget value={formsWidget} threadId="thread-1" />
|
|
@@ -316,7 +304,7 @@ describe("AgentKitActionWidget", () => {
|
|
|
316
304
|
try {
|
|
317
305
|
await act(async () => {
|
|
318
306
|
root.render(
|
|
319
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
307
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
320
308
|
<AgentKitProvider controller={client} threadId="thread-1">
|
|
321
309
|
<>
|
|
322
310
|
{widgets.map((widget) => (
|
|
@@ -399,7 +387,7 @@ describe("AgentKitActionWidget", () => {
|
|
|
399
387
|
try {
|
|
400
388
|
await act(async () => {
|
|
401
389
|
root.render(
|
|
402
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
390
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
403
391
|
<AgentKitProvider controller={client} threadId="thread-1">
|
|
404
392
|
{widgets.map((widget) => (
|
|
405
393
|
<AgentKitActionWidget
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// @vitest-environment happy-dom
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
clearMcpConnectionResume,
|
|
5
|
+
getPendingMcpConnectionResume,
|
|
4
6
|
notifyMcpConnectionComplete,
|
|
5
7
|
saveMcpConnectionResume,
|
|
6
8
|
} from "@agent-native/core/client/resources/mcp-connection-resume";
|
|
@@ -16,6 +18,7 @@ afterEach(() => {
|
|
|
16
18
|
if (root) act(() => root?.unmount());
|
|
17
19
|
root = undefined;
|
|
18
20
|
window.sessionStorage.clear();
|
|
21
|
+
window.localStorage.clear();
|
|
19
22
|
window.history.replaceState({}, "", "/chat/thread-1");
|
|
20
23
|
});
|
|
21
24
|
|
|
@@ -78,4 +81,138 @@ describe("McpAgentKitConnectionResume", () => {
|
|
|
78
81
|
);
|
|
79
82
|
expect(onMessageResume).not.toHaveBeenCalled();
|
|
80
83
|
});
|
|
84
|
+
|
|
85
|
+
it("shows a failure and keeps the saved request when resuming fails", async () => {
|
|
86
|
+
const target = { threadId: "thread-1", runId: "run-1", requestId: "req-1" };
|
|
87
|
+
saveMcpConnectionResume("Restore the request.", target);
|
|
88
|
+
const onResume = vi.fn().mockRejectedValue(new Error("offline"));
|
|
89
|
+
const container = document.createElement("div");
|
|
90
|
+
root = createRoot(container);
|
|
91
|
+
|
|
92
|
+
await act(async () => {
|
|
93
|
+
root?.render(<McpAgentKitConnectionResume onResume={onResume} />);
|
|
94
|
+
await Promise.resolve();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(container.querySelector('[role="alert"]')).not.toBeNull();
|
|
98
|
+
expect(getPendingMcpConnectionResume()).toMatchObject({
|
|
99
|
+
message: "Restore the request.",
|
|
100
|
+
agentKit: target,
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("resumes a completed popup after remount and continues when the run is gone", async () => {
|
|
105
|
+
window.history.replaceState({}, "", "/chat/thread-1");
|
|
106
|
+
const target = {
|
|
107
|
+
threadId: "thread-1",
|
|
108
|
+
runId: "run-1",
|
|
109
|
+
requestId: "req-1",
|
|
110
|
+
};
|
|
111
|
+
const completionId = "8d1bd7cf-419e-4ff0-8545-19dedb819154";
|
|
112
|
+
saveMcpConnectionResume("Restore the request.", target, completionId);
|
|
113
|
+
const onResume = vi
|
|
114
|
+
.fn()
|
|
115
|
+
.mockRejectedValue(new Error(`Unknown AgentKit run: ${target.runId}`));
|
|
116
|
+
const onMessageResume = vi.fn();
|
|
117
|
+
const container = document.createElement("div");
|
|
118
|
+
root = createRoot(container);
|
|
119
|
+
|
|
120
|
+
await act(async () => {
|
|
121
|
+
root?.render(
|
|
122
|
+
<McpAgentKitConnectionResume
|
|
123
|
+
onResume={onResume}
|
|
124
|
+
onMessageResume={onMessageResume}
|
|
125
|
+
/>,
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
expect(onResume).not.toHaveBeenCalled();
|
|
129
|
+
expect(getPendingMcpConnectionResume()).toBeNull();
|
|
130
|
+
|
|
131
|
+
act(() => {
|
|
132
|
+
root?.unmount();
|
|
133
|
+
});
|
|
134
|
+
root = undefined;
|
|
135
|
+
window.localStorage.setItem(
|
|
136
|
+
`agent-native:mcp-connection-completion:${completionId}`,
|
|
137
|
+
"1",
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const remountedContainer = document.createElement("div");
|
|
141
|
+
root = createRoot(remountedContainer);
|
|
142
|
+
await act(async () => {
|
|
143
|
+
root?.render(
|
|
144
|
+
<McpAgentKitConnectionResume
|
|
145
|
+
onResume={onResume}
|
|
146
|
+
onMessageResume={onMessageResume}
|
|
147
|
+
/>,
|
|
148
|
+
);
|
|
149
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
expect(onResume).toHaveBeenCalledOnce();
|
|
153
|
+
expect(onResume).toHaveBeenCalledWith(
|
|
154
|
+
target,
|
|
155
|
+
expect.objectContaining({ message: "Restore the request." }),
|
|
156
|
+
);
|
|
157
|
+
expect(onMessageResume).toHaveBeenCalledOnce();
|
|
158
|
+
expect(onMessageResume).toHaveBeenCalledWith(
|
|
159
|
+
expect.objectContaining({ message: "Restore the request." }),
|
|
160
|
+
);
|
|
161
|
+
expect(getPendingMcpConnectionResume()).toBeNull();
|
|
162
|
+
clearMcpConnectionResume();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("keeps the saved request when the fallback chat submission fails", async () => {
|
|
166
|
+
const target = { threadId: "thread-1", runId: "run-1", requestId: "req-1" };
|
|
167
|
+
saveMcpConnectionResume("Restore the request.", target);
|
|
168
|
+
const onResume = vi
|
|
169
|
+
.fn()
|
|
170
|
+
.mockRejectedValue(new Error(`Unknown AgentKit run: ${target.runId}`));
|
|
171
|
+
const onMessageResume = vi.fn().mockRejectedValue(new Error("offline"));
|
|
172
|
+
const container = document.createElement("div");
|
|
173
|
+
root = createRoot(container);
|
|
174
|
+
|
|
175
|
+
await act(async () => {
|
|
176
|
+
root?.render(
|
|
177
|
+
<McpAgentKitConnectionResume
|
|
178
|
+
onResume={onResume}
|
|
179
|
+
onMessageResume={onMessageResume}
|
|
180
|
+
/>,
|
|
181
|
+
);
|
|
182
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(onMessageResume).toHaveBeenCalledOnce();
|
|
186
|
+
expect(container.querySelector('[role="alert"]')).not.toBeNull();
|
|
187
|
+
expect(getPendingMcpConnectionResume()).toMatchObject({
|
|
188
|
+
message: "Restore the request.",
|
|
189
|
+
agentKit: target,
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("clears a stale failure alert after a later successful retry", async () => {
|
|
194
|
+
const target = { threadId: "thread-1", runId: "run-1", requestId: "req-1" };
|
|
195
|
+
saveMcpConnectionResume("Restore the request.", target);
|
|
196
|
+
const onResume = vi
|
|
197
|
+
.fn()
|
|
198
|
+
.mockRejectedValueOnce(new Error("offline"))
|
|
199
|
+
.mockResolvedValue(undefined);
|
|
200
|
+
const container = document.createElement("div");
|
|
201
|
+
root = createRoot(container);
|
|
202
|
+
|
|
203
|
+
await act(async () => {
|
|
204
|
+
root?.render(<McpAgentKitConnectionResume onResume={onResume} />);
|
|
205
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
206
|
+
});
|
|
207
|
+
expect(container.querySelector('[role="alert"]')).not.toBeNull();
|
|
208
|
+
|
|
209
|
+
await act(async () => {
|
|
210
|
+
notifyMcpConnectionComplete();
|
|
211
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(onResume).toHaveBeenCalledTimes(2);
|
|
215
|
+
expect(container.querySelector('[role="alert"]')).toBeNull();
|
|
216
|
+
expect(getPendingMcpConnectionResume()).toBeNull();
|
|
217
|
+
});
|
|
81
218
|
});
|
|
@@ -1,39 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
addMcpConnectionCompleteListener,
|
|
3
|
-
consumeMcpConnectionResume,
|
|
4
|
-
} from "@agent-native/core/client/resources/mcp-connection-resume";
|
|
5
|
-
import { useEffect, useRef } from "react";
|
|
6
|
-
|
|
7
|
-
import {
|
|
1
|
+
export {
|
|
8
2
|
McpAgentKitConnectionRequestCard,
|
|
9
|
-
|
|
3
|
+
McpAgentKitConnectionResume,
|
|
10
4
|
} from "../../resources/index.js";
|
|
11
|
-
|
|
12
|
-
export { McpAgentKitConnectionRequestCard };
|
|
13
|
-
|
|
14
|
-
/** Consumes OAuth resumes once and routes them to the matching chat submit API. */
|
|
15
|
-
export function McpAgentKitConnectionResume({
|
|
16
|
-
onResume,
|
|
17
|
-
onMessageResume,
|
|
18
|
-
}: McpAgentKitConnectionResumeProps) {
|
|
19
|
-
const onResumeRef = useRef(onResume);
|
|
20
|
-
const onMessageResumeRef = useRef(onMessageResume);
|
|
21
|
-
onResumeRef.current = onResume;
|
|
22
|
-
onMessageResumeRef.current = onMessageResume;
|
|
23
|
-
|
|
24
|
-
// Chat callbacks change with render state; one listener must own each stored resume.
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
const resumePending = () => {
|
|
27
|
-
const request = consumeMcpConnectionResume();
|
|
28
|
-
if (!request) return;
|
|
29
|
-
const operation = request.agentKit
|
|
30
|
-
? onResumeRef.current(request.agentKit, request)
|
|
31
|
-
: onMessageResumeRef.current?.(request);
|
|
32
|
-
void Promise.resolve(operation).catch(() => {});
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
resumePending();
|
|
36
|
-
return addMcpConnectionCompleteListener(resumePending);
|
|
37
|
-
}, []);
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
@@ -79,7 +79,7 @@ export interface AgentKitHistoryConfig<
|
|
|
79
79
|
args?:
|
|
80
80
|
| Record<string, unknown>
|
|
81
81
|
| ((threadId: ThreadId) => Record<string, unknown>);
|
|
82
|
-
getVersions: (result: TListResult) => readonly TVersion[];
|
|
82
|
+
getVersions: (result: TListResult) => readonly TVersion[] | null;
|
|
83
83
|
};
|
|
84
84
|
restore: {
|
|
85
85
|
action: string;
|
|
@@ -108,6 +108,8 @@ export interface AgentKitHistoryConfig<
|
|
|
108
108
|
|
|
109
109
|
export interface AgentKitHistoryContextValue {
|
|
110
110
|
beginningVersion: AgentKitHistoryVersion | null;
|
|
111
|
+
historyLoadFailed: boolean;
|
|
112
|
+
isRetryingHistory: boolean;
|
|
111
113
|
isBusy: boolean;
|
|
112
114
|
isRestoring: boolean;
|
|
113
115
|
isSubmissionInFlight: boolean;
|
|
@@ -117,6 +119,7 @@ export interface AgentKitHistoryContextValue {
|
|
|
117
119
|
beginSubmission: () => Promise<(() => void) | null>;
|
|
118
120
|
/** Wait until an in-flight restore has finished before mutating the host. */
|
|
119
121
|
waitForRestore: () => Promise<void>;
|
|
122
|
+
retryHistory: () => void;
|
|
120
123
|
findVersion: (
|
|
121
124
|
message: AgentKitHistoryMessage,
|
|
122
125
|
) => AgentKitHistoryVersion | null;
|
|
@@ -711,15 +714,18 @@ export function AgentKitHistoryProvider<
|
|
|
711
714
|
const currentThreadRef = useRef(threadId);
|
|
712
715
|
const initializedRef = useRef(false);
|
|
713
716
|
|
|
714
|
-
const
|
|
715
|
-
if (listQuery.data == null) return
|
|
717
|
+
const loadedVersions = useMemo(() => {
|
|
718
|
+
if (listQuery.data == null) return null;
|
|
716
719
|
const result = history.list.getVersions(listQuery.data);
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
: [];
|
|
720
|
+
if (!Array.isArray(result)) return null;
|
|
721
|
+
return result.filter((version): version is TVersion =>
|
|
722
|
+
isAssistantChatHistoryVersion(version),
|
|
723
|
+
);
|
|
722
724
|
}, [history.list, listQuery.data]);
|
|
725
|
+
const versions = loadedVersions ?? [];
|
|
726
|
+
const retryHistory = useCallback(() => {
|
|
727
|
+
void listQuery.refetch();
|
|
728
|
+
}, [listQuery.refetch]);
|
|
723
729
|
const historyMessages = useMemo(
|
|
724
730
|
() => getAgentKitHistoryMessages(threadId, thread, history.scope),
|
|
725
731
|
[history.scope, thread, threadId],
|
|
@@ -918,6 +924,9 @@ export function AgentKitHistoryProvider<
|
|
|
918
924
|
threadId,
|
|
919
925
|
history.isEditable,
|
|
920
926
|
),
|
|
927
|
+
historyLoadFailed:
|
|
928
|
+
listQuery.isError || (listQuery.isSuccess && loadedVersions == null),
|
|
929
|
+
isRetryingHistory: listQuery.isFetching,
|
|
921
930
|
isBusy:
|
|
922
931
|
thread.activeRunIds.length > 0 ||
|
|
923
932
|
isRestoring ||
|
|
@@ -930,6 +939,7 @@ export function AgentKitHistoryProvider<
|
|
|
930
939
|
findVersion,
|
|
931
940
|
toHistoryMessage,
|
|
932
941
|
restoreVersion,
|
|
942
|
+
retryHistory,
|
|
933
943
|
}),
|
|
934
944
|
[
|
|
935
945
|
findVersion,
|
|
@@ -937,8 +947,13 @@ export function AgentKitHistoryProvider<
|
|
|
937
947
|
beginSubmission,
|
|
938
948
|
waitForRestore,
|
|
939
949
|
history.isEditable,
|
|
950
|
+
listQuery.isError,
|
|
951
|
+
listQuery.isFetching,
|
|
952
|
+
listQuery.isSuccess,
|
|
953
|
+
loadedVersions,
|
|
940
954
|
isRestoring,
|
|
941
955
|
restoreVersion,
|
|
956
|
+
retryHistory,
|
|
942
957
|
submissionsInFlight,
|
|
943
958
|
submissionCountsByThread,
|
|
944
959
|
thread.activeRunIds.length,
|
|
@@ -38,7 +38,7 @@ export interface AssistantChatHistoryConfig<
|
|
|
38
38
|
args?:
|
|
39
39
|
| Record<string, unknown>
|
|
40
40
|
| ((threadId?: string) => Record<string, unknown>);
|
|
41
|
-
getVersions: (result: TListResult) => readonly TVersion[];
|
|
41
|
+
getVersions: (result: TListResult) => readonly TVersion[] | null;
|
|
42
42
|
};
|
|
43
43
|
restore: {
|
|
44
44
|
action: string;
|
|
@@ -990,7 +990,7 @@ describe("ToolCallDisplay native renderers", () => {
|
|
|
990
990
|
await act(async () => {
|
|
991
991
|
root.render(
|
|
992
992
|
<AgentNativeI18nProvider
|
|
993
|
-
catalog={{
|
|
993
|
+
catalog={createToolkitI18nCatalog({
|
|
994
994
|
sourceLocale: "en-US",
|
|
995
995
|
messages: {
|
|
996
996
|
agentChat: {
|
|
@@ -1001,7 +1001,7 @@ describe("ToolCallDisplay native renderers", () => {
|
|
|
1001
1001
|
},
|
|
1002
1002
|
},
|
|
1003
1003
|
},
|
|
1004
|
-
}}
|
|
1004
|
+
})}
|
|
1005
1005
|
initialLocale="en-US"
|
|
1006
1006
|
initialPreference="en-US"
|
|
1007
1007
|
persistPreference={false}
|
|
@@ -42,24 +42,12 @@ vi.mock("@agent-native/core/client/hooks", () => ({
|
|
|
42
42
|
|
|
43
43
|
import { ACTION_CHAT_UI_RECORD_CHANGE_RENDERER } from "@agent-native/core/action-ui";
|
|
44
44
|
import { normalizeActionChangeResult } from "@agent-native/core/action-ui";
|
|
45
|
-
import {
|
|
46
|
-
AgentNativeI18nProvider as CoreAgentNativeI18nProvider,
|
|
47
|
-
type AgentNativeI18nProviderProps,
|
|
48
|
-
} from "@agent-native/core/client/i18n";
|
|
45
|
+
import { AgentNativeI18nProvider } from "@agent-native/core/client/i18n";
|
|
49
46
|
|
|
50
47
|
import { createToolkitI18nCatalog } from "../../../i18n.js";
|
|
51
48
|
import { RecordChangeWidget } from "./RecordChangeWidget.js";
|
|
52
49
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
function AgentNativeI18nProvider(props: AgentNativeI18nProviderProps) {
|
|
56
|
-
return (
|
|
57
|
-
<CoreAgentNativeI18nProvider
|
|
58
|
-
{...props}
|
|
59
|
-
catalog={props.catalog ?? toolkitI18nCatalog}
|
|
60
|
-
/>
|
|
61
|
-
);
|
|
62
|
-
}
|
|
50
|
+
const catalog = createToolkitI18nCatalog({ messages: {} });
|
|
63
51
|
|
|
64
52
|
describe("core.record-change", () => {
|
|
65
53
|
let container: HTMLDivElement;
|
|
@@ -179,7 +167,7 @@ describe("core.record-change", () => {
|
|
|
179
167
|
};
|
|
180
168
|
await act(async () => {
|
|
181
169
|
root.render(
|
|
182
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
170
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
183
171
|
<RecordChangeWidget context={context} />
|
|
184
172
|
</AgentNativeI18nProvider>,
|
|
185
173
|
);
|
|
@@ -211,7 +199,7 @@ describe("core.record-change", () => {
|
|
|
211
199
|
|
|
212
200
|
await act(async () => {
|
|
213
201
|
root.render(
|
|
214
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
202
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
215
203
|
<RecordChangeWidget context={context} />
|
|
216
204
|
</AgentNativeI18nProvider>,
|
|
217
205
|
);
|
|
@@ -248,7 +236,7 @@ describe("core.record-change", () => {
|
|
|
248
236
|
|
|
249
237
|
await act(async () => {
|
|
250
238
|
root.render(
|
|
251
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
239
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
252
240
|
<RecordChangeWidget context={context} />
|
|
253
241
|
</AgentNativeI18nProvider>,
|
|
254
242
|
);
|
|
@@ -272,7 +260,7 @@ describe("core.record-change", () => {
|
|
|
272
260
|
root = createRoot(container);
|
|
273
261
|
await act(async () => {
|
|
274
262
|
root.render(
|
|
275
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
263
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
276
264
|
<RecordChangeWidget context={context} />
|
|
277
265
|
</AgentNativeI18nProvider>,
|
|
278
266
|
);
|
|
@@ -306,10 +294,10 @@ describe("core.record-change", () => {
|
|
|
306
294
|
await act(async () => {
|
|
307
295
|
root.render(
|
|
308
296
|
<>
|
|
309
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
297
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
310
298
|
<RecordChangeWidget context={context} />
|
|
311
299
|
</AgentNativeI18nProvider>
|
|
312
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
300
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
313
301
|
<RecordChangeWidget context={context} />
|
|
314
302
|
</AgentNativeI18nProvider>
|
|
315
303
|
</>,
|
|
@@ -382,7 +370,7 @@ describe("core.record-change", () => {
|
|
|
382
370
|
|
|
383
371
|
await act(async () => {
|
|
384
372
|
root.render(
|
|
385
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
373
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
386
374
|
<RecordChangeWidget context={context} />
|
|
387
375
|
</AgentNativeI18nProvider>,
|
|
388
376
|
);
|
|
@@ -411,7 +399,7 @@ describe("core.record-change", () => {
|
|
|
411
399
|
it("does not render unsafe change URLs as links", async () => {
|
|
412
400
|
await act(async () => {
|
|
413
401
|
root.render(
|
|
414
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
402
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
415
403
|
<RecordChangeWidget
|
|
416
404
|
context={{
|
|
417
405
|
toolName: "test-action",
|
|
@@ -438,7 +426,7 @@ describe("core.record-change", () => {
|
|
|
438
426
|
it("shows saved drafts as awaiting review with a review and edit action", async () => {
|
|
439
427
|
await act(async () => {
|
|
440
428
|
root.render(
|
|
441
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
429
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
442
430
|
<RecordChangeWidget
|
|
443
431
|
context={{
|
|
444
432
|
toolName: "manage-draft",
|
|
@@ -473,7 +461,7 @@ describe("core.record-change", () => {
|
|
|
473
461
|
it("uses the filter icon for Mail rule changes", async () => {
|
|
474
462
|
await act(async () => {
|
|
475
463
|
root.render(
|
|
476
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
464
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
477
465
|
<RecordChangeWidget
|
|
478
466
|
context={{
|
|
479
467
|
toolName: "manage-email-rules",
|
|
@@ -503,7 +491,7 @@ describe("core.record-change", () => {
|
|
|
503
491
|
it("localizes sharing roles and visibility in action cards", async () => {
|
|
504
492
|
await act(async () => {
|
|
505
493
|
root.render(
|
|
506
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
494
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
507
495
|
<RecordChangeWidget
|
|
508
496
|
context={{
|
|
509
497
|
toolName: "share-resource",
|
|
@@ -537,7 +525,7 @@ describe("core.record-change", () => {
|
|
|
537
525
|
]) {
|
|
538
526
|
await act(async () => {
|
|
539
527
|
root.render(
|
|
540
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
528
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
541
529
|
<RecordChangeWidget
|
|
542
530
|
context={{
|
|
543
531
|
toolName: "set-resource-visibility",
|
|
@@ -566,7 +554,7 @@ describe("core.record-change", () => {
|
|
|
566
554
|
it("renders an available Calendar time with a use-time action", async () => {
|
|
567
555
|
await act(async () => {
|
|
568
556
|
root.render(
|
|
569
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
557
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
570
558
|
<RecordChangeWidget
|
|
571
559
|
context={{
|
|
572
560
|
toolName: "find-a-time",
|
|
@@ -602,7 +590,7 @@ describe("core.record-change", () => {
|
|
|
602
590
|
}).format(Date.parse(scheduledAt));
|
|
603
591
|
await act(async () => {
|
|
604
592
|
root.render(
|
|
605
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
593
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
606
594
|
<RecordChangeWidget
|
|
607
595
|
context={{
|
|
608
596
|
toolName: "create-scheduled-send",
|
|
@@ -634,7 +622,7 @@ describe("core.record-change", () => {
|
|
|
634
622
|
it("localizes booking-link fallback titles and durations", async () => {
|
|
635
623
|
await act(async () => {
|
|
636
624
|
root.render(
|
|
637
|
-
<AgentNativeI18nProvider persistPreference={false}>
|
|
625
|
+
<AgentNativeI18nProvider catalog={catalog} persistPreference={false}>
|
|
638
626
|
<RecordChangeWidget
|
|
639
627
|
context={{
|
|
640
628
|
toolName: "create-booking-link",
|
|
@@ -666,6 +654,7 @@ describe("core.record-change", () => {
|
|
|
666
654
|
await act(async () => {
|
|
667
655
|
root.render(
|
|
668
656
|
<AgentNativeI18nProvider
|
|
657
|
+
catalog={catalog}
|
|
669
658
|
initialLocale="es-ES"
|
|
670
659
|
initialPreference="es-ES"
|
|
671
660
|
persistPreference={false}
|
|
@@ -697,6 +686,7 @@ describe("core.record-change", () => {
|
|
|
697
686
|
await act(async () => {
|
|
698
687
|
root.render(
|
|
699
688
|
<AgentNativeI18nProvider
|
|
689
|
+
catalog={catalog}
|
|
700
690
|
initialLocale="fr-FR"
|
|
701
691
|
initialPreference="fr-FR"
|
|
702
692
|
persistPreference={false}
|
|
@@ -730,6 +720,7 @@ describe("core.record-change", () => {
|
|
|
730
720
|
await act(async () => {
|
|
731
721
|
root.render(
|
|
732
722
|
<AgentNativeI18nProvider
|
|
723
|
+
catalog={catalog}
|
|
733
724
|
initialLocale="es-ES"
|
|
734
725
|
initialPreference="es-ES"
|
|
735
726
|
persistPreference={false}
|
|
@@ -1,133 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { ChatFirstCopy } from "./types.js";
|
|
4
|
-
|
|
5
|
-
const DEFAULT_COPY: Record<string, string> = {
|
|
6
|
-
newChat: "New chat",
|
|
7
|
-
search: "Search",
|
|
8
|
-
workspaceApps: "Apps",
|
|
9
|
-
allApps: "All apps",
|
|
10
|
-
integrations: "Integrations",
|
|
11
|
-
scheduled: "Scheduled",
|
|
12
|
-
createWorkspaceApp: "Create app",
|
|
13
|
-
openApp: "Open {name}",
|
|
14
|
-
appsLoadError: "Apps could not be loaded",
|
|
15
|
-
noWorkspaceApps: "No apps yet",
|
|
16
|
-
createApp: "Create app",
|
|
17
|
-
retry: "Retry",
|
|
18
|
-
dismiss: "Dismiss",
|
|
19
|
-
unpinApp: "Unpin this app",
|
|
20
|
-
pinApp: "Pin this app",
|
|
21
|
-
reloadApp: "Reload app",
|
|
22
|
-
removePinned: "Remove from pinned apps",
|
|
23
|
-
pinTop: "Pin app to the top",
|
|
24
|
-
moveUp: "Move up",
|
|
25
|
-
moveDown: "Move down",
|
|
26
|
-
removeApp: "Remove app from workspace",
|
|
27
|
-
showMore: "Show more",
|
|
28
|
-
showLess: "Show less",
|
|
29
|
-
appOrderUnavailable: "App order could not be saved on this device.",
|
|
30
|
-
openSideSurfaces: "Open side surfaces",
|
|
31
|
-
sideSurfaces: "Side surfaces",
|
|
32
|
-
resizeSideSurface: "Resize side surface",
|
|
33
|
-
closeTab: "Close {name}",
|
|
34
|
-
close: "Close",
|
|
35
|
-
closeOthers: "Close others",
|
|
36
|
-
closeToRight: "Close to the right",
|
|
37
|
-
closeAll: "Close all",
|
|
38
|
-
deferred: "Deferred",
|
|
39
|
-
openActivity: "Open activity",
|
|
40
|
-
unavailable: "This surface is not available here.",
|
|
41
|
-
browserBack: "Back",
|
|
42
|
-
browserForward: "Forward",
|
|
43
|
-
browserReload: "Reload page",
|
|
44
|
-
browserAddress: "Browser address",
|
|
45
|
-
browserOpenExternal: "Open in external browser",
|
|
46
|
-
browserClose: "Close browser",
|
|
47
|
-
browserPage: "Browser page",
|
|
48
|
-
browserInvalidUrl: "Enter a full http(s) URL to navigate.",
|
|
49
|
-
browserPreviewStarting: "Starting preview…",
|
|
50
|
-
browserPreviewError: "Preview unavailable",
|
|
51
|
-
appUnavailable: "This workspace app is no longer available.",
|
|
52
|
-
appLoadError: "This app could not be loaded",
|
|
53
|
-
appLoading: "Loading app",
|
|
54
|
-
agentActivityEyebrow: "Workspace",
|
|
55
|
-
agentActivityTitle: "Agent activity",
|
|
56
|
-
agentActivityDescription:
|
|
57
|
-
"Follow runs and open a second session beside this chat.",
|
|
58
|
-
refreshAgentActivity: "Refresh agent activity",
|
|
59
|
-
noAgentSessions: "No agent sessions yet",
|
|
60
|
-
startAgentSession: "Start an agent run and it will appear here.",
|
|
61
|
-
watchSession: "Watch",
|
|
62
|
-
copySessionId: "Copy session ID",
|
|
63
|
-
copySessionIdFor: "Copy session ID for {name}",
|
|
64
|
-
sessionIdCopied: "Session ID copied",
|
|
65
|
-
sessionIdShort: "ID",
|
|
66
|
-
copied: "Copied",
|
|
67
|
-
agentActivityStatusQueued: "Queued",
|
|
68
|
-
agentActivityStatusRunning: "Running",
|
|
69
|
-
agentActivityStatusPaused: "Paused",
|
|
70
|
-
agentActivityStatusNeedsApproval: "Needs approval",
|
|
71
|
-
agentActivityStatusCompleted: "Completed",
|
|
72
|
-
agentActivityStatusErrored: "Needs attention",
|
|
73
|
-
agentActivityStatusRecent: "Recent",
|
|
74
|
-
agentActivityStatusUnknown: "Unknown",
|
|
75
|
-
watchingSession: "Watching {name}",
|
|
76
|
-
session: "session",
|
|
77
|
-
stopWatchingSession: "Stop watching session",
|
|
78
|
-
stopWatching: "Stop watching",
|
|
79
|
-
watchedSession: "Watched session",
|
|
80
|
-
agentsTitle: "Subagents",
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const SURFACE_COPY: Record<
|
|
84
|
-
ChatFirstSurfaceKind,
|
|
85
|
-
{ label: string; reason: string }
|
|
86
|
-
> = {
|
|
87
|
-
app: {
|
|
88
|
-
label: "App",
|
|
89
|
-
reason: "Open a workspace app beside the conversation.",
|
|
90
|
-
},
|
|
91
|
-
browser: {
|
|
92
|
-
label: "Browser",
|
|
93
|
-
reason: "Ask the agent to open a web URL.",
|
|
94
|
-
},
|
|
95
|
-
terminal: {
|
|
96
|
-
label: "Terminal",
|
|
97
|
-
reason:
|
|
98
|
-
"Deferred: an embedded PTY lifecycle is not connected in this release.",
|
|
99
|
-
},
|
|
100
|
-
files: {
|
|
101
|
-
label: "Files",
|
|
102
|
-
reason:
|
|
103
|
-
"Deferred: a bounded workspace tree is not connected in this release.",
|
|
104
|
-
},
|
|
105
|
-
diff: {
|
|
106
|
-
label: "Diff",
|
|
107
|
-
reason: "Deferred: changed-file data is not connected in this release.",
|
|
108
|
-
},
|
|
109
|
-
"side-chat": {
|
|
110
|
-
label: "Side chat",
|
|
111
|
-
reason: "Choose Watch and message from any chat row.",
|
|
112
|
-
},
|
|
113
|
-
agents: {
|
|
114
|
-
label: "Agents",
|
|
115
|
-
reason: "Review recent runs or watch one beside this conversation.",
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
function interpolate(value: string, values?: Record<string, string>): string {
|
|
120
|
-
if (!values) return value;
|
|
121
|
-
return value.replace(/\{(\w+)\}/g, (_, key: string) => values[key] ?? "");
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export const defaultChatFirstCopy: ChatFirstCopy = (key, values) => {
|
|
125
|
-
if (key.startsWith("surface.")) {
|
|
126
|
-
const [, kind, field] = key.split(".");
|
|
127
|
-
const surface = SURFACE_COPY[kind as ChatFirstSurfaceKind];
|
|
128
|
-
if (surface && (field === "label" || field === "reason")) {
|
|
129
|
-
return surface[field];
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return interpolate(DEFAULT_COPY[key] ?? key, values);
|
|
133
|
-
};
|
|
1
|
+
export { defaultChatFirstCopy } from "../chat-first-copy.js";
|