@agent-native/core 0.7.19 → 0.7.21
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/README.md +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +45 -2
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/loop-settings.d.ts +37 -0
- package/dist/agent/loop-settings.d.ts.map +1 -0
- package/dist/agent/loop-settings.js +127 -0
- package/dist/agent/loop-settings.js.map +1 -0
- package/dist/agent/production-agent.d.ts +8 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +268 -29
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +76 -3
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +65 -2
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +3 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +52 -10
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/tool-search.d.ts +37 -0
- package/dist/agent/tool-search.d.ts.map +1 -0
- package/dist/agent/tool-search.js +201 -0
- package/dist/agent/tool-search.js.map +1 -0
- package/dist/agent/types.d.ts +8 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +44 -9
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/workspacify.d.ts +2 -0
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +34 -1
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +277 -18
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +1 -1
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +14 -6
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts +14 -0
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -0
- package/dist/client/NewWorkspaceAppFlow.js +198 -0
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -0
- package/dist/client/PoweredByBadge.d.ts +10 -1
- package/dist/client/PoweredByBadge.d.ts.map +1 -1
- package/dist/client/PoweredByBadge.js +120 -8
- package/dist/client/PoweredByBadge.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts +3 -5
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +26 -19
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +15 -3
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/analytics.d.ts +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +141 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/builder-frame.d.ts +10 -0
- package/dist/client/builder-frame.d.ts.map +1 -0
- package/dist/client/builder-frame.js +94 -0
- package/dist/client/builder-frame.js.map +1 -0
- package/dist/client/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +5 -1
- package/dist/client/composer/MentionPopover.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +11 -6
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/error-format.d.ts +20 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +53 -5
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +28 -1
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +88 -6
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +145 -9
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +13 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +50 -9
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +3 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +88 -7
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
- package/dist/client/tools/ToolsListPage.js +16 -1
- package/dist/client/tools/ToolsListPage.js.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.js +63 -8
- package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
- package/dist/client/tools/tool-order.d.ts +7 -0
- package/dist/client/tools/tool-order.d.ts.map +1 -0
- package/dist/client/tools/tool-order.js +47 -0
- package/dist/client/tools/tool-order.js.map +1 -0
- package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
- package/dist/client/transcription/BuilderTranscriptionCta.js +71 -6
- package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
- package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
- package/dist/client/use-send-to-agent-chat.js +11 -3
- package/dist/client/use-send-to-agent-chat.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js +1 -1
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +5 -1
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/build.d.ts +1 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +4 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/oauth-tokens/index.d.ts +1 -1
- package/dist/oauth-tokens/index.d.ts.map +1 -1
- package/dist/oauth-tokens/index.js +1 -1
- package/dist/oauth-tokens/index.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +6 -0
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +19 -19
- package/dist/observability/store.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +95 -61
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +17 -8
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/org/migrations.js +2 -2
- package/dist/org/migrations.js.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +2 -3
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/scripts/db/exec.d.ts +2 -1
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +264 -61
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/schema.d.ts.map +1 -1
- package/dist/scripts/db/schema.js +16 -4
- package/dist/scripts/db/schema.js.map +1 -1
- package/dist/scripts/dev/index.d.ts.map +1 -1
- package/dist/scripts/dev/index.js +36 -11
- package/dist/scripts/dev/index.js.map +1 -1
- package/dist/scripts/manage-agent-loop-settings.d.ts +7 -0
- package/dist/scripts/manage-agent-loop-settings.d.ts.map +1 -0
- package/dist/scripts/manage-agent-loop-settings.js +63 -0
- package/dist/scripts/manage-agent-loop-settings.js.map +1 -0
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +11 -0
- package/dist/scripts/runner.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +60 -18
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/app-url.d.ts +5 -4
- package/dist/server/app-url.d.ts.map +1 -1
- package/dist/server/app-url.js +8 -4
- package/dist/server/app-url.js.map +1 -1
- package/dist/server/auth.d.ts +8 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +82 -29
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +16 -5
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +12 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +36 -4
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +350 -53
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +21 -3
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +51 -21
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/google-oauth.d.ts +3 -0
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +27 -3
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +4 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.js +2 -2
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/schema-prompt.d.ts.map +1 -1
- package/dist/server/schema-prompt.js +2 -1
- package/dist/server/schema-prompt.js.map +1 -1
- package/dist/server/security-headers.d.ts +3 -0
- package/dist/server/security-headers.d.ts.map +1 -1
- package/dist/server/security-headers.js +7 -1
- package/dist/server/security-headers.js.map +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +31 -6
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/templates/default/_gitignore +5 -1
- package/dist/templates/default/app/root.tsx +1 -0
- package/dist/templates/default/public/favicon.svg +3 -3
- package/dist/templates/default/public/icon-180.svg +3 -3
- package/dist/templates/default/public/icon-192.svg +3 -3
- package/dist/templates/default/public/icon-512.svg +3 -3
- package/dist/templates/workspace-core/AGENTS.md +23 -7
- package/dist/templates/workspace-core/package.json +2 -1
- package/dist/templates/workspace-core/src/credentials.ts +22 -11
- package/dist/templates/workspace-root/.env.example +7 -0
- package/dist/templates/workspace-root/README.md +6 -3
- package/dist/templates/workspace-root/_gitignore +3 -0
- package/dist/templates/workspace-root/package.json +3 -1
- package/dist/templates/workspace-root/scripts/workspace-dev.ts +375 -0
- package/dist/tools/actions.d.ts.map +1 -1
- package/dist/tools/actions.js +2 -0
- package/dist/tools/actions.js.map +1 -1
- package/dist/tools/html-shell.d.ts.map +1 -1
- package/dist/tools/html-shell.js +13 -1
- package/dist/tools/html-shell.js.map +1 -1
- package/dist/tools/store.d.ts.map +1 -1
- package/dist/tools/store.js +10 -10
- package/dist/tools/store.js.map +1 -1
- package/dist/tracking/providers.d.ts +1 -0
- package/dist/tracking/providers.d.ts.map +1 -1
- package/dist/tracking/providers.js +72 -0
- package/dist/tracking/providers.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +106 -9
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +62 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/authentication.md +17 -13
- package/docs/content/deployment.md +11 -11
- package/docs/content/mcp-clients.md +2 -2
- package/docs/content/onboarding.md +32 -30
- package/docs/content/security.md +1 -1
- package/docs/content/tools.md +4 -0
- package/package.json +2 -2
- package/src/templates/default/_gitignore +5 -1
- package/src/templates/default/app/root.tsx +1 -0
- package/src/templates/default/public/favicon.svg +3 -3
- package/src/templates/default/public/icon-180.svg +3 -3
- package/src/templates/default/public/icon-192.svg +3 -3
- package/src/templates/default/public/icon-512.svg +3 -3
- package/src/templates/workspace-core/AGENTS.md +23 -7
- package/src/templates/workspace-core/package.json +2 -1
- package/src/templates/workspace-core/src/credentials.ts +22 -11
- package/src/templates/workspace-root/.env.example +7 -0
- package/src/templates/workspace-root/README.md +6 -3
- package/src/templates/workspace-root/_gitignore +3 -0
- package/src/templates/workspace-root/package.json +3 -1
- package/src/templates/workspace-root/scripts/workspace-dev.ts +375 -0
|
@@ -16,8 +16,9 @@ import { useBuilderConnectFlow } from "./settings/useBuilderStatus.js";
|
|
|
16
16
|
import { IframeEmbed, parseEmbedBody } from "./IframeEmbed.js";
|
|
17
17
|
import { useDevMode } from "./use-dev-mode.js";
|
|
18
18
|
import { agentNativePath } from "./api-path.js";
|
|
19
|
+
import { BUILDER_SPACE_SETTINGS_URL } from "./error-format.js";
|
|
19
20
|
import { TiptapComposer, } from "./composer/TiptapComposer.js";
|
|
20
|
-
import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, } from "@tabler/icons-react";
|
|
21
|
+
import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, IconGauge, IconArrowRight, IconSettings, IconAlertTriangle, IconRefresh, IconPlayerPlay, } from "@tabler/icons-react";
|
|
21
22
|
const ThumbsFeedbackLazy = React.lazy(() => import("./observability/ThumbsFeedback.js").then((m) => ({
|
|
22
23
|
default: m.ThumbsFeedback,
|
|
23
24
|
})));
|
|
@@ -46,6 +47,7 @@ const markdownStyles = `
|
|
|
46
47
|
@media (prefers-color-scheme: dark) { :root:not(.light) .agent-markdown-shiki pre { background: var(--shiki-dark-bg); color: var(--shiki-dark); } :root:not(.light) .agent-markdown-shiki pre span { color: var(--shiki-dark); background: var(--shiki-dark-bg); } }
|
|
47
48
|
.agent-markdown hr { border: none; border-top: 1px solid hsl(var(--border, 0 0% 20%)); margin: 0.75em 0; }
|
|
48
49
|
.agent-markdown a { text-decoration: underline; text-underline-offset: 2px; }
|
|
50
|
+
.agent-markdown a.agent-markdown-cta { text-decoration: none; }
|
|
49
51
|
.agent-markdown blockquote { border-left: 2px solid hsl(var(--border, 0 0% 20%)); padding-left: 0.75em; margin: 0.5em 0; opacity: 0.8; }
|
|
50
52
|
.agent-markdown table { border-collapse: collapse; margin: 0.5em 0; font-size: 0.875em; }
|
|
51
53
|
.agent-markdown th, .agent-markdown td { border: 1px solid hsl(var(--border, 0 0% 20%)); padding: 0.35em 0.65em; text-align: left; }
|
|
@@ -219,6 +221,14 @@ function HighlightedCodeBlock({ code, lang }) {
|
|
|
219
221
|
return (_jsx("pre", { children: _jsx("code", { className: lang ? `language-${lang}` : undefined, children: code }) }));
|
|
220
222
|
}
|
|
221
223
|
const markdownComponents = {
|
|
224
|
+
a(props) {
|
|
225
|
+
const { href, children, className, rel: _rel, target: _target, ...rest } = props;
|
|
226
|
+
const isBuilderCta = isBuilderErrorCtaHref(href);
|
|
227
|
+
if (!isBuilderCta) {
|
|
228
|
+
return (_jsx("a", { href: href, className: className, ...rest, children: children }));
|
|
229
|
+
}
|
|
230
|
+
return (_jsxs("a", { href: href, target: "_blank", rel: "noreferrer", className: cn("agent-markdown-cta mt-1 inline-flex items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background no-underline shadow-sm transition-colors hover:bg-foreground/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", className), ...rest, children: [_jsx("span", { children: children }), _jsx(IconExternalLink, { size: 13, strokeWidth: 2, "aria-hidden": "true" })] }));
|
|
231
|
+
},
|
|
222
232
|
pre(props) {
|
|
223
233
|
const { children, ...rest } = props;
|
|
224
234
|
if (React.isValidElement(children)) {
|
|
@@ -238,6 +248,22 @@ const markdownComponents = {
|
|
|
238
248
|
return _jsx("pre", { ...rest, children: children });
|
|
239
249
|
},
|
|
240
250
|
};
|
|
251
|
+
function isBuilderErrorCtaHref(href) {
|
|
252
|
+
if (!href)
|
|
253
|
+
return false;
|
|
254
|
+
try {
|
|
255
|
+
const url = new URL(href);
|
|
256
|
+
if (url.protocol !== "https:" || url.hostname !== "builder.io") {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
return (url.href === BUILDER_SPACE_SETTINGS_URL ||
|
|
260
|
+
url.pathname === "/account/billing" ||
|
|
261
|
+
/^\/app\/organizations\/[^/]+\/billing$/.test(url.pathname));
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
241
267
|
function MarkdownText() {
|
|
242
268
|
useEffect(() => {
|
|
243
269
|
injectMarkdownStyles();
|
|
@@ -585,10 +611,11 @@ function AssistantMessage() {
|
|
|
585
611
|
const [restoreState, setRestoreState] = useState("idle");
|
|
586
612
|
const messageRuntime = useMessageRuntime();
|
|
587
613
|
const thread = useThread();
|
|
614
|
+
const chatRunning = React.useContext(ChatRunningContext);
|
|
588
615
|
const msg = messageRuntime.getState();
|
|
589
616
|
const isLast = thread.messages.length > 0 &&
|
|
590
617
|
thread.messages[thread.messages.length - 1].id === msg.id;
|
|
591
|
-
const isComplete = !isLast || !
|
|
618
|
+
const isComplete = !isLast || !chatRunning;
|
|
592
619
|
const cpCtx = React.useContext(CheckpointContext);
|
|
593
620
|
const handleRestore = useCallback(async () => {
|
|
594
621
|
if (restoreState === "idle") {
|
|
@@ -641,14 +668,13 @@ function AssistantMessage() {
|
|
|
641
668
|
tools: {
|
|
642
669
|
Fallback: ToolCallFallback,
|
|
643
670
|
},
|
|
644
|
-
} }) }), _jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore }),
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
})(), messageSeq: thread.messages.findIndex((m) => m.id === msg.id) }) })))] })] }));
|
|
671
|
+
} }) }), isComplete && (_jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore }), showRestore && restoreState === "confirming" ? (_jsxs("div", { className: "flex items-center gap-1 text-xs", children: [_jsx("button", { onClick: handleRestore, className: "rounded-md bg-destructive px-1.5 py-0.5 text-destructive-foreground hover:bg-destructive/90", children: "Restore to here?" }), _jsx("button", { onClick: cancelRestore, className: "rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Cancel" })] })) : showRestore && restoreState === "restoring" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), "Restoring..."] })) : (_jsx(React.Suspense, { fallback: null, children: _jsx(ThumbsFeedbackLazy, { threadId: cpCtx?.threadId ?? "", runId: (() => {
|
|
672
|
+
const meta = messageRuntime.getState().metadata;
|
|
673
|
+
return ((typeof meta?.custom?.runId === "string" &&
|
|
674
|
+
meta.custom.runId) ||
|
|
675
|
+
(typeof meta?.runId === "string" && meta.runId) ||
|
|
676
|
+
"");
|
|
677
|
+
})(), messageSeq: thread.messages.findIndex((m) => m.id === msg.id) }) }))] }))] }));
|
|
652
678
|
}
|
|
653
679
|
// ─── Thinking Indicator ─────────────────────────────────────────────────────
|
|
654
680
|
function ThinkingIndicator({ label = "Thinking" } = {}) {
|
|
@@ -730,6 +756,163 @@ function ApiKeySetupCard({ apiUrl }) {
|
|
|
730
756
|
handleSave();
|
|
731
757
|
}, placeholder: "sk-ant-...", className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground/50 outline-none focus:ring-1 focus:ring-ring", autoComplete: "off" }), error && _jsx("p", { className: "text-xs text-destructive", children: error }), apiKey.trim() && (_jsx("button", { onClick: handleSave, disabled: saving, className: "w-full rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed", children: saving ? "Saving..." : "Save API key" })), _jsx("p", { className: "text-[10px] text-muted-foreground/60 text-center", children: _jsx("a", { href: "https://console.anthropic.com/settings/keys", target: "_blank", rel: "noopener noreferrer", className: "underline hover:text-foreground/80", children: "Get an Anthropic key" }) })] })] }));
|
|
732
758
|
}
|
|
759
|
+
function getLoopLimitMetadata(message) {
|
|
760
|
+
const meta = message?.metadata;
|
|
761
|
+
const loopLimit = meta?.custom?.loopLimit ?? meta?.loopLimit;
|
|
762
|
+
if (!loopLimit || typeof loopLimit !== "object")
|
|
763
|
+
return null;
|
|
764
|
+
return {
|
|
765
|
+
...(typeof loopLimit.maxIterations === "number"
|
|
766
|
+
? { maxIterations: loopLimit.maxIterations }
|
|
767
|
+
: {}),
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
function getRunErrorMetadata(message) {
|
|
771
|
+
const meta = message?.metadata;
|
|
772
|
+
const runError = meta?.custom?.runError ?? meta?.runError;
|
|
773
|
+
if (!runError || typeof runError !== "object")
|
|
774
|
+
return null;
|
|
775
|
+
const messageText = typeof runError.message === "string" ? runError.message : "";
|
|
776
|
+
if (!messageText)
|
|
777
|
+
return null;
|
|
778
|
+
const runId = typeof runError.runId === "string"
|
|
779
|
+
? runError.runId
|
|
780
|
+
: typeof meta?.custom?.runId === "string"
|
|
781
|
+
? meta.custom.runId
|
|
782
|
+
: typeof meta?.runId === "string"
|
|
783
|
+
? meta.runId
|
|
784
|
+
: undefined;
|
|
785
|
+
return {
|
|
786
|
+
message: messageText,
|
|
787
|
+
...(typeof runError.details === "string"
|
|
788
|
+
? { details: runError.details }
|
|
789
|
+
: {}),
|
|
790
|
+
...(typeof runError.errorCode === "string"
|
|
791
|
+
? { errorCode: runError.errorCode }
|
|
792
|
+
: {}),
|
|
793
|
+
...(runId ? { runId } : {}),
|
|
794
|
+
...(runError.recoverable ? { recoverable: true } : {}),
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
function getMessageText(message) {
|
|
798
|
+
const msg = message?.message ?? message;
|
|
799
|
+
const content = msg?.content;
|
|
800
|
+
if (Array.isArray(content)) {
|
|
801
|
+
return content
|
|
802
|
+
.filter((p) => p?.type === "text" && typeof p.text === "string")
|
|
803
|
+
.map((p) => p.text)
|
|
804
|
+
.join("\n")
|
|
805
|
+
.trim();
|
|
806
|
+
}
|
|
807
|
+
return typeof content === "string" ? content.trim() : "";
|
|
808
|
+
}
|
|
809
|
+
function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDismiss, }) {
|
|
810
|
+
const [detailsOpen, setDetailsOpen] = useState(false);
|
|
811
|
+
const [copied, setCopied] = useState(false);
|
|
812
|
+
const copyDetails = useCallback(() => {
|
|
813
|
+
const text = [
|
|
814
|
+
info.message,
|
|
815
|
+
info.errorCode ? `Code: ${info.errorCode}` : "",
|
|
816
|
+
info.runId ? `Run: ${info.runId}` : "",
|
|
817
|
+
info.details ? `Details:\n${info.details}` : "",
|
|
818
|
+
]
|
|
819
|
+
.filter(Boolean)
|
|
820
|
+
.join("\n\n");
|
|
821
|
+
navigator.clipboard.writeText(text);
|
|
822
|
+
setCopied(true);
|
|
823
|
+
setTimeout(() => setCopied(false), 1200);
|
|
824
|
+
}, [info]);
|
|
825
|
+
return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: "The agent stopped before finishing" }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), "Continue"] }), _jsxs("button", { type: "button", onClick: onRetry, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { size: 13 }), "Retry"] }), onFork && (_jsxs("button", { type: "button", onClick: onFork, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconGitFork, { size: 13 }), "Fork"] })), _jsxs("button", { type: "button", onClick: copyDetails, className: "ml-auto inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium text-muted-foreground hover:bg-background/80 hover:text-foreground", children: [copied ? _jsx(IconCheck, { size: 13 }) : _jsx(IconCopy, { size: 13 }), copied ? "Copied" : "Copy"] })] })] }));
|
|
826
|
+
}
|
|
827
|
+
function LoopLimitContinueCard({ info, onContinue, }) {
|
|
828
|
+
const [settings, setSettings] = useState(null);
|
|
829
|
+
const [value, setValue] = useState("");
|
|
830
|
+
const [saving, setSaving] = useState(false);
|
|
831
|
+
const [saved, setSaved] = useState(false);
|
|
832
|
+
const [error, setError] = useState(null);
|
|
833
|
+
const load = useCallback(() => {
|
|
834
|
+
let cancelled = false;
|
|
835
|
+
fetch(agentNativePath("/_agent-native/agent-loop-settings"))
|
|
836
|
+
.then((r) => (r.ok ? r.json() : null))
|
|
837
|
+
.then((data) => {
|
|
838
|
+
if (cancelled || !data)
|
|
839
|
+
return;
|
|
840
|
+
setSettings(data);
|
|
841
|
+
setValue(String(data.maxIterations));
|
|
842
|
+
})
|
|
843
|
+
.catch(() => {
|
|
844
|
+
if (!cancelled)
|
|
845
|
+
setValue(String(info.maxIterations ?? ""));
|
|
846
|
+
});
|
|
847
|
+
return () => {
|
|
848
|
+
cancelled = true;
|
|
849
|
+
};
|
|
850
|
+
}, [info.maxIterations]);
|
|
851
|
+
useEffect(() => load(), [load]);
|
|
852
|
+
const currentLimit = settings?.maxIterations ?? info.maxIterations;
|
|
853
|
+
const numericValue = Number(value);
|
|
854
|
+
const hasPendingChange = !!settings &&
|
|
855
|
+
settings.canUpdate &&
|
|
856
|
+
Number.isInteger(numericValue) &&
|
|
857
|
+
numericValue !== settings.maxIterations;
|
|
858
|
+
const scopeLabel = settings?.scope === "org"
|
|
859
|
+
? settings.orgName
|
|
860
|
+
? `${settings.orgName} org`
|
|
861
|
+
: "org"
|
|
862
|
+
: "your account";
|
|
863
|
+
const saveLimit = useCallback(async () => {
|
|
864
|
+
if (!settings?.canUpdate)
|
|
865
|
+
return false;
|
|
866
|
+
setSaving(true);
|
|
867
|
+
setSaved(false);
|
|
868
|
+
setError(null);
|
|
869
|
+
try {
|
|
870
|
+
const res = await fetch(agentNativePath("/_agent-native/agent-loop-settings"), {
|
|
871
|
+
method: "PUT",
|
|
872
|
+
headers: { "Content-Type": "application/json" },
|
|
873
|
+
body: JSON.stringify({ maxIterations: numericValue }),
|
|
874
|
+
});
|
|
875
|
+
const body = await res.json().catch(() => ({}));
|
|
876
|
+
if (!res.ok) {
|
|
877
|
+
throw new Error(body?.error ?? `Save failed (${res.status})`);
|
|
878
|
+
}
|
|
879
|
+
setSettings(body);
|
|
880
|
+
setValue(String(body.maxIterations));
|
|
881
|
+
setSaved(true);
|
|
882
|
+
window.dispatchEvent(new CustomEvent("agent-loop-settings:changed", { detail: body }));
|
|
883
|
+
setTimeout(() => setSaved(false), 2000);
|
|
884
|
+
return true;
|
|
885
|
+
}
|
|
886
|
+
catch (err) {
|
|
887
|
+
setError(err instanceof Error ? err.message : "Save failed");
|
|
888
|
+
return false;
|
|
889
|
+
}
|
|
890
|
+
finally {
|
|
891
|
+
setSaving(false);
|
|
892
|
+
}
|
|
893
|
+
}, [numericValue, settings?.canUpdate]);
|
|
894
|
+
const handleContinue = useCallback(async () => {
|
|
895
|
+
if (hasPendingChange) {
|
|
896
|
+
const ok = await saveLimit();
|
|
897
|
+
if (!ok)
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
onContinue();
|
|
901
|
+
}, [hasPendingChange, onContinue, saveLimit]);
|
|
902
|
+
const openSettings = useCallback(() => {
|
|
903
|
+
try {
|
|
904
|
+
window.location.hash = "agent-limits";
|
|
905
|
+
}
|
|
906
|
+
catch { }
|
|
907
|
+
window.dispatchEvent(new CustomEvent("agent-panel:open-settings"));
|
|
908
|
+
}, []);
|
|
909
|
+
return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] px-3 py-3 shadow-sm", children: [_jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-600 dark:text-amber-400", children: _jsx(IconGauge, { size: 14 }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Step limit reached" }), _jsxs("p", { className: "mt-0.5 text-xs leading-relaxed text-muted-foreground", children: ["The agent used", " ", currentLimit
|
|
910
|
+
? `${currentLimit.toLocaleString()} steps`
|
|
911
|
+
: "all available steps", ". Keep going in a fresh turn, or raise the ", scopeLabel, " limit first."] })] })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-end gap-2", children: [_jsxs("label", { className: "min-w-[116px] flex-1 space-y-1", children: [_jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Max steps" }), _jsx("input", { type: "number", min: settings?.minMaxIterations ?? 1, max: settings?.maxMaxIterations ?? 1000, value: value, disabled: !settings?.canUpdate || saving, onChange: (e) => {
|
|
912
|
+
setValue(e.target.value);
|
|
913
|
+
setError(null);
|
|
914
|
+
}, className: "h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground outline-none focus:ring-1 focus:ring-ring disabled:opacity-60" })] }), _jsx("button", { type: "button", onClick: saveLimit, disabled: !hasPendingChange || saving, className: "inline-flex h-8 items-center gap-1 rounded-md border border-border px-2.5 text-xs font-medium text-foreground hover:bg-accent disabled:opacity-50", children: saving ? (_jsx(IconLoader2, { size: 12, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 12 })) : ("Save") }), _jsxs("button", { type: "button", onClick: openSettings, className: "inline-flex h-8 items-center gap-1 rounded-md border border-border px-2.5 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground", children: [_jsx(IconSettings, { size: 12 }), "Settings"] }), _jsxs("button", { type: "button", onClick: handleContinue, disabled: saving, className: "ml-auto inline-flex h-8 items-center gap-1 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90 disabled:opacity-60", children: [hasPendingChange ? "Save and keep going" : "Keep going", _jsx(IconArrowRight, { size: 12 })] })] }), settings && !settings.canUpdate && (_jsx("p", { className: "mt-2 text-[11px] text-muted-foreground", children: "Only organization owners and admins can change this limit." })), error && _jsx("p", { className: "mt-2 text-[11px] text-destructive", children: error })] }));
|
|
915
|
+
}
|
|
733
916
|
export const CHAT_STORAGE_PREFIX = "agent-chat:";
|
|
734
917
|
/** Remove persisted chat for a given tabId (or "default"). */
|
|
735
918
|
export function clearChatStorage(tabId) {
|
|
@@ -778,6 +961,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
778
961
|
// on mount, or queue state that hasn't actually changed).
|
|
779
962
|
const lastPersistedQueueRef = useRef("[]");
|
|
780
963
|
const [showContinue, setShowContinue] = useState(false);
|
|
964
|
+
const [loopLimitInfo, setLoopLimitInfo] = useState(null);
|
|
965
|
+
const [runErrorInfo, setRunErrorInfo] = useState(null);
|
|
966
|
+
const [dismissedRunErrorKey, setDismissedRunErrorKey] = useState(null);
|
|
781
967
|
const [isReconnecting, setIsReconnecting] = useState(false);
|
|
782
968
|
const [reconnectContent, setReconnectContent] = useState([]);
|
|
783
969
|
// When stop is clicked during reconnect, keep content visible (don't wipe it)
|
|
@@ -1212,12 +1398,36 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1212
1398
|
const handler = (e) => {
|
|
1213
1399
|
const detail = e.detail;
|
|
1214
1400
|
if (!tabId || detail?.tabId === tabId) {
|
|
1401
|
+
setLoopLimitInfo({
|
|
1402
|
+
...(typeof detail?.maxIterations === "number"
|
|
1403
|
+
? { maxIterations: detail.maxIterations }
|
|
1404
|
+
: {}),
|
|
1405
|
+
});
|
|
1215
1406
|
setShowContinue(true);
|
|
1216
1407
|
}
|
|
1217
1408
|
};
|
|
1218
1409
|
window.addEventListener("agent-chat:loop-limit", handler);
|
|
1219
1410
|
return () => window.removeEventListener("agent-chat:loop-limit", handler);
|
|
1220
1411
|
}, [tabId]);
|
|
1412
|
+
useEffect(() => {
|
|
1413
|
+
const handler = (e) => {
|
|
1414
|
+
const detail = e.detail;
|
|
1415
|
+
if (tabId && detail?.tabId && detail.tabId !== tabId)
|
|
1416
|
+
return;
|
|
1417
|
+
if (!detail?.message)
|
|
1418
|
+
return;
|
|
1419
|
+
setRunErrorInfo({
|
|
1420
|
+
message: detail.message,
|
|
1421
|
+
...(detail.details ? { details: detail.details } : {}),
|
|
1422
|
+
...(detail.errorCode ? { errorCode: detail.errorCode } : {}),
|
|
1423
|
+
...(detail.runId ? { runId: detail.runId } : {}),
|
|
1424
|
+
...(detail.recoverable ? { recoverable: detail.recoverable } : {}),
|
|
1425
|
+
});
|
|
1426
|
+
setDismissedRunErrorKey(null);
|
|
1427
|
+
};
|
|
1428
|
+
window.addEventListener("agent-chat:run-error", handler);
|
|
1429
|
+
return () => window.removeEventListener("agent-chat:run-error", handler);
|
|
1430
|
+
}, [tabId]);
|
|
1221
1431
|
// Auto-dequeue: when agent finishes running, send the next queued message
|
|
1222
1432
|
useEffect(() => {
|
|
1223
1433
|
if (wasRunningRef.current && !isRunning && queuedMessages.length > 0) {
|
|
@@ -1273,6 +1483,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1273
1483
|
}, [isReconnecting, forceStopped]);
|
|
1274
1484
|
const addToQueue = useCallback((text, images, references) => {
|
|
1275
1485
|
setShowContinue(false);
|
|
1486
|
+
setLoopLimitInfo(null);
|
|
1487
|
+
setRunErrorInfo(null);
|
|
1488
|
+
setDismissedRunErrorKey(null);
|
|
1276
1489
|
// Selection context attached via Cmd+I is one-shot — clear it as soon
|
|
1277
1490
|
// as the user actually sends a message so it can't be re-used.
|
|
1278
1491
|
clearPendingSelection();
|
|
@@ -1374,6 +1587,35 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1374
1587
|
const { isDevMode: cpDevMode } = useDevMode(apiUrl);
|
|
1375
1588
|
const checkpointCtx = useMemo(() => ({ apiUrl, devMode: cpDevMode, threadId }), [apiUrl, cpDevMode, threadId]);
|
|
1376
1589
|
const messageActionsCtx = useMemo(() => ({ onForkChat }), [onForkChat]);
|
|
1590
|
+
const lastMessageLoopLimit = useMemo(() => {
|
|
1591
|
+
const last = messages[messages.length - 1];
|
|
1592
|
+
if (!last || last.role !== "assistant")
|
|
1593
|
+
return null;
|
|
1594
|
+
return getLoopLimitMetadata(last);
|
|
1595
|
+
}, [messages]);
|
|
1596
|
+
const lastMessageRunError = useMemo(() => {
|
|
1597
|
+
const last = messages[messages.length - 1];
|
|
1598
|
+
if (!last || last.role !== "assistant")
|
|
1599
|
+
return null;
|
|
1600
|
+
return getRunErrorMetadata(last);
|
|
1601
|
+
}, [messages]);
|
|
1602
|
+
const lastUserText = useMemo(() => {
|
|
1603
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1604
|
+
if (messages[i]?.role === "user")
|
|
1605
|
+
return getMessageText(messages[i]);
|
|
1606
|
+
}
|
|
1607
|
+
return "";
|
|
1608
|
+
}, [messages]);
|
|
1609
|
+
const visibleLoopLimit = showContinue
|
|
1610
|
+
? (loopLimitInfo ?? lastMessageLoopLimit ?? {})
|
|
1611
|
+
: lastMessageLoopLimit;
|
|
1612
|
+
const visibleRunError = runErrorInfo ?? lastMessageRunError;
|
|
1613
|
+
const visibleRunErrorKey = visibleRunError
|
|
1614
|
+
? `${visibleRunError.runId ?? ""}:${visibleRunError.errorCode ?? ""}:${visibleRunError.message}`
|
|
1615
|
+
: null;
|
|
1616
|
+
const shouldShowRunError = !!visibleRunError &&
|
|
1617
|
+
!showRunningInUI &&
|
|
1618
|
+
visibleRunErrorKey !== dismissedRunErrorKey;
|
|
1377
1619
|
return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ChatRunningContext.Provider, { value: isRunning, children: _jsxs("div", { className: cn("flex flex-1 flex-col h-full min-h-0 text-foreground", className), children: [showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsxs("button", { onClick: onSwitchToCli, className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", title: "Switch to CLI", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] })) })] })), _jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto overflow-x-hidden min-h-0", children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-destructive/10", children: _jsx(IconLock, { className: "h-5 w-5 text-destructive" }) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authError.sessionExpired
|
|
1378
1620
|
? "Session expired"
|
|
1379
1621
|
: "Authentication required" }), _jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: authError.sessionExpired ? ("Your session may have expired. Log out and log back in to reconnect.") : (_jsxs(_Fragment, { children: ["You need to log in to use the agent. If you're running locally, add", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded text-[10px]", children: "AUTH_MODE=local" }), " ", "to your", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded text-[10px]", children: ".env" }), " ", "file and restart the dev server."] })) })] }), _jsxs("div", { className: "flex gap-2", children: [authError.sessionExpired && (_jsx("button", { onClick: async () => {
|
|
@@ -1395,16 +1637,31 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1395
1637
|
}, className: "w-full rounded-lg border border-border px-3 py-2 text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground", children: suggestion }, suggestion))) }))] })) : (_jsxs("div", { className: "agent-thread-content flex flex-col gap-4 px-4 py-4", children: [_jsx(ThreadPrimitive.Messages, { components: {
|
|
1396
1638
|
UserMessage,
|
|
1397
1639
|
AssistantMessage,
|
|
1398
|
-
} }),
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1640
|
+
} }), visibleLoopLimit && !showRunningInUI && (_jsx(LoopLimitContinueCard, { info: visibleLoopLimit, onContinue: () => {
|
|
1641
|
+
setShowContinue(false);
|
|
1642
|
+
setLoopLimitInfo(null);
|
|
1643
|
+
addToQueue("Continue from where you left off.");
|
|
1644
|
+
} })), shouldShowRunError && visibleRunError && (_jsx(RunErrorRecoveryCard, { info: visibleRunError, onContinue: () => {
|
|
1645
|
+
setRunErrorInfo(null);
|
|
1646
|
+
addToQueue("Continue from where you stopped. Use the partial work above, verify what succeeded, and finish the original request. Prefer dedicated app actions over raw database edits when they exist.");
|
|
1647
|
+
}, onRetry: () => {
|
|
1648
|
+
setRunErrorInfo(null);
|
|
1649
|
+
addToQueue(lastUserText
|
|
1650
|
+
? `Retry the previous request from a clean approach. Original request:\n\n${lastUserText}`
|
|
1651
|
+
: "Retry the previous request from a clean approach.");
|
|
1652
|
+
}, onFork: onForkChat, onDismiss: () => {
|
|
1653
|
+
if (visibleRunErrorKey) {
|
|
1654
|
+
setDismissedRunErrorKey(visibleRunErrorKey);
|
|
1655
|
+
}
|
|
1656
|
+
setRunErrorInfo(null);
|
|
1657
|
+
} })), (isReconnecting || reconnectFrozen) &&
|
|
1402
1658
|
reconnectContent.length > 0 && (_jsx(ReconnectStreamMessage, { content: reconnectContent })), showRunningInUI && (_jsx(ThinkingIndicator, { label: isReconnecting ? "Reconnecting" : "Thinking" })), queuedMessages.map((msg) => {
|
|
1403
1659
|
const displayText = msg.text
|
|
1404
1660
|
.replace(/<context>[\s\S]*?<\/context>\n?/g, "")
|
|
1405
1661
|
.trim();
|
|
1406
1662
|
return (_jsx("div", { className: "flex justify-end group", children: _jsxs("div", { className: "relative max-w-[85%] rounded-lg bg-accent/50 text-foreground/60 px-3 py-2 text-sm leading-relaxed whitespace-pre-wrap break-words", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground mb-1 font-medium uppercase tracking-wide", children: [_jsx(IconClock, { className: "h-3 w-3" }), "Queued"] }), displayText, msg.images && msg.images.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5", children: msg.images.map((img, j) => (_jsx("img", { src: img, alt: "", className: "h-12 w-12 rounded object-cover border border-border/50" }, j))) })), _jsx("button", { type: "button", onClick: () => setQueuedMessages((prev) => prev.filter((m) => m.id !== msg.id)), "aria-label": "Remove from queue", className: "absolute -top-2 -right-2 flex h-5 w-5 items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:text-foreground hover:bg-accent shadow-sm", children: _jsx(IconX, { className: "h-3 w-3" }) })] }) }, msg.id));
|
|
1407
|
-
})] })) }), showScrollToBottom && (_jsx("div", { className: "shrink-0 flex justify-center -mb-1", children: _jsx("button", { type: "button", onClick: scrollToBottom, className: "flex h-7 w-7 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent", "aria-label": "Scroll to bottom", children: _jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) })), composerSlot, _jsx(SelectionAttachedPill, {}), _jsx("div", { className: "agent-composer-area shrink-0 px-3 py-2", children: _jsxs(ComposerPrimitive.Root, { className: "flex flex-col rounded-lg border border-input bg-background focus-within:ring-1 focus-within:ring-ring",
|
|
1663
|
+
})] })) }), showScrollToBottom && (_jsx("div", { className: "shrink-0 flex justify-center -mb-1", children: _jsx("button", { type: "button", onClick: scrollToBottom, className: "flex h-7 w-7 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent", "aria-label": "Scroll to bottom", children: _jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) })), composerSlot, _jsx(SelectionAttachedPill, {}), _jsx("div", { className: "agent-composer-area shrink-0 px-3 py-2", children: _jsxs(ComposerPrimitive.Root, { className: cn("flex flex-col rounded-lg border border-input bg-background focus-within:ring-1 focus-within:ring-ring", execMode === "plan" &&
|
|
1664
|
+
"border-amber-500/50 bg-amber-500/[0.03] focus-within:ring-amber-500/30"), children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, disabled: missingApiKey, placeholder: missingApiKey
|
|
1408
1665
|
? "Connect an AI engine above to start chatting…"
|
|
1409
1666
|
: isRunning
|
|
1410
1667
|
? queuedMessages.length > 0
|
|
@@ -1417,10 +1674,12 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1417
1674
|
// immediately. This unblocks submission even if the
|
|
1418
1675
|
// runtime or reconnect state is stuck.
|
|
1419
1676
|
setForceStopped(true);
|
|
1677
|
+
const activeRun = getActiveRun();
|
|
1678
|
+
const runIdToAbort = reconnectRunIdRef.current ?? activeRun?.runId;
|
|
1679
|
+
if (runIdToAbort) {
|
|
1680
|
+
fetch(`${apiUrl}/runs/${encodeURIComponent(runIdToAbort)}/abort`, { method: "POST" }).catch(() => { });
|
|
1681
|
+
}
|
|
1420
1682
|
if (isReconnecting) {
|
|
1421
|
-
if (reconnectRunIdRef.current) {
|
|
1422
|
-
fetch(`${apiUrl}/runs/${encodeURIComponent(reconnectRunIdRef.current)}/abort`, { method: "POST" });
|
|
1423
|
-
}
|
|
1424
1683
|
reconnectAbortRef.current?.abort();
|
|
1425
1684
|
reconnectAbortRef.current = null;
|
|
1426
1685
|
reconnectRunIdRef.current = null;
|