Commit Graph

1681 Commits

Author SHA1 Message Date
Levi Neely 7c6dff4a01 rename EDSL constructors for clarity
- Leaf → FileNode (file node)
- Dir → DirNode (directory node)
- Blueprint → Dynamic (state-dependent directory)

The names now clearly indicate what they create:
- FileNode: a file
- DirNode: a directory
- Dynamic: a directory whose children depend on runtime state
2026-08-04 10:45:28 +02:00
Levi Neely 99e88ef407 add Blueprint pattern unit tests
Test coverage for:
- Basic Blueprint: structure declaration, instance resolution, aliases
- Nested Blueprints: session/{id}/agent/{aid} pattern
- Context propagation: handlers called with bound context
- UID/GID inheritance: custom vs inherited ownership
- Rename callback: instance rename via Rename func
- Empty instances: graceful handling of no instances
- Mixed static/dynamic: Blueprint alongside static children
- File modes: correct permissions on blueprint files

Also fix validation to accept template nodes with Instances (not just List).
2026-08-04 10:38:56 +02:00
Levi Neely 3a920998bd implement Blueprint pattern for EDSL
New EDSL construct: Blueprint(name, instancesFn, ...children)
- Declares static structure in treeSpec
- InstanceFn returns identity info (name, aliases, UID/GID, data binding)
- Handlers access instance data via ctx.Session/Agent/AgentLog
- No more closure captures for session/agent data

Changes:
- Add Instance type and InstanceFn to fsnode.go
- Add Blueprint() constructor
- Update builder.go to handle blueprint node expansion
- Convert session/{id} to Blueprint with sessionInstances
- Convert agent/{aid} to Blueprint with agentInstances
- Convert all handlers to use ctx fields instead of closures

Benefits:
- Full namespace structure visible in treeSpec at top of spec.go
- Handlers are stateless functions (easier to test/reason about)
- Less memory (no closure allocations per instance)
- Cleaner separation: structure vs data binding vs handlers
2026-08-04 10:35:18 +02:00
Levi Neely b6e2f9048b consolidate fs handlers into spec.go
Single source of truth for the 9P namespace:
- Move rootfiles.go handlers into spec.go
- Move sessionfiles.go (listSessions) into spec.go
- Move agentfiles.go (listAgents) into spec.go
- Move procfiles.go (listProcesses) into spec.go
- Move elevatefiles.go handlers into spec.go

The full namespace structure is now visible in one file with
structure comments documenting the layout of dynamic subtrees.

No functional changes - just reorganization.
2026-08-04 10:24:26 +02:00
Levi Neely 66850e822f cleanup: remove dead code from olliesrv
- Remove unused GroupTable.Remove() method, rename Add to Populate
- Remove unused toolPrompt field from Server struct and Config
- Remove unused ModelCache type alias
- Remove unused toolsrv import
- Flatten if true {} blocks (debugging remnants)
- Convert fcallTypeName switch to map lookup
- Remove unused Tree.Unmount() method

-44 lines
2026-08-04 10:19:12 +02:00
Levi Neely 0c6dd5b32a update kde submodule: cleanup debug logging 2026-08-03 20:44:27 +02:00
Levi Neely ae2ee819f1 update kde submodule: fix state role binding 2026-08-03 20:31:25 +02:00
Levi Neely cc5c682109 update kde submodule: targeted state dot updates in render path 2026-08-03 20:29:47 +02:00
Levi Neely d3a7a50845 update kde submodule: fast path for active agent state changes 2026-08-03 20:27:54 +02:00
Levi Neely c5bc73ecd7 update kde submodule: optimize handleEvent() hot path 2026-08-03 20:22:27 +02:00
Levi Neely 65c14ee37b update kde submodule: single-pass session parsing 2026-08-03 20:16:18 +02:00
Levi Neely 8257bf4584 update kde submodule: eliminate C++ calls in QML update loop 2026-08-03 20:13:45 +02:00
Levi Neely 1b0a000a13 update kde submodule: remove per-agent connection polling 2026-08-03 20:11:00 +02:00
Levi Neely 10076d7b03 lib9p: remove test.c (confuses cgo) 2026-08-03 20:05:48 +02:00
Levi Neely 06dca57a19 update kde submodule: native 9P client via libollie9p 2026-08-03 20:04:26 +02:00
Levi Neely b5c67e1a93 lib9p: shared library for 9P client operations
Go shared library (c-shared buildmode) that wraps 9fans.net/go/plan9/client.
Provides C API for persistent 9P connections, eliminating process spawn
overhead for GUI operations.

