zeroruntime

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// FinishReasonLength means the response was truncated at the output token
	// cap (OpenAI finish_reason=="length", Anthropic stop_reason=="max_tokens",
	// Gemini finishReason=="MAX_TOKENS").
	FinishReasonLength = "length"
	// FinishReasonContentFilter means the response was withheld or cut off by a
	// content/safety filter (OpenAI finish_reason=="content_filter",
	// Gemini finishReason=="SAFETY").
	FinishReasonContentFilter = "content_filter"
)

Normalized terminal finish reasons for responses that did not end normally. Providers map their native stop reasons onto these so consumers can detect a truncated or filtered response regardless of which provider produced it. A normal completion leaves the finish reason empty.

Variables

This section is empty.

Functions

func NormalizeImageMediaType

func NormalizeImageMediaType(s string) string

NormalizeImageMediaType canonicalizes a caller-supplied image type to one of the allow-listed MIME strings (image/png, image/jpeg, image/gif, image/webp) or "" when the input is outside the allow-list (the caller then rejects it).

It lowercases and trims the input, strips a leading "data:<m>;base64," prefix (using <m>), maps a bare png|jpeg|jpg|gif|webp to image/<x> (jpg->jpeg), and passes through an already-image/<x> value in the allow-list (image/jpg is also folded to image/jpeg). It is pure and has no dependencies.

Types

type AgentEventType

type AgentEventType string

AgentEventType is the stable PRD-level event stream shared by TUI, headless output, sessions, and future editor integrations.

const (
	AgentEventText       AgentEventType = "text"
	AgentEventToolCall   AgentEventType = "tool_call"
	AgentEventToolResult AgentEventType = "tool_result"
	AgentEventThinking   AgentEventType = "thinking"
	AgentEventUsage      AgentEventType = "usage"
	AgentEventPlanUpdate AgentEventType = "plan_update"
	AgentEventError      AgentEventType = "error"
	AgentEventTurnEnd    AgentEventType = "turn_end"
)

type CollectOptions

type CollectOptions struct {
	OnText      func(string)
	OnReasoning func(string)
	OnUsage     func(Usage)
	// OnToolCallStart fires when a tool call opens (id + tool name), and
	// OnToolCallDelta fires for each streamed argument fragment. Together they let
	// a surface render a tool call's arguments LIVE (e.g. a file being written)
	// instead of waiting for the whole call to accumulate. nil is a no-op.
	OnToolCallStart func(id, name string)
	OnToolCallDelta func(id, fragment string)
}

CollectOptions provides callbacks for consumers that need live stream updates.

type CollectedStream

type CollectedStream struct {
	Text             string
	ToolCalls        []ToolCall
	Usage            Usage
	Error            string
	DroppedToolCalls int // malformed tool calls the provider could not dispatch
	// FinishReason is the provider's normalized terminal stop reason when the
	// response did not end normally (FinishReasonLength / FinishReasonContentFilter).
	// It is empty for a normal completion. Truncated reports whether it is set.
	FinishReason string
	// ReasoningBlocks are the response's preserved reasoning artifacts (Anthropic
	// thinking blocks) that must be replayed on the next turn. Empty for providers
	// or runs without extended thinking.
	ReasoningBlocks []ReasoningBlock
	// HasReasoning records whether the provider streamed reasoning deltas. The
	// deltas remain non-answer content, but they still prove the turn was live.
	HasReasoning bool
}

CollectedStream is the non-streaming summary of provider events.

func CollectStream

func CollectStream(ctx context.Context, events <-chan StreamEvent) CollectedStream

CollectStream drains provider events into text, tool calls, usage, and error state.

func CollectStreamWithOptions

func CollectStreamWithOptions(ctx context.Context, events <-chan StreamEvent, options CollectOptions) CollectedStream

CollectStreamWithOptions drains provider events and emits optional live callbacks.

func (CollectedStream) Truncated

func (collected CollectedStream) Truncated() bool

Truncated reports whether the response ended for a non-normal reason (the output was cut at the token cap or withheld by a content filter), so callers can warn instead of treating a clipped answer as complete.

type CompletionRequest

