atif

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 14 Imported by: 0

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

View Source
const (
	SourceSystem = "system"
	SourceUser   = "user"
	SourceAgent  = "agent"
)

Step sources.

View Source
const (
	PartText  = "text"
	PartImage = "image"
	PartAudio = "audio"
)

Content part types.

View Source
const MaxSize = 1 << 30

MaxSize bounds a document. A larger file is refused rather than read into memory.

Variables

View Source
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.

View Source
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

func FindSessions(root string) ([]string, error)

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.

func Probe

func Probe(path string) (string, bool)

Probe reports whether the file at path holds an ATIF document: a JSON object whose schema_version starts "ATIF-v", read from the members before it, whatever comes after. It returns the version.

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

func (a Agent) MarshalJSON() ([]byte, error)

MarshalJSON writes the agent back as it was read.

func (*Agent) UnmarshalJSON

func (a *Agent) UnmarshalJSON(data []byte) error

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) IsZero

func (c Content) IsZero() bool

IsZero reports whether the content is absent or null.

func (Content) MarshalJSON

func (c Content) MarshalJSON() ([]byte, error)

MarshalJSON writes the content back in the form it was read.

func (Content) String

func (c Content) String() string

String is the content's text: the string, or the text parts joined with newlines.

func (*Content) UnmarshalJSON

func (c *Content) UnmarshalJSON(data []byte) error

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 Parse

func Parse(data []byte) (*File, error)

Parse reads a document from its bytes; see Read.

func Read

func Read(r io.Reader) (*File, error)

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.

func ReadFile

func ReadFile(path string) (*File, error)

ReadFile reads a document from a file.

func (*File) Units

func (f *File) Units() int

Units is the number of units the file accounts for: the document's root and steps, at any depth, and a step cut short.

type Members

type Members = jsonline.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

func (m Metrics) MarshalJSON() ([]byte, error)

MarshalJSON writes the metrics back as they were read.

func (*Metrics) UnmarshalJSON

func (m *Metrics) UnmarshalJSON(data []byte) error

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

func (o Object) MarshalJSON() ([]byte, error)

MarshalJSON writes the value back.

func (*Object) UnmarshalJSON

func (o *Object) UnmarshalJSON(data []byte) error

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

func (p Part) MarshalJSON() ([]byte, error)

MarshalJSON writes the part back as it was read.

func (*Part) UnmarshalJSON

func (p *Part) UnmarshalJSON(data []byte) error

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

func (r Ref) MarshalJSON() ([]byte, error)

MarshalJSON writes the reference back as it was read.

func (*Ref) UnmarshalJSON

func (r *Ref) UnmarshalJSON(data []byte) error

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

func (r Refs) MarshalJSON() ([]byte, error)

MarshalJSON writes the references back in the form they were read.

func (*Refs) UnmarshalJSON

func (r *Refs) UnmarshalJSON(data []byte) error

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

func (r Result) MarshalJSON() ([]byte, error)

MarshalJSON writes the result back as it was read.

func (*Result) UnmarshalJSON

func (r *Result) UnmarshalJSON(data []byte) error

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

func (s Source) MarshalJSON() ([]byte, error)

MarshalJSON writes the source back as it was read.

func (*Source) UnmarshalJSON

func (s *Source) UnmarshalJSON(data []byte) error

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) Copied

func (s *Step) Copied() bool

Copied reports whether the step is marked as copied context.

func (Step) MarshalJSON

func (s Step) MarshalJSON() ([]byte, error)

MarshalJSON writes the step back as it was read.

func (*Step) UnmarshalJSON

func (s *Step) UnmarshalJSON(data []byte) error

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

func (c ToolCall) MarshalJSON() ([]byte, error)

MarshalJSON writes the tool call back as it was read.

func (*ToolCall) UnmarshalJSON

func (c *ToolCall) UnmarshalJSON(data []byte) error

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.

Directories

Path Synopsis
Package convert converts ATIF trajectories into the Agent Session Format.
Package convert converts ATIF trajectories into the Agent Session Format.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL