agent-ops-patterns / gallery / opencode map / how it decides
How opencode decides
In opencode, the AI model chooses each next step, and a step normally ends the turn when it calls no local tool; plain code checks its tool calls, decides when older history is summarised, and decides from the agent's and session's rules whether an action runs, waits for you, or is refused. Nothing reads the final answer to check the work, and unless an agent sets a step limit, nothing caps how many steps a run takes.
What it does without asking you
-
Does an action run, wait for a person, or get refused?
Decided by plain code Code merges the agent's rules with the session's rules; if the last matching rule for any resource is a deny, the action is refused. Otherwise the project's saved approvals are added, anything no rule matches waits for a person, and plugin hooks may still change the result.
permission.ts:160-176· decision D1 in the full map -
In the terminal interface, who answers a request that waits for a person?
Decided by a person You do: Allow once, Always allow (when the request offers it) or Reject. If the interface was started with --auto, --yolo or --dangerously-skip-permissions, or set to auto-accept, code answers "once" for you and no prompt is shown.
permission.tsx:113-266· decision D12 in the full map -
In a headless opencode run, what happens to a request that would ask a person?
Decided by plain code Code answers every such request in the run's own sessions. Without --auto it refuses with a message telling the model nobody can approve, and the model carries on (in the older compatibility mode the run stops instead); with --auto it allows each one once.
noninteractive.ts:158-186· decision D16 in the full map
How it decides it is done
-
How does it decide the turn is finished?
Decided by an AI model Normally, a step that calls no local tool ends the turn, and code then ends the run when no further input is waiting. Nothing reads the final text.
publish-llm-event.ts:649-652· decision G1 in the full map -
When older history is summarised, is the summary good enough to use?
Decided by plain code Code accepts it if any one of its lines matches a heading from the summary template; otherwise it asks once more and checks again, then fails the compaction.
compaction.ts:468-483· decision G2 in the full map -
What does a subagent hand back as its result?
Decided by plain code Normally, the text of the newest completed, error-free reply among the child session's 20 newest messages (after a restart, its whole recovered history is searched); with none, a fixed note that the subagent completed without a text response.
subagent-job.ts:53-61· decision H6 in the full map
Limits and memory
-
When is the conversation summarised to make room?
Decided by plain code Before each step, code compares an estimate of the context size with the model's window minus a reserve (by default at least 15% of the window) and compacts when it is reached. It skips this when automatic compaction is off, right after a compaction, or when the model's window is unknown.
compaction.ts:409-418· decision F1 in the full map -
Who writes the summary that replaces older history?
Decided by an AI model A model: the compaction agent's model when one is configured, otherwise the session's own model, given the conversation and a summary prompt. A plugin can supply the summary instead.
compaction.ts:264-282· decision F2 in the full map -
How many steps can a run take?
Decided by plain code No limit unless the agent sets one. On the step where an agent's limit is reached, code tells the model to answer in text and turns its tools off.
llm.ts:224· decision F10 in the full map -
How much of a tool's output does the model see?
Decided by plain code Unless the tool already cut it, the start of it: up to 2,000 lines and 50 KiB by default. The full text is saved to a file for 7 days and the model is told where.
tool-output.ts:69-120· decision E5 in the full map
Other judgments
-
What does the agent do next?
Decided by an AI model The session's model decides in one call per step: answer in text, or call tools with arguments it chooses. Code then checks each call against the tool's schema.
step.ts:107· decision C1 in the full map -
Which model runs the next step?
Decided by plain code The session's stored model if it is still available, else the step fails. With no stored model, the agent's configured model if available, otherwise the default model, without a warning.
model.ts:77-99· decision A4 in the full map
Three problems in the code
-
1. An agent's chosen model can be swapped for the default without a warning
When a session has no model of its own and the model its agent is set up with is not among the available models, code uses the default model instead. Nothing tells you the agent is running on a different model from the one it was configured with.
Not reported upstream, checked 2026-11-01.
Where:
model.ts:79-87. How we checked: the code was re-read at the source version named above; the sentences were checked by an independent AI reviewer from another company (OpenAI Codex, read-only) on 2026-11-01; every sentence it found too wide was rewritten or removed, and every rewrite was checked again. -
2. A patch change goes to the first lines that match
For the models that edit files through patches (some GPT models), each change is placed at the first spot, searching from the end of the previous change, where its lines match, trying looser matches (ignoring spaces at the ends of lines, then at both ends) when there is no exact match. If the same lines appear more than once, the change goes to the first of them; the edit tool that other models use returns that case to the model as a failure unless it was asked to replace every match.
Not reported upstream, checked 2026-11-01.
Where:
patch.ts:344-360,patch.ts:311-342. How we checked: the code was re-read at the source version named above; the sentences were checked by an independent AI reviewer from another company (OpenAI Codex, read-only) on 2026-11-01; every sentence it found too wide was rewritten or removed, and every rewrite was checked again. -
3. No default limit on a run that keeps repeating itself
By default an agent has no step limit, and the map found no check in the current core for a model that keeps making the same tool calls, so a run whose repeated calls keep succeeding has no built-in limit and can go on until you stop it. opencode's tracker has an open discussion of this (#59339) and an open pull request that proposes loop detection.
Reported; a fix is proposed, not merged (#53032), checked 2026-11-01.
Where:
llm.ts:224,agent.ts:39-52. How we checked: the code was re-read at the source version named above; the sentences were checked by an independent AI reviewer from another company (OpenAI Codex, read-only) on 2026-11-01; every sentence it found too wide was rewritten or removed, and every rewrite was checked again.