@agent-native/core 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action.d.ts +8 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +18 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +9 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +148 -36
- 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 +20 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +14 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +63 -6
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +2 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/create.js +1 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/setup-agents.d.ts.map +1 -1
- package/dist/cli/setup-agents.js +0 -2
- package/dist/cli/setup-agents.js.map +1 -1
- package/dist/cli/templates-meta.d.ts +52 -0
- package/dist/cli/templates-meta.d.ts.map +1 -0
- package/dist/cli/templates-meta.js +165 -0
- package/dist/cli/templates-meta.js.map +1 -0
- package/dist/client/AgentPanel.d.ts +5 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +279 -30
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +172 -40
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts +21 -0
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -0
- package/dist/client/ConnectBuilderCard.js +196 -0
- package/dist/client/ConnectBuilderCard.js.map +1 -0
- package/dist/client/FeedbackButton.d.ts +15 -0
- package/dist/client/FeedbackButton.d.ts.map +1 -0
- package/dist/client/FeedbackButton.js +72 -0
- package/dist/client/FeedbackButton.js.map +1 -0
- package/dist/client/IframeEmbed.d.ts +17 -0
- package/dist/client/IframeEmbed.d.ts.map +1 -0
- package/dist/client/IframeEmbed.js +108 -0
- package/dist/client/IframeEmbed.js.map +1 -0
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +34 -7
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +34 -15
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +7 -0
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +27 -24
- package/dist/client/composer/MentionPopover.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +21 -4
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/embed.d.ts +28 -0
- package/dist/client/embed.d.ts.map +1 -0
- package/dist/client/embed.js +50 -0
- package/dist/client/embed.js.map +1 -0
- package/dist/client/index.d.ts +4 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +4 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +2 -2
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/onboarding/OnboardingBanner.js +2 -2
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +139 -52
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -1
- package/dist/client/onboarding/SetupButton.js +13 -3
- package/dist/client/onboarding/SetupButton.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +12 -7
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +57 -2
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +5 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +17 -10
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +12 -10
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +6 -3
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/ComingSoonSection.js +1 -1
- package/dist/client/settings/ComingSoonSection.js.map +1 -1
- package/dist/client/settings/LLMSection.d.ts.map +1 -1
- package/dist/client/settings/LLMSection.js +1 -1
- package/dist/client/settings/LLMSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +16 -23
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsSection.js +2 -2
- package/dist/client/settings/SettingsSection.js.map +1 -1
- package/dist/client/settings/UsageSection.d.ts +2 -0
- package/dist/client/settings/UsageSection.d.ts.map +1 -0
- package/dist/client/settings/UsageSection.js +70 -0
- package/dist/client/settings/UsageSection.js.map +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +67 -4
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +25 -2
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +62 -1
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +16 -1
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/db/client.d.ts +12 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +89 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts +11 -0
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +47 -3
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +62 -5
- package/dist/db/migrations.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +7 -2
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/oauth-tokens/google-refresh.d.ts +31 -0
- package/dist/oauth-tokens/google-refresh.d.ts.map +1 -0
- package/dist/oauth-tokens/google-refresh.js +115 -0
- package/dist/oauth-tokens/google-refresh.js.map +1 -0
- package/dist/oauth-tokens/index.d.ts +1 -0
- package/dist/oauth-tokens/index.d.ts.map +1 -1
- package/dist/oauth-tokens/index.js +1 -0
- package/dist/oauth-tokens/index.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +57 -18
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/org/context.js +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +35 -10
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +37 -22
- package/dist/org/plugin.js.map +1 -1
- package/dist/resources/handlers.js +1 -1
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/metadata.d.ts.map +1 -1
- package/dist/resources/metadata.js +2 -2
- package/dist/resources/metadata.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +27 -1
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/db/patch.d.ts.map +1 -1
- package/dist/scripts/db/patch.js +273 -11
- package/dist/scripts/db/patch.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +2 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +26 -0
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +12 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +495 -48
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.js +2 -2
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +21 -58
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth.d.ts +6 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +284 -41
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +70 -4
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +21 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +67 -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 +122 -4
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/desktop-sso.d.ts +30 -0
- package/dist/server/desktop-sso.d.ts.map +1 -0
- package/dist/server/desktop-sso.js +74 -0
- package/dist/server/desktop-sso.js.map +1 -0
- package/dist/server/email.d.ts +23 -0
- package/dist/server/email.d.ts.map +1 -0
- package/dist/server/email.js +105 -0
- package/dist/server/email.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +29 -0
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +19 -3
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/local-migration.d.ts +9 -0
- package/dist/server/local-migration.d.ts.map +1 -1
- package/dist/server/local-migration.js +44 -14
- package/dist/server/local-migration.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +2 -0
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +2 -0
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +6 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +229 -25
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +48 -0
- package/dist/server/poll.js.map +1 -1
- package/dist/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -0
- package/dist/usage/store.d.ts +74 -12
- package/dist/usage/store.d.ts.map +1 -1
- package/dist/usage/store.js +210 -44
- package/dist/usage/store.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +55 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/deployment.md +59 -2
- package/docs/content/resources.md +9 -9
- package/docs/content/workspace-management.md +2 -2
- package/package.json +3 -3
- package/src/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -0
- /package/dist/templates/workspace-core/{skills → .agents/skills}/company-policies/SKILL.md +0 -0
- /package/src/templates/workspace-core/{skills → .agents/skills}/company-policies/SKILL.md +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export declare function BuilderCtaCard({ reason, usageCents, limitCents, }: {
|
|
2
|
+
export declare function BuilderCtaCard({ reason, usageCents, limitCents, apiUrl, }: {
|
|
3
3
|
reason: "usage_limit" | "code_changes" | "cli_tab";
|
|
4
4
|
usageCents?: number;
|
|
5
5
|
limitCents?: number;
|
|
6
|
+
apiUrl?: string;
|
|
6
7
|
}): import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export interface AssistantChatHandle {
|
|
8
9
|
/** Programmatically send a message into this chat */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAy5Bf,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,UAAU,EACV,UAAU,EACV,MAAoC,GACrC,EAAE;IACD,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG,SAAS,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,2CAyJA;AAID,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;CACrD;AAED,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,QAI9C;AAoBD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAo5B7B,eAAO,MAAM,aAAa,gGAoCxB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useRef, useEffect, useCallback, useMemo, forwardRef, useImperativeHandle, } from "react";
|
|
2
|
+
import React, { useState, useRef, useEffect, useCallback, useMemo, forwardRef, useImperativeHandle, } from "react";
|
|
3
3
|
import { AssistantRuntimeProvider, useLocalRuntime, useThreadRuntime, useThread, useAui, useComposer, useMessageRuntime, ThreadPrimitive, ComposerPrimitive, MessagePrimitive, } from "@assistant-ui/react";
|
|
4
4
|
import { SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, CompositeAttachmentAdapter, } from "@assistant-ui/react";
|
|
5
5
|
import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";
|
|
@@ -9,8 +9,10 @@ import { createAgentChatAdapter } from "./agent-chat-adapter.js";
|
|
|
9
9
|
import { readSSEStreamRaw } from "./sse-event-processor.js";
|
|
10
10
|
import { cn } from "./utils.js";
|
|
11
11
|
import { AgentTaskCard } from "./AgentTaskCard.js";
|
|
12
|
+
import { ConnectBuilderCard } from "./ConnectBuilderCard.js";
|
|
13
|
+
import { IframeEmbed, parseEmbedBody } from "./IframeEmbed.js";
|
|
12
14
|
import { TiptapComposer, } from "./composer/TiptapComposer.js";
|
|
13
|
-
import {
|
|
15
|
+
import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, } from "@tabler/icons-react";
|
|
14
16
|
// ─── Markdown Text ──────────────────────────────────────────────────────────
|
|
15
17
|
const markdownStyles = `
|
|
16
18
|
.agent-markdown > :first-child { margin-top: 0; }
|
|
@@ -43,11 +45,37 @@ function injectMarkdownStyles() {
|
|
|
43
45
|
style.textContent = markdownStyles;
|
|
44
46
|
document.head.appendChild(style);
|
|
45
47
|
}
|
|
48
|
+
function extractCodeText(child) {
|
|
49
|
+
if (typeof child === "string")
|
|
50
|
+
return child;
|
|
51
|
+
if (Array.isArray(child))
|
|
52
|
+
return child.map(extractCodeText).join("");
|
|
53
|
+
if (React.isValidElement(child)) {
|
|
54
|
+
const props = child.props;
|
|
55
|
+
return extractCodeText(props.children);
|
|
56
|
+
}
|
|
57
|
+
return "";
|
|
58
|
+
}
|
|
59
|
+
const markdownComponents = {
|
|
60
|
+
pre(props) {
|
|
61
|
+
const { children, ...rest } = props;
|
|
62
|
+
if (React.isValidElement(children)) {
|
|
63
|
+
const childProps = children.props;
|
|
64
|
+
const className = childProps.className || "";
|
|
65
|
+
if (/\blanguage-embed\b/.test(className)) {
|
|
66
|
+
const body = extractCodeText(childProps.children);
|
|
67
|
+
const parsed = parseEmbedBody(body);
|
|
68
|
+
return (_jsx(IframeEmbed, { ...parsed }));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return _jsx("pre", { ...rest, children: children });
|
|
72
|
+
},
|
|
73
|
+
};
|
|
46
74
|
function MarkdownText() {
|
|
47
75
|
useEffect(() => {
|
|
48
76
|
injectMarkdownStyles();
|
|
49
77
|
}, []);
|
|
50
|
-
return (_jsx(MarkdownTextPrimitive, { smooth: true, className: "agent-markdown break-words", remarkPlugins: [remarkGfm] }));
|
|
78
|
+
return (_jsx(MarkdownTextPrimitive, { smooth: true, className: "agent-markdown break-words", remarkPlugins: [remarkGfm], components: markdownComponents }));
|
|
51
79
|
}
|
|
52
80
|
// ─── Composer Attachment Preview ─────────────────────────────────────────────
|
|
53
81
|
function getImageAttachmentSrc(attachment) {
|
|
@@ -106,6 +134,18 @@ function ToolCallDisplay({ toolName, argsText, args, result, isRunning, }) {
|
|
|
106
134
|
streamRef.current.scrollTop = streamRef.current.scrollHeight;
|
|
107
135
|
}
|
|
108
136
|
}, [agentStreamText, isAgentCall, isRunning]);
|
|
137
|
+
// Render connect-builder as ConnectBuilderCard once the result is available
|
|
138
|
+
if (toolName === "connect-builder" && result) {
|
|
139
|
+
try {
|
|
140
|
+
const parsed = JSON.parse(result);
|
|
141
|
+
if (parsed?.kind === "connect-builder-card") {
|
|
142
|
+
return (_jsx(ConnectBuilderCard, { configured: !!parsed.configured, builderEnabled: !!parsed.builderEnabled, connectUrl: parsed.connectUrl || "", orgName: parsed.orgName ?? null, prompt: typeof parsed.prompt === "string" ? parsed.prompt : "" }));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// fall through to default pill rendering
|
|
147
|
+
}
|
|
148
|
+
}
|
|
109
149
|
// Render spawn-task as AgentTaskCard once the result is available
|
|
110
150
|
if (toolName === "spawn-task" && result) {
|
|
111
151
|
try {
|
|
@@ -146,7 +186,7 @@ function ToolCallDisplay({ toolName, argsText, args, result, isRunning, }) {
|
|
|
146
186
|
const isExpanded = isAgentCall ? hasStreamText && expanded : expanded;
|
|
147
187
|
return (_jsxs("div", { className: "my-1 overflow-hidden", children: [_jsxs("button", { onClick: () => canExpand && setExpanded(!isExpanded), className: cn("flex items-center gap-2 rounded-md px-2.5 py-1.5 text-xs font-mono w-full text-left overflow-hidden", isRunning
|
|
148
188
|
? "bg-muted text-muted-foreground"
|
|
149
|
-
: "bg-muted text-muted-foreground hover:bg-accent"), children: [_jsx("span", { className: "shrink-0", children: isRunning ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "h-3 w-3 text-destructive" })) : result !== undefined ? (_jsx(IconCheck, { className: "h-3 w-3 text-emerald-500" })) : (_jsx(IconSquareFilled, { className: "h-3 w-3 text-muted-foreground" })) }), _jsxs("span", { className: "truncate min-w-0", children: [_jsx("span", { className: "font-medium", children: displayName }), argsStr && _jsxs("span", { className: "opacity-60 ml-1", children: ["(", argsStr, ")"] })] }), canExpand && !isRunning && (_jsx(IconChevronDown, { className: cn("ml-auto h-3 w-3 shrink-0 opacity-40", isExpanded && "rotate-180") }))] }), isExpanded && isAgentCall && hasStreamText && (_jsx("div", { ref: streamRef, className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground break-words max-h-48 overflow-y-auto agent-markdown prose prose-sm prose-invert max-w-none", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: agentStreamText }) })), isExpanded && !isAgentCall && result !== undefined && (_jsx("div", { className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs font-mono text-muted-foreground whitespace-pre-wrap break-all max-h-48 overflow-y-auto", children: typeof result === "string"
|
|
189
|
+
: "bg-muted text-muted-foreground hover:bg-accent"), children: [_jsx("span", { className: "shrink-0", children: isRunning ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "h-3 w-3 text-destructive" })) : result !== undefined ? (_jsx(IconCheck, { className: "h-3 w-3 text-emerald-500" })) : (_jsx(IconSquareFilled, { className: "h-3 w-3 text-muted-foreground" })) }), _jsxs("span", { className: "truncate min-w-0", children: [_jsx("span", { className: "font-medium", children: displayName }), argsStr && _jsxs("span", { className: "opacity-60 ml-1", children: ["(", argsStr, ")"] })] }), canExpand && !isRunning && (_jsx(IconChevronDown, { className: cn("ml-auto h-3 w-3 shrink-0 opacity-40", isExpanded && "rotate-180") }))] }), isExpanded && isAgentCall && hasStreamText && (_jsx("div", { ref: streamRef, className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground break-words max-h-48 overflow-y-auto agent-markdown prose prose-sm prose-invert max-w-none", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: agentStreamText }) })), isExpanded && !isAgentCall && result !== undefined && (_jsx("div", { className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs font-mono text-muted-foreground whitespace-pre-wrap break-all max-h-48 overflow-y-auto", children: typeof result === "string"
|
|
150
190
|
? result
|
|
151
191
|
: JSON.stringify(result, null, 2) }))] }));
|
|
152
192
|
}
|
|
@@ -169,7 +209,7 @@ function ReconnectStreamMessage({ content }) {
|
|
|
169
209
|
}, [content]);
|
|
170
210
|
return (_jsx("div", { className: "flex justify-start", children: _jsxs("div", { className: "max-w-[95%] text-sm leading-relaxed text-foreground space-y-1", children: [content.map((part, i) => {
|
|
171
211
|
if (part.type === "text") {
|
|
172
|
-
return (_jsx("div", { className: "agent-markdown break-words", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: part.text }) }, `reconnect-text-${i}`));
|
|
212
|
+
return (_jsx("div", { className: "agent-markdown break-words", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: part.text }) }, `reconnect-text-${i}`));
|
|
173
213
|
}
|
|
174
214
|
if (part.type === "tool-call") {
|
|
175
215
|
return (_jsx(ToolCallDisplay, { toolName: part.toolName, argsText: part.argsText, args: part.args, result: part.result, isRunning: part.result === undefined }, `reconnect-tool-${i}`));
|
|
@@ -254,13 +294,22 @@ function UserMessageText({ text }) {
|
|
|
254
294
|
function UserMessageAttachments() {
|
|
255
295
|
const messageRuntime = useMessageRuntime();
|
|
256
296
|
const msg = messageRuntime.getState();
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
297
|
+
// assistant-ui stores user attachments on msg.attachments (separate from content).
|
|
298
|
+
// Each attachment has: { id, type, name, contentType?, content: MessagePart[] }.
|
|
299
|
+
// Image adapters put a {type:"image", image:"data:..."} part in content; text
|
|
300
|
+
// adapters put a {type:"text", text:"<attachment>..."} part. Fall back to a
|
|
301
|
+
// file chip when there's no inline image.
|
|
302
|
+
const attachments = msg
|
|
303
|
+
.attachments;
|
|
304
|
+
if (!attachments || attachments.length === 0)
|
|
262
305
|
return null;
|
|
263
|
-
return (
|
|
306
|
+
return (_jsx("div", { className: "flex flex-wrap justify-end gap-1.5 mb-1.5", children: attachments.map((att) => {
|
|
307
|
+
const imagePart = att.content?.find((p) => p.type === "image" && "image" in p && !!p.image);
|
|
308
|
+
if (imagePart) {
|
|
309
|
+
return (_jsx("div", { className: "h-16 w-16 overflow-hidden rounded-lg border border-border/70 bg-muted/50", title: att.name, children: _jsx("img", { src: imagePart.image, alt: att.name, className: "h-full w-full object-cover" }) }, att.id));
|
|
310
|
+
}
|
|
311
|
+
return (_jsxs("div", { className: "flex items-center gap-1.5 rounded-lg border border-border/70 bg-muted/50 px-2 py-1.5 text-xs text-muted-foreground", title: att.name, children: [_jsx(IconFile, { className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "truncate max-w-[120px]", children: att.name || "file" })] }, att.id));
|
|
312
|
+
}) }));
|
|
264
313
|
}
|
|
265
314
|
function UserMessage() {
|
|
266
315
|
const [expanded, setExpanded] = useState(false);
|
|
@@ -367,7 +416,7 @@ function ApiKeySetupCard({ apiUrl }) {
|
|
|
367
416
|
if (saved) {
|
|
368
417
|
return (_jsx("div", { className: "mx-4 my-6 rounded-lg border border-emerald-500/30 bg-emerald-500/5 p-4", children: _jsxs("div", { className: "flex items-center gap-2 text-sm text-emerald-400", children: [_jsx(IconCheck, { className: "h-4 w-4" }), "API key saved. Reloading..."] }) }));
|
|
369
418
|
}
|
|
370
|
-
return (_jsxs("div", { className: "mx-4 my-6 rounded-lg border border-border bg-card p-5", children: [_jsxs("div", { className: "flex items-center gap-3 mb-3", children: [_jsx("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted", children: _jsx(
|
|
419
|
+
return (_jsxs("div", { className: "mx-4 my-6 rounded-lg border border-border bg-card p-5", children: [_jsxs("div", { className: "flex items-center gap-3 mb-3", children: [_jsx("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted", children: _jsx(IconMessage, { className: "h-4.5 w-4.5 text-muted-foreground" }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-foreground", children: "Connect your AI" }), _jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Connect Builder or add an Anthropic API key to enable the agent" })] })] }), _jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "rounded-md border border-border px-3 py-2.5", children: _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: "Connect Builder" }), _jsx("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: "Use Builder's managed Anthropic proxy \u2014 no API key needed" })] }), _jsx("span", { className: "shrink-0 rounded border border-border px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: "Coming soon" })] }) }), _jsxs("div", { className: "relative flex items-center", children: [_jsx("div", { className: "flex-grow border-t border-border" }), _jsx("span", { className: "mx-2 text-[10px] uppercase tracking-wider text-muted-foreground/60", children: "or" }), _jsx("div", { className: "flex-grow border-t border-border" })] }), _jsxs("div", { className: "rounded-md bg-muted/50 px-3 py-2.5 text-xs text-muted-foreground leading-relaxed", children: [_jsxs("p", { children: ["1. Go to", " ", _jsx("a", { href: "https://console.anthropic.com/settings/keys", target: "_blank", rel: "noopener noreferrer", className: "underline text-foreground/80 hover:text-foreground", children: "console.anthropic.com/settings/keys" })] }), _jsx("p", { className: "mt-1", children: "2. Create a new API key and paste it below" })] }), _jsx("input", { type: "password", value: apiKey, onChange: (e) => {
|
|
371
420
|
setApiKey(e.target.value);
|
|
372
421
|
setError(null);
|
|
373
422
|
}, onKeyDown: (e) => {
|
|
@@ -376,22 +425,60 @@ function ApiKeySetupCard({ apiUrl }) {
|
|
|
376
425
|
}, 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 }), _jsx("button", { onClick: handleSave, disabled: saving || !apiKey.trim(), 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" })] })] }));
|
|
377
426
|
}
|
|
378
427
|
// ─── Builder.io CTA Card (usage limit / code changes / CLI) ─────────────────
|
|
379
|
-
export function BuilderCtaCard({ reason, usageCents, limitCents, }) {
|
|
428
|
+
export function BuilderCtaCard({ reason, usageCents, limitCents, apiUrl = "/_agent-native/agent-chat", }) {
|
|
380
429
|
const appName = typeof window !== "undefined"
|
|
381
430
|
? window.location.hostname.split(".")[0]
|
|
382
431
|
: "app";
|
|
383
432
|
const cloneCommand = `npx agent-native create ${appName}`;
|
|
433
|
+
const [apiKey, setApiKey] = useState("");
|
|
434
|
+
const [saving, setSaving] = useState(false);
|
|
435
|
+
const [saved, setSaved] = useState(false);
|
|
436
|
+
const [error, setError] = useState(null);
|
|
437
|
+
const handleSave = async () => {
|
|
438
|
+
if (!apiKey.trim())
|
|
439
|
+
return;
|
|
440
|
+
setSaving(true);
|
|
441
|
+
setError(null);
|
|
442
|
+
try {
|
|
443
|
+
const res = await fetch(`${apiUrl}/save-key`, {
|
|
444
|
+
method: "POST",
|
|
445
|
+
headers: { "Content-Type": "application/json" },
|
|
446
|
+
body: JSON.stringify({ key: apiKey.trim() }),
|
|
447
|
+
});
|
|
448
|
+
if (!res.ok) {
|
|
449
|
+
const data = await res.json().catch(() => ({}));
|
|
450
|
+
throw new Error(data.error || "Failed to save");
|
|
451
|
+
}
|
|
452
|
+
setSaved(true);
|
|
453
|
+
setTimeout(() => window.location.reload(), 1000);
|
|
454
|
+
}
|
|
455
|
+
catch (err) {
|
|
456
|
+
setError(err instanceof Error ? err.message : "Failed to save");
|
|
457
|
+
}
|
|
458
|
+
finally {
|
|
459
|
+
setSaving(false);
|
|
460
|
+
}
|
|
461
|
+
};
|
|
384
462
|
const title = reason === "usage_limit"
|
|
385
463
|
? "Free usage limit reached"
|
|
386
464
|
: reason === "code_changes"
|
|
387
465
|
? "Code changes require a local setup"
|
|
388
466
|
: "Get full access";
|
|
389
467
|
const description = reason === "usage_limit"
|
|
390
|
-
?
|
|
468
|
+
? null
|
|
391
469
|
: reason === "code_changes"
|
|
392
|
-
? "This app is running in hosted mode. To make code changes,
|
|
393
|
-
: "This hosted app has limited AI features.
|
|
394
|
-
|
|
470
|
+
? "This app is running in hosted mode. To make code changes, add your own Anthropic API key or clone and run locally."
|
|
471
|
+
: "This hosted app has limited AI features. Add your own Anthropic API key for the full experience, or clone and run locally.";
|
|
472
|
+
if (saved) {
|
|
473
|
+
return (_jsx("div", { className: "mx-4 my-6 rounded-lg border border-emerald-500/30 bg-emerald-500/5 p-4", children: _jsxs("div", { className: "flex items-center gap-2 text-sm text-emerald-400", children: [_jsx(IconCheck, { className: "h-4 w-4" }), "API key saved. Reloading..."] }) }));
|
|
474
|
+
}
|
|
475
|
+
return (_jsxs("div", { className: "mx-4 my-6 rounded-lg border border-border bg-card p-5", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4", children: [_jsx("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted", children: _jsx(IconMessage, { className: "h-4.5 w-4.5 text-muted-foreground" }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-foreground", children: title }), description && (_jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: description }))] })] }), _jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "rounded-md bg-muted/50 px-3 py-2.5 text-xs text-muted-foreground leading-relaxed", children: _jsxs("p", { children: ["Paste an Anthropic API key (", _jsx("a", { href: "https://console.anthropic.com/settings/keys", target: "_blank", rel: "noopener noreferrer", className: "underline text-foreground/80 hover:text-foreground", children: "console.anthropic.com/settings/keys" }), ") to skip the free-tier limit."] }) }), _jsx("input", { type: "password", value: apiKey, onChange: (e) => {
|
|
476
|
+
setApiKey(e.target.value);
|
|
477
|
+
setError(null);
|
|
478
|
+
}, onKeyDown: (e) => {
|
|
479
|
+
if (e.key === "Enter")
|
|
480
|
+
handleSave();
|
|
481
|
+
}, 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 }), _jsx("button", { onClick: handleSave, disabled: saving || !apiKey.trim(), 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" }), _jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute inset-0 flex items-center", children: _jsx("span", { className: "w-full border-t border-border" }) }), _jsx("div", { className: "relative flex justify-center text-xs", children: _jsx("span", { className: "bg-card px-2 text-muted-foreground", children: "or" }) })] }), _jsxs("div", { className: "rounded-md bg-muted/50 px-3 py-2.5", children: [_jsx("p", { className: "text-xs text-muted-foreground mb-1.5", children: "Clone and run locally:" }), _jsx("code", { className: "block text-xs text-foreground/80 font-mono break-all select-all", children: cloneCommand })] }), _jsx("div", { className: "rounded-md border border-border px-3 py-2.5", children: _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: "Connect Builder.io" }), _jsx("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: "Builder's managed Anthropic proxy \u2014 no API key needed" })] }), _jsx("span", { className: "shrink-0 rounded border border-border px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: "Coming soon" })] }) })] })] }));
|
|
395
482
|
}
|
|
396
483
|
export const CHAT_STORAGE_PREFIX = "agent-chat:";
|
|
397
484
|
/** Remove persisted chat for a given tabId (or "default"). */
|
|
@@ -438,18 +525,17 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
438
525
|
const [reconnectFrozen, setReconnectFrozen] = useState(false);
|
|
439
526
|
const reconnectRunIdRef = useRef(null);
|
|
440
527
|
const reconnectAbortRef = useRef(null);
|
|
441
|
-
// Nuclear stop: user clicked stop
|
|
442
|
-
//
|
|
443
|
-
//
|
|
444
|
-
//
|
|
528
|
+
// Nuclear stop: user clicked stop. Clears the stop button/indicator AND
|
|
529
|
+
// lets new submissions go through immediately — prevents the "stuck
|
|
530
|
+
// queueing forever" state where isReconnecting or isRuntimeRunning gets
|
|
531
|
+
// wedged (e.g. after a tab refresh + stop during reconnect).
|
|
445
532
|
const [forceStopped, setForceStopped] = useState(false);
|
|
446
533
|
// Real running state — drives submission/queue gating. Treat reconnecting
|
|
447
|
-
// to an active run the same as running
|
|
448
|
-
|
|
534
|
+
// to an active run the same as running, UNLESS the user has explicitly
|
|
535
|
+
// clicked stop (forceStopped).
|
|
536
|
+
const isRunning = !forceStopped && (isRuntimeRunning || isReconnecting);
|
|
449
537
|
// UI-only running state — drives the stop button and thinking indicator.
|
|
450
|
-
|
|
451
|
-
// underlying runtime or reconnect state hasn't caught up yet.
|
|
452
|
-
const showRunningInUI = !forceStopped && isRunning;
|
|
538
|
+
const showRunningInUI = isRunning;
|
|
453
539
|
const wasRunningRef = useRef(false);
|
|
454
540
|
const tiptapRef = useRef(null);
|
|
455
541
|
// ─── Chat persistence ──────────────────────────────────────────────
|
|
@@ -524,6 +610,38 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
524
610
|
// can abort it even if clicked before the function body runs.
|
|
525
611
|
const abortCtrl = new AbortController();
|
|
526
612
|
reconnectAbortRef.current = abortCtrl;
|
|
613
|
+
// Watchdog: poll /runs/active to detect when the run is no
|
|
614
|
+
// longer running server-side. If the SSE stream hangs (e.g.
|
|
615
|
+
// because the agent process died but its SQL run row is still
|
|
616
|
+
// marked "running", or the stream just never emits `done`),
|
|
617
|
+
// this aborts the fetch so we fall through to thread refresh
|
|
618
|
+
// instead of showing "Thinking..." forever.
|
|
619
|
+
const watchdog = setInterval(async () => {
|
|
620
|
+
try {
|
|
621
|
+
const res = await fetch(`${apiUrl}/runs/active?threadId=${encodeURIComponent(threadId)}`);
|
|
622
|
+
if (!res.ok) {
|
|
623
|
+
abortCtrl.abort();
|
|
624
|
+
clearInterval(watchdog);
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
const info = await res.json();
|
|
628
|
+
if (info.status !== "running") {
|
|
629
|
+
abortCtrl.abort();
|
|
630
|
+
clearInterval(watchdog);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
catch {
|
|
634
|
+
// Network blip — keep polling
|
|
635
|
+
}
|
|
636
|
+
}, 3000);
|
|
637
|
+
// Hard cap: no single reconnect should wedge the UI for
|
|
638
|
+
// more than 2 minutes. Even if the watchdog is fooled and
|
|
639
|
+
// the SSE stream never closes, this guarantees "Thinking..."
|
|
640
|
+
// eventually clears.
|
|
641
|
+
const maxReconnectTimer = setTimeout(() => {
|
|
642
|
+
abortCtrl.abort();
|
|
643
|
+
clearInterval(watchdog);
|
|
644
|
+
}, 2 * 60 * 1000);
|
|
527
645
|
const streamReconnect = async () => {
|
|
528
646
|
try {
|
|
529
647
|
const sseRes = await fetch(`${apiUrl}/runs/${encodeURIComponent(runInfo.runId)}/events?after=0`, { signal: abortCtrl.signal });
|
|
@@ -551,6 +669,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
551
669
|
catch {
|
|
552
670
|
// Stream error or abort — fall through to re-fetch
|
|
553
671
|
}
|
|
672
|
+
finally {
|
|
673
|
+
clearInterval(watchdog);
|
|
674
|
+
clearTimeout(maxReconnectTimer);
|
|
675
|
+
}
|
|
554
676
|
// Poll for thread data — server's updateThreadData may not have
|
|
555
677
|
// committed yet when the SSE `done` event fires, so retry until
|
|
556
678
|
// an assistant message appears (up to ~5 s) before clearing.
|
|
@@ -811,7 +933,17 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
811
933
|
const addToQueue = useCallback((text, images, references) => {
|
|
812
934
|
setShowContinue(false);
|
|
813
935
|
if (isRunning) {
|
|
814
|
-
setQueuedMessages((prev) => [
|
|
936
|
+
setQueuedMessages((prev) => [
|
|
937
|
+
...prev,
|
|
938
|
+
{
|
|
939
|
+
id: typeof crypto !== "undefined" && crypto.randomUUID
|
|
940
|
+
? crypto.randomUUID()
|
|
941
|
+
: `q-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
942
|
+
text,
|
|
943
|
+
images,
|
|
944
|
+
references,
|
|
945
|
+
},
|
|
946
|
+
]);
|
|
815
947
|
}
|
|
816
948
|
else {
|
|
817
949
|
const content = [{ type: "text", text }];
|
|
@@ -908,44 +1040,44 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
908
1040
|
}, className: "text-xs text-destructive hover:text-destructive/80 px-3 py-1.5 rounded-md border border-destructive/30 hover:bg-destructive/10", children: "Log out" })), _jsx("button", { onClick: () => {
|
|
909
1041
|
setAuthError(null);
|
|
910
1042
|
window.location.reload();
|
|
911
|
-
}, className: "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Retry" })] })] })) : missingApiKey ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(ApiKeySetupCard, { apiUrl: apiUrl }) })) : usageLimitReached ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(BuilderCtaCard, { reason: "usage_limit", usageCents: usageLimitReached.usageCents, limitCents: usageLimitReached.limitCents }) })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : messages.length === 0 && !isReconnecting ? (_jsxs("div", { className: "flex flex-col items-center justify-center gap-4 py-16 px-4 h-full", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: _jsx(
|
|
1043
|
+
}, className: "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Retry" })] })] })) : missingApiKey ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(ApiKeySetupCard, { apiUrl: apiUrl }) })) : usageLimitReached ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(BuilderCtaCard, { reason: "usage_limit", usageCents: usageLimitReached.usageCents, limitCents: usageLimitReached.limitCents, apiUrl: apiUrl }) })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : messages.length === 0 && !isReconnecting ? (_jsxs("div", { className: "flex flex-col items-center justify-center gap-4 py-16 px-4 h-full", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: _jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" }) }), _jsx("p", { className: "text-sm text-muted-foreground text-center max-w-[240px]", children: emptyStateText ?? "How can I help you?" }), suggestions && suggestions.length > 0 && (_jsx("div", { className: "flex flex-col gap-1.5 w-full max-w-[280px]", children: suggestions.map((suggestion) => (_jsx("button", { onClick: () => {
|
|
912
1044
|
threadRuntime.append({
|
|
913
1045
|
role: "user",
|
|
914
1046
|
content: [{ type: "text", text: suggestion }],
|
|
915
1047
|
});
|
|
916
|
-
}, 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: "flex flex-col gap-4 px-4 py-4", children: [_jsx(ThreadPrimitive.Messages, { components: {
|
|
1048
|
+
}, 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: {
|
|
917
1049
|
UserMessage,
|
|
918
1050
|
AssistantMessage,
|
|
919
1051
|
} }), showContinue && !showRunningInUI && (_jsx("div", { className: "flex justify-center py-2", children: _jsx("button", { type: "button", onClick: () => {
|
|
920
1052
|
setShowContinue(false);
|
|
921
1053
|
addToQueue("Continue from where you left off.");
|
|
922
1054
|
}, className: "rounded-lg border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-accent", children: "Continue" }) })), (isReconnecting || reconnectFrozen) &&
|
|
923
|
-
reconnectContent.length > 0 && (_jsx(ReconnectStreamMessage, { content: reconnectContent })), showRunningInUI && _jsx(ThinkingIndicator, {}), queuedMessages.map((msg
|
|
1055
|
+
reconnectContent.length > 0 && (_jsx(ReconnectStreamMessage, { content: reconnectContent })), showRunningInUI && _jsx(ThinkingIndicator, {}), queuedMessages.map((msg) => {
|
|
1056
|
+
const displayText = msg.text
|
|
1057
|
+
.replace(/<context>[\s\S]*?<\/context>\n?/g, "")
|
|
1058
|
+
.trim();
|
|
1059
|
+
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));
|
|
1060
|
+
})] })) }), 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("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", children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, placeholder: isRunning
|
|
924
1061
|
? queuedMessages.length > 0
|
|
925
1062
|
? `${queuedMessages.length} queued — type another...`
|
|
926
1063
|
: "Queue a message..."
|
|
927
1064
|
: undefined, onSubmit: isRunning
|
|
928
1065
|
? (text, references) => addToQueue(text, undefined, references.length > 0 ? references : undefined)
|
|
929
|
-
: undefined, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange,
|
|
930
|
-
//
|
|
931
|
-
//
|
|
932
|
-
//
|
|
1066
|
+
: undefined, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, extraActionButton: showRunningInUI ? (_jsx("button", { type: "button", onClick: () => {
|
|
1067
|
+
// Nuclear stop: flip forceStopped so isRunning is false
|
|
1068
|
+
// immediately. This unblocks submission even if the
|
|
1069
|
+
// runtime or reconnect state is stuck.
|
|
933
1070
|
setForceStopped(true);
|
|
934
1071
|
if (isReconnecting) {
|
|
935
|
-
// Abort the server-side run (fire-and-forget)
|
|
936
1072
|
if (reconnectRunIdRef.current) {
|
|
937
1073
|
fetch(`${apiUrl}/runs/${encodeURIComponent(reconnectRunIdRef.current)}/abort`, { method: "POST" });
|
|
938
1074
|
}
|
|
939
|
-
// Abort the client-side SSE stream
|
|
940
1075
|
reconnectAbortRef.current?.abort();
|
|
941
1076
|
reconnectAbortRef.current = null;
|
|
942
1077
|
reconnectRunIdRef.current = null;
|
|
943
1078
|
setIsReconnecting(false);
|
|
944
|
-
// Keep reconnectContent visible (frozen) — don't wipe it
|
|
945
1079
|
setReconnectFrozen(reconnectContent.length > 0);
|
|
946
1080
|
}
|
|
947
|
-
// Always try to cancel the runtime run too (handles the
|
|
948
|
-
// normal non-reconnect path and is a no-op if not running)
|
|
949
1081
|
threadRuntime.cancelRun();
|
|
950
1082
|
window.dispatchEvent(new CustomEvent("builder.chatRunning", {
|
|
951
1083
|
detail: {
|
|
@@ -953,7 +1085,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
953
1085
|
tabId: tabId || threadId,
|
|
954
1086
|
},
|
|
955
1087
|
}));
|
|
956
|
-
}, className: "shrink-0 flex h-7 w-7 items-center justify-center rounded-md bg-
|
|
1088
|
+
}, className: "shrink-0 flex h-7 w-7 items-center justify-center rounded-md bg-muted text-foreground hover:bg-muted/80", title: "Stop generating", children: _jsx(IconPlayerStop, { className: "h-3.5 w-3.5" }) })) : undefined })] }) })] }));
|
|
957
1089
|
});
|
|
958
1090
|
export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = "/_agent-native/agent-chat", tabId, threadId, ...props }, ref) {
|
|
959
1091
|
const adapter = useMemo(() => createAgentChatAdapter({ apiUrl, tabId, threadId }), [apiUrl, tabId, threadId]);
|