lcode-cli 0.2.2__tar.gz → 0.3.0__tar.gz
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.
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/CHANGELOG.md +14 -1
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/PKG-INFO +4 -2
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/README.md +3 -1
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/SECURITY.md +2 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/configuration.md +2 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/how-it-works.md +1 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/index.md +1 -1
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/quickstart.md +1 -1
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/usage.md +35 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/__init__.py +1 -1
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/agent.py +17 -0
- lcode_cli-0.3.0/src/lcode/checkpoints.py +449 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/cli.py +1 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/config.py +1 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/repl.py +163 -1
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/tools.py +3 -0
- lcode_cli-0.3.0/tests/test_checkpoints.py +226 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.editorconfig +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/CODEOWNERS +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/ISSUE_TEMPLATE/model_request.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/dependabot.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/workflows/ci.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/workflows/docs.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.github/workflows/release.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.gitignore +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/.pre-commit-config.yaml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/AGENTS.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/CODE_OF_CONDUCT.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/CONTRIBUTING.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/LICENSE +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/assets/demo.svg +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/assets/extra.css +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/assets/logo.svg +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/assets/social-preview.png +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/changelog.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/contributing.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/installation.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/models.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/docs/troubleshooting.md +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/install.sh +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/mkdocs.yml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/overrides/main.html +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/pyproject.toml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/scripts/record_demo.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/scripts/social-preview.html +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/__main__.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/catalog.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/hardware.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/limits.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/models.toml +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/ollama.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/permissions.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/render.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/sessions.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/src/lcode/web.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/conftest.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_agent.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_catalog.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_cli.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_config.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_context_picker.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_permissions.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_sessions.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_tools.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/tests/test_web.py +0 -0
- {lcode_cli-0.2.2 → lcode_cli-0.3.0}/uv.lock +0 -0
|
@@ -6,6 +6,18 @@ All notable changes to lcode are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.3.0] - 2026-09-30
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `/undo` takes back the file changes of the last request: lcode saves a checkpoint before the model
|
|
14
|
+
first changes files in a request, and restores edited and deleted files and removes new ones,
|
|
15
|
+
including changes made by shell commands. `/undo` again goes further back, `/rewind N` goes back
|
|
16
|
+
to before request N (optionally removing those requests from the conversation too), and
|
|
17
|
+
`/checkpoints` lists them. Checkpoints live in a separate git repository in lcode's state folder,
|
|
18
|
+
so your own repository is never touched, and work in folders that aren't git repositories.
|
|
19
|
+
Turn them off with `lcode config set checkpoints false`.
|
|
20
|
+
|
|
9
21
|
## [0.2.2] - 2026-09-30
|
|
10
22
|
|
|
11
23
|
### Added
|
|
@@ -116,7 +128,8 @@ First public release.
|
|
|
116
128
|
- `AGENTS.md` project instructions and `/init` to generate them.
|
|
117
129
|
- One-line installer for Linux and macOS.
|
|
118
130
|
|
|
119
|
-
[Unreleased]: https://github.com/nasser1941/lcode/compare/v0.
|
|
131
|
+
[Unreleased]: https://github.com/nasser1941/lcode/compare/v0.3.0...HEAD
|
|
132
|
+
[0.3.0]: https://github.com/nasser1941/lcode/compare/v0.2.2...v0.3.0
|
|
120
133
|
[0.2.2]: https://github.com/nasser1941/lcode/compare/v0.2.1...v0.2.2
|
|
121
134
|
[0.2.1]: https://github.com/nasser1941/lcode/compare/v0.2.0...v0.2.1
|
|
122
135
|
[0.2.0]: https://github.com/nasser1941/lcode/compare/v0.1.2...v0.2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: lcode-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: A local-first terminal coding agent powered by open-weight models on your own GPU or Mac, via Ollama.
|
|
5
5
|
Project-URL: Homepage, https://nasser1941.github.io/lcode/
|
|
6
6
|
Project-URL: Documentation, https://nasser1941.github.io/lcode/
|
|
@@ -76,6 +76,8 @@ through [Ollama](https://ollama.com), and when it needs current information it c
|
|
|
76
76
|
largest context that fits: `lcode setup` does it in one step.
|
|
77
77
|
- **Safe by default.** Every edit is shown as a diff and every command that isn't read-only needs
|
|
78
78
|
your approval. `auto-edit` and `yolo` modes when you want speed.
|
|
79
|
+
- **Undo.** lcode saves a checkpoint before the model changes files; `/undo` takes back the last
|
|
80
|
+
request's edits, new files and shell-command changes, without touching your git history.
|
|
79
81
|
- **Bring your own model.** Eight curated open-weight models, all tested end to end, or any Ollama model
|
|
80
82
|
with tool calling.
|
|
81
83
|
- **Web search when needed.** Looks up the latest versions, docs and error messages with Ollama web
|
|
@@ -123,6 +125,7 @@ lcode
|
|
|
123
125
|
| `lcode -c` / `lcode --resume` | continue the last session here / pick a saved session from a list |
|
|
124
126
|
| `lcode --model qwen3.5-9b --context 128k` | pick a model and context window for this session |
|
|
125
127
|
| `lcode models` / `lcode doctor` | what fits this machine / check the installation |
|
|
128
|
+
| `/undo`, `/rewind` | take back the last request's file changes, or go back further |
|
|
126
129
|
| `/rename`, `/resume` | name the current session, resume a saved one |
|
|
127
130
|
| `/model`, `/context`, `/compact`, `/help` | switch model, resize the context window (pick from a list), summarize, list commands |
|
|
128
131
|
|
|
@@ -167,7 +170,6 @@ fills up. Details: [How it works](https://nasser1941.github.io/lcode/how-it-work
|
|
|
167
170
|
|
|
168
171
|
See the pinned [Roadmap issue](https://github.com/nasser1941/lcode/issues/10). Next up:
|
|
169
172
|
|
|
170
|
-
- [`/undo` and automatic checkpoints](https://github.com/nasser1941/lcode/issues/4)
|
|
171
173
|
- [`lcode bench`: score models on your own hardware](https://github.com/nasser1941/lcode/issues/5)
|
|
172
174
|
- [MCP tool servers](https://github.com/nasser1941/lcode/issues/6)
|
|
173
175
|
- [Homebrew formula](https://github.com/nasser1941/lcode/issues/8) and an [optional sandbox for shell commands](https://github.com/nasser1941/lcode/issues/9)
|
|
@@ -43,6 +43,8 @@ through [Ollama](https://ollama.com), and when it needs current information it c
|
|
|
43
43
|
largest context that fits: `lcode setup` does it in one step.
|
|
44
44
|
- **Safe by default.** Every edit is shown as a diff and every command that isn't read-only needs
|
|
45
45
|
your approval. `auto-edit` and `yolo` modes when you want speed.
|
|
46
|
+
- **Undo.** lcode saves a checkpoint before the model changes files; `/undo` takes back the last
|
|
47
|
+
request's edits, new files and shell-command changes, without touching your git history.
|
|
46
48
|
- **Bring your own model.** Eight curated open-weight models, all tested end to end, or any Ollama model
|
|
47
49
|
with tool calling.
|
|
48
50
|
- **Web search when needed.** Looks up the latest versions, docs and error messages with Ollama web
|
|
@@ -90,6 +92,7 @@ lcode
|
|
|
90
92
|
| `lcode -c` / `lcode --resume` | continue the last session here / pick a saved session from a list |
|
|
91
93
|
| `lcode --model qwen3.5-9b --context 128k` | pick a model and context window for this session |
|
|
92
94
|
| `lcode models` / `lcode doctor` | what fits this machine / check the installation |
|
|
95
|
+
| `/undo`, `/rewind` | take back the last request's file changes, or go back further |
|
|
93
96
|
| `/rename`, `/resume` | name the current session, resume a saved one |
|
|
94
97
|
| `/model`, `/context`, `/compact`, `/help` | switch model, resize the context window (pick from a list), summarize, list commands |
|
|
95
98
|
|
|
@@ -134,7 +137,6 @@ fills up. Details: [How it works](https://nasser1941.github.io/lcode/how-it-work
|
|
|
134
137
|
|
|
135
138
|
See the pinned [Roadmap issue](https://github.com/nasser1941/lcode/issues/10). Next up:
|
|
136
139
|
|
|
137
|
-
- [`/undo` and automatic checkpoints](https://github.com/nasser1941/lcode/issues/4)
|
|
138
140
|
- [`lcode bench`: score models on your own hardware](https://github.com/nasser1941/lcode/issues/5)
|
|
139
141
|
- [MCP tool servers](https://github.com/nasser1941/lcode/issues/6)
|
|
140
142
|
- [Homebrew formula](https://github.com/nasser1941/lcode/issues/8) and an [optional sandbox for shell commands](https://github.com/nasser1941/lcode/issues/9)
|
|
@@ -37,6 +37,8 @@ user, in your working directory**. It is not a sandbox. Keep in mind:
|
|
|
37
37
|
snippets from your code. Use `web = ask` to approve each search, or `web = off` / `--no-web` to
|
|
38
38
|
keep everything local.
|
|
39
39
|
- Sessions (including file contents the model read) are stored in `~/.local/state/lcode/sessions`.
|
|
40
|
+
Checkpoints for `/undo` keep copies of your project's files (except ignored ones) in
|
|
41
|
+
`~/.local/state/lcode/checkpoints` for 14 days; turn them off with `checkpoints = false`.
|
|
40
42
|
|
|
41
43
|
Reports about bypassing the permission prompts, the read-only allowlist, or data leaving the
|
|
42
44
|
machine unexpectedly are especially welcome.
|
|
@@ -25,6 +25,7 @@ lcode config path # print the file location
|
|
|
25
25
|
| `web` | `on` | Web search and page fetching: `on`, `ask` (before each search/website) or `off` |
|
|
26
26
|
| `search_backend` | `auto` | `auto`, `ollama`, `brave`, `tavily` or `searxng`; `auto` uses the first one configured |
|
|
27
27
|
| `searxng_url` | | Your SearXNG instance, e.g. `http://localhost:8888` |
|
|
28
|
+
| `checkpoints` | `true` | Save a checkpoint before the model changes files, so [`/undo`](usage.md#undo-and-checkpoints) can restore them |
|
|
28
29
|
|
|
29
30
|
Example file:
|
|
30
31
|
|
|
@@ -58,6 +59,7 @@ Environment variables override the file, which is useful for one-off runs and CI
|
|
|
58
59
|
| `~/.config/lcode/config.toml` | Settings |
|
|
59
60
|
| `~/.local/state/lcode/sessions/` | Saved conversations (for `lcode -c`) |
|
|
60
61
|
| `~/.local/state/lcode/history` | Prompt history (++up++ in the prompt) |
|
|
62
|
+
| `~/.local/state/lcode/checkpoints/` | Checkpoints for `/undo` (copies of your project's files; deleted after 14 days) |
|
|
61
63
|
| `~/.local/state/lcode/limits.json` | Context sizes that ran out of GPU memory on this machine (safe to delete) |
|
|
62
64
|
|
|
63
65
|
Sessions contain everything the model read, including file contents. Delete the folder to clear them.
|
|
@@ -75,6 +75,7 @@ the Ollama server you configure, it only contacts the web when the model searche
|
|
|
75
75
|
| `agent.py` | System prompt, streaming, tool loop, compaction, sessions |
|
|
76
76
|
| `tools.py` | Tool schemas and implementations |
|
|
77
77
|
| `permissions.py` | Approval prompts and the read-only allowlist |
|
|
78
|
+
| `checkpoints.py` | Snapshots before the model changes files, for `/undo` and `/rewind` |
|
|
78
79
|
| `catalog.py`, `models.toml` | Model catalog and memory estimates |
|
|
79
80
|
| `hardware.py` | NVIDIA / Apple Silicon detection |
|
|
80
81
|
| `ollama.py` | Ollama HTTP client |
|
|
@@ -67,7 +67,7 @@ until the task is done, asking before it changes anything.
|
|
|
67
67
|
---
|
|
68
68
|
|
|
69
69
|
Every edit is shown as a diff and every non-read-only command needs your approval, unless you
|
|
70
|
-
choose otherwise.
|
|
70
|
+
choose otherwise. `/undo` takes back a request's file changes.
|
|
71
71
|
|
|
72
72
|
- :material-swap-horizontal:{ .lg .middle } **Bring your own model**
|
|
73
73
|
|
|
@@ -49,6 +49,9 @@ reasoning is on.
|
|
|
49
49
|
| `/clear` | Start a new conversation (the current one stays saved) |
|
|
50
50
|
| `/rename NAME` | Name the current session so it's easy to find later |
|
|
51
51
|
| `/resume [SESSION]` | Resume a saved session: pick from a list, or give its number or name; `/resume all` lists every folder |
|
|
52
|
+
| `/undo` | Undo the file changes of the last request ([details](#undo-and-checkpoints)) |
|
|
53
|
+
| `/rewind [N]` | Go back to before request N: its files, and optionally the conversation |
|
|
54
|
+
| `/checkpoints` | List the requests that changed files, and which files |
|
|
52
55
|
| `/compact [focus]` | Summarize the conversation to free context |
|
|
53
56
|
| `/context [size]` | Show how full the context window is and change its size: pick from a list with memory estimates, or give a size like `/context 128k` (`/ctx` is a shortcut) |
|
|
54
57
|
| `/model [name]`, `/models` | Switch model, list models |
|
|
@@ -97,6 +100,38 @@ or ++n++. Text after ++n++ goes to the model as instructions: `n run the tests w
|
|
|
97
100
|
In `yolo` mode the model can run any command as your user. Use it in a container, a VM or a
|
|
98
101
|
throwaway clone, not on a machine with data you care about.
|
|
99
102
|
|
|
103
|
+
## Undo and checkpoints
|
|
104
|
+
|
|
105
|
+
Before the model first changes anything in a request (an edit, a new file, or a shell command that
|
|
106
|
+
isn't read-only), lcode saves a checkpoint of your project. If the result isn't what you wanted,
|
|
107
|
+
`/undo` puts the files back:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
❯ /undo
|
|
111
|
+
Undoing request 3: switch the parser to the new tokenizer
|
|
112
|
+
restore src/parser.py
|
|
113
|
+
restore tests/test_parser.py
|
|
114
|
+
remove src/tokenizer_v2.py
|
|
115
|
+
Done: restored src/parser.py, tests/test_parser.py; removed src/tokenizer_v2.py.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- `/undo` again goes one more request back. The model is told which files were restored, so it
|
|
119
|
+
reads them again instead of assuming its changes are still there.
|
|
120
|
+
- `/checkpoints` lists the requests that changed files. `/rewind 2` goes back to before request 2
|
|
121
|
+
in one step (undoing every request after it too) and offers to remove those requests from the
|
|
122
|
+
conversation as well.
|
|
123
|
+
- Changes made by shell commands are covered too (`sed -i`, generated files, `rm`), in any folder,
|
|
124
|
+
whether or not it's a git repository.
|
|
125
|
+
- If you edited one of those files yourself after the model did, lcode lists it and asks before
|
|
126
|
+
going back, since that would lose your edit. Files the model didn't touch are never changed.
|
|
127
|
+
|
|
128
|
+
Checkpoints are stored in a separate git repository under `~/.local/state/lcode/checkpoints/`. Your
|
|
129
|
+
own repository (its index, branches, stash and history) is never touched. Ignored files (per
|
|
130
|
+
`.gitignore`), `node_modules`, virtual environments and files over 10 MB aren't included. Folders
|
|
131
|
+
with more than 20,000 files, or your home folder itself, aren't checkpointed; lcode says so once and
|
|
132
|
+
carries on. Checkpoints are deleted after 14 days. To turn them off:
|
|
133
|
+
`lcode config set checkpoints false`.
|
|
134
|
+
|
|
100
135
|
## Web search
|
|
101
136
|
|
|
102
137
|
When the answer depends on information newer than the model's training data, such as the latest
|
|
@@ -19,6 +19,7 @@ from rich.panel import Panel
|
|
|
19
19
|
from rich.text import Text
|
|
20
20
|
|
|
21
21
|
from lcode import catalog, limits, sessions, web
|
|
22
|
+
from lcode.checkpoints import Checkpoints
|
|
22
23
|
from lcode.config import format_tokens
|
|
23
24
|
from lcode.ollama import Ollama, OllamaError
|
|
24
25
|
from lcode.permissions import Permissions
|
|
@@ -136,6 +137,7 @@ class Settings:
|
|
|
136
137
|
web: str = "on" # on | ask | off
|
|
137
138
|
search_backend: str = "auto"
|
|
138
139
|
searxng_url: str | None = None
|
|
140
|
+
checkpoints: bool = True # snapshot files before the model changes them, for /undo
|
|
139
141
|
|
|
140
142
|
|
|
141
143
|
class Agent:
|
|
@@ -147,6 +149,7 @@ class Agent:
|
|
|
147
149
|
self.perms = Permissions(self.console, settings.permission_mode)
|
|
148
150
|
self.tools = Toolbox(self)
|
|
149
151
|
self.session_id = self.new_session_id()
|
|
152
|
+
self.checkpoints = Checkpoints(self.console, settings.checkpoints)
|
|
150
153
|
self.session_name = ""
|
|
151
154
|
self.session_title = ""
|
|
152
155
|
self.ctx_used = 0
|
|
@@ -220,6 +223,7 @@ class Agent:
|
|
|
220
223
|
"name": self.session_name,
|
|
221
224
|
"title": self.session_title,
|
|
222
225
|
"messages": self.messages,
|
|
226
|
+
"checkpoints": self.checkpoints.to_json(),
|
|
223
227
|
}
|
|
224
228
|
f.write_text(json.dumps(data))
|
|
225
229
|
|
|
@@ -228,6 +232,7 @@ class Agent:
|
|
|
228
232
|
self.session_id = self.new_session_id()
|
|
229
233
|
self.session_name = ""
|
|
230
234
|
self.session_title = ""
|
|
235
|
+
self.checkpoints.reset(self.session_id)
|
|
231
236
|
|
|
232
237
|
def rename(self, name: str) -> None:
|
|
233
238
|
self.session_name = " ".join(name.split())
|
|
@@ -249,6 +254,7 @@ class Agent:
|
|
|
249
254
|
note = f"The session's directory {saved_cwd} no longer exists; staying in {self.cwd}"
|
|
250
255
|
self.messages = [{"role": "system", "content": self.system_prompt()}, *data.get("messages", [])[1:]]
|
|
251
256
|
self.session_id = info.id
|
|
257
|
+
self.checkpoints.load(info.id, data.get("checkpoints") or [])
|
|
252
258
|
self.session_name = data.get("name", "")
|
|
253
259
|
self.session_title = data.get("title") or sessions.title_from(self.messages)
|
|
254
260
|
self.tools.read_mtimes.clear() # files may have changed since; the model must read them again
|
|
@@ -406,6 +412,17 @@ class Agent:
|
|
|
406
412
|
return name
|
|
407
413
|
|
|
408
414
|
def run_turn(self, user_text: str) -> None:
|
|
415
|
+
self.checkpoints.begin_turn(self.session_id, user_text, len(self.messages))
|
|
416
|
+
try:
|
|
417
|
+
self._run_turn(user_text)
|
|
418
|
+
finally:
|
|
419
|
+
self.checkpoints.end_turn()
|
|
420
|
+
|
|
421
|
+
def checkpoint(self) -> None:
|
|
422
|
+
"""Called before the model changes files: snapshot them once per request, for /undo."""
|
|
423
|
+
self.checkpoints.before_change(self.cwd)
|
|
424
|
+
|
|
425
|
+
def _run_turn(self, user_text: str) -> None:
|
|
409
426
|
self.messages.append({"role": "user", "content": self.expand_mentions(user_text)})
|
|
410
427
|
malformed = 0
|
|
411
428
|
for _ in range(MAX_STEPS_PER_TURN):
|