@jupyterlite/ai 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/agent.js CHANGED
@@ -654,17 +654,24 @@ Guidelines:
654
654
  - End with a brief summary of accomplishments
655
655
  - Use natural, conversational tone throughout
656
656
 
657
- COMMAND DISCOVERY:
658
- - 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.
659
- - The query should typically be a single word, e.g., 'terminal', 'notebook', 'cell', 'file', 'edit', 'view', 'run', etc, to find relevant commands.
660
- - 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.
661
- - 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.
657
+ PRIMARY TOOL USAGE - COMMAND-BASED OPERATIONS:
658
+ Most operations in JupyterLab should be performed using the command system:
659
+ 1. Use 'discover_commands' to find available commands and their metadata
660
+ 2. Use 'execute_command' to perform the actual operation
662
661
 
663
- TOOL SELECTION GUIDELINES:
664
- - For file operations (create, read, write, modify files and directories): Use dedicated file manipulation tools
665
- - For general JupyterLab UI interactions (opening panels, running commands, navigating interface): Use the general command tool (execute_command)
666
- - Examples of file operations: Creating notebooks, editing code files, managing project structure
667
- - Examples of UI interactions: Opening terminal, switching tabs, running notebook cells, accessing menus
662
+ COMMAND DISCOVERY WORKFLOW:
663
+ - For file and notebook operations, use query 'jupyterlab-ai-commands' to discover the curated set of AI commands (~17 commands for file/notebook/directory operations)
664
+ - For other JupyterLab operations (terminal, launcher, UI), use specific keywords like 'terminal', 'launcher', etc.
665
+ - IMPORTANT: Always use 'jupyterlab-ai-commands' as the query for file/notebook tasks - this returns a focused set of commands instead of 100+ generic JupyterLab commands
666
+
667
+ KERNEL PREFERENCE FOR NOTEBOOKS AND CONSOLES:
668
+ When creating notebooks or consoles for a specific programming language, use the 'kernelPreference' argument to specify the kernel:
669
+ - To specify by language: { "kernelPreference": { "language": "python" } } or { "kernelPreference": { "language": "julia" } }
670
+ - To specify by kernel name: { "kernelPreference": { "name": "python3" } } or { "kernelPreference": { "name": "julia-1.10" } }
671
+ - Example: execute_command with commandId="notebook:create-new" and args={ "kernelPreference": { "language": "python" } }
672
+ - Example: execute_command with commandId="console:create" and args={ "kernelPreference": { "name": "python3" } }
673
+ - Common kernel names: "python3" (Python), "julia-1.10" (Julia), "ir" (R), "xpython" (xeus-python)
674
+ - If unsure of exact kernel name, prefer using "language" which will match any kernel supporting that language
668
675
  `;
669
676
  return baseSystemPrompt + progressReportingPrompt;
670
677
  }
@@ -81,6 +81,13 @@ export declare class AIChatModel extends AbstractChatModel {
81
81
  * @param event Event containing the message completion data
82
82
  */
83
83
  private _handleMessageComplete;
84
+ /**
85
+ * Extracts a human-readable summary from tool input for display in the header.
86
+ * @param toolName The name of the tool being called
87
+ * @param input The formatted JSON input string
88
+ * @returns A short summary string or empty string if none available
89
+ */
90
+ private _extractToolSummary;
84
91
  /**
85
92
  * Handles the start of a tool call execution.
86
93
  * @param event Event containing the tool call start data
package/lib/chat-model.js CHANGED
@@ -242,18 +242,47 @@ export class AIChatModel extends AbstractChatModel {
242
242
  this._currentStreamingMessage = null;
243
243
  }
244
244
  }
245
+ /**
246
+ * Extracts a human-readable summary from tool input for display in the header.
247
+ * @param toolName The name of the tool being called
248
+ * @param input The formatted JSON input string
249
+ * @returns A short summary string or empty string if none available
250
+ */
251
+ _extractToolSummary(toolName, input) {
252
+ try {
253
+ const parsedInput = JSON.parse(input);
254
+ switch (toolName) {
255
+ case 'execute_command':
256
+ if (parsedInput.commandId) {
257
+ return parsedInput.commandId;
258
+ }
259
+ break;
260
+ case 'discover_commands':
261
+ if (parsedInput.query) {
262
+ return `query: "${parsedInput.query}"`;
263
+ }
264
+ break;
265
+ }
266
+ }
267
+ catch {
268
+ // If parsing fails, return empty string
269
+ }
270
+ return '';
271
+ }
245
272
  /**
246
273
  * Handles the start of a tool call execution.
247
274
  * @param event Event containing the tool call start data
248
275
  */
249
276
  _handleToolCallStartEvent(event) {
250
277
  const messageId = UUID.uuid4();
278
+ const summary = this._extractToolSummary(event.data.toolName, event.data.input);
251
279
  const context = {
252
280
  toolCallId: event.data.callId,
253
281
  messageId,
254
282
  toolName: event.data.toolName,
255
283
  input: event.data.input,
256
- status: 'pending'
284
+ status: 'pending',
285
+ summary
257
286
  };
258
287
  this._toolContexts.set(event.data.callId, context);
259
288
  const toolCallMessage = {
@@ -261,6 +290,7 @@ export class AIChatModel extends AbstractChatModel {
261
290
  toolName: context.toolName,
262
291
  input: context.input,
263
292
  status: context.status,
293
+ summary: context.summary,
264
294
  trans: this._trans
265
295
  }),
266
296
  sender: this._getAIUser(),
@@ -337,6 +367,7 @@ export class AIChatModel extends AbstractChatModel {
337
367
  toolName: context.toolName,
338
368
  input: context.input,
339
369
  status: context.status,
370
+ summary: context.summary,
340
371
  output,
341
372
  approvalId: context.approvalId,
342
373
  trans: this._trans
@@ -642,12 +673,15 @@ var Private;
642
673
  * Builds HTML for a tool call display.
643
674
  */
644
675
  function buildToolCallHtml(options) {
645
- const { toolName, input, status, output, approvalId, trans } = options;
676
+ const { toolName, input, status, summary, output, approvalId, trans } = options;
646
677
  const config = STATUS_CONFIG[status];
647
678
  const statusText = getStatusText(status, trans);
648
679
  const escapedToolName = escapeHtml(toolName);
649
680
  const escapedInput = escapeHtml(input);
650
681
  const openAttr = config.open ? ' open' : '';
682
+ const summaryHtml = summary
683
+ ? `<span class="jp-ai-tool-summary">${escapeHtml(summary)}</span>`
684
+ : '';
651
685
  let bodyContent = `
