@agent-native/core 0.7.18 → 0.7.20
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 +60 -5
- 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 +57 -11
- 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 +303 -14
- 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 +16 -24
- 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 +200 -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 +8 -0
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +32 -5
- 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/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/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +14 -2
- package/dist/client/org/TeamPage.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 +9 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +95 -8
- 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/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +1 -1
- package/dist/integrations/pending-tasks-retry-job.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 +37 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +114 -35
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +15 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +131 -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 +35 -18
- 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/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 +24 -4
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts +7 -0
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +1 -0
- package/dist/server/voice-providers-status.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 +410 -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 +16 -11
- 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 +67 -2
- 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 +410 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AACA,OAAO,KAQN,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AACA,OAAO,KAQN,MAAM,OAAO,CAAC;AA22Df,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6DAA6D;IAC7D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,4CAA4C;IAC5C,SAAS,IAAI,OAAO,CAAC;IACrB,+BAA+B;IAC/B,aAAa,IAAI,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wGAAwG;IACxG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,0CAA0C;IAC1C,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,KACE,IAAI,CAAC;IACV,+DAA+D;IAC/D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,8DAA8D;IAC9D,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,+FAA+F;IAC/F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,uDAAuD;IACvD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,QAI9C;AAyBD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAymC7B,eAAO,MAAM,aAAa,gGAwDxB,CAAC"}
|
|
@@ -7,6 +7,7 @@ import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";
|
|
|
7
7
|
import ReactMarkdown from "react-markdown";
|
|
8
8
|
import remarkGfm from "remark-gfm";
|
|
9
9
|
import { createAgentChatAdapter } from "./agent-chat-adapter.js";
|
|
10
|
+
import { getActiveRun } from "./active-run-state.js";
|
|
10
11
|
import { readSSEStreamRaw } from "./sse-event-processor.js";
|
|
11
12
|
import { cn } from "./utils.js";
|
|
12
13
|
import { AgentTaskCard } from "./AgentTaskCard.js";
|
|
@@ -15,8 +16,9 @@ import { useBuilderConnectFlow } from "./settings/useBuilderStatus.js";
|
|
|
15
16
|
import { IframeEmbed, parseEmbedBody } from "./IframeEmbed.js";
|
|
16
17
|
import { useDevMode } from "./use-dev-mode.js";
|
|
17
18
|
import { agentNativePath } from "./api-path.js";
|
|
19
|
+
import { BUILDER_SPACE_SETTINGS_URL } from "./error-format.js";
|
|
18
20
|
import { TiptapComposer, } from "./composer/TiptapComposer.js";
|
|
19
|
-
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";
|
|
20
22
|
const ThumbsFeedbackLazy = React.lazy(() => import("./observability/ThumbsFeedback.js").then((m) => ({
|
|
21
23
|
default: m.ThumbsFeedback,
|
|
22
24
|
})));
|
|
@@ -45,6 +47,7 @@ const markdownStyles = `
|
|
|
45
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); } }
|
|
46
48
|
.agent-markdown hr { border: none; border-top: 1px solid hsl(var(--border, 0 0% 20%)); margin: 0.75em 0; }
|
|
47
49
|
.agent-markdown a { text-decoration: underline; text-underline-offset: 2px; }
|
|
50
|
+
.agent-markdown a.agent-markdown-cta { text-decoration: none; }
|
|
48
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; }
|
|
49
52
|
.agent-markdown table { border-collapse: collapse; margin: 0.5em 0; font-size: 0.875em; }
|
|
50
53
|
.agent-markdown th, .agent-markdown td { border: 1px solid hsl(var(--border, 0 0% 20%)); padding: 0.35em 0.65em; text-align: left; }
|
|
@@ -218,6 +221,14 @@ function HighlightedCodeBlock({ code, lang }) {
|
|
|
218
221
|
return (_jsx("pre", { children: _jsx("code", { className: lang ? `language-${lang}` : undefined, children: code }) }));
|
|
219
222
|
}
|
|
220
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
|
+
},
|
|
221
232
|
pre(props) {
|
|
222
233
|
const { children, ...rest } = props;
|
|
223
234
|
if (React.isValidElement(children)) {
|
|
@@ -237,6 +248,22 @@ const markdownComponents = {
|
|
|
237
248
|
return _jsx("pre", { ...rest, children: children });
|
|
238
249
|
},
|
|
239
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
|
+
}
|
|
240
267
|
function MarkdownText() {
|
|
241
268
|
useEffect(() => {
|
|
242
269
|
injectMarkdownStyles();
|
|
@@ -543,7 +570,17 @@ function MessageActionsMenu({ showRevert, onRevert, } = {}) {
|
|
|
543
570
|
}, [messageRuntime]);
|
|
544
571
|
const handleCopyRequestId = useCallback(() => {
|
|
545
572
|
const m = messageRuntime.getState();
|
|
546
|
-
const
|
|
573
|
+
const meta = m.metadata;
|
|
574
|
+
// Live yields put the trace ID at metadata.custom.runId; server-persisted
|
|
575
|
+
// messages put it at metadata.runId. If neither is present (e.g. the run
|
|
576
|
+
// is still in flight and this is the first message), fall back to the
|
|
577
|
+
// active-run state so a hung / mid-stream chat still surfaces a usable
|
|
578
|
+
// trace ID. Last resort is the assistant-ui local message id.
|
|
579
|
+
const runId = (typeof meta?.custom?.runId === "string" && meta.custom.runId) ||
|
|
580
|
+
(typeof meta?.runId === "string" && meta.runId) ||
|
|
581
|
+
(typeof window !== "undefined" ? getActiveRun()?.runId : null) ||
|
|
582
|
+
m.id ||
|
|
583
|
+
"";
|
|
547
584
|
navigator.clipboard.writeText(runId);
|
|
548
585
|
setCopied("id");
|
|
549
586
|
setTimeout(() => {
|
|
@@ -574,10 +611,11 @@ function AssistantMessage() {
|
|
|
574
611
|
const [restoreState, setRestoreState] = useState("idle");
|
|
575
612
|
const messageRuntime = useMessageRuntime();
|
|
576
613
|
const thread = useThread();
|
|
614
|
+
const chatRunning = React.useContext(ChatRunningContext);
|
|
577
615
|
const msg = messageRuntime.getState();
|
|
578
616
|
const isLast = thread.messages.length > 0 &&
|
|
579
617
|
thread.messages[thread.messages.length - 1].id === msg.id;
|
|
580
|
-
const isComplete = !isLast || !
|
|
618
|
+
const isComplete = !isLast || !chatRunning;
|
|
581
619
|
const cpCtx = React.useContext(CheckpointContext);
|
|
582
620
|
const handleRestore = useCallback(async () => {
|
|
583
621
|
if (restoreState === "idle") {
|
|
@@ -589,7 +627,10 @@ function AssistantMessage() {
|
|
|
589
627
|
setRestoreState("restoring");
|
|
590
628
|
try {
|
|
591
629
|
const m = messageRuntime.getState();
|
|
592
|
-
const
|
|
630
|
+
const meta = m.metadata;
|
|
631
|
+
const runId = (typeof meta?.custom?.runId === "string" && meta.custom.runId) ||
|
|
632
|
+
(typeof meta?.runId === "string" && meta.runId) ||
|
|
633
|
+
null;
|
|
593
634
|
if (!runId) {
|
|
594
635
|
setRestoreState("idle");
|
|
595
636
|
return;
|
|
@@ -627,7 +668,13 @@ function AssistantMessage() {
|
|
|
627
668
|
tools: {
|
|
628
669
|
Fallback: ToolCallFallback,
|
|
629
670
|
},
|
|
630
|
-
} }) }), 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:
|
|
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) }) }))] }))] }));
|
|
631
678
|
}
|
|
632
679
|
// ─── Thinking Indicator ─────────────────────────────────────────────────────
|
|
633
680
|
function ThinkingIndicator({ label = "Thinking" } = {}) {
|
|
@@ -709,6 +756,163 @@ function ApiKeySetupCard({ apiUrl }) {
|
|
|
709
756
|
handleSave();
|
|
710
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" }) })] })] }));
|
|
711
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
|
+
}
|
|
712
916
|
export const CHAT_STORAGE_PREFIX = "agent-chat:";
|
|
713
917
|
/** Remove persisted chat for a given tabId (or "default"). */
|
|
714
918
|
export function clearChatStorage(tabId) {
|
|
@@ -757,6 +961,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
757
961
|
// on mount, or queue state that hasn't actually changed).
|
|
758
962
|
const lastPersistedQueueRef = useRef("[]");
|
|
759
963
|
const [showContinue, setShowContinue] = useState(false);
|
|
964
|
+
const [loopLimitInfo, setLoopLimitInfo] = useState(null);
|
|
965
|
+
const [runErrorInfo, setRunErrorInfo] = useState(null);
|
|
966
|
+
const [dismissedRunErrorKey, setDismissedRunErrorKey] = useState(null);
|
|
760
967
|
const [isReconnecting, setIsReconnecting] = useState(false);
|
|
761
968
|
const [reconnectContent, setReconnectContent] = useState([]);
|
|
762
969
|
// When stop is clicked during reconnect, keep content visible (don't wipe it)
|
|
@@ -1191,12 +1398,36 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1191
1398
|
const handler = (e) => {
|
|
1192
1399
|
const detail = e.detail;
|
|
1193
1400
|
if (!tabId || detail?.tabId === tabId) {
|
|
1401
|
+
setLoopLimitInfo({
|
|
1402
|
+
...(typeof detail?.maxIterations === "number"
|
|
1403
|
+
? { maxIterations: detail.maxIterations }
|
|
1404
|
+
: {}),
|
|
1405
|
+
});
|
|
1194
1406
|
setShowContinue(true);
|
|
1195
1407
|
}
|
|
1196
1408
|
};
|
|
1197
1409
|
window.addEventListener("agent-chat:loop-limit", handler);
|
|
1198
1410
|
return () => window.removeEventListener("agent-chat:loop-limit", handler);
|
|
1199
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]);
|
|
1200
1431
|
// Auto-dequeue: when agent finishes running, send the next queued message
|
|
1201
1432
|
useEffect(() => {
|
|
1202
1433
|
if (wasRunningRef.current && !isRunning && queuedMessages.length > 0) {
|
|
@@ -1252,6 +1483,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1252
1483
|
}, [isReconnecting, forceStopped]);
|
|
1253
1484
|
const addToQueue = useCallback((text, images, references) => {
|
|
1254
1485
|
setShowContinue(false);
|
|
1486
|
+
setLoopLimitInfo(null);
|
|
1487
|
+
setRunErrorInfo(null);
|
|
1488
|
+
setDismissedRunErrorKey(null);
|
|
1255
1489
|
// Selection context attached via Cmd+I is one-shot — clear it as soon
|
|
1256
1490
|
// as the user actually sends a message so it can't be re-used.
|
|
1257
1491
|
clearPendingSelection();
|
|
@@ -1353,6 +1587,35 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1353
1587
|
const { isDevMode: cpDevMode } = useDevMode(apiUrl);
|
|
1354
1588
|
const checkpointCtx = useMemo(() => ({ apiUrl, devMode: cpDevMode, threadId }), [apiUrl, cpDevMode, threadId]);
|
|
1355
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;
|
|
1356
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
|
|
1357
1620
|
? "Session expired"
|
|
1358
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 () => {
|
|
@@ -1374,16 +1637,31 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1374
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: {
|
|
1375
1638
|
UserMessage,
|
|
1376
1639
|
AssistantMessage,
|
|
1377
|
-
} }),
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
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) &&
|
|
1381
1658
|
reconnectContent.length > 0 && (_jsx(ReconnectStreamMessage, { content: reconnectContent })), showRunningInUI && (_jsx(ThinkingIndicator, { label: isReconnecting ? "Reconnecting" : "Thinking" })), queuedMessages.map((msg) => {
|
|
1382
1659
|
const displayText = msg.text
|
|
1383
1660
|
.replace(/<context>[\s\S]*?<\/context>\n?/g, "")
|
|
1384
1661
|
.trim();
|
|
1385
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));
|
|
1386
|
-
})] })) }), 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
|
|
1387
1665
|
? "Connect an AI engine above to start chatting…"
|
|
1388
1666
|
: isRunning
|
|
1389
1667
|
? queuedMessages.length > 0
|
|
@@ -1396,10 +1674,12 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1396
1674
|
// immediately. This unblocks submission even if the
|
|
1397
1675
|
// runtime or reconnect state is stuck.
|
|
1398
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
|
+
}
|
|
1399
1682
|
if (isReconnecting) {
|
|
1400
|
-
if (reconnectRunIdRef.current) {
|
|
1401
|
-
fetch(`${apiUrl}/runs/${encodeURIComponent(reconnectRunIdRef.current)}/abort`, { method: "POST" });
|
|
1402
|
-
}
|
|
1403
1683
|
reconnectAbortRef.current?.abort();
|
|
1404
1684
|
reconnectAbortRef.current = null;
|
|
1405
1685
|
reconnectRunIdRef.current = null;
|
|
@@ -1420,7 +1700,16 @@ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentN
|
|
|
1420
1700
|
modelRef.current = props.selectedModel;
|
|
1421
1701
|
const engineRef = useRef(props.selectedEngine);
|
|
1422
1702
|
engineRef.current = props.selectedEngine;
|
|
1423
|
-
const
|
|
1703
|
+
const execModeRef = useRef(props.execMode);
|
|
1704
|
+
execModeRef.current = props.execMode;
|
|
1705
|
+
const adapter = useMemo(() => createAgentChatAdapter({
|
|
1706
|
+
apiUrl,
|
|
1707
|
+
tabId,
|
|
1708
|
+
threadId,
|
|
1709
|
+
modelRef,
|
|
1710
|
+
engineRef,
|
|
1711
|
+
execModeRef,
|
|
1712
|
+
}), [apiUrl, tabId, threadId]);
|
|
1424
1713
|
const attachmentAdapter = useMemo(() => new CompositeAttachmentAdapter([
|
|
1425
1714
|
new SimpleImageAttachmentAdapter(),
|
|
1426
1715
|
new SimpleTextAttachmentAdapter(),
|