Exports: ollie9p_connect, ollie9p_read, ollie9p_write, ollie9p_rdwr,
ollie9p_ls, ollie9p_stat, ollie9p_remove, ollie9p_create, ollie9p_mkdir,
ollie9p_rename, ollie9p_close, ollie9p_last_error, ollie9p_free

Build: go build -buildmode=c-shared -o libollie9p.so
Install: just lib9p (installs to ~/.local/lib and ~/.local/include)
2026-08-03 20:04:07 +02:00
Levi Neely 6d902ba7e9 9p: default log level to warn, not debug
The 9P logger was hardcoded to LevelDebug, causing all 9P operations
to print timing info to stdout. This blocked the server on terminal
output, hurting GUI responsiveness.

Now uses NewLogger('9p') which:
- Defaults to the sink's level (warn)
- Can be overridden with OLLIE_9P_LOG=debug

Also updates kde submodule with incremental session tree updates.
2026-08-03 19:52:07 +02:00
Levi Neely 0f37c1c990 update kde submodule: QML rendering optimizations 2026-08-03 19:29:54 +02:00
Levi Neely 4c40be4709 update kde submodule: pubsub delta events optimization 2026-08-03 19:17:52 +02:00
Levi Neely 73de0b3cc0 hierarchical event topics and TCP support
Event topics now follow session hierarchy:
  session.{sid}.new/kill/pause/resume/rename
  session.{sid}.agent.{aid}.new/kill/state

Wildcard routing publishes to all ancestors:
  session.{sid}.agent.{aid}.state publishes to:
    session.{sid}.agent.{aid}.*
    session.{sid}.agent.*
    session.{sid}.*
    session.*
    *

GUI can subscribe to session.{sid}.* to get all events
for one session including its agents.

Also:
- ollie-9p -a flag now supports TCP (host:port or tcp!host:port)
- Add Session.ID() accessor method
2026-08-03 19:10:31 +02:00
Levi Neely 4e817f5de9 replace event ring buffer with pubsub
- Use github.com/simonfxr/pubsub for topic-based event routing
- Topic format: session.{id}.{action}, agent.{id}.{action}
- Wildcard subscriptions: *, session.*, agent.*
- PublishEvent routes to exact topic + wildcards
- WaitEvent maintains backwards compatibility for eventwait
- Add agent.SetOnStateChange callback for state change events
- Extend session/idx format with paused, connected, agent list

Events now published:
- session.{id}.new/kill/pause/resume/rename
- agent.{id}.new/kill/state