652
686
  <div class="jp-ai-tool-section">
653
687
  <div class="jp-ai-tool-label">${trans.__('Input')}</div>
@@ -674,7 +708,7 @@ var Private;
674
708
  return `<details class="jp-ai-tool-call ${config.cssClass}"${openAttr}>
675
709
  <summary class="jp-ai-tool-header">
676
710
  <div class="jp-ai-tool-icon">⚡</div>
677
- <div class="jp-ai-tool-title">${escapedToolName}</div>
711
+ <div class="jp-ai-tool-title">${escapedToolName}${summaryHtml}</div>
678
712
  <div class="jp-ai-tool-status ${config.statusClass}">${statusText}</div>
679
713
  </summary>
680
714
  <div class="jp-ai-tool-body">${bodyContent}
@@ -8,10 +8,9 @@ export function ClearButton(props) {
8
8
  const { translator: trans } = props;
9
9
  const tooltip = trans.__('Clear chat');
10
10
  return (React.createElement(TooltippedButton, { onClick: props.clearMessages, tooltip: tooltip, buttonProps: {
11
- size: 'small',
11
+ title: tooltip,
12
12
  variant: 'outlined',
13
- color: 'secondary',
14
- title: tooltip
13
+ color: 'secondary'
15
14
  } },
16
15
  React.createElement(ClearIcon, null)));
17
16
  }
@@ -61,16 +61,15 @@ export function ModelSelect(props) {
61
61
  // Show a message if no providers are configured
62
62
  if (availableModels.length === 0) {
63
63
  return (React.createElement(TooltippedButton, { onClick: () => { }, tooltip: trans.__('No providers configured. Please go to AI Settings to add a provider.'), buttonProps: {
64
- size: 'small',
65
64
  variant: 'outlined',
66
65
  color: 'warning',
67
66
  disabled: true,
68
67
  title: trans.__('No Providers Available')
69
68
  }, sx: {
70
69
  minWidth: 'auto',
70
+ width: 'unset',
71
71
  display: 'flex',
72
- alignItems: 'center',
73
- height: '29px'
72
+ alignItems: 'center'
74
73
  } },
75
74
  React.createElement(Typography, { variant: "caption", sx: { fontSize: '0.7rem', fontWeight: 500 } }, trans.__('No Providers'))));
76
75
  }
@@ -78,9 +77,6 @@ export function ModelSelect(props) {
78
77
  React.createElement(TooltippedButton, { onClick: e => {
79
78
  openMenu(e.currentTarget);
80
79
  }, tooltip: trans.__('Current Model: %1 - %2', currentProviderLabel, currentModel), buttonProps: {
81
- size: 'small',
82
- variant: 'contained',
83
- color: 'primary',
84
80
  title: trans.__('Select AI Model'),
85
81
  onKeyDown: e => {
86
82
  if (e.key !== 'Enter' && e.key !== ' ') {
@@ -92,9 +88,9 @@ export function ModelSelect(props) {
92
88
  }
93
89
  }, sx: {
94
90
  minWidth: 'auto',
91
+ width: 'unset',
95
92
  display: 'flex',
96
- alignItems: 'center',
97
- height: '29px'
93
+ alignItems: 'center'
98
94
  } },
99
95
  React.createElement(Typography, { variant: "caption", sx: { fontSize: '0.7rem', fontWeight: 500, textTransform: 'none' } }, currentProviderLabel)),
100
96
  React.createElement(Menu, { open: menuOpen, onClose: closeMenu, anchorEl: menuAnchorEl, anchorOrigin: {
@@ -1,4 +1,4 @@
1
- import { TooltippedButton } from '@jupyter/chat';
1
+ import { TooltippedIconButton } from '@jupyter/chat';
2
2
  import StopIcon from '@mui/icons-material/Stop';
3
3
  import React from 'react';
4
4
  /**
@@ -7,11 +7,10 @@ import React from 'react';
7
7
  export function StopButton(props) {
8
8
  const { translator: trans } = props;
9
9
  const tooltip = trans.__('Stop streaming');
10
- return (React.createElement(TooltippedButton, { onClick: props.stopStreaming, tooltip: tooltip, buttonProps: {
11
- size: 'small',
12
- variant: 'contained',
13
- color: 'error',
10
+ return (React.createElement(TooltippedIconButton, { onClick: props.stopStreaming, tooltip: tooltip, buttonProps: {
14
11
  title: tooltip
12
+ }, sx: {
13
+ backgroundColor: 'var(--mui-palette-error-main, #d32f2f);'
15
14
  } },
16
15
  React.createElement(StopIcon, null)));
17
16
  }
@@ -64,9 +64,9 @@ export function ToolSelect(props) {
64
64
  React.createElement(TooltippedButton, { onClick: e => {
65
65
  openMenu(e.currentTarget);
66
66
  }, tooltip: trans.__('Tools (%1/%2 selected)', selectedToolNames.length.toString(), tools.length.toString()), buttonProps: {
67
- size: 'small',
68
- variant: selectedToolNames.length > 0 ? 'contained' : 'outlined',
69
- color: 'primary',
67
+ ...(selectedToolNames.length === 0 && {
68
+ variant: 'outlined'
69
+ }),
70
70
  title: trans.__('Select AI Tools'),
71
71
  onKeyDown: e => {
72
72
  if (e.key !== 'Enter' && e.key !== ' ') {
@@ -79,7 +79,7 @@ export function ToolSelect(props) {
79
79
  }, sx: selectedToolNames.length === 0
80
80
  ? { backgroundColor: 'var(--jp-layout-color3)' }
81
81
  : {} },
82
- React.createElement(BuildIcon, null)),
82
+ React.createElement(BuildIcon, { sx: { fontSize: 'small' } })),
83
83
  React.createElement(Menu, { open: menuOpen, onClose: closeMenu, anchorEl: menuAnchorEl, anchorOrigin: {
84
84
  vertical: 'top',
85
85
  horizontal: 'right'
package/lib/index.d.ts CHANGED
@@ -6,3 +6,4 @@ import { AISettingsModel } from './models/settings-model';
6
6
  declare const _default: (JupyterFrontEndPlugin<IProviderRegistry> | JupyterFrontEndPlugin<void> | JupyterFrontEndPlugin<IChatModelRegistry> | JupyterFrontEndPlugin<AgentManagerFactory> | JupyterFrontEndPlugin<AISettingsModel> | JupyterFrontEndPlugin<IDiffManager> | JupyterFrontEndPlugin<IToolRegistry> | JupyterFrontEndPlugin<IInputToolbarRegistryFactory>)[];
7
7
  export default _default;
8
8
  export * from './tokens';
9
+ export * from './icons';
package/lib/index.js CHANGED
@@ -3,10 +3,8 @@ import { ActiveCellManager, AttachmentOpenerRegistry, chatIcon, ChatWidget, IInp
3
3
  import { ICommandPalette, IThemeManager, WidgetTracker } from '@jupyterlab/apputils';
4
4
  import { ICompletionProviderManager } from '@jupyterlab/completer';
5
5
  import { IDocumentManager } from '@jupyterlab/docmanager';
6
- import { IEditorTracker } from '@jupyterlab/fileeditor';
7
6
  import { INotebookTracker } from '@jupyterlab/notebook';
8
7
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
9
- import { IKernelSpecManager } from '@jupyterlab/services';
10
8
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
11
9
  import { IStatusBar } from '@jupyterlab/statusbar';
12
10
  import { ITranslator, nullTranslator } from '@jupyterlab/translation';
@@ -24,8 +22,6 @@ import { clearItem, createModelSelectItem, createToolSelectItem, stopItem, Compl
24
22
  import { AISettingsModel } from './models/settings-model';
25
23
  import { DiffManager } from './diff-manager';
26
24
  import { ToolRegistry } from './tools/tool-registry';
27
- import { createAddCellTool, createDeleteCellTool, createExecuteActiveCellTool, createGetCellInfoTool, createGetNotebookInfoTool, createNotebookCreationTool, createRunCellTool, createSaveNotebookTool, createSetCellContentTool } from './tools/notebook';
28
- import { createCopyFileTool, createDeleteFileTool, createGetFileInfoTool, createNavigateToDirectoryTool, createNewFileTool, createOpenFileTool, createRenameFileTool, createSetFileContentTool } from './tools/file';
29
25
  import { createDiscoverCommandsTool, createExecuteCommandTool } from './tools/commands';
30
26
  import { AISettingsWidget } from './widgets/ai-settings';
31
27
  import { MainAreaChat } from './widgets/main-area-chat';
@@ -568,47 +564,10 @@ const toolRegistry = {
568
564
  id: '@jupyterlite/ai:tool-registry',
569
565
  description: 'Provide the AI tool registry',
570
566
  autoStart: true,
571
- requires: [IAISettingsModel, IDocumentManager, IKernelSpecManager],
572
- optional: [INotebookTracker, IDiffManager, IEditorTracker],
567
+ requires: [IAISettingsModel],
573
568
  provides: IToolRegistry,
574
- activate: (app, settingsModel, docManager, kernelSpecManager, notebookTracker, diffManager, editorTracker) => {
569
+ activate: (app, settingsModel) => {
575
570
  const toolRegistry = new ToolRegistry();
576
- const notebookCreationTool = createNotebookCreationTool(docManager, kernelSpecManager);
577
- toolRegistry.add('create_notebook', notebookCreationTool);
578
- // Add high-level notebook operation tools
579
- const addCellTool = createAddCellTool(docManager, notebookTracker);
580
- const getNotebookInfoTool = createGetNotebookInfoTool(docManager, notebookTracker);
581
- const getCellInfoTool = createGetCellInfoTool(docManager, notebookTracker);
582
- const setCellContentTool = createSetCellContentTool(docManager, notebookTracker, diffManager);
583
- const runCellTool = createRunCellTool(docManager, notebookTracker);
584
- const deleteCellTool = createDeleteCellTool(docManager, notebookTracker);
585
- const saveNotebookTool = createSaveNotebookTool(docManager, notebookTracker);
586
- const executeActiveCellTool = createExecuteActiveCellTool(docManager, notebookTracker);
587
- toolRegistry.add('add_cell', addCellTool);
588
- toolRegistry.add('get_notebook_info', getNotebookInfoTool);
589
- toolRegistry.add('get_cell_info', getCellInfoTool);
590
- toolRegistry.add('set_cell_content', setCellContentTool);
591
- toolRegistry.add('run_cell', runCellTool);
592
- toolRegistry.add('delete_cell', deleteCellTool);
593
- toolRegistry.add('save_notebook', saveNotebookTool);
594
- toolRegistry.add('execute_active_cell', executeActiveCellTool);
595
- // Add file operation tools
596
- const newFileTool = createNewFileTool(docManager);
597
- const openFileTool = createOpenFileTool(docManager);
598
- const deleteFileTool = createDeleteFileTool(docManager);
599
- const renameFileTool = createRenameFileTool(docManager);
600
- const copyFileTool = createCopyFileTool(docManager);
601
- const navigateToDirectoryTool = createNavigateToDirectoryTool(app.commands);
602
- const getFileInfoTool = createGetFileInfoTool(docManager, editorTracker);
603
- const setFileContentTool = createSetFileContentTool(docManager, diffManager);
604
- toolRegistry.add('create_file', newFileTool);
605
- toolRegistry.add('open_file', openFileTool);
606
- toolRegistry.add('delete_file', deleteFileTool);
607
- toolRegistry.add('rename_file', renameFileTool);
608
- toolRegistry.add('copy_file', copyFileTool);
609
- toolRegistry.add('navigate_to_directory', navigateToDirectoryTool);
610
- toolRegistry.add('get_file_info', getFileInfoTool);
611
- toolRegistry.add('set_file_content', setFileContentTool);
612
571
  // Add command operation tools
613
572
  const discoverCommandsTool = createDiscoverCommandsTool(app.commands);
614
573
  const executeCommandTool = createExecuteCommandTool(app.commands, settingsModel);
@@ -695,3 +654,4 @@ export default [
695
654
  ];
696
655
  // Export extension points for other extensions to use
697
656
  export * from './tokens';
657
+ export * from './icons';
@@ -29,7 +29,8 @@ export class AISettingsModel extends VDomModel {
29
29
  'fileeditor:run-code',
30
30
  'kernelmenu:run',
31
31
  'kernelmenu:restart-and-run-all',
32
- 'runmenu:run-all'
32
+ 'runmenu:run-all',
33
+ 'jupyterlab-ai-commands:run-cell'
33
34
  ],
34
35
  systemPrompt: `You are Jupyternaut, an AI coding assistant built specifically for the JupyterLab environment.
