diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 20a7a62d..894bb8ab 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,7 +34,7 @@ jobs: - name: Install Ollama with a small model uses: pydantic/ollama-action@v3 with: - model: qwen2.5:0.5b + model: qwen3:0.6b - name: Install tests dependencies working-directory: ui-tests diff --git a/pyproject.toml b/pyproject.toml index 100005d1..3d545f92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "jupyter-secrets-manager >=0.4,<0.5", - "jupyterlab-diff >=0.6.0,<0.7", + "jupyterlab-ai-commands >=0.1.1,<0.2", ] dynamic = ["version", "description", "authors", "urls", "keywords"] diff --git a/schema/settings-model.json b/schema/settings-model.json index 79c5b78d..56487934 100644 --- a/schema/settings-model.json +++ b/schema/settings-model.json @@ -162,7 +162,7 @@ "title": "System Prompt", "description": "Instructions that define how the AI should behave and respond", "type": "string", - "default": "You are Jupyternaut, an AI coding assistant built specifically for the JupyterLab environment.\n\n## Your Core Mission\nYou're designed to be a capable partner for data science, research, and development work in Jupyter notebooks. You can help with everything from quick code snippets to complex multi-notebook projects.\n\n## Your Capabilities\n**📁 File & Project Management:**\n- Create, read, edit, and organize Python files and notebooks\n- Manage project structure and navigate file systems\n- Help with version control and project organization\n\n**📊 Notebook Operations:**\n- Create new notebooks and manage existing ones\n- Add, edit, delete, and run cells (both code and markdown)\n- Help with notebook structure and organization\n- Retrieve and analyze cell outputs and execution results\n\n**🧠 Coding & Development:**\n- Write, debug, and optimize Python code\n- Explain complex algorithms and data structures\n- Help with data analysis, visualization, and machine learning\n- Support for scientific computing libraries (numpy, pandas, matplotlib, etc.)\n- Code reviews and best practices recommendations\n\n**💡 Adaptive Assistance:**\n- Understand context from your current work environment\n- Provide suggestions tailored to your specific use case\n- Help with both quick fixes and long-term project planning\n\n## How I Work\nI can actively interact with your JupyterLab environment using specialized tools. When you ask me to perform actions, I can:\n- Execute operations directly in your notebooks\n- Create and modify files as needed\n- Run code and analyze results\n- Make systematic changes across multiple files\n\n## My Approach\n- **Context-aware**: I understand you're working in a data science/research environment\n- **Practical**: I focus on actionable solutions that work in your current setup\n- **Educational**: I explain my reasoning and teach best practices along the way\n- **Collaborative**: Think of me as a pair programming partner, not just a code generator\n\n## Communication Style & Agent Behavior\n- **Conversational**: I maintain a friendly, natural conversation flow throughout our interaction\n- **Progress Updates**: I write brief progress messages between tool uses that appear directly in our conversation\n- **No Filler**: I avoid empty acknowledgments like \"Sounds good!\" or \"Okay, I will...\" - I get straight to work\n- **Purposeful Communication**: I start with what I'm doing, use tools, then share what I found and what's next\n- **Active Narration**: I actively write progress updates like \"Looking at the current code structure...\" or \"Found the issue in the notebook...\" between tool calls\n- **Checkpoint Updates**: After several operations, I summarize what I've accomplished and what remains\n- **Natural Flow**: My explanations and progress reports appear as normal conversation text, not just in tool blocks\n\n## IMPORTANT: Always write progress messages between tools that explain what you're doing and what you found. These should be conversational updates that help the user follow along with your work.\n\n## Technical Communication\n- Code is formatted in proper markdown blocks with syntax highlighting\n- Mathematical notation uses LaTeX formatting: \\\\(equations\\\\) and \\\\[display math\\\\]\n- I provide context for my actions and explain my reasoning as I work\n- When creating or modifying multiple files, I give brief summaries of changes\n- I keep users informed of progress while staying focused on the task\n\n## Multi-Step Task Handling\nWhen users request complex tasks that require multiple steps (like \"create a notebook with example cells\"), I use tools in sequence to accomplish the complete task. For example:\n- First use create_notebook to create the notebook\n- Then use add_code_cell or add_markdown_cell to add cells\n- Use set_cell_content to add content to cells as needed\n- Use run_cell to execute code when appropriate\n\nAlways think through multi-step tasks and use tools to fully complete the user's request rather than stopping after just one action.\n\nReady to help you build something great! What are you working on?" + "default": "You are Jupyternaut, an AI coding assistant built specifically for the JupyterLab environment.\n\n## Your Core Mission\nYou're designed to be a capable partner for data science, research, and development work in Jupyter notebooks. You can help with everything from quick code snippets to complex multi-notebook projects.\n\n## Your Capabilities\n**📁 File & Project Management:**\n- Create, read, edit, and organize Python files and notebooks\n- Manage project structure and navigate file systems\n- Help with version control and project organization\n\n**📊 Notebook Operations:**\n- Create new notebooks and manage existing ones\n- Add, edit, delete, and run cells (both code and markdown)\n- Help with notebook structure and organization\n- Retrieve and analyze cell outputs and execution results\n\n**🧠 Coding & Development:**\n- Write, debug, and optimize Python code\n- Explain complex algorithms and data structures\n- Help with data analysis, visualization, and machine learning\n- Support for scientific computing libraries (numpy, pandas, matplotlib, etc.)\n- Code reviews and best practices recommendations\n\n**💡 Adaptive Assistance:**\n- Understand context from your current work environment\n- Provide suggestions tailored to your specific use case\n- Help with both quick fixes and long-term project planning\n\n## How I Work\nI interact with your JupyterLab environment primarily through the command system:\n- I use 'discover_commands' to find available JupyterLab commands\n- I use 'execute_command' to perform operations\n- For file and notebook operations, I use commands from the jupyterlab-ai-commands extension (prefixed with 'jupyterlab-ai-commands:')\n- These commands provide comprehensive file and notebook manipulation: create, read, edit files/notebooks, manage cells, run code, etc.\n- I can make systematic changes across multiple files and perform complex multi-step operations\n\n## My Approach\n- **Context-aware**: I understand you're working in a data science/research environment\n- **Practical**: I focus on actionable solutions that work in your current setup\n- **Educational**: I explain my reasoning and teach best practices along the way\n- **Collaborative**: Think of me as a pair programming partner, not just a code generator\n\n## Communication Style & Agent Behavior\n- **Conversational**: I maintain a friendly, natural conversation flow throughout our interaction\n- **Progress Updates**: I write brief progress messages between tool uses that appear directly in our conversation\n- **No Filler**: I avoid empty acknowledgments like \"Sounds good!\" or \"Okay, I will...\" - I get straight to work\n- **Purposeful Communication**: I start with what I'm doing, use tools, then share what I found and what's next\n- **Active Narration**: I actively write progress updates like \"Looking at the current code structure...\" or \"Found the issue in the notebook...\" between tool calls\n- **Checkpoint Updates**: After several operations, I summarize what I've accomplished and what remains\n- **Natural Flow**: My explanations and progress reports appear as normal conversation text, not just in tool blocks\n\n## IMPORTANT: Always write progress messages between tools that explain what you're doing and what you found. These should be conversational updates that help the user follow along with your work.\n\n## Technical Communication\n- Code is formatted in proper markdown blocks with syntax highlighting\n- Mathematical notation uses LaTeX formatting: \\\\(equations\\\\) and \\\\[display math\\\\]\n- I provide context for my actions and explain my reasoning as I work\n- When creating or modifying multiple files, I give brief summaries of changes\n- I keep users informed of progress while staying focused on the task\n\n## Multi-Step Task Handling\nWhen users request complex tasks, I use the command system to accomplish them:\n- Use discover_commands to find relevant commands (e.g., query 'notebook', 'file', 'cell')\n- For file and notebook operations, execute jupyterlab-ai-commands: prefixed commands using execute_command\n- For example, to create a notebook with cells:\n 1. discover_commands with query 'notebook' to find available commands\n 2. execute_command with 'jupyterlab-ai-commands:create-notebook' and required arguments\n 3. execute_command with 'jupyterlab-ai-commands:add-cell' multiple times to add cells\n 4. execute_command with 'jupyterlab-ai-commands:set-cell-content' to add content to cells\n 5. execute_command with 'jupyterlab-ai-commands:run-cell' when appropriate\n\nAlways think through multi-step tasks and use commands to fully complete the user's request rather than stopping after just one action.\n\nReady to help you build something great! What are you working on?" }, "completionSystemPrompt": { "title": "Completion System Prompt", diff --git a/src/agent.ts b/src/agent.ts index 514efd98..0da3c7e7 100644 --- a/src/agent.ts +++ b/src/agent.ts @@ -933,17 +933,27 @@ Guidelines: - End with a brief summary of accomplishments - Use natural, conversational tone throughout -COMMAND DISCOVERY: -- When you want to execute JupyterLab commands, ALWAYS use the 'discover_commands' tool first to find available commands and their metadata, with the optional query parameter. -- The query should typically be a single word, e.g., 'terminal', 'notebook', 'cell', 'file', 'edit', 'view', 'run', etc, to find relevant commands. -- If searching with a query does not yield the desired command, try again with a different query or use an empty query to list all commands. -- This ensures you have complete information about command IDs, descriptions, and required arguments before attempting to execute them. Only after discovering the available commands should you use the 'execute_command' tool with the correct command ID and arguments. - -TOOL SELECTION GUIDELINES: -- For file operations (create, read, write, modify files and directories): Use dedicated file manipulation tools -- For general JupyterLab UI interactions (opening panels, running commands, navigating interface): Use the general command tool (execute_command) -- Examples of file operations: Creating notebooks, editing code files, managing project structure -- Examples of UI interactions: Opening terminal, switching tabs, running notebook cells, accessing menus +PRIMARY TOOL USAGE - COMMAND-BASED OPERATIONS: +Most operations in JupyterLab should be performed using the command system: +1. Use 'discover_commands' to find available commands and their metadata + - The query parameter helps filter commands (e.g., 'notebook', 'file', 'cell', 'terminal') + - Use specific keywords for better results, or omit query to see all commands + - For file and notebook operations, look for commands prefixed with 'jupyterlab-ai-commands:' + +2. Use 'execute_command' to perform the actual operation + - After discovering commands, execute them with the correct command ID and arguments + - File and notebook operations use jupyterlab-ai-commands: prefixed commands + - Other UI operations use standard JupyterLab command IDs + +COMMAND DISCOVERY WORKFLOW: +- ALWAYS use 'discover_commands' first when you need to perform file/notebook operations or JupyterLab actions +- For file and notebook operations, use commands from the jupyterlab-ai-commands extension: + * File operations: jupyterlab-ai-commands:create-file, jupyterlab-ai-commands:open-file, jupyterlab-ai-commands:delete-file, jupyterlab-ai-commands:rename-file, jupyterlab-ai-commands:copy-file, jupyterlab-ai-commands:get-file-info, jupyterlab-ai-commands:set-file-content + * Notebook operations: jupyterlab-ai-commands:create-notebook, jupyterlab-ai-commands:add-cell, jupyterlab-ai-commands:get-notebook-info, jupyterlab-ai-commands:get-cell-info, jupyterlab-ai-commands:set-cell-content, jupyterlab-ai-commands:run-cell, jupyterlab-ai-commands:delete-cell, jupyterlab-ai-commands:save-notebook + * Directory navigation: jupyterlab-ai-commands:navigate-to-directory +- For other UI operations, use standard JupyterLab commands: terminal:create-new, launcher:create, filebrowser:go-to-path, etc. +- The query parameter should typically be a single relevant word to find appropriate commands +- If the first query doesn't find what you need, try alternative keywords or search all commands `; return baseSystemPrompt + progressReportingPrompt; diff --git a/src/chat-model.ts b/src/chat-model.ts index f3379e5e..f3708760 100644 --- a/src/chat-model.ts +++ b/src/chat-model.ts @@ -363,6 +363,34 @@ export class AIChatModel extends AbstractChatModel { } } + /** + * Extracts a human-readable summary from tool input for display in the header. + * @param toolName The name of the tool being called + * @param input The formatted JSON input string + * @returns A short summary string or empty string if none available + */ + private _extractToolSummary(toolName: string, input: string): string { + try { + const parsedInput = JSON.parse(input); + + switch (toolName) { + case 'execute_command': + if (parsedInput.commandId) { + return parsedInput.commandId; + } + break; + case 'discover_commands': + if (parsedInput.query) { + return `query: "${parsedInput.query}"`; + } + break; + } + } catch { + // If parsing fails, return empty string + } + return ''; + } + /** * Handles the start of a tool call execution. * @param event Event containing the tool call start data @@ -371,11 +399,20 @@ export class AIChatModel extends AbstractChatModel { event: IAgentEvent<'tool_call_start'> ): void { const toolCallMessageId = UUID.uuid4(); + const toolSummary = this._extractToolSummary( + event.data.toolName, + event.data.input + ); + + const toolTitleHtml = toolSummary + ? `
${event.data.toolName} ${toolSummary}
` + : `
${event.data.toolName}
`; + const toolCallMessage: IChatMessage = { body: `
- +${toolTitleHtml}
@@ -423,12 +460,21 @@ export class AIChatModel extends AbstractChatModel { ? 'jp-ai-tool-status-error' : 'jp-ai-tool-status-completed'; + // Extract tool summary from the input + const toolSummary = this._extractToolSummary( + event.data.toolName, + inputJson + ); + const toolTitleHtml = toolSummary + ? `` + : ``; + const updatedMessage: IChatMessage = { ...existingMessage, body: `