Skip to content

Commit c6033fb

Browse files
committed
Data Engineer mode (rebased on 3.10.5)
improve nb edit tool, articulate append case out of insert case
1 parent 0fd0800 commit c6033fb

29 files changed

+1818
-4
lines changed

src/core/Cline.ts

Lines changed: 415 additions & 0 deletions
Large diffs are not rendered by default.

src/core/assistant-message/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export const toolUseNames = [
2626
"switch_mode",
2727
"new_task",
2828
"fetch_instructions",
29+
"notebook_read",
30+
"notebook_edit",
31+
"notebook_execute",
2932
] as const
3033

3134
// Converts array of tool call names into a union type ("execute_command" | "read_file" | ...)
@@ -61,6 +64,12 @@ export const toolParamNames = [
6164
"cwd",
6265
"follow_up",
6366
"task",
67+
"cell_index",
68+
"cell_type",
69+
"cell_content",
70+
"language_id",
71+
"start_index",
72+
"end_index",
6473
] as const
6574

6675
export type ToolParamName = (typeof toolParamNames)[number]
@@ -148,3 +157,23 @@ export interface NewTaskToolUse extends ToolUse {
148157
name: "new_task"
149158
params: Partial<Pick<Record<ToolParamName, string>, "mode" | "message">>
150159
}
160+
161+
export interface NotebookReadToolUse extends ToolUse {
162+
name: "notebook_read"
163+
params: Partial<Pick<Record<ToolParamName, string>, "action">>
164+
}
165+
166+
export interface NotebookEditToolUse extends ToolUse {
167+
name: "notebook_edit"
168+
params: Partial<
169+
Pick<
170+
Record<ToolParamName, string>,
171+
"action" | "cell_index" | "start_index" | "end_index" | "cell_content" | "cell_type" | "language_id"
172+
>
173+
>
174+
}
175+
176+
export interface NotebookExecuteToolUse extends ToolUse {
177+
name: "notebook_execute"
178+
params: Partial<Pick<Record<ToolParamName, string>, "action" | "start_index" | "end_index">>
179+
}

