agsekit 0.9.4__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.
- agsekit-0.9.4/LICENSE +21 -0
- agsekit-0.9.4/MANIFEST.in +4 -0
- agsekit-0.9.4/PKG-INFO +264 -0
- agsekit-0.9.4/README.md +229 -0
- agsekit-0.9.4/agsekit.egg-info/PKG-INFO +264 -0
- agsekit-0.9.4/agsekit.egg-info/SOURCES.txt +63 -0
- agsekit-0.9.4/agsekit.egg-info/dependency_links.txt +1 -0
- agsekit-0.9.4/agsekit.egg-info/entry_points.txt +2 -0
- agsekit-0.9.4/agsekit.egg-info/requires.txt +3 -0
- agsekit-0.9.4/agsekit.egg-info/top_level.txt +1 -0
- agsekit-0.9.4/agsekit_cli/__init__.py +7 -0
- agsekit-0.9.4/agsekit_cli/agent_scripts/claude-code.sh +12 -0
- agsekit-0.9.4/agsekit_cli/agent_scripts/codex-glibc.sh +212 -0
- agsekit-0.9.4/agsekit_cli/agent_scripts/codex.sh +83 -0
- agsekit-0.9.4/agsekit_cli/agent_scripts/proxychains_common.sh +105 -0
- agsekit-0.9.4/agsekit_cli/agent_scripts/qwen.sh +83 -0
- agsekit-0.9.4/agsekit_cli/agents.py +271 -0
- agsekit-0.9.4/agsekit_cli/backup.py +294 -0
- agsekit-0.9.4/agsekit_cli/cli.py +166 -0
- agsekit-0.9.4/agsekit_cli/commands/__init__.py +15 -0
- agsekit-0.9.4/agsekit_cli/commands/backup_once.py +31 -0
- agsekit-0.9.4/agsekit_cli/commands/backup_repeated.py +148 -0
- agsekit-0.9.4/agsekit_cli/commands/config_example.py +42 -0
- agsekit-0.9.4/agsekit_cli/commands/config_gen.py +210 -0
- agsekit-0.9.4/agsekit_cli/commands/create_vm.py +83 -0
- agsekit-0.9.4/agsekit_cli/commands/destroy_vm.py +112 -0
- agsekit-0.9.4/agsekit_cli/commands/install_agents.py +208 -0
- agsekit-0.9.4/agsekit_cli/commands/mounts.py +122 -0
- agsekit-0.9.4/agsekit_cli/commands/portforward.py +141 -0
- agsekit-0.9.4/agsekit_cli/commands/prepare.py +260 -0
- agsekit-0.9.4/agsekit_cli/commands/run.py +171 -0
- agsekit-0.9.4/agsekit_cli/commands/shell.py +72 -0
- agsekit-0.9.4/agsekit_cli/commands/ssh.py +119 -0
- agsekit-0.9.4/agsekit_cli/commands/start_vm.py +83 -0
- agsekit-0.9.4/agsekit_cli/commands/stop.py +78 -0
- agsekit-0.9.4/agsekit_cli/commands/systemd.py +108 -0
- agsekit-0.9.4/agsekit_cli/config.py +370 -0
- agsekit-0.9.4/agsekit_cli/i18n.py +67 -0
- agsekit-0.9.4/agsekit_cli/interactive.py +487 -0
- agsekit-0.9.4/agsekit_cli/locales/en.json +344 -0
- agsekit-0.9.4/agsekit_cli/locales/ru.json +344 -0
- agsekit-0.9.4/agsekit_cli/mounts.py +60 -0
- agsekit-0.9.4/agsekit_cli/run_with_proxychains.sh +47 -0
- agsekit-0.9.4/agsekit_cli/vm.py +405 -0
- agsekit-0.9.4/config-example.yaml +34 -0
- agsekit-0.9.4/pyproject.toml +31 -0
- agsekit-0.9.4/setup.cfg +4 -0
- agsekit-0.9.4/tests/test_agents.py +154 -0
- agsekit-0.9.4/tests/test_backup_progress.py +96 -0
- agsekit-0.9.4/tests/test_backup_repeated.py +74 -0
- agsekit-0.9.4/tests/test_backup_repeated_commands.py +245 -0
- agsekit-0.9.4/tests/test_config_agents.py +44 -0
- agsekit-0.9.4/tests/test_config_gen_command.py +92 -0
- agsekit-0.9.4/tests/test_config_mounts.py +59 -0
- agsekit-0.9.4/tests/test_config_vms.py +120 -0
- agsekit-0.9.4/tests/test_create_vm_command.py +48 -0
- agsekit-0.9.4/tests/test_install_agents_command.py +81 -0
- agsekit-0.9.4/tests/test_interactive_mode.py +244 -0
- agsekit-0.9.4/tests/test_make_single_backup.py +400 -0
- agsekit-0.9.4/tests/test_mount_commands.py +191 -0
- agsekit-0.9.4/tests/test_prepare_command.py +93 -0
- agsekit-0.9.4/tests/test_run_command.py +253 -0
- agsekit-0.9.4/tests/test_shell_command.py +133 -0
- agsekit-0.9.4/tests/test_start_vm_command.py +108 -0
- agsekit-0.9.4/tests/test_stop_vm_command.py +108 -0
agsekit-0.9.4/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mihanentalpo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
agsekit-0.9.4/PKG-INFO
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agsekit
|
|
3
|
+
Version: 0.9.4
|
|
4
|
+
Summary: Agent Safety Kit command-line utilities
|
|
5
|
+
Author-email: Mihanentalpo <mihanentalpo@yandex.ru>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Mihanentalpo
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: click<9,>=8.1
|
|
32
|
+
Requires-Dist: PyYAML<7,>=6.0
|
|
33
|
+
Requires-Dist: questionary<3,>=2.0
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
[README.md на русском](README-ru.md)
|
|
37
|
+
|
|
38
|
+
# Agent Safety Kit
|
|
39
|
+
|
|
40
|
+
A toolkit for running AI agents in an isolated environment inside a Multipass virtual machine.
|
|
41
|
+
|
|
42
|
+
## Why this matters
|
|
43
|
+
|
|
44
|
+
<img width="437" height="379" alt="image" src="https://github.com/user-attachments/assets/c3486072-e96a-4197-8b1f-d6ac228c2cc6" />
|
|
45
|
+
|
|
46
|
+
Some stories (you can find plenty more):
|
|
47
|
+
|
|
48
|
+
* [Qwen Coder agent destroys working builds](https://github.com/QwenLM/qwen-code/issues/354)
|
|
49
|
+
* [Codex keeps deleting unrelated and uncommitted files! even ignoring rejected requests](https://github.com/openai/codex/issues/4969)
|
|
50
|
+
* [comment: qwen-code CLI destroyed my entire project, deleted important files](https://www.reddit.com/r/DeepSeek/comments/1mmfjsl/right_now_qwen_is_the_best_model_they_have_the/)
|
|
51
|
+
* [Claude Code deleted my entire workspace, here's the proof](https://www.reddit.com/r/ClaudeAI/comments/1m299f5/claude_code_deleted_my_entire_workspace_heres_the/)
|
|
52
|
+
* [I Asked Claude Code to Fix All Bugs, and It Deleted the Whole Repo](https://levelup.gitconnected.com/i-asked-claude-code-to-fix-all-bugs-and-it-deleted-the-whole-repo-e7f24f5390c5)
|
|
53
|
+
* [Codex has twice deleted and corrupted my files (r/ClaudeAI comment)](https://www.reddit.com/r/ClaudeAI/comments/1nhvyu0/openai_drops_gpt5_codex_cli_right_after/)
|
|
54
|
+
|
|
55
|
+
Everyone says "you should have backups" and "everything must live in git", but console AI agents still lack built-in snapshots to roll back after every change they make. Until sandboxes catch up, this toolkit helps you manage that yourself.
|
|
56
|
+
|
|
57
|
+
## Key ideas
|
|
58
|
+
|
|
59
|
+
- Agents run only inside a virtual machine.
|
|
60
|
+
- The VM is launched via Multipass (a simple Canonical tool to start Ubuntu VMs with a single command).
|
|
61
|
+
- Project folders from the host are mounted into the VM; an automatic backup job runs in parallel to a sibling directory at a configurable interval (defaults to every five minutes and only when changes are detected), using `rsync` with hardlinks to save space.
|
|
62
|
+
- VM, mount, and cloud-init settings are stored in a YAML config.
|
|
63
|
+
- You can run the agent without entering the guest via `multipass shell`—it still executes inside the VM.
|
|
64
|
+
- Multipass commands and agent runs can be wrapped in proxychains: set a proxy URL per VM or override it once with `--proxychains` to generate a temporary proxychains config automatically.
|
|
65
|
+
|
|
66
|
+
## Working agents
|
|
67
|
+
|
|
68
|
+
Currently confirmed working agent types are:
|
|
69
|
+
|
|
70
|
+
- qwen
|
|
71
|
+
- codex
|
|
72
|
+
- codex-glibc (built dynamically)
|
|
73
|
+
|
|
74
|
+
## Quick start
|
|
75
|
+
|
|
76
|
+
1. Install the package with pip (requires Python 3.9 or newer):
|
|
77
|
+
```bash
|
|
78
|
+
python3 -m venv ./venv
|
|
79
|
+
source ./venv/bin/activate
|
|
80
|
+
pip install agsekit
|
|
81
|
+
```
|
|
82
|
+
This makes the `agsekit` command available inside the virtual environment.
|
|
83
|
+
|
|
84
|
+
2. Alternatively, clone the repository and install from sources:
|
|
85
|
+
```bash
|
|
86
|
+
git clone https://github.com/MihanEntalpo/agent-safety-kit/
|
|
87
|
+
cd agent-safety-kit
|
|
88
|
+
pip install .
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
3. Create a YAML configuration (the CLI checks `--config`, then `CONFIG_PATH`, then `~/.config/agsekit/config.yaml`):
|
|
92
|
+
```bash
|
|
93
|
+
agsekit config-example
|
|
94
|
+
# edit vms/mounts/cloud-init to your needs
|
|
95
|
+
```
|
|
96
|
+
When working from a cloned repository, you can also copy the file directly:
|
|
97
|
+
```bash
|
|
98
|
+
mkdir -p ~/.config/agsekit
|
|
99
|
+
cp config-example.yaml ~/.config/agsekit/config.yaml
|
|
100
|
+
```
|
|
101
|
+
You can also run `agsekit config-gen` to answer a few questions and save the config (defaults to `~/.config/agsekit/config.yaml`; use `--overwrite` to replace an existing file).
|
|
102
|
+
|
|
103
|
+
4. Install required system dependencies (in particular, Multipass; requires sudo and currently works only on Debian-based systems):
|
|
104
|
+
```bash
|
|
105
|
+
agsekit prepare
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
5. Create the virtual machines defined in YAML:
|
|
109
|
+
```bash
|
|
110
|
+
agsekit create-vms
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
To launch just one VM, use `agsekit create-vm <name>`. If the config contains only one VM, you can omit `<name>` and it will be used automatically. If a VM already exists, the command compares the desired resources with the current ones and reports any differences. Changing resources of an existing VM is not supported yet.
|
|
114
|
+
|
|
115
|
+
6. Mount your folders (assuming mounts are already configured in the YAML file):
|
|
116
|
+
```bash
|
|
117
|
+
agsekit mount --all
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
7. Install all configured agents into their default VMs:
|
|
121
|
+
```bash
|
|
122
|
+
agsekit install-agents --all-agents
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
8. Launch an agent inside its VM (example runs `qwen` in the folder where `/host/path/project` is mounted, with backups enabled by default):
|
|
126
|
+
```bash
|
|
127
|
+
agsekit run qwen /host/path/project --vm agent-ubuntu
|
|
128
|
+
```
|
|
129
|
+
On the very first run with backups enabled, the CLI creates an initial snapshot with progress output before launching the agent, so wait for it to complete.
|
|
130
|
+
|
|
131
|
+
## agsekit commands
|
|
132
|
+
|
|
133
|
+
### Setup and VM lifecycle
|
|
134
|
+
|
|
135
|
+
* `agsekit prepare` — installs required system dependencies (including Multipass; requires sudo and currently works only on Debian-based systems).
|
|
136
|
+
* `agsekit config-gen [--config <path>] [--overwrite]` — interactive wizard that asks about VMs, mounts, and agents, then writes a YAML config to the chosen path (defaults to `~/.config/agsekit/config.yaml`). Without `--overwrite`, the command warns if the file already exists.
|
|
137
|
+
* `agsekit config-example [<path>]` — copies `config-example.yaml` to the target path (defaults to `~/.config/agsekit/config.yaml`). If the default config already exists, the command skips copying.
|
|
138
|
+
* `agsekit create-vms` — creates every VM defined in the YAML configuration.
|
|
139
|
+
* `agsekit create-vm <name>` — launches just one VM. If the config contains only one VM, you can omit `<name>` and it will be used automatically. If a VM already exists, the command compares the desired resources with the current ones and reports any differences. Changing resources of an existing VM is not supported yet.
|
|
140
|
+
* `agsekit shell [<vm_name>] [--config <path>]` — opens an interactive `multipass shell` session inside the chosen VM, applying any configured port forwarding. If only
|
|
141
|
+
one VM is defined in the config, the CLI connects there even without `vm_name`. When multiple VMs exist and the command runs in
|
|
142
|
+
a TTY, the CLI prompts you to pick one; in non-interactive mode, an explicit `vm_name` is required.
|
|
143
|
+
* `agsekit ssh <vm_name> [--config <path>] [<ssh_args...>]` — connects to the VM over SSH using `~/.config/agsekit/ssh/id_rsa` and forwards any extra arguments directly to the `ssh` command (for example, `-L`, `-R`, `-N`).
|
|
144
|
+
* `agsekit portforward [--config <path>]` — starts a dedicated `agsekit ssh` tunnel for each VM that defines `port-forwarding` rules, monitoring the child processes and restarting them if they exit. Stop with Ctrl+C to gracefully terminate the tunnels.
|
|
145
|
+
* `agsekit start-vm <vm_name> [--config <path>]` — starts the specified VM from the configuration. If only one VM is configured, the name can be omitted.
|
|
146
|
+
* `agsekit start-vm --all-vms [--config <path>]` — starts every VM declared in the config file.
|
|
147
|
+
* `agsekit stop-vm <vm_name> [--config <path>]` — stops the specified VM from the configuration. If only one VM is configured, the name can be omitted.
|
|
148
|
+
* `agsekit stop-vm --all-vms [--config <path>]` — stops every VM declared in the config file.
|
|
149
|
+
* `agsekit destroy-vm <vm_name> [--config <path>] [-y]` — deletes the specified VM from Multipass. Without `-y`, the CLI asks for interactive confirmation.
|
|
150
|
+
* `agsekit destroy-vm --all [--config <path>] [-y]` — deletes every VM from the configuration, with the same confirmation requirement.
|
|
151
|
+
* `agsekit systemd install [--config <path>]` — writes `~/.config/agsekit/systemd.env` with absolute paths to `agsekit`, the config, and the current project directory, then registers and starts the user unit from `systemd/agsekit-portforward.service` via `systemctl --user` (link, daemon-reload, start, enable).
|
|
152
|
+
* `agsekit systemd uninstall` — stops and disables the user unit, then removes the linked `systemd/agsekit-portforward.service` from systemd via `systemctl --user`.
|
|
153
|
+
|
|
154
|
+
### Mount management
|
|
155
|
+
|
|
156
|
+
* `agsekit mount --source-dir <path> [--config <path>]` — mounts the directory described by `source` in the configuration file (default search: `--config`, `CONFIG_PATH`, `~/.config/agsekit/config.yaml`) into its VM using `multipass mount`. Use `--all` to mount every entry from the config. When there is only one mount in the config, the command can be run without `--source-dir` or `--all`.
|
|
157
|
+
* `agsekit umount --source-dir <path> [--config <path>]` — unmounts the directory described by `source` in the config (or `CONFIG_PATH`/`--config`); `--all` unmounts every configured path. If only one mount is configured, the command will unmount it even without explicit flags.
|
|
158
|
+
|
|
159
|
+
### Backups
|
|
160
|
+
|
|
161
|
+
#### One-off backup
|
|
162
|
+
|
|
163
|
+
`agsekit backup-once --source-dir <path> --dest-dir <path> [--exclude <pattern> ...] [--progress]` — runs a single backup of the source directory into the specified destination using `rsync`.
|
|
164
|
+
The command creates a timestamped directory with a `-partial` suffix, supports incremental copies via `--link-dest` to the previous backup, and honors exclusions from `.backupignore` and `--exclude` arguments. When finished, the temporary folder is renamed to a final timestamp without the suffix. If nothing changed relative to the last backup, no new snapshot is created and the tool reports the absence of updates.
|
|
165
|
+
Pass `--progress` to forward rsync progress flags and show a console progress bar while files are copied.
|
|
166
|
+
|
|
167
|
+
`.backupignore` examples:
|
|
168
|
+
```
|
|
169
|
+
# exclude virtual environments and dependencies
|
|
170
|
+
venv/
|
|
171
|
+
node_modules/
|
|
172
|
+
|
|
173
|
+
# ignore temporary and log files by pattern
|
|
174
|
+
*.log
|
|
175
|
+
*.tmp
|
|
176
|
+
|
|
177
|
+
# include a specific file inside an excluded folder
|
|
178
|
+
!logs/important.log
|
|
179
|
+
|
|
180
|
+
# skip documentation build artifacts
|
|
181
|
+
docs/build/
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Backups use `rsync` with incremental links (`--link-dest`) to the previous copy: if only a small set of files changed, the new snapshot stores just the updated data, while unchanged files are hardlinked to the prior snapshot. This keeps a chain of dated directories while consuming minimal space when changes are rare.
|
|
185
|
+
|
|
186
|
+
#### Repeated backups
|
|
187
|
+
|
|
188
|
+
* `agsekit backup-repeated --source-dir <path> --dest-dir <path> [--exclude <pattern> ...] [--interval <minutes>] [--skip-first]` — runs an immediate backup and then repeats it every `interval` minutes (defaults to five minutes). With `--skip-first`, the loop waits for the first interval before performing the initial run. After each backup it prints `Done, waiting N minutes` with the actual interval value.
|
|
189
|
+
* `agsekit backup-repeated-mount --mount <path> [--config <path>]` — looks up the mount by its `source` path in the configuration file (default search: `--config`, `CONFIG_PATH`, `~/.config/agsekit/config.yaml`) and launches repeated backups using the paths and interval from the config. When only one mount is present, `--mount` can be omitted; with multiple mounts, an explicit choice is required.
|
|
190
|
+
* `agsekit backup-repeated-all [--config <path>]` — reads all mounts from the config (default search: `--config`, `CONFIG_PATH`, `~/.config/agsekit/config.yaml`) and starts concurrent repeated backups for each entry within a single process. Use Ctrl+C to stop the loops.
|
|
191
|
+
|
|
192
|
+
### Agent installation
|
|
193
|
+
|
|
194
|
+
* `agsekit install-agents <agent_name> [<vm>|--all-vms] [--config <path>] [--proxychains <value>]` — runs the prepared installation script for the chosen agent type inside the specified VM (or the agent's default VM if none is provided). If the config defines only one agent, you can skip `<agent_name>` and it will be picked automatically. Use `--proxychains <scheme://host:port>` to override the VM proxy for this installation or `--proxychains ""` to ignore it once.
|
|
195
|
+
* `agsekit install-agents --all-agents [--all-vms] [--config <path>] [--proxychains <value>]` — installs every configured agent either into their default VM or into every VM when `--all-vms` is set.
|
|
196
|
+
|
|
197
|
+
The installation scripts live in `agsekit_cli/agent_scripts/`: `codex` installs the npm CLI, `codex-glibc` builds the Rust sources with the glibc target and installs the binary as `codex-glibc`, and `qwen`/`claude-code` follow their upstream steps (the `qwen` script installs the qwen-code CLI). Other agent types are not supported yet.
|
|
198
|
+
|
|
199
|
+
### Running agents
|
|
200
|
+
|
|
201
|
+
* `agsekit run <agent_name> [<source_dir>|--vm <vm_name>] [--config <path>] [--proxychains <value>] [--disable-backups] [--skip-default-args] [--debug] -- <agent_args...>` — starts an interactive agent command inside Multipass. Environment variables from the config are passed to the process. If a `source_dir` from the mounts list is provided, the agent starts inside the mounted target path in the matching VM; otherwise it launches in the home directory of the default VM. Unless `--disable-backups` is set, background repeated backups for the selected mount are started for the duration of the run. When no backups exist yet, the CLI first creates an initial snapshot with progress output before launching the agent and then starts the repeated loop with the initial run skipped. Arguments from `agents.<name>.default-args` are added unless `--skip-default-args` is set; if the user already passed an option with the same name (for example `--openai-api-key`), the default value is skipped. With `--debug`, the CLI prints every external command before executing it to help troubleshoot agent launches. Use `--proxychains <scheme://host:port>` to override the VM setting for one run; pass an empty string to disable it temporarily.
|
|
202
|
+
|
|
203
|
+
### Interactive mode
|
|
204
|
+
|
|
205
|
+
In a TTY you don’t have to type full commands every time: the CLI can guide you through an interactive menu that fills in parameters for you.
|
|
206
|
+
|
|
207
|
+
* Run `agsekit` without arguments to open the interactive menu, choose a command, and select options such as the config path, mounts, or agent parameters.
|
|
208
|
+
* Start a command without mandatory arguments (for example, `agsekit run`) to automatically fall back to the interactive flow after the CLI prints a “not enough parameters” hint. Use `--non-interactive` if you prefer the usual help output instead of prompts.
|
|
209
|
+
|
|
210
|
+
## Localization
|
|
211
|
+
|
|
212
|
+
The CLI reads the system locale and falls back to English if it cannot detect a supported language. You can override this behavior with the `AGSEKIT_LANG` environment variable:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
AGSEKIT_LANG=ru agsekit --help
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## YAML configuration
|
|
219
|
+
|
|
220
|
+
The configuration file (looked up via `--config`, `CONFIG_PATH`, or `~/.config/agsekit/config.yaml`) describes VM parameters, mounted directories, and any `cloud-init` settings. A base example lives in `config-example.yaml`:
|
|
221
|
+
|
|
222
|
+
```yaml
|
|
223
|
+
vms: # VM parameters for Multipass (you can define multiple)
|
|
224
|
+
agent-ubuntu: # VM name
|
|
225
|
+
cpu: 2 # number of vCPUs
|
|
226
|
+
ram: 4G # RAM size (supports 2G, 4096M, etc.)
|
|
227
|
+
disk: 20G # disk size
|
|
228
|
+
proxychains: "" # optional proxy URL (scheme://host:port); agsekit writes a temporary proxychains.conf and wraps Multipass commands automatically
|
|
229
|
+
cloud-init: {} # place your standard cloud-init config here if needed
|
|
230
|
+
port-forwarding: # Port forwarding config
|
|
231
|
+
- type: remote # Open port inside VM and pass connections to Host machine's port
|
|
232
|
+
host-addr: 127.0.0.1:80
|
|
233
|
+
vm-addr: 127.0.0.1:8080
|
|
234
|
+
- type: local # Open port on Host machine, and pass connections to VM's port
|
|
235
|
+
host-addr: 0.0.0.0:15432
|
|
236
|
+
vm-addr: 127.0.0.1:5432
|
|
237
|
+
- type: socks5 # Open socks5-proxy port inside VM, directing traffic to Host machine's network
|
|
238
|
+
vm-addr: 127.0.0.1:8088
|
|
239
|
+
mounts:
|
|
240
|
+
- source: /host/path/project # path to the source folder on the host
|
|
241
|
+
target: /home/ubuntu/project # mount point inside the VM; defaults to /home/ubuntu/<source_basename>
|
|
242
|
+
backup: /host/backups/project # backup directory; defaults to backups-<source_basename> next to source
|
|
243
|
+
interval: 5 # backup interval in minutes; defaults to 5 if omitted
|
|
244
|
+
vm: agent-ubuntu # VM name; defaults to the first VM in the configuration
|
|
245
|
+
agents:
|
|
246
|
+
qwen: # agent name; add as many as you need
|
|
247
|
+
type: qwen # agent type: qwen (installs and uses the `qwen` binary), codex, codex-glibc (installs the `codex-glibc` binary), or claude-code (other types are not supported yet)
|
|
248
|
+
env: # arbitrary environment variables passed to the agent process
|
|
249
|
+
OPENAI_API_KEY: "my_local_key"
|
|
250
|
+
OPENAI_BASE_URL: "https://127.0.0.1:11556/v1"
|
|
251
|
+
OPENAI_MODEL: "Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8"
|
|
252
|
+
default-args: # arguments passed to the agent unless the user overrides them
|
|
253
|
+
- "--openai-api-key=my_local_key"
|
|
254
|
+
- "--openai-base-url=https://127.0.0.1:11556/v1"
|
|
255
|
+
vm: qwen-ubuntu # default VM for this agent; falls back to the mount VM or the first VM in the list
|
|
256
|
+
codex:
|
|
257
|
+
type: codex
|
|
258
|
+
claude:
|
|
259
|
+
type: claude-code
|
|
260
|
+
codex2:
|
|
261
|
+
type: codex-glibc
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
> **Note:** Prefer ASCII-only paths for both `source` and `target` mount points: AppArmor may refuse to mount directories whose paths contain non-ASCII characters.
|
agsekit-0.9.4/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
[README.md на русском](README-ru.md)
|
|
2
|
+
|
|
3
|
+
# Agent Safety Kit
|
|
4
|
+
|
|
5
|
+
A toolkit for running AI agents in an isolated environment inside a Multipass virtual machine.
|
|
6
|
+
|
|
7
|
+
## Why this matters
|
|
8
|
+
|
|
9
|
+
<img width="437" height="379" alt="image" src="https://github.com/user-attachments/assets/c3486072-e96a-4197-8b1f-d6ac228c2cc6" />
|
|
10
|
+
|
|
11
|
+
Some stories (you can find plenty more):
|
|
12
|
+
|
|
13
|
+
* [Qwen Coder agent destroys working builds](https://github.com/QwenLM/qwen-code/issues/354)
|
|
14
|
+
* [Codex keeps deleting unrelated and uncommitted files! even ignoring rejected requests](https://github.com/openai/codex/issues/4969)
|
|
15
|
+
* [comment: qwen-code CLI destroyed my entire project, deleted important files](https://www.reddit.com/r/DeepSeek/comments/1mmfjsl/right_now_qwen_is_the_best_model_they_have_the/)
|
|
16
|
+
* [Claude Code deleted my entire workspace, here's the proof](https://www.reddit.com/r/ClaudeAI/comments/1m299f5/claude_code_deleted_my_entire_workspace_heres_the/)
|
|
17
|
+
* [I Asked Claude Code to Fix All Bugs, and It Deleted the Whole Repo](https://levelup.gitconnected.com/i-asked-claude-code-to-fix-all-bugs-and-it-deleted-the-whole-repo-e7f24f5390c5)
|
|
18
|
+
* [Codex has twice deleted and corrupted my files (r/ClaudeAI comment)](https://www.reddit.com/r/ClaudeAI/comments/1nhvyu0/openai_drops_gpt5_codex_cli_right_after/)
|
|
19
|
+
|
|
20
|
+
Everyone says "you should have backups" and "everything must live in git", but console AI agents still lack built-in snapshots to roll back after every change they make. Until sandboxes catch up, this toolkit helps you manage that yourself.
|
|
21
|
+
|
|
22
|
+
## Key ideas
|
|
23
|
+
|
|
24
|
+
- Agents run only inside a virtual machine.
|
|
25
|
+
- The VM is launched via Multipass (a simple Canonical tool to start Ubuntu VMs with a single command).
|
|
26
|
+
- Project folders from the host are mounted into the VM; an automatic backup job runs in parallel to a sibling directory at a configurable interval (defaults to every five minutes and only when changes are detected), using `rsync` with hardlinks to save space.
|
|
27
|
+
- VM, mount, and cloud-init settings are stored in a YAML config.
|
|
28
|
+
- You can run the agent without entering the guest via `multipass shell`—it still executes inside the VM.
|
|
29
|
+
- Multipass commands and agent runs can be wrapped in proxychains: set a proxy URL per VM or override it once with `--proxychains` to generate a temporary proxychains config automatically.
|
|
30
|
+
|
|
31
|
+
## Working agents
|
|
32
|
+
|
|
33
|
+
Currently confirmed working agent types are:
|
|
34
|
+
|
|
35
|
+
- qwen
|
|
36
|
+
- codex
|
|
37
|
+
- codex-glibc (built dynamically)
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
1. Install the package with pip (requires Python 3.9 or newer):
|
|
42
|
+
```bash
|
|
43
|
+
python3 -m venv ./venv
|
|
44
|
+
source ./venv/bin/activate
|
|
45
|
+
pip install agsekit
|
|
46
|
+
```
|
|
47
|
+
This makes the `agsekit` command available inside the virtual environment.
|
|
48
|
+
|
|
49
|
+
2. Alternatively, clone the repository and install from sources:
|
|
50
|
+
```bash
|
|
51
|
+
git clone https://github.com/MihanEntalpo/agent-safety-kit/
|
|
52
|
+
cd agent-safety-kit
|
|
53
|
+
pip install .
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
3. Create a YAML configuration (the CLI checks `--config`, then `CONFIG_PATH`, then `~/.config/agsekit/config.yaml`):
|
|
57
|
+
```bash
|
|
58
|
+
agsekit config-example
|
|
59
|
+
# edit vms/mounts/cloud-init to your needs
|
|
60
|
+
```
|
|
61
|
+
When working from a cloned repository, you can also copy the file directly:
|
|
62
|
+
```bash
|
|
63
|
+
mkdir -p ~/.config/agsekit
|
|
64
|
+
cp config-example.yaml ~/.config/agsekit/config.yaml
|
|
65
|
+
```
|
|
66
|
+
You can also run `agsekit config-gen` to answer a few questions and save the config (defaults to `~/.config/agsekit/config.yaml`; use `--overwrite` to replace an existing file).
|
|
67
|
+
|
|
68
|
+
4. Install required system dependencies (in particular, Multipass; requires sudo and currently works only on Debian-based systems):
|
|
69
|
+
```bash
|
|
70
|
+
agsekit prepare
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
5. Create the virtual machines defined in YAML:
|
|
74
|
+
```bash
|
|
75
|
+
agsekit create-vms
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
To launch just one VM, use `agsekit create-vm <name>`. If the config contains only one VM, you can omit `<name>` and it will be used automatically. If a VM already exists, the command compares the desired resources with the current ones and reports any differences. Changing resources of an existing VM is not supported yet.
|
|
79
|
+
|
|
80
|
+
6. Mount your folders (assuming mounts are already configured in the YAML file):
|
|
81
|
+
```bash
|
|
82
|
+
agsekit mount --all
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
7. Install all configured agents into their default VMs:
|
|
86
|
+
```bash
|
|
87
|
+
agsekit install-agents --all-agents
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
8. Launch an agent inside its VM (example runs `qwen` in the folder where `/host/path/project` is mounted, with backups enabled by default):
|
|
91
|
+
```bash
|
|
92
|
+
agsekit run qwen /host/path/project --vm agent-ubuntu
|
|
93
|
+
```
|
|
94
|
+
On the very first run with backups enabled, the CLI creates an initial snapshot with progress output before launching the agent, so wait for it to complete.
|
|
95
|
+
|
|
96
|
+
## agsekit commands
|
|
97
|
+
|
|
98
|
+
### Setup and VM lifecycle
|
|
99
|
+
|
|
100
|
+
* `agsekit prepare` — installs required system dependencies (including Multipass; requires sudo and currently works only on Debian-based systems).
|
|
101
|
+
* `agsekit config-gen [--config <path>] [--overwrite]` — interactive wizard that asks about VMs, mounts, and agents, then writes a YAML config to the chosen path (defaults to `~/.config/agsekit/config.yaml`). Without `--overwrite`, the command warns if the file already exists.
|
|
102
|
+
* `agsekit config-example [<path>]` — copies `config-example.yaml` to the target path (defaults to `~/.config/agsekit/config.yaml`). If the default config already exists, the command skips copying.
|
|
103
|
+
* `agsekit create-vms` — creates every VM defined in the YAML configuration.
|
|
104
|
+
* `agsekit create-vm <name>` — launches just one VM. If the config contains only one VM, you can omit `<name>` and it will be used automatically. If a VM already exists, the command compares the desired resources with the current ones and reports any differences. Changing resources of an existing VM is not supported yet.
|
|
105
|
+
* `agsekit shell [<vm_name>] [--config <path>]` — opens an interactive `multipass shell` session inside the chosen VM, applying any configured port forwarding. If only
|
|
106
|
+
one VM is defined in the config, the CLI connects there even without `vm_name`. When multiple VMs exist and the command runs in
|
|
107
|
+
a TTY, the CLI prompts you to pick one; in non-interactive mode, an explicit `vm_name` is required.
|
|
108
|
+
* `agsekit ssh <vm_name> [--config <path>] [<ssh_args...>]` — connects to the VM over SSH using `~/.config/agsekit/ssh/id_rsa` and forwards any extra arguments directly to the `ssh` command (for example, `-L`, `-R`, `-N`).
|
|
109
|
+
* `agsekit portforward [--config <path>]` — starts a dedicated `agsekit ssh` tunnel for each VM that defines `port-forwarding` rules, monitoring the child processes and restarting them if they exit. Stop with Ctrl+C to gracefully terminate the tunnels.
|
|
110
|
+
* `agsekit start-vm <vm_name> [--config <path>]` — starts the specified VM from the configuration. If only one VM is configured, the name can be omitted.
|
|
111
|
+
* `agsekit start-vm --all-vms [--config <path>]` — starts every VM declared in the config file.
|
|
112
|
+
* `agsekit stop-vm <vm_name> [--config <path>]` — stops the specified VM from the configuration. If only one VM is configured, the name can be omitted.
|
|
113
|
+
* `agsekit stop-vm --all-vms [--config <path>]` — stops every VM declared in the config file.
|
|
114
|
+
* `agsekit destroy-vm <vm_name> [--config <path>] [-y]` — deletes the specified VM from Multipass. Without `-y`, the CLI asks for interactive confirmation.
|
|
115
|
+
* `agsekit destroy-vm --all [--config <path>] [-y]` — deletes every VM from the configuration, with the same confirmation requirement.
|
|
116
|
+
* `agsekit systemd install [--config <path>]` — writes `~/.config/agsekit/systemd.env` with absolute paths to `agsekit`, the config, and the current project directory, then registers and starts the user unit from `systemd/agsekit-portforward.service` via `systemctl --user` (link, daemon-reload, start, enable).
|
|
117
|
+
* `agsekit systemd uninstall` — stops and disables the user unit, then removes the linked `systemd/agsekit-portforward.service` from systemd via `systemctl --user`.
|
|
118
|
+
|
|
119
|
+
### Mount management
|
|
120
|
+
|
|
121
|
+
* `agsekit mount --source-dir <path> [--config <path>]` — mounts the directory described by `source` in the configuration file (default search: `--config`, `CONFIG_PATH`, `~/.config/agsekit/config.yaml`) into its VM using `multipass mount`. Use `--all` to mount every entry from the config. When there is only one mount in the config, the command can be run without `--source-dir` or `--all`.
|
|
122
|
+
* `agsekit umount --source-dir <path> [--config <path>]` — unmounts the directory described by `source` in the config (or `CONFIG_PATH`/`--config`); `--all` unmounts every configured path. If only one mount is configured, the command will unmount it even without explicit flags.
|
|
123
|
+
|
|
124
|
+
### Backups
|
|
125
|
+
|
|
126
|
+
#### One-off backup
|
|
127
|
+
|
|
128
|
+
`agsekit backup-once --source-dir <path> --dest-dir <path> [--exclude <pattern> ...] [--progress]` — runs a single backup of the source directory into the specified destination using `rsync`.
|
|
129
|
+
The command creates a timestamped directory with a `-partial` suffix, supports incremental copies via `--link-dest` to the previous backup, and honors exclusions from `.backupignore` and `--exclude` arguments. When finished, the temporary folder is renamed to a final timestamp without the suffix. If nothing changed relative to the last backup, no new snapshot is created and the tool reports the absence of updates.
|
|
130
|
+
Pass `--progress` to forward rsync progress flags and show a console progress bar while files are copied.
|
|
131
|
+
|
|
132
|
+
`.backupignore` examples:
|
|
133
|
+
```
|
|
134
|
+
# exclude virtual environments and dependencies
|
|
135
|
+
venv/
|
|
136
|
+
node_modules/
|
|
137
|
+
|
|
138
|
+
# ignore temporary and log files by pattern
|
|
139
|
+
*.log
|
|
140
|
+
*.tmp
|
|
141
|
+
|
|
142
|
+
# include a specific file inside an excluded folder
|
|
143
|
+
!logs/important.log
|
|
144
|
+
|
|
145
|
+
# skip documentation build artifacts
|
|
146
|
+
docs/build/
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Backups use `rsync` with incremental links (`--link-dest`) to the previous copy: if only a small set of files changed, the new snapshot stores just the updated data, while unchanged files are hardlinked to the prior snapshot. This keeps a chain of dated directories while consuming minimal space when changes are rare.
|
|
150
|
+
|
|
151
|
+
#### Repeated backups
|
|
152
|
+
|
|
153
|
+
* `agsekit backup-repeated --source-dir <path> --dest-dir <path> [--exclude <pattern> ...] [--interval <minutes>] [--skip-first]` — runs an immediate backup and then repeats it every `interval` minutes (defaults to five minutes). With `--skip-first`, the loop waits for the first interval before performing the initial run. After each backup it prints `Done, waiting N minutes` with the actual interval value.
|
|
154
|
+
* `agsekit backup-repeated-mount --mount <path> [--config <path>]` — looks up the mount by its `source` path in the configuration file (default search: `--config`, `CONFIG_PATH`, `~/.config/agsekit/config.yaml`) and launches repeated backups using the paths and interval from the config. When only one mount is present, `--mount` can be omitted; with multiple mounts, an explicit choice is required.
|
|
155
|
+
* `agsekit backup-repeated-all [--config <path>]` — reads all mounts from the config (default search: `--config`, `CONFIG_PATH`, `~/.config/agsekit/config.yaml`) and starts concurrent repeated backups for each entry within a single process. Use Ctrl+C to stop the loops.
|
|
156
|
+
|
|
157
|
+
### Agent installation
|
|
158
|
+
|
|
159
|
+
* `agsekit install-agents <agent_name> [<vm>|--all-vms] [--config <path>] [--proxychains <value>]` — runs the prepared installation script for the chosen agent type inside the specified VM (or the agent's default VM if none is provided). If the config defines only one agent, you can skip `<agent_name>` and it will be picked automatically. Use `--proxychains <scheme://host:port>` to override the VM proxy for this installation or `--proxychains ""` to ignore it once.
|
|
160
|
+
* `agsekit install-agents --all-agents [--all-vms] [--config <path>] [--proxychains <value>]` — installs every configured agent either into their default VM or into every VM when `--all-vms` is set.
|
|
161
|
+
|
|
162
|
+
The installation scripts live in `agsekit_cli/agent_scripts/`: `codex` installs the npm CLI, `codex-glibc` builds the Rust sources with the glibc target and installs the binary as `codex-glibc`, and `qwen`/`claude-code` follow their upstream steps (the `qwen` script installs the qwen-code CLI). Other agent types are not supported yet.
|
|
163
|
+
|
|
164
|
+
### Running agents
|
|
165
|
+
|
|
166
|
+
* `agsekit run <agent_name> [<source_dir>|--vm <vm_name>] [--config <path>] [--proxychains <value>] [--disable-backups] [--skip-default-args] [--debug] -- <agent_args...>` — starts an interactive agent command inside Multipass. Environment variables from the config are passed to the process. If a `source_dir` from the mounts list is provided, the agent starts inside the mounted target path in the matching VM; otherwise it launches in the home directory of the default VM. Unless `--disable-backups` is set, background repeated backups for the selected mount are started for the duration of the run. When no backups exist yet, the CLI first creates an initial snapshot with progress output before launching the agent and then starts the repeated loop with the initial run skipped. Arguments from `agents.<name>.default-args` are added unless `--skip-default-args` is set; if the user already passed an option with the same name (for example `--openai-api-key`), the default value is skipped. With `--debug`, the CLI prints every external command before executing it to help troubleshoot agent launches. Use `--proxychains <scheme://host:port>` to override the VM setting for one run; pass an empty string to disable it temporarily.
|
|
167
|
+
|
|
168
|
+
### Interactive mode
|
|
169
|
+
|
|
170
|
+
In a TTY you don’t have to type full commands every time: the CLI can guide you through an interactive menu that fills in parameters for you.
|
|
171
|
+
|
|
172
|
+
* Run `agsekit` without arguments to open the interactive menu, choose a command, and select options such as the config path, mounts, or agent parameters.
|
|
173
|
+
* Start a command without mandatory arguments (for example, `agsekit run`) to automatically fall back to the interactive flow after the CLI prints a “not enough parameters” hint. Use `--non-interactive` if you prefer the usual help output instead of prompts.
|
|
174
|
+
|
|
175
|
+
## Localization
|
|
176
|
+
|
|
177
|
+
The CLI reads the system locale and falls back to English if it cannot detect a supported language. You can override this behavior with the `AGSEKIT_LANG` environment variable:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
AGSEKIT_LANG=ru agsekit --help
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## YAML configuration
|
|
184
|
+
|
|
185
|
+
The configuration file (looked up via `--config`, `CONFIG_PATH`, or `~/.config/agsekit/config.yaml`) describes VM parameters, mounted directories, and any `cloud-init` settings. A base example lives in `config-example.yaml`:
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
vms: # VM parameters for Multipass (you can define multiple)
|
|
189
|
+
agent-ubuntu: # VM name
|
|
190
|
+
cpu: 2 # number of vCPUs
|
|
191
|
+
ram: 4G # RAM size (supports 2G, 4096M, etc.)
|
|
192
|
+
disk: 20G # disk size
|
|
193
|
+
proxychains: "" # optional proxy URL (scheme://host:port); agsekit writes a temporary proxychains.conf and wraps Multipass commands automatically
|
|
194
|
+
cloud-init: {} # place your standard cloud-init config here if needed
|
|
195
|
+
port-forwarding: # Port forwarding config
|
|
196
|
+
- type: remote # Open port inside VM and pass connections to Host machine's port
|
|
197
|
+
host-addr: 127.0.0.1:80
|
|
198
|
+
vm-addr: 127.0.0.1:8080
|
|
199
|
+
- type: local # Open port on Host machine, and pass connections to VM's port
|
|
200
|
+
host-addr: 0.0.0.0:15432
|
|
201
|
+
vm-addr: 127.0.0.1:5432
|
|
202
|
+
- type: socks5 # Open socks5-proxy port inside VM, directing traffic to Host machine's network
|
|
203
|
+
vm-addr: 127.0.0.1:8088
|
|
204
|
+
mounts:
|
|
205
|
+
- source: /host/path/project # path to the source folder on the host
|
|
206
|
+
target: /home/ubuntu/project # mount point inside the VM; defaults to /home/ubuntu/<source_basename>
|
|
207
|
+
backup: /host/backups/project # backup directory; defaults to backups-<source_basename> next to source
|
|
208
|
+
interval: 5 # backup interval in minutes; defaults to 5 if omitted
|
|
209
|
+
vm: agent-ubuntu # VM name; defaults to the first VM in the configuration
|
|
210
|
+
agents:
|
|
211
|
+
qwen: # agent name; add as many as you need
|
|
212
|
+
type: qwen # agent type: qwen (installs and uses the `qwen` binary), codex, codex-glibc (installs the `codex-glibc` binary), or claude-code (other types are not supported yet)
|
|
213
|
+
env: # arbitrary environment variables passed to the agent process
|
|
214
|
+
OPENAI_API_KEY: "my_local_key"
|
|
215
|
+
OPENAI_BASE_URL: "https://127.0.0.1:11556/v1"
|
|
216
|
+
OPENAI_MODEL: "Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8"
|
|
217
|
+
default-args: # arguments passed to the agent unless the user overrides them
|
|
218
|
+
- "--openai-api-key=my_local_key"
|
|
219
|
+
- "--openai-base-url=https://127.0.0.1:11556/v1"
|
|
220
|
+
vm: qwen-ubuntu # default VM for this agent; falls back to the mount VM or the first VM in the list
|
|
221
|
+
codex:
|
|
222
|
+
type: codex
|
|
223
|
+
claude:
|
|
224
|
+
type: claude-code
|
|
225
|
+
codex2:
|
|
226
|
+
type: codex-glibc
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
> **Note:** Prefer ASCII-only paths for both `source` and `target` mount points: AppArmor may refuse to mount directories whose paths contain non-ASCII characters.
|