gollem

package module
v0.26.0 Latest Latest
Warning

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

Go to latest
Published: Jun 13, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

README

🤖 gollem Go Reference Test Lint Gosec Trivy

GO for Large LanguagE Model (GOLLEM)

gollem provides:

  • Common interface to query prompt to Large Language Model (LLM) services
    • Generate / Stream: Generate text content from prompt (with per-call option overrides)
    • GenerateEmbedding: Generate embedding vector from text (OpenAI and Gemini)
  • Framework for building agentic applications of LLMs with
    • Tools by MCP (Model Context Protocol) server and your built-in tools
    • Automatic session management for continuous conversations
    • Portable conversational memory with history for stateless/distributed applications
    • Intelligent memory management with automatic history compaction
    • Middleware system for monitoring, logging, and controlling agent behavior

Supported LLMs

Install

go get github.com/gollem-dev/gollem

Quick Start

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/gollem-dev/gollem"
	"github.com/gollem-dev/gollem/llm/openai"
)

func main() {
	ctx := context.Background()

	// Create LLM client
	client, err := openai.New(ctx, os.Getenv("OPENAI_API_KEY"))
	if err != nil {
		panic(err)
	}

	// Create session for one-time query
	session, err := client.NewSession(ctx)
	if err != nil {
		panic(err)
	}

	// Generate content
	result, err := session.Generate(ctx, []gollem.Input{gollem.Text("Hello, how are you?")})
	if err != nil {
		panic(err)
	}

	fmt.Println(result.Texts)
}

Features

Agent Framework

Build conversational agents with automatic session management and tool integration. Learn more →

agent := gollem.New(client,
	gollem.WithTools(&GreetingTool{}),
	gollem.WithSystemPrompt("You are a helpful assistant."),
)

// Session is managed automatically across calls
agent.Execute(ctx, "Hello!")
agent.Execute(ctx, "What did I just say?") // remembers context
Tool Integration

Define custom tools for LLMs to call, or connect external tools via MCP. Tools → | MCP →

// Custom tool - implement Spec() and Run()
type SearchTool struct{}

func (t *SearchTool) Spec() gollem.ToolSpec {
	return gollem.ToolSpec{
		Name:        "search",
		Description: "Search the database",
		Parameters:  map[string]*gollem.Parameter{
			"query": {Type: gollem.TypeString, Description: "Search query"},
		},
	}
}

func (t *SearchTool) Run(ctx context.Context, args map[string]any) (map[string]any, error) {
	return map[string]any{"results": doSearch(args["query"].(string))}, nil
}

// MCP server - connect external tool servers
mcpClient, _ := mcp.NewStdio(ctx, "./mcp-server", []string{})
agent := gollem.New(client,
	gollem.WithTools(&SearchTool{}),
	gollem.WithToolSets(mcpClient),
)
Multimodal Input

Send images and PDFs alongside text prompts. Learn more →

img, _ := gollem.NewImage(imageBytes)
pdf, _ := gollem.NewPDFFromReader(file)

result, _ := session.Generate(ctx, []gollem.Input{img, pdf, gollem.Text("Describe these.")})
Structured Output

Constrain LLM responses to a JSON Schema. Learn more →

schema, _ := gollem.ToSchema(UserProfile{})
session, _ := client.NewSession(ctx,
	gollem.WithSessionContentType(gollem.ContentTypeJSON),
	gollem.WithSessionResponseSchema(schema),
)
resp, _ := session.Generate(ctx, []gollem.Input{gollem.Text("Extract: John, 30, john@example.com")})
// resp.Texts[0] is valid JSON matching the schema

For one-shot queries, Query[T]() combines schema generation, session creation, LLM call, and JSON parsing into a single generic function call with automatic retry on parse failures:

type UserProfile struct {
	Name  string `json:"name" description:"User's full name"`
	Age   int    `json:"age" description:"Age in years"`
	Email string `json:"email" description:"Email address"`
}

result, _ := gollem.Query[UserProfile](ctx, client, "Extract: John, 30, john@example.com",
	gollem.WithQuerySystemPrompt("You are a data extractor."),
)
// result.Data is *UserProfile — type-safe, already parsed

To run a structured query on an existing session (preserving conversation history), use SessionQuery[T]():

// session already has conversation context from prior Generate calls
resp, _ := gollem.SessionQuery[UserProfile](ctx, session, "Who am I?")
// resp.Data is *UserProfile, parsed from the LLM's JSON response
// The session's history (including this exchange) is preserved
Middleware

Monitor, log, and control agent behavior with composable middleware. Learn more →

agent := gollem.New(client,
	gollem.WithToolMiddleware(func(next gollem.ToolHandler) gollem.ToolHandler {
		return func(ctx context.Context, req *gollem.ToolExecRequest) (*gollem.ToolExecResponse, error) {
			log.Printf("Tool called: %s", req.Tool.Name)
			return next(ctx, req)
		}
	}),
)
Strategy Pattern

Swap execution strategies: simple, ReAct, or Plan & Execute. Learn more →

import "github.com/gollem-dev/gollem/strategy/planexec"

agent := gollem.New(client,
	gollem.WithStrategy(planexec.New(client)),
	gollem.WithTools(&SearchTool{}, &AnalysisTool{}),
)
Tracing

Observe agent execution with pluggable backends (in-memory, OpenTelemetry). Learn more →

import "github.com/gollem-dev/gollem/trace"

rec := trace.New(trace.WithRepository(trace.NewFileRepository("./traces")))
agent := gollem.New(client, gollem.WithTrace(rec))

History Management

Portable conversation history for stateless/distributed applications. Learn more →

// Export history for persistence
history := agent.Session().History()
data, _ := json.Marshal(history)

// Restore in another process
var restored gollem.History
json.Unmarshal(data, &restored)
agent := gollem.New(client, gollem.WithHistory(&restored))

For automatic persistence, implement HistoryRepository and pass it via WithHistoryRepository. gollem then loads history at the start of a session and saves it after every LLM round-trip — no manual marshaling required.

agent := gollem.New(client,
    gollem.WithHistoryRepository(repo, "session-id"),
)

// History is loaded automatically on first Execute, and saved after each round-trip
err := agent.Execute(ctx, gollem.Text("Hello!"))

Examples

