Commit Graph

388 Commits

Author SHA1 Message Date
Ollie Agent 1e126ce76a Replace imperative 9P filesystem with declarative EDSL
The old fs/session/ package (14 files) and cmd/olliesrv/elevate_tree.go
(imperative FileTree implementations) are gone. Replaced by a single
declarative EDSL in fs/spec.go that declares the entire 9P namespace.

cmd/olliesrv/server.go simplified from 1430 to 825 lines:
- Deleted pathType() (110 lines) — tree.Stat() now handles all path resolution
- Deleted isSessionFile(), dirMode(), filePerm() — all from tree's info
- Deleted fsRoute/routes/route/routeDir — single rootTree, no route table
- Deleted elevateTree — EDSL handles /elevate/ in spec.go
- Deleted handleWrite(), readDNS(), helpPath() — dead code
- Deleted all 5 per-fid result fields — EDSL Request handlers manage state
- Deleted all path-based intercepts in read()/write() — entry.RequestRespMode()
- Deleted all path-depth hacks in makeStat() — custom Stat() closures in EDSL
- Deleted all content-length compute logic — info.Size() from tree
- Removed imports: agent, backend, elevate, paths, toolsrv, json

New fs/ package:
- spec.go — single EDSL declaration of the entire namespace
- builder.go — BuildTree() validates and compiles spec into *Tree
- tree.go — configurable FileTree implementation
- fsnode.go — Dir(), Leaf(), TemplateDir(), NodeOption constructors
- agentfiles.go / sessionfiles.go / rootfiles.go / elevatefiles.go
  — handler implementations wired by the EDSL
- lifecycle.go — Create, Kill, Rename, Shutdown, InterruptAll
- persist.go, procfiles.go
- edsl.md — documentation of the EDSL
2026-08-02 15:22:17 +02:00
Ollie Agent fd5b215268 eventwait: redesign as global /eventwait with structured delta events
BREAKING CHANGE: /session/eventwait is removed. Use /eventwait instead.

The old event system had several problems:
1. eventwait lived inside /session/ (per-session) but events are global
2. It returned the entire session index on every event, growing unboundedly
3. No structured event data — consumers couldn't tell WHAT happened

New design:
- Global /eventwait at the root of the 9P namespace
- Events are structured delta lines: '<scope> <action> <path>'
  e.g. 'S new session/foo', 'A kill session/foo/agent/bar'
- Ring buffer capped at 100 events (bounded memory)
- Offset-based blocking reads (consumers track position)
- Per-event granularity: S=new/kill/rename, A=new/kill/rename

Call sites updated:
- Session create → 'S new session/{name}'
- Agent create → 'A new session/{name}/agent/{aid}'
- Session kill → 'A kill ...' per agent + 'S kill session/{name}'
- Session rename → 'S rename session/{old} session/{new}'
- Agent rename → 'A rename session/{name}/agent/{old} ...'

KDE GUI updated to use ollie-9p read /eventwait instead of
plan9port 9p read session/eventwait.
2026-08-02 10:25:33 +02:00
Ollie Agent d9c2c4c7a3 olliesrv: classify /session descendants before routeDir
The generic routeDir(path) check ran before session-specific path handling.
Because /session is a mounted tree, every descendant under /session/... was
being classified as a directory, including regular files like state,
statewait, cfg, prompt, etc.

Fix pathType() to handle /session/... first, and only fall back to the
generic routeDir check afterward.
2026-08-02 09:58:22 +02:00
Ollie Agent a01829991f olliesrv: route agent paths by FindAgent, not active agent
The 9P server path classifier still validated /session/{id}/agent/{aid}
against sess.Core.Agent().Name(), which leaked single-agent semantics into
multi-agent routing. This broke per-agent paths even when the per-agent
file trees were otherwise correct.

