Commit Graph

2267 Commits

Author SHA1 Message Date
Levi Neely dd0021fd9a fix: restore sessions after 9P listener is ready
ConsumeFeed dials the 9P socket. Moving session restore to after
the listener starts ensures the socket exists when feed consumers
connect.
2026-08-13 20:55:02 +02:00
Levi Neely dcd119c853 virtfs: refactor Stream to accept (readFn, signalFn)
Same pattern as BlockOnce: framework handles the blocking loop.
readFn takes a base string, returns (data, nextBase, error).
signal fires when new data may be available.

Chat stream handlers now use Stream(a.ChatRead, a.ChatSignal).
StreamRaw retained for custom handlers.

streamChat() in support.go is now dead code (replaced by ChatRead).
2026-08-13 20:50:27 +02:00
Levi Neely 794673a5d0 virtfs: refactor BlockOnce to accept (readFn, signalFn)
BlockOnce now takes a value-reader and a signal source. The framework
handles the blocking loop: read → compare hash to base → if different
return → else wait on signal or timeout.

On timeout (ctx.Done), returns empty (not error) so clients re-open
cleanly.

BlockOnceRaw retained for queue-style handlers (bypass/pending,
proc/wait) that manage their own blocking.

EventValue adapter wraps a <-chan Event into BlockOnce-compatible
(readFn, signalFn) pair via a thin goroutine.
2026-08-13 20:44:50 +02:00
Levi Neely b5cb8c397d feed: BlockOnce with base init, ConsumeFeed via lib9p client
- BlockOnce handler initializes base to current hash on fresh open,
  then blocks until hash changes. Same pattern as statewait.
- ConsumeFeed is a plain function: dials 9P, reads feed in a loop
  (open → block → data → close → repeat), submits to agent.
- Context cancellation closes the 9P client, unblocking Read().
- Called as go ConsumeFeed(ctx, ag) from AddAgent and session resume.
2026-08-13 20:26:08 +02:00
Levi Neely e2695d6f50 feed: export Feed field, remove wrapper methods, use direct access everywhere 2026-08-13 20:09:28 +02:00
Levi Neely 1537e35685 feed: inline handlers, remove FeedBlockingRead wrapper 2026-08-13 20:06:32 +02:00
Levi Neely 721b49ffa2 feed: use BlockOnce for read side, dedup via base comparison
Feed is now read-write (0666):
- Write: store data, signal via notifyChange
- Read (BlockOnce): block until content hash differs from base

Dedup lives in the read layer (same pattern as statewait). The
internal consumer goroutine and external 9P clients both call
FeedBlockingRead — same codepath, same dedup logic.

Consumer started from AddAgent (if ctx available) and session resume.
2026-08-13 20:05:46 +02:00
Levi Neely dfacdfed94 agent: add feed file — change-detecting streaming input gate
Feed is a write-only file in the agent namespace. Writes are
deduplicated against the previous value; the internal consumer
(blocking on WaitChange/WatchFeed) only wakes when genuinely new
data arrives.

Wiring is external and source-agnostic:
  # human → observer (poll git):
  while :; do git diff HEAD; sleep 5; done | ollie-9p write .../feed
  # agent → observer (stream chat):
  ollie-9p read .../coder/chat | ollie-9p write .../observer/feed

Uses the agent's existing signalCh/notifyChange plumbing — no new
channel infrastructure. Consumer goroutine spawned at agent creation
(AddAgent) and session resume, tied to session context.
2026-08-13 20:02:06 +02:00
Levi Neely 5459e7fa2a fix: XDG default fallback in prompt resolver; deduplicate tool headers
- envLookup: provide XDG spec defaults (XDG_CONFIG_HOME, XDG_DATA_HOME,
  XDG_CACHE_HOME) when env vars are unset, so agent profile prompts
  resolve correctly on systems without explicit XDG vars.
- renderTools: skip generated '## name' header when the tool's prompt
  text already starts with a markdown header, eliminating duplicates.
