Skip to content

Commit 5409742

Browse files
committed
Data Engineer mode (base 3.12)
1 parent 0374436 commit 5409742

35 files changed

+2246
-6
lines changed

src/core/Cline.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ import { askFollowupQuestionTool } from "./tools/askFollowupQuestionTool"
7676
import { switchModeTool } from "./tools/switchModeTool"
7777
import { attemptCompletionTool } from "./tools/attemptCompletionTool"
7878
import { newTaskTool } from "./tools/newTaskTool"
79+
import { notebookReadTool } from "./tools/notebookReadTool"
80+
import { notebookEditTool } from "./tools/notebookEditTool"
81+
import { notebookExecuteTool } from "./tools/notebookExecuteTool"
82+
import { notebookSaveTool } from "./tools/notebookSaveTool"
7983

8084
export type ToolResponse = string | Array<Anthropic.TextBlockParam | Anthropic.ImageBlockParam>
8185
type UserContent = Array<Anthropic.Messages.ContentBlockParam>
@@ -1422,6 +1426,14 @@ export class Cline extends EventEmitter<ClineEvents> {
14221426
const modeName = getModeBySlug(mode, customModes)?.name ?? mode
14231427
return `[${block.name} in ${modeName} mode: '${message}']`
14241428
}
1429+
case "notebook_read":
1430+
return `[${block.name} action '${block.params.action}']`
1431+
case "notebook_edit":
1432+
return `[${block.name} action '${block.params.action}']`
1433+
case "notebook_execute":
1434+
return `[${block.name} action '${block.params.action}']`
1435+
case "notebook_save":
1436+
return `[${block.name}]`
14251437
}
14261438
}
14271439

@@ -1666,6 +1678,25 @@ export class Cline extends EventEmitter<ClineEvents> {
16661678
askFinishSubTaskApproval,
16671679
)
16681680
break
1681+
case "notebook_read":
1682+
await notebookReadTool(this, block, askApproval, handleError, pushToolResult, removeClosingTag)
1683+
break
1684+
case "notebook_edit":
1685+
await notebookEditTool(this, block, askApproval, handleError, pushToolResult, removeClosingTag)
1686+
break
1687+
case "notebook_execute":
1688+
await notebookExecuteTool(
1689+
this,
1690+
block,
1691+
askApproval,
1692+
handleError,
1693+
pushToolResult,
1694+
removeClosingTag,
1695+
)
1696+
break
1697+
case "notebook_save":
1698+
await notebookSaveTool(this, block, askApproval, handleError, pushToolResult, removeClosingTag)
1699+
break
16691700
}
16701701

16711702
break

src/core/assistant-message/index.ts

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

3135
// Converts array of tool call names into a union type ("execute_command" | "read_file" | ...)
@@ -61,6 +65,11 @@ export const toolParamNames = [
6165
"follow_up",
6266
"task",
6367
"size",
68+
"cells",
69+
"insert_at_index",
70+
"start_index",
71+
"end_index",
72+
"noexec",
6473
] as const
6574

6675
export type ToolParamName = (typeof toolParamNames)[number]
@@ -148,3 +157,28 @@ 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" | "cells" | "insert_at_index" | "start_index" | "end_index" | "noexec"
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+
}
180+
181+
export interface NotebookSaveToolUse extends ToolUse {
182+
name: "notebook_save"
183+
params: Partial<Record<ToolParamName, string>>
184+
}