This enables efficient selective subscriptions - GUI can subscribe
to specific sessions/agents instead of receiving all events.
2026-08-03 18:48:30 +02:00
Levi Neely 6d31d81ac5 update kde submodule: session pause/resume UI 2026-08-03 18:36:25 +02:00
Levi Neely fc4a11e145 update kde submodule: live agent state indicators 2026-08-03 18:30:30 +02:00
Levi Neely 7f1708256f update kde submodule: RPC health color indicators 2026-08-03 18:14:12 +02:00
Levi Neely 5634123c6d feat: add session connected file for RPC health check
Adds session/{id}/connected file that pings the RPC connection to
determine if the tool server is responsive. Used by GUI to show:
- Green: connected and not paused
- Gray: paused (intentional)
- Red: disconnected/crashed (not paused but connection broken)
- Yellow: zombie (paused but still connected - shouldn't happen)
2026-08-03 18:13:53 +02:00
Levi Neely 4b8fb5c96a update kde submodule: pause indicator and agent count 2026-08-03 18:12:10 +02:00
Levi Neely 8cebf08cbd feat: session pause/resume to reduce resource usage
Adds pause and resume commands to session/ctl:
- pause: stops the tool server process, closes connections
- resume: respawns the process and re-establishes connection

When paused, tool calls return 'connection closed' errors which
propagate to the chat log. Useful for reducing resource usage when
many sessions exist but aren't actively being used.

Also adds session/{id}/paused file to check pause status.
2026-08-03 18:08:09 +02:00
Levi Neely ff3f8c8819 fix: ollie-9p write/rdwr propagate clunk errors
The 9P protocol returns write handler errors via Rclunk, not Rwrite.
cmdWrite and cmdRdwr were using defer fid.Close() which discarded the
error. Now they check fid.Close() return value and exit non-zero on
failure, allowing the GUI to detect rename errors.
2026-08-03 18:04:12 +02:00
Levi Neely 76c6021d16 update kde submodule: rename error dialog 2026-08-03 17:53:46 +02:00
Levi Neely 063dc435c6 update kde submodule: clear active agent when killed 2026-08-03 17:51:23 +02:00
Levi Neely a6ab61cfed fix: session/idx includes sessions with zero agents
buildIndex was skipping sessions where Core != nil but Agents() was empty.
Now empty sessions appear in idx so the GUI can display them as tree nodes.
2026-08-03 17:48:47 +02:00
Levi Neely fa7abc9a99 fix: set Backend on Runtime when creating second agent in session
CreateAgent() was missing rt.Backend = be for the second agent path,
causing nil pointer dereference when /agent command accessed runtime.Backend.
2026-08-03 17:46:11 +02:00
Levi Neely 50b95f342e chore: update kde submodule (multi-agent handling fix) 2026-08-03 17:42:15 +02:00
Levi Neely e5ebf0550a test(toolsrv): add integration tests for RPC protocol
Comprehensive tests for the ollie-remote JSON-RPC 2.0 protocol:

Direct RPC dispatch tests:
- ping: liveness check returns 'pong'
- host_info: returns platform, arch, git repo status
- list_tools: empty list when no tools loaded
- set_env: environment variable injection with hook verification
- set_cwd: working directory updates
- set_allow_tools: tool restriction configuration
- is_parallel_read: parallel safety classification
- result_tier / result_tier_args: retention tier lookup
- detach: returns false when no process running
- list_detached: empty list initially
- signal_detached: error for nonexistent PID
- get_detached_output: error for nonexistent PID
- dismiss_detached: returns false for nonexistent PID
- tool call: error for unloaded tools
- invalid params: -32602 error code

Pipe-based client/server tests:
- Full roundtrip through toolsrv.Conn client
- Concurrent request handling (10 parallel pings)
- Context cancellation propagation
- Connection close detection

JSON-RPC protocol compliance:
- Table-driven tests for request/response format
- Error code verification (-32602 invalid params, -32000 server error)
2026-08-03 16:31:04 +02:00
Levi Neely f9becce7cc fix(agent): refresh outputFormat lookup on each turn
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.
2026-08-03 16:26:08 +02:00
Levi Neely b57bc003b2 chore: update kde submodule (chat rendering rewrite) 2026-08-03 16:16:51 +02:00
Levi Neely a56f9dfe73 chore: update kde submodule (syntax highlighting fix) 2026-08-03 16:07:52 +02:00
Levi Neely 6a32b3afce chore: update kde submodule (agent connection retry fix) 2026-08-03 16:03:07 +02:00
Levi Neely 2dc4098c09 fix(backend): strip tool blocks when no tools defined
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.
2026-08-03 15:58:29 +02:00
Levi Neely aae307046a fs: ensure tool server on agent creation, retry via keeper
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.
2026-08-03 15:51:23 +02:00
Levi Neely aa84cd1c9f agent: nil-check ToolServer before ListTools in turn
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).
2026-08-03 15:45:57 +02:00
Levi Neely c9c76d51c0 agent: inject tool documentation + schemas into preamble
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.
2026-08-03 13:07:26 +02:00
Levi Neely 7189a9fc24 scripts: add 'o write' subcommand 2026-08-03 12:48:08 +02:00
Levi Neely 81e47c8513 fs: add error logging to Kill when session not found in map
Helps trace zombie sessions — if Kill is called with a key that
doesn't match the sessions map, we'll see it in the log.
2026-08-03 12:34:42 +02:00
Levi Neely 5795fe8864 kde: update submodule (fix stale stream spam) 2026-08-03 12:28:46 +02:00
Levi Neely fe2348c0cc toolsrv: add ProcessKeeper for resilient ollie-remote lifecycle
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.
2026-08-03 12:21:54 +02:00
Levi Neely c11d513202 kde: update submodule (no-retry agent connections) 2026-08-03 11:33:46 +02:00
Levi Neely ce53f57e4c kde: update submodule (agent disconnect fix) 2026-08-03 11:31:14 +02:00
Levi Neely 256d5177d1 ollie-remote: call env.EnsureDefaults, keep OLLIE_SESSION_ID/OLLIE_UNAME current
- 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
2026-08-03 11:27:04 +02:00
Levi Neely 8bb4246cde prompts: document tool discovery in session-9p.md
- Global catalog: read /tools
- Loaded tools: read agent/tools
- Load a tool: write tool name to agent/tools
- Added tools to agent directory file table
2026-08-03 11:26:37 +02:00