@copilotkit/web-inspector 1.80.0 → 1.82.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generative-ui-view.mjs","names":[],"sources":["../../src/components/generative-ui-view.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport {\n GENERATIVE_UI_ROOT_ID,\n childIdsAtRefs,\n collectChildRefs,\n} from \"@copilotkit/shared\";\nimport type {\n A2UIComponentNode,\n A2UIOperation,\n GenerativeUIComponentManifest,\n GenerativeUITemplateChildren,\n} from \"@copilotkit/shared\";\nimport { renderHighlightedJsonBlock } from \"../lib/json-block.js\";\nimport type {\n ɵGenerativeUIDebugPromptSection,\n ɵGenerativeUIDebugRun,\n ɵGenerativeUIDebugSnapshot,\n ɵGenerativeUIDebugSource,\n ɵGenerativeUIDebugSurface,\n} from \"@copilotkit/core\";\n\ntype GenerativeUITab = \"surfaces\" | \"catalog\" | \"prompt\";\n\nconst TABS: ReadonlyArray<{ key: GenerativeUITab; label: string }> = [\n { key: \"surfaces\", label: \"Surfaces\" },\n { key: \"catalog\", label: \"Catalog\" },\n { key: \"prompt\", label: \"Prompt\" },\n];\n\nconst PROMPT_SOURCE_NOTES: Record<\n ɵGenerativeUIDebugPromptSection[\"source\"],\n string\n> = {\n runtime:\n \"The runtime adds this text as a context entry, with the render_ui tool.\",\n context: \"The provider sends this text as a context entry.\",\n backend:\n \"sendContext is false. Your backend builds the prompt, usually from this text.\",\n};\n\n/** A rough token count: about 4 characters for each token. */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nfunction formatTokens(text: string) {\n return `~${estimateTokens(text).toLocaleString()} tokens`;\n}\n\nfunction json(value: unknown) {\n return JSON.stringify(value, null, 2) ?? \"undefined\";\n}\n\n/** The kind of an A2UI operation, for example `updateComponents`. */\nexport function operationKind(operation: unknown): string {\n if (typeof operation !== \"object\" || operation === null) return \"unknown\";\n return Object.keys(operation).find((key) => key !== \"version\") ?? \"unknown\";\n}\n\n/** One component of a surface, as the browser renders it. */\nexport interface ComponentTreeNode {\n id: string;\n component: string;\n /** The props that are not slots, as the model wrote them. */\n props: Record<string, unknown>;\n /** Set when a template repeats the component for each item at this path. */\n repeat?: string;\n children: ComponentTreeNode[];\n}\n\n/**\n * The component tree of a surface, from its root. Later operations replace\n * components with the same id. Skipped operations (rejected by the browser)\n * are left out. A slot id with no component yet is left out too.\n */\nexport function componentTree(\n operations: readonly A2UIOperation[],\n skip: ReadonlySet<number>,\n catalog: Record<string, GenerativeUIComponentManifest>,\n): ComponentTreeNode | undefined {\n const byId = new Map<string, A2UIComponentNode>();\n operations.forEach((operation, index) => {\n if (skip.has(index)) return;\n const components =\n \"createSurface\" in operation\n ? operation.createSurface.components\n : \"updateComponents\" in operation\n ? operation.updateComponents.components\n : undefined;\n for (const node of components ?? []) byId.set(node.id, node);\n });\n const seen = new Set<string>();\n const build = (id: unknown, repeat?: string): ComponentTreeNode[] => {\n const node = typeof id === \"string\" ? byId.get(id) : undefined;\n // The browser rejects cycles. The guard keeps a bad snapshot from looping.\n if (!node || seen.has(node.id)) return [];\n seen.add(node.id);\n const { id: _id, component, ...rest } = node;\n const manifest = catalog[component];\n // A child is in a slot, or at a `child()` / `childList()` ref of the\n // props. A top-level ref reads like a slot. A deeper ref (the `child` of\n // each tab) stays in the props, and its ids become children too.\n const refs = manifest ? collectChildRefs(manifest.props) : [];\n const childKeys = new Set([\n ...Object.keys(manifest?.slots ?? {}),\n ...refs.filter((ref) => ref.path.length === 1).map((ref) => ref.path[0]),\n ]);\n const nested = refs.filter((ref) => ref.path.length > 1);\n const props: Record<string, unknown> = {};\n const children: ComponentTreeNode[] = [];\n for (const [name, value] of Object.entries(rest)) {\n if (!childKeys.has(name)) props[name] = value;\n else if (Array.isArray(value)) {\n for (const child of value) children.push(...build(child));\n } else if (typeof value === \"object\" && value !== null) {\n const template = value as Partial<GenerativeUITemplateChildren>;\n children.push(...build(template.componentId, template.path));\n } else children.push(...build(value));\n }\n for (const child of childIdsAtRefs(rest, nested)) {\n children.push(...build(child));\n }\n return [\n {\n id: node.id,\n component,\n props,\n ...(repeat ? { repeat } : {}),\n children,\n },\n ];\n };\n return build(GENERATIVE_UI_ROOT_ID)[0];\n}\n\n/** The first element of the page whose `attribute` is `value`. */\nfunction findOnPage(attribute: string, value: string) {\n return [...document.querySelectorAll<HTMLElement>(`[${attribute}]`)].find(\n (element) => element.getAttribute(attribute) === value,\n );\n}\n\n/**\n * The function problem that the inspector shows. A function goes to the\n * model only with exactly one mounted handler.\n */\n/**\n * Splits components by the catalog that declared them: the catalog of the\n * provider first, then each base in the order of `extends`.\n */\nexport function groupByCatalog<Entry extends [string, unknown]>(\n components: Entry[],\n snapshot: Pick<ɵGenerativeUIDebugSnapshot, \"catalogId\" | \"componentCatalogs\">,\n): [string, Entry[]][] {\n const groups = new Map<string, Entry[]>([[snapshot.catalogId, []]]);\n for (const entry of components) {\n const id = snapshot.componentCatalogs[entry[0]] ?? snapshot.catalogId;\n groups.set(id, [...(groups.get(id) ?? []), entry]);\n }\n return [...groups].filter(([, group]) => group.length > 0);\n}\n\nexport function functionHandlerProblem(handlers: number): string | undefined {\n if (handlers === 1) return undefined;\n if (handlers === 0) {\n return \"No useGenerativeUIFunction handler is mounted, so the model does not get this function.\";\n }\n return `${handlers} handlers are mounted. Mount exactly one, or the model does not get this function.`;\n}\n\n/**\n * The Generative UI pane: the catalog, the targets and surfaces on the page,\n * and what a run adds to the prompt of the model.\n */\nexport class CpkGenerativeUIView extends LitElement {\n static properties = {\n source: { attribute: false },\n };\n\n source: ɵGenerativeUIDebugSource | undefined;\n private tab: GenerativeUITab = \"surfaces\";\n private run: \"last\" | \"next\" = \"last\";\n private filter = \"\";\n private readonly expanded = new Set<string>();\n private copied: string | null = null;\n private unsubscribe: (() => void) | null = null;\n private subscribedSource: ɵGenerativeUIDebugSource | undefined;\n private outlined: {\n element: HTMLElement;\n outline: string;\n outlineOffset: string;\n } | null = null;\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.unhighlight();\n this.unsubscribe?.();\n this.unsubscribe = null;\n this.subscribedSource = undefined;\n }\n\n override willUpdate() {\n if (this.source === this.subscribedSource && this.unsubscribe) return;\n this.unsubscribe?.();\n this.subscribedSource = this.source;\n this.unsubscribe =\n this.source?.subscribe(() => this.requestUpdate()) ?? null;\n }\n\n private toggle(key: string) {\n if (this.expanded.has(key)) this.expanded.delete(key);\n else this.expanded.add(key);\n this.requestUpdate();\n }\n\n private async copy(key: string, text: string) {\n try {\n await navigator.clipboard.writeText(text);\n this.copied = key;\n } catch {\n this.copied = null;\n }\n this.requestUpdate();\n setTimeout(() => {\n if (this.copied !== key) return;\n this.copied = null;\n this.requestUpdate();\n }, 1500);\n }\n\n /**\n * Outlines an element of the page and scrolls it into view, until\n * `unhighlight`. Hover and keyboard focus call these two.\n */\n private highlight(element: HTMLElement | null | undefined) {\n this.unhighlight();\n if (!element) return;\n const { outline, outlineOffset } = element.style;\n this.outlined = { element, outline, outlineOffset };\n element.style.outline = \"2px solid #7567ff\";\n element.style.outlineOffset = \"4px\";\n element.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }\n\n private unhighlight() {\n if (!this.outlined) return;\n const { element, outline, outlineOffset } = this.outlined;\n element.style.outline = outline;\n element.style.outlineOffset = outlineOffset;\n this.outlined = null;\n }\n\n override render() {\n if (!this.source) {\n return html`\n <div class=\"empty\">\n <p class=\"strong\">No generative UI</p>\n <p>\n Pass <code>generativeUI</code> to <code>CopilotKitProvider</code>, and this\n pane shows its catalog, surfaces, and prompt.\n </p>\n </div>\n `;\n }\n const snapshot = this.source.getSnapshot();\n return html`\n <header class=\"header\">\n <div class=\"title-row\">\n <h2>Generative UI</h2>\n <span class=\"chip\">${snapshot.transport} transport</span>\n <code class=\"muted\">${snapshot.catalogId}</code>\n </div>\n <p class=\"muted small\">\n ${\n snapshot.agentIds\n ? `For agents: ${snapshot.agentIds.join(\", \")}`\n : \"For every agent\"\n }\n · ${Object.keys(snapshot.components).length} components ·\n ${Object.keys(snapshot.functions).length} functions ·\n ${snapshot.surfaces.length} surfaces\n </p>\n <nav class=\"tabs\" role=\"tablist\">\n ${TABS.map(\n (tab) =>\n html`<button\n type=\"button\"\n role=\"tab\"\n aria-selected=${this.tab === tab.key}\n class=\"tab ${this.tab === tab.key ? \"active\" : \"\"}\"\n @click=${() => {\n this.tab = tab.key;\n this.requestUpdate();\n }}\n >\n ${tab.label}\n </button>`,\n )}\n </nav>\n </header>\n <div class=\"body\">\n ${\n this.tab === \"surfaces\"\n ? this.renderSurfaces(snapshot)\n : this.tab === \"catalog\"\n ? this.renderCatalog(snapshot)\n : this.renderPrompt(snapshot)\n }\n </div>\n `;\n }\n\n private renderSurfaces(snapshot: ɵGenerativeUIDebugSnapshot) {\n const stateKeys = Object.keys(snapshot.state);\n const active = snapshot.surfaces.filter(\n (surface) => surface.threadId === snapshot.activeThreadId,\n );\n const other = snapshot.surfaces.filter(\n (surface) => surface.threadId !== snapshot.activeThreadId,\n );\n return html`\n <section>\n <h3>Targets</h3>\n <p class=\"muted small\">\n Where the model can render. The model sees each description.\n </p>\n ${snapshot.targets.map((target) => {\n const show = () =>\n this.highlight(findOnPage(\"data-generative-ui-surface\", target.id));\n return html`<div\n class=\"row\"\n @mouseenter=${show}\n @mouseleave=${this.unhighlight}\n >\n <div class=\"row-main\">\n <div class=\"row-title\">\n <code>${target.id}</code>\n <span class=\"chip\">${target.kind}</span>\n ${\n target.components\n ? html`<span class=\"chip\"\n >${target.components.length} components only</span\n >`\n : nothing\n }\n </div>\n ${\n target.description\n ? html`<p class=\"small\">${target.description}</p>`\n : target.kind === \"inline\"\n ? html`\n <p class=\"small warn\">\n No description. Give the surface a description, so the model knows what to put\n in it.\n </p>\n `\n : nothing\n }\n ${\n target.components\n ? html`<p class=\"muted small\">\n ${target.components.join(\", \") || \"No components\"}\n </p>`\n : nothing\n }\n </div>\n </div>`;\n })}\n </section>\n <section>\n <h3>Surfaces in this thread</h3>\n ${\n active.length === 0\n ? html`\n <p class=\"muted small\">No surfaces yet. Ask the chat for something visual.</p>\n `\n : active.map((surface) =>\n this.renderSurface(surface, snapshot.components),\n )\n }\n ${\n other.length > 0\n ? html`<h4>Other threads</h4>\n ${other.map((surface) =>\n this.renderSurface(surface, snapshot.components),\n )}`\n : nothing\n }\n </section>\n <section>\n <h3>App state</h3>\n <p class=\"muted small\">\n Bound props read these values. The model does not see them.\n </p>\n ${\n stateKeys.length === 0\n ? html`\n <p class=\"muted small\">No state is set.</p>\n `\n : renderHighlightedJsonBlock(snapshot.state)\n }\n </section>\n `;\n }\n\n private renderComponent(\n node: ComponentTreeNode,\n key: string,\n ): ReturnType<typeof html> {\n const nodeKey = `${key}:component:${node.id}`;\n const propCount = Object.keys(node.props).length;\n return html`<li>\n <button\n type=\"button\"\n class=\"op-toggle\"\n aria-expanded=${this.expanded.has(nodeKey)}\n @click=${() => this.toggle(nodeKey)}\n >\n <code>${node.component}</code>\n <span class=\"muted small\">${node.id}</span>\n ${\n node.repeat\n ? html`<span class=\"chip\">each item of ${node.repeat}</span>`\n : nothing\n }\n <span class=\"muted small\">${propCount} props</span>\n </button>\n ${\n this.expanded.has(nodeKey)\n ? renderHighlightedJsonBlock(node.props)\n : nothing\n }\n ${\n node.children.length > 0\n ? html`<ul class=\"tree\">\n ${node.children.map((child) => this.renderComponent(child, key))}\n </ul>`\n : nothing\n }\n </li>`;\n }\n\n private renderSurface(\n surface: ɵGenerativeUIDebugSurface,\n catalog: ɵGenerativeUIDebugSnapshot[\"components\"],\n ) {\n const key = `surface:${surface.threadId}:${surface.surfaceId}`;\n const isOpen = this.expanded.has(key);\n const userPaths = Object.keys(surface.userValues);\n const browserRejected = new Set(\n surface.rejected\n .filter((rejection) => rejection.source === \"browser\")\n .map((rejection) => rejection.index),\n );\n const tree = isOpen\n ? componentTree(surface.operations, browserRejected, catalog)\n : undefined;\n // Hover or focus outlines the surface on the page. The surface root has\n // `display: contents`, so the box is the `<GenerativeUISurface>` around\n // it. A chat surface has none, so the chat does not scroll.\n const show = () =>\n this.highlight(\n findOnPage(\n \"data-generative-ui-root\",\n surface.surfaceId,\n )?.closest<HTMLElement>(\"[data-generative-ui-surface]\"),\n );\n return html`<div\n class=\"card\"\n @mouseenter=${show}\n @mouseleave=${this.unhighlight}\n @focusin=${show}\n @focusout=${this.unhighlight}\n >\n <div class=\"card-head\">\n <button\n type=\"button\"\n class=\"card-toggle\"\n aria-expanded=${isOpen}\n @click=${() => this.toggle(key)}\n >\n <span class=\"row-title\">\n <code>${surface.surfaceId}</code>\n <span class=\"chip status-${surface.status}\">${surface.status}</span>\n <span class=\"muted small\">in ${surface.target}</span>\n </span>\n <span class=\"muted small\">\n ${surface.operations.length} operations\n ${\n surface.rejected.length > 0\n ? html`·\n <span class=\"danger\"\n >${surface.rejected.length} rejected</span\n >`\n : nothing\n }\n ${\n userPaths.length > 0\n ? html`· ${userPaths.length} user values`\n : nothing\n }\n </span>\n </button>\n </div>\n ${\n isOpen\n ? html`<div class=\"card-body\">\n ${\n surface.rejected.length > 0\n ? html`<h4>Rejected operations</h4>\n <p class=\"muted small\">\n These were dropped. The model gets them on its next run, so\n it can fix them.\n </p>\n <ul class=\"list\">\n ${surface.rejected.map(\n (rejection) =>\n html`<li class=\"danger\">\n <span class=\"chip\">${rejection.source}</span>\n operation ${rejection.index}: ${rejection.reason}\n </li>`,\n )}\n </ul>`\n : nothing\n }\n ${\n userPaths.length > 0\n ? html`<h4>User values</h4>\n <p class=\"muted small\">\n The user wrote these paths. Agent writes to them are\n ignored.\n </p>\n ${renderHighlightedJsonBlock(surface.userValues)}`\n : nothing\n }\n <h4>Components</h4>\n ${\n tree\n ? html`<ul class=\"tree root\">\n ${this.renderComponent(tree, key)}\n </ul>`\n : html`\n <p class=\"muted small\">No root component yet.</p>\n `\n }\n <h4>Data model</h4>\n ${renderHighlightedJsonBlock(surface.dataModel)}\n <h4>Operations</h4>\n <ol class=\"ops\">\n ${surface.operations.map((operation, index) => {\n const opKey = `${key}:op:${index}`;\n const rejected = browserRejected.has(index);\n return html`<li class=${rejected ? \"danger\" : \"\"}>\n <button\n type=\"button\"\n class=\"op-toggle\"\n aria-expanded=${this.expanded.has(opKey)}\n @click=${() => this.toggle(opKey)}\n >\n <span class=\"muted\">${index}</span>\n <code>${operationKind(operation)}</code>\n ${\n rejected\n ? html`\n <span class=\"chip\">rejected</span>\n `\n : nothing\n }\n </button>\n ${\n this.expanded.has(opKey)\n ? renderHighlightedJsonBlock(operation)\n : nothing\n }\n </li>`;\n })}\n </ol>\n <p class=\"muted small\">Thread <code>${surface.threadId}</code></p>\n </div>`\n : nothing\n }\n </div>`;\n }\n\n private renderCatalogComponent(\n name: string,\n component: GenerativeUIComponentManifest,\n ) {\n const key = `component:${name}`;\n const isOpen = this.expanded.has(key);\n const events = Object.keys(component.events ?? {});\n const slots = [\n ...Object.entries(component.slots ?? {}),\n ...collectChildRefs(component.props).map(\n (ref) => [ref.path.join(\".\"), ref.kind] as const,\n ),\n ];\n return html`<div class=\"card\">\n <button\n type=\"button\"\n class=\"card-toggle\"\n aria-expanded=${isOpen}\n @click=${() => this.toggle(key)}\n >\n <span class=\"row-title\">\n <code>${name}</code>\n ${slots.map(\n ([slot, kind]) => html`<span class=\"chip\">${slot}: ${kind}</span>`,\n )}\n ${events.map(\n (event) => html`<span class=\"chip event\">${event}</span>`,\n )}\n </span>\n ${\n component.description\n ? html`<span class=\"small\">${component.description}</span>`\n : html`\n <span class=\"small warn\">No description</span>\n `\n }\n </button>\n ${\n isOpen\n ? html`<div class=\"card-body\">\n <h4>Props (JSON Schema)</h4>\n ${renderHighlightedJsonBlock(component.props)}\n ${\n component.events\n ? html`<h4>Events</h4>\n ${renderHighlightedJsonBlock(component.events)}`\n : nothing\n }\n </div>`\n : nothing\n }\n </div>`;\n }\n\n private renderCatalog(snapshot: ɵGenerativeUIDebugSnapshot) {\n const query = this.filter.trim().toLowerCase();\n const matches = ([name, entry]: [string, { description?: string }]) =>\n !query ||\n name.toLowerCase().includes(query) ||\n entry.description?.toLowerCase().includes(query);\n const components = Object.entries(snapshot.components).filter(matches);\n const functions = Object.entries(snapshot.functions).filter(matches);\n return html`\n <section>\n <div class=\"section-head\">\n <h3>Components</h3>\n <input\n class=\"filter\"\n type=\"search\"\n placeholder=\"Search\"\n aria-label=\"Search components and functions\"\n .value=${this.filter}\n @input=${(event: Event) => {\n this.filter = (event.target as HTMLInputElement).value;\n this.requestUpdate();\n }}\n />\n </div>\n <p class=\"muted small\">\n ${Object.keys(snapshot.components).length} components ·\n ${formatTokens(JSON.stringify(snapshot.components))} in the envelope\n </p>\n ${groupByCatalog(components, snapshot).map(([catalogId, group]) => {\n const key = `catalog:${catalogId}`;\n const isOwn = catalogId === snapshot.catalogId;\n // The provider catalog starts open and a base catalog starts\n // closed. A search opens all of them, so each match shows.\n const toggled = this.expanded.has(key);\n const isOpen = query !== \"\" || (isOwn ? !toggled : toggled);\n return html`<h4>\n <button\n type=\"button\"\n class=\"op-toggle catalog-toggle\"\n aria-expanded=${isOpen}\n @click=${() => this.toggle(key)}\n >\n <code>${catalogId}</code>\n ${\n isOwn\n ? nothing\n : html`\n <span class=\"chip\">extended</span>\n `\n }\n <span class=\"muted small\">${group.length} components</span>\n </button>\n </h4>\n ${\n isOpen\n ? group.map(([name, component]) =>\n this.renderCatalogComponent(name, component),\n )\n : nothing\n }`;\n })}\n ${\n query && components.length === 0\n ? html`\n <p class=\"muted small\">No component matches.</p>\n `\n : nothing\n }\n </section>\n <section>\n <h3>Functions</h3>\n ${\n functions.length === 0\n ? html`<p class=\"muted small\">\n ${query ? \"No function matches.\" : \"No functions are declared.\"}\n </p>`\n : functions.map(([name, fn]) => {\n const problem = functionHandlerProblem(fn.handlers);\n return html`<div class=\"card\">\n <div class=\"card-body\">\n <div class=\"row-title\">\n <code>${name}</code>\n <span\n class=\"chip ${problem ? \"status-error\" : \"status-ready\"}\"\n >${fn.handlers}\n handler${fn.handlers === 1 ? \"\" : \"s\"}</span\n >\n </div>\n ${\n fn.description\n ? html`<p class=\"small\">${fn.description}</p>`\n : nothing\n }\n ${\n problem\n ? html`<p class=\"small warn\">${problem}</p>`\n : nothing\n }\n ${renderHighlightedJsonBlock(fn.parameters)}\n </div>\n </div>`;\n })\n }\n </section>\n `;\n }\n\n /**\n * The prompt text and the envelope are large (about 90,000 characters\n * each in the shop), and the next run changes with each surface change.\n * So they are drawn only when open.\n */\n private renderShowButton(key: string) {\n const open = this.expanded.has(key);\n return html`<button\n type=\"button\"\n class=\"button\"\n aria-expanded=${open}\n @click=${() => this.toggle(key)}\n >\n ${open ? \"Hide\" : \"Show\"}\n </button>`;\n }\n\n private renderPrompt(snapshot: ɵGenerativeUIDebugSnapshot) {\n const showing = this.run === \"last\" && snapshot.lastRun ? \"last\" : \"next\";\n const run: ɵGenerativeUIDebugRun =\n showing === \"last\" && snapshot.lastRun\n ? snapshot.lastRun\n : snapshot.nextRun;\n const isLast = showing === \"last\";\n const envelope = json(run.envelope);\n return html`\n <div class=\"segmented\" role=\"radiogroup\">\n ${([\"last\", \"next\"] as const).map(\n (option) =>\n html`<button\n type=\"button\"\n role=\"radio\"\n aria-checked=${showing === option}\n class=\"tab ${showing === option ? \"active\" : \"\"}\"\n ?disabled=${option === \"last\" && !snapshot.lastRun}\n @click=${() => {\n this.run = option;\n this.requestUpdate();\n }}\n >\n ${option === \"last\" ? \"Last run\" : \"Next run\"}\n </button>`,\n )}\n </div>\n <p class=\"muted small\">\n ${\n isLast\n ? html`What the last run of\n <code>${run.agentId ?? \"the agent\"}</code> sent${\n run.startedAt\n ? `, at ${new Date(run.startedAt).toLocaleTimeString()}`\n : \"\"\n }.`\n : html`\n What the next run will send, from the page as it is now.\n `\n }\n Your own system prompt and tools are not shown.\n </p>\n ${run.prompt.map((section, index) => {\n const key = `prompt:${index}`;\n return html`<section>\n <div class=\"section-head\">\n <h3>${section.title}</h3>\n <span class=\"muted small\">${formatTokens(section.text)}</span>\n ${this.renderShowButton(key)}\n <button\n type=\"button\"\n class=\"button\"\n @click=${() => void this.copy(key, section.text)}\n >\n ${this.copied === key ? \"Copied\" : \"Copy\"}\n </button>\n </div>\n <p class=\"muted small\">${PROMPT_SOURCE_NOTES[section.source]}</p>\n ${\n this.expanded.has(key)\n ? html`<pre class=\"prompt\">${section.text || \"(empty)\"}</pre>`\n : nothing\n }\n </section>`;\n })}\n <section>\n <div class=\"section-head\">\n <h3>Envelope</h3>\n <span class=\"muted small\">${formatTokens(envelope)}</span>\n ${this.renderShowButton(\"envelope\")}\n <button\n type=\"button\"\n class=\"button\"\n @click=${() => void this.copy(\"envelope\", envelope)}\n >\n ${this.copied === \"envelope\" ? \"Copied\" : \"Copy\"}\n </button>\n </div>\n <p class=\"muted small\">\n The run sends this as <code>forwardedProps.copilotkit.ui</code>.\n </p>\n ${\n this.expanded.has(\"envelope\")\n ? renderHighlightedJsonBlock(run.envelope)\n : nothing\n }\n </section>\n `;\n }\n\n static styles = css`\n :host {\n --gui-ink: #202127;\n --gui-muted: #64656f;\n --gui-line: #dcdce4;\n --gui-soft: #f7f7fa;\n --gui-canvas: #fff;\n --gui-accent: #7567ff;\n --gui-accent-soft: #f0edff;\n --gui-green: #168b69;\n --gui-green-soft: #eaf6f1;\n --gui-amber: #8a5a00;\n --gui-amber-soft: #fff6e0;\n --gui-danger: #a12f2f;\n --gui-danger-soft: #fff4f4;\n --cpk-json-key: #3d408f;\n --cpk-json-str: #0b6b4c;\n --cpk-json-num: #8a5900;\n --cpk-json-bool: #c0333a;\n --cpk-json-nil: #57575b;\n display: block;\n height: 100%;\n overflow: auto;\n color: var(--gui-ink);\n background: var(--gui-canvas);\n font-family: Inter, ui-sans-serif, system-ui, sans-serif;\n font-size: 12px;\n }\n :host([data-color-scheme=\"dark\"]) {\n color-scheme: dark;\n --gui-ink: #f3f4f8;\n --gui-muted: #b0b3be;\n --gui-line: #3a3e4b;\n --gui-soft: #20232d;\n --gui-canvas: #15171e;\n --gui-accent: #a296ff;\n --gui-accent-soft: #2a2940;\n --gui-green: #4dc69d;\n --gui-green-soft: #172923;\n --gui-amber: #f2c46d;\n --gui-amber-soft: #2f2716;\n --gui-danger: #ffabab;\n --gui-danger-soft: #321f25;\n --cpk-json-key: #bec2ff;\n --cpk-json-str: #85ecce;\n --cpk-json-num: #ffac4d;\n --cpk-json-bool: #fa5f67;\n --cpk-json-nil: #afafb7;\n }\n .header {\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 12px 16px 0;\n background: var(--gui-canvas);\n border-bottom: 1px solid var(--gui-line);\n }\n .title-row,\n .row-title,\n .section-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n }\n .title-row,\n .row-title {\n align-items: baseline;\n }\n .section-head h3 {\n margin-right: auto;\n }\n h2 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n }\n h3 {\n margin: 0 0 4px;\n font-size: 12px;\n font-weight: 600;\n }\n h4 {\n margin: 12px 0 4px;\n font-size: 11px;\n font-weight: 600;\n color: var(--gui-muted);\n }\n p {\n margin: 2px 0 6px;\n }\n code {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11px;\n }\n .body {\n padding: 12px 16px 24px;\n }\n section {\n margin-bottom: 20px;\n }\n .muted {\n color: var(--gui-muted);\n }\n .small {\n font-size: 11px;\n }\n .strong {\n font-weight: 600;\n color: var(--gui-ink);\n }\n .warn {\n color: var(--gui-amber);\n }\n .danger {\n color: var(--gui-danger);\n }\n .tabs,\n .segmented {\n display: flex;\n gap: 4px;\n margin-top: 8px;\n }\n .segmented {\n margin: 0 0 8px;\n }\n .tab {\n border: 0;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--gui-muted);\n font: inherit;\n font-weight: 500;\n padding: 6px 8px;\n cursor: pointer;\n }\n .segmented .tab {\n border: 1px solid var(--gui-line);\n border-radius: 6px;\n }\n .tab.active {\n color: var(--gui-ink);\n border-bottom-color: var(--gui-accent);\n }\n .segmented .tab.active {\n border-color: var(--gui-accent);\n background: var(--gui-accent-soft);\n }\n .tab:disabled {\n opacity: 0.5;\n cursor: default;\n }\n .chip {\n display: inline-block;\n border: 1px solid var(--gui-line);\n border-radius: 999px;\n padding: 0 6px;\n font-size: 10px;\n line-height: 16px;\n color: var(--gui-muted);\n background: var(--gui-soft);\n }\n .chip.event {\n color: var(--gui-accent);\n background: var(--gui-accent-soft);\n }\n .status-ready {\n color: var(--gui-green);\n background: var(--gui-green-soft);\n }\n .status-streaming {\n color: var(--gui-accent);\n background: var(--gui-accent-soft);\n }\n .status-error {\n color: var(--gui-danger);\n background: var(--gui-danger-soft);\n }\n .row {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 8px 0;\n border-bottom: 1px solid var(--gui-line);\n }\n .row-main {\n flex: 1;\n min-width: 0;\n }\n .card {\n border: 1px solid var(--gui-line);\n border-radius: 8px;\n margin-bottom: 6px;\n overflow: hidden;\n }\n .card-head {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-right: 8px;\n }\n .cpk-json-block {\n margin: 4px 0 0;\n max-height: 320px;\n overflow: auto;\n border: 1px solid var(--gui-line);\n border-radius: 6px;\n padding: 8px 10px;\n background: var(--gui-soft);\n color: var(--gui-ink);\n font-family: \"Spline Sans Mono\", ui-monospace, monospace;\n font-size: 11px;\n line-height: 1.6;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n .cpk-json-token--key {\n color: var(--cpk-json-key);\n }\n .cpk-json-token--str {\n color: var(--cpk-json-str);\n }\n .cpk-json-token--num {\n color: var(--cpk-json-num);\n }\n .cpk-json-token--bool {\n color: var(--cpk-json-bool);\n }\n .cpk-json-token--nil {\n color: var(--cpk-json-nil);\n }\n .card-toggle {\n display: flex;\n flex: 1;\n box-sizing: border-box;\n width: 100%;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n min-width: 0;\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n text-align: left;\n padding: 8px 10px;\n cursor: pointer;\n }\n .card-toggle:hover {\n background: var(--gui-soft);\n }\n .card-body {\n padding: 8px 10px;\n border-top: 1px solid var(--gui-line);\n }\n .card > .card-body:first-child {\n border-top: 0;\n }\n .button {\n flex-shrink: 0;\n border: 1px solid var(--gui-line);\n border-radius: 6px;\n background: var(--gui-canvas);\n color: var(--gui-ink);\n font: inherit;\n font-size: 11px;\n padding: 2px 8px;\n cursor: pointer;\n }\n .button:hover {\n border-color: var(--gui-accent);\n }\n .section-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n }\n .filter {\n width: 160px;\n box-sizing: border-box;\n border: 1px solid var(--gui-line);\n border-radius: 6px;\n background: var(--gui-canvas);\n color: var(--gui-ink);\n font: inherit;\n font-size: 11px;\n padding: 3px 6px;\n }\n .catalog-toggle::before {\n content: \"▸\";\n display: inline-block;\n width: 10px;\n color: var(--gui-muted);\n transition: transform 0.1s;\n }\n .catalog-toggle[aria-expanded=\"true\"]::before {\n transform: rotate(90deg);\n }\n pre {\n margin: 4px 0 0;\n max-height: 320px;\n overflow: auto;\n border-radius: 6px;\n background: var(--gui-soft);\n padding: 8px;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 11px;\n line-height: 1.45;\n white-space: pre-wrap;\n word-break: break-word;\n }\n pre.prompt {\n max-height: 480px;\n }\n .list,\n .ops {\n margin: 0;\n padding-left: 18px;\n }\n .list li {\n margin-bottom: 4px;\n }\n .ops {\n list-style: none;\n padding: 0;\n }\n .tree {\n list-style: none;\n margin: 0;\n padding-left: 14px;\n border-left: 1px solid var(--gui-line);\n }\n .tree.root {\n padding-left: 0;\n border-left: 0;\n }\n .op-toggle {\n display: flex;\n align-items: baseline;\n gap: 6px;\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n padding: 2px 0;\n cursor: pointer;\n }\n .empty {\n padding: 48px 24px;\n text-align: center;\n color: var(--gui-muted);\n }\n `;\n}\n\nif (!customElements.get(\"cpk-generative-ui-view\")) {\n customElements.define(\"cpk-generative-ui-view\", CpkGenerativeUIView);\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -10,6 +10,8 @@ const require_notification_article = require('./styles/notification-article.cjs'
10
10
  const require_inspector_logo = require('./assets/inspector-logo.cjs');