2026-08-13 15:45:35 +02:00
Levi Neely 0b932a60ca rename observer-feed to ObserverFeed 2026-08-13 14:55:33 +02:00
Levi Neely b9dfae0204 observer prompt: make constraints explicit and unambiguous 2026-08-13 14:28:51 +02:00
Levi Neely 81e78a952d add observer agent: read-only watcher with git-based feeder script
- observer.json: read-only tool set (file_read, file_grep, file_glob, reasoning_think)
- agent-observer.md: terse observation-only prompt
- observer-feed: polls git diff, feeds changes to agent prompt
- justfile: install new files
2026-08-13 14:28:20 +02:00
Levi Neely 78d11f2ce8 update kde submodule 2026-08-13 12:27:39 +02:00
Levi Neely 6a19c135eb prompts: drop tool path from system prompt, use absolute path in copilot example 2026-08-13 12:04:52 +02:00
Levi Neely 83b0b59a0a prompts: remove /home/user path examples that bias tilde expansion
- file_grep.meta: replace /home/user/project with /abs/path
- system_prompt.md: use $XDG_CONFIG_HOME instead of ~
- agent-copilot.md: use relative path in code block example
2026-08-13 12:02:27 +02:00
Levi Neely 1ac50d97e1 agent: drain FIFO after interrupted/failed turns
Fix holes where queued prompts were orphaned:
- After turn loop exits (interrupt, toolsrv unavailable), drain remaining FIFO items
- On panic recovery, pop next FIFO item and re-submit in a new goroutine
- fifo file write triggers Submit when agent is idle
2026-08-13 11:59:11 +02:00
Levi Neely e662d32c61 o: simplify new — only accept sname/aname syntax 2026-08-13 09:30:01 +02:00
Levi Neely 6465861908 o: accept sname/aname syntax for new command 2026-08-13 09:29:00 +02:00
Levi Neely 05770ee28b o: re-split args to handle quoted invocations from acme 2026-08-13 09:24:52 +02:00
Levi Neely 37608ab9b6 o new: ignore 'session already exists' error 2026-08-13 09:22:18 +02:00
Levi Neely bbf8176cc8 o new: use sname/aname syntax to create session+agent 2026-08-13 09:19:34 +02:00
Levi Neely c4b5a58300 doc: promote evolution.md to doc/, add rationale
It's a study log, not a resource. Added opening paragraph explaining
what the document is and why the dead ends matter.
2026-08-12 21:48:06 +02:00
Levi Neely 155e4fe97b evolution: consolidate dead ends into comprehensive final table
Removed two inline 'Dead Ends and Reversals' tables scattered mid-document.
Added single comprehensive table at the end covering all reversals from all
phases — including hooks, event ring buffer, abstractions, namespace merges,
concurrent-by-default rejection, and every other thing that was built and
then killed.
2026-08-12 21:39:53 +02:00
Levi Neely 8ead5c29e1 evolution: update background process interrupt delivery, drop concurrent-by-default
Background processes now deliver completions as user prompts (queued via
the agent's prompt file) upon completion, not injected in-loop alongside
tool results.

Removed 'Open Problem: Concurrency' section — concurrent-by-default was
considered and rejected (sequential execution but slower and more expensive).
Replaced with a paragraph explaining the deliberate design choice.
2026-08-12 21:30:33 +02:00
Levi Neely e323e7079e doc: add Phases 22-26 + Good Idea Fairy + pubsub migration to evolution.md
Major architectural changes documented:
- Aug 3: Ring buffer -> pubsub (Phase 19)
- Aug 5: Hooks deleted entirely, ~960 lines removed
- Aug 11-12: Meta-only tool definitions, bypass via 9P, fs/ flattening,
  sandbox simplification, agent loop cleanup
2026-08-12 20:43:08 +02:00
Levi Neely ef9a56d41b doc: rename tool scripts to tool definitions throughout 2026-08-12 19:40:06 +02:00
Levi Neely df7eefaf71 doc: rename tool-overlays to tool-definitions 2026-08-12 19:35:58 +02:00
Levi Neely 7d44e9ac1f doc: add tool overlays documentation
- Add doc/tool-overlays.md explaining meta-only tools and overlay pattern
- Examples: ripgrep, kubectl, MCP server wrapping
- Update README.md with tool overlays row in capabilities table
2026-08-12 19:14:32 +02:00
Levi Neely 9b98a958cc fix: treat meta cmd as shell command string, prepend tools dir to PATH
- ResolveTool now returns cmd field as-is instead of trying to resolve
  it as a binary path. This allows meta-only tools to use full shell
  command strings with env vars, pipes, and subshells.

- Prepend ~/.config/ollie/tools to PATH when executing tools so cmd
  fields can reference other tools by name.
2026-08-12 18:44:16 +02:00
Levi Neely 92d9fec51a docs: fix auth section - both servers use attach identity for permissions 2026-08-12 18:20:34 +02:00
Levi Neely 255986bad6 docs: fix 9p.md auth section, clarify toolsrv Tauth and aname scoping 2026-08-12 18:17:39 +02:00
Levi Neely 79a7cc68c7 docs: rewrite 9p.md to match current olliesrv and toolsrv namespaces 2026-08-12 18:16:55 +02:00
Levi Neely c2df612da5 docs: update usage.md slash commands, fix context model description 2026-08-12 18:12:01 +02:00
Levi Neely 31d550a94b docs: update README and usage for current architecture 2026-08-12 18:06:22 +02:00
Levi Neely 23f3a6092b refactor: eliminate TurnCtx, make loop functions Agent methods
- Delete TurnCtx struct (was progressively populated with optional nil fields)
- Convert run(), streamResponse(), execToolCalls(), execBatch(), execOne(),
  trackErrors(), retryCountdown() to Agent methods
- Extract autoCompact() and popInject() as Agent methods
- turn.go now installs a turn-scoped output handler wrapper instead of
  building TurnCtx closures
- context.Context is now passed as plain context.Context, not smuggled
  with unrelated state

Add history compaction tests:
- TestBuildCompactedHistory_OrphanedToolWalkback: verifies walk-back logic
  prevents orphaned tool messages at hot zone boundary
- TestBuildCompactedHistory_NoOrphanAtBoundary: verifies tool messages
  always have preceding assistant with tool_calls
2026-08-12 18:06:19 +02:00
Levi Neely fe24736b19 docs: update for background process changes
- doc/TODO.md: remove stale bgTracker cleanup item, add future considerations
- doc/9p.md: add proc/ section with list, new, new.bg, and per-pid files
- doc/9p.md: document <system-proc-complete> push mechanism
- README.md: update background process description
2026-08-12 17:39:16 +02:00
Levi Neely 0a4149218a fix: set agent ID on toolsrv connection after resume 2026-08-12 17:10:22 +02:00
Levi Neely bc7f51a9dc refactor: push proc completion from toolsrv to agent prompt
- toolsrv pushes <system-proc-complete> to agent prompt when bg proc exits
- Remove bgTracker and CollectInterrupts from olliesrv
- Add Cmd, AgentID, SessionID fields to Proc
- Add OnProcExit callback to State
- Add command field to Proc.Stat() output
2026-08-12 16:39:43 +02:00
Levi Neely 1e2ce1f899 chore: update kde submodule 2026-08-12 16:21:10 +02:00
Levi Neely 85f51e3b35 chore: update kde submodule 2026-08-12 16:19:36 +02:00
Levi Neely 10423c3339 chore: update kde submodule 2026-08-12 16:19:04 +02:00
Levi Neely 6eb3bf960b refactor: query toolsrv directly for proc list
- ListProcs() now queries toolsrv directly instead of local tracker
- Remove ownership verification from SignalProc/ProcOutput/DismissProc
- Clean up stale procs from local tracker when they disappear from toolsrv
- Document local tracker quirk in TODO.md for future cleanup
2026-08-12 16:06:22 +02:00
Levi Neely 1d5e9c4f8d fix: background proc output capture and status display
- Detach background proc context from request context so processes survive
  after the 9P request returns (fixes premature SIGTERM)
- Add /proc/list file to toolsrv showing all procs with state
- Show status (running/exited (N)) in agent proc list
- Keep exited procs in tracker until explicitly dismissed
- Skip 'list' entry in ListDetachedRaw
2026-08-12 14:10:08 +02:00
Levi Neely 85435447bf fix: clean shutdown without connection errors
- Use read deadline + context check instead of forcibly closing connections
- ReadBypassPending now takes context and exits cleanly on cancellation
- Remove forced conn.Close() loop from Kill() - context cancellation suffices
2026-08-12 12:40:40 +02:00
Levi Neely 9057d36f05 docs: clarify tool usage in system prompt, add cancellation flow doc
- Explicitly tell model not to invoke tool scripts via filesystem path
- Add concrete examples of native tool calls vs shell
- Document context cancellation flow from interrupt to process kill
2026-08-12 12:20:34 +02:00
Levi Neely aedfdec564 fix: set agent ID on tool server after /agent switch
SwitchProfile creates a new tool server connection but wasn't calling
SetAgentID on it, causing 'agent ID required' errors when listing tools.
2026-08-12 11:08:37 +02:00
Levi Neely edd5ade471 refactor: simplify bypass - toolsrv is the broker, olliesrv is just a client
- Remove olliesrv's bypass broker machinery (pendingCh, EvaluateRequest, etc)
- Session bypass loop now just reads from toolsrv's bypass/pending and notifies
- Notification handler writes directly to toolsrv's bypass/resolve (fire and forget)
- Remove bypass/ directory from olliesrv's 9P namespace
- Remove session/*/bypass file (policy can be added back to toolsrv later if needed)

The flow is now:
1. toolsrv blocks tool execution, exposes request via bypass/pending
2. olliesrv reads from toolsrv, shows D-Bus notification
3. User clicks approve/deny, olliesrv writes to toolsrv's bypass/resolve
4. toolsrv unblocks and executes (or denies)
2026-08-12 11:01:29 +02:00
Levi Neely 46bd0dd999 fix: toolsrv 9P server now handles BlockOnce/Stream reads correctly
- Added BlockingReadMode() and StreamMode() handling to toolsrv's handleRead()
- Made NextPending() context-aware in both toolsrv and olliesrv bypass packages
- This fixes the bypass approval flow via 9P - reads now properly block until
  a request is available and respect context cancellation
2026-08-12 10:49:08 +02:00
Levi Neely d59f49ee54 feat: context cancellation for tool calls
Wire context cancellation through the toolsrv 9P server so that
canceling a CallTool context properly terminates the running tool.

Changes:
- virtfs: Add Close() to File interface with CloseFn for Request handlers
- toolsrv/p9.go: Handle requests concurrently to allow Tclunk during
  blocking Twrite; call entry.Close() in handleClunk
- toolsrv/internal/server/proc.go: Check ctx.Done() while waiting for
  tool completion in NewProc
- Integration tests for context cancellation chain

The cancellation chain: client cancels ctx → fid.Close() → Tclunk →
handleClunk calls entry.Close() → closeFn cancels reqCtx → NewProc
sees ctx.Done() and returns ctx.Err()
2026-08-12 10:00:44 +02:00
Levi Neely 31681cb4e7 Add context cancellation to bypass.Submit
bypass.Submit now takes a context and returns early when cancelled.
This allows the stop command to properly cancel pending bypass requests
that haven't been approved or denied yet.

The full context chain is now:
1. stop command -> Interrupt -> cancel actCtx
2. actCtx cancellation -> closes CallTool fid
3. toolsrv proc/new sees closed fid -> propagates ctx cancellation
4. ExecuteTool -> executeBypassDirect -> bypass.Submit
5. bypass.Submit returns ctx.Err() when context is cancelled
2026-08-12 09:32:21 +02:00