Documentation
¶
Overview ¶
Cursor encoding: a pagination cursor is `{id, time}` encoded as unpadded RFC 4648 URL-safe base64.
Event names and payloads. The runtime's bus owns registration and delivery; this package owns the public names, versions, aggregate key, and wire payload shapes.
Error conversion. Stream-error parsing lives here because it is a pure JSON decision.
Package msgmodel is the persisted message and part model: the assistant, user and tool parts a session stores, the conversion pipeline from stored messages to the model-facing message list, the compaction filter, and the part-assembly helpers the step loop and the stream processor build on.
Opaque provider objects (metadata, tool input, structured output) are kept as raw JSON so their bytes round-trip unchanged; the doom-loop guard compares tool inputs byte for byte. Optional fields are pointers with omitempty. Every discriminated union re-asserts its own tag in MarshalJSON, and parts are stored and type-switched as VALUES, never pointers.
Storage functions. Query construction is behind Store; Page does the descending (time,id) pagination with a one-row lookahead, hydration, and per-page reversal. Stream returns newest-first order.
Index ¶
- Constants
- Variables
- func DifferentModel(model Model, msg Assistant) bool
- func EncodeCursor(input Cursor) (string, error)
- func IsMedia(mime string) bool
- func IsRecord(v RawObject) bool
- func SameInput(a, b RawObject) bool
- func SetMessageIDFactoryForTesting(f func() string) func()
- func SpreadAbortedToolState(prev ToolState, now uint64) (json.RawMessage, error)
- func SpreadObject(base RawObject, overrides ...RawField) json.RawMessage
- func SpreadToolState(prev ToolState, overrides ...RawField) (json.RawMessage, error)
- func TruncateToolOutput(text string, maxChars *float64) string
- type APIError
- type AbortFailure
- type Assistant
- type AssistantError
- func FromError(value any) AssistantError
- func NewAPIError(data APIError) AssistantError
- func NewContextOverflowError(data ContextOverflowErrorData) AssistantError
- func NewMessageAbortedError(message string) AssistantError
- func NewMessageOutputLengthError() AssistantError
- func NewStructuredOutputError(message string, retries uint64) AssistantError
- func NewUnknownError(message string) AssistantError
- type AssistantPath
- type AssistantTime
- type CompactionPart
- type ContextOverflowErrorData
- type ConvertOptions
- type Cursor
- type FileContent
- type FileDiff
- type FilePart
- type FilePartSource
- type FilePartSourceText
- type Info
- type LSPPosition
- type LSPRange
- type MessageAbortedErrorData
- type MessageBase
- type MessageConversionError
- type MessageOutputLengthErrorData
- type MessageRecord
- type Model
- type ModelAPI
- type ModelMessage
- type OutputFormat
- type OutputLengthFailure
- type PageInput
- type PageResult
- type ParsedStreamError
- type Part
- type PartBase
- type PartDeltaEvent
- type PartRemovedEvent
- type PartUpdatedEvent
- type Parts
- type RawField
- type RawObject
- func (r RawObject) Field(key string) (json.RawMessage, bool)
- func (r RawObject) Fields() []RawField
- func (r RawObject) MarshalJSON() ([]byte, error)
- func (r RawObject) Raw() json.RawMessage
- func (r RawObject) StrictTrue(key string) bool
- func (r RawObject) StringField(key string) (string, bool)
- func (r RawObject) Truthy(key string) bool
- func (r *RawObject) UnmarshalJSON(b []byte) error
- func (r RawObject) Value() json.RawMessage
- type RawValue
- type ReasoningContent
- type ReasoningPart
- type RemovedEvent
- type StepFinishPart
- type StepStartPart
- type Store
- type StructuredOutputErrorData
- type TextContent
- type TextPart
- type TimeCreated
- type TimeStartEnd
- type ToModelOptions
- type TokenCache
- type Tokens
- type ToolCallContent
- type ToolModelOutputFn
- type ToolOutput
- type ToolOutputContentMedia
- type ToolOutputContentText
- type ToolPart
- type ToolResultContent
- type ToolState
- type ToolStateCompleted
- type ToolStateError
- type ToolStatePending
- type ToolStateRunning
- type ToolTimeCompleted
- type ToolTimeSpan
- type ToolTimeStart
- type UIMessage
- type UIPart
- type UnknownErrorData
- type UpdatedEvent
- type User
- type UserModel
- type UserSummary
- type WithParts
Constants ¶
const ( EventMessageUpdated = "message.updated" EventMessageRemoved = "message.removed" EventMessagePartUpdated = "message.part.updated" EventMessagePartDelta = "message.part.delta" EventMessagePartRemoved = "message.part.removed" SyncEventVersion = 1 SyncAggregateKey = "sessionID" )
const ( PartTypeText = "text" PartTypeReasoning = "reasoning" PartTypeFile = "file" PartTypeTool = "tool" PartTypeStepStart = "step-start" PartTypeStepFinish = "step-finish" PartTypeCompaction = "compaction" )
Part `type` discriminants.
const ( ToolStatusPending = "pending" ToolStatusRunning = "running" ToolStatusCompleted = "completed" ToolStatusError = "error" )
ToolState `status` discriminants.
const ( ErrNameUnknown = "UnknownError" ErrNameMessageOutputLength = "MessageOutputLengthError" ErrNameMessageAborted = "MessageAbortedError" ErrNameStructuredOutput = "StructuredOutputError" ErrNameContextOverflow = "ContextOverflowError" ErrNameAPI = "APIError" )
AssistantError `name` discriminants.
const ( ToolAbortedError = "Tool execution aborted" ToolInterruptedError = "[Tool execution was interrupted]" ToolCompactedOutput = "[Old tool result content cleared]" )
Fixed strings the settlement path writes. ToolAbortedError is replayed to the model as the tool's errorText; ToolInterruptedError is what a pending or running tool replays as.
const ( UIToolInputStreaming = "input-streaming" UIToolInputAvailable = "input-available" UIToolOutputAvailable = "output-available" UIToolOutputError = "output-error" )
UI part `state` values.
const SyntheticAttachmentPrompt = "Attached media from tool result:"
SyntheticAttachmentPrompt opens the synthetic user message that carries media extracted from a tool result.
Variables ¶
var ErrNotFound = errors.New("msgmodel: not found")
Functions ¶
func DifferentModel ¶
DifferentModel is a plain string comparison of "<providerID>/<modelID>" between the model about to be called and the model that produced the historical turn. When they differ, that turn's provider-specific metadata is stripped below.
func EncodeCursor ¶
func SameInput ¶
SameInput is the doom-loop equality test: two tool inputs compared as stored bytes. Both sides are already verbatim, so this only has to normalise insignificant whitespace; key order is deliberately NOT normalised.
func SetMessageIDFactoryForTesting ¶
func SetMessageIDFactoryForTesting(f func() string) func()
SetMessageIDFactoryForTesting swaps the synthetic-message id source and returns a restore func.
func SpreadAbortedToolState ¶
func SpreadAbortedToolState(prev ToolState, now uint64) (json.RawMessage, error)
SpreadAbortedToolState is the cleanup drain's force-write: `status:"error"`, `error:"Tool execution aborted"`, `metadata:{...existing, interrupted:true}` and `time.start` taken from the previous state, or `now` when the state has none (`pending` does not). It is a spread over the previous state, `{...state, status, error, metadata, time}`, so a `pending` state's `raw` and a `running` state's `title` survive into an object ToolStateError does not declare. Returned as raw JSON because those fields have no typed home.
func SpreadObject ¶
func SpreadObject(base RawObject, overrides ...RawField) json.RawMessage
SpreadObject is the object spread `{...base, k1: v1, k2: v2}`: an overridden key keeps the position it had in base and takes the new value; a new key is appended in the order given. Key order is load-bearing: the doom-loop guard compares the stored bytes verbatim.
func SpreadToolState ¶
func SpreadToolState(prev ToolState, overrides ...RawField) (json.RawMessage, error)
SpreadToolState is `{...prev, ...overrides}` for any transition: the tool-call → running step as well as the cleanup drain.
func TruncateToolOutput ¶
TruncateToolOutput keeps the first maxChars characters of a tool output and appends a marker naming how many were dropped. A nil or non-positive limit leaves the text alone.
Types ¶
type APIError ¶
type APIError struct {
Message string `json:"message"`
StatusCode *uint64 `json:"statusCode,omitempty"`
IsRetryable bool `json:"isRetryable"`
ResponseHeaders RawObject `json:"responseHeaders,omitempty"`
ResponseBody *string `json:"responseBody,omitempty"`
Metadata RawObject `json:"metadata,omitempty"`
}
APIError is the `data` payload of the APIError variant. `responseBody` is searched by substring by the error classifiers, so it is a string kept byte-for-byte, never re-encoded JSON.
type AbortFailure ¶
type AbortFailure struct{ Message string }
Marker errors FromError classifies by type.
func (AbortFailure) Error ¶
func (e AbortFailure) Error() string
type Assistant ¶
type Assistant struct {
MessageBase
Role string `json:"role"`
Time AssistantTime `json:"time"`
Error *AssistantError `json:"error,omitempty"`
ParentID string `json:"parentID"`
ModelID string `json:"modelID"`
ProviderID string `json:"providerID"`
// Mode always carries the same value as Agent; both are persisted.
Mode string `json:"mode"`
Agent string `json:"agent"`
Path AssistantPath `json:"path"`
Summary *bool `json:"summary,omitempty"`
Cost float64 `json:"cost"`
Tokens Tokens `json:"tokens"`
Structured RawValue `json:"structured,omitempty"`
Variant *string `json:"variant,omitempty"`
// Finish is one of the unified finish reasons (orclient.Finish*).
Finish *string `json:"finish,omitempty"`
// Upstream is the endpoint that served the message's last step, copied
// from the step-finish part so a message-level consumer (the agent
// summary) can attribute cache misses without walking parts.
Upstream string `json:"upstream,omitempty"`
}
func (Assistant) MarshalJSON ¶
func (Assistant) MessageRole ¶
type AssistantError ¶
type AssistantError struct {
Name string `json:"name"`
Data json.RawMessage `json:"data"`
}
AssistantError is `{name, data}`. `Data` stays raw so an error minted elsewhere round-trips verbatim; the typed constructors below cover the seven known variants.
func FromError ¶
func FromError(value any) AssistantError
FromError classifies a failure value into the persisted AssistantError shape. `value` is the raw `error` payload of a model stream, a Go error, or one of the marker types above.
func NewAPIError ¶
func NewAPIError(data APIError) AssistantError
func NewContextOverflowError ¶
func NewContextOverflowError(data ContextOverflowErrorData) AssistantError
func NewMessageAbortedError ¶
func NewMessageAbortedError(message string) AssistantError
func NewMessageOutputLengthError ¶
func NewMessageOutputLengthError() AssistantError
func NewStructuredOutputError ¶
func NewStructuredOutputError(message string, retries uint64) AssistantError
func NewUnknownError ¶
func NewUnknownError(message string) AssistantError
func (*AssistantError) IsAborted ¶
func (e *AssistantError) IsAborted() bool
IsAborted is a bare `name` comparison, nothing more.
type AssistantPath ¶
AssistantPath is Assistant.path.
type AssistantTime ¶
type AssistantTime struct {
Created uint64 `json:"created"`
Completed *uint64 `json:"completed,omitempty"`
}
AssistantTime is Assistant.time.
type CompactionPart ¶
type CompactionPart struct {
PartBase
Type string `json:"type"`
Auto bool `json:"auto"`
Overflow *bool `json:"overflow,omitempty"`
TailStartID *string `json:"tail_start_id,omitempty"`
}
func (CompactionPart) Base ¶
func (p CompactionPart) Base() PartBase
func (CompactionPart) MarshalJSON ¶
func (p CompactionPart) MarshalJSON() ([]byte, error)
func (CompactionPart) PartType ¶
func (p CompactionPart) PartType() string
type ContextOverflowErrorData ¶
type ContextOverflowErrorData struct {
Message string `json:"message"`
ResponseBody *string `json:"responseBody,omitempty"`
}
ContextOverflowErrorData is the ContextOverflowError payload.
type ConvertOptions ¶
type ConvertOptions struct {
IgnoreIncompleteToolCalls bool
Tools map[string]ToolModelOutputFn
}
ConvertOptions are the conversion options.
type Cursor ¶
func DecodeCursor ¶
type FileContent ¶
type FileContent struct {
Type string `json:"type"`
MediaType string `json:"mediaType"`
Filename RawValue `json:"filename,omitempty"`
Data string `json:"data"`
ProviderOptions RawValue `json:"providerOptions,omitempty"`
}
FileContent is a file content part.
type FilePart ¶
type FilePart struct {
PartBase
Type string `json:"type"`
Mime string `json:"mime"`
Filename *string `json:"filename,omitempty"`
URL string `json:"url"`
Source *FilePartSource `json:"source,omitempty"`
}
func (FilePart) MarshalJSON ¶
type FilePartSource ¶
type FilePartSource struct {
Text FilePartSourceText `json:"text"`
Type string `json:"type"`
Path string `json:"path,omitempty"`
Range *LSPRange `json:"range,omitempty"`
Name string `json:"name,omitempty"`
Kind *uint64 `json:"kind,omitempty"`
ClientName string `json:"clientName,omitempty"`
URI string `json:"uri,omitempty"`
}
FilePartSource is the file / symbol / resource source union, discriminated on `type`. Nothing in this package reads it, so it is a single carrier struct rather than an interface, with the shared `text` first.
type FilePartSourceText ¶
type FilePartSourceText struct {
Value string `json:"value"`
Start uint64 `json:"start"`
End uint64 `json:"end"`
}
FilePartSourceText is the text span a file part source covers.
type Info ¶
Info is the User | Assistant union.
func UnmarshalInfo ¶
UnmarshalInfo dispatches on `role`.
type LSPPosition ¶
LSPPosition / LSPRange locate a symbol source in its file.
type LSPRange ¶
type LSPRange struct {
Start LSPPosition `json:"start"`
End LSPPosition `json:"end"`
}
type MessageAbortedErrorData ¶
type MessageAbortedErrorData struct {
Message string `json:"message"`
}
MessageAbortedErrorData is the MessageAbortedError payload.
type MessageBase ¶
MessageBase is the id pair every message carries.
type MessageConversionError ¶
type MessageConversionError struct {
Message string
}
MessageConversionError is the only error ConvertToModelMessages raises.
func (*MessageConversionError) Error ¶
func (e *MessageConversionError) Error() string
type MessageOutputLengthErrorData ¶
type MessageOutputLengthErrorData struct{}
MessageOutputLengthErrorData is the MessageOutputLengthError payload: no fields.
type MessageRecord ¶
type Model ¶
type Model struct {
ProviderID string `json:"providerID"`
ID string `json:"id"`
API ModelAPI `json:"api"`
}
Model is the slice of a catalog model this package reads: `providerID` and `id` feed DifferentModel, `api` feeds supportsMediaInToolResult.
type ModelAPI ¶
ModelAPI is the `api` sub-object of a catalog model: the provider SDK identifier and the provider-side model id. supportsMediaInToolResult reads both.
type ModelMessage ¶
type ModelMessage struct {
Role string `json:"role"`
Content any `json:"content"`
ProviderOptions RawValue `json:"providerOptions,omitempty"`
}
ModelMessage is one entry of the `ModelMessage[]` handed to the provider. `Content` is a string for `role:"system"` and a content-part slice otherwise.
func ConvertToModelMessages ¶
func ConvertToModelMessages(messages []UIMessage, options *ConvertOptions) ([]ModelMessage, error)
ConvertToModelMessages is the conversion described above.
func ToModelMessages ¶
func ToModelMessages(input []WithParts, model Model, options *ToModelOptions) ([]ModelMessage, error)
ToModelMessages converts stored messages into the model-facing message list.
func UserText ¶
func UserText(text string) ModelMessage
UserText builds a plain-text user message in the one content shape the wire converter accepts: a []any list holding a single TextContent, which is what ConvertToModelMessages emits for the coder's own prompt.
The shape is easy to get wrong: a typed []TextContent slice fails the converter's `msg.Content.([]any)` assertion. Every hand-built user message must come from here, and the converter rejects any other shape instead of sending an empty turn.
type OutputFormat ¶
type OutputFormat = json.RawMessage
OutputFormat is the `OutputFormatText | OutputFormatJsonSchema` union. It is only carried, never inspected, by anything in this package, so it keeps its bytes verbatim.
type OutputLengthFailure ¶
type OutputLengthFailure struct{}
func (OutputLengthFailure) Error ¶
func (OutputLengthFailure) Error() string
type PageResult ¶
type ParsedStreamError ¶
func ParseStreamError ¶
func ParseStreamError(input any) *ParsedStreamError
type Part ¶
type Part interface {
// PartType is the `type` discriminant.
PartType() string
// PartBase returns the shared {id, sessionID, messageID}.
Base() PartBase
json.Marshaler
}
Part is the seven-variant part union, discriminated on `type`. PartBase is embedded first in every variant, so id/sessionID/messageID lead the JSON.
func UnmarshalPart ¶
UnmarshalPart dispatches on `type`.
type PartBase ¶
type PartBase struct {
ID string `json:"id"`
SessionID string `json:"sessionID"`
MessageID string `json:"messageID"`
}
PartBase is embedded first in every part so id/sessionID/messageID lead the JSON.
type PartDeltaEvent ¶
type PartRemovedEvent ¶
type PartUpdatedEvent ¶
type Parts ¶
type Parts []Part
Parts is `Part[]` with union-aware decoding.
func MessageParts ¶
func (Parts) MarshalJSON ¶
MarshalJSON keeps a nil slice as `[]`; `parts` is a required array.
func (*Parts) UnmarshalJSON ¶
type RawField ¶
type RawField struct {
Key string
Value json.RawMessage
}
RawField is one own property of a JSON object, in source order.
type RawObject ¶
type RawObject json.RawMessage
RawObject is a JSON object kept as the verbatim bytes it arrived as. Never decode one into map[string]any: Go sorts map keys on re-marshal, and the doom-loop guard compares tool inputs byte for byte, key order included.
A zero-length RawObject is an absent value. On an OPTIONAL field (tagged `omitempty`) that means the key is omitted; on a REQUIRED field it marshals as `{}`, which is what the processor writes for an empty input/metadata.
func MergeInterrupted ¶
MergeInterrupted is `{...metadata, interrupted: true}`. A pre-existing `interrupted` key keeps its original position.
func (RawObject) Field ¶
func (r RawObject) Field(key string) (json.RawMessage, bool)
Field returns the raw value at key, or ok=false when absent (or when the receiver is not an object).
func (RawObject) Fields ¶
Fields returns the object's own properties in insertion order, or nil when the value is absent or not an object.
func (RawObject) MarshalJSON ¶
func (RawObject) Raw ¶
func (r RawObject) Raw() json.RawMessage
Raw returns the underlying bytes, or nil when the value was absent: the reading for an OPTIONAL field.
func (RawObject) StrictTrue ¶
StrictTrue reports whether the value at key is exactly `true`.
func (RawObject) StringField ¶
StringField returns the value at key when it is a string.
func (*RawObject) UnmarshalJSON ¶
func (RawObject) Value ¶
func (r RawObject) Value() json.RawMessage
Value returns `{}` for an absent value: the reading for a REQUIRED field (`input`, ToolStateCompleted.metadata), which is always at least an empty object.
type RawValue ¶
type RawValue = json.RawMessage
RawValue is any JSON value carried verbatim. A zero-length RawValue is an absent value (the key is omitted), not JSON null.
type ReasoningContent ¶
type ReasoningContent struct {
Type string `json:"type"`
Text string `json:"text"`
ProviderOptions RawValue `json:"providerOptions,omitempty"`
}
ReasoningContent is a reasoning content part. `providerOptions` is copied unconditionally (contrast text/file); an absent value is dropped by `omitempty`.
type ReasoningPart ¶
type ReasoningPart struct {
PartBase
Type string `json:"type"`
Text string `json:"text"`
Metadata RawObject `json:"metadata,omitempty"`
Time TimeStartEnd `json:"time"`
}
func (ReasoningPart) Base ¶
func (p ReasoningPart) Base() PartBase
func (ReasoningPart) MarshalJSON ¶
func (p ReasoningPart) MarshalJSON() ([]byte, error)
func (ReasoningPart) PartType ¶
func (p ReasoningPart) PartType() string
type RemovedEvent ¶
type StepFinishPart ¶
type StepFinishPart struct {
PartBase
Type string `json:"type"`
Reason string `json:"reason"`
Snapshot *string `json:"snapshot,omitempty"`
Cost float64 `json:"cost"`
Tokens Tokens `json:"tokens"`
// Upstream is the endpoint OpenRouter reports as having served the call
// (its response `provider` field). Cache-miss attribution needs to know
// when successive calls changed endpoint, and the wire already says so.
// Absent when the provider never reported one.
Upstream string `json:"upstream,omitempty"`
}
func (StepFinishPart) Base ¶
func (p StepFinishPart) Base() PartBase
func (StepFinishPart) MarshalJSON ¶
func (p StepFinishPart) MarshalJSON() ([]byte, error)
func (StepFinishPart) PartType ¶
func (p StepFinishPart) PartType() string
type StepStartPart ¶
type StepStartPart struct {
PartBase
Type string `json:"type"`
Snapshot *string `json:"snapshot,omitempty"`
}
func (StepStartPart) Base ¶
func (p StepStartPart) Base() PartBase
func (StepStartPart) MarshalJSON ¶
func (p StepStartPart) MarshalJSON() ([]byte, error)
func (StepStartPart) PartType ¶
func (p StepStartPart) PartType() string
type Store ¶
type Store interface {
SelectMessages(ctx context.Context, sessionID string, limit int, before *Cursor) ([]MessageRecord, error)
SessionExists(ctx context.Context, sessionID string) (bool, error)
SelectParts(ctx context.Context, messageIDs []string) (Parts, error)
SelectMessage(ctx context.Context, sessionID, messageID string) (MessageRecord, bool, error)
SelectMessageParts(ctx context.Context, messageID string) (Parts, error)
}
Store methods must return messages in descending (time_created,id) order and parts in ascending (message_id,id) order.
type StructuredOutputErrorData ¶
type StructuredOutputErrorData struct {
Message string `json:"message"`
Retries uint64 `json:"retries"`
}
StructuredOutputErrorData is the StructuredOutputError payload.
type TextContent ¶
type TextContent struct {
Type string `json:"type"`
Text string `json:"text"`
ProviderOptions RawValue `json:"providerOptions,omitempty"`
}
TextContent is a text content part.
type TextPart ¶
type TextPart struct {
PartBase
Type string `json:"type"`
Text string `json:"text"`
Synthetic *bool `json:"synthetic,omitempty"`
Ignored *bool `json:"ignored,omitempty"`
Time *TimeStartEnd `json:"time,omitempty"`
Metadata RawObject `json:"metadata,omitempty"`
}
func (TextPart) MarshalJSON ¶
type TimeCreated ¶
type TimeCreated struct {
Created uint64 `json:"created"`
}
TimeCreated is `{created}`.
type TimeStartEnd ¶
TimeStartEnd is `{start, end?}`. TextPart.time and ReasoningPart.time share the shape; only the outer optionality differs.
type ToModelOptions ¶
ToModelOptions tune the conversion. Both are pointers: an absent StripMedia is false, and an absent or non-positive ToolOutputMaxChars leaves outputs untruncated.
type TokenCache ¶
TokenCache is `{read, write}`.
type Tokens ¶
type Tokens struct {
Total *uint64 `json:"total,omitempty"`
Input uint64 `json:"input"`
Output uint64 `json:"output"`
Reasoning uint64 `json:"reasoning"`
Cache TokenCache `json:"cache"`
}
Tokens is the token block shared by StepFinishPart and Assistant.
type ToolCallContent ¶
type ToolCallContent struct {
Type string `json:"type"`
ToolCallID string `json:"toolCallId"`
ToolName string `json:"toolName"`
Input RawValue `json:"input,omitempty"`
ProviderExecuted RawValue `json:"providerExecuted,omitempty"`
ProviderOptions RawValue `json:"providerOptions,omitempty"`
}
ToolCallContent is a tool-call content part.
type ToolModelOutputFn ¶
type ToolModelOutputFn func(toolCallID string, input RawValue, output RawValue) ToolOutput
ToolModelOutputFn converts a tool's stored output into the shape the model sees. `output` is the raw JSON value; a nil `output` is absent.
type ToolOutput ¶
ToolOutput is a tool result as the model sees it: one of text / json / error-text / error-json / content.
type ToolOutputContentMedia ¶
type ToolOutputContentText ¶
ToolOutputContentText / ToolOutputContentMedia are the two element shapes toModelOutput emits inside `{type:"content"}`.
type ToolPart ¶
type ToolPart struct {
PartBase
Type string `json:"type"`
CallID string `json:"callID"`
Tool string `json:"tool"`
State ToolState `json:"state"`
Metadata RawObject `json:"metadata,omitempty"`
}
func (ToolPart) MarshalJSON ¶
func (ToolPart) ProviderExecuted ¶
ProviderExecuted reads the one key of ToolPart.metadata that has a read path. It is a truthiness test, not a strict `true` comparison.
func (*ToolPart) UnmarshalJSON ¶
UnmarshalJSON on ToolPart has to route `state` through the union decoder.
type ToolResultContent ¶
type ToolResultContent struct {
Type string `json:"type"`
ToolCallID string `json:"toolCallId"`
ToolName string `json:"toolName"`
Output ToolOutput `json:"output"`
ProviderOptions RawValue `json:"providerOptions,omitempty"`
}
ToolResultContent is a tool-result content part.
type ToolState ¶
type ToolState interface {
ToolStatus() string
// Input is `Record<string, any>`, present on every variant.
ToolInput() RawObject
// ToolMetadata is the variant's `metadata`, or a zero RawObject when the
// variant has none (pending).
ToolMetadata() RawObject
// StartTime is `state.time.start`; ok=false for `pending`.
StartTime() (uint64, bool)
json.Marshaler
}
ToolState is the four-variant tool state union, discriminated on `status`. The field sets differ: `pending` has no `time` at all, which is why the cleanup drain falls back to `now`.
func UnmarshalToolState ¶
UnmarshalToolState dispatches on `status`.
type ToolStateCompleted ¶
type ToolStateCompleted struct {
Status string `json:"status"`
Input RawObject `json:"input"`
Output string `json:"output"`
Title string `json:"title"`
Metadata RawObject `json:"metadata"`
Time ToolTimeCompleted `json:"time"`
Attachments *[]FilePart `json:"attachments,omitempty"`
}
func CompletedToolState ¶
func CompletedToolState(input RawObject, output, title string, metadata RawObject, start, end uint64, attachments *[]FilePart) ToolStateCompleted
CompletedToolState is the typed `completed` state. The processor writes its keys in the order status, input, output, metadata, title, time, attachments; this struct keeps the declared order (title before metadata).
func (ToolStateCompleted) MarshalJSON ¶
func (s ToolStateCompleted) MarshalJSON() ([]byte, error)
func (ToolStateCompleted) StartTime ¶
func (s ToolStateCompleted) StartTime() (uint64, bool)
func (ToolStateCompleted) ToolInput ¶
func (s ToolStateCompleted) ToolInput() RawObject
func (ToolStateCompleted) ToolMetadata ¶
func (s ToolStateCompleted) ToolMetadata() RawObject
func (ToolStateCompleted) ToolStatus ¶
func (s ToolStateCompleted) ToolStatus() string
type ToolStateError ¶
type ToolStateError struct {
Status string `json:"status"`
Input RawObject `json:"input"`
Error string `json:"error"`
Metadata RawObject `json:"metadata,omitempty"`
Time ToolTimeSpan `json:"time"`
}
func (ToolStateError) MarshalJSON ¶
func (s ToolStateError) MarshalJSON() ([]byte, error)
func (ToolStateError) StartTime ¶
func (s ToolStateError) StartTime() (uint64, bool)
func (ToolStateError) ToolInput ¶
func (s ToolStateError) ToolInput() RawObject
func (ToolStateError) ToolMetadata ¶
func (s ToolStateError) ToolMetadata() RawObject
func (ToolStateError) ToolStatus ¶
func (s ToolStateError) ToolStatus() string
type ToolStatePending ¶
type ToolStatePending struct {
Status string `json:"status"`
Input RawObject `json:"input"`
Raw string `json:"raw"`
}
func PendingToolState ¶
func PendingToolState() ToolStatePending
PendingToolState is `{status:"pending", input:{}, raw:""}`.
func (ToolStatePending) MarshalJSON ¶
func (s ToolStatePending) MarshalJSON() ([]byte, error)
func (ToolStatePending) StartTime ¶
func (s ToolStatePending) StartTime() (uint64, bool)
func (ToolStatePending) ToolInput ¶
func (s ToolStatePending) ToolInput() RawObject
func (ToolStatePending) ToolMetadata ¶
func (s ToolStatePending) ToolMetadata() RawObject
func (ToolStatePending) ToolStatus ¶
func (s ToolStatePending) ToolStatus() string
type ToolStateRunning ¶
type ToolStateRunning struct {
Status string `json:"status"`
Input RawObject `json:"input"`
Title *string `json:"title,omitempty"`
Metadata RawObject `json:"metadata,omitempty"`
Time ToolTimeStart `json:"time"`
}
func (ToolStateRunning) MarshalJSON ¶
func (s ToolStateRunning) MarshalJSON() ([]byte, error)
func (ToolStateRunning) StartTime ¶
func (s ToolStateRunning) StartTime() (uint64, bool)
func (ToolStateRunning) ToolInput ¶
func (s ToolStateRunning) ToolInput() RawObject
func (ToolStateRunning) ToolMetadata ¶
func (s ToolStateRunning) ToolMetadata() RawObject
func (ToolStateRunning) ToolStatus ¶
func (s ToolStateRunning) ToolStatus() string
type ToolTimeCompleted ¶
type ToolTimeCompleted struct {
Start uint64 `json:"start"`
End uint64 `json:"end"`
Compacted *uint64 `json:"compacted,omitempty"`
}
ToolTimeCompleted is ToolStateCompleted.time.
type ToolTimeSpan ¶
ToolTimeSpan is ToolStateError.time.
type ToolTimeStart ¶
type ToolTimeStart struct {
Start uint64 `json:"start"`
}
ToolTimeStart is ToolStateRunning.time.
type UIMessage ¶
type UIMessage struct {
ID string `json:"id"`
Role string `json:"role"`
Parts []UIPart `json:"parts"`
}
UIMessage / UIPart are the intermediate value ToModelMessages builds before handing it to ConvertToModelMessages.
A UIPart is ONE flat struct rather than a Go union: the parts are duck-typed on their `type` string, and the tool discriminant is a DYNAMIC string `"tool-" + toolName`, so an interface would buy nothing. UIMessages are never serialised as an output, so field order here is documentation rather than contract.
type UIPart ¶
type UIPart struct {
Type string `json:"type"`
// text / reasoning
Text string `json:"text,omitempty"`
// text / file / reasoning
ProviderMetadata RawValue `json:"providerMetadata,omitempty"`
// file
MediaType string `json:"mediaType,omitempty"`
Filename RawValue `json:"filename,omitempty"`
URL string `json:"url,omitempty"`
// dynamic-tool
ToolName string `json:"toolName,omitempty"`
// tool-* / dynamic-tool
ToolCallID string `json:"toolCallId,omitempty"`
State string `json:"state,omitempty"`
Input RawValue `json:"input,omitempty"`
RawInput RawValue `json:"rawInput,omitempty"`
Output RawValue `json:"output,omitempty"`
ErrorText string `json:"errorText,omitempty"`
ProviderExecuted RawValue `json:"providerExecuted,omitempty"`
CallProviderMetadata RawValue `json:"callProviderMetadata,omitempty"`
ResultProviderMetadata RawValue `json:"resultProviderMetadata,omitempty"`
}
func (UIPart) ResolveToolName ¶
ResolveToolName returns the tool a part refers to: a dynamic part carries the name; a static part's name is everything after the first dash of its type, which preserves every internal dash. That is load-bearing because the type is built as `"tool-" + part.tool` and tool names contain dashes.
type UnknownErrorData ¶
type UnknownErrorData struct {
Message string `json:"message"`
}
UnknownErrorData is the UnknownError payload.
type UpdatedEvent ¶
type User ¶
type User struct {
MessageBase
Role string `json:"role"`
Time TimeCreated `json:"time"`
Format OutputFormat `json:"format,omitempty"`
Summary *UserSummary `json:"summary,omitempty"`
Agent string `json:"agent"`
Model UserModel `json:"model"`
System *string `json:"system,omitempty"`
Tools *map[string]bool `json:"tools,omitempty"`
}
func (User) MarshalJSON ¶
func (User) MessageRole ¶
type UserModel ¶
type UserModel struct {
ProviderID string `json:"providerID"`
ModelID string `json:"modelID"`
Variant *string `json:"variant,omitempty"`
}
UserModel is User.model.
type UserSummary ¶
type UserSummary struct {
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
Diffs []FileDiff `json:"diffs"`
}
UserSummary is User.summary.
type WithParts ¶
func FilterCompacted ¶
FilterCompacted projects a session onto what the model should see: a newest-first walk over the messages that stops at the last completed compaction, then (when the compaction names a `tail_start_id` that sits BEFORE it) rotates the summary block in front of the retained tail.
`msgs` must arrive newest-first; the result is chronological.
The step loop mutates the returned parts in place (WrapLateUserText), so the caller needs parts it owns. This function does NOT deep-copy; the storage layer that feeds it must hand over fresh values.