Commit Graph

53 Commits

Author SHA1 Message Date
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
Levi Neely 44bff71a65 env: centralize daemon env in pkg/env; clean up session env propagation
- New pkg/env package owns EnsureDefaults, Set, Get, All, Format
- BuildAgentEnv reverted to 3-arg signature (no initialEnv)
- agentCore.setEnv removed; pushSessionEnv handles OLLIE_SESSION_ID only
- execute.Server.SetEnv no longer calls os.Setenv (session-scoped only)
- !cmd handler sets OLLIE_SESSION_ID explicitly in subprocess env
- mcp/transport: seed cmd.Env from os.Environ() so MCP servers inherit PATH etc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 15:43:01 +02:00
Levi Neely 92034b5342 add OLLIE_CFG_PATH and OLLIE_DATA_PATH env vars
Replace all hard-coded ~/.config/ollie and ~/.local/share/ollie paths
with a new paths package that reads OLLIE_CFG_PATH and OLLIE_DATA_PATH,
falling back to the previous defaults when unset.
2026-04-17 15:31:19 +02:00
Levi Neely c2ba1728e4 execute: unify execute_pipe into execute_code as pipeline primitive
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 21:36:22 +02:00
Levi Neely ab96de2771 execute: remove execute_tool; use execute_code {tool} steps instead
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 21:18:12 +02:00
Levi Neely cf25268d80 execute: refactor execute_code to parallel steps; add parallel pipe stages
- execute_code now takes steps:[{code,language}|{tool,args}] instead of
  a single code/language pair. Single-step calls return raw output;
  multi-step calls run in parallel and return results under === step N ===
  headers in submission order.
- execute_pipe stages may now include {parallel:[...]} to fan out
  concurrently within a pipeline. Parallel outputs are concatenated in
  submission order and fed as stdin to the next stage.
- Stage execution is now Go-level (stdin chaining) rather than a single
  bash pipeline string, enabling parallel stages and tool/code mixing.
- CodeStep and resolveCodeStep are the shared primitives for both
  execute_code and execute_pipe parallel stages.
- executeWithStdin added to Server for stdin chaining between stages.
- Tool steps use shebang detection; language field applies only to
  inline code steps (default: bash).
- ListTools schemas and descriptions updated throughout.
2026-04-16 20:06:05 +02:00
Levi Neely da094e9803 Revert "execute_tool: resolve tools from $OLLIE/t"
This reverts commit 42b7b5b5c2.
2026-04-15 11:13:37 +02:00
Levi Neely 42b7b5b5c2 execute_tool: resolve tools from $OLLIE/t
ToolsPath() fell back to ~/.config/ollie/tools when OLLIE_TOOLS_PATH
was unset, ignoring the 9P mount entirely. Add /home/lkn/mnt/ollie/t as the
preferred fallback so execute_tool finds tools on the mounted
filesystem regardless of cwd.
2026-04-15 11:12:53 +02:00
Levi Neely 655b9e7060 fix: surface tool script errors to model; inject session env at startup
- extractMCPResult: parse isError from MCP response so tool failures
  are returned as Go errors and marked isErr=true in the loop
- CallTool: emit isError:true content block instead of bare {"error":...}
  so the model sees tool failures as error results, not success
- SetEnv: call os.Setenv so OLLIE_SESSION_ID/OLLIE are in the process
  env and inherited by sandboxed subprocesses
- NewAgentCore: inject session env into execute server at creation time,
  not only on rename, so tools have OLLIE_SESSION_ID from the first call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 22:49:00 +02:00
Levi Neely 13590a84e7 implement TrustedTools: explicit trust replaces implicit allow-all
- Add TrustedToolsSetter interface and SetTrustedTools to execute.Server
- Add allowed(): trusted tools return true; untrusted with no Confirm
  return false (deny by default). Confirm returns true=allow, consistent
  with allowed() semantics throughout.
