Commit Graph

39 Commits

Author SHA1 Message Date
Ollie Agent cb13f6523c fs/session: fix deadlock in agent/new via setAgentLogLocked
SetAgentLog acquires sess.mu, but CreateAgent in create.go
already holds sess.mu when calling it — causing a deadlock on
agent/new writes. Split into SetAgentLog (locks) and
setAgentLogLocked (no lock) so callers that already hold the
lock can use the locked variant directly.
2026-08-01 20:32:18 +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 6fe212a6fc fix: add name= field to agent/new template, support in CreateAgent
- Added name= as the first field in agent/new read template
- CreateAgent now accepts name= as alias for agent_alias=
- gofmt formatting fixes
2026-08-01 19:58:00 +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 349d0fc470 server+kde: session/new and agent/new use rdwr pattern (write request, read response) 2026-08-01 18:50:10 +02:00
Ollie Agent 4bfbf70d45 fix: CreateAgent creates session (with Core) atomically, never registers nil Core in map 2026-08-01 18:46:06 +02:00
Ollie Agent 90ffca8622 server: split session/new (name only) from agent/new (cwd, backend, model, agent, alias, remote) 2026-08-01 18:41:10 +02:00
Ollie Agent 32706fdac2 server: add agent_alias param to session/new for explicit agent name 2026-08-01 18:32:58 +02:00
Ollie Agent e7f3fa32f8 agent: ID is UUID first segment (not incrementing); default Name = ID; remove atomic.NextUID 2026-08-01 18:26:07 +02:00
Ollie Agent ff17a90bbf fix: agent rename uses SetName() not Submit(/agent ...); add SetName method to agent.Agent 2026-08-01 18:12:18 +02:00
Ollie Agent d90fd1448f fix: agent rename path parsing — route strips session/ prefix, so old is ollie/agent/default not session/ollie/agent/default 2026-08-01 18:08:49 +02:00
Ollie Agent 19690d0ef5 fix: validate agent directory by Name only (not ID); gofmt all changed files 2026-08-01 17:59:39 +02:00
Ollie Agent 859d3cb16f agent: directory keyed by Name (not ID); agent rename via mv; validate both Name and ID 2026-08-01 17:46:23 +02:00
Ollie Agent afda1f7dd6 agent: add id (immutable) and name (mutable) files to 9P agent directory 2026-08-01 17:41:17 +02:00
Ollie Agent 20f05eae6a fix: key sessions map by Name (not UUID); rename moves dir; id file immutable 2026-08-01 17:34:52 +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 962a1ec654 fs/session: suppress reasoning_think tool output from chat log
reasoning_think emits with Role:tool producing [[[tool:reasoning_think]]]...[[[end]]]
blocks. When followed by the model's text response ([[[text]]]...[[[end]]]),
the chat log gets two [[[end]]] markers per turn, breaking the state machine
parser.

Fix: check for ev.Name == "reasoning_think" in the tool case and suppress
it the same way as the reasoning role — set streamingRole and return without
writing to the log.
2026-08-01 17:00:15 +02:00
Ollie Agent 0d814cd274 chat log: switch to [[[type]]]/[[[end]]] block format
Replace the single-bracket INI-like chat log format with triple-bracket
blocks. Each block opens with [[[type]]] and closes with [[[end]]].
The parser tracks m_inBlock to ignore content between blocks, making
the format robust against accidental header-like content.

- FormatEvent: writes [[[type]]]...content...[[[end]]]
- NewEventHandler: emits [[[end]]] on role transitions
- replayMessagesToLog: uses new format
- C++ parser: updated regex, new [[[end]]] handler, m_inBlock gate
- QML: update hardcoded [info] string
2026-08-01 16:49:01 +02:00
Ollie Agent 839911f6a0 fs/session: stop writing reasoning blocks to chat log
Reasoning text can contain header-like patterns (e.g. [tool:read],
[error]) that the chat log parser interprets as new block boundaries,
causing subsequent text to appear in wrong blocks.

Split the combined assistant/reasoning case: reasoning still tracks
streamingRole for proper separator logic but never calls AppendLog.
The LLM context still receives reasoning — only the chat log omits it.
2026-08-01 16:28:44 +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 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 405ae3137a move plan from session to agent level
plan is now at session/{id}/agent/{aid}/plan, not session/{id}/plan
2026-08-01 13:58:38 +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
Ollie Agent 0554862ec5 fix retry streaming: newline between each tick so they appear on separate lines 2026-08-01 12:51:44 +02:00
Ollie Agent 04ce9d7611 fix retry block: streaming pattern instead of in-place mutation, HH:MM:ss countdown 2026-08-01 12:45:44 +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 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 c031cb430e session/remote: fail fast on SSH auth and deploy errors
- Skip cwd existence check when remote is specified (cwd is on remote)
- Add BatchMode=yes to SSH: pubkey-only, no password fallback
- Add StrictHostKeyChecking=accept-new: auto-accept new hosts, reject
  changed keys
- Deploy failure already propagates as session creation error via
  RemoteDial returning error
2026-07-31 11:00:07 +02:00
Levi Neely a73899bc2f session: reject creation with non-existent cwd
When a session is created with a cwd that doesn't exist, all tool
execution fails with a confusing 'fork/exec landrun: no such file or
directory' because exec.Command sets cmd.Dir to the non-existent path.

Validate that cwd exists and is a directory at session creation time,
returning a clear error instead of allowing a broken session.

Also includes the earlier USER/NAMESPACE env export fix (agent.go,
shell.go) for the ollie-9p namespace path issue.
2026-07-31 09:28:44 +02:00
Ollie Agent f37e81d8cc remove emoji reaction feature (core, dbus, KDE GUI) 2026-07-31 09:09:24 +02:00
Ollie Agent 1015536f2c tools: move builtins to tools/builtin/
Prepares tools/ as the umbrella for all tool implementations:
- tools/builtin/ — in-process handlers (shell, reasoning, tool/skill registry)
- tools/lsp/ — (next) Go LSP tools with shared client library

Package rename: ollie/tools → ollie/tools/builtin
2026-07-30 22:04:32 +02:00
Ollie Agent ddddb1f53b remove s/, u/, x/ script namespaces and 9P backing
All session scripts (s/sh, s/b, s/bfg, s/bbg, s/ls, s/kill, s/cleanup),
utility scripts (u/optimize, u/complete, u/cascade, u/escalate), and
internal scripts (x/bd, x/prime, x/freeloader, x/task) are removed.

These are replaced by:
- generate, complete, route files (ollie-9p rdwr)
- integrated elevation broker
- D-Bus/9P session management

Also removes:
- 9P rootFileOrder entries and permission map for script files
- Script-serving catch-all in rootOpen
- prependOlliePath (no x/ scripts to shadow PATH with)

ollie-watchdog moved to contrib/scripts/ alongside ollie-remount.
2026-07-30 21:36:54 +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