src/core/prompts/tools/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ 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"
20+
import { getNotebookSaveToolDescription } from "./notebook-save"
1721
import { DiffStrategy } from "../../diff/DiffStrategy"
1822
import { McpHub } from "../../../services/mcp/McpHub"
1923
import { Mode, ModeConfig, getModeConfig, isToolAllowedForMode, getGroupName } from "../../../shared/modes"
@@ -38,6 +42,10 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
3842
new_task: (args) => getNewTaskDescription(args),
3943
insert_content: (args) => getInsertContentDescription(args),
4044
search_and_replace: (args) => getSearchAndReplaceDescription(args),
45+
notebook_read: (args) => getNotebookReadToolDescription(args),
46+
notebook_edit: (args) => getNotebookEditToolDescription(args),
47+
notebook_execute: (args) => getNotebookExecuteToolDescription(args),
48+
notebook_save: (args) => getNotebookSaveToolDescription(args),
4149
apply_diff: (args) =>
4250
args.diffStrategy ? args.diffStrategy.getToolDescription({ cwd: args.cwd, toolOptions: args.toolOptions }) : "",
4351
}
@@ -112,4 +120,8 @@ export {
112120
getSwitchModeDescription,
113121
getInsertContentDescription,
114122
getSearchAndReplaceDescription,
123+
getNotebookReadToolDescription,
124+
getNotebookEditToolDescription,
125+
getNotebookExecuteToolDescription,
126+
getNotebookSaveToolDescription,
115127
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { ToolArgs } from "./types"
2+
3+
export function getNotebookEditToolDescription(args: ToolArgs): string {
4+
return `## notebook_edit
5+
Description: Edit the active notebook. 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 true.
6+
Parameters:
7+
- action: (required) The action to perform. Valid values are:
8+
- "insert_cells": Insert new cells into the notebook (or append to the end if insert_at_index is omitted)
9+
- "modify_cell_content": Modify the content of existing cells in the notebook (note: this will clear any existing outputs)
10+
- "replace_cells": Replace a range of cells with new cells (note: this will clear any existing outputs)
11+
- "delete_cells": Delete a range of cells from the notebook
12+
- cells: (required for insert_cells, modify_cell_content, replace_cells) Contains cell definitions using markdown code blocks:
13+
- For insert_cells: A series of code blocks representing the cells to insert
14+
- For modify_cell_content: Code blocks with @cell#N tag before each block (where N is the 0-based index)
15+
- For replace_cells: Series of code blocks to replace the specified range of cells
16+
- insert_at_index: (optional, only for insert_cells action) The position to insert cells at (0-based, defaults to end of notebook)
17+
- start_index: (required for replace_cells and delete_cells) The starting index of the range (0-based, inclusive)
18+
- end_index: (required for replace_cells and delete_cells) The ending index of the range (0-based, exclusive)
19+
- noexec: (optional) Boolean value to prevent automatic execution of new/modified code cells.
20+
21+
The language of each cell is determined by the code block header (e.g., \`\`\`python).
22+
Cells with \`\`\`markdown header are treated as markdown cells, all others are code cells.
23+
24+
Usage:
25+
<notebook_edit>
26+
<action>action name here</action>
27+
<cells>
28+
(markdown code blocks for cell content here)
29+
</cells>
30+
<insert_at_index>index value here (if required)</insert_at_index>
31+
<start_index>start index (for replace/delete actions)</start_index>
32+
<end_index>end index (for replace/delete actions)</end_index>
33+
<noexec>true</noexec>
34+
</notebook_edit>
35+
36+
Example 1: Insert multiple cells at index 0
37+
<notebook_edit>
38+
<action>insert_cells</action>
39+
<insert_at_index>0</insert_at_index>
40+
<cells>
41+
\`\`\`markdown
42+
# Data Analysis
43+
This notebook contains the analysis of our dataset.
44+
\`\`\`
45+
46+
\`\`\`python
47+
import pandas as pd
48+
import numpy as np
49+
df = pd.read_csv('data.csv')
50+
df.head()
51+
\`\`\`
52+
</cells>
53+
</notebook_edit>
54+
55+
Example 2: Append a new markdown cell (no insert_at_index specified)
56+
<notebook_edit>
57+
<action>insert_cells</action>
58+
<cells>
59+
\`\`\`markdown
60+
# Data Analysis
61+
This notebook contains the analysis of our dataset with the following steps:
62+
1. Data loading and cleaning
63+
2. Exploratory data analysis
64+
3. Statistical testing
65+
4. Visualization
66+
\`\`\`
67+
</cells>
68+
</notebook_edit>
69+
70+
Example 3: Modify multiple existing cells without execution
71+
<notebook_edit>
72+
<action>modify_cell_content</action>
73+
<cells>
74+
@cell#2
75+
\`\`\`python
76+
import matplotlib.pyplot as plt
77+
plt.figure(figsize=(10, 6))
78+
plt.plot(df['x'], df['y'])
79+
plt.title('Data Visualization')
80+
plt.xlabel('X Axis')
81+
plt.ylabel('Y Axis')
82+
plt.show()
83+
\`\`\`
84+
85+
@cell#3
86+
\`\`\`markdown
87+
# Statistical Analysis
88+
Let's analyze the correlation between variables.
89+
\`\`\`
90+
</cells>
91+
<noexec>true</noexec>
92+
</notebook_edit>
93+
94+
Example 4: Replace a range of cells with new cells
95+
<notebook_edit>
96+
<action>replace_cells</action>
97+
<start_index>2</start_index>
98+
<end_index>4</end_index>
99+
<cells>
100+
\`\`\`python
101+
import matplotlib.pyplot as plt
102+
import seaborn as sns
103+
104+
plt.figure(figsize=(10, 6))
105+
sns.scatterplot(x='x', y='y', data=df)
106+
plt.title('Scatter Plot')
107+
plt.show()
108+
\`\`\`
109+
110+
\`\`\`markdown
111+
## Observations
112+
The scatter plot shows a positive correlation between x and y variables.
113+
\`\`\`
114+
</cells>
115+
</notebook_edit>
116+
117+
Example 5: Delete a range of cells
118+
<notebook_edit>
119+
<action>delete_cells</action>
120+
<start_index>2</start_index>
121+
<end_index>4</end_index>
122+
<cells>
123+
</cells>
124+
</notebook_edit>
125+
126+
Notes:
127+
- The user must have opened a notebook file in VSCode to have an active notebook in the workspace
128+
- If no active notebook is found, an error message will be returned
129+
- Cell indices are 0-based (the first cell is at index 0)
130+
- For modify_cell_content, each code block must have a @cell#N tag to identify which cell to modify`
131+
}
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 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 user must have opened a notebook file in VSCode to have an active notebook in the workspace
27+
- The execution is initiated immediately, but completion time depends on the cells' content
28+
- The tool will wait for execution to complete and return the results
29+
- Results include both the cell content and any outputs produced by execution
30+
- Execution will timeout if it takes too long, and a timeout message will be included in the response
31+
- Cell outputs are truncated if they exceed the configured size limit
32+
- To execute a single cell, set end_index to start_index + 1`
33+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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.
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 user must have opened a notebook file in VSCode to have an active notebook in the workspace
28+
- The "get_info" action provides a comprehensive overview including URI, kernel info, and statistics about cell types and languages
29+
- If no active notebook is found, "get_info" will return a message stating "No active notebook found"
30+
- The "get_cells" action provides a formatted analysis of all cells, including their content and outputs
31+
- If no active notebook is found, "get_cells" will return an error message
32+
- Cell content and outputs are truncated if they exceed the configured size limit
33+
- For code cells, both the source code and execution outputs are included`
34+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ToolArgs } from "./types"
2+
3+
export function getNotebookSaveToolDescription(args: ToolArgs): string {
4+
return `## notebook_save
5+
Description: Save the active notebook to disk.
6+
Parameters:
7+
None - this tool simply saves the active notebook.
8+
9+
Usage:
10+
<notebook_save>
11+
</notebook_save>
12+
13+
Example: Save the active notebook
14+
<notebook_save>
15+
</notebook_save>
16+
17+
Notes:
18+
- This tool requires notebook_edit permissions
19+
- The user must have opened a notebook file in VSCode to have an active notebook in the workspace
20+
- All unsaved changes in the notebook will be saved
21+
- This is useful after making changes to a notebook to ensure your work is preserved
22+
- If no active notebook is found, an error message will be returned`
23+
}

0 commit comments

Comments
 (0)