- BuildAgentEnv wires cfg.TrustedTools into the execute server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:52:37 +02:00
Levi Neely 4e230d6f0c fix execute_tool: detect language for #!/usr/bin/env shebangs
detectLanguage only checked filepath.Base(fields[0]), which returns
"env" for #!/usr/bin/env python3. Every such script was run as bash,
producing syntax errors. Now checks fields[1] when fields[0] is "env".

Also add OLLIE_MEMORY_PATH to default env passthrough.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 17:29:19 +02:00
Levi Neely abe8ab76cc tools: replace file and reasoning built-ins with shell scripts
Remove pkg/tools/file and pkg/tools/reasoning. Both are now implemented
as execute_tool scripts in ollie/t/ with feature parity:
- file_read, file_write, file_edit, file_grep, file_glob
- reasoning_think

isread guard delegated to /tmp/ollie/$OLLIE_SESSION_ID/<hash> markers.
SetSessionID renames the tmpdir on session rename.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 15:26:12 +02:00
Levi Neely 87f056e221 prompt: idx-based tool/skill discovery; session self-awareness
- Replace {{.Tools}} injection with ollie/t/idx (generated at session
  start by rebuildToolsIdx); prompt now instructs grep-based discovery
- Replace {{.Skills}} injection with ollie/sk/idx (rebuildSkillsIdx);
  same grep pattern
- Add {{.SessionID}} to system prompt identity line
- Expand filesystem section: full ollie/s/ layout, all session files,
  ctl commands, s/idx cooperation pattern
- Fix execute_tool description: use ollie/t instead of physical ToolsPath()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 14:27:39 +02:00
Levi Neely 5d86326edf execute: language-specific dangerous patterns; skip domain-specific tools
universalPatterns: mkfs, dd if=/dev/, sudo/su, /etc/shadow|sudoers
bashPatterns: rm -rf flag syntax, fork bomb, redirects, eval "...$"
pythonPatterns: shutil.rmtree, os.system/subprocess with rm -rf, os.remove on sys paths
perlPatterns: system/exec/backtick with rm -rf, unlink glob on sys paths
luaPatterns: os.execute/io.popen with rm -rf, os.remove on sys paths
Domain-specific tools (awk, sed, jq, ed, bc, expect) skip validation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:36:18 +02:00
Levi Neely 109622ded1 execute: remove bash wrappers; use direct invocation and stdin piping
awk/sed/jq: exec.Command directly with program as arg — no shell, no escaping.
ed/expect/bc: exec.Command with cmd.Stdin — program piped without escaping.
execute_tool with file args: language switches to "bash" after injectArgs
since the resulting snippet is already a bash command.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:32:25 +02:00
Levi Neely cdbf3096be execute: add lua support via lua -e; arg table injection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:28:16 +02:00
Levi Neely b65fc0fdf7 execute: add jq, expect, bc support
jq: filter as positional arg, file args appended, pipeline-safe.
expect: pipes script via printf '%s' $'...' | expect -.
bc: pipes via printf '%s' $'...' | bc -ql (quiet + math library).
All three use ANSI-C quoting consistently.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:25:43 +02:00
Levi Neely 9ec58b0ae8 execute: add sed and ed support; refactor detectLanguage to use shebang basename
sed: sed -e $'...' inline, file args appended, pipeline-safe.
ed: pipes script via printf '%s' $'...' | ed -s [file].
detectLanguage now parses shebang command basename rather than
using strings.Contains, fixing potential false matches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:18:08 +02:00
Levi Neely 2ecdcc26c8 execute: add awk support via gawk -e; file args passed after --
Uses gawk -e $'...' (ANSI-C quoting) consistently across Execute() and
pipelines. injectArgs for awk produces a bash snippet with file args
after --. No BEGIN block hacks needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:15:27 +02:00
Levi Neely 3f0a77619b execute: add perl support (shebang detection, @ARGV injection, pipe support)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 13:07:03 +02:00
Levi Neely ac77e11afa remove built-in memory and task tool servers
Delegate memory and task to MCP servers (denote-mcp, 9beads-mcp or
equivalents). When no MCP server provides these tools, the model
degrades gracefully — files in ollie/m and ollie/pl remain accessible
via file_* and execute_code. reasoning_think and file_* stay built-in.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 08:37:26 +02:00
Levi Neely ae3fc3be78 refactor: split memory and task out of reasoning into own packages
- pkg/tools/memory: memory_remember + memory_recall with FlatDirBackend
  baked in (no more injectable MemoryBackend abstraction)