See the examples directory for complete working examples:

  • Simple: Minimal example for getting started
  • Query: Type-safe structured query with Query[T]()
  • Basic: Simple agent with custom tools
  • Chat: Interactive chat application
  • MCP: Integration with MCP servers
  • Tools: Custom tool development
  • JSON Schema: Structured output with JSON Schema validation
  • Embedding: Text embedding generation
  • Tracing: Agent execution tracing with file persistence

Documentation

License

Apache 2.0 License. See LICENSE for details.

Documentation

Overview

Package gollem provides a unified interface for interacting with various LLM services.

Index

Constants

View Source
const (
	DefaultLoopLimit = 128
)
View Source
const DefaultMaxPDFSize = 32 * 1024 * 1024

DefaultMaxPDFSize is the default maximum size for PDF data (32MB)

View Source
const (
	HistoryVersion = 3 // Unified format version (v3: removed legacy function calls and provider dialects)
)

Variables

View Source
var (
	// ErrInvalidTool is returned when the tool validation of definition fails.
	ErrInvalidTool = errors.New("invalid tool specification")

	// ErrInvalidParameter is returned when the parameter validation of definition fails.
	ErrInvalidParameter = errors.New("invalid parameter")

	// ErrToolNameConflict is returned when the tool name is already used.
	ErrToolNameConflict = errors.New("tool name conflict")

	// ErrLoopLimitExceeded is returned when the session loop limit is exceeded. You can resume the session by calling the Prompt() method again.
	ErrLoopLimitExceeded = errors.New("loop limit exceeded")

	// ErrInvalidInputSchema is returned when the input schema from MCP is invalid or unsupported.
	ErrInvalidInputSchema = errors.New("invalid input schema")

	// ErrInvalidHistoryData is returned when the history data is invalid or unsupported.
	ErrInvalidHistoryData = errors.New("invalid history data")

	// ErrLLMTypeMismatch is returned when the LLM type is invalid or unsupported when loading history.
	ErrLLMTypeMismatch = errors.New("llm type mismatch")

	// ErrHistoryVersionMismatch is returned when the history version is invalid or unsupported.
	ErrHistoryVersionMismatch = errors.New("history version mismatch")

	// ErrExitConversation is returned when a tool signals that the conversation should be exited.
	// This error is treated as a successful completion of the conversation loop.
	ErrExitConversation = errors.New("exit conversation")

	// ErrPlanAlreadyExecuted is returned when trying to run an already executed plan
	ErrPlanAlreadyExecuted = errors.New("plan already executed")

	// ErrPlanNotInitialized is returned when plan is not properly initialized
	ErrPlanNotInitialized = errors.New("plan not properly initialized")

	// ErrPlanStepFailed is returned when a plan step fails during execution
	ErrPlanStepFailed = errors.New("plan step execution failed")

	// ErrTokenSizeExceeded is returned when the token size exceeds the limit
	ErrTokenSizeExceeded = errors.New("token size exceeded")

	// ErrFunctionCallFormat is returned when the function call format is invalid
	ErrFunctionCallFormat = errors.New("function call format error")

	// ErrProhibitedContent is returned when the content violates policy
	ErrProhibitedContent = errors.New("prohibited content")

	// ErrToolArgsValidation is returned when the tool arguments from LLM fail validation.
	// This is distinct from ErrInvalidParameter which is for spec definition validation.
	ErrToolArgsValidation = errors.New("tool arguments validation failed")

	// ErrSubAgentFactory is returned when the subagent factory fails to create an agent.
	ErrSubAgentFactory = errors.New("subagent factory failed")

	// ErrTagTokenExceeded is a tag for errors caused by token limit exceeded
	ErrTagTokenExceeded = goerr.NewTag("token_exceeded")
)
View Source
var (
	ErrUnsupportedType = goerr.New("unsupported type for schema conversion")
	ErrInvalidTag      = goerr.New("invalid struct tag")
	ErrCyclicReference = goerr.New("cyclic reference detected")
)

Functions

func IsValidImageMimeType

func IsValidImageMimeType(mimeType ImageMimeType) bool

IsValidImageMimeType checks if the MIME type is supported

func NewGenerateConfig

func NewGenerateConfig(opts ...GenerateOption) generateConfig

NewGenerateConfig creates a generateConfig from the given options. This is required for LLM client implementations.

Types

type Agent

type Agent struct {
	// contains filtered or unexported fields
}

Agent is core structure of the package. Note: Agent is not thread-safe. Each instance should be used by a single goroutine or proper synchronization must be implemented by the caller.

func New

func New(llmClient LLMClient, options ...Option) *Agent

New creates a new gollem agent.

func (*Agent) Clone

func (c *Agent) Clone() *gollemConfig

func (*Agent) Execute

func (g *Agent) Execute(ctx context.Context, input ...Input) (_ *ExecuteResponse, err error)

Execute performs the agent task with the given prompt. This method manages the session state internally, allowing for continuous conversation without manual history management. Returns (*ExecuteResponse, error) where ExecuteResponse contains the final conclusion. Use this method instead of Prompt for better agent-like behavior.

func (*Agent) Session

func (x *Agent) Session() Session

Session returns the current session for the agent. This is the only way to access the session and its history. If no session exists, this will return nil.

type ContentBlockHandler

type ContentBlockHandler func(ctx context.Context, req *ContentRequest) (*ContentResponse, error)

ContentBlockHandler handles content generation requests synchronously.

func BuildContentBlockChain

func BuildContentBlockChain(middlewares []ContentBlockMiddleware, handler ContentBlockHandler) ContentBlockHandler

BuildContentBlockChain builds a chain of ContentBlockMiddleware functions. The middlewares are applied in the order they are provided.

type ContentBlockMiddleware

type ContentBlockMiddleware func(next ContentBlockHandler) ContentBlockHandler

ContentBlockMiddleware is a function that wraps a ContentBlockHandler to add behavior. Used for synchronous content generation.

type ContentRequest

type ContentRequest struct {
	Inputs       []Input  // Current user inputs
	History      *History // Modifiable conversation history
	SystemPrompt string   // System prompt for this request
}

ContentRequest represents a request for content generation with modifiable history.

type ContentResponse

type ContentResponse struct {
	Texts         []string        // Generated text content
	Thoughts      []string        // Thinking/reasoning content
	FunctionCalls []*FunctionCall // Function/tool call requests
	InputToken    int             // Number of input tokens used
	OutputToken   int             // Number of output tokens used
	Error         error           // Error if any occurred
}

