@mcp-b/react-components 0.6.5 → 0.7.1
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/AgentChat-403mckDG.d.ts +101 -0
- package/dist/BrowserLiveView-ZktFZiMD.d.ts +47 -0
- package/dist/BrowserReplay-6G-mnwcn.d.ts +40 -0
- package/dist/{CodeBlock-BK0sOAbV.js → CodeBlock-D9koxDA7.js} +1 -1
- package/dist/{FileTree-BWQZ0FSi.js → FileTree-BdK93Uuu.js} +1 -1
- package/dist/ModelSelector-MQvK-pNb.js +306 -0
- package/dist/PromptInput-D6-G24p7.d.ts +528 -0
- package/dist/ThinkChatActivity-CeHzk6-K.d.ts +73 -0
- package/dist/ThinkChatContext-CC94HL4u.d.ts +28 -0
- package/dist/ThinkChatToolParts-DnUiZgCC.d.ts +83 -0
- package/dist/components/Activity.js +1 -1
- package/dist/components/AgentChat.d.ts +1 -103
- package/dist/components/AgentChat.js +77 -58
- package/dist/components/AgentConnection.d.ts +43 -2
- package/dist/components/AgentConnection.js +154 -3
- package/dist/components/Artifact.js +1 -1
- package/dist/components/BrowserLiveView.d.ts +1 -46
- package/dist/components/BrowserLiveView.js +1 -1
- package/dist/components/BrowserReplay.d.ts +1 -39
- package/dist/components/BrowserReplay.js +1 -1
- package/dist/components/ChainOfThought.d.ts +1 -1
- package/dist/components/ChainOfThought.js +1 -1
- package/dist/components/ChatGptSignInScreen.d.ts +38 -0
- package/dist/components/ChatGptSignInScreen.js +201 -0
- package/dist/components/CodeBlock.js +1 -1
- package/dist/components/Commit.js +1 -1
- package/dist/components/Context.d.ts +6 -10
- package/dist/components/Context.js +4 -2
- package/dist/components/ContextMenu.js +1 -1
- package/dist/components/Conversation.d.ts +28 -28
- package/dist/components/Conversation.js +36 -55
- package/dist/components/Dialog.js +1 -1
- package/dist/components/EnvironmentVariables.js +1 -1
- package/dist/components/FileTree.js +1 -1
- package/dist/components/Marker.d.ts +57 -0
- package/dist/components/Marker.js +89 -0
- package/dist/components/McpServerPicker.js +1 -1
- package/dist/components/Menubar.js +1 -1
- package/dist/components/Message.js +1 -1
- package/dist/components/MessageScroller.d.ts +52 -0
- package/dist/components/MessageScroller.js +62 -0
- package/dist/components/ModelSelector.js +1 -305
- package/dist/components/NavigationMenu.js +1 -1
- package/dist/components/PromptInput.d.ts +2 -534
- package/dist/components/PromptInput.js +18 -12
- package/dist/components/Queue.js +1 -1
- package/dist/components/Reasoning.js +1 -1
- package/dist/components/Select.js +1 -1
- package/dist/components/Sources.js +1 -1
- package/dist/components/Stepper.js +1 -1
- package/dist/components/Task.js +1 -1
- package/dist/components/Terminal.js +2 -2
- package/dist/components/TestResults.js +1 -1
- package/dist/components/ThinkChat.d.ts +23 -80
- package/dist/components/ThinkChat.js +60 -857
- package/dist/components/ThinkChatActivity.d.ts +3 -0
- package/dist/components/ThinkChatActivity.js +429 -0
- package/dist/components/ThinkChatContext.d.ts +2 -0
- package/dist/components/ThinkChatContext.js +10 -0
- package/dist/components/ThinkChatToolPanels.d.ts +39 -0
- package/dist/components/ThinkChatToolPanels.js +355 -0
- package/dist/components/ThinkChatToolParts.d.ts +2 -0
- package/dist/components/ThinkChatToolParts.js +66 -0
- package/dist/components/ThinkFullApp.d.ts +23 -0
- package/dist/components/ThinkFullApp.js +175 -0
- package/dist/components/WebPreview.js +1 -1
- package/dist/components/WorkspaceExplorer.d.ts +1 -1
- package/dist/components/WorkspaceExplorer.js +3 -3
- package/dist/components/icons.d.ts +2 -2
- package/dist/components/icons.js +2 -2
- package/dist/components/useStickToBottom.d.ts +5 -2
- package/dist/components/useStickToBottom.js +5 -2
- package/dist/{copy-button-CB2MWcau.js → copy-button-TVhDAroI.js} +1 -1
- package/dist/{icons-BCNawx-T.js → icons-BAlTbWWP.js} +27 -1
- package/dist/{icons-BYpJY6L2.d.ts → icons-BRI54ATJ.d.ts} +2 -1
- package/dist/styles/agent-chat.css +15 -3
- package/dist/styles/agent-connection.css +33 -4
- package/dist/styles/chatgpt-sign-in-screen.css +224 -0
- package/dist/styles/code-block.css +6 -4
- package/dist/styles/conversation.css +10 -0
- package/dist/styles/index.css +4 -0
- package/dist/styles/marker.css +95 -0
- package/dist/styles/message-scroller.css +113 -0
- package/dist/styles/message.css +2 -1
- package/dist/styles/prompt-input.css +1 -0
- package/dist/styles/scrollbars.css +10 -2
- package/dist/styles/streamdown.css +2 -0
- package/dist/styles/think-full-app.css +318 -0
- package/dist/utils/mcp-server-catalog.d.ts +23 -1
- package/dist/utils/mcp-server-catalog.js +27 -1
- package/package.json +3 -2
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { InferUITools, ToolUIPart, UIMessage } from "ai";
|
|
2
|
+
import { ProxyToolInput, ProxyToolOutput } from "@cloudflare/codemode";
|
|
3
|
+
import { QuickActionExtractInput, QuickActionPage, QuickActionScrapeInput, QuickActionToolName } from "@cloudflare/think/tools/browser";
|
|
4
|
+
import { FetchResult } from "@cloudflare/think/tools/fetch";
|
|
5
|
+
import { WorkspaceTools } from "@cloudflare/think/tools/workspace";
|
|
6
|
+
|
|
7
|
+
//#region src/components/ThinkChatToolParts.d.ts
|
|
8
|
+
type ThinkChatPart = UIMessage["parts"][number];
|
|
9
|
+
type WorkspaceUITools = InferUITools<Required<WorkspaceTools>>;
|
|
10
|
+
type WorkspaceToolPart = ToolUIPart<WorkspaceUITools>;
|
|
11
|
+
type ThinkWorkspaceToolName = keyof WorkspaceUITools;
|
|
12
|
+
type ThinkBashToolPart = Extract<WorkspaceToolPart, {
|
|
13
|
+
type: "tool-bash";
|
|
14
|
+
}>;
|
|
15
|
+
type ThinkBashToolOutput = WorkspaceUITools["bash"]["output"];
|
|
16
|
+
declare function isWorkspaceToolPart(part: ThinkChatPart): part is WorkspaceToolPart;
|
|
17
|
+
type SkillUITools = {
|
|
18
|
+
activate_skill: {
|
|
19
|
+
input: {
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
output: string;
|
|
23
|
+
};
|
|
24
|
+
read_skill_resource: {
|
|
25
|
+
input: {
|
|
26
|
+
name?: string;
|
|
27
|
+
path: string;
|
|
28
|
+
};
|
|
29
|
+
output: string;
|
|
30
|
+
};
|
|
31
|
+
run_skill_script: {
|
|
32
|
+
input: {
|
|
33
|
+
name: string;
|
|
34
|
+
path: string;
|
|
35
|
+
input?: unknown;
|
|
36
|
+
};
|
|
37
|
+
output: unknown;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
type SkillToolPart = ToolUIPart<SkillUITools>;
|
|
41
|
+
declare function isSkillToolPart(part: ThinkChatPart): part is SkillToolPart;
|
|
42
|
+
type FetchToolPart = ToolUIPart<Record<string, {
|
|
43
|
+
input: {
|
|
44
|
+
url?: string;
|
|
45
|
+
path?: string;
|
|
46
|
+
};
|
|
47
|
+
output: FetchResult;
|
|
48
|
+
}>>;
|
|
49
|
+
declare function isFetchToolPart(part: ThinkChatPart): part is FetchToolPart;
|
|
50
|
+
type QuickActionInputs = {
|
|
51
|
+
markdown: QuickActionPage;
|
|
52
|
+
extract: QuickActionExtractInput;
|
|
53
|
+
links: QuickActionPage;
|
|
54
|
+
scrape: QuickActionScrapeInput;
|
|
55
|
+
content: QuickActionPage;
|
|
56
|
+
};
|
|
57
|
+
type BrowserUITools = {
|
|
58
|
+
browser_execute: {
|
|
59
|
+
input: ProxyToolInput;
|
|
60
|
+
output: ProxyToolOutput;
|
|
61
|
+
};
|
|
62
|
+
} & { [K in QuickActionToolName as `browser_${K}`]: {
|
|
63
|
+
input: QuickActionInputs[K];
|
|
64
|
+
output: unknown;
|
|
65
|
+
} };
|
|
66
|
+
type BrowserToolPart = ToolUIPart<BrowserUITools>;
|
|
67
|
+
declare function isBrowserToolPart(part: ThinkChatPart): part is BrowserToolPart;
|
|
68
|
+
type ExecuteToolPart = ToolUIPart<{
|
|
69
|
+
execute: {
|
|
70
|
+
input: ProxyToolInput;
|
|
71
|
+
output: ProxyToolOutput;
|
|
72
|
+
};
|
|
73
|
+
}>;
|
|
74
|
+
declare function isExecuteToolPart(part: ThinkChatPart): part is ExecuteToolPart;
|
|
75
|
+
/** Agent work (reasoning, tool calls, step boundaries) vs. content shown to the user. */
|
|
76
|
+
declare function isThinkChatActivityPart(part: ThinkChatPart | undefined, excludeTools?: ReadonlySet<string>): boolean;
|
|
77
|
+
/** In-flight: the stream opened this part but hasn't delivered its result yet. */
|
|
78
|
+
declare function isPartWorking(part: ThinkChatPart): boolean;
|
|
79
|
+
/** Errored or denied — upstream's simplified tool-part state vocabulary. */
|
|
80
|
+
declare function isPartFailed(part: ThinkChatPart): boolean;
|
|
81
|
+
declare function displayUrl(url: string | undefined): string;
|
|
82
|
+
//#endregion
|
|
83
|
+
export { isThinkChatActivityPart as _, ThinkBashToolOutput as a, ThinkWorkspaceToolName as c, isBrowserToolPart as d, isExecuteToolPart as f, isSkillToolPart as g, isPartWorking as h, SkillToolPart as i, WorkspaceToolPart as l, isPartFailed as m, ExecuteToolPart as n, ThinkBashToolPart as o, isFetchToolPart as p, FetchToolPart as r, ThinkChatPart as s, BrowserToolPart as t, displayUrl as u, isWorkspaceToolPart as v };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CollapsiblePanel, CollapsibleRoot, CollapsibleTrigger } from "./Collapsible.js";
|
|
2
2
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
3
|
-
import { c as ChevronRightIcon } from "../icons-
|
|
3
|
+
import { c as ChevronRightIcon } from "../icons-BAlTbWWP.js";
|
|
4
4
|
import "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
//#region src/components/Activity.tsx
|
|
@@ -1,104 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { ChatAddToolApproveResponseFunction, UIMessage } from "ai";
|
|
4
|
-
|
|
5
|
-
//#region src/components/AgentChat.d.ts
|
|
6
|
-
type AgentChatPart<MessageT extends UIMessage = UIMessage> = MessageT["parts"][number];
|
|
7
|
-
interface AgentChatRenderPartContext<MessageT extends UIMessage = UIMessage> {
|
|
8
|
-
message: MessageT;
|
|
9
|
-
part: AgentChatPart<MessageT>;
|
|
10
|
-
partIndex: number;
|
|
11
|
-
defaultRender: () => React.ReactNode;
|
|
12
|
-
}
|
|
13
|
-
interface AgentChatRenderMessageContext<MessageT extends UIMessage = UIMessage> {
|
|
14
|
-
message: MessageT;
|
|
15
|
-
messageIndex: number;
|
|
16
|
-
}
|
|
17
|
-
interface AgentChatProps<MessageT extends UIMessage = UIMessage> {
|
|
18
|
-
className?: string;
|
|
19
|
-
/** AI SDK `UIMessage`s to render, oldest first. */
|
|
20
|
-
messages: readonly MessageT[];
|
|
21
|
-
/** Drives the composer's send/stop affordance and streaming indicators. */
|
|
22
|
-
status?: PromptInputStatus;
|
|
23
|
-
/** Called with the composed message when the user submits. Omit for a read-only transcript. */
|
|
24
|
-
onSubmit?: (message: PromptInputMessage) => void | Promise<void>;
|
|
25
|
-
/** Called when the user hits stop while `status` is streaming/submitted. */
|
|
26
|
-
onStop?: () => void;
|
|
27
|
-
placeholder?: string;
|
|
28
|
-
disabled?: boolean;
|
|
29
|
-
/** Rendered in place of the transcript while `messages` is empty. */
|
|
30
|
-
emptyState?: React.ReactNode;
|
|
31
|
-
/** Extra controls rendered in the composer toolbar. */
|
|
32
|
-
composerTools?: React.ReactNode;
|
|
33
|
-
/** Extra rows rendered in the built-in plus menu after files. */
|
|
34
|
-
composerAddMenuItems?: React.ReactNode;
|
|
35
|
-
/**
|
|
36
|
-
* Transient status rendered between the transcript and the composer —
|
|
37
|
-
* e.g. a "Reconnecting…" pill. `ThinkChat.Messages` fills this from the
|
|
38
|
-
* hook's `isRecovering`/`connectionError` automatically.
|
|
39
|
-
*/
|
|
40
|
-
notice?: React.ReactNode;
|
|
41
|
-
/**
|
|
42
|
-
* When set, the last assistant message gets a Retry action that calls this
|
|
43
|
-
* with its message id — pass to the AI SDK's `regenerate({ messageId })`.
|
|
44
|
-
*/
|
|
45
|
-
onRegenerate?: (messageId: string) => void;
|
|
46
|
-
/**
|
|
47
|
-
* Pass `addToolApprovalResponse` from `useAgentChat`/`useChat` directly.
|
|
48
|
-
* When set and a tool call awaits approval, the composer becomes the
|
|
49
|
-
* confirmation.
|
|
50
|
-
*/
|
|
51
|
-
onApprovalResponse?: ChatAddToolApproveResponseFunction;
|
|
52
|
-
/**
|
|
53
|
-
* When set, paused codemode executions surface in the same composer
|
|
54
|
-
* confirmation as tool approvals. See {@link ExecutionApprovals}.
|
|
55
|
-
*/
|
|
56
|
-
executionApprovals?: ExecutionApprovals;
|
|
57
|
-
/**
|
|
58
|
-
* When set, a Context ring in the composer footer shows how much of the
|
|
59
|
-
* model's window the conversation occupies. Used tokens come from the
|
|
60
|
-
* newest message carrying `metadata.usage` (the AI SDK `messageMetadata`
|
|
61
|
-
* convention; Think merges it into message metadata as turns finish).
|
|
62
|
-
*/
|
|
63
|
-
contextWindow?: {
|
|
64
|
-
maxTokens: number;
|
|
65
|
-
modelId?: string;
|
|
66
|
-
};
|
|
67
|
-
/** Override rendering per part; return `undefined` to fall back to the default part UI. */
|
|
68
|
-
renderPart?: (context: AgentChatRenderPartContext<MessageT>) => React.ReactNode | undefined;
|
|
69
|
-
/** Rendered after each message's parts — for actions, citations, and the like. */
|
|
70
|
-
renderMessageAfter?: (context: AgentChatRenderMessageContext<MessageT>) => React.ReactNode;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* A complete agent chat surface: auto-scrolling conversation of AI SDK
|
|
74
|
-
* `UIMessage`s (text, reasoning, and tool parts rendered by default) plus a
|
|
75
|
-
* prompt composer. Customize per-part rendering with `renderPart`.
|
|
76
|
-
*
|
|
77
|
-
* This is the presentational layer under `ThinkChat` — props in, no
|
|
78
|
-
* transport. Use it directly with plain AI SDK `useChat` or a read-only
|
|
79
|
-
* transcript; if you have a Cloudflare Think agent, use `ThinkChat` instead.
|
|
80
|
-
*/
|
|
81
|
-
declare function AgentChat<MessageT extends UIMessage = UIMessage>({
|
|
82
|
-
className,
|
|
83
|
-
messages,
|
|
84
|
-
status,
|
|
85
|
-
onSubmit,
|
|
86
|
-
onStop,
|
|
87
|
-
placeholder,
|
|
88
|
-
disabled,
|
|
89
|
-
emptyState,
|
|
90
|
-
composerTools,
|
|
91
|
-
composerAddMenuItems,
|
|
92
|
-
notice,
|
|
93
|
-
onRegenerate,
|
|
94
|
-
onApprovalResponse,
|
|
95
|
-
executionApprovals,
|
|
96
|
-
contextWindow,
|
|
97
|
-
renderPart,
|
|
98
|
-
renderMessageAfter,
|
|
99
|
-
ref
|
|
100
|
-
}: AgentChatProps<MessageT> & {
|
|
101
|
-
ref?: React.Ref<HTMLDivElement>;
|
|
102
|
-
}): React.JSX.Element;
|
|
103
|
-
//#endregion
|
|
1
|
+
import { a as AgentChatRenderPartContext, i as AgentChatRenderMessageContext, n as AgentChatPart, r as AgentChatProps, t as AgentChat } from "../AgentChat-403mckDG.js";
|
|
104
2
|
export { AgentChat, AgentChatPart, AgentChatProps, AgentChatRenderMessageContext, AgentChatRenderPartContext };
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
|
-
import {
|
|
2
|
+
import { O as PlusIcon, k as RefreshIcon } from "../icons-BAlTbWWP.js";
|
|
3
3
|
import { Activity, ActivityContent, ActivityPanel, ActivityTrigger } from "./Activity.js";
|
|
4
4
|
import { Context, ContextContent, ContextContentBody, ContextContentHeader, ContextTrigger, getContextUsage, getContextUsedTokens } from "./Context.js";
|
|
5
|
-
import {
|
|
5
|
+
import { MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport } from "./MessageScroller.js";
|
|
6
|
+
import { ConversationEmptyState } from "./Conversation.js";
|
|
6
7
|
import { Message, MessageAction, MessageActions, MessageAttachment, MessageContent, MessageResponse } from "./Message.js";
|
|
7
8
|
import { MenuGroup, MenuGroupLabel } from "./Menu.js";
|
|
8
9
|
import { PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputFooter, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals, usePromptInputAttachments } from "./PromptInput.js";
|
|
9
10
|
import { Reasoning, ReasoningContent, ReasoningTrigger } from "./Reasoning.js";
|
|
10
11
|
import * as React from "react";
|
|
11
12
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
-
import { getToolName, isFileUIPart, isReasoningUIPart, isTextUIPart,
|
|
13
|
+
import { getToolName, isFileUIPart, isReasoningUIPart, isTextUIPart, isToolUIPart } from "ai";
|
|
13
14
|
//#region src/components/AgentChat.tsx
|
|
15
|
+
const EMPTY_PENDING_APPROVALS = [];
|
|
14
16
|
function AgentChatAttachButton() {
|
|
15
17
|
const attachments = usePromptInputAttachments();
|
|
16
18
|
return /* @__PURE__ */ jsx(PromptInputButton, {
|
|
@@ -33,11 +35,11 @@ function AgentChatAddMenu({ children }) {
|
|
|
33
35
|
function isCompactedPart(message, part, partIndex) {
|
|
34
36
|
const metadata = message.metadata;
|
|
35
37
|
if (isTextUIPart(part)) return Array.isArray(metadata?.compactedTextParts) && metadata.compactedTextParts.includes(partIndex);
|
|
36
|
-
if (
|
|
38
|
+
if (isToolUIPart(part)) return Array.isArray(metadata?.compactedToolOutputs) && metadata.compactedToolOutputs.includes(part.toolCallId);
|
|
37
39
|
return false;
|
|
38
40
|
}
|
|
39
41
|
function getPartKey(part, partIndex) {
|
|
40
|
-
if (
|
|
42
|
+
if (isToolUIPart(part)) return part.toolCallId;
|
|
41
43
|
if ("id" in part && typeof part.id === "string") return `${part.type}-${part.id}`;
|
|
42
44
|
return `${part.type}-${partIndex}`;
|
|
43
45
|
}
|
|
@@ -88,39 +90,35 @@ function renderDefaultPart(part) {
|
|
|
88
90
|
isStreaming: part.state === "streaming",
|
|
89
91
|
children: [/* @__PURE__ */ jsx(ReasoningTrigger, {}), /* @__PURE__ */ jsx(ReasoningContent, { children: part.text })]
|
|
90
92
|
});
|
|
91
|
-
if (
|
|
93
|
+
if (isToolUIPart(part)) return renderToolActivity(part);
|
|
92
94
|
return null;
|
|
93
95
|
}
|
|
94
96
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* This is the presentational layer under `ThinkChat` — props in, no
|
|
100
|
-
* transport. Use it directly with plain AI SDK `useChat` or a read-only
|
|
101
|
-
* transcript; if you have a Cloudflare Think agent, use `ThinkChat` instead.
|
|
97
|
+
* Low-level transcript/composer surface used by `ThinkChat`: props in, no
|
|
98
|
+
* transport. Product code that talks to a Cloudflare Think agent should render
|
|
99
|
+
* `ThinkChat`; use this directly only for plain AI SDK or read-only messages.
|
|
102
100
|
*/
|
|
103
|
-
function AgentChat({ className, messages, status = "ready", onSubmit, onStop, placeholder = "Ask anything...", disabled, emptyState, composerTools, composerAddMenuItems, notice, onRegenerate, onApprovalResponse, executionApprovals, contextWindow, renderPart, renderMessageAfter, ref }) {
|
|
101
|
+
function AgentChat({ className, messages, status = "ready", onSubmit, onStop, placeholder = "Ask anything...", disabled, emptyState, composerTools, composerAddMenuItems, notice, onRegenerate, onApprovalResponse, executionApprovals, pendingApprovals: durableApprovals = EMPTY_PENDING_APPROVALS, contextWindow, renderPart, renderMessageAfter, ref }) {
|
|
104
102
|
const handleSubmit = React.useCallback((message) => {
|
|
105
103
|
onSubmit?.(message);
|
|
106
104
|
}, [onSubmit]);
|
|
107
105
|
const [skippedApprovalIds, setSkippedApprovalIds] = React.useState([]);
|
|
108
|
-
const
|
|
106
|
+
const pendingApprovalItems = [...getPendingToolApprovals(messages, { pausedExecutions: Boolean(executionApprovals) }).filter(({ part }) => {
|
|
109
107
|
if (part.state === "approval-requested" && !onApprovalResponse) return false;
|
|
110
108
|
const id = getApprovalStateKey(part);
|
|
111
109
|
return Boolean(id) && !skippedApprovalIds.includes(id);
|
|
112
|
-
});
|
|
110
|
+
}).map((approval) => ({ part: approval.part })), ...executionApprovals ? durableApprovals.filter((approval) => approval.source === "action" && !skippedApprovalIds.includes(approval.executionId)).map((approval) => ({ approval })) : []];
|
|
113
111
|
const approvalsWired = Boolean(onApprovalResponse || executionApprovals);
|
|
114
112
|
const [permissionMode, setPermissionMode] = React.useState("ask");
|
|
115
113
|
const autoApprovedIds = React.useRef(/* @__PURE__ */ new Set());
|
|
116
114
|
React.useEffect(() => {
|
|
117
115
|
if (permissionMode !== "bypass") return;
|
|
118
|
-
for (const
|
|
119
|
-
const id = getApprovalRequestId(part);
|
|
120
|
-
const key = getApprovalStateKey(part);
|
|
116
|
+
for (const item of pendingApprovalItems) {
|
|
117
|
+
const id = "part" in item ? getApprovalRequestId(item.part) : item.approval.executionId;
|
|
118
|
+
const key = "part" in item ? getApprovalStateKey(item.part) : item.approval.executionId;
|
|
121
119
|
if (!id || !key || autoApprovedIds.current.has(key)) continue;
|
|
122
120
|
autoApprovedIds.current.add(key);
|
|
123
|
-
if (part.state === "approval-requested") onApprovalResponse?.({
|
|
121
|
+
if ("part" in item && item.part.state === "approval-requested") onApprovalResponse?.({
|
|
124
122
|
id,
|
|
125
123
|
approved: true
|
|
126
124
|
});
|
|
@@ -129,10 +127,11 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
|
|
|
129
127
|
}, [
|
|
130
128
|
permissionMode,
|
|
131
129
|
messages,
|
|
130
|
+
durableApprovals,
|
|
132
131
|
onApprovalResponse,
|
|
133
132
|
executionApprovals
|
|
134
133
|
]);
|
|
135
|
-
const pendingApproval = permissionMode === "bypass" ? void 0 :
|
|
134
|
+
const pendingApproval = permissionMode === "bypass" ? void 0 : pendingApprovalItems[0];
|
|
136
135
|
const contextUsage = contextWindow ? getContextUsage(messages) : void 0;
|
|
137
136
|
const lastAssistantIndex = onRegenerate && status !== "streaming" && status !== "submitted" ? messages.findLastIndex((message) => message.role === "assistant") : -1;
|
|
138
137
|
const composerRef = (el) => {
|
|
@@ -147,40 +146,59 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
|
|
|
147
146
|
return /* @__PURE__ */ jsxs("div", {
|
|
148
147
|
ref,
|
|
149
148
|
className: cx("agent-chat", className),
|
|
150
|
-
children: [/* @__PURE__ */
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
children:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
149
|
+
children: [/* @__PURE__ */ jsx(MessageScrollerProvider, {
|
|
150
|
+
autoScroll: true,
|
|
151
|
+
defaultScrollPosition: "last-anchor",
|
|
152
|
+
children: /* @__PURE__ */ jsxs(MessageScroller, {
|
|
153
|
+
className: "agent-chat__conversation",
|
|
154
|
+
children: [/* @__PURE__ */ jsx(MessageScrollerViewport, { children: /* @__PURE__ */ jsxs(MessageScrollerContent, {
|
|
155
|
+
"aria-busy": status === "streaming" || status === "submitted",
|
|
156
|
+
className: "agent-chat__transcript-content",
|
|
157
|
+
children: [messages.length === 0 ? /* @__PURE__ */ jsx(MessageScrollerItem, {
|
|
158
|
+
className: "agent-chat__empty-row",
|
|
159
|
+
children: emptyState ?? /* @__PURE__ */ jsx(ConversationEmptyState, {
|
|
160
|
+
title: "Start a conversation",
|
|
161
|
+
description: "Ask the agent to inspect, plan, or build."
|
|
162
|
+
})
|
|
163
|
+
}) : null, messages.map((message, messageIndex) => /* @__PURE__ */ jsx(MessageScrollerItem, {
|
|
164
|
+
messageId: message.id,
|
|
165
|
+
scrollAnchor: message.role === "user",
|
|
166
|
+
children: /* @__PURE__ */ jsxs(Message, {
|
|
167
|
+
from: message.role,
|
|
168
|
+
children: [
|
|
169
|
+
message.parts.map((part, partIndex) => {
|
|
170
|
+
const defaultRender = () => renderDefaultPart(part);
|
|
171
|
+
const custom = renderPart?.({
|
|
172
|
+
message,
|
|
173
|
+
part,
|
|
174
|
+
partIndex,
|
|
175
|
+
defaultRender
|
|
176
|
+
});
|
|
177
|
+
const rendered = custom === void 0 ? defaultRender() : custom;
|
|
178
|
+
return rendered ? /* @__PURE__ */ jsxs(MessageContent, { children: [rendered, isCompactedPart(message, part, partIndex) ? /* @__PURE__ */ jsx("div", {
|
|
179
|
+
className: "message__compacted",
|
|
180
|
+
children: "Output truncated for storage"
|
|
181
|
+
}) : null] }, getPartKey(part, partIndex)) : null;
|
|
182
|
+
}),
|
|
183
|
+
renderMessageAfter?.({
|
|
184
|
+
message,
|
|
185
|
+
messageIndex
|
|
186
|
+
}),
|
|
187
|
+
onRegenerate && messageIndex === lastAssistantIndex ? /* @__PURE__ */ jsx(MessageActions, { children: /* @__PURE__ */ jsx(MessageAction, {
|
|
188
|
+
label: "Retry",
|
|
189
|
+
tooltip: "Regenerate response",
|
|
190
|
+
onClick: () => onRegenerate(message.id),
|
|
191
|
+
children: /* @__PURE__ */ jsx(RefreshIcon, { size: 14 })
|
|
192
|
+
}) }) : null
|
|
193
|
+
]
|
|
194
|
+
})
|
|
195
|
+
}, message.id ?? messageIndex))]
|
|
196
|
+
}) }), /* @__PURE__ */ jsx(MessageScrollerButton, {
|
|
197
|
+
"aria-label": "Scroll to latest",
|
|
198
|
+
className: "agent-chat__scroll-button",
|
|
199
|
+
size: "icon"
|
|
200
|
+
})]
|
|
201
|
+
})
|
|
184
202
|
}), /* @__PURE__ */ jsxs("div", {
|
|
185
203
|
ref: composerRef,
|
|
186
204
|
className: "agent-chat__composer",
|
|
@@ -191,12 +209,13 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
|
|
|
191
209
|
multiple: true,
|
|
192
210
|
onSubmit: handleSubmit,
|
|
193
211
|
children: pendingApproval ? /* @__PURE__ */ jsx(PromptInputApproval, {
|
|
194
|
-
part: pendingApproval.part,
|
|
195
|
-
|
|
212
|
+
part: "part" in pendingApproval ? pendingApproval.part : void 0,
|
|
213
|
+
approval: "approval" in pendingApproval ? pendingApproval.approval : void 0,
|
|
214
|
+
count: pendingApprovalItems.length,
|
|
196
215
|
onRespond: onApprovalResponse,
|
|
197
216
|
executionApprovals,
|
|
198
217
|
onSkip: () => {
|
|
199
|
-
const id = getApprovalStateKey(pendingApproval.part);
|
|
218
|
+
const id = "part" in pendingApproval ? getApprovalStateKey(pendingApproval.part) : pendingApproval.approval.executionId;
|
|
200
219
|
if (id) setSkippedApprovalIds((previous) => [...previous, id]);
|
|
201
220
|
}
|
|
202
221
|
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServerCard, McpServerManualSetup } from "../utils/mcp-server-catalog.js";
|
|
1
|
+
import { McpServerCard, McpServerManualSetup, McpServerSetupAuth } from "../utils/mcp-server-catalog.js";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/components/AgentConnection.d.ts
|
|
@@ -38,6 +38,28 @@ type AgentConnectionPopoverProps = Omit<AgentConnectionPanelProps, "section"> &
|
|
|
38
38
|
type McpServerSetupProps = {
|
|
39
39
|
readonly setup: McpServerManualSetup;
|
|
40
40
|
};
|
|
41
|
+
type McpConnectorFormValues = {
|
|
42
|
+
readonly bearerToken?: string;
|
|
43
|
+
readonly clientId?: string;
|
|
44
|
+
readonly clientSecret?: string;
|
|
45
|
+
readonly name: string;
|
|
46
|
+
readonly scope?: string;
|
|
47
|
+
readonly url: string;
|
|
48
|
+
};
|
|
49
|
+
type McpConnectorFormDefaults = Partial<Pick<McpConnectorFormValues, "name" | "url">>;
|
|
50
|
+
type McpConnectorFormProps = Omit<React.FormHTMLAttributes<HTMLFormElement>, "onSubmit" | "status"> & {
|
|
51
|
+
/** Authentication metadata that decides which credential fields render. */readonly auth?: McpServerSetupAuth; /** Label for the OAuth authorization button. */
|
|
52
|
+
readonly authorizeLabel?: string; /** Initial MCP name and URL values. */
|
|
53
|
+
readonly defaults?: McpConnectorFormDefaults; /** Pattern used to validate the MCP name field. */
|
|
54
|
+
readonly namePattern?: string; /** OAuth URL waiting for the user to authorize, when available. */
|
|
55
|
+
readonly pendingAuthUrl?: string | null; /** Read-only redirect URL shown for manual OAuth client setup. */
|
|
56
|
+
readonly redirectUrl?: string; /** Inline connection status announced politely to assistive tech. */
|
|
57
|
+
readonly status?: React.ReactNode; /** Label for the submit button. */
|
|
58
|
+
readonly submitLabel?: string; /** Label shown while submit is pending. */
|
|
59
|
+
readonly submittingLabel?: string; /** Called when the user starts OAuth authorization. */
|
|
60
|
+
readonly onAuthorize?: () => void | Promise<void>; /** Called with normalized connector values after native form validation passes. */
|
|
61
|
+
readonly onSubmit: (values: McpConnectorFormValues) => void | Promise<void>;
|
|
62
|
+
};
|
|
41
63
|
declare function Connection({
|
|
42
64
|
fromX,
|
|
43
65
|
fromY,
|
|
@@ -69,6 +91,25 @@ declare function AgentConnectionPanel({
|
|
|
69
91
|
declare function McpServerSetup({
|
|
70
92
|
setup
|
|
71
93
|
}: McpServerSetupProps): React.JSX.Element;
|
|
94
|
+
/** Collects MCP connector settings and optional credentials with native form validation. */
|
|
95
|
+
declare function McpConnectorForm({
|
|
96
|
+
auth,
|
|
97
|
+
authorizeLabel,
|
|
98
|
+
className,
|
|
99
|
+
defaults,
|
|
100
|
+
namePattern,
|
|
101
|
+
pendingAuthUrl,
|
|
102
|
+
redirectUrl,
|
|
103
|
+
status,
|
|
104
|
+
submitLabel,
|
|
105
|
+
submittingLabel,
|
|
106
|
+
onAuthorize,
|
|
107
|
+
onSubmit,
|
|
108
|
+
ref,
|
|
109
|
+
...props
|
|
110
|
+
}: McpConnectorFormProps & {
|
|
111
|
+
ref?: React.Ref<HTMLFormElement>;
|
|
112
|
+
}): React.JSX.Element;
|
|
72
113
|
/**
|
|
73
114
|
* Compact popover trigger for showing AgentConnectionPanel inline.
|
|
74
115
|
*/
|
|
@@ -77,4 +118,4 @@ declare function AgentConnectionPopover({
|
|
|
77
118
|
...props
|
|
78
119
|
}: AgentConnectionPopoverProps): React.JSX.Element;
|
|
79
120
|
//#endregion
|
|
80
|
-
export { AgentConnectionCommand, AgentConnectionPanel, AgentConnectionPanelProps, AgentConnectionPopover, AgentConnectionPopoverProps, AgentConnectionTarget, Connection, ConnectionProps, McpServerSetup, McpServerSetupProps, NanitesAgentConnectionOptions, buildNanitesAgentConnectionCommands };
|
|
121
|
+
export { AgentConnectionCommand, AgentConnectionPanel, AgentConnectionPanelProps, AgentConnectionPopover, AgentConnectionPopoverProps, AgentConnectionTarget, Connection, ConnectionProps, McpConnectorForm, McpConnectorFormDefaults, McpConnectorFormProps, McpConnectorFormValues, McpServerSetup, McpServerSetupProps, NanitesAgentConnectionOptions, buildNanitesAgentConnectionCommands };
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
|
-
import {
|
|
2
|
+
import { b as LinkIcon } from "../icons-BAlTbWWP.js";
|
|
3
3
|
import { Popover } from "./Popover.js";
|
|
4
4
|
import { Button } from "./Button.js";
|
|
5
|
-
import { a as CodeBlockCopyButton, i as CodeBlockContent, n as CodeBlockActions, p as CodeBlockTitle, r as CodeBlockContainer, s as CodeBlockHeader, t as CodeBlock } from "../CodeBlock-
|
|
5
|
+
import { a as CodeBlockCopyButton, i as CodeBlockContent, n as CodeBlockActions, p as CodeBlockTitle, r as CodeBlockContainer, s as CodeBlockHeader, t as CodeBlock } from "../CodeBlock-D9koxDA7.js";
|
|
6
|
+
import { Field } from "./Field.js";
|
|
7
|
+
import { Form } from "./Form.js";
|
|
6
8
|
import { DCR_MCP_SERVER_CARDS, MANUAL_MCP_SERVER_CARDS, getMcpServerIconSrc } from "../utils/mcp-server-catalog.js";
|
|
7
9
|
import * as React from "react";
|
|
8
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
11
|
//#region src/components/AgentConnection.tsx
|
|
10
12
|
const DEFAULT_LOCAL_ORIGIN = "http://localhost:5173";
|
|
11
13
|
const CONNECTION_CURVE_MIDPOINT = .5;
|
|
14
|
+
const MCP_CONNECTOR_NAME_PATTERN = "[A-Za-z_$][A-Za-z0-9_$]*";
|
|
15
|
+
const CUSTOM_AUTH_FIELDS = [{
|
|
16
|
+
inputType: "password",
|
|
17
|
+
label: "Bearer",
|
|
18
|
+
name: "bearerToken"
|
|
19
|
+
}];
|
|
12
20
|
function Connection({ fromX, fromY, toX, toY, ...props }) {
|
|
13
21
|
const controlX = fromX + (toX - fromX) * CONNECTION_CURVE_MIDPOINT;
|
|
14
22
|
return /* @__PURE__ */ jsxs("g", {
|
|
@@ -211,6 +219,149 @@ function McpServerSetup({ setup }) {
|
|
|
211
219
|
]
|
|
212
220
|
});
|
|
213
221
|
}
|
|
222
|
+
/** Collects MCP connector settings and optional credentials with native form validation. */
|
|
223
|
+
function McpConnectorForm({ auth, authorizeLabel = "Authorize", className, defaults, namePattern = MCP_CONNECTOR_NAME_PATTERN, pendingAuthUrl, redirectUrl = "", status, submitLabel = "Connect MCP", submittingLabel = "Connecting", onAuthorize, onSubmit, ref, ...props }) {
|
|
224
|
+
const [submitting, setSubmitting] = React.useState(false);
|
|
225
|
+
const credentialFields = (auth?.fields ?? CUSTOM_AUTH_FIELDS).filter(isCredentialAuthField);
|
|
226
|
+
const redirectUrlField = auth?.fields.find((field) => field.name === "redirectUrl");
|
|
227
|
+
async function handleSubmit(event) {
|
|
228
|
+
event.preventDefault();
|
|
229
|
+
event.stopPropagation();
|
|
230
|
+
if (!event.currentTarget.reportValidity()) return;
|
|
231
|
+
setSubmitting(true);
|
|
232
|
+
try {
|
|
233
|
+
await onSubmit(readMcpConnectorFormValues(new FormData(event.currentTarget)));
|
|
234
|
+
} finally {
|
|
235
|
+
setSubmitting(false);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return /* @__PURE__ */ jsxs(Form, {
|
|
239
|
+
ref,
|
|
240
|
+
"aria-label": "MCP connector",
|
|
241
|
+
className: cx("agent-connect__mcp-form", className),
|
|
242
|
+
noValidate: false,
|
|
243
|
+
onSubmit: handleSubmit,
|
|
244
|
+
...props,
|
|
245
|
+
children: [
|
|
246
|
+
/* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
247
|
+
/* @__PURE__ */ jsx(Field.Label, {
|
|
248
|
+
htmlFor: "mcpName",
|
|
249
|
+
children: "MCP name"
|
|
250
|
+
}),
|
|
251
|
+
/* @__PURE__ */ jsx(Field.Control, {
|
|
252
|
+
id: "mcpName",
|
|
253
|
+
name: "name",
|
|
254
|
+
pattern: namePattern,
|
|
255
|
+
required: true,
|
|
256
|
+
title: "Use a valid JavaScript identifier.",
|
|
257
|
+
defaultValue: defaults?.name ?? "localMcp"
|
|
258
|
+
}),
|
|
259
|
+
/* @__PURE__ */ jsx(Field.Error, {
|
|
260
|
+
match: "valueMissing",
|
|
261
|
+
children: "MCP name is required."
|
|
262
|
+
}),
|
|
263
|
+
/* @__PURE__ */ jsx(Field.Error, {
|
|
264
|
+
match: "patternMismatch",
|
|
265
|
+
children: "Use a valid JavaScript identifier."
|
|
266
|
+
})
|
|
267
|
+
] }),
|
|
268
|
+
/* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
269
|
+
/* @__PURE__ */ jsx(Field.Label, {
|
|
270
|
+
htmlFor: "mcpUrl",
|
|
271
|
+
children: "MCP URL"
|
|
272
|
+
}),
|
|
273
|
+
/* @__PURE__ */ jsx(Field.Control, {
|
|
274
|
+
id: "mcpUrl",
|
|
275
|
+
name: "url",
|
|
276
|
+
placeholder: "http://127.0.0.1:8787/mcp",
|
|
277
|
+
required: true,
|
|
278
|
+
type: "url",
|
|
279
|
+
defaultValue: defaults?.url ?? ""
|
|
280
|
+
}),
|
|
281
|
+
/* @__PURE__ */ jsx(Field.Error, {
|
|
282
|
+
match: "valueMissing",
|
|
283
|
+
children: "MCP URL is required."
|
|
284
|
+
}),
|
|
285
|
+
/* @__PURE__ */ jsx(Field.Error, {
|
|
286
|
+
match: "typeMismatch",
|
|
287
|
+
children: "MCP URL must use http or https."
|
|
288
|
+
})
|
|
289
|
+
] }),
|
|
290
|
+
redirectUrlField ? /* @__PURE__ */ jsxs(Field.Root, { children: [/* @__PURE__ */ jsx(Field.Label, {
|
|
291
|
+
htmlFor: "mcpRedirectUrl",
|
|
292
|
+
children: redirectUrlField.label
|
|
293
|
+
}), /* @__PURE__ */ jsx(Field.Control, {
|
|
294
|
+
id: "mcpRedirectUrl",
|
|
295
|
+
name: "redirectUrl",
|
|
296
|
+
readOnly: true,
|
|
297
|
+
type: "url",
|
|
298
|
+
value: redirectUrl
|
|
299
|
+
})] }) : null,
|
|
300
|
+
credentialFields.map((authField) => /* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
301
|
+
/* @__PURE__ */ jsx(Field.Label, {
|
|
302
|
+
htmlFor: `mcp-${authField.name}`,
|
|
303
|
+
children: authField.label
|
|
304
|
+
}),
|
|
305
|
+
/* @__PURE__ */ jsx(Field.Control, {
|
|
306
|
+
autoComplete: "off",
|
|
307
|
+
id: `mcp-${authField.name}`,
|
|
308
|
+
name: authField.name,
|
|
309
|
+
placeholder: authField.placeholder,
|
|
310
|
+
required: authField.required,
|
|
311
|
+
type: authField.inputType ?? "text"
|
|
312
|
+
}),
|
|
313
|
+
/* @__PURE__ */ jsxs(Field.Error, {
|
|
314
|
+
match: "valueMissing",
|
|
315
|
+
children: [authField.label, " is required."]
|
|
316
|
+
})
|
|
317
|
+
] }, authField.name)),
|
|
318
|
+
/* @__PURE__ */ jsxs("div", {
|
|
319
|
+
className: "agent-connect__mcp-form-actions",
|
|
320
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
321
|
+
type: "submit",
|
|
322
|
+
size: "sm",
|
|
323
|
+
disabled: submitting,
|
|
324
|
+
children: submitting ? submittingLabel : submitLabel
|
|
325
|
+
}), pendingAuthUrl ? /* @__PURE__ */ jsx(Button, {
|
|
326
|
+
type: "button",
|
|
327
|
+
variant: "outline",
|
|
328
|
+
color: "neutral",
|
|
329
|
+
size: "sm",
|
|
330
|
+
onClick: () => {
|
|
331
|
+
onAuthorize?.();
|
|
332
|
+
},
|
|
333
|
+
children: authorizeLabel
|
|
334
|
+
}) : null]
|
|
335
|
+
}),
|
|
336
|
+
status ? /* @__PURE__ */ jsx("span", {
|
|
337
|
+
className: "agent-connect__mcp-form-status",
|
|
338
|
+
"aria-live": "polite",
|
|
339
|
+
children: status
|
|
340
|
+
}) : null
|
|
341
|
+
]
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
function readMcpConnectorFormValues(data) {
|
|
345
|
+
const bearerToken = readFormString(data, "bearerToken");
|
|
346
|
+
const clientId = readFormString(data, "clientId");
|
|
347
|
+
const clientSecret = readFormString(data, "clientSecret");
|
|
348
|
+
const scope = readFormString(data, "scope");
|
|
349
|
+
return {
|
|
350
|
+
...bearerToken ? { bearerToken } : {},
|
|
351
|
+
...clientId ? { clientId } : {},
|
|
352
|
+
...clientSecret ? { clientSecret } : {},
|
|
353
|
+
name: readFormString(data, "name"),
|
|
354
|
+
...scope ? { scope } : {},
|
|
355
|
+
url: readFormString(data, "url")
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function readFormString(data, name) {
|
|
359
|
+
const value = data.get(name);
|
|
360
|
+
return typeof value === "string" ? value.trim() : "";
|
|
361
|
+
}
|
|
362
|
+
function isCredentialAuthField(field) {
|
|
363
|
+
return field.name !== "redirectUrl";
|
|
364
|
+
}
|
|
214
365
|
function renderMcpServerIcon(server) {
|
|
215
366
|
const src = getMcpServerIconSrc(server);
|
|
216
367
|
if (src) return /* @__PURE__ */ jsx(McpServerIconImage, {
|
|
@@ -261,4 +412,4 @@ function AgentConnectionPopover({ className, ...props }) {
|
|
|
261
412
|
}) })] });
|
|
262
413
|
}
|
|
263
414
|
//#endregion
|
|
264
|
-
export { AgentConnectionPanel, AgentConnectionPopover, Connection, McpServerSetup, buildNanitesAgentConnectionCommands };
|
|
415
|
+
export { AgentConnectionPanel, AgentConnectionPopover, Connection, McpConnectorForm, McpServerSetup, buildNanitesAgentConnectionCommands };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
|
-
import {
|
|
2
|
+
import { I as XIcon } from "../icons-BAlTbWWP.js";
|
|
3
3
|
import { Button } from "./Button.js";
|
|
4
4
|
import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
|
|
5
5
|
import "react";
|