- pkg/tools/task: task_plan + task_complete with file-based plan
  persistence baked in (no more injectable PlanBackend abstraction)
- pkg/tools/reasoning: stripped to reasoning_think only
- pkg/tools/tools: remove PlanStep/PlanBackend/MemoryBackend interfaces
- pkg/agent: remove dispatchMemoryBackend, dispatchPlanBackend,
  WithFallbackPlanBackend; BuildAgentEnv takes no options

Fixes infinite recursion crash: previously dispatchMemoryBackend routed
memory_recall back to the reasoning server that owned it, causing
unbounded mutual recursion and a goroutine stack overflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 08:14:41 +02:00
Levi Neely 2d122c70dd gate file tools with sandbox path checks
file_read, file_write, file_edit, file_grep, and file_glob now check
paths against the sandbox config before operating. Same policy that
landrun enforces on execute_code, applied at the application level.

- Add sandbox.LoadMerged: loads base config + named layer, graceful
  fallback if layer missing. Replaces duplicated logic in execute.
- Add sandbox.CheckPath: resolves symlinks, expands templates, checks
  path against allowed entries (RO/ROX for read, RW/RWX for write).
- file.Server.checkAccess wires the check into every file dispatch.
2026-04-13 18:37:17 +02:00
Levi Neely 809ad3472d rename workdir to cwd
Go API: WorkDir→CWD, SetWorkDir→SetCWD, WorkDirSetter→CWDSetter.
Unexported: workdir→cwd in fields, params, locals.
Docs: README.md updated.
2026-04-13 18:03:20 +02:00
Levi Neely 46cd8e9a66 reasoning_plan: make tool description backend-agnostic
Strip flatfs-specific lifecycle instructions (filenames, sed, mv)
from the reasoning_plan tool description. The abstract tool now
describes only generic state transitions; concrete backends supply
their own instructions via CreatePlan response messages.
2026-04-13 13:05:04 +02:00
Levi Neely d705eb520e plan prompt: document __todo/__wip/__done lifecycle and listing patterns 2026-04-13 12:01:36 +02:00
Levi Neely 47133b1ccd flat planning repo built-in 2026-04-13 11:41:01 +02:00
Levi Neely a1acf0d936 core: update default tools path to ~/.config/ollie/tools
- OLLIE_TOOLS_PATH now takes first entry if colon-separated
- Default changed from ~/.local/share/ollie/tools to ~/.config/ollie/tools
- Update README accordingly
2026-04-13 10:25:18 +02:00
Levi Neely 4786866e66 fix: strip inline comments in env file parser, fix backtick syntax errors
loadEnvFile now strips " # ..." suffixes from values so inline comments
in ~/.config/ollie/env don't leak into environment variables.  Also add
kiro to the supported-backends error message and fix two raw-string
backtick escaping errors in tool descriptions.
2026-04-13 09:32:56 +02:00
Levi Neely f9918525d5 refactor: improve tool prompts for consistency and clarity
- Standardize all tool description format
- Add usage guidelines and examples
- Clarify tool-specific behaviors and limitations
- Include cross-references between related tools
- Add security warnings for execute_code
- Provide concrete examples for complex tools
- Ensure prompts match actual implementations

File tools:
- file_read: clarify limits (8MB, 2000 lines/chars), diff format
- file_write: simplify, emphasize read-before-write
- file_edit: explain uniqueness and diff format handling
- file_grep: add ripgrep syntax guidance and examples
- file_glob: add pattern examples, clarify sorting

Execute tools:
- execute_code: add security warnings, examples
- execute_tool: clarify tool discovery and usage
- execute_pipe: explain structure with examples

