base

package
v0.5.0-beta Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package base provides shared functionality for LLM thread implementations. It contains common fields, methods, and constants used across all LLM providers (Anthropic, OpenAI, and Google) to reduce code duplication.

Index

Constants

View Source
const (
	MaxImageFileSize = 5 * 1024 * 1024 // 5MB limit
	MaxImageCount    = 10              // Maximum 10 images per message
)

Constants for image processing (shared across all providers)

Variables

This section is empty.

Functions

func AvailableTools

func AvailableTools(state tooltypes.State, noToolUse bool) []tooltypes.Tool

AvailableTools returns tools from state while handling disabled tool use and nil state.

func AvailableToolsForThread

func AvailableToolsForThread(thread llmtypes.Thread, state tooltypes.State, noToolUse bool) []tooltypes.Tool

AvailableToolsForThread returns tools filtered by any per-turn extension tool-list patch.

func Base64ImageSourceMediaType

func Base64ImageSourceMediaType(mimeType string) (string, error)

Base64ImageSourceMediaType validates Anthropic-compatible base64 image MIME types.

func BuildShortSummaryPrompt

func BuildShortSummaryPrompt(markdown string) string

BuildShortSummaryPrompt wraps rendered conversation markdown in the short-summary instruction.

func CompactContextWithSummary

func CompactContextWithSummary(
	ctx context.Context,
	runUtilityPrompt func(ctx context.Context, prompt string, useWeakModel bool) (string, error),
	swapContext func(ctx context.Context, summary string) error,
) error

CompactContextWithSummary runs the built-in compact prompt to produce a summary, then swaps context to that summary.

func DataURLFromBase64Payload

func DataURLFromBase64Payload(mimeType, base64Data string) string

DataURLFromBase64Payload constructs a data URL from mime type and base64 bytes.

func DispatchAgentStart

func DispatchAgentStart(ctx context.Context, thread llmtypes.Thread)

DispatchAgentStart notifies extension handlers when an agent loop starts.

func DispatchTurnStart

func DispatchTurnStart(ctx context.Context, thread llmtypes.Thread, turnNumber int)

DispatchTurnStart notifies extension handlers before a model turn starts.

func FirstUserMessageFallback

func FirstUserMessageFallback(messages []conversations.StreamableMessage) string

FirstUserMessageFallback builds a user-facing conversation title from the first user text message.

func GenerateShortSummary

func GenerateShortSummary(
	ctx context.Context,
	markdown string,
	runUtilityPrompt func(ctx context.Context, prompt string, useWeakModel bool) (string, error),
) (string, error)

GenerateShortSummary runs a summary prompt using the utility prompt runner. It returns a normalized summary on success, or an error when generation fails or produces an empty result.

func HandleAgentStopFollowUps

func HandleAgentStopFollowUps(
	ctx context.Context,
	thread llmtypes.Thread,
	handler llmtypes.MessageHandler,
) bool

HandleAgentStopFollowUps checks agent.end extension handlers and appends any follow-up user messages. Returns true when follow-ups were added and the caller should continue the loop.

func HandleGoalAutoContinuation

func HandleGoalAutoContinuation(ctx context.Context, thread llmtypes.Thread, availableTools []tooltypes.Tool) bool

HandleGoalAutoContinuation appends a goal continuation user-context message and reports whether the provider loop should continue. It is called only when the model would otherwise stop for the current exchange.

func ImageMIMETypeFromExtension

func ImageMIMETypeFromExtension(ext string) (string, error)

ImageMIMETypeFromExtension returns the MIME type for supported image extensions.

func IsInsecureHTTPURL

func IsInsecureHTTPURL(imagePath string) bool

IsInsecureHTTPURL returns true when the image path starts with plain HTTP.

func ParseBase64DataURL

func ParseBase64DataURL(dataURL string) (string, string, error)

ParseBase64DataURL parses data URLs with the format: data:<mediatype>;base64,<data>.

func ProcessSystemPrompt

func ProcessSystemPrompt(ctx context.Context, thread llmtypes.Thread, systemPrompt string) string

ProcessSystemPrompt dispatches agent.init and returns the effective prompt.

func ProcessUserMessage

func ProcessUserMessage(
	ctx context.Context,
	thread llmtypes.Thread,
	message string,
) (string, error)

ProcessUserMessage dispatches user.message and returns the effective message.

func ReadImageFileAsBase64

func ReadImageFileAsBase64(filePath string) (string, string, error)

ReadImageFileAsBase64 validates an image file and returns its MIME type and base64 payload.

func ReadImageFileAsDataURL

