Documentation
¶
Overview ¶
Package message owns the provider-neutral wire DTOs shared by every chat turn: a role-tagged Message carrying an ordered Content of [Part]s, plus the tool-call DTOs (ToolDefinition, ToolCall, ToolResult) and the JSON Schema helpers that build a ToolDefinition.
The package has no runtime: no providers, no executors, no middleware. It is the canonical shape of "what travels on the wire" — the layer above this package (core/inference for LLM calls, core/tool for tool execution, core/memory for stored turns) operates on these types but does not own them. Two consumers can therefore share a message log without pulling in each other's runtime.
The wire format is JSON. Content.MarshalJSON / Content.UnmarshalJSON tag each part with its PartKind so the same payload survives a round-trip through any tool that ignores FlowCraft's Go types.
The media subpackage holds the operation-neutral Source / Format types that ride inside multimodal Parts (images, audio, video). They are DTOs for the same reason and live here for the same reason.
Live media rides the same Part model: media.Stream / media.Pipe define a bounded pull transport, and a stream-backed Audio/Video Source is how a part exists while it is in flight. Streams are never serialized and never enter durable context or history — MaterializeContent converts them back into inline-byte parts at the commit boundary.
Index ¶
- func HasStreamSource(content Content) bool
- func Items(typ string) map[string]any
- func MarshalPart(part Part) ([]byte, error)
- func NewAudioStream(stream Stream, mediaType string) (media.AudioSource, error)
- func NewVideoStream(stream Stream, mediaType string) (media.VideoSource, error)
- type AudioPart
- type Content
- type DataPart
- type FilePart
- type ImagePart
- type Message
- type Part
- type PartKind
- type Pipe
- type ReasoningPart
- type Role
- type SchemaBuilder
- type Stream
- type TextPart
- type ToolCall
- type ToolCallPart
- type ToolDefinition
- type ToolPropertyDef
- func ToolArrayProperty(name, description string, items map[string]any) ToolPropertyDef
- func ToolEnumProperty(name, typ, description string, values ...string) ToolPropertyDef
- func ToolObjectProperty(name, description string, properties map[string]any) ToolPropertyDef
- func ToolProperty(name, typ, description string) ToolPropertyDef
- func ToolPropertyWithDefault(name, typ, description string, defaultVal any) ToolPropertyDef
- func ToolStringMapProperty(name, description string) ToolPropertyDef
- type ToolResult
- type ToolResultPart
- type VideoPart
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HasStreamSource ¶ added in v0.1.17
HasStreamSource reports whether any part in content carries a stream-backed media source. It is the cheap pre-check callers use before deciding whether MaterializeContent has work to do.
func Items ¶
Items is the schema for the elements of a ToolArrayProperty: the common "array of plain-typed values" case without a raw map.
func MarshalPart ¶
MarshalPart encodes one canonical part in its wire form: a type-discriminated object, e.g. {"type":"image","source":...}. This is the same shape Content uses for each entry of its "parts" array, exported so single-part carriers (stream deltas, protocol envelopes) can reuse the canonical encoding instead of duplicating the switch.
func NewAudioStream ¶ added in v0.1.17
func NewAudioStream(stream Stream, mediaType string) (media.AudioSource, error)
NewAudioStream wraps a live part stream as an audio source, the message-level convenience for media.NewAudioStream instantiated over Part.
func NewVideoStream ¶ added in v0.1.17
func NewVideoStream(stream Stream, mediaType string) (media.VideoSource, error)
NewVideoStream wraps a live part stream as a video source, the message-level convenience for media.NewVideoStream instantiated over Part.
Types ¶
type AudioPart ¶
type AudioPart struct {
Source media.AudioSource `json:"source"`
Format *media.AudioFormat `json:"format,omitempty"`
DurationMillis *int64 `json:"duration_millis,omitempty"`
}
type Content ¶
type Content struct {
Parts []Part `json:"parts"`
}
Content is an ordered collection of canonical parts. Intent deliberately does not belong here; only InputContent may attach execution intent.
func MaterializeContent ¶ added in v0.1.17
MaterializeContent converts every stream-backed audio and video part in content into its durable form by draining the stream to completion:
- a stream-backed AudioPart becomes one inline-byte AudioPart;
- a stream-backed VideoPart becomes one inline-byte VideoPart.
Content without stream sources is returned unchanged. The stream is consumed exactly once: callers that also read it live must materialize from their own accumulated bytes instead (or ensure the stream is still readable here).
func (Content) MarshalJSON ¶
func (Content) Text ¶
Text concatenates the message's text parts in order. Non-text parts are skipped; it answers "what did the user/assistant say" without imposing prose structure on multi-modal content.
func (*Content) UnmarshalJSON ¶
type DataPart ¶
type DataPart struct {
MediaType string `json:"media_type,omitempty"`
Value json.RawMessage `json:"value"`
}
type FilePart ¶
type ImagePart ¶
type ImagePart struct {
Source media.ImageSource `json:"source"`
}
type Message ¶
func CloneMessages ¶
CloneMessages returns a deep copy of msgs. Nil stays nil so callers can preserve the usual JSON / len semantics.
func LastByRole ¶
LastByRole returns the last message in msgs whose Role matches role. The boolean is false when no such message exists. The returned Message is the slice element itself (not a deep copy); callers that intend to mutate it should call Message.Clone first.
Typical use is for graph nodes that need to read a single role-scoped turn from a board channel — e.g. "the latest user message on MainChannel" — without re-implementing the reverse scan everywhere.
func NewTextMessage ¶
NewTextMessage builds a message carrying a single text part.
func (Message) HasToolCalls ¶
func (Message) ToolResults ¶
func (m Message) ToolResults() []ToolResult
type Part ¶
type Part interface {
Kind() PartKind
Clone() Part
Validate() error
// contains filtered or unexported methods
}
Part is the sealed canonical content union. Each operation validates which kinds it accepts; for example, Embed currently accepts only text and image.
func MaterializePart ¶ added in v0.1.17
MaterializePart returns part in its durable form. Stream-backed audio and video parts are drained into inline-byte parts; every other part is returned unchanged. See MaterializeContent for the rules.
func NormalizePart ¶
NormalizePart returns part in its canonical value form. Both T and *T satisfy Part, so values may cross runtime boundaries as either form; NormalizePart collapses pointers back to values and leaves value parts untouched. This lets callers switch on the canonical part types without handling pointer duplicates.
It returns an error if part is nil (including a typed nil pointer) or is not one of the canonical part types.
func UnmarshalPart ¶
UnmarshalPart decodes one type-discriminated wire object back into its canonical part value. Unknown "type" values are rejected so a typo cannot silently decode into a zero part.
type Pipe ¶ added in v0.1.17
Pipe is the bounded, buffered implementation of Stream. Producers Send into it (blocking when the buffer is full, which is the backpressure contract); consumers Read from it. See media.Pipe for the full Close / Interrupt semantics.
func NewPartPipe ¶ added in v0.1.17
NewPartPipe creates a bounded part pipe with the given buffer capacity.
type ReasoningPart ¶
type ReasoningPart struct {
Text string `json:"text,omitempty"`
Signature string `json:"signature,omitempty"`
ID string `json:"id,omitempty"`
}
ReasoningPart is one provider reasoning trace: the thinking a model produced while composing the answer. It is a trace, not a requested artifact — reasoning-capable models emit it whether or not the request set a reasoning intent, so responses may always carry it.
Text holds the visible reasoning; providers that hide the content (Anthropic redacted_thinking, OpenAI encrypted reasoning without a summary) deliver an empty Text. Signature is the provider-issued opaque verification payload (Anthropic signature / redacted data, OpenAI encrypted_content): providers that sign reasoning require it verbatim when the part round-trips through conversation context, so consumers building agent loops must preserve the whole part. The convention Text=="" with Signature!="" therefore means "reasoning happened, content withheld" — it is derived, never a separate flag. ID is the provider-issued trace identifier (OpenAI reasoning item ids); providers that address traces by id require it on round-trip, and providers without item ids (Anthropic thinking blocks) leave it empty.
func (ReasoningPart) Clone ¶
func (p ReasoningPart) Clone() Part
func (ReasoningPart) Kind ¶
func (ReasoningPart) Kind() PartKind
func (ReasoningPart) Validate ¶
func (p ReasoningPart) Validate() error
type SchemaBuilder ¶
type SchemaBuilder struct {
// contains filtered or unexported fields
}
SchemaBuilder constructs a ToolDefinition using a fluent API.
func DefineSchema ¶
func DefineSchema(name, description string, props ...ToolPropertyDef) *SchemaBuilder
DefineSchema starts building a ToolDefinition with the given properties.
func (*SchemaBuilder) Build ¶
func (b *SchemaBuilder) Build() ToolDefinition
Build returns the final ToolDefinition.
func (*SchemaBuilder) DisallowAdditionalProperties ¶
func (b *SchemaBuilder) DisallowAdditionalProperties() *SchemaBuilder
DisallowAdditionalProperties marks the object schema as closed: providers that honor additionalProperties will reject arguments outside the declared properties.
func (*SchemaBuilder) Required ¶
func (b *SchemaBuilder) Required(names ...string) *SchemaBuilder
Required marks the given property names as required in the JSON Schema. Duplicate names are silently ignored.
type Stream ¶ added in v0.1.17
Stream is the canonical pull-based transport for live content: the message-level instantiation of media.Stream over Part.
A Stream is how a message "exists" while it is in flight — for example the audio/video input of a live session. It is deliberately not a new DTO: the items are ordinary Part values, and a stream-backed part is materialized back into ordinary parts before it enters durable context or history (see MaterializeContent).
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Arguments json.RawMessage `json:"arguments"`
}
ToolCall is a provider-requested tool invocation. Arguments is always a JSON object and remains opaque to the inference package.
func NewToolCall ¶
NewToolCall encodes args as the argument object for a tool invocation.
type ToolCallPart ¶
type ToolCallPart struct {
Call ToolCall `json:"call"`
}
func (ToolCallPart) Clone ¶
func (p ToolCallPart) Clone() Part
func (ToolCallPart) Kind ¶
func (ToolCallPart) Kind() PartKind
func (ToolCallPart) Validate ¶
func (p ToolCallPart) Validate() error
type ToolDefinition ¶
type ToolDefinition struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
InputSchema json.RawMessage `json:"input_schema"`
}
ToolDefinition describes a callable tool. InputSchema must be a JSON Schema object; it is kept as raw JSON so inference requests never expose an untyped provider-parameter map.
func (ToolDefinition) Clone ¶
func (d ToolDefinition) Clone() ToolDefinition
func (ToolDefinition) Validate ¶
func (d ToolDefinition) Validate() error
type ToolPropertyDef ¶
type ToolPropertyDef struct {
// contains filtered or unexported fields
}
ToolPropertyDef describes a single JSON Schema property.
func ToolArrayProperty ¶
func ToolArrayProperty(name, description string, items map[string]any) ToolPropertyDef
ToolArrayProperty creates an array property with item schema.
func ToolEnumProperty ¶
func ToolEnumProperty(name, typ, description string, values ...string) ToolPropertyDef
ToolEnumProperty creates a property restricted to a set of string values.
func ToolObjectProperty ¶
func ToolObjectProperty(name, description string, properties map[string]any) ToolPropertyDef
ToolObjectProperty creates an object property with nested properties schema.
func ToolProperty ¶
func ToolProperty(name, typ, description string) ToolPropertyDef
ToolProperty creates a simple typed property definition.
func ToolPropertyWithDefault ¶
func ToolPropertyWithDefault(name, typ, description string, defaultVal any) ToolPropertyDef
ToolPropertyWithDefault creates a typed property with a default value.
func ToolStringMapProperty ¶
func ToolStringMapProperty(name, description string) ToolPropertyDef
ToolStringMapProperty creates an object property whose values must be strings.
type ToolResult ¶
type ToolResult struct {
CallID string `json:"call_id"`
Content string `json:"content"`
IsError bool `json:"is_error,omitempty"`
}
ToolResult carries one tool execution result back into a chat operation.
func (ToolResult) Validate ¶
func (r ToolResult) Validate() error
type ToolResultPart ¶
type ToolResultPart struct {
Result ToolResult `json:"result"`
}
func (ToolResultPart) Clone ¶
func (p ToolResultPart) Clone() Part
func (ToolResultPart) Kind ¶
func (ToolResultPart) Kind() PartKind
func (ToolResultPart) Validate ¶
func (p ToolResultPart) Validate() error