Reasoning tools:
- reasoning_plan: restructure for clarity, add when-to-plan
- reasoning_think: expand usage scenarios
- memory_remember: structure requirements with examples
- memory_recall: clarify search scope (titles/tags only)
2026-04-12 21:20:38 +02:00
Levi Neely 496087a874 tools/file: output diff format (context=bare, new=+, changes=unified diff)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 20:39:42 +02:00
Levi Neely 5efcafa9a6 tools/file: rename tools to file_read/write/edit/grep/glob
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 20:22:49 +02:00
Levi Neely c1e5fceda6 tools/file: port Read, Write, Edit, Grep, Glob from goq
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 20:18:59 +02:00
Levi Neely 1b44244f81 cleanup tools 2026-04-12 16:26:50 +02:00
Levi Neely 41fa92f544 agent: add pluggable memory backend with flat-dir fallback
Introduces memory_remember and memory_recall built-in tools on the
reasoning server. A MemoryBackend interface allows swapping backends:
dispatchMemoryBackend routes through a registered MCP server (e.g.
denote-mcp) when available; FlatDirBackend writes dated markdown files
to ~/.local/share/ollie/memory/ as a zero-config fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:26:26 +02:00
Levi Neely 8142f5096e agent: yield after queue-based planning; extend PlanBackend interface
PlanBackend.CreatePlan now returns an optional message alongside IDs.
When non-empty, the reasoning server uses it as the tool response
instead of the default plan summary — allowing queue backends to
instruct the agent to stop after planning rather than execute directly.

- tools.PlanBackend: CreatePlan returns ([]string, string, error)
- dispatchPlanBackend: returns "" (agent continues as before)
- reasoning/server: uses backend message when non-empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:24:12 +02:00
Levi Neely 1ac68c2ac1 agent: queue-based reasoning_plan fallback; add default-nobeads agent
- BuildAgentEnv accepts WithFallbackPlanBackend option; wired when
  task_create is absent (task backend takes priority when present)
- reasoning_plan description updated to reflect queue fallback
- agents/default-nobeads.json: copy of default without 9beads MCP

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 16:58:34 +02:00
Levi Neely 3d02de4a71 tools: add Python support; document tools in system prompt
- Detect language from shebang (bash default, python3 if shebang contains "python")
- Inject args language-appropriately: set -- for bash, sys.argv for Python
- Add python3 to executor language switch
- Handle Python steps in execute_pipe using bash $'...' embedding
- Update execute_tool description to mention supported languages
- Add Tools section to SYSTEM_PROMPT.md pointing to $OLLIE_9MOUNT/t/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 16:33:57 +02:00
Levi Neely 7d6692183e tools: remove stale discover_skill.sh example from execute_tool schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 16:25:51 +02:00
Levi Neely 4b9b03053f tools: remove file_read and file_write in favor of shell tools
The line-range patching interface was fragile (models drift on line
numbers), and both tools were redundant with execute_code + standard
shell utilities (cat, grep, sed, ed, ssam). Drop the file server
entirely; update agent configs, system prompt, and documentation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 16:11:50 +02:00
Levi Neely 5e08beb9bf agent: add dynamic workdir support via /cwd command and SetWorkDir API
- Add WorkDirSetter interface to pkg/tools so servers can receive workdir updates
- Add SetWorkDir on execute.Server with RWMutex-guarded workdir field
- Add WorkDir()/SetWorkDir() to the Core interface and agentCore
- Store agentPrompt in AgentEnv/agentCore so system prompt can be rebuilt on workdir change
- Add /cwd [path] slash command (no args shows current dir, arg changes it)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 14:21:34 +02:00
Levi Neely 7fa952c59f agent: add reasoning_plan, task backend integration, and /mcp command
- Add reasoning_plan built-in tool: decomposes goals into ordered steps
  with dependency edges; persists to task backend when available, falls
  back to in-context plan otherwise.
- Add PlanBackend/PlanBackendSetter interfaces and PlanStep type to
  pkg/tools; add GetServer to Dispatcher.
- Add dispatchPlanBackend in pkg/agent: routes task_create calls through
  the dispatcher to any registered task MCP server.
- BuildAgentEnv auto-wires the task backend to the reasoning server after
  connecting MCP servers; re-wires on every /agent switch.