Fix route/type validation to resolve the requested agent with FindAgent(),
and use that specific agent for /proc PID checks.
2026-08-01 22:03:41 +02:00
Ollie Agent c5285ac259 fs/session: restore normal blocking semantics for statewait
statewait is a blocking wait file with a 5-second timeout, not an
indefinite long-block stream like chat. Remove LongBlock=true so the
9P server uses the normal blocking path (WithTimeout 5s) instead of
WithCancel-only behavior.

Also remove temporary statewait debug instrumentation.
2026-08-01 21:45:39 +02:00
Ollie Agent 951fdc8133 session: support multiple agents in data structures
- session.Session: r *agent.Agent → agents []*agent.Agent
  - Agent() returns agents[0] for backward compat
  - Added Agents(), AgentAt(), AgentCount(), AddAgent()
  - Close/SetEnv/SetSessionID iterate all agents
  - Other methods use Agent() (primary agent)
- fs/session: AgentLog *AgentLog → AgentLogs map[string]*AgentLog
  - Added AgentLog() (returns first) and SetAgentLog(id, al) methods
  - Updated create.go, persist.go, root.go, olliesrv/server.go
2026-08-01 20:29:23 +02:00
Ollie Agent b038e82931 fix: rdwr on agent/new now returns agent name
The rdwr pattern needs per-fid state to work correctly (like session/new).
- Added agentNewResult field to fid struct
- Intercept writes to /session/{id}/agent/new and store result on fid
- Intercept reads from /session/{id}/agent/new and return stored result
- Added CreateAgentFromRoot public API
- Clearer error message when cwd is missing
2026-08-01 20:02:30 +02:00
Ollie Agent 8b795ad7e6 fix: allow access to agent/new on empty sessions
pathType in server.go blocked walks to agent/new when Core is nil.
Added early return for parts[2]=="new" before the nil-guard so the
agent creation file is always accessible.

Also made agent/new rdwr return the agent name instead of just "ok".
2026-08-01 19:56:14 +02:00
Ollie Agent 94d11f9121 feat: support empty sessions (Core=nil) for multi-agent prep
Create() now registers a Session with Core=nil instead of just reserving
a name. All code paths that accessed sess.Core are nil-guarded:

- root.go: buildIndex, InterruptAll, rootOpen (proc read), rootDel (proc dismiss)
- persist.go: Kill, Rename, Shutdown, waitIdle, persistSession
- files.go: handleCtl save command
- create.go: Create() creates and registers the empty session

Also fixed pathType in server.go which panicked on empty sessions
(calling sess.Core.Agent().Name() when Core is nil). The panic was
caught by the recovery handler and returned as 'internal error'.

AGENTS.md: document cmd/ollie-remote test/build quirk
2026-08-01 19:47:02 +02:00
Ollie Agent daf535308f server: handle session/new write+read in server (rdwr pattern), bypass FileConfig 2026-08-01 19:31:39 +02:00
Ollie Agent 9acc609db5 fix: server.go pathType validates agent by Name not ID 2026-08-01 18:02:57 +02:00
Ollie Agent 89f0ea4179 session: split immutable ID from mutable Name; add id/name files to 9P 2026-08-01 17:31:16 +02:00
Ollie Agent 7403e1f5bb session: replace timestamp-prefix IDs with UUIDv4; show first segment in acme GUI 2026-08-01 17:26:34 +02:00
Ollie Agent 8ae8a6ead4 session rename: eventwait file, broadcast on create/delete/rename, ollie-9p mv 2026-08-01 16:14:49 +02:00
Ollie Agent 4e582688ad session rename: add ollie-9p mv command, wire into KDE GUI 2026-08-01 15:46:56 +02:00
Ollie Agent 937e6aef3b update: agent loop, session persistence, 9P filesystem, server, and remote sandbox 2026-08-01 15:06:49 +02:00
Ollie Agent 83304e2896 split Session into Session + AgentState; move all agent-scoped state to AgentState
Session struct now only holds: id, uname, mu, Core, SessionCtx, cancel,
proc, modelsMu/Cache/At.