ContentResponse represents a response from content generation.

type ContentStreamHandler

type ContentStreamHandler func(ctx context.Context, req *ContentRequest) (<-chan *ContentResponse, error)

ContentStreamHandler handles content generation requests with streaming.

func BuildContentStreamChain

func BuildContentStreamChain(middlewares []ContentStreamMiddleware, handler ContentStreamHandler) ContentStreamHandler

BuildContentStreamChain builds a chain of ContentStreamMiddleware functions. The middlewares are applied in the order they are provided.

type ContentStreamMiddleware

type ContentStreamMiddleware func(next ContentStreamHandler) ContentStreamHandler

ContentStreamMiddleware is a function that wraps a ContentStreamHandler to add behavior. Used for streaming content generation.

type ContentType

type ContentType string

ContentType represents the type of content to be generated by the LLM.

const (
	// ContentTypeText represents plain text content.
	ContentTypeText ContentType = "text"
	// ContentTypeJSON represents JSON content.
	ContentTypeJSON ContentType = "json"
)

type ExecuteResponse

type ExecuteResponse struct {
	// Texts contains the final response texts to be returned to the user.
	// These will be automatically added to session history as assistant messages.
	Texts []string

	// Thoughts contains the thinking/reasoning content from the LLM.
	// This is separate from Texts and represents the model's internal reasoning process.
	Thoughts []string

	// UserInputs contains the user inputs that this response corresponds to.
	// When a strategy returns ExecuteResponse without going through GenerateContent,
	// these inputs need to be added to session history before the response texts.
	// This prevents user input from being lost when strategies return direct responses.
	UserInputs []Input
}

ExecuteResponse represents the final response from Execute method

func NewExecuteResponse

func NewExecuteResponse(texts ...string) *ExecuteResponse

NewExecuteResponse creates a new ExecuteResponse with given texts

func (*ExecuteResponse) IsEmpty

func (r *ExecuteResponse) IsEmpty() bool

IsEmpty returns true if the response has no texts or all texts are empty

func (*ExecuteResponse) String

func (r *ExecuteResponse) String() string

String returns a string representation of the response

type FunctionCall

type FunctionCall struct {
	ID        string
	Name      string
	Arguments map[string]any
}

type FunctionResponse

type FunctionResponse struct {
	ID    string
	Name  string
	Data  map[string]any
	Error error
}

FunctionResponse is a function response. Usage:

input := gollem.FunctionResponse{
	Name:      "function_name",
	Arguments: map[string]any{"key": "value"},
}

func (FunctionResponse) LogValue

func (f FunctionResponse) LogValue() slog.Value

LogValue returns a slog.Value for the FunctionResponse

func (FunctionResponse) String

func (f FunctionResponse) String() string

String returns a string representation of the FunctionResponse

type GenerateOption

type GenerateOption func(*generateConfig)

GenerateOption configures a single Generate/Stream call. Options override session-level defaults for that call only.

Example:

resp, err := session.Generate(ctx, inputs,
    gollem.WithTemperature(0.2),
    gollem.WithMaxTokens(256),
)

func WithGenerateResponseSchema

func WithGenerateResponseSchema(schema *Parameter) GenerateOption

WithGenerateResponseSchema sets the response schema for a single Generate/Stream call.

func WithMaxTokens

func WithMaxTokens(n int) GenerateOption

WithMaxTokens sets the max tokens for a single Generate/Stream call.

func WithTemperature

func WithTemperature(t float64) GenerateOption

WithTemperature sets the temperature for a single Generate/Stream call.

func WithTopP

func WithTopP(p float64) GenerateOption

WithTopP sets the top-p for a single Generate/Stream call.

type History

type History struct {
	LLType   LLMType   `json:"type"`
	Version  int       `json:"version"`
	Messages []Message `json:"messages"`
}

func (*History) Clone

func (x *History) Clone() *History

func (*History) ToCount

func (x *History) ToCount() int

func (*History) UnmarshalJSON

func (x *History) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler with version validation. Returns ErrHistoryVersionMismatch if the serialized version does not match HistoryVersion.

type HistoryRepository

type HistoryRepository interface {
	// Load retrieves a History by session ID.
	// Returns nil History and nil error if the session ID is not found.
	Load(ctx context.Context, sessionID string) (*History, error)

	// Save persists a History with the given session ID.
	// If a History already exists for the session ID, it is overwritten.
	Save(ctx context.Context, sessionID string, history *History) error
}

HistoryRepository is an interface for storing and loading conversation history. Implementations can use any storage backend (filesystem, S3, GCS, database, etc.).

type Image

type Image struct {
	// contains filtered or unexported fields
}

Image represents an image input for LLM

func NewImage

func NewImage(data []byte, opts ...ImageOption) (Image, error)

NewImage creates a new Image with automatic MIME type detection by default

func NewImageFromReader

func NewImageFromReader(r io.Reader, opts ...ImageOption) (Image, error)

NewImageFromReader creates a new Image from io.Reader

func (Image) Base64

func (i Image) Base64() string

Base64 returns the base64 encoded string of the image data

func (Image) Data

func (i Image) Data() []byte

Data returns the image data as bytes

func (Image) LogValue

func (i Image) LogValue() slog.Value

func (Image) MimeType

func (i Image) MimeType() string

MimeType returns the MIME type of the image

func (Image) String

func (i Image) String() string

type ImageContent

type ImageContent struct {
	MediaType string `json:"media_type,omitempty"` // e.g., "image/jpeg", "image/png"
	Data      []byte `json:"data,omitempty"`       // Image data (base64 encoded in JSON)
	URL       string `json:"url,omitempty"`        // Image URL (either Data or URL should be set)
	Detail    string `json:"detail,omitempty"`     // OpenAI: "high", "low", "auto"
}

ImageContent represents image content in a message

type ImageMimeType

type ImageMimeType string

ImageMimeType represents supported MIME types for images

const (
	ImageMimeTypeJPEG ImageMimeType = "image/jpeg"
	ImageMimeTypePNG  ImageMimeType = "image/png"
	ImageMimeTypeGIF  ImageMimeType = "image/gif" // Claude, OpenAI only
	ImageMimeTypeWebP ImageMimeType = "image/webp"
	// Gemini-specific formats
	ImageMimeTypeHEIC ImageMimeType = "image/heic" // Gemini only
	ImageMimeTypeHEIF ImageMimeType = "image/heif" // Gemini only
)

