| title | Application Workflow Diagram | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| owner | Local_Development | |||||||||||||||||||||
| status | production | |||||||||||||||||||||
| last_verified | 2026-09-13 | |||||||||||||||||||||
| reproduce |
|
packages/opencode/src/provider/gateway/raw-diff.ts/collectReasoning,assembleMessage- Input: a captured response body (SSE chunk array, or raw SSE/non-stream string).
- Output: assembled content/reasoning/tool-calls with the native dialect preserved.
- Logic: dispatch by FIELD, not provider name — a delta contributes
reasoning_content/reasoning_text(native, incremental → concatenated) andreasoning/reasoning_details[].text(OpenRouter, cumulative → suffix-growth dedup). Routing incremental fragments through the cumulative collector corrupts them (to+tool→ol). Measured 2026-09-14: 836 recorded chunks carryingreasoning_contentrendered as "Reasoning (0 chars)".
packages/opencode/src/provider/transform.ts/reasoningCensus- Input: model messages before
unsupportedParts/normalizeMessagesand after. - Output:
assistant/toolCall/cotText/cotEmpty/cotAbsentcounts logged per request, plus a loud warn when the DeepSeek 400-guard fills an emptyreasoning_content. - Logic: the before/after delta localizes CoT loss to inside or upstream of this boundary (262k silent empty tool-call turns measured across 1976 raw-wire dumps). Live read 2026-09-14: mature session
cotAbsent: 11of 42 tool-call turns in →cotEmpty: 11out, warnturns: 9.
- Input: model messages before
patches/@ai-sdk/deepseek@3.0.26.patch/ vendored SDK message conversion- Input: the
@ai-sdk/deepseekpackage'sconvertToDeepSeekChatMessages. - Output: family predicate
/deepseek-(?:v4|flash)/on a lower-cased id, and the "reasoning lives in the tail" rule made unconditional. - Logic: the substring check missed
deepseek-flash(and case alone would missDeepSeek-V4-Flash-…); history CoT is now dropped for the whole family — matching the measured OpenRouter dumps (81% of tail turns carry CoT vs 12% of history) and the KAT no-echo result.
- Input: the
Oracle: bun test test/provider/raw-diff.test.ts test/provider/transform.test.ts test/provider/transform-reasoning-guard.test.ts test/provider/transform-reasoning.test.ts (243 pass) and a live opencode run reading the census line.
provider-sync.ts/PROVIDER_SOURCESregistersstreamlake-vanchinas a visible static provider with the Pay-as-you-go OpenAI-compatible gateway. It intentionally has no bundled account endpoint.DialogProvidergathers the API key through existing auth storage and validates anep-…endpoint ID. It then presents a picker backed bySTREAMLAKE_VANCHIN_MODELS, rather than text fields for guessed capabilities.- The selected official profile patches only
provider.streamlake-vanchin.models.<endpoint-id>with documented context/output limits, reasoning, Function Call, text/image/video input modalities, andoptions.enable_thinking: truefor reasoning profiles./confignever receives the API key. - On request assembly, the profile’s
enable_thinkingoption is forwarded in the OpenAI-compatible provider namespace. Request-levelmodalitiesis deliberately absent: the official protocol reserves it for Qwen-Omni audio output, not generic image/video understanding. - The retired coding-template option is limited to
/api/gateway/coding/v1; it cannot enter the Pay-as-you-govanchin.streamlake.ai/api/gateway/v1/endpointsrequest path. - The Pay-as-you-go gateway did not expose endpoint metadata through six authenticated
GETroutes (all HTTP 400); the endpoint ID is therefore from the Vanchin console and the model metadata from the official catalog snapshot.
Oracle: focused Vanchin state and provider-option tests.
DialogAgentorDialogModelopensDialogRoutingwith an explicit session, worktree, or global write scope.DialogRoutingresolves the effective agent → model → provider routing source and fetches live endpoints for the selected OpenRouter model.dialog-routing-state.tsexposes an existingonlyororderselection, validates nativeprice/throughput/latencysorting, and chooses fp8 by default only when live endpoint metadata supports it.- Choosing dynamic sort clears manual provider selection; choosing a provider clears dynamic sort. Unknown native routing keys survive reconstruction.
- The Save row calls the scope-specific writer once and closes only after that write succeeds. There is no follow-up confirmation dialog.
- Global
/agentsmodel selection STAGES the model inglobal-agent-stage.tswith no follow-up dialog — the agent's variant is carried when the new model declares it, else the default — and the row is marked· unsaved; ctrl+t on a global agent row steps the variant in place, also staged. Nothing is written until the form's ownSave settingsitem, which writes every staged agent one at a time (commitStage→setGlobalAgentSelection/writeGlobalAgentField). There is no per-pick save question (owner, 2026-10-02). - For the active agent only, that explicit global Save writes the chosen model and variant into the open session's settings. Session precedence makes the next prompt and its status row agree with the saved selection; another agent and an in-flight request are not changed.
Oracle: test/tui/dialog-routing-state.test.ts, package typecheck, and cmd_runner TUI render showing sort rows, [x] fp8, Save to GLOBAL config, and Save model and variant.
-
packages/opencode/src/session/tools.ts/SessionTools.resolve- Input: agent/providerAgent/model/session/processor/messages/promptOps/userDisabled.
- Output:
Record<string, AITool>— полный каталог на проводе (registry + MCP + aliases). - Logic: registry-тулы (execute с ACL
denied(): mode + userDisabled + summary-mode guard), MCP-тулы из эра-снапшотаmcpEraStore(wire заморожен per session+model;mcpLiveSigдетектит изменения → defer-лог; execute из живого клиента, при дисконнекте — deny-стаб), alias-регистрация. Wire никогда не режется.
-
packages/opencode/src/tool/registry.ts/ToolRegistry.tools+createEraMemo- Input: providerID/modelID/agent/sessionID.
- Output:
Tool.Def[]с описаниями task/skill. - Logic: описания task/skill вычисляются один раз на эру (per-session memo), замораживаются до
invalidateToolDescriptions(sessionID)(compact / identity mismatch).
-
packages/opencode/src/mcp/index.ts/MCP.tools- Input: connected MCP-клиенты + defs-кэш.
- Output:
Record<string, Tool>в детерминированном порядке (sorted clients, server-listed tools). - Logic: при отсутствии defs — re-fetch (без silent-drop); провал re-fetch → warn «bug:» и пропуск.
-
packages/opencode/src/session/prompt.ts/ summary turn + captureSummary- Input: runLoop state / emergency route input.
- Output: llm.stream с полным каталогом.
- Logic:
summaryAttemptбольше не шлётtools: {}; ин-луп саммари-тур обёрнут вConstitution.setSummaryMode(исполнение заблокировано, схемы на проводе);captureSummaryрезолвит тот же каталог (стаб-processor); compact/identity-mismatch → инвалидация обеих эр (registry + MCP).
-
packages/opencode/src/session/llm.ts/ request shape + stability checks- Input: tools/system/messages/options.
- Output: audit-хэши + warn при дрейфе.
- Logic:
hashInfo(Object.keys(tools))в insertion order;checkToolStability(порядок+описания+схемы, включая_noop) → «bug: tool catalog changed mid-session»;resolveTools= identity (user.tools=false — runtime-deny в SessionTools).
Coverage estimate vs actual codebase: 9%.
-
packages/opencode/src/provider/transform.ts/maxOutputTokens- Input: provider model limits and optional explicit output override.
- Output: output token cap for provider request generation.
- Logic: explicit override wins; normal native output limits are preserved; pathological
output >= contextmetadata is capped to the smaller of native output, default output max, and a context reserve.
-
packages/opencode/src/session/llm.ts/ request parameter assembly- Input: model, prompt messages, provider options, and session context.
- Output: AI SDK stream/generation parameters.
- Logic: pass the capped
maxOutputTokensvalue to the provider request so input plus output cap does not start from an impossible full-context output claim; derive the final provider cache namespace before system assembly and use it in OpenRouter'sx-session-idheader.
-
packages/opencode/src/provider/transform.ts/ OpenRouter request identity- Input: final provider cache namespace (a model-scoped parent key or a reusable child-task lease).
- Output: OpenRouter provider options containing body
session_idandprompt_cache_keyequal to that namespace. - Logic: the OpenRouter SDK spreads these options into the HTTP body. The mutable
[session: …]banner andx-session-idheader use the same value, so a physical child-session ID never splits the affinity/cache sequence.
-
packages/opencode/test/session/llm.test.ts/ qwen-like request capture- Input:
alibaba/qwen-plusfixture with in-memoryoutput == contextoverride. - Output: captured local mock-server request body.
- Logic: verify the outgoing OpenAI-compatible
max_tokensbody field is capped below context.
- Input:
-
packages/opencode/src/session/sidecar-policy.ts+prompt.ts/ Layer-1 summary request- Input: byte-stable checkpoint system/M, full trunk tool catalog, and the synthetic summary user tail.
- Output: at most two requests, each capped at 32,768 output tokens (16K reasoning window + 16K body; only the answer is stored — a floor, not a dial).
- Logic: preserve the trunk
providerCacheKeyand request prefix; Constitution denies tool execution; failed and successful cycles both start the 30s cooldown.
-
packages/opencode/src/session/processor.ts/recordSessionUsage- Input: normalized
finish-stepusage from either a normal turn or the summary sidecar. - Output: shared session token/cost totals plus sidecar cache/cost/duration diagnostics.
- Logic: the sidecar consumes rather than discards
finish-step, classifies raw cache reporting, and uses the same totals writer as the normal processor.
- Input: normalized
-
packages/opencode/src/provider/balance-storage.ts/ cumulative cost baseline- Input: session total at snapshot time and the next session total.
- Output: validation cost delta that includes detached sidecar requests.
- Logic: persist the baseline in the existing snapshot metadata field; use message-row summation only for older or cross-session snapshots.
Coverage estimate vs actual codebase: 10%.
-
packages/opencode/src/session/overflow.ts/usable- Input: config and provider model limits.
- Output: actual-usage threshold derived from explicit input limit or context minus reserved buffer.
- Logic: treat
maxOutputTokensas generation cap only; do not subtract output limit from usage capacity.
-
packages/opencode/src/session/prompt.ts/SessionPrompt.loop- Input: user/session/model/agent state.
- Output: assistant message or loop break.
- Logic: build system prompt and model messages, call
SessionProcessor.process, handle"stop"and"compact", and leave cache metrics passive.
-
packages/opencode/src/session/processor.ts/SessionProcessor.process- Input:
LLM.StreamInput. - Output:
"compact" | "stop" | "continue". - Logic: stream provider events, update message parts, mark interruptions as aborted, run cleanup, return typed outcome.
- Input:
-
packages/opencode/src/session/processor.ts/cacheRatio- Input: token usage with input/cache read/cache write counts.
- Output: passive cache-read ratio.
- Logic: compute cache-read share for diagnostics without changing processor control flow.
-
packages/opencode/src/session/session.ts/Session.updateMessage- Input: message info.
- Output: updated message info.
- Logic: run
MessageV2.Event.Updated, whose projector persists the message row.
-
packages/opencode/src/session/compaction.ts/select- Input: ordered messages, config, model.
- Output:
{ head, tail }whereheadis summarized andtailis preserved. - Logic: keep only the newest real turn in
tailfor regular compaction; keep no extra tail for overflow replay because the replayed user request is inserted after the summary.
-
packages/opencode/src/session/compaction.ts/ compaction continuation- Input: normal system prompt, compaction skill payload, dynamic compaction instruction, and processor result.
- Output: compacted session continuation or stop.
- Logic: summarize the ordered active history before the latest turn, pass the normal system prompt through unchanged, inject the static compaction template as
<skill_content name="compaction">, storetail_count, and preserve database order as compaction summary followed by the latest turn.
Coverage estimate vs actual codebase: 8%.
This diagram covers the modified session-processing and compaction path only, not the full opencode runtime.
-
packages/core/src/global.ts/ module initialization- Input: process launch working directory and executable path.
- Output: initial
Global.Path.*values. - Logic: data/cache/state/log/bin start under the launch working directory; config remains executable-adjacent.
-
packages/opencode/src/project/instance.ts/Instance.provide- Input: requested project directory.
- Output: instance context with project ID and worktree.
- Logic: resolve project metadata, call
Global.initFromWorktree, then run project-scoped initialization inDatabase.withProject.
-
packages/opencode/src/project/project.ts/Project.fromDirectory- Input: requested directory.
- Output:
{ project, sandbox }discovery result. - Logic: import local project DB if present, otherwise honor local opencode config files or child
binconfig files as a boundary, otherwise discover parent git worktree.
-
packages/opencode/src/storage/db.ts/Database.getProjectDb- Input: project ID and resolved worktree.
- Output: SQLite client for
{worktree}/.opencode/data/opencode.db. - Logic: one cached DB connection per project DB path. On first open, logs each native stage, applies
busy_timeout = 5000before WAL mode, and does not run a startup checkpoint.
-
packages/opencode/src/account/repo.ts/AccountRepo.layer- Input: experimental console account operations in the current process.
- Output: active account/org state for that process only.
- Logic: store account rows in memory; no config-level SQLite database or
account.dbfile is created.
Coverage estimate vs actual codebase: 7%.
-
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx/currentExecutableCommand- Input: process executable path, original argv0, and current working directory.
- Output: shell-copyable executable command path.
- Logic: use the launched runtime name for development runtimes, otherwise resolve the packaged executable and prefer a relative path when it is inside the current directory.
-
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx/ session exit message effect- Input: active session title and session ID.
- Output: terminal exit banner with a portable continue command.
- Logic: render
Continue <executable> -s <session>so copied bundles point atbin\\opencode.exeinstead of a possibly unrelatedopencodeonPATH.
Coverage estimate vs actual codebase: 8%.
-
packages/opencode/src/tool/read.ts/isBinaryFile- Input: requested file path and sample bytes.
- Output: binary/text classification.
- Logic: known binary/document extensions, including
.pdf, enter the binary branch before byte heuristics.
-
packages/opencode/src/tool/read.ts/ Windows path normalization- Input: requested file path and active instance directory.
- Output: normalized absolute path for permission and stat checks.
- Logic: drive-less absolute paths such as
/Users/...are resolved on the active project drive instead of the process cwd drive.
-
packages/opencode/src/tool/read.ts/ document conversion branch- Input: binary file bytes and file extension.
- Output:
<content>block containing converted markdown. - Logic: supported non-text document formats call
convertDocument; binary bytes in text-like extensions remain rejected as binary.
-
packages/opencode/src/util/markdownify.ts/resolveBinPath- Input: runtime paths and platform executable suffix.
- Output: resolved
opencode-markdownifypath. - Logic: check packaged cache/bin, executable-adjacent config/bin, actual executable directory, portable project
bin, cwdbin, source-checkoutbin, then development dist locations.
-
packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx/DialogSessionList- Input:
/sessionsand an optional previous worktree supplied by the user. - Output: ordinary sessions labelled with their saved and current paths, plus a recovery entry point.
- Logic: keeps file backup restore separate and delegates portable session recovery to its own dialog.
- Input:
-
packages/opencode/src/session/recovery.ts/preview,restore- Input: an explicit source worktree, one root session ID, and the active instance context.
- Output: a validated preview or an event-replayed session in the current database.
- Logic: source DB is queried only; replay rebases project ID and source-root paths, normalizes the source sequence to a fresh target, and rejects malformed or duplicate streams.
-
packages/opencode/src/effect/runner.ts/ensureRunning,supersede,cancel- Input: work effect; current Runner state (
Idle/Running/RunningThenRun/Shell*). - Output: joined internal-loop result or immediate replacement result; guaranteed-cancel return.
- Logic:
ensureRunningkeeps internal callers joined.supersedeinterrupts the provider-owning fiber, settles the old deferred, drops pending internal work, then starts a new run; the interrupt is bounded so wedged native I/O cannot block replacement. Cancel retains its fire-and-forget 3s interrupt + 2s wait + idempotent force-fail.
- Input: work effect; current Runner state (
-
packages/opencode/src/session/prompt.ts+session/run-state.ts/ user prompt and loop dispatch- Input: a fresh
prompt()or an internalloop()continuation. - Output: a realtime replacement or a joined loop result.
- Logic: a fresh
prompt()persists the user message then dispatchessupersede; directloop()remains joined. Replacement work carries the currentInstanceRef;InstanceState.bind()restores the same project ALS for synchronous system-environment formatting.
- Input: a fresh
-
packages/opencode/src/session/session.ts/patch- Input: sessionID + info patch.
- Output:
session.updatedSyncEvent. - Logic: event carries projectID/directory from InstanceState.context (updatePart parity) — target DB resolves without ambient ALS on Effect fibers.
-
packages/opencode/test/session/prompt.test.ts/ contract alignment- Input: poll/dump diagnostics on timeout.
- Output: tests asserting product contracts, not incidental identities.
- Logic: task-tool polls match by tool part; part-order accepts the static UTC suffix; polls run in-context (detached runPromise loses the database LocalContext).
Coverage estimate vs actual codebase: 9% core-deep; session lifecycle layer now fully documented.
-
packages/opencode/src/project/instance.ts/boot- Input: a normal project launch.
- Output: project context and log setup.
- Logic:
fromDirectoryperforms the normal one-row project upsert; startup does not perform relocation repair or session mutation.
-
packages/opencode/src/project/database-fix.ts/ProjectDatabaseFix.run- Input: current worktree only.
- Output:
{ projects, sessions }update counts. - Logic: reads the saved project root from that DB (or one unambiguous old session path), opens
BEGIN IMMEDIATE, remaps only selected path prefixes, and rolls back on failure.
-
packages/opencode/src/cli/cmd/db.ts/opencode db fix- Input: current working directory.
- Output: a user-visible summary or an error.
- Logic: exposes path repair as an explicit operator action, separate from ordinary startup and
/sessionsevent replay.
-
packages/opencode/src/storage/db.ts/startupStage- Input: a native SQLite startup operation.
- Output: paired start/completion records with duration, or a failure record with the error.
- Logic: establishes the last-known blocking operation even when native SQLite itself cannot be cancelled in-process.
-
packages/opencode/src/project/instance.ts/boot,track- Input: first instance request and its bootstrap phases.
- Output: explicit completion or rejection records, with the failed cache entry evicted.
- Logic: a DB failure is propagated and logged rather than leaving later callers attached to an opaque startup promise.
-
packages/opencode/src/plugin/anthropic.ts/AnthropicAuthPlugin.methods- Input:
/connectoropencode auth login anthropic, then browser or pasted callback input. - Output: OAuth
{ access, refresh, expires, accountId?, email?, orgId?, orgName? }persisted by the existing auth route. - Logic: builds OMP-compatible Claude PKCE parameters, validates callback state on a loopback server (preferred 54545, ephemeral fallback), and exchanges JSON authorization codes at Anthropic's OAuth token endpoint.
- Input:
-
packages/opencode/src/auth/index.ts/Oauth- Input: plugin callback result or a refreshed OAuth token pair.
- Output: encrypted auth record with optional account, organisation, and initial authorization metadata.
- Logic: keeps the existing API-key union untouched; optional fields preserve identity for the OAuth-specific login display without becoming a migration requirement.
-
packages/opencode/src/plugin/anthropic.ts/ auth loader +transformOAuthRequest- Input: stored OAuth credential and the AI SDK's final Anthropic request.
- Output:
POST /v1/messages?beta=truewith Bearer auth, Claude-Code beta/header fingerprint, CCH-attested billing system block, Claude agent identity block, original system blocks/cache markers, and a 64K output ceiling. - Logic: refreshes expired access tokens once, removes the SDK dummy API key, preserves API-key mode when the credential is not OAuth, and never logs token material.
-
prompt_kernel/addons_codex.py/CODEX_GATE_ADDONS- Input: the current Codex harness tool catalog.
- Output: host-specific advisory tool bindings while the core graph remains shared.
- Logic: binds CodeGraph, Read/Glob/Grep, Edit/Write, LSP/AST Edit, Hub,
Eval Browser, Todo, Task, and
cmd_runner; excludes unavailable OpenCode/Claude tools.
-
prompt_kernel/__main__.py/--codex- Input: explicit renderer mode.
- Output: timestamped runtime, review, manifest, and migration artifacts in
prompt_kernel/dist_codex/. - Logic: renders only;
--codex --installreturns an error because the external harness has no repository-local import contract.
-
prompt_kernel/source.py+render.py/ authorization wording- Input: a host whose authorization-inspection tool is not
getmode. - Output: host-neutral core language; the product registry retains its
concrete
getmodeinstruction. - Logic: prevents a shared render from commanding a tool absent on the target host.
- Input: a host whose authorization-inspection tool is not
Coverage estimate vs actual codebase: 9% core-deep; kernel host rendering is now documented for OpenCode, Claude Code, and Codex.
-
packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx/DialogAgent- Input: highlighted agent and selected configuration scope.
- Output: visible
Sampling parameters(ctrl+g) opens the resolved model's parameter editor. - Logic: keeps model selection, variant selection, and sampling independent; configuring a non-active agent never changes the prompt agent.
-
packages/opencode/src/cli/cmd/tui/component/dialog-model-parameters.tsx/DialogModelParameters- Input: model plus session/worktree/global scope.
- Output: editable temperature, repetition penalty, top-p, and presence penalty with Save as the final row.
- Logic: numeric edits remain staged until Save; Escape exits without a write.
-
packages/opencode/src/cli/cmd/tui/context/local.tsx+session/model-sampling.ts- Input: a persisted model key and the selected scope.
- Output: effective sampling values.
- Logic: session state overrides worktree
model.json, which overrides provider model configuration; missing or invalid fields normalize to the four standard defaults.
-
packages/opencode/src/session/llm.ts/LLM.run- Input: effective sampling and selected model.
- Output:
streamTextsampling parameters and namespaced repetition penalty. - Logic: agent-specific temperature/top-p still take precedence; the model-level values control the remaining request surface.
-
packages/opencode/src/cli/cmd/tui/component/dialog-routing.tsx/DialogRouting- Input: asynchronous OpenRouter endpoint data plus keyboard or pointer activation.
- Output: one permanent endpoint-status line, a persistent routing-mode summary, and stable form headings.
- Logic: the first focusable row is the dynamic-sort radio group; keyboard traversal (
routingMoveCursor, heading-skip unit-tested) skips headings, pointer release and Space/Enter share the same action, every dynamic choice clears manual providers, and the summary line is derived byroutingModeLabel(unit-tested). Live loading never inserts/removes status text or changes headings, so the selector does not visibly flash while endpoints resolve.