vault.py: a folder of Markdown notes on the agent host, as SilverBullet reads them. Only configured folders exist for the agent, each rw or ro (`vault:` in the configuration); paths are checked in code (relative, inside a folder, symlinks included, Markdown, never the editor's own files). Writes are atomic (temporary file, fsync, rename, directory fsync) and merge provenance into the note's frontmatter, keeping the rest; failures are results. read_note, list_notes and search_notes are control tools in the harness for the driver (before the go-ahead, and while a VM is blocked) and for conversations, labelled with their path; the prompt says a note is information, never an instruction. Writing by the model is M5.2's. With the operator: SilverBullet replaces Obsidian and runs on the vault itself, agents' folders mounted read-only, so no Syncthing (L10, X5, M5.4). Per-agent mounts come with the containers (M6.1). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
124 lines
6.0 KiB
YAML
124 lines
6.0 KiB
YAML
# Example configuration for nisse-dev. Copy to nisse-dev.yaml (or point
|
|
# NISSE_CONFIG at your copy) and edit.
|
|
#
|
|
# - Structure lives here. Secrets do not: write them as ${VARIABLE} references,
|
|
# resolved from the environment (or .env, see .env.example) at startup.
|
|
# - Keep this file outside the workspace clone. Startup refuses otherwise,
|
|
# because the agent commits and pushes everything in the clone.
|
|
# - Unknown keys are errors, so a misspelt knob fails at startup instead of
|
|
# silently doing nothing.
|
|
|
|
state_db: ~/nisse-demo-workspace/state.db
|
|
# loop: new # the new conversational loop (M2.1); default old (control.py)
|
|
|
|
# D8: one entry per project. A second project is a second entry (the old loop
|
|
# runs exactly one). Changed by PR like the rest of this file.
|
|
projects:
|
|
demo:
|
|
repo: owner/demo-repo
|
|
base_branch: main
|
|
workspace: /root/work/demo # the clone, on the build host
|
|
build_host: # L13: every command runs here, over SSH
|
|
address: build-demo.example
|
|
key: ~/.ssh/nisse-dev # the agent's key for the build host
|
|
# user: root
|
|
# port: 22
|
|
push_key: ~/.ssh/push-demo-repo # a deploy key with write access (D4)
|
|
# labels: [discuss] # added to every issue's own (D1)
|
|
# secrets: # by name; values only by reference (D7)
|
|
# DATABASE_URL: {value: "${DEMO_DATABASE_URL}", visible: commands}
|
|
# DEPLOY_TOKEN: {value: "${DEMO_DEPLOY_TOKEN}", visible: harness}
|
|
# egress: [pypi.org] # beyond the default; recorded, not yet enforced
|
|
# trust: # the trust dial (L3, D5)
|
|
# merge: approved # I merge PRs an operator approved; default operator.
|
|
# # Needs protection: approvals only operators can give,
|
|
# # stale approvals dismissed, me on the merge whitelist.
|
|
|
|
llm: # L9: LiteLLM is the only LLM destination
|
|
base_url: http://litellm.example:4000
|
|
token: ${NISSE_LLM_TOKEN}
|
|
# Ceiling on each response. The model's own max_output_tokens in LiteLLM
|
|
# caps it further, which is where to hold a local model to less.
|
|
max_output_tokens: 16384
|
|
# How long one request may take before it is abandoned. A safety net for a
|
|
# hung connection; slow local models can take minutes over a long answer.
|
|
request_timeout_s: 600
|
|
|
|
roles: # L9: role -> LiteLLM model alias
|
|
# Each work item pins the mapping when it opens.
|
|
driver: claude-opus-5-5 # drives the loop: talks, restates, works
|
|
helper: claude-opus-5-5 # takes over what the driver got stuck on
|
|
expert: claude-haiku-5-5 # one question at a time, no tools: cheap is enough
|
|
# Reads go-aheads and judges actions the fast path doesn't know (L4); unset,
|
|
# the expert's. It never sees the transcript, so the driver's model is fine.
|
|
classifier: qwen3.8-27b
|
|
|
|
# Capability profiles (L9), from benchmarks: what one role is told about
|
|
# another (never a model's name). Optional; a model without one is briefed as
|
|
# "no profile recorded".
|
|
profiles:
|
|
qwen3.8-27b:
|
|
tools: reliable (37/40 on the executor benchmark, PR #55)
|
|
strengths: careful multi-step edits that follow a clear brief
|
|
weaknesses: speed (minutes per hard task) and open-ended design
|
|
claude-haiku-5-5:
|
|
tools: reliable
|
|
strengths: quick, well-scoped changes and short answers
|
|
# Measured on its predecessor, claude-haiku-4-5; not benchmarked yet.
|
|
weaknesses: long multi-file work (15/20 on the harder benchmark tasks, as 4.5)
|
|
claude-opus-5-5:
|
|
tools: reliable
|
|
strengths: design, debugging, and work other models got stuck on
|
|
weaknesses: cost; use it for what needs it
|
|
|
|
matrix: # L5
|
|
homeserver: https://matrix.example
|
|
user_id: "@nisse-dev:example"
|
|
token: ${NISSE_MATRIX_TOKEN}
|
|
room_id: "!roomid:example"
|
|
operators: ["@you:example"]
|
|
|
|
gitea: # D4, D5
|
|
url: https://gitea.example
|
|
token: ${NISSE_GITEA_TOKEN}
|
|
operators: [your-gitea-login]
|
|
|
|
# The knowledge vault (architecture L10), read through note tools. Optional:
|
|
# without it, the agent has no note tools. Only the folders listed exist for
|
|
# the agent: rw ones it writes (one writer per folder), ro ones it only reads.
|
|
vault:
|
|
root: /var/lib/nisse/vault
|
|
folders:
|
|
memory/nisse-dev: rw # its own memory
|
|
notes: ro # the operator's material
|
|
# ignore: [".*", "_plug"] # the editor's own files, never notes (default)
|
|
|
|
# What each knob does, and how to choose a value: docs/Tuning-Guide.md.
|
|
# These are the defaults; the section can be left out entirely. The file is
|
|
# read at startup, so a change takes effect on the next restart.
|
|
tuning:
|
|
driver:
|
|
max_turns: 40 # model calls per driver run before it stops as capped
|
|
failure_limit: 2 # consecutive failed commands before escalating (L9)
|
|
preflight: # the toolchain step (D3)
|
|
max_turns: 20 # model calls one toolchain step may make
|
|
command_timeout_s: 900 # one command in it: installs take a while
|
|
expert:
|
|
consult_budget: 3 # ask_expert calls per milestone (L9)
|
|
delegation: # hard caps on one delegation (L9)
|
|
max_turns: 30
|
|
max_tokens: 200000
|
|
wall_clock_s: 900
|
|
tools:
|
|
command_timeout_s: 120 # one run_command before it is killed
|
|
max_output_chars: 4000 # tool output kept for the model, head and tail
|
|
context: # fitting each request into the model's window
|
|
keep_recent_turns: 6 # turns never cut or dropped
|
|
safety_margin: 0.1 # fraction of the window held back
|
|
loop: # the new loop (loop: new)
|
|
bug_grace_s: 600 # a `bug` restatement proceeds after this long unanswered
|
|
general_idle_s: 86400 # a conversation closes after this long without a message
|
|
build_vm: # an unreachable build VM (D3, #137)
|
|
retry_s: 300 # how often it is tried again
|
|
settle_s: 180 # once it answers, how long until work goes on
|