func ReadImageFileAsDataURL(filePath string) (string, error)

ReadImageFileAsDataURL validates an image file and returns a data URL.

func RenderMarkdownForSummary

func RenderMarkdownForSummary(
	messages []conversations.StreamableMessage,
	toolResults map[string]tooltypes.StructuredToolResult,
) string

RenderMarkdownForSummary converts streamable messages into markdown optimized for summary generation.

func RouteImageInput

func RouteImageInput[T any](
	imagePath string,
	handleHTTPSURL func(path string) (T, error),
	handleDataURL func(path string) (T, error),
	handleLocalFile func(path string) (T, error),
) (T, error)

RouteImageInput routes an image path to the corresponding handler based on input kind.

func RunPreparedPrompt

func RunPreparedPrompt(
	ctx context.Context,
	createThread func() (llmtypes.Thread, error),
	prepareThread func(thread llmtypes.Thread) error,
	prompt string,
	opt llmtypes.MessageOpt,
) (string, error)

RunPreparedPrompt creates a helper thread, prepares it, sends a prompt, and collects text output.

func RunPreparedPromptTyped

func RunPreparedPromptTyped[T llmtypes.Thread](
	ctx context.Context,
	createThread func() (T, error),
	prepareThread func(thread T) error,
	prompt string,
	opt llmtypes.MessageOpt,
) (string, error)

RunPreparedPromptTyped is a typed variant of RunPreparedPrompt that avoids provider-side type assertions.

func RunUtilityPrompt

func RunUtilityPrompt[T UtilityThread](
	ctx context.Context,
	createThread func() (T, error),
	seedThread func(thread T),
	prompt string,
	useWeakModel bool,
) (string, error)

RunUtilityPrompt creates a helper thread, seeds provider-specific history, switches it to utility mode, and sends a prompt.

func TriggerTurnEnd

func TriggerTurnEnd(
	ctx context.Context,
	thread llmtypes.Thread,
	finalOutput string,
	turnCount int,
)

TriggerTurnEnd notifies extension handlers when assistant output is finalized for a turn.

func UtilityPromptOptions

func UtilityPromptOptions(useWeakModel bool) llmtypes.MessageOpt

UtilityPromptOptions returns standard options for internal utility prompts (summary/compaction).

func ValidateDataURLPrefix

func ValidateDataURLPrefix(dataURL string) error

ValidateDataURLPrefix validates that a string starts with "data:".

func ValidateHTTPSImageURL

func ValidateHTTPSImageURL(url string) error

ValidateHTTPSImageURL validates that an image URL uses HTTPS.

Types

type AgentInitDecision

type AgentInitDecision struct {
	SystemPrompt  string
	AllowedTools  []string
	ToolsModified bool
}

AgentInitDecision is the host-side result of processing agent.init handlers.

func ProcessAgentInit

func ProcessAgentInit(ctx context.Context, thread llmtypes.Thread, systemPrompt string) AgentInitDecision

ProcessAgentInit dispatches agent.init and applies supported prompt/tool-list mutations.

type ConversationStore

type ConversationStore = conversations.ConversationStore

ConversationStore is an alias for the conversations.ConversationStore interface to avoid direct dependency on the conversations package in provider implementations.

type ImageInputKind

type ImageInputKind int

ImageInputKind describes the source type for an image argument.

const (
	// ImageInputHTTPSURL is an HTTPS URL image source.
	ImageInputHTTPSURL ImageInputKind = iota
	// ImageInputDataURL is a data URL image source.
	ImageInputDataURL
	// ImageInputLocalFile is a local file path image source.
	ImageInputLocalFile
)

func ResolveImageInputPath

func ResolveImageInputPath(imagePath string) (ImageInputKind, string)

ResolveImageInputPath classifies and normalizes an image input path. file:// paths are normalized into local file paths.

type LoadConversationFunc

type LoadConversationFunc func(ctx context.Context)

LoadConversationFunc is a callback function type for provider-specific conversation loading. This is called by EnablePersistence when persistence is enabled and a store is available.

type StructuredResultToolResult

type StructuredResultToolResult struct {
	Result           tooltypes.StructuredToolResult
	RendererRegistry *renderers.RendererRegistry
}

StructuredResultToolResult adapts a structured result back to ToolResult so post-tool extension mutations affect both rendering and provider LLM input.

func (StructuredResultToolResult) AssistantFacing

func (r StructuredResultToolResult) AssistantFacing() string

func (StructuredResultToolResult) ContentParts

func (StructuredResultToolResult) GetError

func (r StructuredResultToolResult) GetError() string

func (StructuredResultToolResult) GetResult

