Documentation
¶
Overview ¶
Package opencode reads the sessions of OpenCode, the TypeScript coding agent (anomalyco/opencode, formerly sst/opencode), in each of the three ways it has stored them under its data directory, ~/.local/share/opencode:
- G1, up to 1.1.65: the storage/ tree, one JSON file per session, message and part (Tree);
- G2, 1.2.0 to 1.19: the V1 tables of opencode.db, session, message and part, whose rows hold the same JSON;
- G3, 2.0.0 on: the V2 tables of the same database, session_v2 and session_message, one row per message.
It imports the standard library alone, so it does not open a database itself: the opencode/sqlite package opens one and yields its rows as this package's types, through the Store interface the storage tree implements too. Not read here: Crush, the Go program once named opencode (opencode-ai/opencode), whose .opencode/opencode.db holds another schema; OpenCode 2's preview opencode-next.db; and the layout OpenCode wrote before its MessageV2 model, project/<dir>/storage/session, which Tree.Legacy lists.
Every object keeps the members it does not declare and writes them back, so a record decoded and encoded again is the same JSON value. A record that cannot be read is a Stray, never an error. The package does not interpret: rebuilding what each request sent, and converting to the Agent Session Format, are the convert subpackage's; docs/formats/opencode.md is the mapping.
Index ¶
- Constants
- Variables
- func Count(raw json.RawMessage) int
- func Databases(dir string) []string
- func FindSessions(root string) ([]string, error)
- func Float(raw json.RawMessage) (float64, bool)
- func Int(raw json.RawMessage) (int64, bool)
- func IsDataDir(dir string) bool
- func IsDatabaseName(name string) bool
- func IsKnownPart(t string) bool
- func IsKnownType(t string) bool
- func IsNull(raw json.RawMessage) bool
- func LocationDirectory(raw json.RawMessage) string
- func MetadataBool(raw json.RawMessage, name string) bool
- func MetadataString(raw json.RawMessage, name string) string
- func Millis(raw json.RawMessage) (int64, bool)
- func ShellOutput(raw json.RawMessage) string
- func SkillText(raw json.RawMessage) (string, bool)
- func SortMessages(gen Generation, ms []*MessageRecord)
- func StoreOf(path string) (string, bool)
- func Truthy(raw json.RawMessage) bool
- func Units(root string) int
- type Cache
- type Column
- type Columns
- type Content2
- type Database
- type File2
- type FileAttachment
- type Fork
- type Generation
- type Members
- type Memory
- func (m *Memory) Messages(s *Session) ([]*MessageRecord, []*Stray, error)
- func (m *Memory) MigrationDone() bool
- func (m *Memory) Name() string
- func (m *Memory) Orphans(map[string]bool) ([]*Stray, error)
- func (m *Memory) Project(id string) (Project, bool)
- func (m *Memory) Rows(s *Session) ([]*Row2, []*QueueRow, error)
- func (m *Memory) Sessions() ([]*Session, []*Stray, error)
- type Message
- type Message2
- type MessageError
- type MessageRecord
- type MessageTime
- type ModelRef
- type Part
- type PartRecord
- type Project
- type QueueRow
- type Revert
- type Row2
- type Session
- type SessionError
- type SessionFile
- type SessionTime
- type Store
- type Stray
- type TaskMetadata
- type Time2
- type Tokens
- type ToolContent
- type ToolState
- type ToolState2
- type ToolTime
- type Tree
- func (t *Tree) Messages(s *Session) ([]*MessageRecord, []*Stray, error)
- func (t *Tree) MigrationDone() bool
- func (t *Tree) Name() string
- func (t *Tree) Orphans(sessions map[string]bool) ([]*Stray, error)
- func (t *Tree) Project(id string) (Project, bool)
- func (t *Tree) Rows(*Session) ([]*Row2, []*QueueRow, error)
- func (t *Tree) Sessions() ([]*Session, []*Stray, error)
Constants ¶
const ( DirStorage = "storage" DirSession = "session" DirMessage = "message" DirPart = "part" DirProject = "project" // DatabaseName is the database OpenCode 1.2 and later keep in the // data directory. DatabaseName = "opencode.db" )
Directory names of a data directory and its storage/ tree.
const ( RoleUser = "user" RoleAssistant = "assistant" )
Message roles of the V1 model.
const ( PartText = "text" PartReasoning = "reasoning" PartFile = "file" PartAgent = "agent" PartCompaction = "compaction" PartSubtask = "subtask" PartRetry = "retry" PartStepStart = "step-start" PartStepFinish = "step-finish" PartSnapshot = "snapshot" PartPatch = "patch" PartTool = "tool" )
Part types of the V1 model, MessageV2.Part.
const ( ToolPending = "pending" ToolRunning = "running" ToolCompleted = "completed" ToolError = "error" )
Tool states of a V1 tool part.
const ( TypeUser = "user" TypeSynthetic = "synthetic" TypeSystem = "system" TypeSkill = "skill" TypeShell = "shell" TypeAssistant = "assistant" TypeCompaction = "compaction" TypeAgentSwitched = "agent-switched" TypeModelSwitched = "model-switched" TypeLocationSwitched = "location-switched" TypeIdle = "idle" )
Types of a V2 session_message row, SessionMessage.Info.
const ( CompactionRunning = "running" CompactionCompleted = "completed" CompactionFailed = "failed" )
Compaction statuses of V2.
const ( ContentText = "text" ContentReasoning = "reasoning" ContentTool = "tool" )
Assistant content types of V2.
const ( Tool2Streaming = "streaming" Tool2Running = "running" Tool2Completed = "completed" Tool2Error = "error" )
Tool states of V2.
const (
ErrorAborted = "MessageAbortedError"
)
Assistant error names of the V1 model.
Variables ¶
var KnownParts = []string{ PartText, PartReasoning, PartFile, PartAgent, PartCompaction, PartSubtask, PartRetry, PartStepStart, PartStepFinish, PartSnapshot, PartPatch, PartTool, }
KnownParts lists the part types OpenCode's V1 model defines.
var KnownTypes = []string{ TypeUser, TypeSynthetic, TypeSystem, TypeSkill, TypeShell, TypeAssistant, TypeCompaction, TypeAgentSwitched, TypeModelSwitched, TypeLocationSwitched, TypeIdle, }
KnownTypes lists the row types OpenCode 2 defines.
Functions ¶
func Count ¶
func Count(raw json.RawMessage) int
Count reads a token count: a non-negative integer, else 0.
func Databases ¶
Databases lists the databases of a data directory other than opencode.db: those of other channels.
func FindSessions ¶
FindSessions lists the OpenCode stores under root: each data directory, each database of another channel in one, and each database file outside one. A file root is returned as it is. A store is converted whole: OpenCode keeps every session of a data directory in one database or one storage/ tree. Directories that cannot be read are passed over, and symbolic links are not followed.
func IsDataDir ¶
IsDataDir reports whether dir is an OpenCode data directory, such as ~/.local/share/opencode: it holds opencode.db, or a storage/ tree with sessions.
func IsDatabaseName ¶
IsDatabaseName reports whether a file name is one OpenCode gives a database: opencode.db, or opencode-<channel>.db for a build of another channel. OpenCode 2's preview database, opencode-next.db, holds another schema and is not one.
func IsKnownPart ¶
IsKnownPart reports whether OpenCode's V1 model defines part type t.
func IsKnownType ¶
IsKnownType reports whether OpenCode 2 defines row type t.
func LocationDirectory ¶
func LocationDirectory(raw json.RawMessage) string
LocationDirectory reads a location-switched row's location.directory.
func MetadataBool ¶
func MetadataBool(raw json.RawMessage, name string) bool
MetadataBool reads a boolean member of a metadata object.
func MetadataString ¶
func MetadataString(raw json.RawMessage, name string) string
MetadataString reads a string member of a metadata object.
func Millis ¶
func Millis(raw json.RawMessage) (int64, bool)
Millis reads an epoch-millisecond time, OpenCode's every timestamp, in the range a time.Time holds.
func ShellOutput ¶
func ShellOutput(raw json.RawMessage) string
ShellOutput reads a shell row's output.output.
func SkillText ¶
func SkillText(raw json.RawMessage) (string, bool)
SkillText reads a V2 user message's skill: its text, when it carries one.
func SortMessages ¶
func SortMessages(gen Generation, ms []*MessageRecord)
SortMessages orders a session's messages as OpenCode reads them: G2 by time_created, then ID; G1 by ID, its file name. Each message's parts are ordered by ID.
func StoreOf ¶
StoreOf returns the store a path names: the data directory it is, or is in, or else the database file itself. A file of the storage/ tree names its data directory, as does opencode.db.
func Truthy ¶
func Truthy(raw json.RawMessage) bool
Truthy reports whether a JSON value is truthy as JavaScript reads it: absent, null, false, 0 and "" are not.
Types ¶
type Cache ¶
type Cache struct {
Read json.RawMessage `json:"read"`
Write json.RawMessage `json:"write"`
Members
}
Cache is a token count's cache reads and writes.
func (Cache) MarshalJSON ¶
MarshalJSON writes the counts back as they were read.
func (*Cache) UnmarshalJSON ¶
UnmarshalJSON decodes the counts, keeping undeclared members.
type Column ¶
Column is one column of a database row: its name and its value as database/sql scans it, an int64, float64, string, []byte or nil.
type Columns ¶
type Columns []Column
Columns is a row of a table, in the table's column order.
func (Columns) JSON ¶
func (cs Columns) JSON() json.RawMessage
JSON writes the row as one JSON object, a member per column in the table's order: a JSON text column as the value it holds when it holds one, text as a string, a number as a number, null as null, and a blob as base64 text.
type Content2 ¶
type Content2 struct {
Type string `json:"type"`
Text string `json:"text"`
State json.RawMessage `json:"state"`
Time json.RawMessage `json:"time"`
ID string `json:"id"`
Name string `json:"name"`
Executed bool `json:"executed"`
ProviderState json.RawMessage `json:"providerState"`
ProviderResultState json.RawMessage `json:"providerResultState"`
Members
}
Content2 is one item of a V2 assistant's content: text, reasoning or a tool. State is the provider state of text and reasoning, and the ToolState2 of a tool, which Content2.Tool decodes.
func (Content2) MarshalJSON ¶
MarshalJSON writes the item back as it was read.
func (*Content2) ReasoningDone ¶
ReasoningDone reports whether a reasoning item's time says it completed; an item with no time is taken as completed, as OpenCode reads it.
func (*Content2) Tool ¶
func (c *Content2) Tool() (*ToolState2, error)
Tool decodes a tool item's state.
func (*Content2) UnmarshalJSON ¶
UnmarshalJSON decodes an item, keeping undeclared members and members of another JSON type.
type File2 ¶
type File2 struct {
Data string `json:"data"`
Mime string `json:"mime"`
Name string `json:"name"`
Description *string
Source struct {
Type string `json:"type"`
URI string `json:"uri"`
} `json:"source"`
Mention *struct {
Text string `json:"text"`
} `json:"mention"`
}
File2 is a V2 user message's attachment, FileAttachment: base64 data, its mime type, where it came from, and how it was mentioned.
func DecodeFile2 ¶
func DecodeFile2(raw json.RawMessage) (File2, bool)
DecodeFile2 reads an attachment; false when it is not an object.
type FileAttachment ¶
type FileAttachment struct {
Mime string `json:"mime"`
Filename string `json:"filename"`
URL string `json:"url"`
}
FileAttachment is the file part a completed tool state's attachments hold, or a user message's file part: the members a converter reads.
func Attachment ¶
func Attachment(raw json.RawMessage) (FileAttachment, bool)
Attachment decodes one attachment; false when it is not a file part.
type Generation ¶
type Generation int
Generation is one of OpenCode's three ways of storing sessions.
const ( // G1 is the storage/ tree of JSON files, up to 1.1.65. G1 Generation = 1 // G2 is the V1 tables of opencode.db, session, message and part, // from 1.2.0 to 1.19. G2 Generation = 2 // G3 is the V2 tables of opencode.db, session_v2 and // session_message, from 2.0.0. G3 Generation = 3 )
func (Generation) String ¶
func (g Generation) String() string
String names the generation as the documents do.
type Members ¶
Members is embedded in every object this package decodes. It keeps the members the Go type does not declare, and remembers which declared members the input carried and which were null, so an object decoded and encoded again is the same JSON value.
type Memory ¶
type Memory struct {
StoreName string
SessionList []*Session
Strays []*Stray
// MessagesOf holds each V1 session's messages, by session ID.
MessagesOf map[string][]*MessageRecord
// RowsOf and QueueOf hold each V2 session's rows and queued input.
RowsOf map[string][]*Row2
QueueOf map[string][]*QueueRow
Projects map[string]Project
Migrated bool
// contains filtered or unexported fields
}
Memory is a store held in memory: what a test or a fuzz target builds, or a reader that has its records already.
func (*Memory) Messages ¶
func (m *Memory) Messages(s *Session) ([]*MessageRecord, []*Stray, error)
Messages returns a V1 session's messages, ordered as its generation orders them.
func (*Memory) MigrationDone ¶
MigrationDone reports Migrated.
type Message ¶
type Message struct {
ID string `json:"id"`
SessionID string `json:"sessionID"`
Role string `json:"role"`
Time *MessageTime `json:"time"`
// A user message's.
Agent string `json:"agent"`
Model *ModelRef `json:"model"`
System string `json:"system"`
Tools json.RawMessage `json:"tools"`
Format json.RawMessage `json:"format"`
Variant string `json:"variant"`
// Summary is an object on a user message and true on an assistant
// message that holds a compaction's summary.
Summary json.RawMessage `json:"summary"`
// An assistant message's.
ParentID string `json:"parentID"`
ModelID string `json:"modelID"`
ProviderID string `json:"providerID"`
Mode string `json:"mode"`
Path json.RawMessage `json:"path"`
Cost json.RawMessage `json:"cost"`
Tokens *Tokens `json:"tokens"`
Error *MessageError `json:"error"`
Finish string `json:"finish"`
Structured json.RawMessage `json:"structured"`
Members
}
Message is a V1 message's info, MessageV2.Info: a user message or an assistant one, told apart by Role. A G1 file holds it whole; a G2 row's data holds it without id and sessionID, which the row's columns carry.
func (*Message) IsSummary ¶
IsSummary reports whether an assistant message holds a compaction's summary.
func (Message) MarshalJSON ¶
MarshalJSON writes the message back as it was read.
func (*Message) UnmarshalJSON ¶
UnmarshalJSON decodes a message, keeping undeclared members and members of another JSON type.
type Message2 ¶
type Message2 struct {
Metadata json.RawMessage `json:"metadata"`
Time *Time2 `json:"time"`
// user, synthetic, system, skill
Text string `json:"text"`
Description string `json:"description"`
Files []json.RawMessage `json:"files"`
Agents json.RawMessage `json:"agents"`
Skills []json.RawMessage `json:"skills"`
Skill string `json:"skill"`
Name string `json:"name"`
// shell
ShellID string `json:"shellID"`
Command string `json:"command"`
Status string `json:"status"`
Exit json.RawMessage `json:"exit"`
Output json.RawMessage `json:"output"`
// assistant, and the switches
Agent string `json:"agent"`
Model *ModelRef `json:"model"`
Previous json.RawMessage `json:"previous"`
Content []json.RawMessage `json:"content"`
Snapshot json.RawMessage `json:"snapshot"`
Finish string `json:"finish"`
RawFinish string `json:"rawFinish"`
ProviderState json.RawMessage `json:"providerState"`
Cost json.RawMessage `json:"cost"`
Tokens *Tokens `json:"tokens"`
Error *SessionError `json:"error"`
Retry json.RawMessage `json:"retry"`
// compaction
Reason string `json:"reason"`
Summary string `json:"summary"`
Recent string `json:"recent"`
ProviderContext json.RawMessage `json:"providerContext"`
// location-switched
Location json.RawMessage `json:"location"`
ProjectID string `json:"projectID"`
Subpath string `json:"subpath"`
// idle
Outcome string `json:"outcome"`
Members
}
Message2 is the data of a V2 session_message row: the message without its id and type, which the row's columns carry. Which members it has depends on the row's type; a member one type declares with another JSON type than another type does is kept raw.
func (Message2) MarshalJSON ¶
MarshalJSON writes the data back as it was read.
func (*Message2) UnmarshalJSON ¶
UnmarshalJSON decodes a row's data, keeping undeclared members and members of another JSON type.
type MessageError ¶
type MessageError struct {
Name string `json:"name"`
Data json.RawMessage `json:"data"`
Members
}
MessageError is a V1 assistant message's error: a name and its data.
func (MessageError) MarshalJSON ¶
func (e MessageError) MarshalJSON() ([]byte, error)
MarshalJSON writes the error back as it was read.
func (*MessageError) Message ¶
func (e *MessageError) Message() string
Message is the error's data.message, when it has one.
func (*MessageError) UnmarshalJSON ¶
func (e *MessageError) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes the error, keeping undeclared members.
type MessageRecord ¶
type MessageRecord struct {
Unit string
ID string
// Created is when OpenCode orders the message by: the row's
// time_created (G2), or info's time.created (G1).
Created int64
Info *Message
// Raw is the message's object as read: a G1 file's contents, or a
// G2 row's data.
Raw json.RawMessage
// Err says why the message could not be read; its parts are then
// strays.
Err error
Parts []*PartRecord
}
MessageRecord is one V1 message as read, with its parts.
func DecodeMessage ¶
func DecodeMessage(unit, id, sessionID string, created int64, data []byte) *MessageRecord
DecodeMessage reads a V1 message: a G1 file's contents, or a G2 row's data with the row's id and session.
type MessageTime ¶
type MessageTime struct {
Created json.RawMessage `json:"created"`
Completed json.RawMessage `json:"completed"`
Members
}
MessageTime is a message's time.
func (MessageTime) MarshalJSON ¶
func (t MessageTime) MarshalJSON() ([]byte, error)
MarshalJSON writes the times back as they were read.
func (*MessageTime) UnmarshalJSON ¶
func (t *MessageTime) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes the times, keeping undeclared members.
type ModelRef ¶
type ModelRef struct {
ProviderID string `json:"providerID"`
ModelID string `json:"modelID"`
ID string `json:"id"`
Variant string `json:"variant"`
Members
}
ModelRef is a model reference: a V1 user message's model {providerID, modelID, variant}, or V2's {providerID, id, variant}.
func (ModelRef) MarshalJSON ¶
MarshalJSON writes the reference back as it was read.
func (*ModelRef) UnmarshalJSON ¶
UnmarshalJSON decodes the reference, keeping undeclared members.
type Part ¶
type Part struct {
ID string `json:"id"`
SessionID string `json:"sessionID"`
MessageID string `json:"messageID"`
Type string `json:"type"`
// text and reasoning; Metadata is the AI SDK's provider metadata on
// text and reasoning, a tool part's call-side metadata on a tool.
Text string `json:"text"`
Synthetic bool `json:"synthetic"`
Ignored bool `json:"ignored"`
Time json.RawMessage `json:"time"`
Metadata json.RawMessage `json:"metadata"`
// file
Mime string `json:"mime"`
Filename string `json:"filename"`
URL string `json:"url"`
Source json.RawMessage `json:"source"`
// agent
Name string `json:"name"`
// compaction
Auto bool `json:"auto"`
Overflow bool `json:"overflow"`
TailStartID string `json:"tail_start_id"`
// subtask
Prompt string `json:"prompt"`
Description string `json:"description"`
Agent string `json:"agent"`
Model json.RawMessage `json:"model"`
Command string `json:"command"`
// retry
Attempt json.RawMessage `json:"attempt"`
Error json.RawMessage `json:"error"`
// step-start, step-finish, snapshot, patch
Snapshot string `json:"snapshot"`
Reason string `json:"reason"`
Cost json.RawMessage `json:"cost"`
Tokens *Tokens `json:"tokens"`
Hash string `json:"hash"`
Files json.RawMessage `json:"files"`
// tool
CallID string `json:"callID"`
Tool string `json:"tool"`
State *ToolState `json:"state"`
Members
}
Part is one part of a V1 message, MessageV2.Part, told apart by Type. A G1 file holds it whole; a G2 row's data holds it without id, sessionID and messageID.
func (Part) MarshalJSON ¶
MarshalJSON writes the part back as it was read.
func (*Part) UnmarshalJSON ¶
UnmarshalJSON decodes a part, keeping undeclared members and members of another JSON type.
type PartRecord ¶
type PartRecord struct {
Unit string
ID string
MessageID string
Part *Part
Raw json.RawMessage
Err error
}
PartRecord is one V1 part as read.
func DecodePart ¶
func DecodePart(unit, id, messageID string, data []byte) *PartRecord
DecodePart reads a V1 part: a G1 file's contents, or a G2 row's data with the row's id and message.
type QueueRow ¶
type QueueRow struct {
Unit string
Table string
ID string
Type string
// Seq is admitted_seq or enqueued_seq.
Seq int64
Created int64
Record json.RawMessage
}
QueueRow is a row of session_pending or session_inbox: input OpenCode 2 has queued and not yet put in the history.
func DecodeQueueRow ¶
DecodeQueueRow reads a session_pending or session_inbox row.
type Revert ¶
Revert is a staged revert: the message it starts at, and the part within it, when it starts at one.
type Row2 ¶
type Row2 struct {
Unit string
ID string
SessionID string
Type string
Seq int64
Created int64
Updated int64
Data *Message2
// Raw is the row's data as read.
Raw json.RawMessage
Err error
}
Row2 is one V2 session_message row as read.
func DecodeRow2 ¶
DecodeRow2 reads a session_message row.
type Session ¶
type Session struct {
Gen Generation
// Unit names the record in findings: a file's path under the data
// directory, or <database>:<table>/<id>.
Unit string
ID, ProjectID, WorkspaceID, ParentID string
// ForkSessionID is a V2 fork's origin, and ForkBoundary where it was
// forked: {type: before|through, messageID}.
ForkSessionID string
ForkBoundary json.RawMessage
Slug string
Directory string
Path string
Title string
// Version is the OpenCode release that created the session.
Version string
Agent string
Model *ModelRef
// Revert is a staged revert, {messageID, partID?, snapshot?, …}.
Revert json.RawMessage
// Created and Updated are in milliseconds; HasCreated says the
// record holds a creation time.
Created, Updated int64
HasCreated bool
// Record is the session as read: the file's object, or the row's
// columns as one object.
Record json.RawMessage
// Err says why the record could not be read; only Unit and, when
// the file name or row gave it, ID are then set.
Err error
}
Session is one copy of a session's record, from any generation: the members a converter reads, and the record itself.
func DecodeSessionFile ¶
DecodeSessionFile reads a G1 session file's contents.
func DecodeSessionRow ¶
func DecodeSessionRow(gen Generation, unit string, cols Columns) *Session
DecodeSessionRow reads a row of the session table (G2) or the session_v2 table (G3).
func (*Session) StagedRevert ¶
StagedRevert reads the session's staged revert; false when none is staged.
type SessionError ¶
SessionError is V2's error: a type, such as provider.rate-limit, permission.rejected or aborted, and a message.
func (SessionError) MarshalJSON ¶
func (e SessionError) MarshalJSON() ([]byte, error)
MarshalJSON writes the error back as it was read.
func (*SessionError) UnmarshalJSON ¶
func (e *SessionError) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes the error, keeping undeclared members.
type SessionFile ¶
type SessionFile struct {
ID string `json:"id"`
Slug string `json:"slug"`
ProjectID string `json:"projectID"`
WorkspaceID string `json:"workspaceID"`
Directory string `json:"directory"`
Path string `json:"path"`
ParentID string `json:"parentID"`
Title string `json:"title"`
Version string `json:"version"`
Agent string `json:"agent"`
Model *ModelRef `json:"model"`
Revert json.RawMessage `json:"revert"`
Time *SessionTime `json:"time"`
Members
}
SessionFile is a G1 session file, Session.Info: the members a converter reads, the rest kept.
func (SessionFile) MarshalJSON ¶
func (s SessionFile) MarshalJSON() ([]byte, error)
MarshalJSON writes the session back as it was read.
func (*SessionFile) UnmarshalJSON ¶
func (s *SessionFile) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes the session, keeping undeclared members and members of another JSON type.
type SessionTime ¶
type SessionTime struct {
Created json.RawMessage `json:"created"`
Updated json.RawMessage `json:"updated"`
Members
}
SessionTime is a G1 session's time.
func (SessionTime) MarshalJSON ¶
func (t SessionTime) MarshalJSON() ([]byte, error)
MarshalJSON writes the times back as they were read.
func (*SessionTime) UnmarshalJSON ¶
func (t *SessionTime) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes the times, keeping undeclared members.
type Store ¶
type Store interface {
// Name names the store in findings: "storage", or the database's
// file name.
Name() string
// Sessions lists every session record the store holds, in any
// generation, and the records that could not be read as one.
Sessions() ([]*Session, []*Stray, error)
// Messages reads a V1 session's messages with their parts, in the
// order OpenCode reads them, and the records read with them that
// belong to none of its messages.
Messages(s *Session) ([]*MessageRecord, []*Stray, error)
// Rows reads a V2 session's rows in seq order, and its queued
// input.
Rows(s *Session) ([]*Row2, []*QueueRow, error)
// Orphans lists the message, part and row records that name a
// session not in the set, or a message that does not exist.
Orphans(sessions map[string]bool) ([]*Stray, error)
// Project reads a project record.
Project(id string) (Project, bool)
// MigrationDone reports whether OpenCode 2 finished copying the V1
// tables into its own, as its kv table records.
MigrationDone() bool
}
Store is the records of one OpenCode store: the storage/ tree of a data directory, or a database. Records are read on demand, a session at a time.
type Stray ¶
type Stray struct {
Unit string
// Session names the session it was read with, when it was.
Session string
// ID is the record's ID, when it has one.
ID string
// Kind says what the record is: "session", "message", "part", "row";
// "directory" or "table" for what holds records and is not one.
Kind string
// Why says why it is a stray, and Err the error behind it, when one
// is.
Why string
Err error
// Malformed says the record could not be read at all.
Malformed bool
}
Stray is a record read that belongs to no session it can be converted with: a part of no message, a message of no session, a file or row that cannot be read.
type TaskMetadata ¶
TaskMetadata is what a V1 task tool part's state metadata says of the sub-agent it ran, and V2's subagent tool.
type Time2 ¶
type Time2 struct {
Created json.RawMessage `json:"created"`
Streamed json.RawMessage `json:"streamed"`
Completed json.RawMessage `json:"completed"`
Members
}
Time2 is a V2 message's time.
func (Time2) MarshalJSON ¶
MarshalJSON writes the times back as they were read.
func (*Time2) UnmarshalJSON ¶
UnmarshalJSON decodes the times, keeping undeclared members.
type Tokens ¶
type Tokens struct {
Total json.RawMessage `json:"total"`
Input json.RawMessage `json:"input"`
Output json.RawMessage `json:"output"`
Reasoning json.RawMessage `json:"reasoning"`
Cache *Cache `json:"cache"`
Members
}
Tokens is a token count: a V1 assistant message's or step-finish part's, or V2's TokenUsage. Input counts neither cache reads nor cache writes.
func (Tokens) MarshalJSON ¶
MarshalJSON writes the counts back as they were read.
func (*Tokens) UnmarshalJSON ¶
UnmarshalJSON decodes the counts, keeping undeclared members.
type ToolContent ¶
type ToolContent struct {
Type string `json:"type"`
Text string `json:"text"`
URI string `json:"uri"`
Mime string `json:"mime"`
Name string `json:"name"`
}
ToolContent is one item of a V2 tool's content: text, or a file by URI.
func DecodeToolContent ¶
func DecodeToolContent(raw json.RawMessage) (ToolContent, bool)
DecodeToolContent reads one content item; false when it is not an object.
type ToolState ¶
type ToolState struct {
Status string `json:"status"`
Input json.RawMessage `json:"input"`
Raw string `json:"raw"`
Output string `json:"output"`
Title string `json:"title"`
Metadata json.RawMessage `json:"metadata"`
Time *ToolTime `json:"time"`
Error string `json:"error"`
Attachments []json.RawMessage `json:"attachments"`
Members
}
ToolState is a V1 tool part's state, by Status: pending holds input and raw; running input, title, metadata and time; completed input, output, title, metadata, time and attachments; error input, error, metadata and time.
func (*ToolState) Compacted ¶
Compacted reports whether a completed tool state's output was pruned, and when, in milliseconds.
func (*ToolState) Interrupted ¶
Interrupted returns the output an errored tool call cleaned up after an abort carries, metadata.output with metadata.interrupted true, which OpenCode sends as the call's output.
func (ToolState) MarshalJSON ¶
MarshalJSON writes the state back as it was read.
func (*ToolState) Task ¶
func (s *ToolState) Task() TaskMetadata
Task reads a task tool state's metadata: V1 writes sessionId, V2 sessionID.
func (*ToolState) UnmarshalJSON ¶
UnmarshalJSON decodes the state, keeping undeclared members and members of another JSON type.
type ToolState2 ¶
type ToolState2 struct {
Status string `json:"status"`
Input json.RawMessage `json:"input"`
Content []json.RawMessage `json:"content"`
Error *SessionError `json:"error"`
Metadata json.RawMessage `json:"metadata"`
Members
}
ToolState2 is a V2 tool's state: streaming holds input as a string, the others as an object; completed holds content, error an error and perhaps content.
func (ToolState2) MarshalJSON ¶
func (s ToolState2) MarshalJSON() ([]byte, error)
MarshalJSON writes the state back as it was read.
func (*ToolState2) Task ¶
func (s *ToolState2) Task() TaskMetadata
Task reads a subagent tool state's metadata: the child session, and whether it runs in the background.
func (*ToolState2) UnmarshalJSON ¶
func (s *ToolState2) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes the state, keeping undeclared members and members of another JSON type.
type ToolTime ¶
type ToolTime struct {
Start json.RawMessage `json:"start"`
End json.RawMessage `json:"end"`
Compacted json.RawMessage `json:"compacted"`
Members
}
ToolTime is a tool state's time. Compacted is set when OpenCode pruned the output: every request after it sent a placeholder.
func (ToolTime) MarshalJSON ¶
MarshalJSON writes the times back as they were read.
func (*ToolTime) UnmarshalJSON ¶
UnmarshalJSON decodes the times, keeping undeclared members.
type Tree ¶
type Tree struct {
// Root is the data directory.
Root string
// Legacy lists the directories of the layout OpenCode wrote before
// its MessageV2 model, project/<dir>/storage/session, which this
// package does not read.
Legacy []string
// contains filtered or unexported fields
}
Tree is the storage/ tree of a data directory, the G1 store: one JSON file per session, message and part. It is read on demand; a session's messages and parts are read when Tree.Messages is called. A Tree is not safe for concurrent use.
func (*Tree) Messages ¶
func (t *Tree) Messages(s *Session) ([]*MessageRecord, []*Stray, error)
Messages reads a session's message files and each one's part files.
func (*Tree) MigrationDone ¶
MigrationDone: the storage tree is not migrated.
func (*Tree) Orphans ¶
Orphans lists the message files of sessions not in the set, and the part files of messages no session read named.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package convert converts OpenCode's sessions into the Agent Session Format: a data directory's storage files, its database's V1 tables and its V2 tables, each session converted once, from the copy that holds the most of what its model saw.
|
Package convert converts OpenCode's sessions into the Agent Session Format: a data directory's storage files, its database's V1 tables and its V2 tables, each session converted once, from the copy that holds the most of what its model saw. |
|
Package sqlite opens OpenCode's database, opencode.db, and reads its rows as the opencode package's types: the V1 tables session, message and part, and the V2 tables session_v2, session_message, session_pending and session_inbox.
|
Package sqlite opens OpenCode's database, opencode.db, and reads its rows as the opencode package's types: the V1 tables session, message and part, and the V2 tables session_v2, session_message, session_pending and session_inbox. |