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>
This commit is contained in:
Levi Neely 2026-04-10 01:52:15 +02:00
parent 2d120f9bdf
commit 34e3119533
2 changed files with 34 additions and 11 deletions

View File

@ -6,7 +6,7 @@ A 9P server that exposes [ollie](../ollie) agent sessions as a virtual filesyste
```
ollie/
ctl write: "new [backend] [agent]" | "kill <session-id>"
ctl write: "new [backend=x] [model=x] [agent=x]" | "kill <session-id>"
<session-id>/
prompt write: submit a prompt to the agent
chat read: cumulative conversation history
@ -41,11 +41,15 @@ The server listens on a Unix socket in the Plan 9 namespace (`$NAMESPACE/ollie`)
### Create a session
```sh
echo new > ~/mnt/ollie/ctl # default backend and agent
echo "new ollama" > ~/mnt/ollie/ctl # specific backend
echo "new ollama myagent" > ~/mnt/ollie/ctl # specific backend and agent
echo new > ~/mnt/ollie/ctl # all defaults
echo "new backend=ollama" > ~/mnt/ollie/ctl # specific backend
echo "new backend=ollama model=qwen3:8b" > ~/mnt/ollie/ctl # backend + model
echo "new backend=ollama model=qwen3:8b agent=myagent" > ~/mnt/ollie/ctl
```
All options are optional and can be specified in any order. Unrecognised keys are rejected.
Valid keys: `backend`, `model`, `agent`.
A new session directory appears under the mount point named by timestamp + random suffix (e.g. `20260410-014002-ba70fc`).
### Send a prompt

View File

@ -590,16 +590,31 @@ func (s *Server) handleRootCtl(input string) {
}
}
// createSession parses key=value options and starts a new agent session.
// Recognised keys: backend, model, agent. Unknown keys are rejected.
// Example: new backend=ollama model=qwen3:8b agent=myagent
func (s *Server) createSession(args []string) error {
home, _ := os.UserHomeDir()
backendOverride := ""
modelOverride := ""
agentName := "default"
if len(args) > 0 {
backendOverride = args[0]
}
if len(args) > 1 {
agentName = args[1]
for _, arg := range args {
k, v, ok := strings.Cut(arg, "=")
if !ok || v == "" {
return fmt.Errorf("invalid option %q (expected key=value)", arg)
}
switch k {
case "backend":
backendOverride = v
case "model":
modelOverride = v
case "agent":
agentName = v
default:
return fmt.Errorf("unknown option %q (valid: backend, model, agent)", k)
}
}
var (
@ -618,6 +633,10 @@ func (s *Server) createSession(args []string) error {
return fmt.Errorf("backend: %w", err)
}
if modelOverride != "" {
be.SetModel(modelOverride)
}
if err := os.MkdirAll(s.sessionsDir, 0700); err != nil {
return fmt.Errorf("sessions dir: %w", err)
}
@ -664,8 +683,8 @@ func (s *Server) createSession(args []string) error {
s.sessions[sessID] = sess
s.mu.Unlock()
fmt.Fprintf(os.Stderr, "olliesrv: new session %s (backend=%s agent=%s)\n",
sessID, sess.backendName, agentName)
fmt.Fprintf(os.Stderr, "olliesrv: new session %s (backend=%s model=%s agent=%s)\n",
sessID, sess.backendName, sess.modelName, agentName)
return nil
}