Skip to content

Commit a037962

Browse files
committed
add delay for run tool, add steps for agent mode prompt
1 parent 440ac12 commit a037962

File tree

5 files changed

+47
-11
lines changed

5 files changed

+47
-11
lines changed

frontend/src/core/ai/tools/__tests__/run-cells-tool.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe("RunStaleCellsTool", () => {
4444
store,
4545
};
4646

47-
tool = new RunStaleCellsTool();
47+
tool = new RunStaleCellsTool({ postExecutionDelay: 0 });
4848

4949
cellId1 = "cell-1" as CellId;
5050
cellId2 = "cell-2" as CellId;

frontend/src/core/ai/tools/edit-notebook-tool.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,11 @@ export class EditNotebookTool
190190
}
191191
return {
192192
status: "success",
193-
next_steps: ["If you need to perform more edits, call this tool again."],
193+
next_steps: [
194+
"If you need to perform more edits, call this tool again.",
195+
"You should use the lint notebook tool to check for errors and lint issues. Fix them by editing the notebook.",
196+
"You should use the run stale cells tool to run the cells that have been edited or newly added. This allows you to see the output of the cells and fix any errors.",
197+
],
194198
};
195199
};
196200

frontend/src/core/ai/tools/run-cells-tool.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import {
2121
} from "./base";
2222
import type { CopilotMode } from "./registry";
2323

24+
const POST_EXECUTION_DELAY = 200;
25+
const WAIT_FOR_CELLS_TIMEOUT = 30_000;
26+
2427
interface CellOutput {
2528
consoleOutput?: string;
2629
cellOutput?: string;
@@ -65,6 +68,12 @@ export class RunStaleCellsTool
6568
}) satisfies z.ZodType<RunStaleCellsOutput>;
6669
readonly mode: CopilotMode[] = ["agent"];
6770

71+
private readonly postExecutionDelay: number;
72+
73+
constructor(opts?: { postExecutionDelay?: number }) {
74+
this.postExecutionDelay = opts?.postExecutionDelay ?? POST_EXECUTION_DELAY;
75+
}
76+
6877
handler = async (
6978
_args: EmptyToolInput,
7079
toolContext: ToolNotebookContext,
@@ -89,7 +98,12 @@ export class RunStaleCellsTool
8998
});
9099

91100
// Wait for all cells to finish executing
92-
const allCellsFinished = await this.waitForCellsToFinish(store, staleCells);
101+
const allCellsFinished = await this.waitForCellsToFinish(
102+
store,
103+
staleCells,
104+
WAIT_FOR_CELLS_TIMEOUT,
105+
this.postExecutionDelay,
106+
);
93107
if (!allCellsFinished) {
94108
return {
95109
status: "success",
@@ -115,7 +129,9 @@ export class RunStaleCellsTool
115129

116130
const cellOutput = cellContextData.cellOutput;
117131
const consoleOutputs = cellContextData.consoleOutputs;
118-
if (!cellOutput && !consoleOutputs) {
132+
const hasConsoleOutput = consoleOutputs && consoleOutputs.length > 0;
133+
134+
if (!cellOutput && !hasConsoleOutput) {
119135
// Set null to show no output
120136
cellsToOutput.set(cellId, null);
121137
continue;
@@ -128,7 +144,7 @@ export class RunStaleCellsTool
128144
}
129145
}
130146

131-
if (consoleOutputs) {
147+
if (hasConsoleOutput) {
132148
consoleOutputString = consoleOutputs
133149
.map((output) => this.formatOutputString(output))
134150
.join("\n");
@@ -207,7 +223,8 @@ export class RunStaleCellsTool
207223
private async waitForCellsToFinish(
208224
store: JotaiStore,
209225
cellIds: CellId[],
210-
timeout = 30_000,
226+
timeout: number,
227+
postExecutionDelay: number,
211228
): Promise<boolean> {
212229
const checkAllFinished = (
213230
notebook: ReturnType<typeof notebookAtom.read>,
@@ -220,9 +237,18 @@ export class RunStaleCellsTool
220237
});
221238
};
222239

223-
// If already finished, return immediately
224-
if (checkAllFinished(store.get(notebookAtom))) {
240+
// Add a small delay after cells finish to allow console outputs to arrive
241+
// Console outputs are streamed and might still be in-flight
242+
const delayForConsoleOutputs = async () => {
243+
if (postExecutionDelay > 0) {
244+
await new Promise((resolve) => setTimeout(resolve, postExecutionDelay));
245+
}
225246
return true;
247+
};
248+
249+
// Return immediately if all cells are finished
250+
if (checkAllFinished(store.get(notebookAtom))) {
251+
return await delayForConsoleOutputs();
226252
}
227253

228254
// Wait for notebook state changes with timeout
@@ -233,7 +259,7 @@ export class RunStaleCellsTool
233259
setTimeout(() => reject(new Error("timeout")), timeout),
234260
),
235261
]);
236-
return true;
262+
return await delayForConsoleOutputs();
237263
} catch {
238264
return false;
239265
}

marimo/_server/ai/prompts.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,10 @@ def _get_mode_intro_message(mode: CopilotMode) -> str:
250250
"You are in agent mode - you have autonomy to resolve the user's query by using the tools provided. Please keep going until the user's query is completely resolved, before ending your turn and yielding back to the user. Only terminate your turn when you are sure that the problem is solved. \n"
251251
"\n\n## Agent Mode\n"
252252
"- You are encouraged to edit existing cells in the notebook or add new cells.\n"
253-
"- Once you have edited the notebook, you can use the run cells tool to run the code. Then, run the lint notebook tool to check for errors and lint issues. If there are errors in cells you have added, edit the existing cell. Don't add new cells to correct errors.\n"
253+
"- You should do the following things after editing the notebook:\n"
254+
"\t 1. Use the lint notebook tool to check for errors and lint issues\n"
255+
"\t 2. Run stale cells tool to run the code\n"
256+
"\t 3. If there are errors in cells you have added, edit the existing cell. Don't add new cells to correct errors.\n"
254257
"- If you say you're about to do something, actually do it in the same turn (run the tool call right after).\n"
255258
"- Group code into logical cells, eg. functions should be in separate cells and all the calls will be in one cell. When asked for explanations or summaries, use markdown cells with proper formatting.\n\n"
256259
"## Capabilities\n"

tests/_server/ai/snapshots/chat_system_prompts.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,10 @@ You are in agent mode - you have autonomy to resolve the user's query by using t
899899

900900
## Agent Mode
901901
- You are encouraged to edit existing cells in the notebook or add new cells.
902-
- Once you have edited the notebook, you can use the run cells tool to run the code. Then, run the lint notebook tool to check for errors and lint issues. If there are errors in cells you have added, edit the existing cell. Don't add new cells to correct errors.
902+
- You should do the following things after editing the notebook:
903+
1. Use the lint notebook tool to check for errors and lint issues
904+
2. Run stale cells tool to run the code
905+
3. If there are errors in cells you have added, edit the existing cell. Don't add new cells to correct errors.
903906
- If you say you're about to do something, actually do it in the same turn (run the tool call right after).
904907
- Group code into logical cells, eg. functions should be in separate cells and all the calls will be in one cell. When asked for explanations or summaries, use markdown cells with proper formatting.
905908

0 commit comments

Comments
 (0)