type CompletionRequest struct {
	Messages []Message
	Tools    []ToolDefinition
	// ReasoningEffort, when non-empty, asks a reasoning-capable model to spend the
	// given level of thinking effort ("minimal"/"low"/"medium"/"high"). Each
	// provider adapter maps it to its own API shape (OpenAI reasoning_effort,
	// Anthropic/Gemini thinking budgets) and ignores it for models that do not
	// support reasoning. Empty means "let the provider decide".
	ReasoningEffort string
	// PromptCacheKey, when non-empty, is an opaque stable identifier for the
	// conversation (the session ID). Providers with server-side prefix-cache
	// routing forward it — OpenAI `prompt_cache_key` — so consecutive requests
	// land on a replica that already holds the cached prompt prefix instead of
	// re-billing the full prefix each turn. Providers without an equivalent
	// ignore it.
	PromptCacheKey string
}

CompletionRequest groups provider input messages and available tools.

type ImageBlock

type ImageBlock struct {
	MediaType string
	Data      []byte
}

ImageBlock is a normalized image attachment carried on a Message. Data is the RAW decoded image bytes (no base64, no data: prefix); each provider encodes it into its own wire format. MediaType is a normalized MIME, e.g. "image/png".

func CloneImageBlocks

func CloneImageBlocks(in []ImageBlock) []ImageBlock

CloneImageBlocks deep-copies a slice of ImageBlock, including each Data byte slice, so the returned blocks share no backing array with the input. It returns nil for a nil or empty input (preserving the text-only "no images" representation). Use it wherever image-carrying messages are seeded or copied so raw image bytes are never aliased across history/request/result copies.

type Message

type Message struct {
	Role       MessageRole
	Content    string
	ToolCalls  []ToolCall
	ToolCallID string
	Images     []ImageBlock     // optional; nil for text-only messages
	Reasoning  []ReasoningBlock // optional; preserved thinking blocks to replay
}

Message is a normalized conversation turn passed to providers.

func SeedMessages

func SeedMessages(systemPrompt string, userPrompt string) []Message

SeedMessages creates the initial system and user turns for a request. It is a text-only convenience that delegates to SeedMessagesWithImages with no images (the user turn's Images stays nil, byte-identical to the prior behavior).

func SeedMessagesWithImages

func SeedMessagesWithImages(systemPrompt string, userPrompt string, images []ImageBlock) []Message

SeedMessagesWithImages creates the initial system and user turns and attaches any image attachments to the user turn. images may be nil (text-only). The images are deep-copied so the seeded message never aliases the caller's slice or the underlying Data bytes (a later mutation of the caller's bytes can never reach into the conversation history).

type MessageRole

type MessageRole string

MessageRole identifies the origin of a conversation message.

const (
	MessageRoleSystem    MessageRole = "system"
	MessageRoleUser      MessageRole = "user"
	MessageRoleAssistant MessageRole = "assistant"
	MessageRoleTool      MessageRole = "tool"
)

type Provider

type Provider interface {
	StreamCompletion(ctx context.Context, request CompletionRequest) (<-chan StreamEvent, error)
}

Provider streams normalized completion events for one request.

type ReasoningBlock

type ReasoningBlock struct {
	Provider  string // adapter that produced and can replay this block ("anthropic", "gemini")
	Type      string // provider block type ("thinking", "redacted_thinking")
	Text      string // human-readable reasoning text (empty for redacted/opaque blocks)
	Signature string // cryptographic signature the provider requires on replay
	Data      string // opaque provider payload (e.g. Anthropic redacted_thinking data)
}

ReasoningBlock is a provider-emitted reasoning artifact that must be replayed verbatim on later turns or the provider rejects the (tool-using) conversation: Anthropic requires thinking / redacted_thinking blocks be passed back with their signatures. Only the adapter named by Provider interprets a block; other adapters ignore foreign blocks, so a mid-run provider switch is safe.

type StreamEvent