type ImageOption

type ImageOption func(*imageConfig) error

ImageOption is a functional option for creating Image

func WithMimeType

func WithMimeType(mimeType ImageMimeType) ImageOption

WithMimeType explicitly sets the MIME type

type Input

type Input interface {
	LogValue() slog.Value
	String() string
	// contains filtered or unexported methods
}

type LLMClient

type LLMClient interface {
	NewSession(ctx context.Context, options ...SessionOption) (Session, error)
	GenerateEmbedding(ctx context.Context, dimension int, input []string) ([][]float64, error)
}

LLMClient is a client for each LLM service.

type LLMType

type LLMType string

History represents a conversation history that can be used across different LLM sessions. It stores messages in a format specific to each LLM type (OpenAI, Claude, or Gemini).

For detailed documentation, see docs/history.md

const (
	LLMTypeOpenAI LLMType = "OpenAI"
	LLMTypeGemini LLMType = "gemini"
	LLMTypeClaude LLMType = "claude"
)

type Message

type Message struct {
	Role     MessageRole      `json:"role"`
	Contents []MessageContent `json:"contents"`

	// Optional fields for provider-specific information
	Name     string                 `json:"name,omitempty"`     // OpenAI's name field
	Metadata map[string]interface{} `json:"metadata,omitempty"` // Extension metadata
}

Message represents a unified message format that can be converted between different LLM providers. All provider-specific messages are converted to this common format for cross-provider compatibility.

type MessageContent

type MessageContent struct {
	Type MessageContentType `json:"type"`
	// Data contains type-specific content that should be unmarshaled based on Type
	Data json.RawMessage `json:"data"`
	// Meta contains provider-specific metadata (e.g., Gemini's ThoughtSignature)
	Meta json.RawMessage `json:"meta,omitempty"`
}

MessageContent represents the content of a message in a unified format

func NewImageContent

func NewImageContent(mediaType string, imageData []byte, url string, detail string) (MessageContent, error)

NewImageContent creates a new image message content

func NewPDFContent

func NewPDFContent(pdfData []byte, url string) (MessageContent, error)

NewPDFContent creates a new PDF message content

func NewTextContent

func NewTextContent(text string) (MessageContent, error)

NewTextContent creates a new text message content

func NewThinkingContent

func NewThinkingContent(text string) (MessageContent, error)

NewThinkingContent creates a new thinking message content

func NewToolCallContent

func NewToolCallContent(id, name string, args map[string]interface{}) (MessageContent, error)

NewToolCallContent creates a new tool call message content

func NewToolResponseContent

func NewToolResponseContent(toolCallID, name string, response map[string]interface{}, isError bool) (MessageContent, error)

NewToolResponseContent creates a new tool response message content

func (*MessageContent) GetImageContent

func (mc *MessageContent) GetImageContent() (*ImageContent, error)

GetImageContent extracts image content from a MessageContent

func (*MessageContent) GetPDFContent

func (mc *MessageContent) GetPDFContent() (*PDFContent, error)

GetPDFContent extracts PDF content from a MessageContent

func (*MessageContent) GetTextContent

func (mc *MessageContent) GetTextContent() (*TextContent, error)

GetTextContent extracts text content from a MessageContent

func (*MessageContent) GetThinkingContent

func (mc *MessageContent) GetThinkingContent() (*ThinkingContent, error)

GetThinkingContent extracts thinking content from a MessageContent

func (*MessageContent) GetToolCallContent

func (mc *MessageContent) GetToolCallContent() (*ToolCallContent, error)

GetToolCallContent extracts tool call content from a MessageContent

func (*MessageContent) GetToolResponseContent

func (mc *MessageContent) GetToolResponseContent() (*ToolResponseContent, error)

GetToolResponseContent extracts tool response content from a MessageContent

type MessageContentType

type MessageContentType string

MessageContentType represents the type of content in a message

const (
	MessageContentTypeText         MessageContentType = "text"
	MessageContentTypeImage        MessageContentType = "image"
	MessageContentTypePDF          MessageContentType = "pdf"
	MessageContentTypeToolCall     MessageContentType = "tool_call"
	MessageContentTypeToolResponse MessageContentType = "tool_response"
	MessageContentTypeThinking     MessageContentType = "thinking"
)

type MessageRole

type MessageRole string

MessageRole represents the role of a message in a conversation

const (
	RoleSystem    MessageRole = "system"
	RoleUser      MessageRole = "user"
	RoleAssistant MessageRole = "assistant"
	RoleTool      MessageRole = "tool" // Tool response (unified across all providers)
)

type Option

type Option func(*gollemConfig)

Option is the type for the options of the gollem agent.

func WithContentBlockMiddleware

func WithContentBlockMiddleware(middleware ContentBlockMiddleware) Option

WithContentBlockMiddleware adds a content block middleware to the agent. The middleware will be applied to all sessions created by this agent.

func WithContentStreamMiddleware

func WithContentStreamMiddleware(middleware ContentStreamMiddleware) Option

WithContentStreamMiddleware adds a content stream middleware to the agent. The middleware will be applied to all streaming sessions created by this agent.

func WithContentType

func WithContentType(contentType ContentType) Option

WithContentType sets the content type for the agent. This will be applied to all sessions created by this agent.

func WithDisableArgsValidation

func WithDisableArgsValidation() Option

WithDisableArgsValidation disables automatic argument validation before tool execution. By default, the agent validates tool arguments from LLM against the tool's parameter specifications before calling Tool.Run(). Use this option to skip that validation.

func WithHistory

func WithHistory(history *History) Option

WithHistory sets the history for the gollem agent.

func WithHistoryRepository

func WithHistoryRepository(repo HistoryRepository, sessionID string) Option

WithHistoryRepository sets a HistoryRepository for automatic history persistence. When set, the agent automatically loads history on session creation and saves history after each LLM round-trip. The sessionID uniquely identifies the conversation session in the repository.

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger sets the logger for the gollem agent. Default is discard logger.

func WithLoopLimit

func WithLoopLimit(loopLimit int) Option

WithLoopLimit sets the maximum number of loops for the gollem session iteration (ask LLM and execute tools is one loop).

