92 lines
3.5 KiB
Markdown
92 lines
3.5 KiB
Markdown
# marvin-turnstone
|
|
|
|
Local turnstone deployment as a [boco](https://git.nubo.sh/hulthe/boco) **container-VM**.
|
|
|
|
host podman build ──> boco build qcow2 ──> boco boot
|
|
│ QEMU/KVM (virtio, user-net)
|
|
┌─────────────────────┴───────────────────┐
|
|
│ VM (Arch) │
|
|
│ /boco/init → start-turnstone.sh (root) │
|
|
│ ├─ sshd (ops channel) │
|
|
│ └─ setpriv marvin │
|
|
│ └─ turnstone-server :8080 PID 1 │
|
|
└─────────────────────────────────────────┘
|
|
host :8080 ──hostfwd──> web UI host :2222 ──> guest sshd :22
|
|
|
|
## Prerequisites
|
|
- `podman`, `qemu-base`, `virtiofsd`, `boco`
|
|
|
|
## Build
|
|
|
|
```sh
|
|
scripts/build.sh
|
|
```
|
|
|
|
Creates `configs/ssh/id_ed25519` (ops keypair, once), builds the podman
|
|
image, then packs it as `boco` qcow2 into the boco registry.
|
|
|
|
## Run
|
|
|
|
```sh
|
|
scripts/run.sh
|
|
```
|
|
|
|
This exposes the turnstone console on `:8080`, and ssh on `:2222`
|
|
|
|
### LLM backend
|
|
|
|
Set up `configs/turnstone/config.toml` with an OpenAI-compatible endpoint.
|
|
|
|
## Shares (virtiofs, survives reboots)
|
|
|
|
| Host path | Guest path | Purpose |
|
|
|------------------------|--------------------------------|--------------------------|
|
|
| `configs/turnstone/` | `/home/marvin/.config/turnstone` | turnstone config.toml |
|
|
| `data/` | `/var/lib/turnstone` | SQLite database |
|
|
| `work/` | `/home/marvin/work` | agent workspace |
|
|
|
|
Note that virtiofsd runs under `podman unshare`, which means that files
|
|
written by the guest-VM will be owned by a subuid-range.
|
|
|
|
## Configuration
|
|
|
|
Edit `configs/turnstone/config.toml` (see `config.toml.example`):
|
|
|
|
- `[models.<provider>]` - LLM provider; `api_key` must be set.
|
|
- `[auth] jwt_secret` - required, generate once.
|
|
- `[database] path` - SQLite on the `data/` share.
|
|
- `[tools]` - `workspace_dir` surfaced to the model.
|
|
|
|
### Personas
|
|
|
|
Turnstone offers a few built-in personas (Engineer, Writer, Researcher,
|
|
Scribe, Manager, Executive), which are seeded by turnstone's migration.
|
|
|
|
This deployment adds a custom default persona `marvin` (VM-specific:
|
|
persistence rules, Gitea remotes, podman) via `scripts/persona.py` -
|
|
the prompt text is versioned there and re-applied after a DB reset:
|
|
|
|
```sh
|
|
python3 scripts/persona.py # --db data/turnstone.db default
|
|
```
|
|
|
|
(Without a console deployment, persona CRUD is a direct SQLite write;
|
|
with `turnstone-console` running, use its admin API/Personas tab.)
|
|
|
|
### Skills
|
|
|
|
Skills are checked in under `skills` in the `SKILL.md format.`
|
|
These are imported into turnstone's DB-backed catalog via
|
|
`scripts/import_skills.py`. The script runs inside the VM.
|
|
|
|
```sh
|
|
scp -O -i configs/ssh/id_ed25519 -P 2222 -r skills scripts/import_skills.py \
|
|
marvin@localhost:/tmp/
|
|
ssh -i configs/ssh/id_ed25519 -p 2222 marvin@localhost \
|
|
/opt/turnstone/bin/python /tmp/import_skills.py --dir /tmp/skills
|
|
```
|
|
|
|
Idempotent (`--update` re-imports + appends version rows). **Reboot the
|
|
VM after importing** - the running server holds a stale WAL snapshot
|
|
and won't see new rows until restart.
|