Commit Graph

202 Commits

Author SHA1 Message Date
Levi Neely 8ad8e35551 Add goq backend support 2026-04-10 16:13:49 +02:00
Levi Neely 08a81c3317 agent: add Usage type to backend package 2026-04-01 14:22:50 +02:00
Levi Neely 8537832162 Rename NewOllama to NewOllie; drop ollama backend alias
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:33:18 +02:00
Levi Neely 1edf03b67c Fix backend Name: ollama -> ollie so ollie.yaml config is applied
LoadBackend uses cfg.Name to find the sandbox config file; keeping
it as 'ollama' meant ollama.yaml was loaded instead of ollie.yaml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:32:41 +02:00
Levi Neely 4e14a6f12b Rename ollama.go to ollie.go; update command and state inspector
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:26:45 +02:00
Levi Neely 6810414194 Switch ollama backend from ollama-mcp-client to ollie
Command is now `ollie [model]`. Config path removed (ollie defaults
to ~/.config/ollie/config.json). Reads OLLIE_MODEL with fallback to
ANVILLM_OLLAMA_MODEL. State inspector updated for ollie's process
tree; hooks are the primary busy signal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 02:19:49 +02:00
Levi Neely a616fa12aa p9: handle Twstat for FUSE O_TRUNC compatibility
9pfuse sends Twstat when truncating already-open files (O_TRUNC).
Without a handler, the server returned 'not supported' which 9pfuse
mapped to ERANGE, causing shell redirection (>) to fail on the
FUSE mount. Accept and ignore wstat on synthetic files.
2026-03-21 15:54:25 +01:00
Levi Neely 1acb1e3909 Rename mcptools to tools in search paths 2026-03-20 16:37:58 +01:00
Levi Neely bb29ec6de7 Extract Assist to anvillm-acme, move logging to pkg/ 2026-03-20 15:29:06 +01:00
Levi Neely ed43407383 Move sandbox to pkg/ for external import 2026-03-20 15:18:50 +01:00
Levi Neely 8e50b84707 Extract beads to standalone 9beads service
- Remove embedded BeadsFS from anvilsrv
- Remove beads.go and related tests from p9 package
- Update Assist to connect to separate 'beads' 9P service
- Update mcptools scripts: anvillm/beads/* -> beads/*

Beads now served by 9beads (separate repo/process).
2026-03-20 15:13:02 +01:00
Levi Neely daf50d9783 beads: natural sort for hierarchical IDs
Sort bd-1.2 before bd-1.10 instead of lexicographic order.
2026-03-20 14:28:19 +01:00
Levi Neely 304bf25bf1 resolve prjdir from worktree/workspace dir 2026-03-18 23:07:45 +01:00
Levi Neely cfd4cf5daa mailbox: delete only removes from inbox, not completed 2026-03-18 17:20:41 +01:00
Levi Neely e78d91cf55 mailbox: add DeleteFromInbox, delete tries inbox then completed 2026-03-18 17:19:40 +01:00
Levi Neely b03324baaf beads: add deferred filter endpoint
Add /beads/deferred aggregate endpoint and per-mount /beads/<mount>/deferred
endpoint to list beads with status=deferred.

- internal/p9/beads.go: add readDeferredFromStore and readDeferredAggregate
- internal/p9/server.go: wire up deferred in walk, directory listings
- cmd/Assist: update listBeadsWithFilter to use deferred endpoint
2026-03-18 17:02:32 +01:00
Levi Neely 1f7d3ace54 fix crash on double mount 2026-03-18 09:25:28 +01:00
Levi Neely d3e2a543cb Update remaining read_inbox references to check_inbox 2026-03-18 08:20:41 +01:00
Levi Neely 3ab11f1c88 beads: remove workspace detection — can't distinguish from worktree-based 2026-03-16 15:11:27 +01:00
Levi Neely 6645cd9efb beads: fix worktree detection — allow worktree-based repos, reject feature workspaces 2026-03-16 15:08:51 +01:00
Levi Neely ff58ef9438 beads: move worktree/workspace validation to server-side 2026-03-16 15:04:13 +01:00
Levi Neely d5b30ed38e config: add shared ANVILLM_PROJECT_DIRS config
- Loaded once at startup, defaults to ~/src:~/prj
- Beads mount validation uses shared config
- Available for other uses via config.ProjectDirs
2026-03-16 14:52:28 +01:00
Levi Neely 7935950e4d beads: warn on overlapping mount paths 2026-03-16 14:47:39 +01:00
Levi Neely 69829a98a1 beads: add scope-based filtering for worktree/workspace isolation
- Beads tagged with scope:<value> label, auto-derived from cwd
- Strict scope matching: bots only see beads matching their scope
- Updated scripts: create_bead, list_beads, list_ready_beads, wait_for_bead, search_beads, batch_create_beads, jira_to_beads, github_to_beads
- Fixed batch-create to handle raw JSON and create beads one at a time
- Added scope to JSON output and BeadReady events
2026-03-16 14:41:54 +01:00
Levi Neely 2d908c6dcd Assist: add Comment tag to leave comments on beads
- Add Comment tag to bead view window tagline
- New /AnviLLM/Tasks/{bead-id}/comment window with Put handler
- Fix comments display: JSON field is 'text' not 'body'
2026-03-16 11:23:46 +01:00
Levi Neely 47a97e5cea supervisor: replace Go package with anvillm-supervisor shell script
Remove the internal/supervisor Go package and cron-driven orphan check
script. Replace with a single anvillm-supervisor script invoked by cron
that handles both orphan bead recovery (--orphans, every 5m) and idle
worker nudging (--nudge, every 1m). Nudges use send_message.sh as user,
consistent with existing mail processing. anvilsrv no longer runs any
supervisor goroutine.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 14:47:56 +01:00
Levi Neely 8e88660f65 supervisor: nudge idle worker-role bots to run their polling loop
Replace dead assignWork() stub with nudgeIdleWorkers(), which sends a
prompt to any session whose role has worker: true in its front-matter
and has been idle for more than 15 seconds. A 15-second ticker drives
the checks. Bots that should be polling for beads will self-correct
after a brief idle period.

Add Worker bool to RoleMeta, parsed from "worker: true" front-matter,
and IsWorker() helper on RolesFS. Remove unused beads/mailbox/eventbus
deps from the supervisor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 14:25:21 +01:00
Levi Neely b4e84f57ee supervisor: stop sending inbox messages to bots
BeadReady events are already fired when a bead becomes ready; bots
listen for those directly. Sending inbox messages was redundant and
caused duplicate/unexpected prompts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 14:16:03 +01:00
Levi Neely 173746ce3b beads: add per-mount write mutex to serialize concurrent writes
Concurrent writes to the same mount (e.g. two bots claiming the same
bead simultaneously) could race through RunInTransaction before either
committed. A per-mount writeMu serializes all writes without blocking
independent mounts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 13:57:07 +01:00
Levi Neely 9120e51215 beads,roles: emit BeadClaimed event; add bead loop to worker roles
BeadClaimed fires on successful claim with source=beads/<mount> and
data={bead_id, assignee, mount}.

Worker roles (developer, devops, pkgmgr, researcher, tester, author)
now have a Bead Loop section: wait_for_bead.sh → claim → work →
complete → repeat. Reviewer role is spawned by workers, not looping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 20:58:58 +01:00
Levi Neely b52f0b5e85 beads: simplify claim — open only, orphan recovery via unclaim
Claim now rejects anything not in status=open. Dead-assignee takeover
is handled by unclaiming the bead (which fires BeadReady), letting any
waiting bot claim it normally. Removes isAlive/SetSessionLiveness.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 20:51:22 +01:00
Levi Neely d0acd32f8f beads: atomic conditional claim with orphan takeover
claim now runs in a transaction: reads current status/assignee, allows
claim only if status=open or (status=in_progress and assignee is dead).
Returns ErrAlreadyClaimed if the current assignee is alive.

BeadsFS.SetSessionLiveness wires a func(agentID string) bool from the
session manager so the claim handler can check liveness without importing
the session package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 20:48:14 +01:00
Levi Neely c58f0615a9 events: rename agent→source, embed full bead in BeadReady
Event.Agent renamed to Event.Source (json: "source") — more accurate since
the field carries a session ID for session events and a subsystem identifier
for infrastructure events.

BeadReady source is now "beads/<mount>" so listeners can filter by mount
without fetching. BeadReady data is now the full bead JSON including comments,
eliminating the round trip a listener would need to decide whether to claim.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 20:36:38 +01:00
Levi Neely cb97b3640c p9: remove pending_approval/pending_review from protocol
Drop status constants, readPendingFromStore, pending-approval/pending-review/resume
ctl handlers, and the pending virtual file from the 9P directory listing.
No migration needed — status is a string field; unused values simply won't appear.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 20:13:17 +01:00
Levi Neely 62319aef68 supervisor: fix panic crash and add recover
- bead["id"].(string) was an unsafe type assertion — panicked if id was
  missing or not a string, killing the server process. Use comma-ok form.
- Add recover() to Run() to log panics instead of crashing anvilsrv.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 16:08:54 +01:00
Levi Neely 9c5f98218c supervisor: exclude in_progress beads from assignment candidates
GetReadyWork returns both open and in_progress by default. Only open
unassigned beads should be offered to idle sessions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 15:58:51 +01:00
Levi Neely 21450ba02c supervisor: remove redundant in-memory assignment tracking
s.assigned and s.lastAssigned were redundant: the bead's own assignee
field is the source of truth, and on server restart all sessions die
anyway making in_progress beads orphans for the cron to recover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 15:55:18 +01:00
Levi Neely 68cc9445a9 supervisor: replace polling with event-driven work assignment
- Add EventBeadReady to eventbus, published by BeadsFS on open/reopen/unclaim
- Wire eventbus into BeadsFS via SetEventBus (called after server init)
- Supervisor now reacts to EventStateChange{idle} and EventBeadReady
  instead of a 5s ticker; 60s fallback ticker retained for safety

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 15:52:18 +01:00
Levi Neely d39a7f118d supervisor: align to new workflow
- Remove "claimable" label requirement: ready beads (open, unblocked,
  unassigned) are claimable by definition; deferred is now the default
  new-bead state so no label gate is needed
- Fix mount name: use bead["mount"] from readReadyAggregate() instead
  of filepath.Base(cwd) which was wrong after dropping friendly names
- Remove auto-mount on session state change: mounts are now explicit
  (user/operator controlled via mount_beads.sh)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 15:46:01 +01:00
Levi Neely 5436a4223d beads: restore update_bead.sh; block atomic fields from direct update
The update ctl command now rejects fields managed by atomic operations
(status, assignee, closed_at, close_reason, defer_until) with a hint
pointing to the correct command. update_bead.sh is restored with valid
fields documented in the header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 13:16:36 +01:00
Levi Neely e55742d691 beads: add atomic ctl operations; replace update_bead.sh
Add to 9p ctl handler: open, defer [until <RFC3339>], reopen, relate,
unrelate, config. Add corresponding mcptools scripts. Remove
update_bead.sh in favour of atomic operation scripts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 13:14:39 +01:00
Levi Neely 5dbd4cf777 beads: default new bead status to deferred
New beads created via the 9p interface now start as deferred instead
of open. Planning/human review is required to promote a bead to open
before the scheduler can assign it to a worker.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 13:07:59 +01:00
Levi Neely 179a59bf16 p9: buffer Twrite chunks, dispatch on Tclunk
The 9P client splits writes larger than msize into multiple Twrite
messages with increasing offsets. The server was dispatching each
Twrite immediately, so only the first chunk was ever processed —
causing JSON parse failures for payloads exceeding msize.

Fix: accumulate all Twrite data into a per-fid writeBuf, then dispatch
the fully-assembled payload in Tclunk. Tclunk can return Rerror if
dispatch fails, preserving error reporting to the caller.

This unblocks large bead descriptions/comments and message bodies
without any msize negotiation changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 23:17:57 +01:00
Levi Neely 2a1d620a31 rename 9P endpoint from 'agent' to 'anvillm'
- Update socket path, MountService calls, path prefixes
- Update mcptools, scripts, docs, diagrams, services
- Fix idleSince initialization at session creation
2026-03-12 12:13:40 +01:00
Levi Neely 46da046fb3 tmux: remove FIFO plumbing, fix per-window metadata
- Remove dead streaming code: reader(), waitForReady(), StartupHandler, pipe-pane
- Switch recovery metadata from session-scoped set-environment to window-scoped set-option -w @key
- Sessions now start in idle state immediately (no startup wait)
2026-03-12 11:47:37 +01:00
Levi Neely 39b49e83ce beads: reduce context overflow, simplify filters, atomic blockers
- list_beads.sh/list_ready_beads.sh: filter to id,priority,title,status
- Add read_bead_comments.sh tool and Comments view in Assist
- Simplify Assist filters to All/Ready (was 6 status filters)
- Server-side filtering: list excludes closed at DB, ready uses GetReadyWork
- Default limit 100, DB-level filtering
- Atomic blockers= support in new command
2026-03-11 09:45:20 +01:00
Levi Neely 919335a271 conductor: adaptive delegation based on available staff
- roles/conductor.md: discover roster before planning; adapt workflow
  to available roles (dev-only, dev+review, dev+review+test, etc.);
  drive iterative cycles; parallelize across multiple same-role bots;
  report skipped phases instead of blocking on missing roles

- team-templates/debug: new workflow with conductor+developer+tester;
  blocks until all roles are idle before returning

- list format: replace model field with role (field 5) in agent/list;
  update Assist, anvillm, anvilwebgw, list_sessions.sh accordingly

- Assist /AnviLLM/: replace Model column with Role in session list
2026-03-07 17:24:40 +01:00
Levi Neely 10d25a371a session: reset initialPromptSent when context is set
If context is written after the first mail nudge has already fired,
initialPromptSent was already true and the context would never be
injected. Resetting it on SetContext ensures the context is always
prepended to the next prompt regardless of timing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 12:30:21 +01:00
Levi Neely e4ea258c6a session: remove wakeup channel, use ticker-only mail processing
The wakeup channel caused duplicate message delivery: inbox delivery
and idle state transitions both signaled an immediate wakeup with
bypassIdleCheck=true, prompting bots before they were ready.

Replace with a simple 5-second ticker. The idle threshold is always
applied, eliminating the race condition. Worst-case delivery latency
is 10 seconds (one tick to drain outboxes, next tick to prompt).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 22:38:21 +01:00
Levi Neely 7891d062ab p9: on role write, validate role exists and deliver to bot inbox
Instead of silently setting context on the session, writing to
agent/{id}/role now: validates the role exists in RolesFS (returning
"role not found" on failure), sets the role name on the session, and
delivers the role definition as a PROMPT_REQUEST from "user" to the
bot's inbox. The wakeup mechanism fires immediately via the onRecv
callback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 19:39:21 +01:00