- Add ListServers() to Core interface: groups all registered tools by
  server, returns formatted text.
- Add /mcp command to handleCommand(); update /help.
- Add doc/PLANNING.md and update ARCHITECTURE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 11:31:41 +02:00
Levi Neely 2f68cc1f31 agent: add usage tracking and per-turn token reporting
Emit usage events from the loop when backends report token counts.
Session tracks cumulative input/output tokens and request count.
2026-04-10 20:29:49 +02:00
Levi Neely 23913d0d76 execute, agent: thread workdir through Decl and AgentCoreConfig
execute.Decl is now a function (func(workdir string) func() tools.Server)
rather than a var, making workdir an explicit dependency rather than
an implicit os.Getwd() call. execute.Server stores the workdir and
sets cmd.Dir accordingly; falls back to os.Getwd() if empty.

AgentCoreConfig gains WorkDir string, threaded into BuildAgentEnv and
the system prompt. The /agent switch uses s.workdir so the correct
directory is preserved across agent switches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 09:04:19 +02:00
Levi Neely 8496742f14 tools: add Decl vars, NewDispatcherFunc; strip execute logging
- execute.Decl and file.Decl: package-level func() tools.Server factories;
  consumers reference them without calling directly
- tools.NewDispatcherFunc: builds a fresh Dispatcher per call by invoking
  each registered Decl — used as AgentCoreConfig.NewDispatcher
- execute.Server: remove LogDir, WorkspaceBase, MaxOutputChars, and all
  file-based logging (metrics.go deleted); New() takes no args
- Export AgentConfigPath, NewSessionID, DefaultAgentsDir, DefaultSessionsDir
  from pkg/agent so frontends don't duplicate them

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 08:27:56 +02:00
Levi Neely f87699ac7d Unify tool servers: dissolve builtin/MCP distinction
All tool servers now implement tools.Server equally. tools.MCPExecutor →
tools.Dispatcher (unexported dispatcher), tools.Executor → tools.Dispatcher
interface, tools.NewMCPServer → tools.NewServer, execute.Executor →
execute.Server, file.Server added. BuildAgentEnv takes a pre-configured
Dispatcher; caller registers execute and file servers before calling.
builtinServer collapsed — no special "builtin" concept remains.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:51:10 +02:00
Levi Neely 2e82bb2306 tools: unexport builtinServer, add NewBuiltinServer constructor
Matches the pattern of mcpServer/NewMCPServer — both are unexported
Server implementations created via constructors. No conceptual
difference between the two from the caller's perspective.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:19:02 +02:00
Levi Neely 9d1021f129 tools: consolidate builtin server in pkg/tools/
- pkg/tools/builtin.go: BuiltinServer implements tools.Server for all
  built-in tools; ExecuteDefs/FileDefs live here (subpackages can't
  hold them without reintroducing the import cycle)
- pkg/tools/execute/dispatch.go: drop tools.Server implementation;
  export Dispatch method for BuiltinServer to call
- pkg/tools/file/: export Read(path) and Write(path,content,start,end);
  remove server.go
- pkg/agent/core.go: register one tools.BuiltinServer instead of two
  separate servers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:16:29 +02:00
Levi Neely 01c9ac534e tools: move file_read/file_write into pkg/tools/file
- New pkg/tools/file package with read.go, write.go, server.go
- file.Server implements tools.Server; registered as "file" in MCPExecutor
- Remove file_read/file_write from execute/dispatch.go
- Confirm closure shared between builtin and file servers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:03:50 +02:00
Levi Neely 8875bc8377 tools: unify builtin and MCP dispatch through tools.Server
- Add tools.Server interface; MCPExecutor now holds map[string]Server
- execute.Executor implements tools.Server (ListTools/CallTool/Close)
- Built-in tools register as "builtin" server in MCPExecutor
- Remove duplicate dispatch functions from core.go (moved to dispatch.go)
- Remove builtinTools() from core.go (now in dispatch.go)
- Remove invalidateCaches and trustedTools dead code
- All tool calls now route through one mcpExec.Execute() path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:00:23 +02:00