type StreamEvent struct {
	Type              StreamEventType
	Content           string
	ToolCallID        string
	ToolName          string
	ToolCallSignature string // opaque reasoning signature bound to this call (Gemini thoughtSignature)
	ArgumentsFragment string
	Usage             Usage
	Error             string
	// FinishReason carries the provider's normalized terminal stop reason when a
	// response did not end normally (e.g. FinishReasonLength when the output hit
	// the token cap, or FinishReasonContentFilter when it was filtered). It is
	// empty for a normal completion. Providers set it on the terminal/done event.
	FinishReason string
	// ReasoningBlocks carries completed reasoning artifacts (Anthropic thinking /
	// redacted_thinking blocks) that must be preserved for replay. Providers attach
	// them to the terminal/done event; the collector accumulates them.
	ReasoningBlocks []ReasoningBlock
}

StreamEvent is one normalized event emitted by a streaming provider.

type StreamEventType

type StreamEventType string

StreamEventType identifies one event in a provider completion stream.

const (
	StreamEventText StreamEventType = "text"
	// StreamEventReasoning carries live reasoning deltas that must never be
	// folded into answer text or persisted as assistant content.
	StreamEventReasoning     StreamEventType = "reasoning"
	StreamEventToolCallStart StreamEventType = "tool-call-start"
	StreamEventToolCallDelta StreamEventType = "tool-call-delta"
	StreamEventToolCallEnd   StreamEventType = "tool-call-end"
	// StreamEventToolCallDropped signals the model attempted a tool call that
	// was malformed (no usable name/id) and could not be dispatched. The agent
	// uses this to ask the model to retry instead of silently ending the turn.
	StreamEventToolCallDropped StreamEventType = "tool-call-dropped"
	StreamEventUsage           StreamEventType = "usage"
	StreamEventDone            StreamEventType = "done"
	StreamEventError           StreamEventType = "error"
)

type TokenUsage

type TokenUsage struct {
	InputTokens       int
	PromptTokens      int
	CachedInputTokens int
	// CacheWriteTokens is the cache-creation (cache-write) portion of the input,
	// billed at a premium rate by providers that support it (e.g. Anthropic).
	// Like CachedInputTokens it is a SUBSET of InputTokens, not additive.
	CacheWriteTokens int
	OutputTokens     int
	CompletionTokens int
	ReasoningTokens  int
}

TokenUsage accepts provider-specific token aliases before normalization.

type ToolCall

type ToolCall struct {
	ID        string
	Name      string
	Arguments string
	// Signature carries a provider's opaque reasoning signature bound to this call
	// (Gemini attaches a thoughtSignature to a functionCall part). It must be
	// echoed back with the call on later turns or the provider may reject the
	// multi-turn function-calling conversation. Empty for providers that do not
	// use it. Only the originating adapter interprets it.
	Signature string
}

ToolCall is a normalized assistant request to run a tool.

type ToolDefinition

type ToolDefinition struct {
	Name        string
	Description string
	Parameters  map[string]any
}

ToolDefinition describes a model-visible tool and its JSON-schema parameters.

type Usage

type Usage struct {
	InputTokens       int
	OutputTokens      int
	PromptTokens      int
	CompletionTokens  int
	CachedInputTokens int
	CacheWriteTokens  int
	ReasoningTokens   int
}

Usage records normalized token accounting reported by a provider.

Token accounting is consistent across providers: InputTokens is the TOTAL prompt size (uncached + cache-read + cache-write); CachedInputTokens (cache read, discounted) and CacheWriteTokens (cache creation, premium) are subsets of it, so uncached input = InputTokens - CachedInputTokens - CacheWriteTokens. OutputTokens is the TOTAL output size, including hidden reasoning tokens when a provider reports them separately; ReasoningTokens is a subset of OutputTokens, not an additive count.

func NormalizeUsage

func NormalizeUsage(input TokenUsage) (Usage, error)

NormalizeUsage converts provider token aliases into the shared runtime shape.

func (Usage) BillableOutputTokens

func (usage Usage) BillableOutputTokens() int

func (Usage) EffectiveInputTokens

func (usage Usage) EffectiveInputTokens() int

func (Usage) EffectiveOutputTokens

func (usage Usage) EffectiveOutputTokens() int

func (Usage) TotalTokens

func (usage Usage) TotalTokens() int

TotalTokens returns prompt plus completion tokens.

func (Usage) VisibleOutputTokens

func (usage Usage) VisibleOutputTokens() int

Jump to

Keyboard shortcuts

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