@artooi/ag-ui-web-component 0.1.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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +471 -0
- package/dist/ag-ui-web-component.bundle.js +319 -0
- package/dist/ag-ui-web-component.bundle.js.map +7 -0
- package/dist/ag_ui_chat.d.ts +85 -0
- package/dist/ag_ui_chat.d.ts.map +1 -0
- package/dist/agui_client.d.ts +99 -0
- package/dist/agui_client.d.ts.map +1 -0
- package/dist/animations.d.ts +33 -0
- package/dist/animations.d.ts.map +1 -0
- package/dist/client_tool_registry.d.ts +32 -0
- package/dist/client_tool_registry.d.ts.map +1 -0
- package/dist/confirmation_modal.d.ts +14 -0
- package/dist/confirmation_modal.d.ts.map +1 -0
- package/dist/constants.d.ts +40 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/conversation_store.d.ts +54 -0
- package/dist/conversation_store.d.ts.map +1 -0
- package/dist/create_http_agent.d.ts +22 -0
- package/dist/create_http_agent.d.ts.map +1 -0
- package/dist/define_ag_ui_chat.d.ts +9 -0
- package/dist/define_ag_ui_chat.d.ts.map +1 -0
- package/dist/dom_driver.d.ts +24 -0
- package/dist/dom_driver.d.ts.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1159 -0
- package/dist/index.js.map +7 -0
- package/dist/is_destructive.d.ts +8 -0
- package/dist/is_destructive.d.ts.map +1 -0
- package/dist/is_navigates.d.ts +9 -0
- package/dist/is_navigates.d.ts.map +1 -0
- package/dist/page_map.d.ts +16 -0
- package/dist/page_map.d.ts.map +1 -0
- package/dist/route_map.d.ts +27 -0
- package/dist/route_map.d.ts.map +1 -0
- package/dist/state_hook.d.ts +23 -0
- package/dist/state_hook.d.ts.map +1 -0
- package/dist/styles.d.ts +2 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/tool_call_card.d.ts +29 -0
- package/dist/tool_call_card.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +79 -0
- package/src/ag_ui_chat.ts +411 -0
- package/src/agui_client.ts +212 -0
- package/src/animations.ts +86 -0
- package/src/client_tool_registry.ts +56 -0
- package/src/confirmation_modal.ts +69 -0
- package/src/constants.ts +48 -0
- package/src/conversation_store.ts +103 -0
- package/src/create_http_agent.ts +40 -0
- package/src/define_ag_ui_chat.ts +15 -0
- package/src/dom_driver.ts +60 -0
- package/src/index.ts +60 -0
- package/src/is_destructive.ts +11 -0
- package/src/is_navigates.ts +12 -0
- package/src/page_map.ts +25 -0
- package/src/route_map.ts +83 -0
- package/src/state_hook.ts +44 -0
- package/src/styles.ts +296 -0
- package/src/tool_call_card.ts +95 -0
- package/src/version.ts +1 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/agui_client.ts", "../src/constants.ts", "../src/client_tool_registry.ts", "../src/confirmation_modal.ts", "../src/conversation_store.ts", "../src/create_http_agent.ts", "../src/is_destructive.ts", "../src/is_navigates.ts", "../src/page_map.ts", "../src/route_map.ts", "../src/state_hook.ts", "../src/styles.ts", "../src/tool_call_card.ts", "../src/ag_ui_chat.ts", "../src/animations.ts", "../src/define_ag_ui_chat.ts", "../src/dom_driver.ts", "../src/version.ts"],
|
|
4
|
+
"sourcesContent": ["import { type AbstractAgent, type AgentSubscriber, randomUUID } from \"@ag-ui/client\";\nimport type { Context, Message, Tool } from \"@ag-ui/core\";\nimport { MAX_TOOL_ROUNDS } from \"./constants.js\";\n\n/** A tool call surfaced to the host by {@link AgUiClient}. */\nexport interface AgUiToolCall {\n readonly id: string;\n readonly name: string;\n readonly args: Record<string, unknown>;\n}\n\n/** The result of executing a frontend tool, destined for a tool-result message. */\nexport interface ToolExecution {\n /** String content for the AG-UI tool-result message. */\n content: string;\n /** Present when the handler failed; surfaced for logging. */\n error?: string;\n /**\n * When `true`, a navigating tool triggered a page reload. The loop stops\n * without appending a result \u2014 the result is supplied after the next mount\n * (see the resume path). Mutually exclusive with a usable `content`.\n */\n halt?: boolean;\n}\n\n/**\n * Executes a frontend tool call.\n *\n * Returns the {@link ToolExecution} to post back to the agent, or ``null`` when\n * the call is not a frontend tool the host owns (a server-side tool the server\n * already executed \u2014 the client must not re-run for it).\n */\nexport type ExecuteTool = (call: AgUiToolCall) => Promise<ToolExecution | null>;\n\n/**\n * Callbacks the {@link AgUiClient} invokes as a run progresses. The host\n * (the `<ag-ui-chat>` element) implements these to render streaming text and\n * tool activity into the chat.\n */\nexport interface AgUiClientHandlers {\n onRunStart(): void;\n /** Fired on every streamed token; ``buffer`` is the full text so far. */\n onTextDelta(buffer: string): void;\n /** Fired when the assistant message completes; ``buffer`` is the final text. */\n onTextEnd(buffer: string): void;\n /** Fired when the agent finishes calling a tool (server- or frontend-side). */\n onToolCall(call: AgUiToolCall): void;\n onRunEnd(): void;\n onError(message: string): void;\n}\n\n/**\n * Provider of the per-run frontend tool catalog and context. Both are read\n * fresh on every {@link AgUiClient.send} so the catalog reflects the current\n * page state.\n */\nexport interface AgUiRunInputs {\n getTools?: () => Tool[];\n getContext?: () => Context[];\n}\n\nexport interface AgUiClientConfig extends AgUiRunInputs {\n /** The AG-UI agent to drive. Injected so it can be faked in tests. */\n agent: AbstractAgent;\n handlers: AgUiClientHandlers;\n /** Executes frontend tool calls. Omit for server-only tool sets. */\n executeTool?: ExecuteTool;\n /**\n * Invoked with the latest history whenever it changes, so the host can\n * persist it for durability across page reloads. Omit to keep the\n * conversation in-memory only.\n */\n onPersist?: (messages: readonly Message[]) => void;\n}\n\n/**\n * Thin orchestration layer over an AG-UI {@link AbstractAgent}.\n *\n * Translates AG-UI's subscriber callbacks into the host's\n * {@link AgUiClientHandlers}, and appends the user message + current frontend\n * tool catalog + context to each run.\n */\nexport class AgUiClient {\n readonly #agent: AbstractAgent;\n readonly #handlers: AgUiClientHandlers;\n readonly #getTools: () => Tool[];\n readonly #getContext: () => Context[];\n readonly #executeTool: ExecuteTool | null;\n readonly #onPersist: (messages: readonly Message[]) => void;\n\n constructor(config: AgUiClientConfig) {\n this.#agent = config.agent;\n this.#handlers = config.handlers;\n this.#getTools = config.getTools ?? (() => []);\n this.#getContext = config.getContext ?? (() => []);\n this.#executeTool = config.executeTool ?? null;\n this.#onPersist = config.onPersist ?? (() => {});\n }\n\n /** Whether a run is currently in flight. */\n get running(): boolean {\n return this.#agent.isRunning;\n }\n\n /** The current conversation history (for persistence / rehydration). */\n get messages(): readonly Message[] {\n return this.#agent.messages;\n }\n\n /**\n * Append a user message and run the agent to completion.\n *\n * When the agent calls frontend tools, this executes them and re-runs the\n * agent with the results, looping until the agent stops calling frontend\n * tools (bounded by {@link MAX_TOOL_ROUNDS}).\n */\n async send(content: string): Promise<void> {\n this.#agent.addMessage({ id: randomUUID(), role: \"user\", content });\n this.#onPersist(this.#agent.messages);\n await this.#run();\n }\n\n /**\n * Resume the run loop after a navigating tool's result was supplied\n * post-reload (via {@link addToolResult}). Unlike {@link send}, adds no user\n * message \u2014 it simply continues the conversation already in history.\n */\n async resume(): Promise<void> {\n await this.#run();\n }\n\n /** Append a frontend tool result to history (used by the resume path). */\n addToolResult(toolCallId: string, content: string): void {\n this.#agent.addMessage({ id: randomUUID(), role: \"tool\", content, toolCallId });\n this.#onPersist(this.#agent.messages);\n }\n\n async #run(): Promise<void> {\n try {\n await this.#runLoop();\n } catch (error) {\n this.#handlers.onError(error instanceof Error ? error.message : String(error));\n }\n }\n\n async #runLoop(): Promise<void> {\n for (let round = 0; round < MAX_TOOL_ROUNDS; round += 1) {\n const pending: AgUiToolCall[] = [];\n await this.#agent.runAgent(\n { tools: this.#getTools(), context: this.#getContext() },\n this.#buildSubscriber(pending),\n );\n this.#onPersist(this.#agent.messages);\n if (this.#executeTool === null || pending.length === 0) {\n return;\n }\n let executed = false;\n for (const call of pending) {\n const result = await this.#executeTool(call);\n if (result === null) {\n continue;\n }\n if (result.halt === true) {\n // A navigating tool reloaded the page; the result arrives on the\n // next mount. Stop here rather than re-running into a dead context.\n return;\n }\n this.#agent.addMessage({\n id: randomUUID(),\n role: \"tool\",\n content: result.content,\n toolCallId: call.id,\n });\n this.#onPersist(this.#agent.messages);\n executed = true;\n }\n if (!executed) {\n return;\n }\n }\n }\n\n #buildSubscriber(pending: AgUiToolCall[]): AgentSubscriber {\n const h = this.#handlers;\n return {\n onRunInitialized() {\n h.onRunStart();\n },\n onTextMessageContentEvent({ textMessageBuffer }) {\n h.onTextDelta(textMessageBuffer);\n },\n onTextMessageEndEvent({ textMessageBuffer }) {\n h.onTextEnd(textMessageBuffer);\n },\n onToolCallEndEvent({ event, toolCallName, toolCallArgs }) {\n const call: AgUiToolCall = {\n id: event.toolCallId,\n name: toolCallName,\n args: toolCallArgs,\n };\n pending.push(call);\n h.onToolCall(call);\n },\n onRunErrorEvent({ event }) {\n h.onError(event.message);\n },\n onRunFinalized() {\n h.onRunEnd();\n },\n };\n }\n}\n", "// The package's single home for enums and constant-like values. Per\n// CLAUDE.md this is the only file allowed to export multiple symbols.\n\n/** The Custom Element tag name registered by {@link defineAgUiChat}. */\nexport const ELEMENT_TAG = \"ag-ui-chat\";\n\n/**\n * Event dispatched by `<ag-ui-chat>` when the user submits a message.\n * `detail` carries `{ content: string }`. Later phases wire this to the\n * AG-UI client; for now it is the public seam for host integration.\n */\nexport const SUBMIT_EVENT = \"ag-ui-submit\";\n\n/** Roles a chat message can take. */\nexport const MESSAGE_ROLE = {\n USER: \"user\",\n ASSISTANT: \"assistant\",\n} as const;\n\n/**\n * JSON-Schema extension key marking a tool as destructive. Mirrors the\n * `django-ag-ui` server side. When a tool's `parameters` carries\n * `{ \"x-destructive\": true }`, the element gates its execution behind the\n * confirmation modal (unless `autoConfirm` is set).\n */\nexport const X_DESTRUCTIVE_KEY = \"x-destructive\";\n\n/**\n * JSON-Schema extension key marking a tool as navigating \u2014 its handler triggers\n * a full page reload (an MPA navigation). When a tool's `parameters` carries\n * `{ \"x-navigates\": true }`, the element checkpoints the call before the reload\n * and resumes the run loop once the next page mounts. Mirrors `x-destructive`.\n */\nexport const X_NAVIGATES_KEY = \"x-navigates\";\n\n/** Upper bound on frontend tool-call \u2192 re-run rounds within one send. */\nexport const MAX_TOOL_ROUNDS = 10;\n\n/**\n * Lifecycle status of a rendered tool-call card. A card opens as `PENDING`\n * while the call runs, then settles to `DONE`, `ERROR`, or `DECLINED`.\n */\nexport const TOOL_CALL_STATUS = {\n PENDING: \"pending\",\n DONE: \"done\",\n ERROR: \"error\",\n DECLINED: \"declined\",\n} as const;\n", "import type { Tool } from \"@ag-ui/core\";\n\n/**\n * A tool the frontend declares and executes itself.\n *\n * `parameters` is a JSON Schema (and may carry the `x-destructive` extension).\n * `handler` receives the parsed arguments and returns a result that is\n * JSON-serialised into the AG-UI tool-result message sent back to the agent.\n */\nexport interface ClientTool {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n handler: (args: Record<string, unknown>) => unknown | Promise<unknown>;\n}\n\n/**\n * Holds the frontend tools a host has declared on an `<ag-ui-chat>` element.\n *\n * Produces AG-UI {@link Tool} definitions for `RunAgentInput.tools` and looks\n * up handlers when the agent calls a tool. Pure (no DOM); the element owns one\n * instance.\n */\nexport class ClientToolRegistry {\n readonly #tools = new Map<string, ClientTool>();\n\n /** Register a tool. Throws if the name is already taken. */\n register(tool: ClientTool): void {\n if (this.#tools.has(tool.name)) {\n throw new Error(`tool \"${tool.name}\" already registered`);\n }\n this.#tools.set(tool.name, tool);\n }\n\n has(name: string): boolean {\n return this.#tools.has(name);\n }\n\n /** Return a registered tool or throw. */\n get(name: string): ClientTool {\n const tool = this.#tools.get(name);\n if (tool === undefined) {\n throw new Error(`tool \"${name}\" is not registered`);\n }\n return tool;\n }\n\n /** AG-UI tool definitions for `RunAgentInput.tools`. */\n tools(): Tool[] {\n return [...this.#tools.values()].map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }));\n }\n}\n", "/** What the confirmation modal displays. */\nexport interface ConfirmationRequest {\n toolName: string;\n args: Record<string, unknown>;\n}\n\n/**\n * Render a confirmation modal into ``host`` and resolve when the user decides.\n *\n * Resolves ``true`` if the user confirms, ``false`` if they cancel or dismiss\n * via the backdrop. The modal is appended to ``host`` (the chat container\n * inside the element's shadow root) and removed once resolved.\n */\nexport function requestConfirmation(\n host: Node & ParentNode,\n request: ConfirmationRequest,\n): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const overlay = document.createElement(\"div\");\n overlay.className = \"modal-overlay\";\n\n const dialog = document.createElement(\"div\");\n dialog.className = \"modal\";\n\n const title = document.createElement(\"div\");\n title.className = \"modal-title\";\n title.textContent = \"Confirm action\";\n\n const body = document.createElement(\"div\");\n body.className = \"modal-body\";\n body.textContent = `Run \u201C${request.toolName}\u201D?`;\n\n const args = document.createElement(\"pre\");\n args.className = \"modal-args\";\n args.textContent = JSON.stringify(request.args, null, 2);\n\n const actions = document.createElement(\"div\");\n actions.className = \"modal-actions\";\n\n const cancel = document.createElement(\"button\");\n cancel.className = \"modal-btn modal-btn--cancel\";\n cancel.type = \"button\";\n cancel.textContent = \"Cancel\";\n\n const confirm = document.createElement(\"button\");\n confirm.className = \"modal-btn modal-btn--confirm\";\n confirm.type = \"button\";\n confirm.textContent = \"Run\";\n\n const close = (accepted: boolean): void => {\n overlay.remove();\n resolve(accepted);\n };\n\n cancel.addEventListener(\"click\", () => close(false));\n confirm.addEventListener(\"click\", () => close(true));\n overlay.addEventListener(\"click\", (event) => {\n if (event.target === overlay) {\n close(false);\n }\n });\n\n actions.append(cancel, confirm);\n dialog.append(title, body, args, actions);\n overlay.append(dialog);\n host.appendChild(overlay);\n confirm.focus();\n });\n}\n", "import { randomUUID } from \"@ag-ui/client\";\nimport type { Message } from \"@ag-ui/core\";\n\n/**\n * A checkpoint recorded just before a navigating tool reloads the page.\n *\n * The reload destroys the in-memory run loop, so the element persists this\n * marker first; on the next mount it supplies the tool's result and resumes.\n */\nexport interface NavigationCheckpoint {\n /** The tool-call id whose result must be supplied after the reload. */\n readonly toolCallId: string;\n}\n\n/**\n * Client-side persistence seam for the conversation and a pending-navigation\n * checkpoint, keyed by `thread_id`.\n *\n * The default {@link SessionStorageStore} keeps everything per-tab in\n * `sessionStorage`, so the chat survives the full page reloads of a\n * multi-page app. A host may inject a server-backed store instead (e.g. one\n * that rehydrates from a history endpoint); `loadMessages` is therefore\n * async-friendly. The checkpoint methods stay synchronous \u2014 the marker is a\n * tiny local hint a server store can derive from history and no-op.\n */\nexport interface ClientConversationStore {\n /** A stable conversation id, generated and persisted on first read. */\n threadId(): string;\n /** Load the persisted message history, or `null` when none exists. */\n loadMessages(threadId: string): Promise<readonly Message[] | null>;\n /** Persist the message history. */\n saveMessages(threadId: string, messages: readonly Message[]): void;\n /** Load the pending-navigation checkpoint, or `null` when none is set. */\n loadCheckpoint(threadId: string): NavigationCheckpoint | null;\n /** Set the pending-navigation checkpoint, or clear it when given `null`. */\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void;\n /** Forget the conversation and checkpoint (e.g. a \"new chat\" action). */\n clear(threadId: string): void;\n}\n\nconst THREAD_KEY = \"ag-ui-chat:thread\";\nconst MESSAGES_PREFIX = \"ag-ui-chat:messages:\";\nconst CHECKPOINT_PREFIX = \"ag-ui-chat:checkpoint:\";\n\n/**\n * Default {@link ClientConversationStore}: per-tab `sessionStorage`.\n *\n * Survives full page reloads and same-tab navigation, clears on tab close \u2014\n * the right scope for an embedded agent's conversation in a multi-page app.\n * One thread id per tab; the message history and checkpoint are namespaced by\n * it so two tabs hold independent conversations.\n */\nexport class SessionStorageStore implements ClientConversationStore {\n threadId(): string {\n const existing = sessionStorage.getItem(THREAD_KEY);\n if (existing !== null) {\n return existing;\n }\n const id = randomUUID();\n sessionStorage.setItem(THREAD_KEY, id);\n return id;\n }\n\n loadMessages(threadId: string): Promise<readonly Message[] | null> {\n return Promise.resolve(this.#readJson<Message[]>(MESSAGES_PREFIX + threadId));\n }\n\n saveMessages(threadId: string, messages: readonly Message[]): void {\n sessionStorage.setItem(MESSAGES_PREFIX + threadId, JSON.stringify(messages));\n }\n\n loadCheckpoint(threadId: string): NavigationCheckpoint | null {\n return this.#readJson<NavigationCheckpoint>(CHECKPOINT_PREFIX + threadId);\n }\n\n saveCheckpoint(threadId: string, checkpoint: NavigationCheckpoint | null): void {\n const key = CHECKPOINT_PREFIX + threadId;\n if (checkpoint === null) {\n sessionStorage.removeItem(key);\n return;\n }\n sessionStorage.setItem(key, JSON.stringify(checkpoint));\n }\n\n clear(threadId: string): void {\n sessionStorage.removeItem(MESSAGES_PREFIX + threadId);\n sessionStorage.removeItem(CHECKPOINT_PREFIX + threadId);\n sessionStorage.removeItem(THREAD_KEY);\n }\n\n /** Parse a stored JSON value, returning `null` when absent or corrupt. */\n #readJson<T>(key: string): T | null {\n const raw = sessionStorage.getItem(key);\n if (raw === null) {\n return null;\n }\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n }\n}\n", "import { type AbstractAgent, HttpAgent } from \"@ag-ui/client\";\nimport type { Message } from \"@ag-ui/core\";\n\n/** Config for {@link createHttpAgent}. */\nexport interface HttpAgentOptions {\n endpoint: string;\n headers?: Record<string, string>;\n /** Stable conversation id, so the agent's runs share a thread. */\n threadId?: string;\n /** Rehydrated history to seed the agent with (durable conversation). */\n initialMessages?: readonly Message[];\n}\n\n/**\n * Build an AG-UI {@link HttpAgent} pointed at ``endpoint``.\n *\n * This is the default agent factory used by ``<ag-ui-chat>``. Tests and\n * advanced hosts override the element's ``agentFactory`` to inject a\n * different {@link AbstractAgent} (e.g. a fake, or a middleware-wrapped one).\n */\nexport function createHttpAgent(options: HttpAgentOptions): AbstractAgent {\n return new HttpAgent({\n url: options.endpoint,\n headers: options.headers ?? {},\n // HttpAgent invokes its configured fetch as a method (`this.fetch(...)`),\n // which would rebind the global `fetch` to the agent instance and trigger\n // \"Illegal invocation\" in browsers. Wrap it so `fetch` is always called as\n // a free function with the correct receiver.\n fetch: (url, init) => fetch(url, init),\n // Spread conditionally: under `exactOptionalPropertyTypes` an explicit\n // `undefined` is not assignable to these optional config fields.\n ...(options.threadId !== undefined ? { threadId: options.threadId } : {}),\n ...(options.initialMessages !== undefined\n ? { initialMessages: [...options.initialMessages] }\n : {}),\n });\n}\n\n/** Signature of the agent factory the element calls to build its agent. */\nexport type AgentFactory = (options: HttpAgentOptions) => AbstractAgent;\n", "import { X_DESTRUCTIVE_KEY } from \"./constants.js\";\n\n/**\n * Whether a tool's JSON-Schema `parameters` marks it destructive.\n *\n * Reads the `x-destructive` extension stamped by the server (`django-ag-ui`'s\n * `build_input_schema`) or by a host declaring a tool directly.\n */\nexport function isDestructive(parameters: Record<string, unknown>): boolean {\n return parameters[X_DESTRUCTIVE_KEY] === true;\n}\n", "import { X_NAVIGATES_KEY } from \"./constants.js\";\n\n/**\n * Whether a tool's JSON-Schema `parameters` marks it as navigating.\n *\n * Reads the `x-navigates` extension. A navigating tool's handler reloads the\n * page (MPA navigation), so the element checkpoints the call and resumes the\n * run loop after the next page mounts, rather than awaiting a result inline.\n */\nexport function isNavigates(parameters: Record<string, unknown>): boolean {\n return parameters[X_NAVIGATES_KEY] === true;\n}\n", "import type { Context } from \"@ag-ui/core\";\n\n/**\n * A compact snapshot of the current page's actionable surface (field\n * names/types/labels, button labels+handles \u2014 not values). Host-defined shape;\n * kept small because it rides in every `RunAgentInput.context`.\n */\nexport type PageMap = Record<string, unknown>;\n\n/**\n * Build the per-run context entry for the page map.\n *\n * Returns a single `page_map` context item when auto-injection is on and a\n * provider is set, else nothing. Recomputed each run so it reflects the page\n * the agent is currently looking at.\n */\nexport function createPageMapContext(\n getPageMap: (() => PageMap) | null,\n autoInject: boolean,\n): Context[] {\n if (!autoInject || getPageMap === null) {\n return [];\n }\n return [{ description: \"page_map\", value: JSON.stringify(getPageMap()) }];\n}\n", "import type { ClientTool } from \"./client_tool_registry.js\";\nimport { X_NAVIGATES_KEY } from \"./constants.js\";\n\n/** A single navigable route the host declares for the agent. */\nexport interface Route {\n /** Stable id the agent uses with `navigate_to_route`. */\n readonly id: string;\n /** The URL path to navigate to. */\n readonly path: string;\n /** Human label shown to the agent. */\n readonly title?: string;\n /** Optional grouping (e.g. an app or section). */\n readonly group?: string;\n /** Optional longer description of when to use the route. */\n readonly description?: string;\n}\n\n/** The host-declared catalog of navigable routes. */\nexport type RouteMap = readonly Route[];\n\n/** Append `params` to `path` as a query string (no-op when empty). */\nfunction withQuery(path: string, params: Record<string, unknown> | undefined): string {\n if (params === undefined) {\n return path;\n }\n const usp = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n usp.set(key, String(value));\n }\n const query = usp.toString();\n return query === \"\" ? path : `${path}?${query}`;\n}\n\n/**\n * The built-in `route.*` tools, bound to live getters so a host can set\n * `routeMap` / `navigate` before or after mount.\n *\n * `list_routes` is read-only; `navigate_to_route` is marked `x-navigates` so an\n * MPA reload checkpoints + resumes. When the host supplies a `navigate(path)`\n * callback (an SPA), the element routes client-side instead and the run loop\n * simply continues \u2014 see `AgUiChat`'s execute path.\n */\nexport function createRouteTools(\n getRouteMap: () => RouteMap,\n getNavigate: () => ((path: string) => void) | null,\n): ClientTool[] {\n return [\n {\n name: \"list_routes\",\n description: \"List the routes the app can navigate to.\",\n parameters: { type: \"object\", properties: {}, required: [] },\n handler: () => getRouteMap(),\n },\n {\n name: \"navigate_to_route\",\n description: \"Navigate to one of the app's routes by its id.\",\n parameters: {\n type: \"object\",\n properties: {\n route_id: { type: \"string\" },\n params: { type: \"object\" },\n },\n required: [\"route_id\"],\n [X_NAVIGATES_KEY]: true,\n },\n handler: (args) => {\n const routeId = args[\"route_id\"];\n const route = getRouteMap().find((r) => r.id === routeId);\n if (route === undefined) {\n throw new Error(`unknown route \"${String(routeId)}\"`);\n }\n const path = withQuery(route.path, args[\"params\"] as Record<string, unknown> | undefined);\n const navigate = getNavigate();\n if (navigate !== null) {\n navigate(path);\n } else {\n window.location.assign(path);\n }\n return { navigated: true, path };\n },\n },\n ];\n}\n", "import type { ClientTool } from \"./client_tool_registry.js\";\nimport { X_DESTRUCTIVE_KEY } from \"./constants.js\";\n\n/**\n * A binding from a named piece of host application state to agent tools.\n *\n * Ergonomic sugar over `registerTool` for SPA state (Redux/Zustand/signals):\n * generates a read tool and, when `write` is given, a destructive set tool.\n */\nexport interface StateHook {\n /** Base name; tools become `read_<name>` and `set_<name>`. */\n readonly name: string;\n /** Returns the current state value. */\n readonly read: () => unknown;\n /** Mutates the state from the agent-supplied args. Omit for read-only. */\n readonly write?: (args: Record<string, unknown>) => unknown;\n /** JSON-Schema for the set tool's args. Defaults to an open object. */\n readonly schema?: Record<string, unknown>;\n}\n\n/**\n * Build the tools for a {@link StateHook}: always a `read_<name>` (read-only)\n * tool, plus a `set_<name>` (`x-destructive`) tool when `write` is supplied.\n */\nexport function createStateHookTools(hook: StateHook): ClientTool[] {\n const tools: ClientTool[] = [\n {\n name: `read_${hook.name}`,\n description: `Read the \"${hook.name}\" state.`,\n parameters: { type: \"object\", properties: {}, required: [] },\n handler: () => hook.read(),\n },\n ];\n const write = hook.write;\n if (write !== undefined) {\n tools.push({\n name: `set_${hook.name}`,\n description: `Update the \"${hook.name}\" state.`,\n parameters: { ...(hook.schema ?? { type: \"object\" }), [X_DESTRUCTIVE_KEY]: true },\n handler: (args) => write(args),\n });\n }\n return tools;\n}\n", "// Shadow-DOM-scoped styles for the chat shell. Kept as a string constant so\n// the Custom Element can inject it into its shadow root without a build-time\n// CSS pipeline. Scoped by the shadow boundary, so class names stay terse.\n\nexport const STYLES = `\n:host {\n /* Colors */\n --ag-ui-bg: #ffffff;\n --ag-ui-fg: #1a1a2e;\n --ag-ui-accent: #4f46e5;\n --ag-ui-user-bg: #4f46e5;\n --ag-ui-user-fg: #ffffff;\n --ag-ui-assistant-bg: #f1f1f6;\n --ag-ui-input-bg: var(--ag-ui-bg);\n --ag-ui-tool-bg: var(--ag-ui-assistant-bg);\n --ag-ui-tool-fg: var(--ag-ui-accent);\n --ag-ui-header-bg: var(--ag-ui-accent);\n --ag-ui-header-fg: #ffffff;\n --ag-ui-border: #e2e2ec;\n --ag-ui-radius: 12px;\n\n /* Status accents for tool-call cards. */\n --ag-ui-success: #15803d;\n --ag-ui-danger: #b91c1c;\n --ag-ui-muted: #6b7280;\n\n /* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */\n --ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);\n --ag-ui-font: inherit;\n --ag-ui-font-size: 14px;\n\n /* Layout \u2014 override from outside to dock the widget anywhere.\n Set --ag-ui-position: static (and place this element in your own\n grid/flex layout) to embed it in the page flow instead of floating. */\n --ag-ui-position: fixed;\n --ag-ui-z-index: 2147483000;\n --ag-ui-width: 380px;\n --ag-ui-height: 560px;\n --ag-ui-inset: auto 24px 24px auto;\n --ag-ui-max-width: calc(100vw - 48px);\n --ag-ui-max-height: calc(100vh - 48px);\n\n position: var(--ag-ui-position);\n inset: var(--ag-ui-inset);\n z-index: var(--ag-ui-z-index);\n width: var(--ag-ui-width);\n max-width: var(--ag-ui-max-width);\n height: var(--ag-ui-height);\n max-height: var(--ag-ui-max-height);\n display: flex;\n font-family: var(--ag-ui-font);\n font-size: var(--ag-ui-font-size);\n color: var(--ag-ui-fg);\n}\n\n.chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: var(--ag-ui-radius);\n box-shadow: var(--ag-ui-shadow);\n overflow: hidden;\n}\n\n.header {\n padding: 12px 16px;\n font-weight: 600;\n border-bottom: 1px solid var(--ag-ui-border);\n background: var(--ag-ui-header-bg);\n color: var(--ag-ui-header-fg);\n}\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.message {\n max-width: 80%;\n padding: 8px 12px;\n border-radius: 14px;\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.message--user {\n align-self: flex-end;\n background: var(--ag-ui-user-bg);\n color: var(--ag-ui-user-fg);\n border-bottom-right-radius: 4px;\n}\n\n.message--assistant {\n align-self: flex-start;\n background: var(--ag-ui-assistant-bg);\n border-bottom-left-radius: 4px;\n}\n\n.tool-call {\n align-self: flex-start;\n max-width: 80%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--ag-ui-tool-bg);\n border: 1px solid var(--ag-ui-border);\n color: var(--ag-ui-tool-fg);\n}\n\n.tool-call-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.tool-call-name {\n font-weight: 600;\n word-break: break-word;\n}\n\n.tool-call-status {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: rgba(127, 127, 127, 0.16);\n color: var(--ag-ui-muted);\n}\n\n.tool-call[data-status=\"done\"] .tool-call-status {\n color: var(--ag-ui-success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-status {\n color: var(--ag-ui-danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-status {\n color: var(--ag-ui-muted);\n}\n\n.tool-call-args,\n.tool-call-result {\n margin: 0;\n padding: 6px 8px;\n max-height: 160px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--ag-ui-fg);\n}\n\n.tool-call-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-weight: 600;\n color: var(--ag-ui-accent);\n cursor: pointer;\n}\n\n.tool-call-toggle::before {\n content: \"\u25B8 \";\n}\n\n.tool-call-toggle[aria-expanded=\"true\"]::before {\n content: \"\u25BE \";\n}\n\n.input-row {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid var(--ag-ui-border);\n}\n\n.input {\n flex: 1;\n resize: none;\n background: var(--ag-ui-input-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 10px;\n font: inherit;\n color: inherit;\n outline: none;\n}\n\n.input:focus {\n border-color: var(--ag-ui-accent);\n}\n\n.send {\n border: none;\n border-radius: 8px;\n padding: 0 16px;\n background: var(--ag-ui-accent);\n color: #ffffff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.send:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n.modal-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n background: rgba(20, 20, 50, 0.4);\n backdrop-filter: blur(2px);\n}\n\n.modal {\n width: 100%;\n max-width: 320px;\n background: var(--ag-ui-bg);\n border-radius: 12px;\n box-shadow: 0 16px 40px rgba(20, 20, 50, 0.3);\n overflow: hidden;\n}\n\n.modal-title {\n padding: 12px 16px;\n font-weight: 600;\n border-bottom: 1px solid var(--ag-ui-border);\n}\n\n.modal-body {\n padding: 12px 16px 4px;\n}\n\n.modal-args {\n margin: 0 16px 12px;\n padding: 8px 10px;\n max-height: 140px;\n overflow: auto;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n background: var(--ag-ui-assistant-bg);\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.modal-actions {\n display: flex;\n gap: 8px;\n padding: 0 16px 16px;\n justify-content: flex-end;\n}\n\n.modal-btn {\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--ag-ui-bg);\n color: var(--ag-ui-fg);\n}\n\n.modal-btn--confirm {\n border-color: var(--ag-ui-accent);\n background: var(--ag-ui-accent);\n color: #ffffff;\n}\n`;\n", "import { TOOL_CALL_STATUS } from \"./constants.js\";\n\n/** Any state a tool-call card can be in. */\nexport type ToolCallStatus = (typeof TOOL_CALL_STATUS)[keyof typeof TOOL_CALL_STATUS];\n\n/** The terminal states a card settles into (everything but `pending`). */\nexport type SettledStatus = Exclude<ToolCallStatus, typeof TOOL_CALL_STATUS.PENDING>;\n\n/** Short pill text shown for each status. */\nconst STATUS_LABEL: Record<ToolCallStatus, string> = {\n [TOOL_CALL_STATUS.PENDING]: \"running\u2026\",\n [TOOL_CALL_STATUS.DONE]: \"\u2713 done\",\n [TOOL_CALL_STATUS.ERROR]: \"\u26A0 error\",\n [TOOL_CALL_STATUS.DECLINED]: \"\u2298 declined\",\n};\n\n/** Toggle-button label for each settled outcome's collapsible body. */\nconst RESULT_LABEL: Record<SettledStatus, string> = {\n [TOOL_CALL_STATUS.DONE]: \"Result\",\n [TOOL_CALL_STATUS.ERROR]: \"Error\",\n [TOOL_CALL_STATUS.DECLINED]: \"Declined\",\n};\n\n/**\n * A live tool-call card for the chat transcript.\n *\n * Construction renders the tool name, its pretty-printed arguments, and a\n * `running\u2026` status pill. {@link settle} later flips the pill to the outcome\n * and appends a click-to-expand body holding the result (or error / decline\n * message), collapsed by default.\n *\n * Pure DOM (no framework); the host appends {@link element} into its shadow\n * root and themes it via the `--ag-ui-*` custom properties.\n */\nexport class ToolCallCard {\n /** The card's root element; append this into the message list. */\n readonly element: HTMLDivElement;\n\n readonly #status: HTMLSpanElement;\n\n constructor(name: string, args: Record<string, unknown>) {\n this.element = document.createElement(\"div\");\n this.element.className = \"tool-call\";\n this.element.setAttribute(\"data-tool-name\", name);\n this.element.setAttribute(\"data-status\", TOOL_CALL_STATUS.PENDING);\n\n const head = document.createElement(\"div\");\n head.className = \"tool-call-head\";\n\n const label = document.createElement(\"span\");\n label.className = \"tool-call-name\";\n label.textContent = `\uD83D\uDD27 ${name}`;\n\n this.#status = document.createElement(\"span\");\n this.#status.className = \"tool-call-status\";\n this.#status.textContent = STATUS_LABEL[TOOL_CALL_STATUS.PENDING];\n\n head.append(label, this.#status);\n\n const argsEl = document.createElement(\"pre\");\n argsEl.className = \"tool-call-args\";\n argsEl.textContent = JSON.stringify(args, null, 2);\n\n this.element.append(head, argsEl);\n }\n\n /**\n * Flip the status pill to ``status`` and append a collapsed body holding\n * ``text`` (the JSON result, an error message, a decline notice, or a\n * server-executed note) behind a click-to-expand toggle.\n */\n settle(status: SettledStatus, text: string): void {\n this.element.setAttribute(\"data-status\", status);\n this.#status.textContent = STATUS_LABEL[status];\n\n const toggle = document.createElement(\"button\");\n toggle.type = \"button\";\n toggle.className = \"tool-call-toggle\";\n toggle.setAttribute(\"aria-expanded\", \"false\");\n toggle.textContent = RESULT_LABEL[status];\n\n const output = document.createElement(\"pre\");\n output.className = \"tool-call-result\";\n output.textContent = text;\n output.hidden = true;\n\n toggle.addEventListener(\"click\", () => {\n const expand = output.hidden;\n output.hidden = !expand;\n toggle.setAttribute(\"aria-expanded\", String(expand));\n });\n\n this.element.append(toggle, output);\n }\n}\n", "import type { Context, Message, Tool } from \"@ag-ui/core\";\nimport {\n AgUiClient,\n type AgUiClientHandlers,\n type AgUiToolCall,\n type ToolExecution,\n} from \"./agui_client.js\";\nimport { type ClientTool, ClientToolRegistry } from \"./client_tool_registry.js\";\nimport { requestConfirmation } from \"./confirmation_modal.js\";\nimport { MESSAGE_ROLE, SUBMIT_EVENT, TOOL_CALL_STATUS } from \"./constants.js\";\nimport {\n type ClientConversationStore,\n type NavigationCheckpoint,\n SessionStorageStore,\n} from \"./conversation_store.js\";\nimport { type AgentFactory, createHttpAgent } from \"./create_http_agent.js\";\nimport { isDestructive } from \"./is_destructive.js\";\nimport { isNavigates } from \"./is_navigates.js\";\nimport { createPageMapContext, type PageMap } from \"./page_map.js\";\nimport { createRouteTools, type RouteMap } from \"./route_map.js\";\nimport { createStateHookTools, type StateHook } from \"./state_hook.js\";\nimport { STYLES } from \"./styles.js\";\nimport { ToolCallCard } from \"./tool_call_card.js\";\n\n/** The role a rendered chat message takes. */\nexport type MessageRole = (typeof MESSAGE_ROLE)[keyof typeof MESSAGE_ROLE];\n\n/** `detail` shape of the {@link SUBMIT_EVENT} CustomEvent. */\nexport interface SubmitDetail {\n readonly content: string;\n}\n\n/**\n * `<ag-ui-chat>` \u2014 a framework-free chat sidebar Web Component over AG-UI.\n *\n * Owns the Shadow DOM shell (header, scrolling message list, input row),\n * builds an {@link AgUiClient} on first send (via the overridable\n * {@link agentFactory}), and renders streaming assistant text plus tool-call\n * activity. Emits a {@link SUBMIT_EVENT} for host visibility.\n *\n * The per-run frontend tool catalog and context are supplied by\n * {@link getTools} / {@link getContext}, which later phases (the tool\n * registry, DOM driver) populate.\n */\nexport class AgUiChat extends HTMLElement {\n /** Agent factory; override to inject a custom or fake agent (tests). */\n agentFactory: AgentFactory = createHttpAgent;\n\n /** Extra HTTP headers for the AG-UI endpoint (e.g. CSRF). */\n headers: Record<string, string> = {};\n\n /** When true, destructive tools execute without a confirmation modal. */\n autoConfirm = false;\n\n /**\n * Per-run frontend tool catalog provider. Defaults to the built-in\n * `route.*` tools (when a {@link routeMap} is set) plus the tools registered\n * via {@link registerTool} / {@link registerStateHook}; override to supply a\n * fully custom catalog.\n */\n getTools: () => Tool[] = () => [\n ...this.#routeTools().map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n ...this.#toolRegistry.tools(),\n ];\n\n /**\n * Per-run context provider. Defaults to the compact page map (when a\n * {@link getPageMap} provider is set and {@link autoInjectPageMap} is on).\n */\n getContext: () => Context[] = () => createPageMapContext(this.getPageMap, this.autoInjectPageMap);\n\n /**\n * Navigable routes the agent can jump to via the built-in `route.*` tools.\n * A compact summary also rides in each run's context.\n */\n routeMap: RouteMap = [];\n\n /**\n * Optional client-side router. When set (an SPA), `navigate_to_route` routes\n * in-page and the run loop continues; when unset (an MPA like the admin), it\n * falls back to `window.location` and the resumable-loop machinery applies.\n */\n navigate: ((path: string) => void) | null = null;\n\n /** Provider for the per-run page map; see {@link getContext}. */\n getPageMap: (() => PageMap) | null = null;\n\n /** Whether to auto-inject the page map into context each run. */\n autoInjectPageMap = true;\n\n /**\n * Persistence for the conversation + navigation checkpoint. Defaults to\n * per-tab `sessionStorage` so the chat survives full page reloads; inject a\n * server-backed store for cross-tab/device durability.\n */\n conversationStore: ClientConversationStore = new SessionStorageStore();\n\n /**\n * Builds the tool result a navigating tool resumes with after the page\n * reloads. Defaults to the landed URL; a host (e.g. the admin package) can\n * override to include a page snapshot or post-reload validation errors.\n */\n navigationResult: (checkpoint: NavigationCheckpoint) => unknown = () => ({\n navigated: true,\n url: window.location.href,\n });\n\n readonly #toolRegistry = new ClientToolRegistry();\n /** Tool-call cards awaiting execution, keyed by call id. */\n readonly #toolCards = new Map<string, ToolCallCard>();\n readonly #root: ShadowRoot;\n readonly #chat: HTMLDivElement;\n readonly #messages: HTMLDivElement;\n readonly #input: HTMLTextAreaElement;\n readonly #send: HTMLButtonElement;\n\n #client: AgUiClient | null = null;\n #streamingBubble: HTMLDivElement | null = null;\n #threadId = \"\";\n #initialMessages: readonly Message[] = [];\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: \"open\" });\n this.#chat = document.createElement(\"div\");\n this.#messages = document.createElement(\"div\");\n this.#input = document.createElement(\"textarea\");\n this.#send = document.createElement(\"button\");\n }\n\n /** Declare a frontend tool the agent may call. */\n registerTool(tool: ClientTool): void {\n this.#toolRegistry.register(tool);\n }\n\n /** Bind a piece of host state to `read_<name>` / `set_<name>` tools. */\n registerStateHook(hook: StateHook): void {\n for (const tool of createStateHookTools(hook)) {\n this.#toolRegistry.register(tool);\n }\n }\n\n /** The built-in `route.*` tools, present only when a route map is set. */\n #routeTools(): ClientTool[] {\n if (this.routeMap.length === 0) {\n return [];\n }\n return createRouteTools(\n () => this.routeMap,\n () => this.navigate,\n );\n }\n\n /** Resolve a tool by name: built-in route tools first, then the registry. */\n #resolveTool(name: string): ClientTool | null {\n const route = this.#routeTools().find((t) => t.name === name);\n if (route !== undefined) {\n return route;\n }\n return this.#toolRegistry.has(name) ? this.#toolRegistry.get(name) : null;\n }\n\n /** The AG-UI endpoint URL, read from the `endpoint` attribute. */\n get endpoint(): string {\n return this.getAttribute(\"endpoint\") ?? \"\";\n }\n\n connectedCallback(): void {\n this.#render();\n this.#threadId = this.conversationStore.threadId();\n void this.#rehydrate();\n }\n\n /**\n * Restore the conversation from the store on mount, then \u2014 if a navigating\n * tool reloaded the page mid-run \u2014 resume the loop by supplying that tool's\n * result from the page we landed on.\n */\n async #rehydrate(): Promise<void> {\n const messages = await this.conversationStore.loadMessages(this.#threadId);\n if (messages !== null) {\n this.#initialMessages = messages;\n for (const message of messages) {\n this.#renderHistoricMessage(message);\n }\n }\n const checkpoint = this.conversationStore.loadCheckpoint(this.#threadId);\n if (checkpoint !== null) {\n await this.#resumeFrom(checkpoint);\n }\n }\n\n /** Render a restored message as a chat bubble (text turns only). */\n #renderHistoricMessage(message: Message): void {\n if (typeof message.content !== \"string\" || message.content === \"\") {\n return;\n }\n if (message.role === MESSAGE_ROLE.USER) {\n this.appendMessage(MESSAGE_ROLE.USER, message.content);\n } else if (message.role === MESSAGE_ROLE.ASSISTANT) {\n this.appendMessage(MESSAGE_ROLE.ASSISTANT, message.content);\n }\n }\n\n /** Complete the checkpointed navigating tool call and continue the run. */\n async #resumeFrom(checkpoint: NavigationCheckpoint): Promise<void> {\n this.conversationStore.saveCheckpoint(this.#threadId, null);\n const client = this.#ensureClient();\n client.addToolResult(checkpoint.toolCallId, JSON.stringify(this.navigationResult(checkpoint)));\n await client.resume();\n }\n\n /** Append a message bubble and return it. */\n appendMessage(role: MessageRole, content: string): HTMLDivElement {\n const bubble = document.createElement(\"div\");\n bubble.className = `message message--${role}`;\n bubble.textContent = content;\n this.#messages.appendChild(bubble);\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return bubble;\n }\n\n #render(): void {\n const style = document.createElement(\"style\");\n style.textContent = STYLES;\n\n this.#chat.className = \"chat\";\n\n const header = document.createElement(\"div\");\n header.className = \"header\";\n header.textContent = this.getAttribute(\"title-text\") ?? \"Assistant\";\n\n this.#messages.className = \"messages\";\n\n const inputRow = document.createElement(\"div\");\n inputRow.className = \"input-row\";\n\n this.#input.className = \"input\";\n this.#input.rows = 2;\n this.#input.placeholder = \"Ask anything\u2026\";\n this.#input.addEventListener(\"keydown\", (event) => this.#onKeydown(event));\n\n this.#send.className = \"send\";\n this.#send.type = \"button\";\n this.#send.textContent = \"Send\";\n this.#send.addEventListener(\"click\", () => {\n void this.#submit();\n });\n\n inputRow.append(this.#input, this.#send);\n this.#chat.append(header, this.#messages, inputRow);\n this.#root.append(style, this.#chat);\n }\n\n #onKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n void this.#submit();\n }\n }\n\n async #submit(): Promise<void> {\n const content = this.#input.value.trim();\n if (content === \"\") {\n return;\n }\n this.appendMessage(MESSAGE_ROLE.USER, content);\n this.#input.value = \"\";\n this.dispatchEvent(\n new CustomEvent<SubmitDetail>(SUBMIT_EVENT, {\n detail: { content },\n bubbles: true,\n composed: true,\n }),\n );\n await this.#client_send(content);\n }\n\n async #client_send(content: string): Promise<void> {\n if (this.endpoint === \"\") {\n return;\n }\n await this.#ensureClient().send(content);\n }\n\n #ensureClient(): AgUiClient {\n if (this.#client === null) {\n const agent = this.agentFactory({\n endpoint: this.endpoint,\n headers: this.headers,\n threadId: this.#threadId,\n initialMessages: this.#initialMessages,\n });\n this.#client = new AgUiClient({\n agent,\n handlers: this.#handlers(),\n getTools: () => this.getTools(),\n getContext: () => this.getContext(),\n executeTool: (call) => this.#executeTool(call),\n onPersist: (messages) => this.conversationStore.saveMessages(this.#threadId, messages),\n });\n }\n return this.#client;\n }\n\n async #executeTool(call: AgUiToolCall): Promise<ToolExecution | null> {\n const card = this.#cardFor(call);\n this.#toolCards.delete(call.id);\n const tool = this.#resolveTool(call.name);\n if (tool === null) {\n // A server-side tool the server already executed \u2014 not ours to re-run.\n card.settle(TOOL_CALL_STATUS.DONE, \"Executed on the server.\");\n return null;\n }\n if (isDestructive(tool.parameters) && !this.autoConfirm) {\n const accepted = await requestConfirmation(this.#chat, {\n toolName: call.name,\n args: call.args,\n });\n if (!accepted) {\n const message = \"User declined the action.\";\n card.settle(TOOL_CALL_STATUS.DECLINED, message);\n return { content: message };\n }\n }\n // A navigating tool reloads only without a client-side router; with a\n // host `navigate()` (SPA) it routes in-page and the loop just continues.\n const navigates = isNavigates(tool.parameters) && this.navigate === null;\n if (navigates) {\n // Checkpoint before the handler reloads the page; the history (incl.\n // this tool call) was already persisted when the run that produced it\n // settled. The result is supplied on the next mount via the resume path.\n this.conversationStore.saveCheckpoint(this.#threadId, { toolCallId: call.id });\n }\n try {\n const result = await tool.handler(call.args);\n if (navigates) {\n card.settle(TOOL_CALL_STATUS.DONE, \"Navigating\u2026\");\n return { content: \"\", halt: true };\n }\n const content = JSON.stringify(result ?? null);\n card.settle(TOOL_CALL_STATUS.DONE, content);\n return { content };\n } catch (error) {\n if (navigates) {\n // The navigation never happened; drop the dangling checkpoint.\n this.conversationStore.saveCheckpoint(this.#threadId, null);\n }\n const message = error instanceof Error ? error.message : String(error);\n card.settle(TOOL_CALL_STATUS.ERROR, message);\n return { content: `Error: ${message}`, error: message };\n }\n }\n\n #handlers(): AgUiClientHandlers {\n return {\n onRunStart: () => {\n this.#send.disabled = true;\n },\n onTextDelta: (buffer) => {\n this.#streamInto(buffer);\n },\n onTextEnd: (buffer) => {\n this.#streamInto(buffer);\n this.#streamingBubble = null;\n },\n onToolCall: (call) => {\n this.#cardFor(call);\n },\n onRunEnd: () => {\n this.#send.disabled = false;\n this.#streamingBubble = null;\n },\n onError: (message) => {\n this.appendMessage(MESSAGE_ROLE.ASSISTANT, `\u26A0\uFE0F ${message}`);\n this.#send.disabled = false;\n this.#streamingBubble = null;\n },\n };\n }\n\n #streamInto(buffer: string): void {\n if (this.#streamingBubble === null) {\n this.#streamingBubble = this.appendMessage(MESSAGE_ROLE.ASSISTANT, \"\");\n }\n this.#streamingBubble.textContent = buffer;\n this.#messages.scrollTop = this.#messages.scrollHeight;\n }\n\n /**\n * The card for ``call``, creating and appending it on first sight.\n *\n * {@link AgUiClientHandlers.onToolCall} creates the card (pending) during the\n * run; {@link #executeTool} later retrieves the same card to settle it.\n */\n #cardFor(call: AgUiToolCall): ToolCallCard {\n const existing = this.#toolCards.get(call.id);\n if (existing !== undefined) {\n return existing;\n }\n const card = new ToolCallCard(call.name, call.args);\n this.#toolCards.set(call.id, card);\n this.#messages.appendChild(card.element);\n this.#messages.scrollTop = this.#messages.scrollHeight;\n return card;\n }\n}\n", "/**\n * Visible-action animation primitives.\n *\n * These run against the **host page** DOM (not the element's shadow root) so a\n * user watches the agent type, highlight, and click at human-readable speed.\n * Each is configurable; pass small/zero durations in tests (or use fake timers).\n */\n\nconst ACCENT = \"#4f46e5\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\n/** An element whose `value` can be typed into. */\nexport type TextLikeElement = HTMLInputElement | HTMLTextAreaElement;\n\nexport interface TypeOptions {\n /** Milliseconds between characters. Default 35. */\n charDelayMs?: number;\n}\n\n/**\n * Clear ``el`` and type ``value`` one character at a time, firing ``input``\n * events as a real user would, then a final ``change`` event.\n */\nexport async function typeInto(\n el: TextLikeElement,\n value: string,\n options: TypeOptions = {},\n): Promise<void> {\n const charDelayMs = options.charDelayMs ?? 35;\n el.value = \"\";\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n for (const char of value) {\n el.value += char;\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n if (charDelayMs > 0) {\n await delay(charDelayMs);\n }\n }\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\nexport interface HighlightClickOptions {\n /** Milliseconds to hold the highlight before clicking. Default 280. */\n highlightMs?: number;\n}\n\n/** Outline ``el``, pause so the user sees it, then click and restore. */\nexport async function highlightThenClick(\n el: HTMLElement,\n options: HighlightClickOptions = {},\n): Promise<void> {\n const highlightMs = options.highlightMs ?? 280;\n const previousOutline = el.style.outline;\n const previousOffset = el.style.outlineOffset;\n el.style.outline = `2px solid ${ACCENT}`;\n el.style.outlineOffset = \"2px\";\n await delay(highlightMs);\n el.style.outline = previousOutline;\n el.style.outlineOffset = previousOffset;\n el.click();\n}\n\n/** Scroll ``el`` to the vertical centre of the viewport. */\nexport function scrollIntoCenterView(el: HTMLElement): void {\n el.scrollIntoView({ block: \"center\", inline: \"nearest\", behavior: \"smooth\" });\n}\n\nexport interface FlashOptions {\n /** Milliseconds to hold the focus flash. Default 200. */\n flashMs?: number;\n}\n\n/** Focus ``el`` and briefly flash a ring around it. */\nexport async function focusWithFlash(el: HTMLElement, options: FlashOptions = {}): Promise<void> {\n const flashMs = options.flashMs ?? 200;\n el.focus();\n const previousShadow = el.style.boxShadow;\n el.style.boxShadow = `0 0 0 3px rgba(79, 70, 229, 0.4)`;\n await delay(flashMs);\n el.style.boxShadow = previousShadow;\n}\n", "import { AgUiChat } from \"./ag_ui_chat.js\";\nimport { ELEMENT_TAG } from \"./constants.js\";\n\n/**\n * Register the `<ag-ui-chat>` Custom Element.\n *\n * Idempotent: calling it more than once (or after another module already\n * registered the tag) is a no-op. Registration is an explicit step rather\n * than an import side effect so the package is SSR-safe and tree-shakeable.\n */\nexport function defineAgUiChat(): void {\n if (customElements.get(ELEMENT_TAG) === undefined) {\n customElements.define(ELEMENT_TAG, AgUiChat);\n }\n}\n", "import {\n focusWithFlash,\n type HighlightClickOptions,\n highlightThenClick,\n scrollIntoCenterView,\n type TextLikeElement,\n type TypeOptions,\n typeInto,\n} from \"./animations.js\";\n\n/**\n * Generic, framework-free DOM-driving primitives.\n *\n * Each operates on an element the caller has already located. Host packages\n * (e.g. `django-admin-agent`) wrap these with environment-aware lookups \u2014\n * `fill_field(name, value)` finds `#id_<name>` then calls {@link fillField}.\n */\n\nexport interface FillFieldOptions extends TypeOptions, FlashOptionsLike {}\n\ninterface FlashOptionsLike {\n flashMs?: number;\n}\n\n/** Scroll to, focus (with a flash), and type ``value`` into a text field. */\nexport async function fillField(\n el: TextLikeElement,\n value: string,\n options: FillFieldOptions = {},\n): Promise<void> {\n scrollIntoCenterView(el);\n await focusWithFlash(el, { flashMs: options.flashMs ?? 0 });\n await typeInto(el, value, options);\n}\n\n/** Scroll to, highlight, and click an element. */\nexport async function clickElement(\n el: HTMLElement,\n options: HighlightClickOptions = {},\n): Promise<void> {\n scrollIntoCenterView(el);\n await highlightThenClick(el, options);\n}\n\n/**\n * Set a `<select>` or checkbox value without typing animation, dispatching the\n * ``input`` and ``change`` events frameworks listen for.\n */\nexport function setControlValue(\n el: HTMLInputElement | HTMLSelectElement,\n value: string | boolean,\n): void {\n if (el instanceof HTMLInputElement && el.type === \"checkbox\") {\n el.checked = Boolean(value);\n } else {\n el.value = String(value);\n }\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n", "export const VERSION: string = \"0.1.0\";\n"],
|
|
5
|
+
"mappings": "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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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",
|
|
6
|
+
"names": ["randomUUID"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a tool's JSON-Schema `parameters` marks it destructive.
|
|
3
|
+
*
|
|
4
|
+
* Reads the `x-destructive` extension stamped by the server (`django-ag-ui`'s
|
|
5
|
+
* `build_input_schema`) or by a host declaring a tool directly.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isDestructive(parameters: Record<string, unknown>): boolean;
|
|
8
|
+
//# sourceMappingURL=is_destructive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is_destructive.d.ts","sourceRoot":"","sources":["../src/is_destructive.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAE1E"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a tool's JSON-Schema `parameters` marks it as navigating.
|
|
3
|
+
*
|
|
4
|
+
* Reads the `x-navigates` extension. A navigating tool's handler reloads the
|
|
5
|
+
* page (MPA navigation), so the element checkpoints the call and resumes the
|
|
6
|
+
* run loop after the next page mounts, rather than awaiting a result inline.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isNavigates(parameters: Record<string, unknown>): boolean;
|
|
9
|
+
//# sourceMappingURL=is_navigates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is_navigates.d.ts","sourceRoot":"","sources":["../src/is_navigates.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAExE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Context } from "@ag-ui/core";
|
|
2
|
+
/**
|
|
3
|
+
* A compact snapshot of the current page's actionable surface (field
|
|
4
|
+
* names/types/labels, button labels+handles — not values). Host-defined shape;
|
|
5
|
+
* kept small because it rides in every `RunAgentInput.context`.
|
|
6
|
+
*/
|
|
7
|
+
export type PageMap = Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Build the per-run context entry for the page map.
|
|
10
|
+
*
|
|
11
|
+
* Returns a single `page_map` context item when auto-injection is on and a
|
|
12
|
+
* provider is set, else nothing. Recomputed each run so it reflects the page
|
|
13
|
+
* the agent is currently looking at.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createPageMapContext(getPageMap: (() => PageMap) | null, autoInject: boolean): Context[];
|
|
16
|
+
//# sourceMappingURL=page_map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page_map.d.ts","sourceRoot":"","sources":["../src/page_map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,IAAI,EAClC,UAAU,EAAE,OAAO,GAClB,OAAO,EAAE,CAKX"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ClientTool } from "./client_tool_registry.js";
|
|
2
|
+
/** A single navigable route the host declares for the agent. */
|
|
3
|
+
export interface Route {
|
|
4
|
+
/** Stable id the agent uses with `navigate_to_route`. */
|
|
5
|
+
readonly id: string;
|
|
6
|
+
/** The URL path to navigate to. */
|
|
7
|
+
readonly path: string;
|
|
8
|
+
/** Human label shown to the agent. */
|
|
9
|
+
readonly title?: string;
|
|
10
|
+
/** Optional grouping (e.g. an app or section). */
|
|
11
|
+
readonly group?: string;
|
|
12
|
+
/** Optional longer description of when to use the route. */
|
|
13
|
+
readonly description?: string;
|
|
14
|
+
}
|
|
15
|
+
/** The host-declared catalog of navigable routes. */
|
|
16
|
+
export type RouteMap = readonly Route[];
|
|
17
|
+
/**
|
|
18
|
+
* The built-in `route.*` tools, bound to live getters so a host can set
|
|
19
|
+
* `routeMap` / `navigate` before or after mount.
|
|
20
|
+
*
|
|
21
|
+
* `list_routes` is read-only; `navigate_to_route` is marked `x-navigates` so an
|
|
22
|
+
* MPA reload checkpoints + resumes. When the host supplies a `navigate(path)`
|
|
23
|
+
* callback (an SPA), the element routes client-side instead and the run loop
|
|
24
|
+
* simply continues — see `AgUiChat`'s execute path.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createRouteTools(getRouteMap: () => RouteMap, getNavigate: () => ((path: string) => void) | null): ClientTool[];
|
|
27
|
+
//# sourceMappingURL=route_map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route_map.d.ts","sourceRoot":"","sources":["../src/route_map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG5D,gEAAgE;AAChE,MAAM,WAAW,KAAK;IACpB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qDAAqD;AACrD,MAAM,MAAM,QAAQ,GAAG,SAAS,KAAK,EAAE,CAAC;AAexC;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,QAAQ,EAC3B,WAAW,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,GACjD,UAAU,EAAE,CAqCd"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ClientTool } from "./client_tool_registry.js";
|
|
2
|
+
/**
|
|
3
|
+
* A binding from a named piece of host application state to agent tools.
|
|
4
|
+
*
|
|
5
|
+
* Ergonomic sugar over `registerTool` for SPA state (Redux/Zustand/signals):
|
|
6
|
+
* generates a read tool and, when `write` is given, a destructive set tool.
|
|
7
|
+
*/
|
|
8
|
+
export interface StateHook {
|
|
9
|
+
/** Base name; tools become `read_<name>` and `set_<name>`. */
|
|
10
|
+
readonly name: string;
|
|
11
|
+
/** Returns the current state value. */
|
|
12
|
+
readonly read: () => unknown;
|
|
13
|
+
/** Mutates the state from the agent-supplied args. Omit for read-only. */
|
|
14
|
+
readonly write?: (args: Record<string, unknown>) => unknown;
|
|
15
|
+
/** JSON-Schema for the set tool's args. Defaults to an open object. */
|
|
16
|
+
readonly schema?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the tools for a {@link StateHook}: always a `read_<name>` (read-only)
|
|
20
|
+
* tool, plus a `set_<name>` (`x-destructive`) tool when `write` is supplied.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createStateHookTools(hook: StateHook): ClientTool[];
|
|
23
|
+
//# sourceMappingURL=state_hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state_hook.d.ts","sourceRoot":"","sources":["../src/state_hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG5D;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IAC5D,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,EAAE,CAmBlE"}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const STYLES = "\n:host {\n /* Colors */\n --ag-ui-bg: #ffffff;\n --ag-ui-fg: #1a1a2e;\n --ag-ui-accent: #4f46e5;\n --ag-ui-user-bg: #4f46e5;\n --ag-ui-user-fg: #ffffff;\n --ag-ui-assistant-bg: #f1f1f6;\n --ag-ui-input-bg: var(--ag-ui-bg);\n --ag-ui-tool-bg: var(--ag-ui-assistant-bg);\n --ag-ui-tool-fg: var(--ag-ui-accent);\n --ag-ui-header-bg: var(--ag-ui-accent);\n --ag-ui-header-fg: #ffffff;\n --ag-ui-border: #e2e2ec;\n --ag-ui-radius: 12px;\n\n /* Status accents for tool-call cards. */\n --ag-ui-success: #15803d;\n --ag-ui-danger: #b91c1c;\n --ag-ui-muted: #6b7280;\n\n /* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */\n --ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);\n --ag-ui-font: inherit;\n --ag-ui-font-size: 14px;\n\n /* Layout \u2014 override from outside to dock the widget anywhere.\n Set --ag-ui-position: static (and place this element in your own\n grid/flex layout) to embed it in the page flow instead of floating. */\n --ag-ui-position: fixed;\n --ag-ui-z-index: 2147483000;\n --ag-ui-width: 380px;\n --ag-ui-height: 560px;\n --ag-ui-inset: auto 24px 24px auto;\n --ag-ui-max-width: calc(100vw - 48px);\n --ag-ui-max-height: calc(100vh - 48px);\n\n position: var(--ag-ui-position);\n inset: var(--ag-ui-inset);\n z-index: var(--ag-ui-z-index);\n width: var(--ag-ui-width);\n max-width: var(--ag-ui-max-width);\n height: var(--ag-ui-height);\n max-height: var(--ag-ui-max-height);\n display: flex;\n font-family: var(--ag-ui-font);\n font-size: var(--ag-ui-font-size);\n color: var(--ag-ui-fg);\n}\n\n.chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: var(--ag-ui-radius);\n box-shadow: var(--ag-ui-shadow);\n overflow: hidden;\n}\n\n.header {\n padding: 12px 16px;\n font-weight: 600;\n border-bottom: 1px solid var(--ag-ui-border);\n background: var(--ag-ui-header-bg);\n color: var(--ag-ui-header-fg);\n}\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.message {\n max-width: 80%;\n padding: 8px 12px;\n border-radius: 14px;\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.message--user {\n align-self: flex-end;\n background: var(--ag-ui-user-bg);\n color: var(--ag-ui-user-fg);\n border-bottom-right-radius: 4px;\n}\n\n.message--assistant {\n align-self: flex-start;\n background: var(--ag-ui-assistant-bg);\n border-bottom-left-radius: 4px;\n}\n\n.tool-call {\n align-self: flex-start;\n max-width: 80%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--ag-ui-tool-bg);\n border: 1px solid var(--ag-ui-border);\n color: var(--ag-ui-tool-fg);\n}\n\n.tool-call-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.tool-call-name {\n font-weight: 600;\n word-break: break-word;\n}\n\n.tool-call-status {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: rgba(127, 127, 127, 0.16);\n color: var(--ag-ui-muted);\n}\n\n.tool-call[data-status=\"done\"] .tool-call-status {\n color: var(--ag-ui-success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-status {\n color: var(--ag-ui-danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-status {\n color: var(--ag-ui-muted);\n}\n\n.tool-call-args,\n.tool-call-result {\n margin: 0;\n padding: 6px 8px;\n max-height: 160px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--ag-ui-fg);\n}\n\n.tool-call-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-weight: 600;\n color: var(--ag-ui-accent);\n cursor: pointer;\n}\n\n.tool-call-toggle::before {\n content: \"\u25B8 \";\n}\n\n.tool-call-toggle[aria-expanded=\"true\"]::before {\n content: \"\u25BE \";\n}\n\n.input-row {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid var(--ag-ui-border);\n}\n\n.input {\n flex: 1;\n resize: none;\n background: var(--ag-ui-input-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 10px;\n font: inherit;\n color: inherit;\n outline: none;\n}\n\n.input:focus {\n border-color: var(--ag-ui-accent);\n}\n\n.send {\n border: none;\n border-radius: 8px;\n padding: 0 16px;\n background: var(--ag-ui-accent);\n color: #ffffff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.send:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n.modal-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 16px;\n background: rgba(20, 20, 50, 0.4);\n backdrop-filter: blur(2px);\n}\n\n.modal {\n width: 100%;\n max-width: 320px;\n background: var(--ag-ui-bg);\n border-radius: 12px;\n box-shadow: 0 16px 40px rgba(20, 20, 50, 0.3);\n overflow: hidden;\n}\n\n.modal-title {\n padding: 12px 16px;\n font-weight: 600;\n border-bottom: 1px solid var(--ag-ui-border);\n}\n\n.modal-body {\n padding: 12px 16px 4px;\n}\n\n.modal-args {\n margin: 0 16px 12px;\n padding: 8px 10px;\n max-height: 140px;\n overflow: auto;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n background: var(--ag-ui-assistant-bg);\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.modal-actions {\n display: flex;\n gap: 8px;\n padding: 0 16px 16px;\n justify-content: flex-end;\n}\n\n.modal-btn {\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--ag-ui-bg);\n color: var(--ag-ui-fg);\n}\n\n.modal-btn--confirm {\n border-color: var(--ag-ui-accent);\n background: var(--ag-ui-accent);\n color: #ffffff;\n}\n";
|
|
2
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM,6nMAmSlB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TOOL_CALL_STATUS } from "./constants.js";
|
|
2
|
+
/** Any state a tool-call card can be in. */
|
|
3
|
+
export type ToolCallStatus = (typeof TOOL_CALL_STATUS)[keyof typeof TOOL_CALL_STATUS];
|
|
4
|
+
/** The terminal states a card settles into (everything but `pending`). */
|
|
5
|
+
export type SettledStatus = Exclude<ToolCallStatus, typeof TOOL_CALL_STATUS.PENDING>;
|
|
6
|
+
/**
|
|
7
|
+
* A live tool-call card for the chat transcript.
|
|
8
|
+
*
|
|
9
|
+
* Construction renders the tool name, its pretty-printed arguments, and a
|
|
10
|
+
* `running…` status pill. {@link settle} later flips the pill to the outcome
|
|
11
|
+
* and appends a click-to-expand body holding the result (or error / decline
|
|
12
|
+
* message), collapsed by default.
|
|
13
|
+
*
|
|
14
|
+
* Pure DOM (no framework); the host appends {@link element} into its shadow
|
|
15
|
+
* root and themes it via the `--ag-ui-*` custom properties.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ToolCallCard {
|
|
18
|
+
#private;
|
|
19
|
+
/** The card's root element; append this into the message list. */
|
|
20
|
+
readonly element: HTMLDivElement;
|
|
21
|
+
constructor(name: string, args: Record<string, unknown>);
|
|
22
|
+
/**
|
|
23
|
+
* Flip the status pill to ``status`` and append a collapsed body holding
|
|
24
|
+
* ``text`` (the JSON result, an error message, a decline notice, or a
|
|
25
|
+
* server-executed note) behind a click-to-expand toggle.
|
|
26
|
+
*/
|
|
27
|
+
settle(status: SettledStatus, text: string): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=tool_call_card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool_call_card.d.ts","sourceRoot":"","sources":["../src/tool_call_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAEtF,0EAA0E;AAC1E,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAiBrF;;;;;;;;;;GAUG;AACH,qBAAa,YAAY;;IACvB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;gBAIrB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA0BvD;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAuBlD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@artooi/ag-ui-web-component",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework-free <ag-ui-chat> Web Component over the AG-UI protocol. Drop-in chat sidebar with a pluggable client-side tool registry, DOM driver primitives, animations, and destructive-action confirmation modal.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./bundle": {
|
|
15
|
+
"import": "./dist/ag-ui-web-component.bundle.js"
|
|
16
|
+
},
|
|
17
|
+
"./style.css": "./dist/ag-ui-web-component.bundle.css"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist/",
|
|
21
|
+
"src/",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"CHANGELOG.md"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"ag-ui",
|
|
28
|
+
"agent",
|
|
29
|
+
"web-component",
|
|
30
|
+
"custom-element",
|
|
31
|
+
"shadow-dom",
|
|
32
|
+
"ai",
|
|
33
|
+
"llm",
|
|
34
|
+
"pydantic-ai",
|
|
35
|
+
"chat"
|
|
36
|
+
],
|
|
37
|
+
"author": {
|
|
38
|
+
"name": "Artur Veres",
|
|
39
|
+
"email": "artur8118@gmail.com"
|
|
40
|
+
},
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"homepage": "https://github.com/Artui/ag-ui-web-component",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/Artui/ag-ui-web-component.git"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/Artui/ag-ui-web-component/issues"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public",
|
|
52
|
+
"provenance": true
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=20"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@ag-ui/client": ">=0.0.54 <0.1",
|
|
59
|
+
"@ag-ui/core": ">=0.0.54 <0.1"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@biomejs/biome": "^2.4.0",
|
|
63
|
+
"@types/node": "^22.0.0",
|
|
64
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
65
|
+
"esbuild": "^0.25.0",
|
|
66
|
+
"happy-dom": "^16.0.0",
|
|
67
|
+
"typescript": "^5.7.0",
|
|
68
|
+
"vitest": "^3.0.0"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "node esbuild.config.mjs && tsc -p tsconfig.build.json",
|
|
72
|
+
"lint": "biome check .",
|
|
73
|
+
"lint:fix": "biome check --write .",
|
|
74
|
+
"format": "biome format --write .",
|
|
75
|
+
"format:check": "biome format .",
|
|
76
|
+
"type-check": "tsc --noEmit",
|
|
77
|
+
"test": "vitest run --coverage"
|
|
78
|
+
}
|
|
79
|
+
}
|