Drop formatEvent "newline" case (event no longer emitted). Reset
assistantStarted on "user" event instead so chained turns get the
"assistant: " prefix correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename batchJob.status → .state; update all references
- Add done chan struct{} to batchJob, closed on terminal state
- Add statewait file to b/<id>/: blocks until state leaves "running"
- Add CurrentWaitValue/Wait methods to BatchJobStore
- Extend Topen handler to snapshot waitBase for b/ wait files
- Extend Tread handler for b/ to serve statewait with 5s timeout/retry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FUSE puts blocked processes in D state (uninterruptible sleep) waiting
for the read to return. SIGINT cannot interrupt D-state, so Ctrl+C has
no effect even after Tflush cancels the goroutine. A 5s timeout causes
the read to return periodically, letting FUSE unblock the client process
and deliver any pending signals.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two fixes:
- *wait files are one-shot per open: offset > 0 returns EOF immediately
instead of blocking on the next state transition (was consuming two
transitions per cat invocation)
- Tflush now cancels the in-flight request goroutine via per-tag contexts,
so Ctrl+C on a blocking cat properly unblocks the read
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous design read the current value at read time. If a state
change fired between one cat returning and the next cat opening, the
new cat would see the changed value as current and wait forever for
the next change.
Fix: snapshot the baseline in the fid at Topen time. Each read blocks
until the value changes from the open-time snapshot, then updates the
fid's baseline for the next read. The race window is closed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Serve now dispatches each 9P request to its own goroutine with a shared
response channel, so blocking reads no longer stall the serve loop.
*wait files are handled via SessionFileStore.Wait(connCtx, name), which
merges the connection context with the session context via
context.AfterFunc — the wait unblocks on either connection close or
session kill, preventing goroutine leaks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
*wait files block on read until the corresponding value changes, then
return the new value. enqueue/dequeue renamed to fifo.in/fifo.out.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The markdown planning mechanism has been removed. pl/ no longer needs
to exist as a 9P directory.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add PluginStore backed by scripts/x/, exposed read-only at x/ in the
9P filesystem. Remove elevator field and elevation.Detect(); update
execute.Decl() call sites to drop the now-removed elevator parameter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- createSession parses env.NAME=VALUE from spec, passes sessionEnv to
BuildAgentEnv for MCP expansion and core.SetEnv for execute subprocesses
- Remove /env root file (was daemon-global and readable)
- No writable s/{sid}/env file needed; spec is the injection point
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace inline ensureEnv() with env.EnsureDefaults() from ollie/pkg/env
- Serve ollie/env as a readable file containing the daemon's full process env
- Remove extraEnv/InitialEnv session-spec mechanism (no longer needed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add u/ as a top-level namespace backed by scripts/u/
- Expose b/q and b/sched as script files under b/
- Remove q, sched, optimize from s/ (sessionStoreFiles)
- Update s/ script read path to scripts/s/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eliminates the explicit script name list — any entry in sessionStoreFiles
beyond "new" and "idx" is automatically served from disk.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add s/sh, s/job, s/q, s/sched, s/ls, and s/kill as file-backed entries
in the session store, all served from ~/.config/ollie/scripts/. Introduce
sessionStoreFiles to centralize permissions and drive routing, mode, and
stat length — replacing per-entry switch cases and OR chains in server.go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tailing works well for append-only logs but is fundamentally racy for
files that get overwritten: fast state changes collapse into a single
truncation signal, so tail reads the wrong (already-stale) value.
Remove mutableFile, mutableVers, trackMutable, and the per-fid readBuf
entirely. Only chat retains append-only stat reporting (Qid.Vers +
Length) for tail -f. All other session files (state, usage, backend,
model, agent, cwd) are plain poll-on-read files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Expose generation parameters (maxTokens, temperature, frequencyPenalty,
presencePenalty) as a readable/writable 9P file. Read returns all four
keys as key=value lines; empty value means unset (API default). Write
parses the same format, updating only the keys present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace hard-coded ~/.config/ollie and ~/.local/share/ollie paths
with paths.CfgDir() and paths.DataDir() to support OLLIE_CFG_PATH
and OLLIE_DATA_PATH env vars.
Replaces /tmp/ollie per-session scratch space with a 9P-served tmp/
directory backed by OLLIE_TMP_PATH (~/.local/share/ollie/tmp by default).
Markers are now global, hash-addressed by absolute file path, and shared
across all sessions. OLLIE_TMP_PATH is always set by ensureEnv().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
flags after the subcommand (e.g. start -tcp :564) were silently ignored
because flag.Parse() stopped at the first non-flag argument. parse
os.Args[2:] after extracting the subcommand from os.Args[1].
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- -tcp <addr> flag on start/fgstart listens on TCP in addition to the Unix socket
- mount <address> [mountpoint] mounts a remote olliesrv namespace locally via 9pfuse
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Capture chatOffset after the user event is appended rather than
before Submit, so tail -c +$((offset+1)) yields only the model
response for that turn.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Records the byte position of chat EOF immediately before each prompt
is submitted. Clients can read offset after a turn completes and use
tail -c +$((offset+1)) to extract just the new output without needing
a dedicated reply file.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On failure, result is empty and only status carries the error.
Callers (subagent_spawn, oq) now always have a useful value in
result regardless of success or failure.
executeJob was only capturing 'assistant' events from core.Submit.
Backend errors emit an 'error' event that was silently dropped,
causing jobs with nonexistent models to show status=done with empty
result instead of status=failed.
- Add b/ to filesystem layout (job spec, status, result, usage, ctxsz)
- Add BatchStore to backing stores table
- Add Batch jobs section with submit/poll/remove examples and oq reference
- Remove s/{id}/reply from layout
Introduces b/ as a first-class 9P namespace alongside s/. Writing to
b/new creates one or more ephemeral agent jobs (parallel=N suffix -0..-N)
each running the same prompt in an independent agentCore with no
persistent session state.
Per-job files: spec, status, result, usage, ctxsz.
BatchStore/BatchJobStore mirror SessionStore/SessionFileStore.
rm -r b/{id} cancels and removes the job.
Also removes s/{id}/reply: b/{id}/result is the purpose-built
replacement for one-shot prompt->reply use cases.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>