Commit Graph

51 Commits

Author SHA1 Message Date
Levi Neely 818ccf2632 rename workdir to cwd
Rename the user-facing 9P file and session key from "workdir" to
"cwd" for consistency with the /cwd command.
2026-04-13 15:51:49 +02:00
Levi Neely b048aac109 9p: reject unrecognized ctl commands
ctl now validates the first word of input against a closed set of
known commands. Unrecognized input returns an error instead of being
silently forwarded as a prompt to the agent.
2026-04-13 15:44:14 +02:00
Levi Neely fdcf048a70 name= support for ollie/s/new; wip mutable state tailing 2026-04-13 15:23:04 +02:00
Levi Neely 0a4ca8a869 9p: add agents dir, backends, help, plan rm; refactor readSlice 2026-04-13 14:45:17 +02:00
Levi Neely fc5443e314 9p: session rename via wstat, ctl kill/rn, connection tracking
- Support mv on session directories (wstat rename)
- Track connections globally for fid path rewriting on rename
- Add kill and rn <name> to ctl handler
- Append rename notification to chat log
- Update README with rename and ctl docs
2026-04-13 14:25:53 +02:00
Levi Neely 368d1a9ba0 9p: accept empty values in s/new, fix docs to rm -r 2026-04-13 13:56:52 +02:00
Levi Neely e5a20ecf8a 9p: revert ctl to async (fire-and-forget) 2026-04-13 13:42:06 +02:00
Levi Neely 69e5bd18d9 9p: make ctl sync, guard non-stop commands when agent is running
ctl is no longer in the async bucket. stop is always instant.
Slash commands forwarded via Submit are synchronous for recognized
commands. Unrecognized input is rejected with Rerror when the
agent is running to prevent accidentally starting an agent turn.
2026-04-13 13:41:30 +02:00
Levi Neely 81f7379fb6 9p: split clunk into sync (Rerror) and async (fire-and-forget)
prompt, enqueue, ctl writes run async — they may block for an
entire agent turn and don't benefit from Rerror. Everything else
(disk I/O, state mutations, s/new) runs synchronously so errors
surface as Rerror without holding the connection.
2026-04-13 13:37:41 +02:00
Levi Neely d326ca88f7 9p: synchronous clunk with Rerror, guard state writes
handleWrite returns error; clunk runs it synchronously and
returns Rerror on failure. Writes to backend, agent, model
reject with Rerror when the agent is running. Prompt writes
remain async (they block for the full agent turn). Disk I/O
errors now surface as Rerror instead of stderr logging.
2026-04-13 13:34:13 +02:00
Levi Neely 3ff2454dcb 9p: session ctl: remove interrupt alias, drop / prefix for commands
stop is the only out-of-band signal. Everything else is forwarded
as a slash command (/ prepended automatically), so 'echo compact > ctl'
works directly.
2026-04-13 13:23:49 +02:00
Levi Neely 99e001f326 9p: reject mkdir (Tcreate with DMDIR) on flat directories 2026-04-13 13:17:32 +02:00
Levi Neely 9a0aaa67bc 9p: replace root ctl with s/new and rm s/{sid}
- s/new: read returns KV template (workdir, backend, model, agent);
  write creates a session from KV pairs.
- rm s/{sid}: kills the session (Tremove on session directory).
- Remove root ctl file entirely.
2026-04-13 13:15:50 +02:00
Levi Neely 56f9daf13c 9p: implement Tremove for /p, /sk, /t
Allows rm on files under the prompts, skills, and tools directories.
Skills remove the entire skill directory (including SKILL.md).
Other paths still return 'remove not supported'.
2026-04-13 13:08:15 +02:00
Levi Neely 1188706a3b filePlanBackend: include sed example in CreatePlan response 2026-04-13 13:05:07 +02:00
Levi Neely dffd2e1ea6 plan: timestamp+uid filenames, __todo/__wip/__done lifecycle
- Replace {sid} with YYYYMMDDThhmmss_{uid8} in plan filenames for
  uniqueness independent of session identity
