olliesrv now supports three operating modes:
+9p +dbus (default): full 9P server with embedded D-Bus adapter
+9p -dbus (-nodbus): pure 9P server, no desktop integration
-9p +dbus (-no9p): D-Bus only, no filesystem interface
The -no9p flag gates all 9P listener setup (unix + tcp), the 9P
server instance, and per-session FUSE mounts. D-Bus becomes mandatory
in this mode (errors if session bus is unavailable). -no9p and -nodbus
are mutually exclusive.
This replaces the need for the archived standalone ollied daemon.
Dial the remote eagerly during session creation so HostInfo is available
for BuildRuntime. Pass PRIME_PLATFORM and PRIME_IS_GIT_REPO as env vars
so the system prompt reflects the remote host, not the local machine.
Remote sessions had no local mount because WithMount9P hooks into the
local execute.Server which does not exist for remote sessions. Start
the mount directly and tear it down on kill/shutdown.
When creating a session with remote=user@host, the session manager
uses remote.Decl() instead of execute.Decl() for the tool dispatcher.
This forwards all tool calls over SSH to an ollie-remote process on
the target host.
Usage: printf "cwd=/path\nremote=user@host\n" > \$OLLIE/s/new
During startup, session.NewManager restores sessions and fires the
OnSessionCreated callback, but dbusAdapter is still nil at that point
so SessionCreated signals were never emitted. WatchExisting runs after
the adapter is live — emit SessionCreated there so GUI clients learn
about pre-existing sessions reliably.
Expose org.ollie.SessionManager on the session bus directly from olliesrv.
The adapter emits StateChanged, ChatUpdated, SessionCreated, SessionKilled,
SessionRenamed, ProcessDetached, and ProcessExited signals. All KDE frontends
work without ollied.
Fixes:
- ListSessions: use Manager.List() instead of broken Readdir("")
- RenameSession: delegate to Manager.RenameSession()
- WatchExisting: start signal watchers for sessions restored at startup
- Introspection XML: declare all methods and signals
Shell fd position advances after write, so the subsequent read
arrives with offset=N (write length). readDNS always serves from
offset 0, fixing empty reads from exec 3<>file; echo >&3; cat <&3.
/route now uses LLM-based capability classification with
OLLIE_ROUTE_MODEL_FAST and OLLIE_ROUTE_MODEL_POWER env vars.
OLLIE_TIER_* env vars are no longer used.
Write a task description to /route; a cheap local model (OLLIE_ROUTE_BACKEND/
OLLIE_ROUTE_MODEL, defaults to ollama/qwen3:8b) classifies it as worker or
expert. The resolved backend+model for that tier is returned on read.
Explicit tier still supported via JSON {"tier":"expert"} to skip classification.
/generate: write a prompt (plain text or JSON with backend/model/system),
read back a one-shot LLM completion. Stateless, no session needed.
/route: write a tier name (worker/expert), read back the resolved
backend+model from OLLIE_TIER_* env vars.
Shutdown() was calling KillSession() which deleted the persisted
JSON files immediately after saveAllSessions() wrote them. Now
Shutdown() closes sessions directly without removing persistence
files, allowing restoreAllSessions() to find them on next start.
Follows the Plan 9 /net/dns pattern: per-fid request-response.
Write JSON request (or plain prefix), write blocks during LLM call,
read returns the completion result. Per-fid state means concurrent
clients get independent request/response pairs.
Also includes the Complete method, findOrCreateCopilot, and noise
stripping helpers in the session package.
Sessions are saved to ~/.local/share/ollie/sessions/active-9p/ on
shutdown and restored on startup. Core auto-saves to SessionsDir
during turns. KillSession removes persisted files.
Closes the major feature gap with the D-Bus daemon.
- ls /s/{id}/proc/ lists detached PIDs
- cat /s/{id}/proc/{pid} reads ring buffer output
- rm /s/{id}/proc/{pid} dismisses the process
- echo detach > /s/{id}/ctl detaches running process
- echo "signal {pid} [TERM|KILL]" > /s/{id}/ctl signals detached process
Walk validates PID exists in detached list before succeeding.
content() holds sess.mu.RLock, then calls CachedListModels which
tried to acquire sess.mu.Lock for cache write — classic RLock/Lock
deadlock. Fix by giving the models cache its own mutex independent
of the session mu.
- Add CachedListModels() with 24h TTL to avoid repeated Models() API calls
- Cache readdir serialized bytes per-fid (rebuild only at offset=0)
- Skip all session file size computation in makeStat (report len=0)
- Short-circuit pathType() for session paths to avoid triggering Stat
- Remove e.Info() call from subdirectory readdir (unused mtime)
- Add monotonic timer to handle() for profiling 9p operations
- Add fcallTypeName() helper
- Fix stubCore for new Detach/SaveSession interface methods
- Add tools-process.md prompt
Before: ls inside a session dir took 1.38s (kiro) / 67ms (openrouter)
After: 182µs regardless of backend (7500x improvement)
Remove a/, p/, sk/, m/, tr/, tmp/, u/, x/, and per-session t/ from the
9P namespace. These are all files on disk that the runtime reads directly
from ~/.config/ollie/ — serving them through 9P added indirection without
value.
What remains:
- /s/ (live sessions: the dynamic state that doesn't exist on disk)
- /backends, /models, /help (synthetic root files)
This brings olliesrv's scope in line with the D-Bus daemon: session
lifecycle, prompt submission, state observation, and streaming output.