func WithResponseMode

func WithResponseMode(responseMode ResponseMode) Option

WithResponseMode sets the response mode for the gollem agent. Default is ResponseModeBlocking.

func WithResponseSchema

func WithResponseSchema(schema *Parameter) Option

WithResponseSchema sets the response schema for the agent. This will be applied to all sessions created by this agent. This option should be used with WithContentType(ContentTypeJSON).

func WithStrategy

func WithStrategy(strategy Strategy) Option

WithStrategy sets the strategy for execution. Default is SimpleLoop.

func WithSubAgents

func WithSubAgents(subagents ...*SubAgent) Option

WithSubAgents adds subagents to the agent. Subagents are converted to tools and can be invoked by the LLM. Each SubAgent implements the Tool interface, so they are added to the tools list.

func WithSystemPrompt

func WithSystemPrompt(systemPrompt string) Option

WithSystemPrompt sets the system prompt for the gollem agent. Default is no system prompt.

func WithToolMiddleware

func WithToolMiddleware(middleware ToolMiddleware) Option

WithToolMiddleware adds a tool middleware to the agent. The middleware will be applied to all tool executions by this agent.

func WithToolSets

func WithToolSets(toolSets ...ToolSet) Option

WithToolSets sets the tool sets for the gollem agent.

func WithTools

func WithTools(tools ...Tool) Option

WithTools sets the tools for the gollem agent.

func WithTrace

func WithTrace(handler trace.Handler) Option

WithTrace sets the trace handler for the agent. When set, the agent will record execution traces including LLM calls, tool executions, and sub-agent invocations.

type PDF

type PDF struct {
	// contains filtered or unexported fields
}

PDF represents a PDF document input for LLM

func NewPDF

func NewPDF(data []byte, opts ...PDFOption) (PDF, error)

NewPDF creates a new PDF from byte data

func NewPDFFromReader

func NewPDFFromReader(r io.Reader, opts ...PDFOption) (PDF, error)

NewPDFFromReader creates a new PDF from io.Reader

func (PDF) Base64

func (p PDF) Base64() string

Base64 returns the base64 encoded string of the PDF data

func (PDF) Data

func (p PDF) Data() []byte

Data returns the PDF data as bytes

func (PDF) LogValue

func (p PDF) LogValue() slog.Value

LogValue returns a slog.Value for the PDF

func (PDF) MimeType

func (p PDF) MimeType() string

MimeType returns the MIME type of the PDF

func (PDF) String

func (p PDF) String() string

String returns a string representation of the PDF

type PDFContent

type PDFContent struct {
	Data []byte `json:"data,omitempty"` // PDF data (base64 encoded in JSON)
	URL  string `json:"url,omitempty"`  // PDF URL (for future URL source support)
}

PDFContent represents PDF document content in a message

type PDFOption

type PDFOption func(*pdfOption)

PDFOption is a functional option for PDF creation

func WithMaxPDFSize

func WithMaxPDFSize(size int) PDFOption

WithMaxPDFSize sets the maximum allowed size for PDF data

type Parameter

type Parameter struct {
	// Title is the user friendly  of the parameter. It's optional.
	Title string

	// Type is the type of the parameter. It's required.
	Type ParameterType

	// Description is the description of the parameter. It's optional.
	Description string

	// Required indicates if this parameter is required.
	Required bool

	// Enum is the enum of the parameter. It's optional.
	Enum []string

	// Properties is the properties of the parameter. It's used for object type.
	Properties map[string]*Parameter

	// Items is the items of the parameter. It's used for array type.
	Items *Parameter

	// Number constraints
	Minimum *float64
	Maximum *float64

	// String constraints
	MinLength *int
	MaxLength *int
	Pattern   string

	// Array constraints
	MinItems *int
	MaxItems *int

	// Default value
	Default any
}

Parameter is a parameter of a tool.

func MustToSchema

func MustToSchema(v any) *Parameter

MustToSchema is like ToSchema but panics on error. Useful for static initializations where errors should be caught at development time.

Example:

var userSchema = gollem.MustToSchema(User{})

func ToSchema

func ToSchema(v any) (*Parameter, error)

ToSchema converts a Go struct to gollem.Parameter using reflection. It analyzes struct tags to extract metadata like descriptions, constraints, and validation rules.

Supported struct tags:

  • json:"field_name" - Field name (standard JSON tag)
  • description:"text" - Field description
  • enum:"value1,value2,value3" - Enum values (comma-separated)
  • min:"0" - Minimum value (for numbers)
  • max:"100" - Maximum value (for numbers)
  • minLength:"1" - Minimum string length
  • maxLength:"255" - Maximum string length
  • pattern:"^[a-z]+$" - Regex pattern for string validation
  • minItems:"1" - Minimum array length
  • maxItems:"10" - Maximum array length
  • required:"true" - Mark field as required

Example:

type User struct {
    Name  string `json:"name" description:"User's full name" required:"true"`
    Age   int    `json:"age" description:"Age in years" min:"0" max:"150"`
    Email string `json:"email" pattern:"^[a-z@.]+$" required:"true"`
    Role  string `json:"role" enum:"admin,user,guest"`
}

schema, err := gollem.ToSchema(User{})
if err != nil {
    // handle error
}

func (*Parameter) Validate

func (p *Parameter) Validate() error

Validate validates the parameter.

func (*Parameter) ValidateValue

func (p *Parameter) ValidateValue(name string, value any) error

ValidateValue validates a value against this parameter's specification. It checks required, type, enum, and constraint validations. Returns nil if the value is valid, or an error describing the validation failure.

type ParameterType

type ParameterType string

ParameterType is the type of a parameter.

const (
	TypeString  ParameterType = "string"
	TypeNumber  ParameterType = "number"
	TypeInteger ParameterType = "integer"
	TypeBoolean ParameterType = "boolean"
	TypeArray   ParameterType = "array"
	TypeObject  ParameterType = "object"
)

type PromptTemplate

type PromptTemplate struct {
	// contains filtered or unexported fields
}

PromptTemplate holds the parsed template and parameter schema for template mode. Use NewPromptTemplate to create an instance with proper error handling.

func DefaultPromptTemplate

func DefaultPromptTemplate() *PromptTemplate