src/core/prompts/tools/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { getUseMcpToolDescription } from "./use-mcp-tool"
1414
import { getAccessMcpResourceDescription } from "./access-mcp-resource"
1515
import { getSwitchModeDescription } from "./switch-mode"
1616
import { getNewTaskDescription } from "./new-task"
17+
import { getNotebookReadToolDescription } from "./notebook-read"
18+
import { getNotebookEditToolDescription } from "./notebook-edit"
19+
import { getNotebookExecuteToolDescription } from "./notebook-execute"
1720
import { DiffStrategy } from "../../diff/DiffStrategy"
1821
import { McpHub } from "../../../services/mcp/McpHub"
1922
import { Mode, ModeConfig, getModeConfig, isToolAllowedForMode, getGroupName } from "../../../shared/modes"
@@ -38,6 +41,9 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
3841
new_task: (args) => getNewTaskDescription(args),
3942
insert_content: (args) => getInsertContentDescription(args),
4043
search_and_replace: (args) => getSearchAndReplaceDescription(args),
44+
notebook_read: (args) => getNotebookReadToolDescription(args),
45+
notebook_edit: (args) => getNotebookEditToolDescription(args),
46+
notebook_execute: (args) => getNotebookExecuteToolDescription(args),
4147
apply_diff: (args) =>
4248
args.diffStrategy ? args.diffStrategy.getToolDescription({ cwd: args.cwd, toolOptions: args.toolOptions }) : "",
4349
}
@@ -112,4 +118,7 @@ export {
112118
getSwitchModeDescription,
113119
getInsertContentDescription,
114120
getSearchAndReplaceDescription,
121+
getNotebookReadToolDescription,
122+
getNotebookEditToolDescription,
123+
getNotebookExecuteToolDescription,
115124
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { ToolArgs } from "./types"
2+
3+
export function getNotebookEditToolDescription(args: ToolArgs): string {
4+
return `## notebook_edit
5+
Description: Edit the active notebook in the editor. This tool allows you to insert new cells, append cells to the end, or replace existing cells. Note that new/modified code cells will be executed immediately by default, unless the <noexec/> parameter is present.
6+
Parameters:
7+
- action: (required) The action to perform. Valid values are:
8+
- "insert_cells": Insert a new cell into the notebook (or append to the end if cell_index is omitted)
9+
- "modify_cell_content": Modify the content of an existing cell in the notebook (note: this will clear any existing outputs)
10+
- "replace_cells": Replace a range of cells with a new cell (note: this will clear any existing outputs)
11+
- cell_index: (required for modify_cell_content, optional for insert_cells) The index of the cell to modify (0-based), or for insert_cells the position to insert at (defaults to end of notebook for append)
12+
- start_index: (required for replace_cells) The starting index of the range to replace (0-based, inclusive)
13+
- end_index: (required for replace_cells) The ending index of the range to replace (0-based, exclusive)
14+
- cell_type: (optional for insert_cells and replace_cells) The type of cell, either "code" or "markdown"
15+
- language_id: (optional for insert_cells and replace_cells) The language of the cell (e.g., "python", "javascript")
16+
- cell_content: (required for all actions) The content of the cell
17+
- noexec: (optional) Can be used as a flag <noexec/> or with explicit value <noexec>true</noexec> to prevent automatic execution of new/modified code cells.
18+
Usage:
19+
<notebook_edit>
20+
<action>action name here</action>
21+
<cell_index>index value here (if required)</cell_index>
22+
<start_index>start index here (if required)</start_index>
23+
<end_index>end index here (if required)</end_index>
24+
<cell_type>cell type here (if required)</cell_type>
25+
<language_id>language here (if required)</language_id>
26+
<cell_content>cell content here</cell_content>
27+
<noexec/>
28+
</notebook_edit>
29+
30+
Example 1: Insert a new Python code cell
31+
<notebook_edit>
32+
<action>insert_cells</action>
33+
<cell_index>0</cell_index>
34+
<cell_type>code</cell_type>
35+
<language_id>python</language_id>
36+
<cell_content>import pandas as pd
37+
import numpy as np
38+
df = pd.read_csv('data.csv')
39+
df.head()</cell_content>
40+
</notebook_edit>
41+
42+
Example 2: Append a new markdown cell
43+
<notebook_edit>
44+
<action>insert_cells</action>
45+
<cell_type>markdown</cell_type>
46+
<cell_content># Data Analysis
47+
This notebook contains the analysis of our dataset with the following steps:
48+
1. Data loading and cleaning
49+
2. Exploratory data analysis
50+
3. Statistical testing
51+
4. Visualization</cell_content>
52+
</notebook_edit>
53+
54+
Example 3: Modify an existing cell without execution
55+
<notebook_edit>
56+
<action>modify_cell_content</action>
57+
<cell_index>2</cell_index>
58+
<noexec/>
59+
<cell_content>import matplotlib.pyplot as plt
60+
plt.figure(figsize=(10, 6))
61+
plt.plot(df['x'], df['y'])
62+
plt.title('Data Visualization')
63+
plt.xlabel('X Axis')
64+
plt.ylabel('Y Axis')
65+
plt.show()</cell_content>
66+
</notebook_edit>
67+
68+
Example 4: Replace a range of cells with a new cell
69+
<notebook_edit>
70+
<action>replace_cells</action>
71+
<start_index>2</start_index>
72+
<end_index>4</end_index>
73+
<cell_type>code</cell_type>
74+
<language_id>python</language_id>
75+
<cell_content>import matplotlib.pyplot as plt
76+
import seaborn as sns
77+
78+
plt.figure(figsize=(10, 6))
79+
sns.scatterplot(x='x', y='y', data=df)
80+
plt.title('Scatter Plot')
81+
plt.show()</cell_content>
82+
</notebook_edit>
83+
84+
IMPORTANT: For insert_cells and replace_cells, each cell_content tag creates a new cell. The cell_type and language_id tags must come BEFORE the cell_content tag they apply to. The last cell_type before a cell_content will be used as that cell's type, and the last language_id before a cell_content will be used as that cell's language.`
85+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { ToolArgs } from "./types"
2+
3+
export function getNotebookExecuteToolDescription(args: ToolArgs): string {
4+
return `## notebook_execute
5+
Description: Execute cells in the active notebook.
6+
Parameters:
7+
- action: (required) The action to perform. Currently only "execute_cells" is supported.
8+
- start_index: (required) The starting index of the range to execute (0-based, inclusive). Must be a valid cell index in the notebook.
9+
- end_index: (required) The ending index of the range to execute (0-based, exclusive). Must be a valid cell index in the notebook and >= start_index.
10+
11+
Usage:
12+
<notebook_execute>
13+
<action>execute_cells</action>
14+
<start_index>start index value here</start_index>
15+
<end_index>end index value here</end_index>
16+
</notebook_execute>
17+
18+
Example: Execute cells from index 3 through 5 (inclusive)
19+
<notebook_execute>
20+
<action>execute_cells</action>
21+
<start_index>3</start_index>
22+
<end_index>6</end_index>
23+
</notebook_execute>
24+
25+
Notes:
26+
- The execution is initiated immediately, but completion time depends on the cells' content
27+
- The tool will wait for execution to complete and return the results
28+
- Results include both the cell content and any outputs produced by execution
29+
- Execution will timeout if it takes too long, and a timeout message will be included in the response
30+
- Cell outputs are truncated if they exceed the configured size limit
31+
- To execute a single cell, set end_index to start_index + 1`
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { ToolArgs } from "./types"
2+
3+
export function getNotebookReadToolDescription(args: ToolArgs): string {
4+
return `## notebook_read
5+
Description: Retrieve information about the active notebook in the editor.
6+
Parameters:
7+
- action: (required) The action to perform. Valid values are:
8+
- "get_info": Get comprehensive information about the active notebook, including URI, kernel info, and cell statistics
9+
- "get_cells": Get the cells of the active notebook. Returns detailed information about each cell, including content and outputs
10+
11+
Usage:
12+
<notebook_read>
13+
<action>action name here</action>
14+
</notebook_read>
15+
16+
Example 1: Get comprehensive notebook information
17+
<notebook_read>
18+
<action>get_info</action>
19+
</notebook_read>
20+
21+
Example 2: Get the cells of the active notebook
22+
<notebook_read>
23+
<action>get_cells</action>
24+
</notebook_read>
25+
26+
Notes:
27+
- The "get_info" action provides a comprehensive overview including URI, kernel info, and statistics about cell types and languages
28+
- If no active notebook is found, "get_info" will return a message stating "No active notebook found"
29+
- The "get_cells" action provides a formatted analysis of all cells, including their content and outputs
30+
- If no active notebook is found, "get_cells" will return an error message
31+
- Cell content and outputs are truncated if they exceed the configured size limit
32+
- For code cells, both the source code and execution outputs are included`
33+
}

src/core/webview/ClineProvider.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,6 +2029,26 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
20292029
await this.postStateToWebview()
20302030
break
20312031
}
2032+
case "notebookOutputSizeLimit":
2033+
await this.updateGlobalState("notebookOutputSizeLimit", message.value)
2034+
await this.postStateToWebview()
2035+
break
2036+
case "notebookExecutionTimeoutSeconds":
2037+
await this.updateGlobalState("notebookExecutionTimeoutSeconds", message.value)
2038+
await this.postStateToWebview()
2039+
break
2040+
case "alwaysAllowReadNotebook":
2041+
await this.updateGlobalState("alwaysAllowReadNotebook", message.bool ?? undefined)
2042+
await this.postStateToWebview()
2043+
break
2044+
case "alwaysAllowEditNotebook":
2045+
await this.updateGlobalState("alwaysAllowEditNotebook", message.bool ?? undefined)
2046+
await this.postStateToWebview()
2047+
break
2048+
case "alwaysAllowExecuteNotebook":
2049+
await this.updateGlobalState("alwaysAllowExecuteNotebook", message.bool ?? undefined)
2050+
await this.postStateToWebview()
2051+
break
20322052
}
20332053
},
20342054
null,
@@ -2538,6 +2558,11 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
25382558
showRooIgnoredFiles,
25392559
language,
25402560
maxReadFileLine,
2561+
notebookOutputSizeLimit,
2562+
notebookExecutionTimeoutSeconds,
2563+
alwaysAllowReadNotebook,
2564+
alwaysAllowEditNotebook,
2565+
alwaysAllowExecuteNotebook,
25412566
} = await this.getState()
25422567

