cortena-ui 1.4.2 → 1.5.0
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/LICENSE +7 -0
- package/README.md +149 -1
- package/dist/a2ui/views.js +2 -2
- package/dist/agent-chat/a2ui-block.d.ts +60 -0
- package/dist/agent-chat/a2ui-block.js +69 -0
- package/dist/agent-chat/a2ui-block.js.map +1 -0
- package/dist/agent-chat/agui-client.d.ts +40 -0
- package/dist/agent-chat/agui-client.js +251 -0
- package/dist/agent-chat/agui-client.js.map +1 -0
- package/dist/agent-chat/bridge.d.ts +109 -0
- package/dist/agent-chat/bridge.js +349 -0
- package/dist/agent-chat/bridge.js.map +1 -0
- package/dist/agent-chat/session.d.ts +58 -0
- package/dist/agent-chat/session.js +249 -0
- package/dist/agent-chat/session.js.map +1 -0
- package/dist/agent-chat/store.d.ts +67 -0
- package/dist/agent-chat/store.js +548 -0
- package/dist/agent-chat/store.js.map +1 -0
- package/dist/agent-chat/types.d.ts +187 -0
- package/dist/agent-chat/types.js +17 -0
- package/dist/agent-chat/types.js.map +1 -0
- package/dist/agent-chat.d.ts +10 -0
- package/dist/agent-chat.js +10 -0
- package/dist/components/admin-permissions/admin-permissions.d.ts +66 -0
- package/dist/components/admin-permissions/admin-permissions.js +101 -0
- package/dist/components/admin-permissions/admin-permissions.js.map +1 -0
- package/dist/components/admin-permissions/context.d.ts +70 -0
- package/dist/components/admin-permissions/context.js +258 -0
- package/dist/components/admin-permissions/context.js.map +1 -0
- package/dist/components/admin-permissions/index.d.ts +10 -0
- package/dist/components/admin-permissions/licence.d.ts +15 -0
- package/dist/components/admin-permissions/licence.js +78 -0
- package/dist/components/admin-permissions/licence.js.map +1 -0
- package/dist/components/admin-permissions/matrix.d.ts +20 -0
- package/dist/components/admin-permissions/matrix.js +191 -0
- package/dist/components/admin-permissions/matrix.js.map +1 -0
- package/dist/components/admin-permissions/members.d.ts +18 -0
- package/dist/components/admin-permissions/members.js +185 -0
- package/dist/components/admin-permissions/members.js.map +1 -0
- package/dist/components/admin-permissions/role-assignment.d.ts +35 -0
- package/dist/components/admin-permissions/role-assignment.js +174 -0
- package/dist/components/admin-permissions/role-assignment.js.map +1 -0
- package/dist/components/admin-permissions/roles.d.ts +25 -0
- package/dist/components/admin-permissions/roles.js +168 -0
- package/dist/components/admin-permissions/roles.js.map +1 -0
- package/dist/components/admin-permissions/types.d.ts +152 -0
- package/dist/components/admin-permissions/types.js +63 -0
- package/dist/components/admin-permissions/types.js.map +1 -0
- package/dist/components/agent-chat-popup.d.ts +29 -0
- package/dist/components/agent-chat-popup.js +188 -0
- package/dist/components/agent-chat-popup.js.map +1 -0
- package/dist/components/agent-chat.d.ts +143 -0
- package/dist/components/agent-chat.js +578 -0
- package/dist/components/agent-chat.js.map +1 -0
- package/dist/components/app-shell.d.ts +126 -0
- package/dist/components/app-shell.js +297 -0
- package/dist/components/app-shell.js.map +1 -0
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button-link.js +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/checkbox.d.ts +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/consent-screen.d.ts +65 -0
- package/dist/components/consent-screen.js +123 -0
- package/dist/components/consent-screen.js.map +1 -0
- package/dist/components/data-table/data-table.d.ts +15 -1
- package/dist/components/data-table/data-table.js +18 -4
- package/dist/components/data-table/data-table.js.map +1 -1
- package/dist/components/data-table/index.d.ts +4 -4
- package/dist/components/data-table/parts.d.ts +27 -3
- package/dist/components/data-table/parts.js +175 -55
- package/dist/components/data-table/parts.js.map +1 -1
- package/dist/components/data-table/types.d.ts +61 -0
- package/dist/components/data-table/use-data-table.js +91 -6
- package/dist/components/data-table/use-data-table.js.map +1 -1
- package/dist/components/data-table/use-server-source.js +119 -28
- package/dist/components/data-table/use-server-source.js.map +1 -1
- package/dist/components/help-panel.d.ts +131 -0
- package/dist/components/help-panel.js +545 -0
- package/dist/components/help-panel.js.map +1 -0
- package/dist/components/login-screen.d.ts +127 -0
- package/dist/components/login-screen.js +339 -0
- package/dist/components/login-screen.js.map +1 -0
- package/dist/components/session-guard.d.ts +268 -0
- package/dist/components/session-guard.js +632 -0
- package/dist/components/session-guard.js.map +1 -0
- package/dist/components/toast.d.ts +1 -1
- package/dist/core.d.ts +5 -1
- package/dist/core.js +11 -7
- package/dist/data-table.d.ts +13 -4
- package/dist/data-table.js +10 -2
- package/dist/hooks/use-cortena-theme.js +49 -3
- package/dist/hooks/use-cortena-theme.js.map +1 -1
- package/dist/index.d.ts +17 -4
- package/dist/index.js +21 -8
- package/dist/markdown.d.ts +2 -1
- package/dist/markdown.js +2 -1
- package/package.json +16 -4
- package/src/agent-chat/a2ui-block.ts +118 -0
- package/src/agent-chat/agui-client.ts +405 -0
- package/src/agent-chat/bridge.ts +433 -0
- package/src/agent-chat/session.ts +392 -0
- package/src/agent-chat/store.ts +738 -0
- package/src/agent-chat/types.ts +213 -0
- package/src/components/admin-permissions/admin-permissions.tsx +130 -0
- package/src/components/admin-permissions/context.tsx +376 -0
- package/src/components/admin-permissions/index.tsx +32 -0
- package/src/components/admin-permissions/licence.tsx +84 -0
- package/src/components/admin-permissions/matrix.tsx +257 -0
- package/src/components/admin-permissions/members.tsx +204 -0
- package/src/components/admin-permissions/role-assignment.tsx +239 -0
- package/src/components/admin-permissions/roles.tsx +169 -0
- package/src/components/admin-permissions/types.ts +231 -0
- package/src/components/agent-chat-popup.tsx +289 -0
- package/src/components/agent-chat.tsx +843 -0
- package/src/components/app-shell.tsx +502 -0
- package/src/components/consent-screen.tsx +239 -0
- package/src/components/data-table/data-table.tsx +36 -0
- package/src/components/data-table/index.tsx +6 -1
- package/src/components/data-table/parts.tsx +223 -47
- package/src/components/data-table/types.ts +68 -0
- package/src/components/data-table/use-data-table.ts +152 -4
- package/src/components/data-table/use-server-source.ts +150 -12
- package/src/components/help-panel.tsx +765 -0
- package/src/components/login-screen.tsx +479 -0
- package/src/components/session-guard.tsx +1071 -0
- package/src/entries/agent-chat.ts +113 -0
- package/src/entries/core.ts +8 -0
- package/src/entries/data-table.ts +41 -0
- package/src/entries/markdown.ts +25 -0
- package/src/hooks/use-cortena-theme.ts +63 -4
- package/src/index.ts +6 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-chat-popup.js","names":[],"sources":["../../src/components/agent-chat-popup.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * AgentChatPopup — the extension's own agent, in the corner of every screen.\n *\n * §17 of how-to-create-a-cortena-extension, audit rule P-25. Mounted in\n * `AppShell`'s `agentSlot`, so it stacks above the theme/help cluster rather\n * than beside it and no extension positions a floating control itself.\n *\n * ```tsx\n * <AppShell\n * extension={{ id: \"tasks\", name: \"Tasks\" }}\n * user={user}\n * agentSlot={\n * <AgentChatPopup\n * extension={{ id: \"tasks\", name: \"Tasks\" }}\n * client={client} // createAguiAgentChatClient({ …, agentId: \"tasks\" })\n * />\n * }\n * />\n * ```\n *\n * Three states, and the transitions between them are fixed: a collapsed pill,\n * a panel, and full screen. **Cmd/Ctrl+J** toggles between the pill and the\n * panel; **Escape** steps full screen -> panel -> pill, except while a run is\n * streaming, where the composer takes Escape to mean \"stop\" — the first Escape\n * during a run is nearly always about the run, not about the window.\n *\n * The chat stays mounted in every state, hidden rather than unmounted while\n * collapsed. That is not an optimisation: a run started before the user\n * collapsed the pop-up keeps streaming into it, and the unread dot on the pill\n * is what says so. Unmounting would throw the reply away halfway through.\n *\n * State is remembered per window, in `sessionStorage`, alongside the session\n * key — a second window of the same extension opens its own chat on its own\n * session rather than inheriting this one's.\n */\n\nimport { Maximize2, Minimize2, X } from \"lucide-react\";\nimport * as React from \"react\";\nimport { BrandMark } from \"@/components/app-shell\";\nimport { Button } from \"@/components/button\";\nimport { AgentChat, type AgentChatProps } from \"@/components/agent-chat\";\nimport { viewStorageKey, windowSessionStorage } from \"@/agent-chat/session\";\nimport type { AgentChatClient } from \"@/agent-chat/types\";\nimport { cn } from \"@/lib/cn\";\n\nexport type AgentChatPopupState = \"pill\" | \"panel\" | \"full\";\n\nexport interface AgentChatPopupExtension {\n /** Registered mark id — the same `x-cortena.icon` the shell draws. */\n id: string;\n /** Display name. Also the agent template slug, unless `agentId` overrides it. */\n name: string;\n}\n\nexport interface AgentChatPopupProps\n extends Omit<\n AgentChatProps,\n \"agentName\" | \"storageScope\" | \"className\" | \"headerSlot\" | \"client\"\n > {\n extension: AgentChatPopupExtension;\n /** The transport. Its `agentId` is the template slug the sessions belong to. */\n client: AgentChatClient;\n /**\n * Names the `sessionStorage` slots. Defaults to the extension id, which is\n * what keeps two extensions on one origin out of each other's sessions.\n */\n storageScope?: string;\n /** Start here instead of collapsed; the stored state still wins on reload. */\n defaultState?: AgentChatPopupState;\n className?: string;\n}\n\n/** Cmd on a Mac, Ctrl elsewhere. Documented in README.md. */\nfunction isToggleShortcut(event: KeyboardEvent): boolean {\n return (event.metaKey || event.ctrlKey) && !event.altKey && event.key.toLowerCase() === \"j\";\n}\n\nfunction AgentChatPopup({\n extension,\n client,\n storageScope,\n defaultState = \"pill\",\n className,\n ...chatProps\n}: AgentChatPopupProps) {\n const scope = storageScope ?? extension.id;\n const [state, setState] = React.useState<AgentChatPopupState>(defaultState);\n const [unread, setUnread] = React.useState(false);\n const stateRef = React.useRef(state);\n stateRef.current = state;\n const pillRef = React.useRef<HTMLButtonElement>(null);\n const panelRef = React.useRef<HTMLDivElement>(null);\n /** Whether the user has opened or closed it, as against it starting open. */\n const moved = React.useRef(false);\n\n // Restore this window's open/collapsed choice. In an effect rather than a\n // lazy initialiser so a server render and the first client render agree.\n React.useEffect(() => {\n try {\n const stored = windowSessionStorage()?.getItem(viewStorageKey(scope));\n if (stored === \"pill\" || stored === \"panel\" || stored === \"full\") {\n setState(stored);\n }\n } catch {\n // A blocked storage just means the pop-up opens collapsed.\n }\n }, [scope]);\n\n const go = React.useCallback(\n (next: AgentChatPopupState) => {\n moved.current = true;\n setState(next);\n if (next !== \"pill\") {\n setUnread(false);\n }\n try {\n windowSessionStorage()?.setItem(viewStorageKey(scope), next);\n } catch {\n // Not remembering the choice is not a reason to refuse the change.\n }\n },\n [scope],\n );\n\n // The unread dot. Subscribed here rather than read out of the chat, because\n // the point is what happened while the surface was not being looked at.\n React.useEffect(() => {\n return client.onChat((event) => {\n if (stateRef.current === \"pill\" && (event.state === \"delta\" || event.state === \"final\")) {\n setUnread(true);\n }\n });\n }, [client]);\n\n React.useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (!isToggleShortcut(event)) {\n return;\n }\n event.preventDefault();\n go(stateRef.current === \"pill\" ? \"panel\" : \"pill\");\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [go]);\n\n /**\n * Escape steps down one level. It is handled on the panel rather than on the\n * window so it only fires when focus is inside the pop-up, and it arrives\n * here only when the composer did not claim it — the composer stops\n * propagation while a run is streaming, where Escape means \"stop the run\".\n */\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== \"Escape\") {\n return;\n }\n event.preventDefault();\n go(stateRef.current === \"full\" ? \"panel\" : \"pill\");\n },\n [go],\n );\n\n const open = state !== \"pill\";\n\n /**\n * Focus follows the pop-up.\n *\n * The panel is `hidden`, not unmounted, so nothing moves focus by itself.\n * Opening left focus on the pill — which is now `hidden`, so the browser\n * resets it to <body> and the next Tab starts at the top of the page rather\n * than in the chat that was just opened. Closing had the mirror problem:\n * focus was inside a subtree that had just become hidden.\n *\n * Only after the user moves it. A pop-up that starts on `panel`, or one\n * restored from `sessionStorage` on load, must not steal focus from the page.\n */\n React.useEffect(() => {\n if (!moved.current) {\n return;\n }\n const frame = requestAnimationFrame(() => {\n if (open) {\n panelRef.current\n ?.querySelector<HTMLElement>('[data-slot=\"agent-chat-input\"]')\n ?.focus({ preventScroll: true });\n } else {\n pillRef.current?.focus({ preventScroll: true });\n }\n });\n return () => cancelAnimationFrame(frame);\n }, [open]);\n\n return (\n <>\n <button\n ref={pillRef}\n type=\"button\"\n data-slot=\"agent-chat-pill\"\n data-state={state}\n data-unread={unread ? \"\" : undefined}\n aria-expanded={open}\n aria-label={`Ask ${extension.name}`}\n hidden={open}\n onClick={() => go(\"panel\")}\n className={cn(\n \"relative inline-flex h-10 items-center gap-2 rounded-[var(--ds-radius-full)] px-3.5\",\n \"border border-[var(--ds-border)] bg-[var(--ds-card)] text-[color:var(--ds-foreground)]\",\n \"shadow-[var(--ds-shadow-md)] outline-none\",\n \"transition-colors duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]\",\n \"hover:bg-[var(--ds-hover)]\",\n \"focus-visible:ring-2 focus-visible:ring-[var(--ds-ring)] focus-visible:ring-offset-2\",\n \"focus-visible:ring-offset-[var(--ds-background)]\",\n className,\n )}\n >\n <span className=\"flex size-5 items-center justify-center text-[color:var(--ds-primary)]\">\n <BrandMark id={extension.id} name={extension.name} size={16} decorative />\n </span>\n <span className=\"text-[length:var(--ds-text-caption-lg)] font-medium\">\n Ask {extension.name}\n </span>\n {unread ? (\n <span\n data-slot=\"agent-chat-pill-unread\"\n aria-label=\"The agent is replying\"\n className=\"size-2 rounded-[var(--ds-radius-full)] bg-[var(--ds-primary)]\"\n />\n ) : null}\n </button>\n\n {/* Hidden, not unmounted: a run started before the pop-up was collapsed\n keeps streaming, and the pill's dot is what reports it. */}\n <div\n ref={panelRef}\n data-slot=\"agent-chat-panel\"\n data-state={state}\n role=\"dialog\"\n aria-label={`${extension.name} agent`}\n hidden={!open}\n onKeyDown={onKeyDown}\n className={cn(\n \"fixed z-50 flex flex-col overflow-hidden border border-[var(--ds-border)]\",\n \"bg-[var(--ds-card)] shadow-[var(--ds-shadow-lg)]\",\n state === \"full\"\n ? \"inset-0 rounded-none\"\n : cn(\n \"right-6 bottom-6 rounded-[var(--ds-radius-lg)]\",\n \"h-[min(40rem,calc(100vh-3rem))] w-[min(26.25rem,calc(100vw-3rem))]\",\n ),\n )}\n >\n <AgentChat\n client={client}\n agentName={extension.name}\n storageScope={scope}\n className=\"min-h-0 flex-1\"\n headerSlot={\n <>\n <Button\n size=\"icon-sm\"\n variant=\"ghost\"\n data-slot=\"agent-chat-expand\"\n aria-label={state === \"full\" ? \"Restore the panel\" : \"Expand to full screen\"}\n onClick={() => go(state === \"full\" ? \"panel\" : \"full\")}\n >\n {state === \"full\" ? <Minimize2 aria-hidden /> : <Maximize2 aria-hidden />}\n </Button>\n <Button\n size=\"icon-sm\"\n variant=\"ghost\"\n data-slot=\"agent-chat-collapse\"\n aria-label=\"Collapse the agent\"\n onClick={() => go(\"pill\")}\n >\n <X aria-hidden />\n </Button>\n </>\n }\n {...chatProps}\n />\n </div>\n </>\n );\n}\n\nexport { AgentChatPopup };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { A2UIAction } from "../a2ui/message.js";
|
|
3
|
+
import { A2UIChatBlock } from "../agent-chat/a2ui-block.js";
|
|
4
|
+
import { AgentApprovalRequest, AgentChatClient, AgentChatMessage, AgentSession } from "../agent-chat/types.js";
|
|
5
|
+
import { AgentToolEntry } from "../agent-chat/store.js";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
//#region src/components/agent-chat.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Should the list jump back to the bottom after its content grew?
|
|
10
|
+
*
|
|
11
|
+
* Judged against the height BEFORE the growth. Measuring afterwards asks "is
|
|
12
|
+
* the newest content already visible", which is false by construction for any
|
|
13
|
+
* append taller than the threshold — a paragraph, a code block, an image — so
|
|
14
|
+
* the re-pin skipped exactly when it was needed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function shouldStickToBottom(params: {
|
|
17
|
+
prevScrollHeight: number;
|
|
18
|
+
scrollTop: number;
|
|
19
|
+
clientHeight: number;
|
|
20
|
+
threshold?: number;
|
|
21
|
+
}): boolean;
|
|
22
|
+
export interface AgentThinkingProps {
|
|
23
|
+
text: string;
|
|
24
|
+
/** Open by default while the turn is live, collapsed once it is finished. */
|
|
25
|
+
defaultOpen?: boolean;
|
|
26
|
+
streaming?: boolean;
|
|
27
|
+
}
|
|
28
|
+
declare function AgentThinking({ text, defaultOpen, streaming }: AgentThinkingProps): React.JSX.Element | null;
|
|
29
|
+
export interface AgentA2UIBlocksProps {
|
|
30
|
+
blocks: readonly A2UIChatBlock[] | undefined;
|
|
31
|
+
/** Set on the streaming bubble: actions are disabled while the turn is live. */
|
|
32
|
+
streaming?: boolean;
|
|
33
|
+
onAction?: (action: A2UIAction) => void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Every block of one message, in arrival order.
|
|
37
|
+
*
|
|
38
|
+
* A block carrying a transport `error` — an unclosed fence, a body that did not
|
|
39
|
+
* parse — gets an error card rather than being dropped. A block that is merely
|
|
40
|
+
* malformed inside is the renderer's error to draw, and it draws the parts that
|
|
41
|
+
* were fine.
|
|
42
|
+
*/
|
|
43
|
+
declare function AgentA2UIBlocks({ blocks, streaming, onAction }: AgentA2UIBlocksProps): React.JSX.Element | null;
|
|
44
|
+
export interface AgentMessageBubbleProps {
|
|
45
|
+
message: AgentChatMessage;
|
|
46
|
+
agentName: string;
|
|
47
|
+
/**
|
|
48
|
+
* True while a run is live. Every A2UI surface in the transcript goes
|
|
49
|
+
* read-only, not just the one being drawn: an earlier surface is still a
|
|
50
|
+
* form wired to `sendAction`, and pressing it mid-run starts a second
|
|
51
|
+
* concurrent turn on the same session.
|
|
52
|
+
*/
|
|
53
|
+
streaming?: boolean;
|
|
54
|
+
onAction?: (action: A2UIAction) => void;
|
|
55
|
+
}
|
|
56
|
+
declare function AgentMessageBubble({ message, agentName, streaming, onAction }: AgentMessageBubbleProps): React.JSX.Element | null;
|
|
57
|
+
export interface AgentStreamingBubbleProps {
|
|
58
|
+
agentName: string;
|
|
59
|
+
text: string;
|
|
60
|
+
thinkingText: string;
|
|
61
|
+
a2ui: readonly A2UIChatBlock[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The assistant bubble while a turn is live.
|
|
65
|
+
*
|
|
66
|
+
* The filter chain is deliberately not applied: streaming text is
|
|
67
|
+
* agent-authored prose in progress, and the filters are about finished
|
|
68
|
+
* messages. Markdown is not processed either — partially arrived source
|
|
69
|
+
* (`**bo`) looks worse than its raw form — so the streaming view is plain text
|
|
70
|
+
* under `whitespace-pre-wrap` and `Markdown` takes over on `final`.
|
|
71
|
+
*/
|
|
72
|
+
declare function AgentStreamingBubble({ agentName, text, thinkingText, a2ui }: AgentStreamingBubbleProps): React.JSX.Element;
|
|
73
|
+
/** A `ui://` resource in a tool result is an MCP App: the extension's own screen. */
|
|
74
|
+
export declare function readMcpAppUri(output: unknown): string | null;
|
|
75
|
+
export interface AgentToolCardProps {
|
|
76
|
+
entry: AgentToolEntry;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The default card. It shows the tool's name, its input and its output — the
|
|
80
|
+
* input being the part that was missing for the whole of the AG-UI path,
|
|
81
|
+
* because the bridge had no `TOOL_CALL_ARGS` case.
|
|
82
|
+
*/
|
|
83
|
+
declare function AgentToolCard({ entry }: AgentToolCardProps): React.JSX.Element;
|
|
84
|
+
export interface AgentApprovalCardProps {
|
|
85
|
+
request: AgentApprovalRequest;
|
|
86
|
+
onResolve: (id: string, decision: "allow-once" | "allow-always" | "deny") => void;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* `exec` as a render-and-wait card: the run is paused on this decision.
|
|
90
|
+
*
|
|
91
|
+
* The three answers are the three cortenacore accepts. "Always allow" is not a
|
|
92
|
+
* nicety — without it the same command is asked about on every turn, and a user
|
|
93
|
+
* who has to answer the same question repeatedly stops reading the question.
|
|
94
|
+
*/
|
|
95
|
+
declare function AgentApprovalCard({ request, onResolve }: AgentApprovalCardProps): React.JSX.Element;
|
|
96
|
+
export interface AgentToolRenderContext {
|
|
97
|
+
entry: AgentToolEntry;
|
|
98
|
+
/** The `ui://` resource this result carries, when it carries one. */
|
|
99
|
+
mcpAppUri: string | null;
|
|
100
|
+
}
|
|
101
|
+
export interface AgentChatProps extends Omit<React.ComponentProps<"div">, "children" | "onError"> {
|
|
102
|
+
/** The transport. `createAguiAgentChatClient` is the AG-UI implementation. */
|
|
103
|
+
client: AgentChatClient;
|
|
104
|
+
/** The extension name, shown on each assistant turn. */
|
|
105
|
+
agentName: string;
|
|
106
|
+
/**
|
|
107
|
+
* Names the `sessionStorage` slot this window's session key lives in. Scope
|
|
108
|
+
* it to the extension id; two chats with different scopes never share a key.
|
|
109
|
+
*/
|
|
110
|
+
storageScope: string;
|
|
111
|
+
/** Do not read or write `sessionStorage`; for a guide or a test. */
|
|
112
|
+
ephemeral?: boolean;
|
|
113
|
+
thinking?: "low" | "medium" | "high";
|
|
114
|
+
/** Rendered between the tool strip and the composer — an attachment picker. */
|
|
115
|
+
attachmentsSlot?: React.ReactNode;
|
|
116
|
+
/**
|
|
117
|
+
* Host wiring for a tool call. Return a node to replace the default card —
|
|
118
|
+
* this is the seam an MCP App frame mounts through, since the sandboxed
|
|
119
|
+
* iframe, its CSP and the `tools/invoke` proxy are the host's to own.
|
|
120
|
+
*/
|
|
121
|
+
renderToolCall?: (context: AgentToolRenderContext) => React.ReactNode | undefined;
|
|
122
|
+
/** Header content, e.g. the pop-up's own window controls. */
|
|
123
|
+
headerSlot?: React.ReactNode;
|
|
124
|
+
}
|
|
125
|
+
declare function AgentChat({ client, agentName, storageScope, ephemeral, thinking, attachmentsSlot, renderToolCall, headerSlot, className, ...props }: AgentChatProps): React.JSX.Element;
|
|
126
|
+
export interface AgentSessionDrawerProps {
|
|
127
|
+
sessions: readonly AgentSession[];
|
|
128
|
+
current: string | null;
|
|
129
|
+
loading?: boolean;
|
|
130
|
+
onResume: (key: string) => void;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Every session of this agent, resumable from any window.
|
|
134
|
+
*
|
|
135
|
+
* The list is not this window's history: a session started in another window is
|
|
136
|
+
* here and can be resumed, which is the difference between "sessions are per
|
|
137
|
+
* window" (which key a window starts on) and "sessions are private to a window"
|
|
138
|
+
* (which they are not).
|
|
139
|
+
*/
|
|
140
|
+
declare function AgentSessionDrawer({ sessions, current, loading, onResume }: AgentSessionDrawerProps): React.JSX.Element;
|
|
141
|
+
//#endregion
|
|
142
|
+
export { AgentA2UIBlocks, AgentApprovalCard, AgentChat, AgentMessageBubble, AgentSessionDrawer, AgentStreamingBubble, AgentThinking, AgentToolCard };
|
|
143
|
+
//# sourceMappingURL=agent-chat.d.ts.map
|