ToolServer is vital infrastructure — it must never be nil. If the
initial dial fails, retry via ProcessKeeper (which respawns
ollie-remote). If still unavailable, fail agent creation with a
clear error asking the user to try again.
Reverted the nil-check band-aid in turn.go — ToolServer is now
guaranteed non-nil for any running agent.
Prevents nil pointer dereference when a newly created agent's
tool server connection failed to establish (keeper.Dial returned
nil, or session was restored with a dead toolsConn).
Models that ignore native tool schemas (via the API tools parameter)
now see full tool documentation in-context: usage docs, argument
definitions, examples, and the JSON schema.
This is appended as a '# Tool Documentation' section in the system
prompt, below the compact '# Available Tools' listing.
The agent's 12-char hex uname was not persisted. On restore,
fs/persist.go incorrectly used ps.ID (session UUID) as the uname,
making OLLIE_UNAME identical to OLLIE_SESSION_ID.
Fix: add Uname field to PersistedAgent, persist ag.id in SaveFull,
restore from ps.Uname (falls back to nextUname for old files).
When a streaming tool completes, emit a final empty-Content event so the
log handler always closes the markdown source fence. In the handler,
emit [[[end]]] directly instead of a blank line, so the GUI block parser
transitions back to BlockStart regardless of what follows.
ollie-9p computes its namespace path from $USER and $DISPLAY via
client.Namespace(). When run inside the sandboxed shell, USER was not
guaranteed to be in the environment, producing /tmp/ns..:0/ollie.
Fix: explicitly inject USER into envExtra in SetSessionEnv (alongside
OLLIE_SESSION_ID and OLLIE_UNAME). Also export the computed NAMESPACE
to cmd.Env so ollie-9p can use it directly without recomputing.
Previously the agent loop used a frozen Tools slice from BuildRuntime.
When tool_load promoted a tool, it was added to the registry but the
runtime's Tools slice was never updated — the LLM never saw the new
tool's schema until a session rebuild.
Fix: on each turn, call ToolServer.ListTools() to get the current set
of built-in + dynamically loaded tools, then convert to backend.Tool.
This makes tool_load behave identically to a built-in: the schema is
injected into the tool definitions on the very next turn.