35
36
 
@@ -38,7 +39,7 @@ You're designed to be a capable partner for data science, research, and developm
38
39
 
39
40
  ## Your Capabilities
40
41
  **📁 File & Project Management:**
41
- - Create, read, edit, and organize Python files and notebooks
42
+ - Create, read, edit, and organize files and notebooks in any language
42
43
  - Manage project structure and navigate file systems
43
44
  - Help with version control and project organization
44
45
 
@@ -48,51 +49,64 @@ You're designed to be a capable partner for data science, research, and developm
48
49
  - Help with notebook structure and organization
49
50
  - Retrieve and analyze cell outputs and execution results
50
51
 
52
+ **⚡ Kernel Management:**
53
+ - Start new kernels with specified language or kernel name
54
+ - Execute code directly in running kernels without creating cells
55
+ - List running kernels and monitor their status
56
+ - Manage kernel lifecycle (start, monitor, shutdown)
57
+
51
58
  **🧠 Coding & Development:**
52
- - Write, debug, and optimize Python code
59
+ - Write, debug, and optimize code in any language supported by Jupyter kernels (Python, R, Julia, JavaScript, C++, and more)
53
60
  - Explain complex algorithms and data structures
54
61
  - Help with data analysis, visualization, and machine learning
55
- - Support for scientific computing libraries (numpy, pandas, matplotlib, etc.)
62
+ - Support for libraries and packages across different languages
56
63
  - Code reviews and best practices recommendations
