Commit Graph

72 Commits

Author SHA1 Message Date
ollie 2c36c023aa execute_code -> shell: simplify to single bash command, remove steps/parallel/detach/language 2026-07-28 23:03:31 +02:00
ollie 1b05433a5b strip execute_code to bash-only; remove language detection; run promoted tools directly 2026-07-28 22:59:44 +02:00
ollie 6bd77276ee remove call_tool and pipe implementations 2026-07-28 22:51:47 +02:00
ollie b26bd7f580 remove allowExecutors from config, execute server, and agent JSONs 2026-07-28 22:39:17 +02:00
ollie dce77f0b8d merge registry into execute: one server, one routing table, deterministic arg ordering 2026-07-28 22:08:44 +02:00
ollie f08e0abdf0 core: support dynamic tool registration 2026-07-28 14:13:08 +02:00
Levi Neely 75f11a7dc9 enforce 128KB tool result ceiling unconditionally
The tool result truncation had two bypasses:

1. Error results were exempt (!isErr condition) — a command returning
   output in its error message could flood the context with megabytes
   of untruncated data.

2. The streaming callback emitted chunks to the event handler (and
   thus D-Bus signals) with no size check, flooding the bus even
   when the final stored result would be truncated.

Fix:
- Remove the configurable ToolResultMaxBytes field; use the constant
  defaultToolResultMaxBytes (128KB) unconditionally for all results
  regardless of success/error status.
- Cap the streaming callback at 128KB so chunks stop being emitted
  once the ceiling is reached.
- Cap output embedded in execute server error messages to 8KB as
  defense in depth.
2026-07-27 13:02:45 +02:00
Levi Neely c418148dc8 elevate: integrated elevation broker package
Core elevation broker that replaces the superpowerd adapter.
Handles command execution outside the sandbox with human-in-the-loop
approval via desktop notifications.

- Policy store: YAML-backed global policy + in-memory session policies
- Request lifecycle: 300s TTL, approve/deny/persist resolution
- Command execution: bash -c with caller env/cwd, streaming d/x frames
- SO_PEERCRED for caller identification
- NotifyFunc callback for UI integration (D-Bus, 9P, etc.)
2026-07-27 10:44:18 +02:00
ollie 69b90de68f remove ensureElevateAdapter
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).
2026-07-21 11:48:53 +02:00
ollie edc96cc841 executeElevated: improve error message when exit non-zero with no output
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.
2026-07-21 07:28:21 +02:00
ollie 5fc7bd816e streaming: emit partial tool output via context callback 2026-07-19 21:06:13 +02:00
ollie 160e285e68 fix: prompt resolution for remote sessions + vet context leaks
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.
2026-07-19 19:43:12 +02:00
ollie adb90e4e7c execute: skip sandbox config loading when Yolo is set
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.
2026-07-19 18:44:25 +02:00
ollie 519869a003 execute: ensure elevate adapter is running before elevated calls
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.
2026-07-19 11:33:34 +02:00
ollie 42361e6505 execute: support elevated+detach combination
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.
2026-07-18 00:16:20 +02:00
ollie c1124b588d execute: add detach field for autonomous background processes
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.
2026-07-17 23:28:14 +02:00
Levi Neely b6d0653d0b execute: fix detached process killed by WaitDelay
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.
2026-07-17 22:15:05 +02:00
Levi Neely f8ed2189f1 agent: inject detached process output on exit
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
2026-07-17 22:07:26 +02:00
Levi Neely c0a52a8031 execute: timeout=0 means no timeout
Allows long-running daemons to be started without a deadline.
timeout < 0 still defaults to 30s. Schema descriptions updated.
2026-07-17 17:06:12 +02:00
Levi Neely 5df603a9e3 agent: expose detach methods on Core interface
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.
2026-07-17 16:49:29 +02:00
Levi Neely 16d057741c execute: add process detach mechanism
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
2026-07-17 16:43:07 +02:00
ollie 817814ab62 Ensure execute processes terminate promptly 2026-07-16 19:58:15 +02:00
Levi Neely fd20070294 refactor: remove 9P mount logic from core execute server
Moved all 9P FUSE mount code from core to 9p module using lifecycle hooks.

Changes:
- Removed 9P-specific fields (mountProc, mountPath, mountEnabled) from execute.Server
- Removed WithMount(), MountPath(), startMount(), remountIfStale() functions
- Added lifecycle hooks: OnPreDispatch, OnClose, OnEnvSet with corresponding options
- Updated SetEnv(), Close(), and Dispatch() to call hooks instead of hardcoded mount logic
- Fixed tool descriptions to use $OLLIE_TOOLS_PATH instead of 9P-specific $OLLIE/s/$SID/t paths
- Removed unused execute import from agent/commands.go