func (r StructuredResultToolResult) GetResult() string

func (StructuredResultToolResult) IsError

func (r StructuredResultToolResult) IsError() bool

func (StructuredResultToolResult) String

func (StructuredResultToolResult) StructuredData

type Thread

type Thread struct {
	Config           llmtypes.Config                           // LLM configuration
	State            tooltypes.State                           // Tool execution state
	Usage            *llmtypes.Usage                           // Token usage tracking
	ConversationID   string                                    // Unique conversation identifier
	Persisted        bool                                      // Whether conversation is being persisted
	Metadata         map[string]any                            // Additional provider-neutral conversation metadata
	Store            ConversationStore                         // Conversation persistence store
	ToolResults      map[string]tooltypes.StructuredToolResult // Maps tool_call_id to structured result
	RendererRegistry *renderers.RendererRegistry               // CLI renderer registry for structured tool results
	LoadConversation LoadConversationFunc                      // Provider-specific callback for loading conversations

	Mu             sync.Mutex // Mutex for thread-safe operations on usage and tool results
	ConversationMu sync.Mutex // Mutex for conversation-related operations
}

Thread contains shared fields that are common across all LLM provider implementations. Provider-specific Thread structs should embed this struct to inherit common functionality.

func NewThread

func NewThread(
	config llmtypes.Config,
	conversationID string,
) *Thread

NewThread creates a new Thread with initialized fields. This constructor should be called by provider-specific constructors.

func (*Thread) AggregateSubagentUsage

func (t *Thread) AggregateSubagentUsage(usage llmtypes.Usage)

AggregateSubagentUsage aggregates usage from a subagent into this thread's usage. This aggregates token counts and costs but NOT context window metrics (CurrentContextWindow and MaxContextWindow remain unchanged to avoid premature auto-compact). This method is thread-safe and uses mutex locking.

func (*Thread) CompactRatioOrDefault

func (t *Thread) CompactRatioOrDefault(optionRatio float64) float64

CompactRatioOrDefault resolves the auto-compact threshold for a message. A zero option value means "use the thread/configured default", not "disable".

func (*Thread) CreateMessageSpan

func (t *Thread) CreateMessageSpan(
	ctx context.Context,
	tracer trace.Tracer,
	message string,
	opt llmtypes.MessageOpt,
	extraAttributes ...attribute.KeyValue,
) (context.Context, trace.Span)

CreateMessageSpan creates a new tracing span for LLM message processing. It includes common attributes shared across all providers and allows for additional provider-specific attributes to be passed in.

Common attributes included:

  • model, max_tokens, weak_model_max_tokens, is_sub_agent
  • conversation_id, is_persisted, message_length, use_weak_model

Provider-specific attributes (passed via extraAttributes):

  • Anthropic: thinking_budget_tokens, prompt_cache
  • OpenAI: reasoning_effort, platform
  • Google: backend

func (*Thread) EnablePersistence

func (t *Thread) EnablePersistence(ctx context.Context, enabled bool)

EnablePersistence enables or disables conversation persistence. When enabling persistence:

  • Initializes the conversation store if not already initialized
  • Calls the LoadConversation callback to load any existing conversation

If store initialization fails, persistence is disabled and the error is logged. The LoadConversation callback must be set by the provider before calling this method if provider-specific conversation loading is needed. This method is thread-safe and uses mutex locking.

func (*Thread) EstimateContextWindowFromMessage

func (t *Thread) EstimateContextWindowFromMessage(msg string)

EstimateContextWindowFromMessage estimates the context window size based on message content. This is useful after compaction to provide an approximate context size before the next API call. Uses a rough estimate of ~4 characters per token. This method is thread-safe and uses mutex locking.

func (*Thread) FinalizeMessageSpan

func (t *Thread) FinalizeMessageSpan(span trace.Span, err error, extraAttributes ...attribute.KeyValue)

FinalizeMessageSpan records final metrics and status to the span before ending it. It includes common usage attributes and allows for additional provider-specific attributes.

Common attributes included:

  • tokens.input, tokens.output, cost.total
  • context_window.current, context_window.max

Provider-specific attributes (passed via extraAttributes):

  • Anthropic: tokens.cache_creation, tokens.cache_read
  • Google: tokens.cache_read

func (*Thread) FinalizeSwapContextLocked

func (t *Thread) FinalizeSwapContextLocked(summary string)

FinalizeSwapContextLocked resets shared state after provider-specific context replacement. Caller must hold t.Mu.

func (*Thread) GetConfig

func (t *Thread) GetConfig() llmtypes.Config

GetConfig returns the configuration of the thread