New AgentState struct holds: log, logVers, ChatOffset, chatCond, plan,
prevPrompt, remote — all per-agent state.

agentHelper now takes an *AgentState alongside *Session. All agent file
operations (plan, log, chat, prevPrompt, offset, remote, cfg) access
AgentState fields instead of Session fields.

Removed startEventLog from NewSession (was writing to session log).
replayMessagesToLog takes *AgentState. Rename no longer appends to log.
ReadPlanStep stubbed out (TODO: look up correct AgentState).
server.go makeStat stubbed out AgentState log size tracking (TODO).
2026-08-01 14:17:56 +02:00
Ollie Agent fb1d10141b decouple session and agent files in 9P tree
Session-level files (session/{id}/): plan, env, ctl
Agent-level files (session/{id}/agent/{aid}/): cwd, prompt, log, chat,
  cfg, state, statewait, usage, cost, ctxsz, models, systemprompt,
  tail, prompt.prev, context, toolsrv.loaded, toolsrv.rev, tools

Key changes:
- Split sessionHelper into sessionHelper and agentHelper types
- ctl moved to session level (kill, rn, save, invalidate)
- cwd moved to agent level (read/write)
- Agent cfg no longer supports rename (use session/ctl rn)
- Permissions updated: cwd=0666, ctl=0666, env=0444 at session level
- Removed duplicate envContent method
2026-08-01 13:57:05 +02:00
Ollie Agent 3046afd8ed fix 9P session/agent boundary enforcement
Bug: reading agent files (log, chat, state, etc.) via 9P returned the
same data regardless of which session or agent ID was specified. The
server did not validate agent IDs and had out-of-bounds slice access
on  when the path had fewer components than expected.

Fixes:
- fs/session/root.go: Added  guard before all
   checks in rootReaddir, rootStat, rootOpen.
  Added  guard before  access in rootStat.
  Added agent ID validation — returns error if the requested agent ID
  doesn't match the session's actual agent.
- cmd/olliesrv/server.go: Restructured pathType() to nest agent path
  checks inside a single
  block, preventing proc-path checks from incorrectly matching agent
  paths. Added agent ID validation (returns "" = not found).
  Added agent-path support in makeStat() for Qid version tracking on
  log/chat. Skip blocking files (chat, statewait) in stat-size
  computation to prevent hangs.
2026-08-01 13:39:14 +02:00
Levi Neely cfa2f49f8c remove no9p flag — 9P is the only interface now
The flag had no remaining purpose after D-Bus removal. 9P listener
is always enabled. The if-true blocks remain for now (cosmetic).
2026-07-31 20:56:52 +02:00
Levi Neely 43d0db520a remove D-Bus adapter from olliesrv
Delete dbus/dbus.go — the entire D-Bus SessionManager service is gone.
No more 150ms poll loop, no more signal emission, no more method handlers.

- Remove ollie/dbus import, nodbus flag, dbusAdapter variable
- Remove OnSessionCreated/Killed/Renamed hooks from Config
- Remove EnableDBus from Config
- Elevation notifications connect to session bus directly (godbus stays
  as a dependency solely for org.freedesktop.Notifications)

All clients now use 9P exclusively. D-Bus is dead.
2026-07-31 20:41:02 +02:00
Levi Neely c39149ca3e 9P streaming: add chat file, rename chat→log, rewrite acme frontend
- Rename 'chat' to 'log': returns last 64KB sliding window (static read).
  Tail still works via Qid.Vers. Full history persisted to disk per turn.

- Add 'chat' streaming file: blocking read that delivers new output as
  the agent produces it. Per-fid offset tracked via waitBase. Blocks
  indefinitely between turns (no EOF). EOF only on kill/session death.

- Add LongBlock interface to File: streaming files bypass the 5s read
  timeout. Server returns content directly (ignores Tread offset for
  streaming files since waitBase tracks position).