The core execute server is now harness-agnostic.
2026-07-08 15:55:10 +02:00
ollie 8e7dd60a8b agent: remove $OLLIE mount dependency from core
- Add ListHandlers map to AgentCoreConfig/agent struct; /skills and /tools
  dispatch through it instead of reading local paths directly
- Add ReadPlanStep to AgentCoreConfig; wired by 9p/ directly from sess.plan
- Export NextUncheckedStep([]byte) as pure helper
- Fix prependOlliePath to use OLLIE_CFG_PATH/scripts/x/ instead of $OLLIE/x/
- Add OLLIE_CFG_PATH to EnsureDefaults and managed env var list
2026-06-16 12:30:36 +02:00
Levi Neely 2b914ce150 codewhisperer: image content block support in user messages and tool results 2026-05-25 23:14:40 +02:00
Levi Neely 82ac183357 add OLLIE_DEFAULT_AGENT support and update agent commands 2026-05-21 12:33:18 +02:00
Levi Neely 84533aed1a sandbox: decouple env resolution from process; plan9 namespace discovery 2026-05-21 11:50:37 +02:00
Levi Neely 4188d5946b execute: transparent per-session mount recovery on stale FUSE 2026-05-21 08:49:36 +02:00
Levi Neely 2bbafb51ec execute: use session OLLIE for PATH prepend, keep ollie-9p-mount on $PATH 2026-05-20 14:16:04 +02:00
Levi Neely 97d14f1100 fix: filter inherited env vars overridden by per-session envExtra
Prevents the agent from using the user's global OLLIE mount to
bypass per-session permission enforcement.
2026-05-19 15:45:00 +02:00
Levi Neely 1e96d4c7f4 agent: separate uname (principal) from session ID
Session identity is now a numeric UID (starting at 10000) assigned at
creation and never changed. Session names can be renamed freely without
affecting the 9P identity.

- AgentCoreConfig.Uname carries the principal
- pushSessionEnv sets OLLIE_UNAME on the execute server
- startMount gated by WithMount() option (not env var)
- Close() uses context timeout to avoid hanging on fusermount
2026-05-19 15:06:16 +02:00
Levi Neely e20f9a7a06 execute: per-session FUSE mount for 9P identity
The execute server now starts ollie-9p-mount when OLLIE_SESSION_ID is
set, giving each agent session its own FUSE proxy that attaches to
olliesrv with Uname=session_id. Tools see the full namespace through
$OLLIE but all 9P operations carry the session's identity.

Close() tears down the mount on session destroy.
2026-05-19 14:10:09 +02:00
Levi Neely 1207e26a07 remove trustedTools and Confirm callback; trust is implicit via allowExecutors 2026-05-17 15:21:26 +02:00
Levi Neely 22d72f143d fix: wire allowExecutors/allowTools in BuildAgentEnv; add missing IncrToolCallCount field 2026-05-17 00:05:34 +02:00
Levi Neely 161d0d237f add allowExecutors/allowTools two-layer tool restriction 2026-05-16 23:54:55 +02:00
Levi Neely 6dfae368d0 fix: wire PlanFile, add missing rate-limit constants, simplify test helpers, fix regex
- Wire PlanFile from $OLLIE/s/{id}/plan into agentConfig so plan
  re-injection is no longer dead code
- Add missing failureWindow/maxFailures/blockDuration constants
- Replace hand-rolled contains() with strings.Contains
- Fix rm -rf .. regex to match end-of-string and whitespace
- Add TestPlanReinjection covering periodic plan re-surfacing
- Add loop_maxsteps_helpers_test.go with mockResponse/newState/sequentialStream
2026-05-16 23:54:04 +02:00
Levi Neely f8299effdf execute: split execute_code into execute_code, call_tool, pipe 2026-05-15 18:47:07 +00:00
Levi Neely c02607aa60 execute: separate steps (parallel) from pipe (sequential)
- steps: independent, run in parallel when annotated safe, outputs
  concatenated. No stdout chaining.
- pipe: explicit pipeline, sequential, stdout of each stage feeds
  stdin of the next.

