Commit Graph

654 Commits

Author SHA1 Message Date
Levi Neely 75f137dda5 backend/kiro: port fixes from goq amzcodewhisp
- Switch endpoint from q.*.amazonaws.com to runtime.*.kiro.dev
- Use management.*.kiro.dev for ListModels
- Fix content encoding: plain string instead of json.RawMessage
- Fix tool results: always use text field (upstream rejects bare JSON primitives)
- Normalize tool call arguments (deduplicate keys)
- Expand retry conditions: add 502, 503, 408, InsufficientModelCapacity
- Add SQLite busy-timeout and Go-level retry for lock contention
- Add 30s refresh timeout and fullLoad before refresh
- Add SSO cache fallback for token refresh
- Add jitter to token expiry checks
- Add sqliteHasNewUsableAccessToken for cross-process recovery
- Add envState to current message
- Update user-agent strings to 1.3.15/2.5.1
- Set X-Amzn-Codewhisperer-Optout to true
- Add reasoning/thinking support (additionalModelRequestFields)
- Add counter-thinking tags on user messages before assistants
- Handle reasoningContentEvent in stream
2026-07-10 11:43:18 +02:00
Levi Neely 0fc9c9613c kiro: update API version and retry transient 500s
The Kiro/CodeWhisperer API started rejecting tool-use requests from
older API versions (0.1.14474) with InternalServerException. Update
to 0.1.16551 and appVersion 0.12.333 to match kiro-cli.

Also add retry with linear backoff (1-5s) for transient 500 errors
which still occur intermittently even with the correct version.
2026-07-10 10:28:48 +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 f05b736af9 agent: update preamble when cwd changes
SetCWD now replaces old cwd references in the system prompt,
matching the pattern used by SetSessionID. Without this, the
model continued to see the original cwd in its environment
section after a directory change.
2026-07-07 12:20:48 +02:00
ollie 331edc332d fix test 2026-07-01 21:22:16 +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
ollie 72ae801e3f add GNU Makefile mirroring mkfile 2026-06-16 06:50:55 +02:00
Levi Neely 391f633785 env: Format() emits only managed vars, not entire process env 2026-06-15 10:49:30 +02:00
Levi Neely 1dbc75cecc agent: replace cold truncation with real LLM summarization
- store all tool results verbatim at update time
- stripColdResults now calls LLM to summarize, skips hot tail
- stripCold interface takes ctx+backend
- remove stripColdResults from RestoreSession
2026-06-01 09:45:27 +02:00
ollie c529ebf41a updates 2026-06-01 08:05:38 +02:00
ollie cb1551fe67 fix compaction model to deepseek-v4-flash; accept error stop reason in loop 2026-05-30 10:46:12 +02:00
ollie bc7a536ced fix: round-trip reasoning_content for DeepSeek thinking models
DeepSeek requires reasoning_content to be echoed back on assistant
messages. Store reasoning from stream events on Message and serialize
it as reasoning_content in the OpenAI wire format.
2026-05-28 19:04:03 +02:00
ollie 10cbded305 token efficiency: fix tier classification, expand cold tier, add usage log and compaction model override
- Fix dead-code bug: ClassifyTier now parses inner tool names from
  call_tool/pipe arguments via ResultTierArgs
- Add file_grep, file_glob, lsp_symbols, lsp_completion, lsp_diagnostics,
  reasoning_think to cold tier
- Add append-only JSONL usage log (~/.local/share/ollie/usage.jsonl)
- Add compaction model override: config > OLLIE_COMPACTION_MODEL env >
  per-backend default (haiku/gpt-4o-mini/flash)
- Expose CompactionModel on Core interface
2026-05-28 18:44:30 +02:00
Levi Neely 2b914ce150 codewhisperer: image content block support in user messages and tool results 2026-05-25 23:14:40 +02:00
ollie 4b4dab3f02 backend: add tests for image ContentBlock encoding (Anthropic + OpenAI)
TestBuildAnthropicMessages_UserImageBlocks: user message with ContentBlocks
TestBuildAnthropicMessages_ToolImageBlocks: tool result with image blocks
TestBuildAnthropicMessages_UserPlainTextFallback: nil ContentBlocks uses Content
TestEncodeMessages_UserWithImageContentBlocks: OpenAI image_url encoding
TestEncodeMessages_UserWithImageContentBlocks_JSON: wire format verification
2026-05-25 18:06:01 +02:00
ollie 02df4b8dd5 agent: plumb image ContentBlocks from tool results through to backend messages
toolExecutor now returns (string, []ContentBlock, error).
extractToolResult parses image blocks from structured tool output.
Session.update populates ContentBlocks on tool messages.
file_read detects PNG/JPEG/GIF/WEBP and returns base64-encoded image blocks.
2026-05-25 18:02:21 +02:00
ollie adb686bc1d backend: add ContentBlock/ImageSource types and multi-modal image encoding for Anthropic and OpenAI
Add canonical ContentBlock and ImageSource types to backend.go.
When Message.ContentBlocks is set, it takes precedence over Content.

Anthropic: new anthropicImageSource type, anthropicContentBlocks() helper
converts canonical blocks to wire format. buildAnthropicMessages handles
ContentBlocks on user and tool messages.

OpenAI: new openAIImageURL type, openAIContentBlocks() helper converts
canonical blocks to wire format (image_url with data: URIs).
encodeOpenAIMessages uses ContentBlocks when present.
2026-05-25 17:08:18 +02:00
Levi Neely 5985ab7d20 backend/kiro: exponential backoff on ThrottlingException
Retry up to 5 times with exponential backoff (5s, 10s, 20s, 40s, 80s)
when the Kiro backend returns ThrottlingException or HTTP 429.
Previously these errors were sent as a fatal StopReason, causing the
agent loop to abort immediately.
2026-05-23 14:45:29 +02:00
Levi Neely 19877f0a06 agent/loop: send full compacted history instead of recent-only tail
After compaction, the loop was discarding cold+warm zones and only
sending the last 8 messages to the backend. This caused the agent to
lose context after manual or auto compaction.