- Initial status is __todo (was __wip)
- Instruct bot to transition __todo → __wip → __done
- Remove sid field from filePlanBackend
2026-04-13 12:01:33 +02:00
Levi Neely e2e7f594ca flat planning repo built-in 2026-04-13 11:40:52 +02:00
Levi Neely 4ae91a1668 usage/ctxsz: separate billed tokens from context size
- Rename Core.Usage() to Core.CtxSz() (estimated context size)
- New Core.Usage() returns billed token counts (in, out, requests)
- 9P: add ctxsz file, usage file now returns billed tokens
- /context command now shows context size summary
- Emacs mode-line reads ctxsz instead of usage
2026-04-13 10:45:45 +02:00
Levi Neely 0586e94672 9p: make /p createable, fix /p dir mode to 0755, update README
- Add /p to create handler (same pattern as /t and /sk)
- Use 0755 for /p directory (prompts aren't executable)
- Update README: sk/ is now r/w
2026-04-13 10:28:45 +02:00
Levi Neely 7b3e159ac0 9p: add create support, writable skills, update tools path
- Route Tcreate to new create handler for /t and /sk
- Add skill file write support (write to SKILL.md in skill dir)
- Make /sk files writable (0666), /t files/dir 0777
- Update default tools path to ~/.config/ollie/tools
2026-04-13 10:25:15 +02:00
Levi Neely 173ab613f5 p9: stop truncating tool result output in chat
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 20:43:02 +02:00
Levi Neely 00dfbaeb83 p9: remove "= " prefix from tool result events
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 20:39:56 +02:00
Levi Neely 13e8cc75a6 p9: wire file tools server into session dispatcher
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 20:19:03 +02:00
Levi Neely 386b4f9ec8 9p: remove routing logic from prompt handler
Submit on core now decides whether to inject or start a new turn.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 22:25:42 +02:00
Levi Neely fa35f4bf5f fix reply 2026-04-11 18:06:32 +02:00
Levi Neely 399ed5ec48 p9: drop shadowed state/reply/name fields from session
State, reply, backendName, agentName, and modelName are now read
directly through Core. The optimistic lock/rollback dance around
backend/agent/model writes is removed — Core owns that truth.

replyVers is kept in session as a 9p transport concern (Qid.Vers
for polling clients).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:55:33 +02:00
Levi Neely cd0818f1c9 handle user event in formatEvent; remove manual appendChat for prompt
The 9p prompt handler no longer directly appends "user: ..." to the chat
log — that now arrives via the "user" event emitted by core's Submit,
which also fires for FIFO-drained queued prompts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:37:12 +02:00
Levi Neely 8070238390 p9: queue steps via agent.Core.Queue; yield message on plan
- queuePlanBackend now holds agent.Core and calls Queue() directly
  instead of writing to a filesystem path (enqueue is a virtual file)
- fallback.core wired after NewAgentCore in createSession
- Returns yield message so agent stops after planning and lets the
  queue drive execution step by step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:24:47 +02:00
Levi Neely 8fa4a8e101 p9: keep queuePlanBackend local; minor comment polish
Tool behavior with a hard 9P filesystem dependency belongs here, not in
core. The extension point (tools.PlanBackend + WithFallbackPlanBackend)
remains in core for other consumers to implement against.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:06:45 +02:00
Levi Neely b4f782b484 p9: wire queue-based plan backend as reasoning_plan fallback
When no task_create MCP tool is registered, reasoning_plan steps are
enqueued to the session's enqueue file in topological order. Placeholder
IDs (q1, q2, …) are returned so the agent can reference steps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 16:58:41 +02:00
Levi Neely db7a1aa42d sessions: require workdir on new session creation
No sensible default exists server-side. Clients must pass workdir=<path>
explicitly. The TUI uses $PWD of the ollie process; shell users should
pass workdir=$PWD or use a wrapper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 16:43:18 +02:00
Levi Neely 5176c0595c tools: remove file server registration
file_read and file_write removed from core; drop the file.Decl entry
from the dispatcher and the import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 16:11:54 +02:00
Levi Neely 5b68e0311a p9: remove dead sess.workdir field
Now that reads go through sess.core.WorkDir(), the cached workdir field
on the session struct serves no purpose. Remove it and the write that
kept it in sync.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 14:25:08 +02:00
Levi Neely 3f873f0c55 p9: read workdir from core instead of cached session field
sess.workdir is only updated via the 9P write handler, so changes made
through the agent core (e.g. /cwd via ctl or prompt) were invisible to
readers. Use sess.core.WorkDir() to always reflect the live value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 14:24:23 +02:00
Levi Neely 071add996c p9: wire SetWorkDir into workdir write handler
Validate the path and propagate the change to the agent core (which
updates the execute server and rebuilds the system prompt) before
updating the session's cached workdir field. Return early on error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 14:21:37 +02:00
Levi Neely 68d6d284f4 p9: add mcp endpoint to session directory
Exposes ollie/s/{sid}/mcp as a read-only file that returns all registered
tool servers and their tools, grouped by server name. Backed by the new
Core.ListServers() method.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 11:31:46 +02:00
Levi Neely 75fc1566c0 p9: split prompt.fifo into enqueue (write) and dequeue (read)
Replaces the r/w prompt.fifo with two separate endpoints: enqueue
(write-only, queues a prompt) and dequeue (read-only, pops the next
queued prompt). Also fixes a bug where cat's trailing EOF read at
non-zero offset would silently consume and discard the next queued item.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 10:03:46 +02:00
Levi Neely f22c00c276 p9: add usage and models endpoints to session directory 2026-04-10 20:37:30 +02:00
Levi Neely 0e434750d0 p9: prompt interrupts if busy; add prompt.fifo for queue 2026-04-10 20:11:26 +02:00
Levi Neely 1d5ad91bf0 p9: rename prompts/ to p/ in filesystem 2026-04-10 19:17:00 +02:00
Levi Neely 8bc8977fbf p9: expose tools as /t/ directory (r/w from ToolsPath)
Same pattern as prompts — reads and writes go directly to disk.
Files are 0755 on write since they're executable scripts.
2026-04-10 19:16:36 +02:00
Levi Neely d674f4b6c2 p9: rename skills/ to sk/ in filesystem and tool scripts 2026-04-10 19:14:59 +02:00
Levi Neely 9122f7477e p9: expose skills/ directory and add skill tool scripts
Serve /skills/<name>.md via pkg/skills (read-only, refreshes from disk
on each read). Add discover_skill.sh and load_skill.sh tool scripts
that read from the 9P mount.
2026-04-10 19:10:53 +02:00
Levi Neely 944445fd4d p9: expose prompts/ directory for runtime prompt editing
Add /prompts/ to the 9P filesystem, backed by DefaultPromptsDir().
Reads serve file contents from disk; writes persist back to disk.
Edits take effect on the next agent session without restart.
2026-04-10 18:45:06 +02:00
Levi Neely f100e5d689 p9: add workdir support to sessions
Sessions now accept workdir= at creation time:
  echo "new workdir=/home/lkn/src/myproject" > ctl

workdir is exposed as a r/w file in each session directory. Writing
to it updates the stored value (takes effect on next /agent switch,
since the execute server is constructed with the workdir at creation).

execute.Decl(workdir) and BuildAgentEnv(..., workdir) are wired
through so the sandbox and system prompt both use the correct path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 09:04:32 +02:00
Levi Neely d9a4ec3255 p9: introduce s/ session directory; use nanosecond session IDs
Sessions are now nested under s/ instead of the root, making it
straightforward to count active sessions and find newly created ones
by offset:

  n=$(ls s/ | wc -l)
  echo "new agent=foo" > ctl
  sid=$(ls s/ | sort | sed -n "$((n+1))p")

Session IDs are now Unix nanosecond timestamps (from ollie's updated
NewSessionID), so ls s/ | sort gives strict creation order. The s/
directory is a stable listing surface; ctl remains at the root for
control operations.

All path parsing updated throughout: pathType, readDir, makeStat,
handleWrite, readChat, readReply, readFile. README updated to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 08:51:07 +02:00
Levi Neely f97b9d355c Use ollie agent helpers and tool Decls; drop local duplicates
Replace local agentConfigPath, newSessionID, home paths with
agent.AgentConfigPath, agent.NewSessionID, agent.DefaultAgentsDir,
agent.DefaultSessionsDir. Replace dispatcher wiring with
tools.NewDispatcherFunc using execute.Decl and file.Decl.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 08:28:07 +02:00
Levi Neely 2c41e68696 Add reply file for agent chaining
reply holds only the clean assistant text from the most recently
completed turn. It is written atomically when Submit returns and cleared
(as a documented side-effect) when a new prompt is submitted. Stat
reports the real byte length and bumps Qid.Vers on each change, so
polling via stat size > 0 is the intended signal that a reply is ready.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 02:10:36 +02:00
Levi Neely 34e3119533 Switch new command to key=value options; add model option
"new" in root ctl now accepts optional key=value pairs in any order:
backend=<name>, model=<name>, agent=<name>. All are optional; omitting
any uses the default. Replaces the old positional backend/agent args.
Unknown keys and malformed entries are rejected with a clear error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 01:52:15 +02:00
Levi Neely 19fac99a3d Add model r/w endpoint to session
Exposes the active model name as a readable/writable file. Initialized
from be.Model() at session creation. Writes submit "/model <name>" via
the agent core and update modelName optimistically, rolling back on an
error event.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 01:49:20 +02:00