- Add 'kill'/'.'' ctl aliases with FIXME: currently kills entire session.
  When multi-agent-per-session lands, kill should kill agent only.

- Rewrite acme frontend (cmd/Ollie) to use 9P client directly instead
  of FUSE mount. streamChat() is a blocking read loop — no polling.
  All file operations (read, write, ls) go through plan9/client.

- Add 9P streaming prototype in experiments/9p-stream demonstrating
  the blocking-read pattern for token delivery.

The key insight: 9P's request-response model gives natural streaming.
Server holds the Tread until data arrives, client blocks on Read().
No polling, no signals, no offset tracking needed.
2026-07-31 19:52:27 +02:00
Levi Neely 7eb022faba remove built-in skill handlers, replace with external tools
skill_list and skill_load are now external shell scripts (data/tools/).
Removed from builtins: SkillList, SkillLoad, SkillActive.
Removed: toolsrv/skills.go, tools/builtin/skill.go, WithSkillsRegistry,
SkillsRegistry accessor, ListSkillsTools.
ollie-remote no longer initializes a skills registry.

The demarcation: built-ins mutate agent internals (tool schema, context
injection). Skills are just file reads — no special treatment needed.
2026-07-31 16:45:37 +02:00
Levi Neely 0acc36abfd toolsrv: embed sandbox/default.yaml, fix lifecycle
- Embed the full sandbox/default.yaml instead of sandbox-remote.yaml
  so local ollie-remote subprocesses get proper sandbox permissions
  (DNS, git config, etc.)
- justfile copies sandbox/default.yaml temporarily during build
- Register builtins + ToolRegistry + SkillsRegistry on ollie-remote
- Pdeathsig: kernel auto-SIGTERMs children when parent dies
- Cleanup: SIGTERM → 3s grace → SIGKILL (guaranteed kill)
- Atomic counter for unique socket paths (no collisions)
2026-07-31 14:17:59 +02:00
Levi Neely 59b672966f toolsrv: unified socket-based execution
Execution is now identical for local and remote:
- Session calls Spawn()/SpawnRemote() → owns *Process with socket
- Clients call Dial(LocalAddr(socket)) → *Conn over Unix socket
- ollie-remote serves --listen mode with multi-client accept loop
- Builtins (shell, tool_load, skill_load) run in subprocess with registries

Lifecycle:
- Pdeathsig ensures children die with parent (no orphans)
- Cleanup: SIGTERM → 3s grace → SIGKILL (guaranteed)
- Socket paths use atomic counter for uniqueness
- Session Kill() closes Process

Protocol:
- Extended RPC: set_env, set_cwd, detach, list_detached, etc.
- Shell goes through builtin dispatch (parses 'cmd' field correctly)
- Streaming output via JSON-RPC notifications
2026-07-31 14:10:47 +02:00
Levi Neely eb7bacc243 ollie-remote: fix empty output and wire generic tool dispatch
Shell results were returned as raw strings but the agent expects
structured content blocks ({content:[{type:text,text:...}]}). Fixed
shell handler to return the same format as the local Server.CallTool.

Shell errors now return as isError content blocks rather than RPC
errors, matching local behavior (output is preserved in errors).

The default RPC handler now dispatches to srv.CallTool() for any
unknown method, enabling named tools (file_read, file_grep, etc.)
from the embedded tools to be called remotely.
2026-07-31 11:32:46 +02:00
Levi Neely 249b9f80f9 ollie-remote: wire streaming output to JSON-RPC notifications
ExecuteInSandbox uses StreamFunc(ctx) to emit partial output. The
context passed to it lacked a WithOutputStream callback, so no output
was ever streamed back to the client.

