Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_generated = require('./styles/generated.cjs'); const require_inspector_logo = require('./assets/inspector-logo.cjs'); const require_inspector_logo_icon = require('./assets/inspector-logo-icon.cjs'); const require_context_helpers = require('./lib/context-helpers.cjs'); const require_persistence = require('./lib/persistence.cjs'); let lit = require("lit"); let lit_directives_style_map_js = require("lit/directives/style-map.js"); let lit_directives_unsafe_html_js = require("lit/directives/unsafe-html.js"); let marked = require("marked"); let lucide = require("lucide"); let _copilotkitnext_core = require("@copilotkitnext/core"); //#region src/index.ts const WEB_INSPECTOR_TAG = "cpk-web-inspector"; const EDGE_MARGIN = 16; const DRAG_THRESHOLD = 6; const MIN_WINDOW_WIDTH = 600; const MIN_WINDOW_WIDTH_DOCKED_LEFT = 420; const MIN_WINDOW_HEIGHT = 200; const INSPECTOR_STORAGE_KEY = "cpk:inspector:state"; const ANNOUNCEMENT_STORAGE_KEY = "cpk:inspector:announcements"; const ANNOUNCEMENT_URL = "https://cdn.copilotkit.ai/announcements.json"; const DEFAULT_BUTTON_SIZE = { width: 48, height: 48 }; const DEFAULT_WINDOW_SIZE = { width: 840, height: 560 }; const DOCKED_LEFT_WIDTH = 500; const MAX_AGENT_EVENTS = 200; const MAX_TOTAL_EVENTS = 500; const AGENT_EVENT_TYPES = [ "RUN_STARTED", "RUN_FINISHED", "RUN_ERROR", "TEXT_MESSAGE_START", "TEXT_MESSAGE_CONTENT", "TEXT_MESSAGE_END", "TOOL_CALL_START", "TOOL_CALL_ARGS", "TOOL_CALL_END", "TOOL_CALL_RESULT", "STATE_SNAPSHOT", "STATE_DELTA", "MESSAGES_SNAPSHOT", "RAW_EVENT", "CUSTOM_EVENT", "REASONING_START", "REASONING_MESSAGE_START", "REASONING_MESSAGE_CONTENT", "REASONING_MESSAGE_END", "REASONING_END", "REASONING_ENCRYPTED_VALUE" ]; var WebInspectorElement = class extends lit.LitElement { constructor(..._args) { super(..._args); this._core = null; this.coreSubscriber = null; this.coreUnsubscribe = null; this.runtimeStatus = null; this.coreProperties = {}; this.lastCoreError = null; this.agentSubscriptions = /* @__PURE__ */ new Map(); this.agentEvents = /* @__PURE__ */ new Map(); this.agentMessages = /* @__PURE__ */ new Map(); this.agentStates = /* @__PURE__ */ new Map(); this.flattenedEvents = []; this.eventCounter = 0; this.contextStore = {}; this.pointerId = null; this.dragStart = null; this.dragOffset = { x: 0, y: 0 }; this.isDragging = false; this.pointerContext = null; this.isOpen = false; this.draggedDuringInteraction = false; this.ignoreNextButtonClick = false; this.selectedMenu = "ag-ui-events"; this.contextMenuOpen = false; this.dockMode = "floating"; this.previousBodyMargins = null; this.transitionTimeoutId = null; this.pendingSelectedContext = null; this.autoAttachCore = true; this.attemptedAutoAttach = false; this.cachedTools = []; this.toolSignature = ""; this.eventFilterText = ""; this.eventTypeFilter = "all"; this.announcementMarkdown = null; this.announcementHtml = null; this.announcementTimestamp = null; this.announcementPreviewText = null; this.hasUnseenAnnouncement = false; this.announcementLoaded = false; this.announcementLoadError = null; this.announcementPromise = null; this.showAnnouncementPreview = true; this.contextState = { button: { position: { x: EDGE_MARGIN, y: EDGE_MARGIN }, size: { ...DEFAULT_BUTTON_SIZE }, anchor: { horizontal: "right", vertical: "top" }, anchorOffset: { x: EDGE_MARGIN, y: EDGE_MARGIN } }, window: { position: { x: EDGE_MARGIN, y: EDGE_MARGIN }, size: { ...DEFAULT_WINDOW_SIZE }, anchor: { horizontal: "right", vertical: "top" }, anchorOffset: { x: EDGE_MARGIN, y: EDGE_MARGIN } } }; this.hasCustomPosition = { button: false, window: false }; this.resizePointerId = null; this.resizeStart = null; this.resizeInitialSize = null; this.isResizing = false; this.menuItems = [ { key: "ag-ui-events", label: "AG-UI Events", icon: "Zap" }, { key: "agents", label: "Agent", icon: "Bot" }, { key: "frontend-tools", label: "Frontend Tools", icon: "Hammer" }, { key: "agent-context", label: "Context", icon: "FileText" } ]; this.handlePointerDown = (event) => { if (this.dockMode !== "floating" && this.isOpen) return; const target = event.currentTarget; const context = target?.dataset.dragContext === "window" ? "window" : "button"; const eventTarget = event.target; if (context === "window" && eventTarget?.closest("button")) return; this.pointerContext = context; this.measureContext(context); event.preventDefault(); this.pointerId = event.pointerId; this.dragStart = { x: event.clientX, y: event.clientY }; const state = this.contextState[context]; this.dragOffset = { x: event.clientX - state.position.x, y: event.clientY - state.position.y }; this.isDragging = false; this.draggedDuringInteraction = false; this.ignoreNextButtonClick = false; target?.setPointerCapture?.(this.pointerId); }; this.handlePointerMove = (event) => { if (this.pointerId !== event.pointerId || !this.dragStart || !this.pointerContext) return; const distance = Math.hypot(event.clientX - this.dragStart.x, event.clientY - this.dragStart.y); if (!this.isDragging && distance < DRAG_THRESHOLD) return; event.preventDefault(); this.setDragging(true); this.draggedDuringInteraction = true; const desired = { x: event.clientX - this.dragOffset.x, y: event.clientY - this.dragOffset.y }; const constrained = this.constrainToViewport(desired, this.pointerContext); this.contextState[this.pointerContext].position = constrained; this.updateHostTransform(this.pointerContext); }; this.handlePointerUp = (event) => { if (this.pointerId !== event.pointerId) return; const target = event.currentTarget; if (target?.hasPointerCapture(this.pointerId)) target.releasePointerCapture(this.pointerId); const context = this.pointerContext ?? this.activeContext; if (this.isDragging && this.pointerContext) { event.preventDefault(); this.setDragging(false); if (this.pointerContext === "window") { this.updateAnchorFromPosition(this.pointerContext); this.hasCustomPosition.window = true; this.applyAnchorPosition(this.pointerContext); } else if (this.pointerContext === "button") { this.snapButtonToCorner(); this.hasCustomPosition.button = true; if (this.draggedDuringInteraction) this.ignoreNextButtonClick = true; } } else if (context === "button" && !this.isOpen && !this.draggedDuringInteraction) this.openInspector(); this.resetPointerTracking(); }; this.handlePointerCancel = (event) => { if (this.pointerId !== event.pointerId) return; const target = event.currentTarget; if (target?.hasPointerCapture(this.pointerId)) target.releasePointerCapture(this.pointerId); this.resetPointerTracking(); }; this.handleButtonClick = (event) => { if (this.isDragging) { event.preventDefault(); return; } if (this.ignoreNextButtonClick) { event.preventDefault(); this.ignoreNextButtonClick = false; return; } if (!this.isOpen) { event.preventDefault(); this.openInspector(); } }; this.handleClosePointerDown = (event) => { event.stopPropagation(); event.preventDefault(); }; this.handleCloseClick = () => { this.closeInspector(); }; this.handleResizePointerDown = (event) => { event.stopPropagation(); event.preventDefault(); this.hasCustomPosition.window = true; this.isResizing = true; this.resizePointerId = event.pointerId; this.resizeStart = { x: event.clientX, y: event.clientY }; this.resizeInitialSize = { ...this.contextState.window.size }; if (document.body && this.dockMode !== "floating") document.body.style.transition = ""; event.currentTarget?.setPointerCapture?.(event.pointerId); }; this.handleResizePointerMove = (event) => { if (!this.isResizing || this.resizePointerId !== event.pointerId || !this.resizeStart || !this.resizeInitialSize) return; event.preventDefault(); const deltaX = event.clientX - this.resizeStart.x; const deltaY = event.clientY - this.resizeStart.y; const state = this.contextState.window; if (this.dockMode === "docked-left") { state.size = this.clampWindowSize({ width: this.resizeInitialSize.width + deltaX, height: state.size.height }); if (document.body) document.body.style.marginLeft = `${state.size.width}px`; } else { state.size = this.clampWindowSize({ width: this.resizeInitialSize.width + deltaX, height: this.resizeInitialSize.height + deltaY }); this.keepPositionWithinViewport("window"); this.updateAnchorFromPosition("window"); } this.requestUpdate(); this.updateHostTransform("window"); }; this.handleResizePointerUp = (event) => { if (this.resizePointerId !== event.pointerId) return; const target = event.currentTarget; if (target?.hasPointerCapture(this.resizePointerId)) target.releasePointerCapture(this.resizePointerId); if (this.dockMode === "floating") { this.updateAnchorFromPosition("window"); this.applyAnchorPosition("window"); } this.persistState(); this.resetResizeTracking(); }; this.handleResizePointerCancel = (event) => { if (this.resizePointerId !== event.pointerId) return; const target = event.currentTarget; if (target?.hasPointerCapture(this.resizePointerId)) target.releasePointerCapture(this.resizePointerId); if (this.dockMode === "floating") { this.updateAnchorFromPosition("window"); this.applyAnchorPosition("window"); } this.persistState(); this.resetResizeTracking(); }; this.handleResize = () => { this.measureContext("button"); this.applyAnchorPosition("button"); this.measureContext("window"); if (this.hasCustomPosition.window) this.applyAnchorPosition("window"); else this.centerContext("window"); this.updateHostTransform(); }; this.contextOptions = [{ key: "all-agents", label: "All Agents" }]; this.selectedContext = "all-agents"; this.expandedRows = /* @__PURE__ */ new Set(); this.copiedEvents = /* @__PURE__ */ new Set(); this.expandedTools = /* @__PURE__ */ new Set(); this.expandedContextItems = /* @__PURE__ */ new Set(); this.copiedContextItems = /* @__PURE__ */ new Set(); this.handleClearEvents = () => { if (this.selectedContext === "all-agents") { this.agentEvents.clear(); this.flattenedEvents = []; } else { this.agentEvents.delete(this.selectedContext); this.flattenedEvents = this.flattenedEvents.filter((event) => event.agentId !== this.selectedContext); } this.expandedRows.clear(); this.copiedEvents.clear(); this.requestUpdate(); }; this.handleGlobalPointerDown = (event) => { if (!this.contextMenuOpen) return; if (!event.composedPath().some((node) => { return node instanceof HTMLElement && node.dataset?.contextDropdownRoot === "true"; })) { this.contextMenuOpen = false; this.requestUpdate(); } }; this.handleDismissAnnouncement = () => { this.markAnnouncementSeen(); }; } static { this.properties = { core: { attribute: false }, autoAttachCore: { type: Boolean, attribute: "auto-attach-core" } }; } get core() { return this._core; } set core(value) { const oldValue = this._core; if (oldValue === value) return; this.detachFromCore(); this._core = value ?? null; this.requestUpdate("core", oldValue); if (this._core) this.attachToCore(this._core); } attachToCore(core) { this.runtimeStatus = core.runtimeConnectionStatus; this.coreProperties = core.properties; this.lastCoreError = null; this.coreSubscriber = { onRuntimeConnectionStatusChanged: ({ status }) => { this.runtimeStatus = status; this.requestUpdate(); }, onPropertiesChanged: ({ properties }) => { this.coreProperties = properties; this.requestUpdate(); }, onError: ({ code, error }) => { this.lastCoreError = { code, message: error.message }; this.requestUpdate(); }, onAgentsChanged: ({ agents }) => { this.processAgentsChanged(agents); }, onContextChanged: ({ context }) => { this.contextStore = this.normalizeContextStore(context); this.requestUpdate(); } }; this.coreUnsubscribe = core.subscribe(this.coreSubscriber).unsubscribe; this.processAgentsChanged(core.agents); if (core.context) this.contextStore = this.normalizeContextStore(core.context); } detachFromCore() { if (this.coreUnsubscribe) { this.coreUnsubscribe(); this.coreUnsubscribe = null; } this.coreSubscriber = null; this.runtimeStatus = null; this.lastCoreError = null; this.coreProperties = {}; this.cachedTools = []; this.toolSignature = ""; this.teardownAgentSubscriptions(); } teardownAgentSubscriptions() { for (const unsubscribe of this.agentSubscriptions.values()) unsubscribe(); this.agentSubscriptions.clear(); this.agentEvents.clear(); this.agentMessages.clear(); this.agentStates.clear(); this.flattenedEvents = []; this.eventCounter = 0; } processAgentsChanged(agents) { const seenAgentIds = /* @__PURE__ */ new Set(); for (const agent of Object.values(agents)) { if (!agent?.agentId) continue; seenAgentIds.add(agent.agentId); this.subscribeToAgent(agent); } for (const agentId of Array.from(this.agentSubscriptions.keys())) if (!seenAgentIds.has(agentId)) { this.unsubscribeFromAgent(agentId); this.agentEvents.delete(agentId); this.agentMessages.delete(agentId); this.agentStates.delete(agentId); } this.updateContextOptions(seenAgentIds); this.refreshToolsSnapshot(); this.requestUpdate(); } refreshToolsSnapshot() { if (!this._core) { if (this.cachedTools.length > 0) { this.cachedTools = []; this.toolSignature = ""; this.requestUpdate(); } return; } const tools = this.extractToolsFromAgents(); const signature = JSON.stringify(tools.map((tool) => ({ agentId: tool.agentId, name: tool.name, type: tool.type, hasDescription: Boolean(tool.description), hasParameters: Boolean(tool.parameters) }))); if (signature !== this.toolSignature) { this.toolSignature = signature; this.cachedTools = tools; this.requestUpdate(); } } tryAutoAttachCore() { if (this.attemptedAutoAttach || this._core || !this.autoAttachCore || typeof window === "undefined") return; this.attemptedAutoAttach = true; const globalWindow = window; const foundCore = [ globalWindow.__COPILOTKIT_CORE__, globalWindow.copilotkit?.core, globalWindow.copilotkitCore ].find((candidate) => !!candidate && typeof candidate === "object"); if (foundCore) this.core = foundCore; } subscribeToAgent(agent) { if (!agent.agentId) return; const agentId = agent.agentId; this.unsubscribeFromAgent(agentId); const { unsubscribe } = agent.subscribe({ onRunStartedEvent: ({ event }) => { this.recordAgentEvent(agentId, "RUN_STARTED", event); }, onRunFinishedEvent: ({ event, result }) => { this.recordAgentEvent(agentId, "RUN_FINISHED", { event, result }); }, onRunErrorEvent: ({ event }) => { this.recordAgentEvent(agentId, "RUN_ERROR", event); }, onTextMessageStartEvent: ({ event }) => { this.recordAgentEvent(agentId, "TEXT_MESSAGE_START", event); }, onTextMessageContentEvent: ({ event, textMessageBuffer }) => { this.recordAgentEvent(agentId, "TEXT_MESSAGE_CONTENT", { event, textMessageBuffer }); }, onTextMessageEndEvent: ({ event, textMessageBuffer }) => { this.recordAgentEvent(agentId, "TEXT_MESSAGE_END", { event, textMessageBuffer }); }, onToolCallStartEvent: ({ event }) => { this.recordAgentEvent(agentId, "TOOL_CALL_START", event); }, onToolCallArgsEvent: ({ event, toolCallBuffer, toolCallName, partialToolCallArgs }) => { this.recordAgentEvent(agentId, "TOOL_CALL_ARGS", { event, toolCallBuffer, toolCallName, partialToolCallArgs }); }, onToolCallEndEvent: ({ event, toolCallArgs, toolCallName }) => { this.recordAgentEvent(agentId, "TOOL_CALL_END", { event, toolCallArgs, toolCallName }); }, onToolCallResultEvent: ({ event }) => { this.recordAgentEvent(agentId, "TOOL_CALL_RESULT", event); }, onStateSnapshotEvent: ({ event }) => { this.recordAgentEvent(agentId, "STATE_SNAPSHOT", event); this.syncAgentState(agent); }, onStateDeltaEvent: ({ event }) => { this.recordAgentEvent(agentId, "STATE_DELTA", event); this.syncAgentState(agent); }, onMessagesSnapshotEvent: ({ event }) => { this.recordAgentEvent(agentId, "MESSAGES_SNAPSHOT", event); this.syncAgentMessages(agent); }, onMessagesChanged: () => { this.syncAgentMessages(agent); }, onRawEvent: ({ event }) => { this.recordAgentEvent(agentId, "RAW_EVENT", event); }, onCustomEvent: ({ event }) => { this.recordAgentEvent(agentId, "CUSTOM_EVENT", event); }, onReasoningStartEvent: ({ event }) => { this.recordAgentEvent(agentId, "REASONING_START", event); }, onReasoningMessageStartEvent: ({ event }) => { this.recordAgentEvent(agentId, "REASONING_MESSAGE_START", event); }, onReasoningMessageContentEvent: ({ event, reasoningMessageBuffer }) => { this.recordAgentEvent(agentId, "REASONING_MESSAGE_CONTENT", { event, reasoningMessageBuffer }); }, onReasoningMessageEndEvent: ({ event, reasoningMessageBuffer }) => { this.recordAgentEvent(agentId, "REASONING_MESSAGE_END", { event, reasoningMessageBuffer }); }, onReasoningEndEvent: ({ event }) => { this.recordAgentEvent(agentId, "REASONING_END", event); }, onReasoningEncryptedValueEvent: ({ event }) => { this.recordAgentEvent(agentId, "REASONING_ENCRYPTED_VALUE", event); } }); this.agentSubscriptions.set(agentId, unsubscribe); this.syncAgentMessages(agent); this.syncAgentState(agent); if (!this.agentEvents.has(agentId)) this.agentEvents.set(agentId, []); } unsubscribeFromAgent(agentId) { const unsubscribe = this.agentSubscriptions.get(agentId); if (unsubscribe) { unsubscribe(); this.agentSubscriptions.delete(agentId); } } recordAgentEvent(agentId, type, payload) { const eventId = `${agentId}:${++this.eventCounter}`; const normalizedPayload = this.normalizeEventPayload(type, payload); const event = { id: eventId, agentId, type, timestamp: Date.now(), payload: normalizedPayload }; const nextAgentEvents = [event, ...this.agentEvents.get(agentId) ?? []].slice(0, MAX_AGENT_EVENTS); this.agentEvents.set(agentId, nextAgentEvents); this.flattenedEvents = [event, ...this.flattenedEvents].slice(0, MAX_TOTAL_EVENTS); this.refreshToolsSnapshot(); this.requestUpdate(); } syncAgentMessages(agent) { if (!agent?.agentId) return; const messages = this.normalizeAgentMessages(agent.messages); if (messages) this.agentMessages.set(agent.agentId, messages); else this.agentMessages.delete(agent.agentId); this.requestUpdate(); } syncAgentState(agent) { if (!agent?.agentId) return; const state = agent.state; if (state === void 0 || state === null) this.agentStates.delete(agent.agentId); else this.agentStates.set(agent.agentId, this.sanitizeForLogging(state)); this.requestUpdate(); } updateContextOptions(agentIds) { const nextOptions = [{ key: "all-agents", label: "All Agents" }, ...Array.from(agentIds).sort((a, b) => a.localeCompare(b)).map((id) => ({ key: id, label: id }))]; if (this.contextOptions.length !== nextOptions.length || this.contextOptions.some((option, index) => option.key !== nextOptions[index]?.key)) this.contextOptions = nextOptions; const pendingContext = this.pendingSelectedContext; if (pendingContext) { if (pendingContext === "all-agents" || agentIds.has(pendingContext)) { if (this.selectedContext !== pendingContext) { this.selectedContext = pendingContext; this.expandedRows.clear(); } this.pendingSelectedContext = null; } else if (agentIds.size > 0) this.pendingSelectedContext = null; } if (!nextOptions.some((option) => option.key === this.selectedContext) && this.pendingSelectedContext === null) { let nextSelected = "all-agents"; if (agentIds.has("default")) nextSelected = "default"; else if (agentIds.size > 0) nextSelected = Array.from(agentIds).sort((a, b) => a.localeCompare(b))[0]; if (this.selectedContext !== nextSelected) { this.selectedContext = nextSelected; this.expandedRows.clear(); this.persistState(); } } } getEventsForSelectedContext() { if (this.selectedContext === "all-agents") return this.flattenedEvents; return this.agentEvents.get(this.selectedContext) ?? []; } filterEvents(events) { const query = this.eventFilterText.trim().toLowerCase(); return events.filter((event) => { if (this.eventTypeFilter !== "all" && event.type !== this.eventTypeFilter) return false; if (!query) return true; const payloadText = this.stringifyPayload(event.payload, false).toLowerCase(); return event.type.toLowerCase().includes(query) || event.agentId.toLowerCase().includes(query) || payloadText.includes(query); }); } getLatestStateForAgent(agentId) { if (this.agentStates.has(agentId)) { const value = this.agentStates.get(agentId); return value === void 0 ? null : value; } const stateEvent = (this.agentEvents.get(agentId) ?? []).find((e) => e.type === "STATE_SNAPSHOT"); if (!stateEvent) return null; return stateEvent.payload; } getLatestMessagesForAgent(agentId) { return this.agentMessages.get(agentId) ?? null; } getAgentStatus(agentId) { const events = this.agentEvents.get(agentId) ?? []; if (events.length === 0) return "idle"; const runEvent = events.find((e) => e.type === "RUN_STARTED" || e.type === "RUN_FINISHED" || e.type === "RUN_ERROR"); if (!runEvent) return "idle"; if (runEvent.type === "RUN_ERROR") return "error"; if (runEvent.type === "RUN_STARTED") return events.find((e) => e.type === "RUN_FINISHED" && e.timestamp > runEvent.timestamp) ? "idle" : "running"; return "idle"; } getAgentStats(agentId) { const events = this.agentEvents.get(agentId) ?? []; const messages = this.agentMessages.get(agentId); const toolCallCount = messages ? messages.reduce((count, message) => count + (message.toolCalls?.length ?? 0), 0) : events.filter((e) => e.type === "TOOL_CALL_END").length; const messageCount = messages?.length ?? 0; return { totalEvents: events.length, lastActivity: events[0]?.timestamp ?? null, messages: messageCount, toolCalls: toolCallCount, errors: events.filter((e) => e.type === "RUN_ERROR").length }; } renderToolCallDetails(toolCalls) { if (!Array.isArray(toolCalls) || toolCalls.length === 0) return lit.nothing; return lit.html`
${toolCalls.map((call, index) => { const functionName = call.function?.name ?? call.toolName ?? "Unknown function"; const callId = typeof call?.id === "string" ? call.id : `tool-call-${index + 1}`; const argsString = this.formatToolCallArguments(call.function?.arguments); return lit.html`
${functionName} ID: ${callId}
${argsString ? lit.html`
${argsString}
` : lit.nothing}
`; })}
`; } formatToolCallArguments(args) { if (args === void 0 || args === null || args === "") return null; if (typeof args === "string") try { const parsed = JSON.parse(args); return JSON.stringify(parsed, null, 2); } catch { return args; } if (typeof args === "object") try { return JSON.stringify(args, null, 2); } catch { return String(args); } return String(args); } hasRenderableState(state) { if (state === null || state === void 0) return false; if (Array.isArray(state)) return state.length > 0; if (typeof state === "object") return Object.keys(state).length > 0; if (typeof state === "string") { const trimmed = state.trim(); return trimmed.length > 0 && trimmed !== "{}"; } return true; } formatStateForDisplay(state) { if (state === null || state === void 0) return ""; if (typeof state === "string") { const trimmed = state.trim(); if (trimmed.length === 0) return ""; try { const parsed = JSON.parse(trimmed); return JSON.stringify(parsed, null, 2); } catch { return state; } } if (typeof state === "object") try { return JSON.stringify(state, null, 2); } catch { return String(state); } return String(state); } getEventBadgeClasses(type) { const base = "font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border"; if (type.startsWith("RUN_")) return `${base} bg-blue-50 text-blue-700 border-blue-200`; if (type.startsWith("TEXT_MESSAGE")) return `${base} bg-emerald-50 text-emerald-700 border-emerald-200`; if (type.startsWith("TOOL_CALL")) return `${base} bg-amber-50 text-amber-700 border-amber-200`; if (type.startsWith("REASONING")) return `${base} bg-fuchsia-50 text-fuchsia-700 border-fuchsia-200`; if (type.startsWith("STATE")) return `${base} bg-violet-50 text-violet-700 border-violet-200`; if (type.startsWith("MESSAGES")) return `${base} bg-sky-50 text-sky-700 border-sky-200`; if (type === "RUN_ERROR") return `${base} bg-rose-50 text-rose-700 border-rose-200`; return `${base} bg-gray-100 text-gray-600 border-gray-200`; } stringifyPayload(payload, pretty) { try { if (payload === void 0) return pretty ? "undefined" : "undefined"; if (typeof payload === "string") return payload; return JSON.stringify(payload, null, pretty ? 2 : 0) ?? ""; } catch (error) { console.warn("Failed to stringify inspector payload", error); return String(payload); } } extractEventFromPayload(payload) { if (payload && typeof payload === "object" && "event" in payload) return payload.event; return payload; } async copyToClipboard(text, eventId) { try { await navigator.clipboard.writeText(text); this.copiedEvents.add(eventId); this.requestUpdate(); setTimeout(() => { this.copiedEvents.delete(eventId); this.requestUpdate(); }, 2e3); } catch (err) { console.error("Failed to copy to clipboard:", err); } } static { this.styles = [(0, lit.unsafeCSS)(require_generated.default), lit.css` :host { position: fixed; top: 0; left: 0; z-index: 2147483646; display: block; will-change: transform; } :host([data-transitioning="true"]) { transition: transform 300ms ease; } .console-button { transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 160ms ease; } .console-button[data-dragging="true"] { transition: opacity 160ms ease; } .inspector-window[data-transitioning="true"] { transition: width 300ms ease, height 300ms ease; } .inspector-window[data-docked="true"] { border-radius: 0 !important; box-shadow: none !important; } .resize-handle { touch-action: none; user-select: none; } .dock-resize-handle { position: absolute; top: 0; right: 0; width: 10px; height: 100%; cursor: ew-resize; touch-action: none; z-index: 50; background: transparent; } .tooltip-target { position: relative; } .tooltip-target::after { content: attr(data-tooltip); position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%) translateY(-4px); white-space: nowrap; background: rgba(17, 24, 39, 0.95); color: white; padding: 4px 8px; border-radius: 6px; font-size: 10px; line-height: 1.2; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15); opacity: 0; pointer-events: none; transition: opacity 120ms ease, transform 120ms ease; z-index: 4000; } .tooltip-target:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); } .announcement-preview { position: absolute; top: 50%; transform: translateY(-50%); min-width: 300px; max-width: 300px; background: white; color: #111827; font-size: 13px; line-height: 1.4; border-radius: 12px; box-shadow: 0 12px 28px rgba(15, 23, 42, 0.22); padding: 10px 12px; display: inline-flex; align-items: flex-start; gap: 8px; z-index: 4500; animation: fade-slide-in 160ms ease; border: 1px solid rgba(148, 163, 184, 0.35); white-space: normal; word-break: break-word; text-align: left; } .announcement-preview[data-side="left"] { right: 100%; margin-right: 10px; } .announcement-preview[data-side="right"] { left: 100%; margin-left: 10px; } .announcement-preview__arrow { position: absolute; width: 10px; height: 10px; background: white; border: 1px solid rgba(148, 163, 184, 0.35); transform: rotate(45deg); top: 50%; margin-top: -5px; z-index: -1; } .announcement-preview[data-side="left"] .announcement-preview__arrow { right: -5px; box-shadow: 6px -6px 10px rgba(15, 23, 42, 0.12); } .announcement-preview[data-side="right"] .announcement-preview__arrow { left: -5px; box-shadow: -6px 6px 10px rgba(15, 23, 42, 0.12); } .announcement-dismiss { color: #6b7280; font-size: 12px; padding: 2px 8px; border-radius: 8px; border: 1px solid rgba(148, 163, 184, 0.5); background: rgba(248, 250, 252, 0.9); transition: background 120ms ease, color 120ms ease; } .announcement-dismiss:hover { background: rgba(241, 245, 249, 1); color: #111827; } .announcement-content { color: #111827; font-size: 14px; line-height: 1.6; } .announcement-content h1, .announcement-content h2, .announcement-content h3 { font-weight: 700; margin: 0.4rem 0 0.2rem; } .announcement-content h1 { font-size: 1.1rem; } .announcement-content h2 { font-size: 1rem; } .announcement-content h3 { font-size: 0.95rem; } .announcement-content p { margin: 0.25rem 0; } .announcement-content ul { list-style: disc; padding-left: 1.25rem; margin: 0.3rem 0; } .announcement-content ol { list-style: decimal; padding-left: 1.25rem; margin: 0.3rem 0; } .announcement-content a { color: #0f766e; text-decoration: underline; } `]; } connectedCallback() { super.connectedCallback(); if (typeof window !== "undefined") { window.addEventListener("resize", this.handleResize); window.addEventListener("pointerdown", this.handleGlobalPointerDown); this.hydrateStateFromStorageEarly(); this.tryAutoAttachCore(); this.ensureAnnouncementLoading(); } } disconnectedCallback() { super.disconnectedCallback(); if (typeof window !== "undefined") { window.removeEventListener("resize", this.handleResize); window.removeEventListener("pointerdown", this.handleGlobalPointerDown); } this.removeDockStyles(); this.detachFromCore(); } firstUpdated() { if (typeof window === "undefined") return; if (!this._core) this.tryAutoAttachCore(); this.measureContext("button"); this.measureContext("window"); this.contextState.button.anchor = { horizontal: "right", vertical: "top" }; this.contextState.button.anchorOffset = { x: EDGE_MARGIN, y: EDGE_MARGIN }; this.contextState.window.anchor = { horizontal: "right", vertical: "top" }; this.contextState.window.anchorOffset = { x: EDGE_MARGIN, y: EDGE_MARGIN }; this.hydrateStateFromStorage(); if (this.isOpen && this.dockMode !== "floating") this.applyDockStyles(true); this.applyAnchorPosition("button"); if (this.dockMode === "floating") if (this.hasCustomPosition.window) this.applyAnchorPosition("window"); else this.centerContext("window"); this.ensureAnnouncementLoading(); this.updateHostTransform(this.isOpen ? "window" : "button"); } render() { return this.isOpen ? this.renderWindow() : this.renderButton(); } renderButton() { return lit.html` `; } renderWindow() { const windowState = this.contextState.window; const isDocked = this.dockMode !== "floating"; const isTransitioning = this.hasAttribute("data-transitioning"); const windowStyles = isDocked ? this.getDockedWindowStyles() : { width: `${Math.round(windowState.size.width)}px`, height: `${Math.round(windowState.size.height)}px`, minWidth: `${MIN_WINDOW_WIDTH}px`, minHeight: `${MIN_WINDOW_HEIGHT}px` }; const hasContextDropdown = this.contextOptions.length > 0; const contextDropdown = hasContextDropdown ? this.renderContextDropdown() : lit.nothing; const coreStatus = this.getCoreStatusSummary(); const agentSelector = hasContextDropdown ? contextDropdown : lit.html`
${this.renderIcon("Bot")} No agents available
`; return lit.html`
${isDocked ? lit.html` ` : lit.nothing}
Inspector logo
${agentSelector}
${this.renderDockControls()}
${this.menuItems.map(({ key, label, icon }) => { const isSelected = this.selectedMenu === key; return lit.html` `; })}
${this.renderAnnouncementPanel()} ${this.renderCoreWarningBanner()} ${this.renderMainContent()}
${this.renderIcon("Activity")} ${coreStatus.label} ${coreStatus.description}
`; } hydrateStateFromStorageEarly() { if (typeof document === "undefined" || typeof window === "undefined") return; const persisted = require_persistence.loadInspectorState(INSPECTOR_STORAGE_KEY); if (!persisted) return; if (typeof persisted.isOpen === "boolean") this.isOpen = persisted.isOpen; if (require_persistence.isValidDockMode(persisted.dockMode)) this.dockMode = persisted.dockMode; if (typeof persisted.selectedMenu === "string") { const validMenu = this.menuItems.find((item) => item.key === persisted.selectedMenu); if (validMenu) this.selectedMenu = validMenu.key; } if (typeof persisted.selectedContext === "string") { this.selectedContext = persisted.selectedContext; this.pendingSelectedContext = persisted.selectedContext; } } hydrateStateFromStorage() { if (typeof document === "undefined" || typeof window === "undefined") return; const persisted = require_persistence.loadInspectorState(INSPECTOR_STORAGE_KEY); if (!persisted) return; const persistedButton = persisted.button; if (persistedButton) { if (require_persistence.isValidAnchor(persistedButton.anchor)) this.contextState.button.anchor = persistedButton.anchor; if (require_persistence.isValidPosition(persistedButton.anchorOffset)) this.contextState.button.anchorOffset = persistedButton.anchorOffset; if (typeof persistedButton.hasCustomPosition === "boolean") this.hasCustomPosition.button = persistedButton.hasCustomPosition; } const persistedWindow = persisted.window; if (persistedWindow) { if (require_persistence.isValidAnchor(persistedWindow.anchor)) this.contextState.window.anchor = persistedWindow.anchor; if (require_persistence.isValidPosition(persistedWindow.anchorOffset)) this.contextState.window.anchorOffset = persistedWindow.anchorOffset; if (require_persistence.isValidSize(persistedWindow.size)) this.contextState.window.size = this.clampWindowSize(persistedWindow.size); if (typeof persistedWindow.hasCustomPosition === "boolean") this.hasCustomPosition.window = persistedWindow.hasCustomPosition; } if (typeof persisted.selectedContext === "string") { this.selectedContext = persisted.selectedContext; this.pendingSelectedContext = persisted.selectedContext; } } get activeContext() { return this.isOpen ? "window" : "button"; } measureContext(context) { const selector = context === "window" ? ".inspector-window" : ".console-button"; const element = this.renderRoot?.querySelector(selector); if (!element) return; const fallback = context === "window" ? DEFAULT_WINDOW_SIZE : DEFAULT_BUTTON_SIZE; require_context_helpers.updateSizeFromElement(this.contextState[context], element, fallback); } centerContext(context) { if (typeof window === "undefined") return; const viewport = this.getViewportSize(); require_context_helpers.centerContext(this.contextState[context], viewport, EDGE_MARGIN); if (context === this.activeContext) this.updateHostTransform(context); this.hasCustomPosition[context] = false; this.persistState(); } ensureWindowPlacement() { if (typeof window === "undefined") return; if (!this.hasCustomPosition.window) { this.centerContext("window"); return; } const viewport = this.getViewportSize(); require_context_helpers.keepPositionWithinViewport(this.contextState.window, viewport, EDGE_MARGIN); require_context_helpers.updateAnchorFromPosition(this.contextState.window, viewport, EDGE_MARGIN); this.updateHostTransform("window"); this.persistState(); } constrainToViewport(position, context) { if (typeof window === "undefined") return position; const viewport = this.getViewportSize(); return require_context_helpers.constrainToViewport(this.contextState[context], position, viewport, EDGE_MARGIN); } keepPositionWithinViewport(context) { if (typeof window === "undefined") return; const viewport = this.getViewportSize(); require_context_helpers.keepPositionWithinViewport(this.contextState[context], viewport, EDGE_MARGIN); } getViewportSize() { if (typeof window === "undefined") return { ...DEFAULT_WINDOW_SIZE }; return { width: window.innerWidth, height: window.innerHeight }; } persistState() { const state = { button: { anchor: this.contextState.button.anchor, anchorOffset: this.contextState.button.anchorOffset, hasCustomPosition: this.hasCustomPosition.button }, window: { anchor: this.contextState.window.anchor, anchorOffset: this.contextState.window.anchorOffset, size: { width: Math.round(this.contextState.window.size.width), height: Math.round(this.contextState.window.size.height) }, hasCustomPosition: this.hasCustomPosition.window }, isOpen: this.isOpen, dockMode: this.dockMode, selectedMenu: this.selectedMenu, selectedContext: this.selectedContext }; require_persistence.saveInspectorState(INSPECTOR_STORAGE_KEY, state); this.pendingSelectedContext = state.selectedContext ?? null; } clampWindowSize(size) { const minWidth = this.dockMode === "docked-left" ? MIN_WINDOW_WIDTH_DOCKED_LEFT : MIN_WINDOW_WIDTH; if (typeof window === "undefined") return { width: Math.max(minWidth, size.width), height: Math.max(MIN_WINDOW_HEIGHT, size.height) }; return require_context_helpers.clampSize(size, this.getViewportSize(), EDGE_MARGIN, minWidth, MIN_WINDOW_HEIGHT); } setDockMode(mode) { if (this.dockMode === mode) return; this.startHostTransition(); this.removeDockStyles(); this.dockMode = mode; if (mode !== "floating") { if (mode === "docked-left") this.contextState.window.size.width = DOCKED_LEFT_WIDTH; this.applyDockStyles(); } else { this.contextState.window.size = { ...DEFAULT_WINDOW_SIZE }; this.centerContext("window"); } this.persistState(); this.requestUpdate(); this.updateHostTransform("window"); } startHostTransition(duration = 300) { this.setAttribute("data-transitioning", "true"); if (this.transitionTimeoutId !== null) clearTimeout(this.transitionTimeoutId); this.transitionTimeoutId = setTimeout(() => { this.removeAttribute("data-transitioning"); this.transitionTimeoutId = null; }, duration); } applyDockStyles(skipTransition = false) { if (typeof document === "undefined" || !document.body) return; const computedStyle = window.getComputedStyle(document.body); this.previousBodyMargins = { left: computedStyle.marginLeft, bottom: computedStyle.marginBottom }; if (!this.isResizing && !skipTransition) document.body.style.transition = "margin 300ms ease"; if (this.dockMode === "docked-left") document.body.style.marginLeft = `${this.contextState.window.size.width}px`; if (!this.isResizing && !skipTransition) setTimeout(() => { if (document.body) document.body.style.transition = ""; }, 300); } removeDockStyles() { if (typeof document === "undefined" || !document.body) return; if (!this.isResizing) document.body.style.transition = "margin 300ms ease"; if (this.previousBodyMargins) { document.body.style.marginLeft = this.previousBodyMargins.left; document.body.style.marginBottom = this.previousBodyMargins.bottom; this.previousBodyMargins = null; } else { document.body.style.marginLeft = ""; document.body.style.marginBottom = ""; } setTimeout(() => { if (document.body) document.body.style.transition = ""; }, 300); } updateHostTransform(context = this.activeContext) { if (context !== this.activeContext) return; if (this.isOpen && this.dockMode === "docked-left") this.style.transform = `translate3d(0, 0, 0)`; else { const { position } = this.contextState[context]; this.style.transform = `translate3d(${position.x}px, ${position.y}px, 0)`; } } setDragging(value) { if (this.isDragging !== value) { this.isDragging = value; this.requestUpdate(); } } updateAnchorFromPosition(context) { if (typeof window === "undefined") return; const viewport = this.getViewportSize(); require_context_helpers.updateAnchorFromPosition(this.contextState[context], viewport, EDGE_MARGIN); } snapButtonToCorner() { if (typeof window === "undefined") return; const viewport = this.getViewportSize(); const state = this.contextState.button; const centerX = state.position.x + state.size.width / 2; const centerY = state.position.y + state.size.height / 2; state.anchor = { horizontal: centerX < viewport.width / 2 ? "left" : "right", vertical: centerY < viewport.height / 2 ? "top" : "bottom" }; state.anchorOffset = { x: EDGE_MARGIN, y: EDGE_MARGIN }; this.startHostTransition(); this.applyAnchorPosition("button"); } applyAnchorPosition(context) { if (typeof window === "undefined") return; const viewport = this.getViewportSize(); require_context_helpers.applyAnchorPosition(this.contextState[context], viewport, EDGE_MARGIN); this.updateHostTransform(context); this.persistState(); } resetResizeTracking() { this.resizePointerId = null; this.resizeStart = null; this.resizeInitialSize = null; this.isResizing = false; } resetPointerTracking() { this.pointerId = null; this.dragStart = null; this.pointerContext = null; this.setDragging(false); this.draggedDuringInteraction = false; } openInspector() { if (this.isOpen) return; this.showAnnouncementPreview = false; this.ensureAnnouncementLoading(); this.isOpen = true; this.persistState(); if (this.dockMode !== "floating") this.applyDockStyles(); this.ensureWindowPlacement(); this.requestUpdate(); this.updateComplete.then(() => { this.measureContext("window"); if (this.dockMode === "floating") if (this.hasCustomPosition.window) this.applyAnchorPosition("window"); else this.centerContext("window"); else this.updateHostTransform("window"); }); } closeInspector() { if (!this.isOpen) return; this.isOpen = false; if (this.dockMode !== "floating") this.removeDockStyles(); this.persistState(); this.updateHostTransform("button"); this.requestUpdate(); this.updateComplete.then(() => { this.measureContext("button"); this.applyAnchorPosition("button"); }); } renderIcon(name) { const iconNode = lucide.icons[name]; if (!iconNode) return lit.nothing; return (0, lit_directives_unsafe_html_js.unsafeHTML)(`${iconNode.map(([tag, attrs]) => `<${tag} ${this.serializeAttributes(attrs)} />`).join("")}`); } renderDockControls() { if (this.dockMode === "floating") return lit.html` `; else return lit.html` `; } getDockedWindowStyles() { if (this.dockMode === "docked-left") return { position: "fixed", top: "0", left: "0", bottom: "0", width: `${Math.round(this.contextState.window.size.width)}px`, height: "100vh", minWidth: `${MIN_WINDOW_WIDTH_DOCKED_LEFT}px`, borderRadius: "0" }; return { width: `${Math.round(this.contextState.window.size.width)}px`, height: `${Math.round(this.contextState.window.size.height)}px`, minWidth: `${MIN_WINDOW_WIDTH}px`, minHeight: `${MIN_WINDOW_HEIGHT}px` }; } handleDockClick(mode) { this.setDockMode(mode); } serializeAttributes(attributes) { return Object.entries(attributes).filter(([key, value]) => key !== "key" && value !== void 0 && value !== null && value !== "").map(([key, value]) => `${key}="${String(value).replace(/"/g, """)}"`).join(" "); } sanitizeForLogging(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) { if (value === void 0) return "[undefined]"; if (value === null || typeof value === "number" || typeof value === "boolean") return value; if (typeof value === "string") return value; if (typeof value === "bigint" || typeof value === "symbol" || typeof value === "function") return String(value); if (value instanceof Date) return value.toISOString(); if (Array.isArray(value)) { if (depth >= 4) return "[Truncated depth]"; return value.map((item) => this.sanitizeForLogging(item, depth + 1, seen)); } if (typeof value === "object") { if (seen.has(value)) return "[Circular]"; seen.add(value); if (depth >= 4) return "[Truncated depth]"; const result = {}; for (const [key, entry] of Object.entries(value)) result[key] = this.sanitizeForLogging(entry, depth + 1, seen); return result; } return String(value); } normalizeEventPayload(_type, payload) { if (payload && typeof payload === "object" && "event" in payload) { const { event, ...rest } = payload; const cleaned = Object.keys(rest).length === 0 ? event : { event, ...rest }; return this.sanitizeForLogging(cleaned); } return this.sanitizeForLogging(payload); } normalizeMessageContent(content) { if (typeof content === "string") return content; if (content && typeof content === "object" && "text" in content) { const maybeText = content.text; if (typeof maybeText === "string") return maybeText; } if (content === null || content === void 0) return ""; if (typeof content === "object") try { return JSON.stringify(this.sanitizeForLogging(content)); } catch { return ""; } return String(content); } normalizeToolCalls(raw) { if (!Array.isArray(raw)) return []; return raw.map((entry) => { if (!entry || typeof entry !== "object") return null; const call = entry; const fn = call.function; const functionName = typeof fn?.name === "string" ? fn.name : typeof call.toolName === "string" ? call.toolName : void 0; const args = fn && "arguments" in fn ? fn.arguments : call.arguments; const normalized = { id: typeof call.id === "string" ? call.id : void 0, toolName: typeof call.toolName === "string" ? call.toolName : functionName, status: typeof call.status === "string" ? call.status : void 0 }; if (functionName) normalized.function = { name: functionName, arguments: this.sanitizeForLogging(args) }; return normalized; }).filter((call) => Boolean(call)); } normalizeAgentMessage(message) { if (!message || typeof message !== "object") return null; const raw = message; const role = typeof raw.role === "string" ? raw.role : "unknown"; const contentText = this.normalizeMessageContent(raw.content); const toolCalls = this.normalizeToolCalls(raw.toolCalls); return { id: typeof raw.id === "string" ? raw.id : void 0, role, contentText, contentRaw: raw.content !== void 0 ? this.sanitizeForLogging(raw.content) : void 0, toolCalls }; } normalizeAgentMessages(messages) { if (!Array.isArray(messages)) return null; return messages.map((message) => this.normalizeAgentMessage(message)).filter((msg) => msg !== null); } normalizeContextStore(context) { if (!context || typeof context !== "object") return {}; const normalized = {}; for (const [key, entry] of Object.entries(context)) if (entry && typeof entry === "object" && "value" in entry) { const candidate = entry; normalized[key] = { description: typeof candidate.description === "string" && candidate.description.trim().length > 0 ? candidate.description : void 0, value: candidate.value }; } else normalized[key] = { value: entry }; return normalized; } getSelectedMenu() { return this.menuItems.find((item) => item.key === this.selectedMenu) ?? this.menuItems[0]; } renderCoreWarningBanner() { if (this._core) return lit.nothing; return lit.html`
${this.renderIcon("AlertTriangle")}
CopilotKit core not attached

Pass a live CopilotKitCore instance to <cpk-web-inspector> or expose it on window.__COPILOTKIT_CORE__ for auto-attach.

`; } getCoreStatusSummary() { if (!this._core) return { label: "Core not attached", tone: "border border-amber-200 bg-amber-50 text-amber-800", description: "Pass a CopilotKitCore instance to or enable auto-attach." }; const status = this.runtimeStatus ?? _copilotkitnext_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected; const lastErrorMessage = this.lastCoreError?.message; if (status === _copilotkitnext_core.CopilotKitCoreRuntimeConnectionStatus.Error) return { label: "Runtime error", tone: "border border-rose-200 bg-rose-50 text-rose-700", description: lastErrorMessage ?? "CopilotKit runtime reported an error." }; if (status === _copilotkitnext_core.CopilotKitCoreRuntimeConnectionStatus.Connecting) return { label: "Connecting", tone: "border border-amber-200 bg-amber-50 text-amber-800", description: "Waiting for CopilotKit runtime to finish connecting." }; if (status === _copilotkitnext_core.CopilotKitCoreRuntimeConnectionStatus.Connected) return { label: "Connected", tone: "border border-emerald-200 bg-emerald-50 text-emerald-700", description: "Live runtime connection established." }; return { label: "Disconnected", tone: "border border-gray-200 bg-gray-50 text-gray-700", description: lastErrorMessage ?? "Waiting for CopilotKit runtime to connect." }; } renderMainContent() { if (this.selectedMenu === "ag-ui-events") return this.renderEventsTable(); if (this.selectedMenu === "agents") return this.renderAgentsView(); if (this.selectedMenu === "frontend-tools") return this.renderToolsView(); if (this.selectedMenu === "agent-context") return this.renderContextView(); return lit.nothing; } renderEventsTable() { const events = this.getEventsForSelectedContext(); const filteredEvents = this.filterEvents(events); const selectedLabel = this.selectedContext === "all-agents" ? "all agents" : `agent ${this.selectedContext}`; if (events.length === 0) return lit.html`
${this.renderIcon("Zap")}

No events yet

Trigger an agent run to see live activity.

`; if (filteredEvents.length === 0) return lit.html`
${this.renderIcon("Filter")}

No events match the current filters.

`; return lit.html`
Showing ${filteredEvents.length} of ${events.length}${this.selectedContext === "all-agents" ? "" : ` for ${selectedLabel}`}
${filteredEvents.map((event, index) => { const rowBg = index % 2 === 0 ? "bg-white" : "bg-gray-50/50"; const badgeClasses = this.getEventBadgeClasses(event.type); const extractedEvent = this.extractEventFromPayload(event.payload); const inlineEvent = this.stringifyPayload(extractedEvent, false) || "—"; const prettyEvent = this.stringifyPayload(extractedEvent, true) || inlineEvent; const isExpanded = this.expandedRows.has(event.id); return lit.html` this.toggleRowExpansion(event.id)} > `; })}
Agent Time Event Type AG-UI Event
${event.agentId} ${new Date(event.timestamp).toLocaleTimeString()} ${event.type} ${isExpanded ? lit.html`
${prettyEvent}
` : inlineEvent}
`; } handleEventFilterInput(event) { this.eventFilterText = event.target?.value ?? ""; this.requestUpdate(); } handleEventTypeChange(event) { const value = event.target?.value; if (!value) return; this.eventTypeFilter = value; this.requestUpdate(); } resetEventFilters() { this.eventFilterText = ""; this.eventTypeFilter = "all"; this.requestUpdate(); } exportEvents(events) { try { const payload = JSON.stringify(events, null, 2); const blob = new Blob([payload], { type: "application/json" }); const url = URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = `copilotkit-events-${Date.now()}.json`; anchor.click(); URL.revokeObjectURL(url); } catch (error) { console.error("Failed to export events", error); } } renderAgentsView() { if (this.selectedContext === "all-agents") return lit.html`
${this.renderIcon("Bot")}

No agent selected

Select an agent from the dropdown above to view details.

`; const agentId = this.selectedContext; const status = this.getAgentStatus(agentId); const stats = this.getAgentStats(agentId); const state = this.getLatestStateForAgent(agentId); const messages = this.getLatestMessagesForAgent(agentId); return lit.html`
${this.renderIcon("Bot")}

${agentId}

${status.charAt(0).toUpperCase() + status.slice(1)}
${stats.lastActivity ? lit.html`Last activity: ${new Date(stats.lastActivity).toLocaleTimeString()}` : lit.nothing}
Messages
${stats.messages}
Tool Calls
${stats.toolCalls}
Errors
${stats.errors}

Current State

${this.hasRenderableState(state) ? lit.html`
${this.formatStateForDisplay(state)}
` : lit.html`
${this.renderIcon("Database")} State is empty
`}

Current Messages

${messages && messages.length > 0 ? lit.html` ${messages.map((msg) => { const role = msg.role || "unknown"; const roleColors = { user: "bg-blue-100 text-blue-800", assistant: "bg-green-100 text-green-800", system: "bg-gray-100 text-gray-800", tool: "bg-amber-100 text-amber-800", unknown: "bg-gray-100 text-gray-600" }; const rawContent = msg.contentText ?? ""; const toolCalls = msg.toolCalls ?? []; const hasContent = rawContent.trim().length > 0; const contentFallback = toolCalls.length > 0 ? "Invoked tool call" : "—"; return lit.html` `; })}
Role Content
${role} ${hasContent ? lit.html`
${rawContent}
` : lit.html`
${contentFallback}
`} ${role === "assistant" && toolCalls.length > 0 ? this.renderToolCallDetails(toolCalls) : lit.nothing}
` : lit.html`
${this.renderIcon("MessageSquare")} No messages available
`}
`; } renderContextDropdown() { const filteredOptions = this.selectedMenu === "agents" ? this.contextOptions.filter((opt) => opt.key !== "all-agents") : this.contextOptions; const selectedLabel = filteredOptions.find((opt) => opt.key === this.selectedContext)?.label ?? ""; return lit.html`
${this.contextMenuOpen ? lit.html`
${filteredOptions.map((option) => lit.html` `)}
` : lit.nothing}
`; } handleMenuSelect(key) { if (!this.menuItems.some((item) => item.key === key)) return; this.selectedMenu = key; if (key === "agents" && this.selectedContext === "all-agents") { const agentOptions = this.contextOptions.filter((opt) => opt.key !== "all-agents"); if (agentOptions.length > 0) { const defaultAgent = agentOptions.find((opt) => opt.key === "default"); this.selectedContext = defaultAgent ? defaultAgent.key : agentOptions[0].key; } } this.contextMenuOpen = false; this.persistState(); this.requestUpdate(); } handleContextDropdownToggle(event) { event.preventDefault(); event.stopPropagation(); this.contextMenuOpen = !this.contextMenuOpen; this.requestUpdate(); } handleContextOptionSelect(key) { if (!this.contextOptions.some((option) => option.key === key)) return; if (this.selectedContext !== key) { this.selectedContext = key; this.expandedRows.clear(); } this.contextMenuOpen = false; this.persistState(); this.requestUpdate(); } renderToolsView() { if (!this._core) return lit.html`
No core instance available
`; this.refreshToolsSnapshot(); const allTools = this.cachedTools; if (allTools.length === 0) return lit.html`
${this.renderIcon("Hammer")}

No tools available

Tools will appear here once agents are configured with tool handlers or renderers.

`; return lit.html`
${(this.selectedContext === "all-agents" ? allTools : allTools.filter((tool) => !tool.agentId || tool.agentId === this.selectedContext)).map((tool) => this.renderToolCard(tool))}
`; } extractToolsFromAgents() { if (!this._core) return []; const tools = []; for (const coreTool of this._core.tools ?? []) tools.push({ agentId: coreTool.agentId ?? "", name: coreTool.name, description: coreTool.description, parameters: coreTool.parameters, type: "handler" }); for (const [agentId, agent] of Object.entries(this._core.agents)) { if (!agent) continue; const handlers = agent.toolHandlers; if (handlers && typeof handlers === "object") { for (const [toolName, handler] of Object.entries(handlers)) if (handler && typeof handler === "object") { const handlerObj = handler; tools.push({ agentId, name: toolName, description: typeof handlerObj.description === "string" && handlerObj.description || handlerObj.tool?.description, parameters: handlerObj.parameters ?? handlerObj.tool?.parameters, type: "handler" }); } } const renderers = agent.toolRenderers; if (renderers && typeof renderers === "object") { for (const [toolName, renderer] of Object.entries(renderers)) if (!tools.some((t) => t.agentId === agentId && t.name === toolName)) { if (renderer && typeof renderer === "object") { const rendererObj = renderer; tools.push({ agentId, name: toolName, description: typeof rendererObj.description === "string" && rendererObj.description || rendererObj.tool?.description, parameters: rendererObj.parameters ?? rendererObj.tool?.parameters, type: "renderer" }); } } } } return tools.sort((a, b) => { const agentCompare = a.agentId.localeCompare(b.agentId); if (agentCompare !== 0) return agentCompare; return a.name.localeCompare(b.name); }); } renderToolCard(tool) { const isExpanded = this.expandedTools.has(`${tool.agentId}:${tool.name}`); const schema = this.extractSchemaInfo(tool.parameters); return lit.html`
${isExpanded ? lit.html`
${schema.properties.length > 0 ? lit.html`
Parameters
${schema.properties.map((prop) => lit.html`
${prop.name}
${prop.required ? lit.html`required` : lit.html`optional`} ${prop.type ? lit.html`${prop.type}` : lit.nothing}
${prop.description ? lit.html`

${prop.description}

` : lit.nothing} ${prop.defaultValue !== void 0 ? lit.html`
Default: ${JSON.stringify(prop.defaultValue)}
` : lit.nothing} ${prop.enum && prop.enum.length > 0 ? lit.html`
Allowed values:
${prop.enum.map((val) => lit.html` ${JSON.stringify(val)} `)}
` : lit.nothing}
`)}
` : lit.html`
No parameters defined
`}
` : lit.nothing}
`; } extractSchemaInfo(parameters) { const result = { properties: [] }; if (!parameters || typeof parameters !== "object") return result; const zodDef = parameters._def; if (zodDef && typeof zodDef === "object") { if (zodDef.typeName === "ZodObject") { const rawShape = zodDef.shape; const shape = typeof rawShape === "function" ? rawShape() : rawShape; if (!shape || typeof shape !== "object") return result; const requiredKeys = /* @__PURE__ */ new Set(); if (zodDef.unknownKeys === "strict" || !zodDef.catchall) Object.keys(shape || {}).forEach((key) => { const candidate = shape[key]; if (candidate?._def && !this.isZodOptional(candidate)) requiredKeys.add(key); }); for (const [key, value] of Object.entries(shape || {})) { const fieldInfo = this.extractZodFieldInfo(value); result.properties.push({ name: key, type: fieldInfo.type, description: fieldInfo.description, required: requiredKeys.has(key), defaultValue: fieldInfo.defaultValue, enum: fieldInfo.enum }); } } } else if (parameters.type === "object" && parameters.properties) { const props = parameters.properties; const required = new Set(Array.isArray(parameters.required) ? parameters.required : []); for (const [key, value] of Object.entries(props ?? {})) { const prop = value; result.properties.push({ name: key, type: prop.type, description: typeof prop.description === "string" ? prop.description : void 0, required: required.has(key), defaultValue: prop.default, enum: Array.isArray(prop.enum) ? prop.enum : void 0 }); } } return result; } isZodOptional(zodSchema) { const schema = zodSchema; if (!schema?._def) return false; const def = schema._def; if (def.typeName === "ZodOptional" || def.typeName === "ZodNullable") return true; if (def.defaultValue !== void 0) return true; return false; } extractZodFieldInfo(zodSchema) { const info = {}; const schema = zodSchema; if (!schema?._def) return info; let currentSchema = schema; let def = currentSchema._def; while (def.typeName === "ZodOptional" || def.typeName === "ZodNullable" || def.typeName === "ZodDefault") { if (def.typeName === "ZodDefault" && def.defaultValue !== void 0) info.defaultValue = typeof def.defaultValue === "function" ? def.defaultValue() : def.defaultValue; currentSchema = def.innerType ?? currentSchema; if (!currentSchema?._def) break; def = currentSchema._def; } info.description = typeof def.description === "string" ? def.description : void 0; const typeName = typeof def.typeName === "string" ? def.typeName : void 0; info.type = typeName ? { ZodString: "string", ZodNumber: "number", ZodBoolean: "boolean", ZodArray: "array", ZodObject: "object", ZodEnum: "enum", ZodLiteral: "literal", ZodUnion: "union", ZodAny: "any", ZodUnknown: "unknown" }[typeName] || typeName.replace("Zod", "").toLowerCase() : void 0; if (typeName === "ZodEnum" && Array.isArray(def.values)) info.enum = def.values; else if (typeName === "ZodLiteral" && def.value !== void 0) info.enum = [def.value]; return info; } toggleToolExpansion(toolId) { if (this.expandedTools.has(toolId)) this.expandedTools.delete(toolId); else this.expandedTools.add(toolId); this.requestUpdate(); } renderContextView() { const contextEntries = Object.entries(this.contextStore); if (contextEntries.length === 0) return lit.html`
${this.renderIcon("FileText")}

No context available

Context will appear here once added to CopilotKit.

`; return lit.html`
${contextEntries.map(([id, context]) => this.renderContextCard(id, context))}
`; } renderContextCard(id, context) { const isExpanded = this.expandedContextItems.has(id); const valuePreview = this.getContextValuePreview(context.value); const hasValue = context.value !== void 0 && context.value !== null; return lit.html`
${isExpanded ? lit.html`
ID
${id}
${hasValue ? lit.html`
Value
${this.formatContextValue(context.value)}
` : lit.html`
No value available
`}
` : lit.nothing}
`; } getContextValuePreview(value) { if (value === void 0 || value === null) return "—"; if (typeof value === "string") return value.length > 50 ? `${value.substring(0, 50)}...` : value; if (typeof value === "number" || typeof value === "boolean") return String(value); if (Array.isArray(value)) return `Array(${value.length})`; if (typeof value === "object") { const keys = Object.keys(value); return `Object with ${keys.length} key${keys.length !== 1 ? "s" : ""}`; } if (typeof value === "function") return "Function"; return String(value); } formatContextValue(value) { if (value === void 0) return "undefined"; if (value === null) return "null"; if (typeof value === "function") return value.toString(); try { return JSON.stringify(value, null, 2); } catch { return String(value); } } async copyContextValue(value, contextId) { if (typeof navigator === "undefined" || !navigator.clipboard?.writeText) { console.warn("Clipboard API is not available in this environment."); return; } const serialized = this.formatContextValue(value); try { await navigator.clipboard.writeText(serialized); this.copiedContextItems.add(contextId); this.requestUpdate(); setTimeout(() => { this.copiedContextItems.delete(contextId); this.requestUpdate(); }, 1500); } catch (error) { console.error("Failed to copy context value:", error); } } toggleContextExpansion(contextId) { if (this.expandedContextItems.has(contextId)) this.expandedContextItems.delete(contextId); else this.expandedContextItems.add(contextId); this.requestUpdate(); } toggleRowExpansion(eventId) { const selection = window.getSelection(); if (selection && selection.toString().length > 0) return; if (this.expandedRows.has(eventId)) this.expandedRows.delete(eventId); else this.expandedRows.add(eventId); this.requestUpdate(); } renderAnnouncementPanel() { if (!this.isOpen) return lit.nothing; this.ensureAnnouncementLoading(); if (!this.hasUnseenAnnouncement) return lit.nothing; if (!this.announcementLoaded && !this.announcementMarkdown) return lit.html`
${this.renderIcon("Megaphone")} Loading latest announcement…
`; if (this.announcementLoadError) return lit.html`
${this.renderIcon("Megaphone")} Announcement unavailable

We couldn’t load the latest notice. Please try opening the inspector again.

`; if (!this.announcementMarkdown) return lit.nothing; const content = this.announcementHtml ? (0, lit_directives_unsafe_html_js.unsafeHTML)(this.announcementHtml) : lit.html`
${this.announcementMarkdown}
`; return lit.html`
${this.renderIcon("Megaphone")} Announcement
${content}
`; } ensureAnnouncementLoading() { if (this.announcementPromise || typeof window === "undefined" || typeof fetch === "undefined") return; this.announcementPromise = this.fetchAnnouncement(); } renderAnnouncementPreview() { if (!this.hasUnseenAnnouncement || !this.showAnnouncementPreview || !this.announcementPreviewText) return lit.nothing; return lit.html`
this.handleAnnouncementPreviewClick()} > ${this.announcementPreviewText}
`; } handleAnnouncementPreviewClick() { this.showAnnouncementPreview = false; this.openInspector(); } async fetchAnnouncement() { try { const response = await fetch(ANNOUNCEMENT_URL, { cache: "no-cache" }); if (!response.ok) throw new Error(`Failed to load announcement (${response.status})`); const data = await response.json(); const timestamp = typeof data?.timestamp === "string" ? data.timestamp : null; const previewText = typeof data?.previewText === "string" ? data.previewText : null; const markdown = typeof data?.announcement === "string" ? data.announcement : null; if (!timestamp || !markdown) throw new Error("Malformed announcement payload"); const storedTimestamp = this.loadStoredAnnouncementTimestamp(); this.announcementTimestamp = timestamp; this.announcementPreviewText = previewText ?? ""; this.announcementMarkdown = markdown; this.hasUnseenAnnouncement = (!storedTimestamp || storedTimestamp !== timestamp) && !!this.announcementPreviewText; this.showAnnouncementPreview = this.hasUnseenAnnouncement; this.announcementHtml = await this.convertMarkdownToHtml(markdown); this.announcementLoaded = true; this.requestUpdate(); } catch (error) { this.announcementLoadError = error; this.announcementLoaded = true; this.requestUpdate(); } } async convertMarkdownToHtml(markdown) { const renderer = new marked.marked.Renderer(); renderer.link = (href, title, text) => { return `${text}`; }; return marked.marked.parse(markdown, { renderer }); } appendRefParam(href) { try { const url = new URL(href, typeof window !== "undefined" ? window.location.href : "https://copilotkit.ai"); if (!url.searchParams.has("ref")) url.searchParams.append("ref", "cpk-inspector"); return url.toString(); } catch { return href; } } escapeHtmlAttr(value) { return value.replace(/&/g, "&").replace(//g, ">").replace(/\"/g, """).replace(/'/g, "'"); } loadStoredAnnouncementTimestamp() { if (typeof window === "undefined" || !window.localStorage) return null; try { const raw = window.localStorage.getItem(ANNOUNCEMENT_STORAGE_KEY); if (!raw) return null; const parsed = JSON.parse(raw); if (parsed && typeof parsed.timestamp === "string") return parsed.timestamp; return null; } catch {} return null; } persistAnnouncementTimestamp(timestamp) { if (typeof window === "undefined" || !window.localStorage) return; try { const payload = JSON.stringify({ timestamp }); window.localStorage.setItem(ANNOUNCEMENT_STORAGE_KEY, payload); } catch {} } markAnnouncementSeen() { this.hasUnseenAnnouncement = false; this.showAnnouncementPreview = false; if (!this.announcementTimestamp) { if (this.announcementPromise && !this.announcementLoaded) this.announcementPromise.then(() => this.markAnnouncementSeen()).catch(() => void 0); this.requestUpdate(); return; } this.persistAnnouncementTimestamp(this.announcementTimestamp); this.requestUpdate(); } }; function defineWebInspector() { if (!customElements.get(WEB_INSPECTOR_TAG)) customElements.define(WEB_INSPECTOR_TAG, WebInspectorElement); } defineWebInspector(); //#endregion exports.WEB_INSPECTOR_TAG = WEB_INSPECTOR_TAG; exports.WebInspectorElement = WebInspectorElement; exports.defineWebInspector = defineWebInspector; //# sourceMappingURL=index.cjs.map