func (*Thread) GetConversationID

func (t *Thread) GetConversationID() string

GetConversationID returns the current conversation ID

func (*Thread) GetMetadata

func (t *Thread) GetMetadata() map[string]any

GetMetadata returns a copy of provider-neutral conversation metadata. This method is thread-safe and uses mutex locking.

func (*Thread) GetState

func (t *Thread) GetState() tooltypes.State

GetState returns the current state of the thread

func (*Thread) GetStructuredToolResults

func (t *Thread) GetStructuredToolResults() map[string]tooltypes.StructuredToolResult

GetStructuredToolResults returns a copy of all structured tool results. This method is thread-safe and uses mutex locking. A copy is returned to avoid race conditions.

func (*Thread) GetUsage

func (t *Thread) GetUsage() llmtypes.Usage

GetUsage returns the current token usage for the thread. This method is thread-safe and uses mutex locking.

func (*Thread) IsPersisted

func (t *Thread) IsPersisted() bool

IsPersisted returns whether this thread is being persisted

func (*Thread) PrepareUtilityMode

func (t *Thread) PrepareUtilityMode(ctx context.Context)

PrepareUtilityMode configures a thread for internal utility calls such as summary generation. Utility mode disables persistence and extensions to avoid side effects.

func (*Thread) ResetContextStateLocked

func (t *Thread) ResetContextStateLocked()

ResetContextStateLocked clears shared state after context replacement/compaction. Caller must hold t.Mu.

func (*Thread) SetConversationID

func (t *Thread) SetConversationID(id string)

SetConversationID sets the conversation ID.

func (*Thread) SetExtensions

func (t *Thread) SetExtensions(runtime any)

SetExtensions updates the turn-scoped extension runtime used by tool execution.

func (*Thread) SetMetadata

func (t *Thread) SetMetadata(metadata map[string]any)

SetMetadata replaces provider-neutral conversation metadata with a copy of metadata. This method is thread-safe and uses mutex locking.

func (*Thread) SetMetadataValue

func (t *Thread) SetMetadataValue(key string, value any)

SetMetadataValue stores a provider-neutral conversation metadata value. This method is thread-safe and uses mutex locking.

func (*Thread) SetState

func (t *Thread) SetState(s tooltypes.State)

SetState sets the state for the thread

func (*Thread) SetStructuredToolResult

func (t *Thread) SetStructuredToolResult(toolCallID string, result tooltypes.StructuredToolResult)

SetStructuredToolResult stores the structured result for a tool call. This method is thread-safe and uses mutex locking.

func (*Thread) SetStructuredToolResults

func (t *Thread) SetStructuredToolResults(results map[string]tooltypes.StructuredToolResult)

SetStructuredToolResults replaces all structured tool results with the provided map. This method is thread-safe and uses mutex locking. A copy of the input map is made to avoid external modifications.

func (*Thread) ShouldAutoCompact

func (t *Thread) ShouldAutoCompact(compactRatio float64) bool

ShouldAutoCompact checks if auto-compact should be triggered based on context window utilization. Returns true if the current context window utilization ratio >= compactRatio. Returns false if compactRatio is invalid (<= 0 or > 1) or MaxContextWindow is 0.

func (*Thread) TryAutoCompact

func (t *Thread) TryAutoCompact(
	ctx context.Context,
	compactRatio float64,
	compactFn func(context.Context) error,
)

TryAutoCompact triggers context compaction when auto-compact conditions are met. compactFn should perform provider-specific compaction logic.

type ToolExecution

type ToolExecution struct {
	// Input is the final tool input after tool.call extension handlers.
	Input string
	// Result is the final tool result after extension mutation.
	Result tooltypes.ToolResult
	// StructuredResult is the final structured payload after tool.result extension handlers.
	StructuredResult tooltypes.StructuredToolResult
	// RenderedOutput is the CLI-rendered output form of StructuredResult.
	RenderedOutput string
}

ToolExecution holds the normalized result of one tool execution cycle.

func ExecuteTool

func ExecuteTool(
	ctx context.Context,
	thread llmtypes.Thread,
	state tooltypes.State,
	rendererRegistry *renderers.RendererRegistry,
	toolName string,
	toolInput string,
	toolCallID string,
) ToolExecution

ExecuteTool runs one complete tool lifecycle: extension tool.call -> tool execution -> extension tool.result -> rendering.

type UtilityThread

type UtilityThread interface {
	llmtypes.Thread
	PrepareUtilityMode(ctx context.Context)
}

UtilityThread is a thread that supports utility-mode preparation.

Jump to

Keyboard shortcuts

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