Documentation
¶
Overview ¶
Package atif reads ATIF, the Agent Trajectory Interchange Format that Harbor (github.com/laude-institute/harbor) defines in its RFC 0001 and its Pydantic models: one JSON document per trajectory, holding the agent, its steps, and optionally embedded sub-agent trajectories. It imports the standard library alone.
A document is decoded block by block: the root, the agent, each step, each tool call, observation result, content part and reference on its own. Every object keeps the members it does not declare and writes them back, so a document read and written again is the same JSON value; a block that is not an object is kept as written with its error, and its neighbours still read. Numbers are kept as written, so a token count spelled 12.0 survives; Int and Float read them as leniently as Harbor's models do. A document cut short, which a producer that rewrites its file in place can leave, is salvaged: the root members and steps that end before the cut are read, and the cut is reported.
Read, Parse and ReadFile read a document; Probe tells an ATIF file from another JSON file; FindSessions lists the ATIF files under a directory and Names the related files a document names. The reader does not interpret: resolving references and continuations, and converting to the Agent Session Format, are the convert subpackage's; docs/formats/atif.md is the mapping.
Index ¶
- Constants
- Variables
- func FindSessions(root string) ([]string, error)
- func Float(raw json.RawMessage) (float64, bool)
- func Int(raw json.RawMessage) (n int64, plain, ok bool)
- func IsNull(raw json.RawMessage) bool
- func Names(t *Trajectory, dir string) []string
- func Probe(path string) (string, bool)
- type Agent
- type Content
- type File
- type Members
- type Metrics
- type Object
- type Observation
- type Part
- type Ref
- type Refs
- type Result
- type Source
- type Step
- type ToolCall
- type Trajectory
Constants ¶
const ( SourceSystem = "system" SourceUser = "user" SourceAgent = "agent" )
Step sources.
const ( PartText = "text" PartImage = "image" PartAudio = "audio" )
Content part types.
const MaxSize = 1 << 30
MaxSize bounds a document. A larger file is refused rather than read into memory.
Variables ¶
var ErrNotDocument = errors.New("atif: not a JSON object")
ErrNotDocument is returned for bytes that are not a JSON object, nor the start of one.
var Versions = []string{
"ATIF-v1.0", "ATIF-v1.1", "ATIF-v1.2", "ATIF-v1.3", "ATIF-v1.4",
"ATIF-v1.5", "ATIF-v1.6", "ATIF-v1.7", "ATIF-v1.8",
}
Versions lists the schema versions Harbor's models accept, oldest first. A document may declare another; it is read with the newest version's members.
Functions ¶
func FindSessions ¶
FindSessions returns the ATIF documents under root: every *.json file at any depth that Probe accepts, sorted. root may be a directory of Harbor jobs, one trial, or a single file, which is returned as it is. A directory that cannot be read is skipped.
func Float ¶
func Float(raw json.RawMessage) (float64, bool)
Float reads a number kept as written, or a string of one.
func Int ¶
func Int(raw json.RawMessage) (n int64, plain, ok bool)
Int reads a count kept as written: an integer, or a number with no fraction such as 12.0, or a string of one, as Harbor's models read it leniently. plain says the value was a bare integer. ok is false for an absent or null value, or one that is no integer.
func IsNull ¶
func IsNull(raw json.RawMessage) bool
IsNull reports whether raw is absent or JSON null.
func Names ¶
func Names(t *Trajectory, dir string) []string
Names lists the files a document names, joined to dir when relative and cleaned, in the order the document names them: its continuation, then each sub-agent reference's trajectory_path, in its own steps and in those of every trajectory it embeds. A URL is not a file and is left out.
Types ¶
type Agent ¶
type Agent struct {
Name string `json:"name"`
Version string `json:"version"`
ModelName string `json:"model_name"`
// ToolDefinitions are OpenAI chat-completions tool objects,
// {"type":"function","function":{name,description,parameters}},
// kept as written.
ToolDefinitions []json.RawMessage `json:"tool_definitions"`
Ext json.RawMessage `json:"extra"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Agent describes the agent that produced the trajectory.
func (Agent) MarshalJSON ¶
MarshalJSON writes the agent back as it was read.
func (*Agent) UnmarshalJSON ¶
UnmarshalJSON decodes an agent, keeping undeclared members; a value that is not an object is kept with Err set.
type Content ¶
type Content struct {
Text string
Parts []*Part
// IsText says the value was a string, the empty string included.
IsText bool
// Raw is a value that is neither, kept as written.
Raw json.RawMessage
}
Content is a message or result content: a string, or, since v1.6, a list of parts.
func (Content) MarshalJSON ¶
MarshalJSON writes the content back in the form it was read.
func (Content) String ¶
String is the content's text: the string, or the text parts joined with newlines.
func (*Content) UnmarshalJSON ¶
UnmarshalJSON accepts a string or a list of parts; anything else is kept in Raw.
type File ¶
type File struct {
// Path is the file the document was read from; empty when it was
// read from a reader.
Path string
// Doc is the document, or, when Cut is set, what of it the reader
// could read.
Doc *Trajectory
// Cut is set when the document does not parse to its end, as a file
// a producer was rewriting in place when it was killed does not:
// Doc then holds the root members and the steps that end before
// CutAt, the byte after the last value that parsed. It is taken
// where the parse last succeeded, not where it failed, since where
// encoding/json stops on an error differs between Go releases.
Cut error
CutAt int64
// CutStep says a step was cut short. It is a unit the reader could
// not read, and is not among Doc's steps.
CutStep bool
// CutMembers lists the root members that were cut short, or that
// follow the cut, as far as the reader can tell: those whose name
// it read.
CutMembers []string
}
File is one ATIF document as read.
func Read ¶
Read reads a document. A step, tool call, result, part or embedded trajectory that is not an object is kept with its error and its neighbours still read; a document cut short is salvaged and Cut set. Read fails when r does, when the document exceeds MaxSize, and with ErrNotDocument for bytes that are not a JSON object.
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 Metrics ¶
type Metrics struct {
// PromptTokens counts all input, cached tokens included.
PromptTokens json.RawMessage `json:"prompt_tokens"`
// CompletionTokens counts all output, reasoning included.
CompletionTokens json.RawMessage `json:"completion_tokens"`
// CachedTokens is the part of PromptTokens read from a cache.
CachedTokens json.RawMessage `json:"cached_tokens"`
CostUSD json.RawMessage `json:"cost_usd"`
PromptTokenIDs json.RawMessage `json:"prompt_token_ids"`
CompletionTokenIDs json.RawMessage `json:"completion_token_ids"`
Logprobs json.RawMessage `json:"logprobs"`
Ext json.RawMessage `json:"extra"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Metrics is an agent step's usage. Counts are kept as written.
func (Metrics) MarshalJSON ¶
MarshalJSON writes the metrics back as they were read.
func (*Metrics) UnmarshalJSON ¶
UnmarshalJSON decodes metrics, keeping undeclared members; a value that is not an object is kept with Err set.
type Object ¶
type Object struct {
Raw json.RawMessage
}
Object is a JSON object kept as written, such as final_metrics, which the converter carries but does not interpret.
func (Object) MarshalJSON ¶
MarshalJSON writes the value back.
func (*Object) UnmarshalJSON ¶
UnmarshalJSON keeps the value as written.
type Observation ¶
type Observation struct {
Results []*Result `json:"results"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Observation holds what a step's actions produced.
func (Observation) MarshalJSON ¶
func (o Observation) MarshalJSON() ([]byte, error)
MarshalJSON writes the observation back as it was read.
func (*Observation) UnmarshalJSON ¶
func (o *Observation) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes an observation, keeping undeclared members; a value that is not an object is kept with Err set.
type Part ¶
type Part struct {
Type string `json:"type"`
Text string `json:"text"`
Source *Source `json:"source"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Part is one content part: text, an image or, since v1.8, audio. Media is always named by a path or URL, never inline.
func (Part) MarshalJSON ¶
MarshalJSON writes the part back as it was read.
func (*Part) UnmarshalJSON ¶
UnmarshalJSON decodes a part; a value that is not an object is kept with Err set.
type Ref ¶
type Ref struct {
TrajectoryID string `json:"trajectory_id"`
SessionID string `json:"session_id"`
TrajectoryPath string `json:"trajectory_path"`
Ext json.RawMessage `json:"extra"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Ref names a sub-agent's trajectory: by trajectory_id, an embedded trajectory of the same document, or by trajectory_path, a file. session_id alone, as references before v1.7 could, resolves nothing.
func (Ref) MarshalJSON ¶
MarshalJSON writes the reference back as it was read.
func (*Ref) UnmarshalJSON ¶
UnmarshalJSON decodes a reference; a value that is not an object is kept with Err set.
type Refs ¶
type Refs struct {
List []*Ref
// Object says the member was one object rather than a list.
Object bool
// Raw is a value that is neither, kept as written.
Raw json.RawMessage
}
Refs is a result's subagent_trajectory_ref: a list of references, or, as RFC 0001 v1.0 wrote it, one reference object.
func (Refs) MarshalJSON ¶
MarshalJSON writes the references back in the form they were read.
func (*Refs) UnmarshalJSON ¶
UnmarshalJSON accepts a list or one object; anything else is kept in Raw.
type Result ¶
type Result struct {
// SourceCallID names a tool call of the same step; empty when the
// result names none (absent or null).
SourceCallID string `json:"source_call_id"`
Content Content `json:"content"`
Refs Refs `json:"subagent_trajectory_ref"`
Ext json.RawMessage `json:"extra"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Result is one observation result: a tool call's output, or, with no source_call_id, the output of a non-tool action or system operation.
func (Result) MarshalJSON ¶
MarshalJSON writes the result back as it was read.
func (*Result) UnmarshalJSON ¶
UnmarshalJSON decodes a result; a value that is not an object is kept with Err set.
type Source ¶
type Source struct {
MediaType string `json:"media_type"`
// Path is relative to the document's directory, absolute, or a URL.
Path string `json:"path"`
// DurationSec is an audio clip's length, kept as written.
DurationSec json.RawMessage `json:"duration_sec"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Source is a media part's file: an image's or an audio clip's.
func (Source) MarshalJSON ¶
MarshalJSON writes the source back as it was read.
func (*Source) UnmarshalJSON ¶
UnmarshalJSON decodes a source, keeping undeclared members; a value that is not an object is kept with Err set.
type Step ¶
type Step struct {
// StepID is the 1-based ordinal, kept as written.
StepID json.RawMessage `json:"step_id"`
Timestamp string `json:"timestamp"`
Source string `json:"source"`
ModelName string `json:"model_name"`
// ReasoningEffort is a string or a number, kept as written.
ReasoningEffort json.RawMessage `json:"reasoning_effort"`
Message Content `json:"message"`
ReasoningContent string `json:"reasoning_content"`
ToolCalls []*ToolCall `json:"tool_calls"`
Observation *Observation `json:"observation"`
Metrics *Metrics `json:"metrics"`
IsCopiedContext *bool `json:"is_copied_context"`
// LLMCallCount is the number of model calls the step stands for,
// kept as written: 0 marks a deterministic dispatch no model made.
LLMCallCount json.RawMessage `json:"llm_call_count"`
Ext json.RawMessage `json:"extra"`
Members
// Raw is the step as read, and Err why it did not decode, for a
// value that is not an object.
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Step is one turn: a system prompt or message, a user message, or one agent response with the observations its actions produced.
func (Step) MarshalJSON ¶
MarshalJSON writes the step back as it was read.
func (*Step) UnmarshalJSON ¶
UnmarshalJSON decodes a step, keeping undeclared members and members of another JSON type; a value that is not an object is kept with Err set.
type ToolCall ¶
type ToolCall struct {
ToolCallID string `json:"tool_call_id"`
FunctionName string `json:"function_name"`
// Arguments is a JSON object in a valid document, kept as written.
Arguments json.RawMessage `json:"arguments"`
Ext json.RawMessage `json:"extra"`
Members
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
ToolCall is one call an agent step made.
func (ToolCall) MarshalJSON ¶
MarshalJSON writes the tool call back as it was read.
func (*ToolCall) UnmarshalJSON ¶
UnmarshalJSON decodes a tool call; a value that is not an object is kept with Err set.
type Trajectory ¶
type Trajectory struct {
SchemaVersion string `json:"schema_version"`
// SessionID is scoped to the run, not the document: a parent, its
// sub-agents and its continuations may share it.
SessionID string `json:"session_id"`
// TrajectoryID names this document; an embedded sub-agent must set
// it, and a reference names the sub-agent by it.
TrajectoryID string `json:"trajectory_id"`
Agent *Agent `json:"agent"`
Steps []*Step `json:"steps"`
Notes string `json:"notes"`
FinalMetrics *Object `json:"final_metrics"`
ContinuedRef string `json:"continued_trajectory_ref"`
Ext json.RawMessage `json:"extra"`
// SubagentsRaw is subagent_trajectories as written, and Subagents
// the trajectories it embeds, each of which may embed its own,
// decoded one by one after this one: decoding them with it would
// decode a nested trajectory again at every level whose members
// need a second pass. SubagentsMistyped says the member is not an
// array.
SubagentsRaw json.RawMessage `json:"subagent_trajectories"`
Subagents []*Trajectory `json:"-"`
SubagentsMistyped bool `json:"-"`
Members
// Raw is the object as read, and Err why it did not decode, for a
// value that is not an object; nothing else is then set.
Raw json.RawMessage `json:"-"`
Err error `json:"-"`
}
Trajectory is one ATIF document: the root object, or a sub-agent's trajectory embedded in its parent's subagent_trajectories.
func (Trajectory) MarshalJSON ¶
func (t Trajectory) MarshalJSON() ([]byte, error)
MarshalJSON writes the trajectory back as it was read.
func (*Trajectory) Units ¶
func (t *Trajectory) Units() int
Units is the number of units the document accounts for: the root and each of its steps, and the same for every embedded trajectory, at any depth. A step or embedded trajectory that is null or not an object counts as one unit; an embedded one that is not an object counts its root alone.
func (*Trajectory) UnmarshalJSON ¶
func (t *Trajectory) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes a trajectory, keeping undeclared members and members of another JSON type. It fails only on JSON that does not parse; a value that is not an object is kept with Err set.