DefaultPromptTemplate returns the default prompt template that accepts a single "query" parameter. This is equivalent to the default behavior when no prompt template is specified.

func NewPromptTemplate

func NewPromptTemplate(tmpl string, params map[string]*Parameter) (*PromptTemplate, error)

NewPromptTemplate creates a new PromptTemplate with the given template and parameters. tmpl: Go text/template string to generate the prompt params: Parameter schema for LLM (key is parameter name)

The template uses missingkey=zero option, so missing variables are replaced with their zero value (empty string for strings). This allows conditional checks like {{if .optional}}...{{end}} for optional parameters.

Returns an error if the template string is invalid.

func (*PromptTemplate) Parameters

func (p *PromptTemplate) Parameters() map[string]*Parameter

Parameters returns the parameter schema for this template. This is useful for inspecting the expected parameters.

func (*PromptTemplate) Render

func (p *PromptTemplate) Render(args map[string]any) (string, error)

Render renders the template with the given arguments and returns the resulting prompt string. This method is useful for testing templates independently from the SubAgent. Returns an error if validation fails (missing required params, type mismatch, constraint violations). Missing optional parameters are replaced with their zero value (empty string for strings). Arguments not defined in parameters (e.g., injected by middleware) are also available in the template.

type QueryOption

type QueryOption func(*queryConfig)

QueryOption configures a Query call.

func WithQueryHistory

func WithQueryHistory(history *History) QueryOption

WithQueryHistory sets the conversation history for the query.

func WithQueryMaxRetry

func WithQueryMaxRetry(n int) QueryOption

WithQueryMaxRetry sets the maximum number of retries when JSON unmarshal fails. Default is 3.

func WithQuerySystemPrompt

func WithQuerySystemPrompt(prompt string) QueryOption

WithQuerySystemPrompt sets the system prompt for the query.

type QueryResponse

type QueryResponse[T any] struct {
	Data        *T
	InputToken  int
	OutputToken int
}

QueryResponse holds the result of a Query call.

func Query

func Query[T any](ctx context.Context, client LLMClient, prompt string, opts ...QueryOption) (*QueryResponse[T], error)

Query executes a one-shot LLM query and returns structured data parsed into type T. It generates a JSON schema from T, creates a session with JSON content type, calls the LLM, and unmarshals the response into T. If JSON unmarshalling fails, it retries up to maxRetry times (default 3), feeding back the error to the LLM for correction.

func SessionQuery

func SessionQuery[T any](ctx context.Context, session Session, prompt string, opts ...SessionQueryOption) (*QueryResponse[T], error)

SessionQuery executes a structured query on an existing session. Unlike Query, it reuses the provided session so the conversation history built by prior Generate calls is preserved. The response schema is derived from T and passed as a per-call GenerateOption, leaving the session's default config unchanged. If JSON unmarshalling or schema validation fails, it retries up to maxRetry times (default 3), feeding back the error for correction.

Example:

type Answer struct {
    Name string `json:"name"`
}
// session already has conversation context from earlier Generate calls
resp, err := gollem.SessionQuery[Answer](ctx, session, "What is my name?")

type Response

type Response struct {
	Texts         []string
	Thoughts      []string
	FunctionCalls []*FunctionCall
	InputToken    int
	OutputToken   int

	// Error is an error that occurred during the generation for streaming response.
	Error error
}

Response is a general response type for each gollem.

func (*Response) HasData

func (r *Response) HasData() bool

type ResponseMode

type ResponseMode string

ResponseMode is the type for the response mode of the gollem agent.

const (
	// ResponseModeBlocking is the response mode that blocks the prompt until the LLM generates a response. The agent will wait until all responses are ready.
	ResponseModeBlocking ResponseMode = "blocking"

	// ResponseModeStreaming is the response mode that streams the response from the LLM. The agent receives responses token by token.
	ResponseModeStreaming ResponseMode = "streaming"
)

func (ResponseMode) String

func (x ResponseMode) String() string

type Session

type Session interface {
	// Generate sends input to the LLM and returns the complete response.
	// Optional GenerateOption values override session-level defaults
	// (e.g. temperature, response schema) for this single call only.
	Generate(ctx context.Context, input []Input, opts ...GenerateOption) (*Response, error)

	// Stream sends input to the LLM and returns a channel that yields
	// response chunks as they arrive. Optional GenerateOption values
	// override session-level defaults for this single call only.
	// The channel is closed when the response is complete.
	Stream(ctx context.Context, input []Input, opts ...GenerateOption) (<-chan *Response, error)

	// Deprecated: Use Generate instead.
	GenerateContent(ctx context.Context, input ...Input) (*Response, error)
	// Deprecated: Use Stream instead.
	GenerateStream(ctx context.Context, input ...Input) (<-chan *Response, error)

	History() (*History, error)
	AppendHistory(*History) error
	CountToken(ctx context.Context, input ...Input) (int, error)
}

Session is a session for the LLM. It maintains conversation state across multiple calls and can be used with the Agent (via Execute) or standalone for direct LLM interaction.

type SessionConfig

type SessionConfig struct {
	// contains filtered or unexported fields
}

SessionConfig is the configuration for the new session. This is required for only LLM client implementations.

func NewSessionConfig

func NewSessionConfig(options ...SessionOption) SessionConfig

NewSessionConfig creates a new session configuration. This is required for only LLM client implementations.

func (*SessionConfig) ContentBlockMiddlewares

func (c *SessionConfig) ContentBlockMiddlewares() []ContentBlockMiddleware

ContentBlockMiddlewares returns the content block middlewares of the session.

func (*SessionConfig) ContentStreamMiddlewares

func (c *SessionConfig) ContentStreamMiddlewares() []ContentStreamMiddleware

ContentStreamMiddlewares returns the content stream middlewares of the session.

func (*SessionConfig) ContentType

func (c *SessionConfig) ContentType() ContentType

ContentType returns the content type of the session.

func (*SessionConfig) History

func (c *SessionConfig) History() *History

History returns the history of the session.

func (*SessionConfig) ResponseSchema

func (c *SessionConfig) ResponseSchema() *Parameter

ResponseSchema returns the response schema of the session.

func (*SessionConfig) SystemPrompt

func (c *SessionConfig) SystemPrompt() string

SystemPrompt returns the system prompt of the session.

func (*SessionConfig) Tools

func (c *SessionConfig) Tools() []Tool

Tools returns the tools of the session.

type SessionOption

type SessionOption func(cfg *SessionConfig)

SessionOption is the option for the session configuration. This is required for only LLM client implementations.

func WithSessionContentBlockMiddleware

func WithSessionContentBlockMiddleware(middlewares ...ContentBlockMiddleware) SessionOption

WithSessionContentBlockMiddleware sets the content block middlewares for the session. Usage: session, err := llmClient.NewSession(ctx, gollem.WithSessionContentBlockMiddleware(middleware1, middleware2))

func WithSessionContentStreamMiddleware

func WithSessionContentStreamMiddleware(middlewares ...ContentStreamMiddleware) SessionOption

WithSessionContentStreamMiddleware sets the content stream middlewares for the session. Usage: session, err := llmClient.NewSession(ctx, gollem.WithSessionContentStreamMiddleware(middleware1, middleware2))

func WithSessionContentType

func WithSessionContentType(contentType ContentType) SessionOption

WithSessionContentType sets the content type for the session. Usage: session, err := llmClient.NewSession(ctx, gollem.WithSessionContentType(gollem.ContentTypeJSON))

func WithSessionHistory

func WithSessionHistory(history *History) SessionOption

WithSessionHistory sets the history for the session. Usage: session, err := llmClient.NewSession(ctx, gollem.WithSessionHistory(history))

func WithSessionResponseSchema

func WithSessionResponseSchema(schema *Parameter) SessionOption

WithSessionResponseSchema sets the response schema for the session. The schema defines the structure of JSON output from the LLM. This option should be used with ContentTypeJSON.

Usage:

schema := &gollem.Parameter{
    Title: "UserProfile",
    Description: "User profile information",
    Type: gollem.TypeObject,
    Properties: map[string]*gollem.Parameter{
        "name": {Type: gollem.TypeString, Description: "User name", Required: true},
        "age": {Type: gollem.TypeInteger, Description: "User age"},
    },
}
session, err := client.NewSession(ctx,
    gollem.WithSessionContentType(gollem.ContentTypeJSON),
    gollem.WithSessionResponseSchema(schema))

func WithSessionSystemPrompt

func WithSessionSystemPrompt(systemPrompt string) SessionOption

WithSessionSystemPrompt sets the system prompt for the session. Usage: session, err := llmClient.NewSession(ctx, gollem.WithSessionSystemPrompt("You are a helpful assistant."))

func WithSessionTools

func WithSessionTools(tools ...Tool) SessionOption

WithSessionTools sets the tools for the session. Usage: session, err := llmClient.NewSession(ctx, gollem.WithSessionTools(tools))

type SessionQueryOption

type SessionQueryOption func(*sessionQueryConfig)

SessionQueryOption configures a SessionQuery call.

func WithSessionQueryMaxRetry

func WithSessionQueryMaxRetry(n int) SessionQueryOption

WithSessionQueryMaxRetry sets the maximum number of retries when JSON unmarshal fails. Default is 3.

type Strategy

type Strategy interface {
	// Init initializes the strategy with initial inputs
	// Called once when Execute is invoked, before the execution loop begins
	Init(ctx context.Context, inputs []Input) error

	// Handle determines the next input for the LLM based on the current state
	// Returns ([]Input, *ExecuteResponse, error) where:
	// - []Input: next input for LLM (nil means no LLM call)
	// - *ExecuteResponse: strategy's conclusion (nil means let LLM decide)
	// - error: execution error
	Handle(ctx context.Context, state *StrategyState) ([]Input, *ExecuteResponse, error)

	// Tools returns the tools that this strategy provides
	// This allows strategies to offer their own specialized tools
	Tools(ctx context.Context) ([]Tool, error)
}

Strategy defines the interface for execution strategies

type StrategyState

type StrategyState struct {
	Session      Session   // Current LLM session
	InitInput    []Input   // Initial input (user input)
	LastResponse *Response // Last LLM response (nil on first call)
	NextInput    []Input   // Next input (same with InitInput in 1st iter, tool results in others)
	Iteration    int       // Current iteration count
	Tools        []Tool    // Available tools for this execution

	// System prompt and history from Agent configuration
	// These are available for strategies that need context-aware planning
	SystemPrompt string   // User's system prompt from gollem.WithSystemPrompt
	History      *History // Conversation history from gollem.WithHistory
}

StrategyState contains the current state of the execution

type SubAgent

type SubAgent struct {
	// contains filtered or unexported fields
}

SubAgent represents an agent that can be invoked as a tool by parent agent. SubAgent implements the Tool interface, allowing it to be added to an agent's tool list.

func NewSubAgent

func NewSubAgent(name, description string, agentFactory func() (*Agent, error), opts ...SubAgentOption) *SubAgent

NewSubAgent creates a new SubAgent that wraps a factory function for creating Agent instances. name: Tool name for the subagent (required, used by LLM to invoke) description: Description of what this subagent does (required, helps LLM decide when to use) agentFactory: A function that creates a new Agent instance (required). Returns error if creation fails.

The factory function is called each time the SubAgent is invoked, ensuring that each execution has an independent session state. This prevents session state from being shared across multiple calls or Chat sessions.

func (*SubAgent) Run

func (s *SubAgent) Run(ctx context.Context, args map[string]any) (_ map[string]any, retErr error)

Run executes the SubAgent with the given arguments. In default mode, it uses the default prompt template with a "query" parameter. In template mode, it renders the template with the arguments and passes the result to the agent. If middleware is set, it is applied to the arguments before template rendering.

func (*SubAgent) Spec

func (s *SubAgent) Spec() ToolSpec

Spec returns the ToolSpec for this SubAgent. In default mode, it returns a spec with a single "query" parameter. In template mode, it returns a spec with the custom parameters.

type SubAgentHandler

type SubAgentHandler func(ctx context.Context, args map[string]any) (SubAgentResult, error)

SubAgentHandler is a function that processes arguments for SubAgent execution. It receives the context and current arguments, and returns SubAgentResult containing both the result data and the session for middleware post-processing.

type SubAgentOption

type SubAgentOption func(*SubAgent)

SubAgentOption is the type for options when creating a SubAgent.

func WithPromptTemplate

func WithPromptTemplate(prompt *PromptTemplate) SubAgentOption