11
11
  const require_inspector_logo_kite = require('./assets/inspector-logo-kite.cjs');
12
12
  const require_learning_view = require('./components/learning-view.cjs');
13
+ const require_json_block = require('./lib/json-block.cjs');
14
+ require('./components/generative-ui-view.cjs');
13
15
  const require_context_helpers = require('./lib/context-helpers.cjs');
14
16
  const require_learning_setup = require('./lib/learning-setup.cjs');
15
17
  const require_inspector_learning = require('./lib/inspector-learning.cjs');
@@ -801,132 +803,6 @@ function getExampleTourTelemetryPair(index) {
801
803
  function getMetadataActionPlacement(placement) {
802
804
  return placement === "threads-footer" ? "threads_footer" : "threads_locked";
803
805
  }
804
- function escapeHtml(s) {
805
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
806
- }
807
- const highlightedJsonCache = /* @__PURE__ */ new WeakMap();
808
- function highlightedJson(obj) {
809
- if (typeof obj === "object" && obj !== null) {
810
- const cached = highlightedJsonCache.get(obj);
811
- if (cached !== void 0) return cached;
812
- }
813
- const json = JSON.stringify(obj, null, 2);
814
- if (!json) return "";
815
- const parts = [];
816
- let lastIndex = 0;
817
- const re = /("(?:\\u[a-fA-F0-9]{4}|\\[^u]|[^\\"])*"(?:\s*:)?|\b(?:true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g;
818
- let match;
819
- while ((match = re.exec(json)) !== null) {
820
- parts.push(escapeHtml(json.slice(lastIndex, match.index)));
821
- const m = match[0];
822
- let token = "num";
823
- if (m.startsWith("\"")) token = m.trimEnd().endsWith(":") ? "key" : "str";
824
- else if (m === "true" || m === "false") token = "bool";
825
- else if (m === "null") token = "nil";
826
- parts.push(`<span class="cpk-json-token cpk-json-token--${token}">${escapeHtml(m)}</span>`);
827
- lastIndex = match.index + m.length;
828
- }
829
- parts.push(escapeHtml(json.slice(lastIndex)));
830
- const result = parts.join("");
831
- if (typeof obj === "object" && obj !== null) highlightedJsonCache.set(obj, result);
832
- return result;
833
- }
834
- function coerceJsonValue(value) {
835
- if (typeof value !== "string") return value;
836
- const trimmed = value.trim();
837
- if (trimmed.length === 0) return value;
838
- if (!(trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]"))) return value;
839
- try {
840
- return JSON.parse(trimmed);
841
- } catch {
842
- return value;
843
- }
844
- }
845
- let inspectorJsonRenderer = null;
846
- let inspectorJsonSlotCount = 0;
847
- const JSON_BLOCK_TAG = "cpk-json-block";
848
- /**
849
- * Replaces the inspector's built-in JSON blocks (tool arguments and results,
850
- * state, events, and context) with a host renderer. Pass `null` to restore the
851
- * built-in blocks. Set it before the inspector renders: a block that is
852
- * already on screen changes at the inspector's next render.
853
- *
854
- * @example
855
- * ```ts
856
- * setInspectorJsonRenderer((container, value) => {
857
- * const root = createRoot(container);
858
- * root.render(<JsonView value={value} />);
859
- * return () => root.unmount();
860
- * });
861
- * ```
862
- */
863
- function setInspectorJsonRenderer(renderer) {
864
- inspectorJsonRenderer = renderer;
865
- }
866
- /**
867
- * Hosts one value drawn by the host renderer. Inside a shadow root, the
868
- * container lives in the shadow host's light DOM and shows here through a
869
- * named slot, so the host page's own styles apply to what the renderer draws.
870
- */
871
- var CpkJsonBlock = class extends (globalThis.HTMLElement ?? class {}) {
872
- #value = void 0;
873
- #hasValue = false;
874
- #cleanup;
875
- #container;
876
- get value() {
877
- return this.#value;
878
- }
879
- set value(next) {
880
- if (this.#hasValue && Object.is(next, this.#value)) return;
881
- this.#value = next;
882
- this.#hasValue = true;
883
- if (this.isConnected) this.#render();
884
- }
885
- connectedCallback() {
886
- this.style.display = "block";
887
- this.#render();
888
- }
889
- disconnectedCallback() {
890
- this.#teardown();
891
- }
892
- #render() {
893
- this.#teardown();
894
- const renderer = inspectorJsonRenderer;
895
- if (!renderer) return;
896
- const root = this.getRootNode();
897
- const container = this.ownerDocument.createElement("div");
898
- if (root.nodeType === Node.DOCUMENT_FRAGMENT_NODE && "host" in root) {
899
- inspectorJsonSlotCount += 1;
900
- const name = `cpk-json-${inspectorJsonSlotCount}`;
901
- const slot = this.ownerDocument.createElement("slot");
902
- slot.name = name;
903
- this.replaceChildren(slot);
904
- container.slot = name;
905
- root.host.append(container);
906
- } else this.replaceChildren(container);
907
- this.#container = container;
908
- const cleanup = renderer(container, this.#value);
909
- this.#cleanup = typeof cleanup === "function" ? cleanup : void 0;
910
- }
911
- #teardown() {
912
- const cleanup = this.#cleanup;
913
- this.#cleanup = void 0;
914
- cleanup?.();
915
- this.#container?.remove();
916
- this.#container = void 0;
917
- this.replaceChildren();
918
- }
919
- };
920
- function renderHighlightedJsonBlock(value, options = {}) {
921
- if (inspectorJsonRenderer) return lit.html`<cpk-json-block
922
- .value=${value}
923
- style=${options.maxHeight ? `overflow:auto;max-height:${options.maxHeight}` : lit.nothing}
924
- ></cpk-json-block>`;
925
- const parsed = coerceJsonValue(value);
926
- return lit.html`<pre class="cpk-json-block" style=${(options.maxHeight ? `max-height:${options.maxHeight}` : void 0) || lit.nothing}>
927
- ${(0, lit_directives_unsafe_html_js.unsafeHTML)(highlightedJson(parsed))}</pre
928
- >`;
929
- }
930
806
  function humanizeEventType(type) {
931
807
  const words = type.trim().split(/[_\s]+/).filter(Boolean).map((word) => word.toLowerCase());
932
808
  if (words.length === 0) return "Event";
@@ -4058,7 +3934,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
4058
3934
  <span>${detailsExpanded ? "Hide details" : "Show details"}</span>
4059
3935
  </button>` : lit.nothing}
4060
3936
  ${item.body ? lit.html`<div class="cpk-td__timeline-body">${item.body}</div>` : lit.nothing}
4061
- ${item.details && detailsExpanded ? renderHighlightedJsonBlock(item.details) : lit.nothing}
3937
+ ${item.details && detailsExpanded ? require_json_block.renderHighlightedJsonBlock(item.details) : lit.nothing}
4062
3938
  </div>
4063
3939
  `;
4064
3940
  }
@@ -4267,12 +4143,12 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
4267
4143
  <div class="cpk-td__tool-data">
4268
4144
  <section>
4269
4145
  <div class="cpk-td__tool-section-label">Arguments</div>
4270
- ${renderHighlightedJsonBlock(item.arguments)}
4146
+ ${require_json_block.renderHighlightedJsonBlock(item.arguments)}
4271
4147
  </section>
4272
4148
  ${item.hasResult ? lit.html`
4273
4149
  <section class="cpk-td__tool-result">
4274
4150
  <div class="cpk-td__tool-section-label">Result</div>
4275
- ${renderHighlightedJsonBlock(item.result)}
4151
+ ${require_json_block.renderHighlightedJsonBlock(item.result)}
4276
4152
  </section>` : lit.nothing}
4277
4153
  </div>
4278
4154
  </div>
@@ -4357,7 +4233,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
4357
4233
  `;
4358
4234
  const stateValue = this.activeState;
4359
4235
  return this.cachedPanelTpl("state", [stateValue], () => {
4360
- return renderHighlightedJsonBlock(stateValue);
4236
+ return require_json_block.renderHighlightedJsonBlock(stateValue);
4361
4237
  });
4362
4238
  }
4363
4239
  renderEvents() {
@@ -4435,7 +4311,7 @@ var CpkThreadInspector = class CpkThreadInspector extends PortableLitElement {
4435
4311
  >${detailsExpanded ? "Hide details" : "Show details"}</span
4436
4312
  >
4437
4313
  </button>
4438
- ${detailsExpanded ? renderHighlightedJsonBlock(event.rawEvent ?? event) : lit.nothing}
4314
+ ${detailsExpanded ? require_json_block.renderHighlightedJsonBlock(event.rawEvent ?? event) : lit.nothing}
4439
4315
  </div>
4440
4316
  `;
4441
4317
  })}`;
@@ -5205,6 +5081,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5205
5081
  this._memoriesAvailable = true;
5206
5082
  this._memoriesRealtimeStatus = "connecting";
5207
5083
  this._memoryUnsub = null;
5084
+ this._generativeUIUnsub = null;
5208
5085
  this._memorySubscribed = false;
5209
5086
  this._memoryStoreUnsupported = false;
5210
5087
  this.learningSnapshot = null;
@@ -5539,14 +5416,9 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5539
5416
  }
5540
5417
  } catch (error) {
5541
5418
  if (generation !== this.learningRequestGeneration || controller.signal.aborted) return;
5542
- if (error instanceof require_inspector_learning.InspectorLearningUnsupportedError) {
5543
- loadOutcome = "unsupported";
5544
- this.learningSupported = false;
5545
- this.learningSnapshot = null;
5546
- } else {
5547
- this.learningError = error instanceof Error ? error.message : "Learning data is unavailable.";
5548
- this.learningPollFailureCount += 1;
5549
- }
5419
+ if (error instanceof require_inspector_learning.InspectorLearningUnsupportedError) loadOutcome = "unsupported";
5420
+ this.learningError = "Learning status unavailable";
5421
+ this.learningPollFailureCount += 1;
5550
5422
  } finally {
5551
5423
  if (generation === this.learningRequestGeneration) {
5552
5424
  this.learningLoading = false;
@@ -5751,6 +5623,13 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
5751
5623
  this.queueHudTelemetry(() => require_telemetry.trackHudHideClicked({ trigger }));
5752
5624
  this.dismissInspectorFor("day");
5753
5625
  };
5626
+ this.retryLearningStatus = (event) => {
5627
+ event.stopPropagation();
5628
+ this.refreshLearningSnapshot().catch(() => {
5629
+ this.learningError = "Learning status unavailable";
5630
+ this.requestUpdate();
5631
+ });
5632
+ };
5754
5633
  this.handleSidebarToggle = () => {
5755
5634
  this.sidebarRailTooltip = null;
5756
5635
  this.sidebarCollapsed = !this.sidebarCollapsed;
@@ -6472,6 +6351,11 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6472
6351
  label: "Context",
6473
6352
  icon: "FileText"
6474
6353
  },
6354
+ ...this._core?.ɵgenerativeUIDebugSource ? [{
6355
+ key: "generative-ui",
6356
+ label: "Generative UI",
6357
+ icon: "LayoutTemplate"
6358
+ }] : [],
6475
6359
  {
6476
6360
  key: "threads",
6477
6361
  label: "Rich Threads",
@@ -6939,6 +6823,10 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
6939
6823
  }
6940
6824
  };
6941
6825
  this.coreUnsubscribe = core.subscribe(this.coreSubscriber).unsubscribe;
6826
+ this._generativeUIUnsub = core.ɵsubscribeToGenerativeUIDebugSource?.(() => {
6827
+ this.reconcileSelectedMenuVisibility();
6828
+ this.requestUpdate();
6829
+ }) ?? null;
6942
6830
  this.processAgentsChanged(core.agents);
6943
6831
  if (core.runtimeConnectionStatus === "connected") {
6944
6832
  if (!core.telemetryDisabled) {
@@ -7132,6 +7020,8 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
7132
7020
  }
7133
7021
  this._memoryUnsub?.();
7134
7022
  this._memoryUnsub = null;
7023
+ this._generativeUIUnsub?.();
7024
+ this._generativeUIUnsub = null;
7135
7025
  this._memories = [];
7136
7026
  this._memoriesLoading = false;
7137
7027
  this._memoriesError = null;
@@ -7563,7 +7453,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
7563
7453
  ${toolError.message}
7564
7454
  </p>` : lit.nothing}