Remove the recentHistory path entirely: state.history() already
returns the compacted (small) history post-compact. The TaskState
render block remains as additional steering injected after the system
prompt.

Removed: StepContext struct, recentHistory from state interface and
Session.
2026-05-23 13:16:41 +02:00
Levi Neely 9d6800a51c agent: parse text-based tool calls instead of failing
Models that don't support native function calling emit tool calls as
plain text. Instead of treating this as ToolUnsupportedError, parse the
text and execute the tool calls normally.

Handles both direct JSON and shorthand (key=value) formats with relaxed
JSON support (unquoted keys).
2026-05-23 11:46:49 +02:00
Levi Neely 1485decdbb backend: fix copilot API paths
Copilot API has no /v1 prefix. Add pathPrefix field to OpenAIBackend
(defaults to /v1) and apply extraHeaders in fetchModels. Copilot sets
pathPrefix to / so it hits /models and /chat/completions directly.
2026-05-21 19:43:23 +02:00
Levi Neely 15d7d3bf50 env: strip quotes from values in LoadFile
LoadFile was setting env vars with literal quotes intact, causing
API keys like OLLIE_GEMINI_KEY to fail auth when loaded from the
env file at olliesrv startup.
2026-05-21 19:23:31 +02:00
Levi Neely 09afd071ed strip quotes from env vars 2026-05-21 19:12:56 +02:00
Levi Neely 8960cd9754 fix TestBackends: expect gemini in backend list 2026-05-21 19:07:39 +02:00
Levi Neely c09229307d add env.sample with all supported OLLIE_* variables 2026-05-21 17:06:53 +00:00
Levi Neely 2ef2dd4290 backend: add gemini backend (Google AI Studio / OpenAI-compat) 2026-05-21 17:04:52 +00:00
Levi Neely 47f8eed119 agent: remove unsandboxed ! shell escape
The ! prefix allowed arbitrary command execution without sandbox
protection. Since agents share the same Submit path as users, this
was a sandbox bypass vector. Remove it entirely; users who need
shell access can use execute_code (sandboxed) or run commands
directly in their terminal.
2026-05-21 15:18:02 +02:00
Levi Neely 8ae0fad8a3 session persistence: /save, /resume, cwd-scoped /sessions
- Add CWD field to PersistedSession for per-directory filtering
- /sessions now shows only sessions matching current cwd (-a for all)
- /save <name> creates a named checkpoint
- /resume <id> restores a saved session (messages + task state)
- Autosave (already existed) now persists cwd with each save
2026-05-21 15:08:16 +02:00
Levi Neely 9d4818af8d refactor agent core: extract runtime, simplify commands 2026-05-21 14:42:45 +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 d00a15093d expand $VAR references in env file values and sandbox paths 2026-05-20 18:35:09 +02:00
Levi Neely 66d9d0502d expand ~ in env file values and sandbox paths 2026-05-20 18:34:00 +02:00
Levi Neely fa9c98fb05 agent: add exec event role for ! command output
Shell command output uses a dedicated "exec" role instead of "info",
formatted with ``` fences in the chat log.
2026-05-20 16:49:41 +02:00
Levi Neely 1479aea274 agent: publish events on pubsub bus, self-drain queue
- Add pubsub.Bus to agent; all events published on "event" topic
- Remove EventHandler param from Submit (and internal methods)
- Queue() self-drains via goroutine when agent is idle
- /i submits directly when idle, injects when running
2026-05-20 16:45:32 +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 5099ccf51d /agent: preserve session ID when switching agents 2026-05-20 10:57:04 +02:00
Levi Neely 82df12e293 add test for SetSessionID preamble update 2026-05-20 10:50:20 +02:00
Levi Neely 09a9364b6f SetSessionID: update session ID in system prompt on rename 2026-05-20 10:47:56 +02:00
Levi Neely 10991ec319 env: load ~/.config/ollie/env at server startup
EnsureDefaults now loads the env file before setting path defaults.
This ensures OLLIE_TIER_*, OLLIE_ENABLED_BACKENDS, and all other
user-configured vars are available to tool scripts from the start,
rather than only after the first backend.NewWithName() call.
2026-05-20 09:36: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 ccacdc4ec8 fix: clear OLLIE env in tests to prevent FUSE mount hangs 2026-05-19 15:20:31 +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 5efed7040d fix: inject OLLIE_SESSION_ID into prompt resolution subprocesses
resolveExecPrompt spawns x/prime which uses envsubst to expand
${OLLIE_SESSION_ID} in the system prompt template. The variable was
never in the process environment at resolution time — it was only
set on the execute server after the prompt was already rendered.

Add env []string parameter to resolvePrompt/resolveExecPrompt and
BuildAgentEnv so callers can inject session-scoped vars into the
subprocess environment. Generate session ID before BuildAgentEnv in
the agent-switch path so it is available at prompt resolution time.
2026-05-18 12:31:35 +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 93c0b374d5 truncation: avoid mid-rune cut with ToValidUTF8 2026-05-17 12:59:49 +02:00
Levi Neely 7237980ff5 truncation: raise hard ceiling to 128KB, include tool name in message 2026-05-17 12:51:43 +02:00
Levi Neely 011843a59d loop: per-step budgets — replan gate (8 rounds) and stall detection (5 rounds) 2026-05-17 12:13:26 +02:00