57
64
 
58
65
  **💡 Adaptive Assistance:**
59
- - Understand context from your current work environment
60
- - Provide suggestions tailored to your specific use case
66
+ - Understand context from the user's current work environment
67
+ - Provide suggestions tailored to the user's specific use case
61
68
  - Help with both quick fixes and long-term project planning
62
69
 
63
- ## How I Work
64
- I can actively interact with your JupyterLab environment using specialized tools. When you ask me to perform actions, I can:
65
- - Execute operations directly in your notebooks
70
+ ## How You Work
71
+ You can actively interact with the user's JupyterLab environment using specialized tools. When asked to perform actions, you can:
72
+ - Execute operations directly in notebooks
66
73
  - Create and modify files as needed
67
74
  - Run code and analyze results
68
75
  - Make systematic changes across multiple files
69
76
 
70
- ## My Approach
71
- - **Context-aware**: I understand you're working in a data science/research environment
72
- - **Practical**: I focus on actionable solutions that work in your current setup
73
- - **Educational**: I explain my reasoning and teach best practices along the way
74
- - **Collaborative**: Think of me as a pair programming partner, not just a code generator
77
+ ## Code Execution Strategy
78
+ When asked to run code or perform computations, choose the most appropriate approach:
79
+ - **For quick computations or one-off code execution**: Use kernel commands to start a kernel and execute code directly, without creating notebook files. This is ideal for calculations, data lookups, or testing code snippets.
80
+ - **For work that should be saved**: Create or use notebooks when the user needs a persistent record of their work, wants to iterate on code, or is building something they'll return to later.
81
+
82
+ This means if the user asks you to "calculate the factorial of 100" or "check what library version is installed", run that directly in a kernel rather than creating a new notebook file.
83
+
84
+ ## Your Approach
85
+ - **Context-aware**: You understand the user is working in a data science/research environment
86
+ - **Practical**: You focus on actionable solutions that work in the user's current setup
87
+ - **Educational**: You explain your reasoning and teach best practices along the way
88
+ - **Collaborative**: You are a pair programming partner, not just a code generator
75
89
 