WithPromptTemplate sets a pre-configured prompt template for the subagent. This option replaces the default "query" parameter behavior. When this option is used, the template is rendered with the provided parameters and the result is passed to agent.Execute().

func WithSubAgentMiddleware

func WithSubAgentMiddleware(middleware func(SubAgentHandler) SubAgentHandler) SubAgentOption

WithSubAgentMiddleware sets a middleware that can modify arguments before template rendering. Multiple middlewares can be chained by calling this option multiple times. The middleware follows the same pattern as WithToolMiddleware and WithContentBlockMiddleware.

The middleware can:

  • Add context information (timestamps, user data, environment info)
  • Modify or transform arguments from the LLM
  • Perform logging or monitoring
  • Validate or filter arguments

Example:

gollem.WithSubAgentMiddleware(func(next gollem.SubAgentHandler) gollem.SubAgentHandler {
    return func(ctx context.Context, args map[string]any) (map[string]any, error) {
        // Add context before processing
        args["current_time"] = time.Now().Format(time.RFC3339)
        return next(ctx, args)
    }
})

func WithSubAgentOptions

func WithSubAgentOptions(opts ...Option) SubAgentOption

WithSubAgentOptions sets additional gollem.Option values to apply to child agents created by the factory function. These options are applied after the factory creates the agent but before Execute() is called.

This enables the parent agent to inject cross-cutting concerns (such as tool middleware for budget tracking or monitoring) into sub-agent execution, without modifying each sub-agent's factory function.

Multiple calls to this option are cumulative - options are appended.

type SubAgentResult

type SubAgentResult struct {
	Data    map[string]any // Result data to be returned to the parent agent
	Session Session        // Session used during execution (read-only access for middleware)
}

SubAgentResult holds the execution result of a SubAgent handler. It contains both the data returned to the caller and the session for post-execution processing by middleware.

type Text

type Text string

Text is a text input as prompt. Usage: input := gollem.Text("Hello, world!")

func (Text) LogValue

func (t Text) LogValue() slog.Value

func (Text) String

func (t Text) String() string

type TextContent

type TextContent struct {
	Text string `json:"text"`
}

TextContent represents text content in a message

type ThinkingContent

type ThinkingContent struct {
	Text string `json:"text"`
}

ThinkingContent represents thinking/reasoning content

type Tool

type Tool interface {
	// Spec returns the specification of the tool. It's called when starting a LLM chat session in Prompt().
	Spec() ToolSpec

	// Run is the execution of the tool.
	// It's called when receiving a tool call from the LLM. Even if the method returns an error, the tool execution is not aborted. Error will be passed to LLM as a response. If you want to abort the tool execution, you need to return an error from the callback function of WithToolErrorHook().
	// Special case: If the tool returns ErrExitConversation, the conversation loop will be terminated normally and the session will be completed successfully.
	Run(ctx context.Context, args map[string]any) (map[string]any, error)
}

Tool is specification and execution of an action that can be called by the LLM.

type ToolCallContent

type ToolCallContent struct {
	ID        string                 `json:"id"`        // Call ID for matching with response
	Name      string                 `json:"name"`      // Tool/function name
	Arguments map[string]interface{} `json:"arguments"` // Arguments as JSON object
}

ToolCallContent represents a tool/function call request

type ToolExecRequest

type ToolExecRequest struct {
	Tool     *FunctionCall // Tool call details
	ToolSpec *ToolSpec     // Tool specification
}

ToolExecRequest represents a tool execution request.

type ToolExecResponse

type ToolExecResponse struct {
	Result   map[string]any // Execution result
	Error    error          // Execution error if any
	Duration int64          // Execution duration in milliseconds
}

ToolExecResponse represents a tool execution response.

type ToolHandler

type ToolHandler func(ctx context.Context, req *ToolExecRequest) (*ToolExecResponse, error)

ToolHandler handles tool execution requests.

type ToolMiddleware

type ToolMiddleware func(next ToolHandler) ToolHandler

ToolMiddleware is a function that wraps a ToolHandler to add behavior. Used at Agent layer for tool execution interception.

type ToolResponseContent

type ToolResponseContent struct {
	ToolCallID string                 `json:"tool_call_id"`       // ID of the corresponding call
	Name       string                 `json:"name,omitempty"`     // Tool/function name (required for Gemini)
	Response   map[string]interface{} `json:"response"`           // Response content
	IsError    bool                   `json:"is_error,omitempty"` // Whether this is an error response (Claude)
}

ToolResponseContent represents a tool/function response

type ToolSet

type ToolSet interface {
	// Specs returns the specifications of the tools.
	Specs(ctx context.Context) ([]ToolSpec, error)

	// Run is the execution of the tool.
	// It's called when receiving a tool call from the LLM.
	Run(ctx context.Context, name string, args map[string]any) (map[string]any, error)
}

ToolSet is a set of tools. It's useful for providing a set of tools to the LLM.

type ToolSpec

type ToolSpec struct {
	Name        string
	Description string
	Parameters  map[string]*Parameter
}

ToolSpec is the specification of a tool.

func (*ToolSpec) Validate

func (s *ToolSpec) Validate() error

Validate validates the tool specification.

func (*ToolSpec) ValidateArgs

func (s *ToolSpec) ValidateArgs(args map[string]any) error

ValidateArgs validates the given arguments against the tool's parameter specifications. It checks all parameters and collects all validation errors. Returns nil if all arguments are valid.

Directories

Path Synopsis
examples
basic command
chat command
history command
Package main demonstrates how to implement HistoryRepository and use it with gollem to persist conversation history across sessions.
Package main demonstrates how to implement HistoryRepository and use it with gollem to persist conversation history across sessions.
json_schema command
mcp command
reflexion command
tracing command
internal
llm
middleware
compacter
Package compacter provides middleware for automatic conversation history compaction when token limit errors are detected.
Package compacter provides middleware for automatic conversation history compaction when token limit errors are detected.
strategy
react
Package react implements the ReAct (Reasoning and Acting) strategy for gollem.
Package react implements the ReAct (Reasoning and Acting) strategy for gollem.
reflexion
Package reflexion implements the Reflexion strategy for gollem.
Package reflexion implements the Reflexion strategy for gollem.
otel
Package otel provides an OpenTelemetry trace handler for gollem.
Package otel provides an OpenTelemetry trace handler for gollem.

Jump to

Keyboard shortcuts

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