Fix: wrap ctx with WithOutputStream that encodes output as JSON-RPC
notifications (id=0, result={data:...}). The client side already
handles these via the outputNotification path in CallTool.
2026-07-31 11:18:53 +02:00
Levi Neely 136ae81a6c fix(ollie-remote): add tools/.gitkeep so embed directive works without justfile 2026-07-31 11:05:10 +02:00
Ollie Agent e968f5407e env: remove OLLIE mount point variable from managed vars and defaults 2026-07-31 08:02:17 +02:00
Ollie Agent 855671d8ac remove dead acme scripts (Kmpl, Oi, Theo, Wtf) and stale data/scripts/README 2026-07-31 07:50:41 +02:00
Ollie Agent 3d65d787a2 elevate: broker credential support for privileged tool execution 2026-07-30 23:37:57 +02:00
Ollie Agent 0cea373207 mount: document purpose and fix misleading comment
Add README.md explaining the network transparency role of the mount
package. Replace 'kept as a convenience' comment with one that explains
why it exists and how it differs from local 9pfuse.
2026-07-30 21:23:25 +02:00
Ollie Agent dd8520abb7 Revert "remove dead mount/ package and olliesrv mount subcommand"
This reverts commit bcfdda26b4.
2026-07-30 21:19:11 +02:00
Ollie Agent bcfdda26b4 remove dead mount/ package and olliesrv mount subcommand
The FUSE-based 9P mount (mount/) was unused — all actual mounting
uses 9pfuse via ollie-remount. Remove the package, the olliesrv mount
subcommand, and the go-fuse dependency.
2026-07-30 21:18:52 +02:00
Ollie Agent 96dc6e442b main.go for olliesrv 2026-07-30 21:14:26 +02:00
Ollie Agent ea3db9eb08 remove httpgw and webui; update AGENTS.md to reflect current structure
- Remove cmd/ollie-httpgw/ directory and webui/ submodule
- Update justfile: remove httpgw/webui build targets
- Update README.md: remove httpgw/webui references
- Update doc/ARCHITECTURE.md: remove httpgw/webui references
- Update doc/EVOLUTION.md: remove httpgw/webui references
- Update doc/USAGE.md: remove httpgw/webui sections
- Update AGENTS.md: fix repo layout, build targets, testing, architecture
  paths, key files, adding tools/prompts, submodule workflow
2026-07-30 20:19:32 +02:00
Ollie Agent 4bc7a21097 flatten: fix stragglers — remote server, _lib, stray go.mod files
- Rewrite cmd/ollie-remote to use toolsrv.Server API (was using non-existent
  ollie/pkg/tools and ollie/pkg/tools/execute packages)
- Restore tools/_lib/ from pre-flatten branch (was lost in migration)
- Remove stray go.mod/go.sum from cmd/Ollie, cmd/ollie-httpgw, cmd/ollie-remote
- Update justfile: ollie-remote target copies tools from contrib/tools/
- Remove leftover root prompts/ directory
2026-07-30 19:01:36 +02:00
Ollie Agent 9b6ddb7df1 flatten: absorb submodules into single Go module
- Remove submodules: core, 9p, acme, httpgw, remote, el
- Keep submodules: kde, webui (separate build systems)
- Collapse core/ packages into root: agent/, backend/, detach/, elevate/,
  env/, log/, paths/, sandbox/, session/, skills/, tools/, toolsrv/
- Collapse 9p/ packages: fs/session/, mount/, dbus/, cmd/olliesrv/
- Move binaries: acme/ → cmd/Ollie/, httpgw/ → cmd/ollie-httpgw/,
  remote/ → cmd/ollie-remote/, 9p/cmd/ollie-9p/ → cmd/ollie-9p/
- Move data: agents/, prompts/, tools/, scripts/, skills/ → contrib/
- Move services/ → contrib/services/, experiments/ → doc/experiments/
- Delete .beads/, .claude/, .kiro
- Single go.mod at root (module ollie)
- Fix all import paths, merge fs/ + session/ packages
- Extract dbus/ and elevate/notify.go from 9p server package
- Update justfile for new paths and single-module build
2026-07-30 18:57:51 +02:00