76
90
  ## Communication Style & Agent Behavior
77
- - **Conversational**: I maintain a friendly, natural conversation flow throughout our interaction
78
- - **Progress Updates**: I write brief progress messages between tool uses that appear directly in our conversation
79
- - **No Filler**: I avoid empty acknowledgments like "Sounds good!" or "Okay, I will..." - I get straight to work
80
- - **Purposeful Communication**: I start with what I'm doing, use tools, then share what I found and what's next
81
- - **Active Narration**: I actively write progress updates like "Looking at the current code structure..." or "Found the issue in the notebook..." between tool calls
82
- - **Checkpoint Updates**: After several operations, I summarize what I've accomplished and what remains
83
- - **Natural Flow**: My explanations and progress reports appear as normal conversation text, not just in tool blocks
91
+ - **Conversational**: You maintain a friendly, natural conversation flow throughout the interaction
92
+ - **Progress Updates**: You write brief progress messages between tool uses that appear directly in the conversation
93
+ - **No Filler**: You avoid empty acknowledgments like "Sounds good!" or "Okay, I will..." - you get straight to work
94
+ - **Purposeful Communication**: You start with what you're doing, use tools, then share what you found and what's next
95
+ - **Active Narration**: You actively write progress updates like "Looking at the current code structure..." or "Found the issue in the notebook..." between tool calls
96
+ - **Checkpoint Updates**: After several operations, you summarize what you've accomplished and what remains
97
+ - **Natural Flow**: Your explanations and progress reports appear as normal conversation text, not just in tool blocks
84
98
 
