feat(backend): file-authoring skills — write-file / edit-file / run-file + notebook cell edit/delete/rerun (closes #85) - #175
Merged
Conversation
…/ edit-file / run-file + notebook cell edit/delete/rerun (closes #85) New skills (purely additive; no signature changes to execute-code or the existing notebook skills): - write-file(path, content, overwrite=true) — wraps volume.write_to_volume; emits file_created / file_updated; does NOT write into scripts/ (authoring is not an execution step). - edit-file(path, mode=replace|overwrite, old/new|content) — exact-anchor replace (must match exactly once) or whole-file overwrite; emits file_updated, never file_created. - run-file(path, heavy=false) — runpy.run_path(path, run_name='__main__') through services.sandbox.run_code under the existing preamble (src/ on sys.path, session cwd); auto-saves a one-line runpy audit entry to scripts/step_NN_run_<name>.py; heavy picks the training sandbox profile with the owner max_timeout cap (same as execute-code post-#160). - edit-notebook-cell / delete-notebook-cell — wrap new notebook_store.edit_cell / delete_cell helpers (outputs preserved on edit, same as apply_source_update; both persist under the existing _lock + save path); broadcast notebook.structure.changed for live UI. - rerun-notebook-cell — looks a cell up by cell_id, re-executes its current source against the persistent kernel via kernel_manager.execute_and_wait (kernel cell_started clears outputs; earlier-cell variables stay in scope); same result envelope as run-notebook-cell. Shared resolve_session_path() helper in services/skills/state.py (session-relative, volume-absolute, and /data/-prefixed paths; rejects escapes). All six skills registered in chat, eda, data_prep, feature_eng, trainer, orchestrator YAMLs, whose 'Workspace is a real Python repo' blocks are replaced by the prescriptive 'Authoring vs running' block (rule of three; edit don't repaste; import from src/ works in kernel cells) keeping the per-agent example bullets. execute-code SKILL.md now documents its one-shot contract. Frontend: file_updated added to the typed SSE union + handled in useSessionStream (tree update, no auto-open). Tests: 48 new (skill handlers happy/failure paths incl. invalid path, non-matching/ambiguous anchor, missing file, cell_id not found, markdown rerun, kernel timeout; notebook_store edit_cell output preservation + delete_cell volume persistence; path resolution). Full backend suite: 647 passed, 8 skipped. ruff 0.15.22 check + format clean. Frontend: vitest 20/20, tsc, next lint, prettier clean.
Owner
Author
|
Merged into integration branch staging-v0.0.5 — closing. |
Comment on lines
+38
to
+39
| try: | ||
| path, _ = resolve_session_path(session_id, raw_path) |
There was a problem hiding this comment.
When write-file or edit-file targets a path under scripts/, path resolution accepts it and the handler overwrites the file, allowing authored content to alter the audit record of what actually ran.
Context Used: backend/skills/AGENTS.md (source)
Comment on lines
+208
to
+213
| output = result["stdout"] | ||
| if result["returncode"] != 0: | ||
| output = ( | ||
| f"Exit code {result['returncode']}.\n" | ||
| f"STDOUT:\n{result['stdout']}\nSTDERR:\n{result['stderr']}" | ||
| ) |
| cell.pop("execution_count", None) | ||
| _cache[key] = nb | ||
|
|
||
| await save(session_id, name) |
There was a problem hiding this comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #85
What
Splits file authoring from code execution per the issue spec — purely additive, no signature changes to
execute-codeor the existing notebook skills.New file skills (
backend/skills/):write-file(path, content, overwrite=true)— wrapsservices.volume.write_to_volume; emitsfile_created(new) /file_updated(overwrite); does not write intoscripts/— authoring is not an execution step.edit-file(path, mode, ...)—mode=replace: exact-anchor substitution (oldmust match exactly once, else informative error);mode=overwrite: whole-file escape hatch. Emitsfile_updated, neverfile_created.run-file(path, heavy=false)— executes an existing workspace file viarunpy.run_path(path, run_name='__main__')throughservices.sandbox.run_code(same preamble as execute-code:src/on sys.path, session cwd). Auto-saves a one-line runpy call toscripts/step_NN_run_<name>.py— the audit log records what ran, the body stays on disk.heavypicks the training sandbox profile with the ownermax_timeoutcap (integrated with feat(agent): agent-selectable GPU/CPU per execute-code call with project allowance #160's compute allowance).New notebook skills:
edit-notebook-cell/delete-notebook-cell— wrap newnotebook_store.edit_cell/delete_cellhelpers (built on the existing_lock(key)+save(...)pattern next toappend_cell; edit preserves outputs exactly likeapply_source_update). Both broadcastnotebook.structure.changedso the UI updates live.rerun-notebook-cell— looks a cell up bycell_id, re-executes its current source against the persistent kernel viakernel_manager.execute_and_wait(kernelcell_startedclears outputs; earlier-cell variables stay in scope). Same result envelope asrun-notebook-cell.Shared plumbing:
resolve_session_path()inservices/skills/state.py— accepts session-relative,/sessions/{sid}/-absolute, and/data/sessions/{sid}/-prefixed paths; rejects escapes.Agent YAMLs (all 6: chat, eda, data_prep, feature_eng, trainer, orchestrator): six new skills listed alongside
execute-code; the descriptive "Workspace is a real Python repo" block replaced by the prescriptive "Authoring vs running — use the right verb" block from the spec §4 (rule of three; edit don't repaste;importfromsrc/works inside a kernel cell), per-agent example bullets kept; eda gains the §5 third-cell-paste guidance.execute-codeSKILL.md now states the one-shot contract (handler/schema/auto-save unchanged).Frontend (minimal):
file_updatedadded to the typed SSE discriminated union (FileUpdatedData, same wire shape asFileCreatedData) + handled inuseSessionStream(tree update in place, no canvas auto-open, added to NON_VISIBLE_EVENTS). The flash-on-update and src/-pinned-open explorer polish from spec §7 is deferred — the event handling is the load-bearing part.Tests
test_write_file.py,test_edit_file.py,test_run_file.py,test_notebook_store.py,test_edit_notebook_cell.py,test_delete_notebook_cell.py,test_rerun_notebook_cell.py— happy + failure paths (invalid path, overwrite=false clobber, anchor not found / ambiguous anchor, missing file,cell_idnot found, markdown-cell rerun, kernel timeout, edit_cell output preservation, delete_cell volume persistence, path resolution).ruff check+ruff format --check(0.15.22): clean (220 files).tsc --noEmitclean,next lintclean, prettier clean.Out of scope (per spec)
delete-file, cross-session src/ promotion, fuzzy patching / unified diffs, cell reordering, multi-cell rerun.
Greptile Summary
Adds file-authoring and file-execution skills plus in-place notebook cell management.
Confidence Score: 2/5
The PR should not merge until authoring is prevented from corrupting audit scripts, failed file runs are reported as failures, and notebook mutations are persisted in a consistently ordered critical section.
The new authoring surface can modify records intended to describe executed code, run-file masks ordinary nonzero exits at the tool-protocol level, and overlapping notebook saves can persist an older snapshot after a newer edit or deletion.
Files Needing Attention: backend/skills/write-file/handler.py, backend/skills/edit-file/handler.py, backend/skills/run-file/handler.py, backend/services/notebook_store.py
Important Files Changed
Sequence Diagram
sequenceDiagram participant A as Agent participant S as Skill handler participant V as Session volume participant X as Sandbox/Kernel participant U as UI via SSE A->>S: write/edit/run file or notebook cell S->>V: Resolve and persist workspace state alt run-file S->>V: Write scripts/ audit entry S->>X: Execute runpy wrapper X-->>S: stdout, stderr, returncode else rerun notebook cell S->>X: Execute current cell source X->>V: Stream and persist outputs end S-->>U: file/notebook update event S-->>A: Tool resultReviews (1): Last reviewed commit: "feat(backend): split file authoring from..." | Re-trigger Greptile
Context used: