"use client"; import { useCopilotContext } from "../../context/copilot-context"; import { useCopilotMessagesContext } from "../../context/copilot-messages-context"; import { COPILOTKIT_VERSION } from "@copilotkit/shared"; import { useEffect, useState } from "react"; import { CheckIcon, CopilotKitIcon, ExclamationMarkTriangleIcon, } from "./icons"; // Type definitions for the developer console interface ActionParameter { name: string; required?: boolean; type?: string; } interface Action { name: string; description?: string; parameters?: ActionParameter[]; status?: string; } interface Readable { name?: string; description?: string; value?: any; content?: string; metadata?: Record; } interface AgentState { status?: string; state?: any; running?: boolean; lastUpdate?: number; } interface Message { id?: string; role?: "user" | "assistant" | "system"; content?: string; timestamp?: number; [key: string]: any; // Allow additional properties from CopilotKit } interface Document { name?: string; content?: string; metadata?: Record; } interface DisplayContext { actions: Record; getAllContext: () => Readable[]; coagentStates: Record; getDocumentsContext: (args?: any[]) => Document[]; } interface MessagesContext { messages: Message[]; } interface DeveloperConsoleModalProps { isOpen: boolean; onClose: () => void; hasApiKey: boolean; } export function DeveloperConsoleModal({ isOpen, onClose, hasApiKey, }: DeveloperConsoleModalProps) { const context = useCopilotContext(); const messagesContext = useCopilotMessagesContext(); const [activeTab, setActiveTab] = useState("actions"); // Handle escape key useEffect(() => { const handleEscape = (e: KeyboardEvent) => { if (e.key === "Escape") { onClose(); } }; if (isOpen) { document.addEventListener("keydown", handleEscape); document.body.style.overflow = "hidden"; } return () => { document.removeEventListener("keydown", handleEscape); document.body.style.overflow = "unset"; }; }, [isOpen, onClose]); if (!isOpen) return null; // Create mock data for preview when no API key const displayContext: DisplayContext = hasApiKey ? (context as DisplayContext) : { actions: { search_web: { name: "search_web", description: "Search the web for information", }, send_email: { name: "send_email", description: "Send an email to a contact", }, create_document: { name: "create_document", description: "Create a new document", }, analyze_code: { name: "analyze_code", description: "Analyze code for issues and improvements", }, generate_tests: { name: "generate_tests", description: "Generate unit tests for functions", }, }, getAllContext: () => [ { content: "User preferences: dark mode enabled, TypeScript preferred", metadata: { source: "settings" }, }, { content: "Current project: Building a React application with CopilotKit", metadata: { source: "project" }, }, { content: "Recent activity: Implemented authentication system", metadata: { source: "activity" }, }, { content: "Development environment: VS Code, Node.js 18, React 18", metadata: { source: "environment" }, }, ], coagentStates: { "main-agent": { status: "active", lastUpdate: Date.now() }, "code-assistant": { status: "active", lastUpdate: Date.now() - 15000, }, "search-agent": { status: "idle", lastUpdate: Date.now() - 60000 }, }, getDocumentsContext: () => [ { content: "README.md: Project setup and installation instructions", metadata: { type: "documentation" }, }, { content: "API Documentation: CopilotKit integration guide", metadata: { type: "documentation" }, }, { content: "package.json: Project dependencies and scripts", metadata: { type: "configuration" }, }, ], }; const displayMessagesContext: MessagesContext = hasApiKey ? (messagesContext as MessagesContext) : { messages: [ { id: "1", role: "user", content: "Help me implement a todo list with drag and drop functionality", }, { id: "2", role: "assistant", content: "I'll help you create a todo list with drag and drop. Let me start by setting up the basic components and then add the drag and drop functionality using React DnD.", }, { id: "3", role: "user", content: "Can you also add priority levels and due dates?", }, { id: "4", role: "assistant", content: "Absolutely! I'll enhance the todo items with priority levels (high, medium, low) and due date functionality. This will make your todo list much more powerful for task management.", }, { id: "5", role: "user", content: "Perfect! How about adding categories or tags?", }, ], }; return (
e.stopPropagation()} > {/* Header */}

Inspector

v{COPILOTKIT_VERSION}
{/* Tab Navigation */}
{[ { id: "actions", label: "Actions", count: Object.keys(displayContext.actions).length, }, { id: "readables", label: "Readables", count: displayContext.getAllContext().length, }, { id: "agent", label: "Agent Status", count: Object.keys(displayContext.coagentStates).length, }, { id: "messages", label: "Messages", count: displayMessagesContext.messages.length, }, { id: "context", label: "Context", count: displayContext.getDocumentsContext([]).length, }, ].map((tab) => ( ))}
{/* Content */}
{activeTab === "actions" && } {activeTab === "readables" && ( )} {activeTab === "agent" && } {activeTab === "messages" && ( )} {activeTab === "context" && }
{/* Footer */} {/* Enhanced CTA Overlay */} {!hasApiKey && (
e.stopPropagation()} >
)}
); } // Tab Components function ActionsTab({ context }: { context: DisplayContext }) { const actions = Object.values(context.actions); if (actions.length === 0) { return (

No actions available

Actions will appear here when registered

); } return (
{actions.map((action: Action, index: number) => (

{action.name}

{action.description && (

{action.description}

)} {action.parameters && action.parameters.length > 0 && (

Parameters:

{action.parameters.map( (param: ActionParameter, pIndex: number) => (
{param.name} {param.required && ( *required )} {param.type && ( ({param.type}) )}
), )}
)}
{action.status === "available" ? ( ) : ( )}
))}
); } function ReadablesTab({ context }: { context: DisplayContext }) { const readables = context.getAllContext(); if (readables.length === 0) { return (

No readable context available

Readable context will appear here when provided

); } return (
{readables.map((readable: Readable, index: number) => (

{readable.name || `Readable ${index + 1}`}

{readable.description && (

{readable.description}

)} {readable.value && (
                  {JSON.stringify(readable.value, null, 2)}
                
)}
))}
); } function AgentStatusTab({ context }: { context: DisplayContext }) { const agentStates = context.coagentStates || {}; const agentStateEntries = Object.entries(agentStates); if (agentStateEntries.length === 0) { return (

No agent states available

Agent states will appear here when agents are active

); } return (
{agentStateEntries.map(([agentName, state]: [string, AgentState]) => (

{agentName}

{state.status || "idle"}
{state.state && (

Current State:

                {JSON.stringify(state.state, null, 2)}
              
)} {state.running && (
Agent is currently running...
)}
))}
); } function MessagesTab({ messagesContext, }: { messagesContext: MessagesContext; }) { const messages = messagesContext.messages || []; if (messages.length === 0) { return (

No messages yet

Messages will appear here as the conversation progresses

); } return (
{messages.map((message: Message, index: number) => (
{message.role || "system"} {message.timestamp && ( {new Date(message.timestamp).toLocaleTimeString()} )}
{message.content || ""}
))}
); } function ContextTab({ context }: { context: DisplayContext }) { const documents = context.getDocumentsContext([]); if (documents.length === 0) { return (

No document context available

Document context will appear here when provided

); } return (
{documents.map((doc: Document, index: number) => (

{doc.name || `Document ${index + 1}`}

{doc.content && (
              {doc.content}
            
)}
))}
); }