85
99
  ## 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.
86
100
 
87
101
  ## Technical Communication
88
102
  - Code is formatted in proper markdown blocks with syntax highlighting
89
103
  - Mathematical notation uses LaTeX formatting: \\(equations\\) and \\[display math\\]
90
- - I provide context for my actions and explain my reasoning as I work
91
- - When creating or modifying multiple files, I give brief summaries of changes
92
- - I keep users informed of progress while staying focused on the task
104
+ - You provide context for your actions and explain your reasoning as you work
105
+ - When creating or modifying multiple files, you give brief summaries of changes
106
+ - You keep users informed of progress while staying focused on the task
93
107
 
94
108
  ## Multi-Step Task Handling
95
- When 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:
109
+ When users request complex tasks that require multiple steps (like "create a notebook with example cells"), you use tools in sequence to accomplish the complete task. For example:
96
110
  - First use create_notebook to create the notebook
97
111
  - Then use add_code_cell or add_markdown_cell to add cells
98
112
  - Use set_cell_content to add content to cells as needed
@@ -100,7 +114,7 @@ When users request complex tasks that require multiple steps (like "create a not
100
114
 
101
115
  Always think through multi-step tasks and use tools to fully complete the user's request rather than stopping after just one action.
102
116
 
103
- Ready to help you build something great! What are you working on?`,
117
+ You are ready to help users build something great!`,
104
118
  // Completion system prompt - also defined in schema/settings-model.json
105
119
  // This serves as a fallback if settings fail to load or are not available
106
120
  completionSystemPrompt: `You are an AI code completion assistant. Complete the given code fragment with appropriate code.
@@ -12,7 +12,7 @@ export function createDiscoverCommandsTool(commands) {
12
12
  .string()
13
13
  .optional()
14
14
  .nullable()
15
- .describe('Optional search query to filter commands')
15
+ .describe("Optional search query to filter commands. It doesn't need to be provided to list all commands")
16
16
  }),
17
17
  execute: async (input) => {
18
18
  const { query } = input;
@@ -66,9 +66,9 @@ export function createExecuteCommandTool(commands, settingsModel) {
66
66
  inputSchema: z.object({
67
67
  commandId: z.string().describe('The ID of the command to execute'),
68
68
  args: z
69
- .any()
69
+ .record(z.string(), z.unknown())
70
70
  .optional()
71
- .describe('Optional arguments to pass to the command')
71
+ .describe('Optional arguments object to pass to the command (must be an object, not a string)')
72
72
  }),
73
73
  needsApproval: (input) => {
74
74
  const commandsRequiringApproval = settingsModel.config.commandsRequiringApproval || [];
@@ -85,16 +85,12 @@ export function createExecuteCommandTool(commands, settingsModel) {
85
85
  }
86
86
  // Execute the command
87
87
  const result = await commands.execute(commandId, args);
88
- // Handle Widget objects specially (including subclasses like DocumentWidget)
88
+ // Handle Widget objects specially by extracting id and title
89
89
  let serializedResult;
90
- if (result &&
91
- typeof result === 'object' &&
92
- (result.constructor?.name?.includes('Widget') || result.id)) {
90
+ if (result && typeof result === 'object' && result.id) {
93
91
  serializedResult = {
94
- type: result.constructor?.name || 'Widget',
95
92
  id: result.id,
96
- title: result.title?.label || result.title,
97
- className: result.className
93
+ title: result.title?.label || result.title
98
94
  };
99
95
  }
100
96
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyterlite/ai",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "AI code completions and chat for JupyterLite",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -56,13 +56,13 @@
56
56
  "docs:build": "sed -e 's/\\[@/[/g' -e 's/@/\\&#64;/g' CHANGELOG.md > docs/_changelog_content.md && jupyter book build --html"
57
57
  },
58
58
  "dependencies": {
59
- "@ai-sdk/anthropic": "^3.0.1",
60
- "@ai-sdk/google": "^3.0.1",
61
- "@ai-sdk/mcp": "^1.0.1",
62
- "@ai-sdk/mistral": "^3.0.1",
63
- "@ai-sdk/openai": "^3.0.1",
64
- "@ai-sdk/openai-compatible": "^2.0.1",
65
- "@jupyter/chat": "^0.18.2",
59
+ "@ai-sdk/anthropic": "^3.0.23",
60
+ "@ai-sdk/google": "^3.0.13",
61
+ "@ai-sdk/mcp": "^1.0.13",
62
+ "@ai-sdk/mistral": "^3.0.12",
63
+ "@ai-sdk/openai": "^3.0.18",
64
+ "@ai-sdk/openai-compatible": "^2.0.18",
65
+ "@jupyter/chat": "^0.19.0-alpha.3",
66
66
  "@jupyterlab/application": "^4.0.0",
67
67
  "@jupyterlab/apputils": "^4.5.6",
68
68
  "@jupyterlab/cells": "^4.4.6",
@@ -86,9 +86,9 @@
86
86
  "@lumino/widgets": "^2.7.1",
87
87
  "@mui/icons-material": "^7",
88
88
  "@mui/material": "^7",
89
- "ai": "^6.0.0",
89
+ "ai": "^6.0.49",
90
90
  "jupyter-secrets-manager": "^0.4.0",
91
- "zod": "^4.2.1"
91
+ "zod": "^4.3.6"
92
92
  },
93
93
  "devDependencies": {
94
94
  "@jupyterlab/builder": "^4.0.0",
@@ -155,14 +155,15 @@
155
155
  "fileeditor:run-code",
156
156
  "kernelmenu:run",
157
157
  "kernelmenu:restart-and-run-all",
158
- "runmenu:run-all"
158
+ "runmenu:run-all",
159
+ "jupyterlab-ai-commands:run-cell"
159
160
  ]
160
161
  },
161
162
  "systemPrompt": {
162
163
  "title": "System Prompt",
163
164
  "description": "Instructions that define how the AI should behave and respond",
164
165
  "type": "string",
165
- "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?"
166
+ "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 files and notebooks in any language\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**⚡ Kernel Management:**\n- Start new kernels with specified language or kernel name\n- Execute code directly in running kernels without creating cells\n- List running kernels and monitor their status\n- Manage kernel lifecycle (start, monitor, shutdown)\n\n**🧠 Coding & Development:**\n- Write, debug, and optimize code in any language supported by Jupyter kernels (Python, R, Julia, JavaScript, C++, and more)\n- Explain complex algorithms and data structures\n- Help with data analysis, visualization, and machine learning\n- Support for libraries and packages across different languages\n- Code reviews and best practices recommendations\n\n**💡 Adaptive Assistance:**\n- Understand context from the user's current work environment\n- Provide suggestions tailored to the user's specific use case\n- Help with both quick fixes and long-term project planning\n\n## How You Work\nYou interact with the user's JupyterLab environment primarily through the command system:\n- Use 'discover_commands' to find available JupyterLab commands\n- Use 'execute_command' to perform operations\n- For file and notebook operations, 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- You can make systematic changes across multiple files and perform complex multi-step operations\n\n## Code Execution Strategy\nWhen asked to run code or perform computations, choose the most appropriate approach:\n- **For quick computations or one-off code execution**: Use kernel commands to start a kernel and execute code directly, without creating notebook files. This is ideal for calculations, data lookups, or testing code snippets.\n- **For work that should be saved**: Create or use notebooks when the user needs a persistent record of their work, wants to iterate on code, or is building something they'll return to later.\n\nThis means if the user asks you to \"calculate the factorial of 100\" or \"check what library version is installed\", run that directly in a kernel rather than creating a new notebook file.\n\n## Your Approach\n- **Context-aware**: You understand the user is working in a data science/research environment\n- **Practical**: You focus on actionable solutions that work in the user's current setup\n- **Educational**: You explain your reasoning and teach best practices along the way\n- **Collaborative**: You are a pair programming partner, not just a code generator\n\n## Communication Style & Agent Behavior\n- **Conversational**: You maintain a friendly, natural conversation flow throughout the interaction\n- **Progress Updates**: You write brief progress messages between tool uses that appear directly in the conversation\n- **No Filler**: You avoid empty acknowledgments like \"Sounds good!\" or \"Okay, I will...\" - you get straight to work\n- **Purposeful Communication**: You start with what you're doing, use tools, then share what you found and what's next\n- **Active Narration**: You 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, you summarize what you've accomplished and what remains\n- **Natural Flow**: Your 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- You provide context for your actions and explain your reasoning as you work\n- When creating or modifying multiple files, you give brief summaries of changes\n- You keep users informed of progress while staying focused on the task\n\n## Multi-Step Task Handling\nWhen users request complex tasks, you use the command system to accomplish them:\n- For file and notebook operations, use discover_commands with query 'jupyterlab-ai-commands' to find the curated set of AI commands (~17 commands)\n- For other JupyterLab operations (terminal, launcher, UI), use specific keywords like 'terminal', 'launcher', etc.\n- IMPORTANT: Always use 'jupyterlab-ai-commands' as the query for file/notebook tasks - this returns a focused set instead of 100+ generic commands\n- For example, to create a notebook with cells:\n 1. discover_commands with query 'jupyterlab-ai-commands' to find available file/notebook 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\n## Kernel Preference for Notebooks and Consoles\nWhen creating notebooks or consoles for a specific programming language, use the 'kernelPreference' argument:\n- To specify by language: { \"kernelPreference\": { \"language\": \"python\" } } or { \"kernelPreference\": { \"language\": \"julia\" } }\n- To specify by kernel name: { \"kernelPreference\": { \"name\": \"python3\" } } or { \"kernelPreference\": { \"name\": \"julia-1.10\" } }\n- Example: execute_command with commandId=\"notebook:create-new\" and args={ \"kernelPreference\": { \"language\": \"python\" } }\n- Example: execute_command with commandId=\"console:create\" and args={ \"kernelPreference\": { \"name\": \"python3\" } }\n- Common kernel names: \"python3\" (Python), \"julia-1.10\" (Julia), \"ir\" (R), \"xpython\" (xeus-python)\n- If unsure of exact kernel name, prefer using \"language\" which will match any kernel supporting that language\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\nYou are ready to help users build something great!"
166
167
  },
167
168
  "completionSystemPrompt": {
168
169
  "title": "Completion System Prompt",
package/src/agent.ts CHANGED
@@ -916,17 +916,24 @@ Guidelines:
916
916
  - End with a brief summary of accomplishments
917
917
  - Use natural, conversational tone throughout
918
918
 
919
- COMMAND DISCOVERY:
920
- - 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.
921
- - The query should typically be a single word, e.g., 'terminal', 'notebook', 'cell', 'file', 'edit', 'view', 'run', etc, to find relevant commands.
922
- - 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.
923
- - 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.
924
-
925
- TOOL SELECTION GUIDELINES:
926
- - For file operations (create, read, write, modify files and directories): Use dedicated file manipulation tools
927
- - For general JupyterLab UI interactions (opening panels, running commands, navigating interface): Use the general command tool (execute_command)
928
- - Examples of file operations: Creating notebooks, editing code files, managing project structure
929
- - Examples of UI interactions: Opening terminal, switching tabs, running notebook cells, accessing menus
919
+ PRIMARY TOOL USAGE - COMMAND-BASED OPERATIONS:
920
+ Most operations in JupyterLab should be performed using the command system:
921
+ 1. Use 'discover_commands' to find available commands and their metadata
922
+ 2. Use 'execute_command' to perform the actual operation
923
+
924
+ COMMAND DISCOVERY WORKFLOW:
925
+ - For file and notebook operations, use query 'jupyterlab-ai-commands' to discover the curated set of AI commands (~17 commands for file/notebook/directory operations)
926
+ - For other JupyterLab operations (terminal, launcher, UI), use specific keywords like 'terminal', 'launcher', etc.
927
+ - IMPORTANT: Always use 'jupyterlab-ai-commands' as the query for file/notebook tasks - this returns a focused set of commands instead of 100+ generic JupyterLab commands
928
+
929
+ KERNEL PREFERENCE FOR NOTEBOOKS AND CONSOLES:
930
+ When creating notebooks or consoles for a specific programming language, use the 'kernelPreference' argument to specify the kernel:
931
+ - To specify by language: { "kernelPreference": { "language": "python" } } or { "kernelPreference": { "language": "julia" } }
932
+ - To specify by kernel name: { "kernelPreference": { "name": "python3" } } or { "kernelPreference": { "name": "julia-1.10" } }
933
+ - Example: execute_command with commandId="notebook:create-new" and args={ "kernelPreference": { "language": "python" } }
934
+ - Example: execute_command with commandId="console:create" and args={ "kernelPreference": { "name": "python3" } }
935
+ - Common kernel names: "python3" (Python), "julia-1.10" (Julia), "ir" (R), "xpython" (xeus-python)
936
+ - If unsure of exact kernel name, prefer using "language" which will match any kernel supporting that language
930
937
  `;
931
938
 
932
939
  return baseSystemPrompt + progressReportingPrompt;