7565
7455
  ${argsString ? lit.html`<div class="mt-2">
7566
- ${renderHighlightedJsonBlock(coerceJsonValue(call.function?.arguments))}
7456
+ ${require_json_block.renderHighlightedJsonBlock(require_json_block.coerceJsonValue(call.function?.arguments))}
7567
7457
  </div>` : lit.nothing}
7568
7458
  </div>
7569
7459
  `;
@@ -10213,8 +10103,22 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
10213
10103
  const titleCharacters = Array.from(title);
10214
10104
  return titleCharacters.length > HUD_ANNOUNCEMENT_TITLE_LIMIT ? `${titleCharacters.slice(0, HUD_ANNOUNCEMENT_TITLE_LIMIT).join("").trimEnd()}...` : title;
10215
10105
  }
10106
+ /** A failed or pending read must never imply that Learning is disabled. */
10107
+ getLearningStatus() {
10108
+ if (this.learningError) return "unavailable";
10109
+ if (this.learningSupported && !this.learningSnapshot) return "checking";
10110
+ return this.learningSnapshot?.configuration.state === "configured" ? "configured" : "not_configured";
10111
+ }
10216
10112
  renderHudRow(args) {
10217
10113
  if (args.connected) return lit.nothing;
10114
+ const learningStatus = args.id === "learning" ? this.getLearningStatus() : null;
10115
+ if (learningStatus === "unavailable" || learningStatus === "checking") return lit.html`
10116
+ <li class="cpk-launcher-hud__row" data-cpk-hud-row="learning">
10117
+ <span class="cpk-launcher-hud__label" role="status">${learningStatus === "unavailable" ? "Learning status unavailable" : "Checking Learning status"}</span>
10118
+ <button type="button" class="cpk-launcher-hud__action" aria-label="Retry Learning status"
10119
+ ?disabled=${this.learningLoading || this.learningRefreshing}
10120
+ @click=${this.retryLearningStatus}>Retry</button>
10121
+ </li>`;
10218
10122
  const detailId = `cpk-hud-detail-${args.id}`;
10219
10123
  const { label, description } = this.hudContent[args.id];
10220
10124
  return lit.html`
