The operational model was only rendered for new sessions, not for
restored sessions or /agent reloads. Store baseLayers on the agent
struct and pass them through on rebuild.
Also fix pre-existing test failures caused by DiscoverTools reading
from the live OLLIE_TOOLS_PATH during tests.
DiscoverTools() results have no InputSchema and are invoked via
call_tool, not directly. Sending them to Bedrock as tool definitions
caused ValidationException (inputSchema.json.type must be object).
Now only built-in executors (execute_code, call_tool, pipe) with proper
schemas are registered as backend tools. Discovered scripts remain in
allToolInfos for the preamble surface listing only.
BuildRuntime now appends a compact surface listing (name + one-liner)
to the preamble instead of full tool prompts. Full prompts are
available on-demand via ToolPrompt(name) for the /net/dns pattern.
- DiscoverTools: extracts short description from first content line
- BuildRuntime: appends "# Available Tools" with name + description
- ToolPrompt(name): returns full ollie:prompt for a specific tool
- Add Prompt field to tools.ToolInfo
- Add ExtractPrompt parser for ollie:prompt...ollie:end blocks
- Add DiscoverTools to scan tool scripts directory
- BuildRuntime appends discovered tool prompts to preamble
Tool scripts can now embed their usage documentation directly in
the script header. This replaces the separate tools-*.md prompt
files and ensures documentation stays co-located with implementation.
BuildRuntime now accepts optional baseLayers (variadic strings) that
are prepended to the agent-resolved preamble. This enables the server
to compose: system_prompt + operational_model + environment + agent_prompts.
- config.Config: add SystemPrompt field (path override)
- AgentCoreConfig: add OperationalModel and SystemPrompt fields
- BuildRuntime: prepend baseLayers before agent prompt content
- Remove debug fprintf statements from prompt resolution
Move the read-safe tool result cache from a per-turn local variable
to the agent struct, persisting it across turns. This eliminates
redundant calls to file_read, lsp_*, and memory_recall when the
underlying data has not changed.
The cache is invalidated (cleared entirely) when file_write or
file_edit executes, ensuring stale results are never returned
after mutations.
saveSession() now sets a dirty flag and starts a 2-second timer
instead of immediately serializing and writing the full message
history. For a 50-step turn, this reduces 50 JSON marshals + disk
writes down to ~25 (one every 2s) plus a guaranteed flush at
turn end and on close.
flushSave() is called:
- At end of turn (after setState idle)
- On interrupt
- On Close()
- When the 2s timer fires (if still dirty)
The elevation adapter is now managed by the system service manager
(openrc/systemd), not started on-demand from inside the sandbox.
The on-demand approach was unreliable (needed master token access,
exec chain failures on Gentoo, stale instances on socket).
When the elevated process exits with a non-zero code but produces no
stdout/stderr output, report a cleaner error message instead of the
confusing "Output: " with empty string.
Added PromptEnvExtra to AgentCoreConfig and agent struct. The /agent
command now uses stored PRIME_* vars instead of recomputing locally.
This ensures remote sessions get the correct remote host info on
every prompt rebuild.
Added PromptEnv(cwd) helper that returns PRIME_CWD, PRIME_PLATFORM,
PRIME_IS_GIT_REPO. All callers of BuildRuntime now pass these.
prime script is now a pure template renderer with no detection logic.
Removed ad-hoc PRIME_CWD injection from prompt_resolver.
prompt_resolver: when cmd.Dir cannot be set (remote CWD does not exist
locally), inject PWD=cwd into subprocess env so envsubst in prime sees
the correct working directory.
remote.Server: fetch host_info RPC after connect, expose HostInfo struct
with platform, arch, is_git_repo for the session to pass to prompts.
The /agent command rebuilds the runtime but only passed OLLIE_SESSION_ID.
For remote sessions where cmd.Dir falls through, the prompt scripts need
PWD explicitly set to the session CWD for envsubst in prime.
Dial() now bootstraps ollie-remote on the remote host automatically:
- Computes SHA-256 of the local ollie-remote binary
- Sends a bootstrap script over SSH stdin
- If the remote has a matching cached binary, skips transfer
- Otherwise transfers gzip+base64 encoded binary
- Monitors stderr for OLLIE_LOADER_START/READY signals
- After bootstrap, stdin/stdout switch to JSON-RPC
The local binary is found at ~/bin/ollie-remote (just build output)
or ~/.local/bin/ollie-remote or PATH.
remote.Server.ListTools() now calls the remote via a list_tools RPC
method instead of returning nil. This ensures the model receives
proper tool definitions through the API.
remote.Server.CallTool() now passes the actual tool name (execute_code,
call_tool, pipe) as the RPC method instead of hardcoding execute.
Simplified result handling since resp.Result is already json.RawMessage.
prompt_resolver: guard cmd.Dir with stat check so remote CWDs that
do not exist locally do not cause prompt commands to fail with ENOENT.
server.go: add cancel on all early-return paths to fix go vet
cancel-not-used-on-all-paths warnings.
If the session CWD does not exist locally (remote execution), do not
set cmd.Dir. This prevents fork/exec failures when the CWD only
exists on the remote host.
Previously loadSandboxConfig was called unconditionally, causing
failures on hosts without ~/.config/ollie/sandbox/ even when yolo
mode was enabled. Move the load inside the !Yolo branch.
Package remote provides a tools.Server implementation that forwards
tool calls to an ollie-remote process over SSH via JSON-RPC.
Key components:
- Dial(): opens SSH, launches ollie-remote, verifies with ping
- Server: implements tools.Server, forwards CallTool over RPC
- Decl(): factory compatible with tools.NewDispatcherFunc
- Config: SSH target, CWD, tools path, yolo flag
Integration: swap execute.Decl() with remote.Decl() in session
creation when remote= config is set.
Add ensureElevateAdapter() which probes the adapter socket and starts
elevate-adapter-start if unreachable. Runs in the execute server
process (outside the sandbox) so the adapter starts unsandboxed.
Track Total, Succeeded, Failed counts and FailedCmds in HookResult.
Add Summary() method producing "(N of X hooks run) (K of X failed: cmd)".
Emit hook summary as info event at all lifecycle hook call sites and
on preTool/postTool failure.
All backend constructors now use SharedClient() which returns an
*http.Client backed by a per-host shared *http.Transport. This enables
HTTP/2 multiplexing: multiple sessions targeting the same API host
share a single TLS connection instead of each maintaining their own.
The pool is keyed by "backend:baseURL" so different endpoints get
separate transports while same-host sessions multiplex.
Route() now queries all configured backends for their model lists,
presents them numbered to the classifier, and parses the number.
No more hardcoded OLLIE_ROUTE_MODEL_FAST/POWER env vars.
The management.*.kiro.dev endpoint was slower/less reliable. Switch to
the same q.<region>.amazonaws.com endpoint that kiro-cli uses, deriving
the region from the profile ARN or runtime endpoint.
Models() now caches at the backend level (shared across sessions) with
a 24h TTL, eliminating repeated expensive HTTP calls to AWS.
The sqliteKiroAuth.load() now caches token reads for 60s, avoiding
shelling out to sqlite3 on every API call (previously 3x per Models
fetch).
Rewrite executeElevated to use the same select/detachCh pattern as
executeWithStdin. When both elevated and detach are set, the process
is immediately backgrounded into the detach registry with streaming
output captured in the ring buffer.
Also adds the detach field to the execute_code JSON schema description.
When detach: true is set on a CodeStep, the process is immediately
backgrounded after start. Its stdout/stderr are captured in a 64KB
ring buffer accessible via GetDetachedOutput. The agent can then
inspect and manage the process via process_list/process_output tools.
After detach, cmd.WaitDelay was still 1s, causing Go exec to
kill the process after context cancellation + 1s delay. Clear
both cmd.Cancel and cmd.WaitDelay in the detach path.
When a detached process exits, its output (last 2KB of ring buffer)
is queued as a prompt wrapped in <detached-process-result> tags.
The agent sees it on its next turn (or immediately if idle via Queue).
- InjectSystemEvent(content) added to Core interface
- SetOnExit(fn) added to execute.Server for external hook wiring
Adds Detach, ListDetached, SignalDetached, GetDetachedOutput,
DismissDetached to the Core interface. Implemented on agent struct
via interface type assertions to the execute server.
Also adds ListDetachedRaw() to execute.Server for cross-package
consumption without import cycles.
Allows the user to detach a running process from the agent mid-execution.
The process continues running; output flows to a 64KB ring buffer.
Detached processes can be listed, signaled (TERM/KILL), and dismissed.
- DetachedProcess struct with ring buffer, signal, output methods
- Server.Detach() signals the currently executing process to detach
- Execute() rewritten: cmd.Start() + select on wait/ctx/detach
- cleanupDetached() on Close() sends SIGTERM to all
- OnDetach/OnExit hooks for integration with D-Bus layer
OLLIE_SKILLS_PATH, OLLIE_AGENTS_PATH, OLLIE_PROMPTS_PATH can be
colon-separated (like PATH). Both WrapCommand and checkPath now
split expanded values on ":" so each component is granted access
individually.
- Add Backend/Model fields to PersistedSession for full restore metadata
- Add saveToFull() that includes backend/model in persisted state
- Add exported LoadPersistedSession(path) helper
- Add SaveSession(path) to Core interface, implemented on agent struct
- Existing saveTo() preserved as backward-compatible wrapper
- Remove IsSocial guard from sqliteKiroAuth.ProfileARN(); the Kiro API
now requires profileArn on all requests including personal accounts
- Add OLLIE_KIRO_PROFILE_ARN env var for static token auth
- Add repeated error detection (3x identical error triggers corrective nudge)
- Include expected format in tool dispatch error messages