Skip to documentation
Documentation navigation

Documentation navigation

Documentation / guides

Overview

The sealed content vocabulary used by messages, codecs, and streaming.

developer

Looprig represents model input and output as an ordered slice of sealed content.Block values. The concrete Go pointer is the in-memory discriminator; JSON adds a type tag at the boundary. This keeps provider codecs independent of ad-hoc maps while still allowing nested tool results.

The block vocabulary

VariantPayloadTypical direction
TextBlockUTF-8 textinput or output
ImageBlockMIME type plus URL or bytesinput
AudioBlockMIME type plus bytesinput
DocumentBlockMIME type, name, bytes, or extracted textinput
ThinkingBlockreasoning text, signature, provider stateoutput and replay
ToolUseBlockcall ID, name, raw JSON argumentsoutput
ToolResultBlocktool-call ID, nested blocks, error bitinput
package main

import (
	"encoding/json"
	"fmt"

	"github.com/looprig/core/content"
)

func main() {
	blocks := []content.Block{
		&content.TextBlock{Text: "Inspect this report."},
		&content.ToolUseBlock{
			ID: "call-1", Name: "search",
			Input: json.RawMessage(`{"query":"revenue"}`),
		},
	}
	wire, err := content.MarshalBlocks(blocks)
	if err != nil {
		panic(err)
	}
	decoded, err := content.UnmarshalBlocks(wire)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%T %T\n", decoded[0], decoded[1])
}

The block interface is sealed by an unexported isBlock method. A consumer should type-switch over the seven exported pointer variants and treat an unexpected or typed-nil value as invalid input.

Blocks and streaming chunks

Complete blocks and incremental chunks are intentionally different types. A TextChunk contains a delta; a TextBlock contains the assembled value. Thinking signatures and tool-call argument fragments are the reason the distinction matters.

%%{init: {"theme":"base","themeVariables":{"background":"#111827","primaryColor":"#1f2937","primaryTextColor":"#f8fafc","primaryBorderColor":"#64748b","lineColor":"#94a3b8","secondaryColor":"#0f172a","tertiaryColor":"#172033","fontFamily":"Inter, ui-sans-serif, system-ui, sans-serif"}}}%%
flowchart LR
    wire[Provider stream] --> chunk[content.Chunk]
    chunk --> fold[streamaccumulator]
    fold --> block[content.Block]
    block --> message[AIMessage]
    classDef dark fill:#1f2937,stroke:#94a3b8,color:#f8fafc
    class wire,chunk,fold,block,message dark

Proof

Related: Messages, Streaming, ToolUseBlock.

← back to documentation