@@ -11045,17 +10949,26 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
11045
10949
  }
11046
10950
  renderHomeFeatures(model) {
11047
10951
  const enabledServices = model.services.filter((service) => service.enabled);
11048
- const disabledServices = model.services.filter((service) => !service.enabled);
10952
+ const learningStatus = this.getLearningStatus();
10953
+ const unavailableServices = model.services.filter((service) => service.id === "memory" && (learningStatus === "unavailable" || learningStatus === "checking"));
10954
+ const disabledServices = model.services.filter((service) => !service.enabled && !unavailableServices.includes(service));
11049
10955
  const renderService = (service) => {
11050
10956
  const copyState = this.homeFeaturePromptCopyState?.serviceId === service.id ? this.homeFeaturePromptCopyState.state : "idle";
11051
- const stateDescription = `${service.label} is ${service.enabled ? "enabled in your runtime" : "not enabled in your runtime"}`;
10957
+ const learningStatus = service.id === "memory" ? this.getLearningStatus() : null;
10958
+ const learningUnavailable = learningStatus === "unavailable" || learningStatus === "checking";
10959
+ const stateDescription = learningStatus ? {
10960
+ configured: "Learning configured",
10961
+ not_configured: "Learning not configured",
10962
+ unavailable: "Learning status unavailable",
10963
+ checking: "Checking Learning status"
10964
+ }[learningStatus] : `${service.label} is ${service.enabled ? "enabled in your runtime" : "not enabled in your runtime"}`;
11052
10965
  const copyLabel = copyState === "copied" ? "Copied" : copyState === "error" ? "Copy failed" : "Copy prompt";
11053
10966
  const copyTitle = copyLabel;
11054
10967
  return lit.html`
11055
10968
  <div
11056
10969
  class="inspector-home-feature"
11057
10970
  data-inspector-service=${service.id}
11058
- data-state=${service.enabled ? "on" : "off"}
10971
+ data-state=${learningUnavailable ? "unavailable" : service.enabled ? "on" : "off"}
11059
10972
  role="listitem"
11060
10973
  >
11061
10974
  <span
@@ -11074,13 +10987,16 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
11074
10987
  rel="noopener noreferrer"
11075
10988
  aria-label="Open ${service.label} documentation in a new tab"
11076
10989
  >
11077
- <span>${service.label}</span>
10990
+ <span>${learningStatus ? stateDescription : service.label}</span>
11078
10991
  <span class="inspector-home-feature-label-icon" aria-hidden="true"
11079
10992
  >${this.renderIcon("ArrowUpRight")}</span
11080
10993
  >
11081
10994
  </a>
11082
10995
  <span class="inspector-home-feature-actions">
11083
- ${service.enabled ? lit.nothing : lit.html`
10996
+ ${learningUnavailable ? lit.html`<button type="button" class="inspector-home-feature-action" aria-label="Retry Learning status"
10997
+ ?disabled=${this.learningLoading || this.learningRefreshing}
10998
+ @click=${this.retryLearningStatus}>Retry</button>` : lit.nothing}
10999
+ ${service.enabled || learningUnavailable ? lit.nothing : lit.html`
11084
11000
  <button
11085
11001
  type="button"
11086
11002
  class="inspector-home-feature-action inspector-system-health-url"
@@ -11124,6 +11040,10 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
11124
11040
  </p>
11125
11041
  ` : lit.html`
11126
11042
  <div class="inspector-home-feature-groups">
11043
+ ${unavailableServices.length ? lit.html`
11044
+ <section class="inspector-home-feature-group" data-feature-state-group="unavailable" aria-label="Feature status unavailable">
11045
+ <div class="inspector-home-feature-list" role="list">${unavailableServices.map(renderService)}</div>
11046
+ </section>` : lit.nothing}
11127
11047
  <section
11128
11048
  class="inspector-home-feature-group"
11129
11049
  data-feature-state-group="active"
@@ -12709,6 +12629,10 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
12709
12629
  if (this.selectedMenu === "frontend-tools") return this.renderToolsView();
12710
12630
  if (this.selectedMenu === "capabilities") return this.renderCapabilitiesView();
12711
12631
  if (this.selectedMenu === "agent-context") return this.renderContextView();
12632
+ if (this.selectedMenu === "generative-ui") return lit.html`<cpk-generative-ui-view
12633
+ data-color-scheme=${this.colorScheme}
12634
+ .source=${this._core?.ɵgenerativeUIDebugSource}
12635
+ ></cpk-generative-ui-view>`;
12712
12636
  if (this.selectedMenu === "threads") return this.renderThreadsView();
12713
12637
  if (this.selectedMenu === "memories") return this.renderMemoriesView();
12714
12638
  return lit.nothing;
@@ -14560,7 +14484,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
14560
14484
  >
14561
14485
  ${isExpanded ? lit.html`
14562
14486
  <div class="group relative">
14563
- ${renderHighlightedJsonBlock(extractedEvent)}
14487
+ ${require_json_block.renderHighlightedJsonBlock(extractedEvent)}
14564
14488
  <button
14565
14489
  class="absolute right-0 top-0 cursor-pointer rounded px-2 py-1 text-[10px] opacity-0 transition group-hover:opacity-100 ${this.copiedEvents.has(event.id) ? "bg-green-100 text-green-700" : "bg-gray-100 text-gray-600 hover:bg-gray-200 hover:text-gray-900"}"
14566
14490
  @click=${(e) => {
@@ -14759,7 +14683,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
14759
14683
  <h4>Current State</h4>
14760
14684
  </div>
14761
14685
  <div class="overflow-auto p-4">
14762
- ${this.hasRenderableState(state) ? renderHighlightedJsonBlock(state, { maxHeight: "16rem" }) : lit.html`
14686
+ ${this.hasRenderableState(state) ? require_json_block.renderHighlightedJsonBlock(state, { maxHeight: "16rem" }) : lit.html`
14763
14687
  <div
14764
14688
  class="flex h-12 items-center justify-center text-xs text-gray-500"
14765
14689
  >
@@ -15585,7 +15509,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
15585
15509
  ${this.copiedContextItems.has(id) ? "Copied" : "Copy JSON"}
15586
15510
  </button>
15587
15511
  </div>
15588
- ${renderHighlightedJsonBlock(context.value, { maxHeight: "180px" })}
15512
+ ${require_json_block.renderHighlightedJsonBlock(context.value, { maxHeight: "180px" })}
15589
15513
  ` : lit.html`
15590
15514
  <div class="flex items-center justify-center py-4 text-xs text-gray-500">
15591
15515
  <span>No value available</span>
@@ -15597,7 +15521,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
15597
15521
  `;
15598
15522
  }
15599
15523
  getContextValuePreview(value) {
15600
- const parsed = coerceJsonValue(value);
15524
+ const parsed = require_json_block.coerceJsonValue(value);
15601
15525
  if (parsed === void 0 || parsed === null) return "—";
15602
15526
  if (typeof parsed === "string") return parsed.length > 50 ? `${parsed.slice(0, 50)}...` : parsed;
15603
15527
  if (typeof parsed === "number" || typeof parsed === "boolean") return String(parsed);
@@ -15643,7 +15567,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
15643
15567
  if (value === void 0) return "undefined";
15644
15568
  if (value === null) return "null";
15645
15569
  if (typeof value === "function") return value.toString();
15646
- const pretty = this.formatStateForDisplay(coerceJsonValue(value));
15570
+ const pretty = this.formatStateForDisplay(require_json_block.coerceJsonValue(value));
15647
15571
  return pretty.length > 0 ? pretty : String(value);
15648
15572
  }
15649
15573
  async copyContextValue(value, contextId, event) {
@@ -16269,10 +16193,10 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
16269
16193
  renderer.link = (href, title, text) => {
16270
16194
  return `<a href="${this.escapeHtmlAttr(this.isSafeAnnouncementHref(href ?? "") ? this.appendRefParam(href ?? "") : "#")}" target="_blank" rel="noopener"${title ? ` title="${this.escapeHtmlAttr(title)}"` : ""}>${text}</a>`;
16271
16195
  };
16272
- renderer.html = (html) => escapeHtml(html);
16196
+ renderer.html = (html) => require_json_block.escapeHtml(html);
16273
16197
  renderer.code = (code, lang) => {
16274
16198
  const safeLang = (lang ?? "").replace(/[^a-z0-9-]/gi, "");
16275
- return `<div class="announcement-code"><pre><code${safeLang ? ` class="language-${safeLang}"` : ""}>${escapeHtml(code)}</code></pre><div class="announcement-code__copy-shield"><button type="button" class="announcement-code__copy" data-copy="${this.encodeBase64(code)}" aria-label="Copy code">Copy</button></div></div>`;
16199
+ return `<div class="announcement-code"><pre><code${safeLang ? ` class="language-${safeLang}"` : ""}>${require_json_block.escapeHtml(code)}</code></pre><div class="announcement-code__copy-shield"><button type="button" class="announcement-code__copy" data-copy="${this.encodeBase64(code)}" aria-label="Copy code">Copy</button></div></div>`;
16276
16200
  };
16277
16201
  return marked.marked.parse(markdown, {
16278
16202
  renderer,
@@ -16321,7 +16245,7 @@ var WebInspectorElement = class WebInspectorElement extends lit.LitElement {
16321
16245
  return hostname === "copilotkit.ai" || hostname.endsWith(".copilotkit.ai");
16322
16246
  }
16323
16247
  escapeHtmlAttr(value) {
16324
- return escapeHtml(value).replace(/"/g, "&quot;").replace(/'/g, "&#39;");
16248
+ return require_json_block.escapeHtml(value).replace(/"/g, "&quot;").replace(/'/g, "&#39;");
16325
16249
  }
16326
16250
  };
16327
16251
  function defineWebInspector(registry = globalThis.customElements) {
@@ -16330,7 +16254,7 @@ function defineWebInspector(registry = globalThis.customElements) {
16330
16254
  defineElementOnce(registry, THREAD_INSPECTOR_TAG, CpkThreadInspector);
16331
16255
  defineElementOnce(registry, "cpk-thread-details", ɵCpkThreadDetails);
16332
16256
  defineElementOnce(registry, "cpk-memory-list", CpkMemoryList);
16333
- defineElementOnce(registry, JSON_BLOCK_TAG, CpkJsonBlock);
16257
+ defineElementOnce(registry, require_json_block.JSON_BLOCK_TAG, require_json_block.CpkJsonBlock);
16334
16258
  defineElementOnce(registry, WEB_INSPECTOR_TAG, WebInspectorElement);
16335
16259
  }
16336
16260
  /**
@@ -16353,7 +16277,7 @@ exports.WEB_INSPECTOR_TAG = WEB_INSPECTOR_TAG;
16353
16277
  exports.WebInspectorElement = WebInspectorElement;
16354
16278
  exports.configureWebInspectorElement = configureWebInspectorElement;
16355
16279
  exports.defineWebInspector = defineWebInspector;
16356
- exports.setInspectorJsonRenderer = setInspectorJsonRenderer;
16280
+ exports.setInspectorJsonRenderer = require_json_block.setInspectorJsonRenderer;
16357
16281
  exports.ɵCpkThreadDetails = ɵCpkThreadDetails;
16358
16282
  exports.ɵbuildCapabilityRows = buildCapabilityRows;
16359
16283
  exports.ɵmaxRecallScore = maxRecallScore;