The OutputFormat function was set once at runtime build time and stored
in ag.runtime.OutputFormat. When tools were dynamically loaded via
tool_load, the tool definitions were refreshed but the OutputFormat
lookup still used the stale runtime version that didn't know about
newly loaded tools.
Build the outputFormats map from the fresh tool list on each turn,
just like we already do for the tool definitions. This ensures
outputFormat (e.g., 'diff' for file_edit) is available immediately
after loading a tool.
Bedrock rejects requests containing toolUse/toolResult content blocks
without a corresponding toolConfig. When agents have zero tools loaded
(e.g., autoload disabled/failed), conversation history containing tool
interactions would cause 'toolConfig field must be defined' errors.
Add kiroStripToolBlocks() to remove tool-related content from messages
when len(tools) == 0, allowing requests to proceed without tool
definitions.
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.
ProcessKeeper maintains a running ollie-remote process and respawns
it on failure. Multiple agents Dial() the same keeper to get
independent connections. If the process dies, the next Dial()
triggers a respawn (up to 3 attempts with backoff).
All session creation and restore paths now use ProcessKeeper.
Kill/Shutdown close the keeper (which closes the current process).
This fixes 'connection closed' errors persisting indefinitely
after ollie-remote crashes — the next tool call respawns it.
- Load ~/.config/ollie/env and set path defaults at startup (same as olliesrv)
- Remove hard exit on missing OLLIE_SESSION_ID; accept it from inherited env
or via set_env RPC (SSH bootstrap path)
- Wire OnEnvSet to propagate OLLIE_SESSION_ID into tool registry and process
env when it arrives dynamically; same for OLLIE_UNAME
ollie-remote was sending 'agent-<pid>' as the session identity to the
elevate broker, which never matches any real session. Now reads
OLLIE_SESSION_ID from inherited environment (set by the parent
olliesrv process) so the broker can validate the session exists.
Lookup() was keyed only by display name, but the elevate broker
passes OLLIE_SESSION_ID (the immutable UUID). Added fallback to
search by sess.id when the name-based lookup misses.
This fixes 'elevate-broker: denied (session not found)' for all
elevated commands.
Agent directories now have proper ownership: UID is the agent's
immutable 12-char hex identity, GID is 'agent'. Consistent with
session directories which use UID(s.Uname()).
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).
Add 'kill' command to agent ctl (removes agent from session).
Add Session.RemoveAgent() method.
Remove activeAgentID field, Agent(), SetActiveAgent, and dead
WaitChange — 'active agent' is a GUI concept, not a server one.
All callers updated to iterate Agents() or use FindAgent(id).
Remove hardcoded ~/.config/ollie/tools path and XXX hack.
Local ollie-remote now inherits OLLIE_TOOLS_PATH from the environment
via os.Environ(), same as remote bootstrap sets it explicitly.
ToolsPath() reads OLLIE_TOOLS_PATH with fallback to ~/.config/ollie/tools.
Tools added to the directory are picked up immediately on next
tool_load — no restart needed.
Removed dead appendEnvVar helper.
Supports C-a, C-e, C-u, C-k, M-b, M-f, arrow keys, etc.
Sent prompts and slash commands are added to readline history
so up-arrow recalls previous inputs.
o kill: kills the active session.
Prompt REPL now supports slash commands:
/stop, /compact, /kill, /clear, /model X, /backend X, /cwd X, /help
Slash commands are handled locally without sending to the agent.
o tui: launches a 4-pane tmux layout with:
- chat stream (left, large)
- statewait monitor (top-right, reactive)
- spare shell with session/agent exported (bottom-right)
- prompt REPL (bottom, full width)
o stop: shorthand for 'o ctl stop' to interrupt a running agent.
Nodes in the 9P namespace can now declare alternate names (Aliases)
that resolve during Twalk but are invisible in directory listings.
Session dirs alias their immutable RunnableID(), agent dirs alias
their ID(). Clients can use session/{uuid}/agent/{uuid}/... paths
that remain valid across renames.
Changes:
- fs/fsnode.go: Add Aliases []string field, Alias() NodeOption
- fs/builder.go: findChild checks aliases via matchAlias helper
- fs/sessionfiles.go: Session dirs get Alias(s.RunnableID())
- fs/agentfiles.go: Agent dirs get Alias(a.ID())
- fs/spec.go: Add /aliases file (read-only alias→path table)
- fs/rootfiles.go: readAliases handler
- fs/lifecycle.go: buildIndex includes immutable ID in session/idx
- doc/edsl.md: Document Aliases field and behavior
- prompts: Update session/idx format documentation
The KDE GUI submodule now uses immutable IDs in all 9P paths,
fixing disconnected indicators after session rename.
For Request-mode files (session/new, complete, generate, route), the
write handler fires immediately during Twrite. On clunk, the server
was also flushing the (empty) writeBuf to Write(), causing the handler
to fire a second time. This created duplicate sessions.
Skip the clunk-time writeBuf flush for Request-mode files since they
already handle writes inline during Twrite.