Skip to main content

Module opencode

Module opencode 

Source
Expand description

OpenCode: sessions in a SQLite database, not a JSONL log.

Format notes (verified on OpenCode 1.18.15, 2026-09-05, against the live opencode.db on this machine):

  • The store is $XDG_DATA_HOME/opencode/opencode.db (or ~/.local/share/opencode/opencode.db), a WAL SQLite database. agent-top opens it read-only and never writes, which honours the observe-only rule and does not block OpenCode’s own writes.
  • session is one row per conversation and already carries the accounting: directory, agent (the agent type, build / explore / plan), model (a JSON blob {"id","providerID","variant"}), cost (US dollars, computed by OpenCode), tokens_input, tokens_output, tokens_reasoning, tokens_cache_read, tokens_cache_write, time_created, time_updated (epoch ms), parent_id and version. A subagent is a session row whose parent_id is the parent’s id.
  • Because OpenCode has already priced the session, its cost is used directly rather than re-priced from agent-top’s table: OpenCode runs third-party models (DeepSeek, and so on) that the table does not carry, and the harness’s own figure is the real one. So an OpenCode row’s cost is exact and never a floor, and unpriced_tokens is zero.
  • message is one row per message, data JSON with role (user / assistant) and time {created, completed} in epoch ms. A user message opens a turn; each assistant message is one inference, from created to completed, and extends the turn it belongs to, which ends at the last reply before the next prompt. A reply with no completed is still in flight, so its inference and turn stay open. Assistant messages are also the turn count.
  • part is one row per message part, data JSON with type. A tool part has tool (the name), callID and state with status (completed / error / …) and time {start,end} in epoch ms, which is one tool span. step-start / step-finish, reasoning, text and patch parts are not read.
  • MCP tool naming was not observable here (no MCP server is configured), so per-server MCP counts are not produced for OpenCode yet; every tool part is counted as a tool call and a span.

A session has no file of its own, so a tracker is addressed by a virtual path <db>/<session id>: unique, stable, and with the session id as its file stem, which is all the collector and the trace resolver need.

Structs§

OpenCodeAdapter
The OpenCode adapter. See the module notes for the store it reads.
OpenCodeTranscript
One OpenCode session as a SessionSummary, read from the database.
Session
One top-level conversation, enough to attribute it to a process and list it.

Functions§

data_dir
$XDG_DATA_HOME/opencode, or ~/.local/share/opencode.
db_path
The session database, when it exists.
recent_sessions
Top-level sessions (no parent) written since since, newest activity first.
session_id_of
The session id in a virtual path.
session_path
The virtual path that stands for a session on disk: the database path with the session id appended. Never opened as a file; only its stem is read.