steps and pipe are mutually exclusive in a single execute_code call.
2026-05-11 13:50:01 +02:00
Logan Neely cafc55e038 execute: add Strict and Yolo server options
Strict rejects inline {code} steps, allowing only named {tool} steps.
Yolo skips the landrun sandbox entirely.
2026-05-07 22:27:22 +02:00
ollie 36d3021aae sandbox: require landrun, fail hard if unavailable
WrapCommand now returns an error instead of silently falling back to
unsandboxed execution when landrun is not in PATH. execute_code
propagates this as a hard failure.
2026-05-03 22:10:02 +02:00
Levi Neely ba9ab44565 execute: fix test sandbox for plan9 PATH, drop GNU-only bc -q flag
Add {PLAN9} to test sandbox rwx list so plan9 binaries (cat, sleep,
grep, bc, sed) are accessible. Drop -q from bc invocation since
plan9 bc does not support it; -l alone works on both GNU and plan9.
2026-05-02 10:40:00 +02:00
Levi Neely f32a2a6907 prompt: support literal strings in exec prompt arrays; clarify timeout schema
Entries in the prompt array that contain a newline are now treated as
literal text instead of shell commands. This enables JIT agent configs
to embed identity text directly without escaping.

Also clarify that execute_code timeout is a top-level parameter, not
per-step, to prevent models from placing it in the wrong location.
2026-05-02 10:29:01 +02:00
Levi Neely 6646740d67 change tools to hierarchical 2026-04-30 14:39:02 +02:00
Levi Neely 6abf0cdb3d execute: parallel dispatch via flock; agent: preTool/postTool hooks, turn rollback, mid-turn compact
execute_code auto-batches consecutive tool steps annotated '# ollie:parallel read'
into goroutine fan-outs. Write/global steps serialize. LOCK_SH/LOCK_EX via
syscall.Flock in a per-session lock dir for cross-process safety. Tool scripts
declare their own parallelism profile; no tool names hardcoded in Go.

- flock.go: lockClass, classifyStep (annotation-driven), acquireFlock
- tools.go: LockDirSetter interface
- server.go: lockDir field, SetLockDir method
- pipe.go: runReadBatch with shared-lock goroutine fan-out
- code.go: auto-batching pipeline loop
- core.go: pushLockDir wires session tmpdir to execute server at init;
  preTool/postTool hook callbacks in agentConfig; AutoCompact after each
  tool round; session snapshot/restore on turn failure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 09:00:29 +02:00
Levi Neely a4bb7608c7 expand ~ in cwd across agent core, hooks, and execute server
- Add paths.ExpandHome() helper for tilde expansion
- Apply in NewAgentCore, SetCWD (agent + execute server), and hook runner
- Fixes 'chdir ~/path: no such file or directory' errors
2026-04-24 20:10:42 +02:00
Levi Neely 0b64808ef5 pkg/tools: add contract tests, remove Close from Server/Dispatcher
- Add contract tests for tools.Server and tools.Dispatcher interfaces
  (tools_test.go), covering all exported behavior including error paths.
  pkg/tools coverage: 0% -> 100%.
- Add contract test for execute.Server (ListTools, CallTool), Decl
  factory test, and executeElevated early-exit test. execute coverage:
  68% -> 71%.
- Remove Close() from Server and Dispatcher interfaces and all
  implementations/callers. These existed for MCP server cleanup which
  has been removed.
2026-04-21 13:38:02 +02:00
Levi Neely 46272f22a6 test: sandbox coverage + backend contract tests
- sandbox: remove dead code (DefaultConfig, Load/Save, LayeredConfig, Merge,
  Version, SystemDefaults, validateName, ConfigPath, OpenSandbox); unexport
  internal symbols; LoadSandbox now takes io.Reader; loadSandboxConfig owns
  file opening; 83% package coverage via new sandbox_test.go
- backend: add BaseURL field to AnthropicBackend for testability; new
  backend_test.go runs checkContract against all five implementations
  (Ollama, OpenAI, Copilot, Anthropic, CodeWhisperer) via httptest servers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 13:00:06 +02:00
Levi Neely aeeb0a3e22 execute: prepend \$OLLIE/x/ to PATH for tool subprocesses
Allows wrapper scripts in ~/.config/ollie/scripts/x/ to shadow system
binaries transparently without modifying the user's shell environment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 11:07:23 +02:00
Levi Neely 56c299d29b elevation: replace Elevator interface with x/elevate plugin script
Remove the elevation package and Elevator interface entirely. The
execute server now invokes x/elevate directly, with detection reduced
to a stat check. Decl() loses the elevator parameter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:50:20 +02:00
Levi Neely e09a6c1250 elevation: add Elevator interface + superpowers backend; add elevated:true to execute_code steps
Remove session-scoped env injection from frontend (s/{id}/env, -e/-env flags) — superseded
by per-invocation superpowers run-session in the elevator. Keep agentCore env map and
OLLIE_SESSION_ID propagation via pushSessionEnv.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:06:43 +02:00