- 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
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.
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.
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.
- 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
- 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
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.
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
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.
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.
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.
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).
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.
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.
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.
- 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
- 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
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.
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
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.
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.