25432568
const telemetryKey = process.env.POSTHOG_API_KEY
@@ -2610,6 +2635,11 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
26102635
language,
26112636
renderContext: this.renderContext,
26122637
maxReadFileLine: maxReadFileLine ?? 500,
2638+
notebookOutputSizeLimit: notebookOutputSizeLimit ?? 2000,
2639+
notebookExecutionTimeoutSeconds: notebookExecutionTimeoutSeconds ?? 30,
2640+
alwaysAllowReadNotebook: alwaysAllowReadNotebook ?? false,
2641+
alwaysAllowEditNotebook: alwaysAllowEditNotebook ?? false,
2642+
alwaysAllowExecuteNotebook: alwaysAllowExecuteNotebook ?? false,
26132643
}
26142644
}
26152645

@@ -2764,6 +2794,11 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
27642794
telemetrySetting: stateValues.telemetrySetting || "unset",
27652795
showRooIgnoredFiles: stateValues.showRooIgnoredFiles ?? true,
27662796
maxReadFileLine: stateValues.maxReadFileLine ?? 500,
2797+
notebookOutputSizeLimit: stateValues.notebookOutputSizeLimit ?? 2000,
2798+
notebookExecutionTimeoutSeconds: stateValues.notebookExecutionTimeoutSeconds ?? 30,
2799+
alwaysAllowReadNotebook: stateValues.alwaysAllowReadNotebook ?? false,
2800+
alwaysAllowEditNotebook: stateValues.alwaysAllowEditNotebook ?? false,
2801+
alwaysAllowExecuteNotebook: stateValues.alwaysAllowExecuteNotebook ?? false,
27672802
}
27682803
}
27692804

src/core/webview/__tests__/ClineProvider.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,8 @@ describe("ClineProvider", () => {
467467
showRooIgnoredFiles: true,
468468
renderContext: "sidebar",
469469
maxReadFileLine: 500,
470+
notebookOutputSizeLimit: 1000,
471+
notebookExecutionTimeoutSeconds: 30,
470472
}
471473

472474
const message: ExtensionMessage = {

src/exports/roo-code.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ export type GlobalStateKey =
225225
| "writeDelayMs"
226226
| "terminalOutputLineLimit"
227227
| "terminalShellIntegrationTimeout"
228+
| "notebookOutputSizeLimit"
229+
| "notebookExecutionTimeoutSeconds"
230+
| "alwaysAllowReadNotebook"
231+
| "alwaysAllowEditNotebook"
232+
| "alwaysAllowExecuteNotebook"
228233
| "mcpEnabled"
229234
| "enableMcpServerCreation"
230235
| "alwaysApproveResubmit"

0 commit comments

Comments
 (0)