Skip to content

Models

Models are provider adapters. They translate godantic requests, history, and tool declarations into the request format required by a specific LLM API.

The rest of your app should mostly ignore provider details. Sessions and stores use godantic types; only the model adapter knows how Gemini, OpenRouter, Groq, Cerebras, or Anthropic want messages represented.

type Model interface {
Model_Request(
request models.Model_Request,
tools []models.FunctionDeclaration,
conversationHistory []stores.Message,
) (models.Model_Response, error)
Stream_Model_Request(
request models.Model_Request,
tools []models.FunctionDeclaration,
conversationHistory []stores.Message,
) (<-chan models.Model_Response, <-chan error)
}

Every built-in provider implements this interface. Your own provider can implement it too.

ProviderConstructorDefault modelEnv var
Geminigodantic.NewGeminiModelgemini-2.0-flashGEMINI_API_KEY
OpenRoutergodantic.NewOpenRouterModelopenai/gpt-4o-miniOPENROUTER_API_KEY
Groqgodantic.NewGroqModelllama-3.1-70b-versatileGROQ_API_KEY
Cerebrasgodantic.NewCerebrasModelllama-3.3-70bCEREBRAS_API_KEY
Anthropicgodantic.NewAnthropicModelclaude-sonnet-4-20250514ANTHROPIC_API_KEY

Example:

model := godantic.NewOpenRouterModel("openai/gpt-4o-mini")
agent := godantic.Create_Agent(model, tools)
NeedGood fit
Google-native API and Gemini modelsGemini
Many models behind one endpointOpenRouter
Low-latency supported open modelsGroq
Cerebras-hosted low-latency modelsCerebras
Claude Messages API behaviorAnthropic
Internal gateway or self-hosted modelCustom Model or OpenRouter-compatible base URL

Use options constructors when you need temperature, token limits, or prompts.

temperature := 0.2
maxTokens := 2048
model := godantic.NewAnthropicModelWithOptions(
"claude-sonnet-4-20250514",
&temperature,
&maxTokens,
"You are concise and careful.",
)

OpenRouter supports site metadata:

model := godantic.NewOpenRouterModelWithOptions(
"anthropic/claude-sonnet-4",
&temperature,
&maxTokens,
"https://example.com",
"Example App",
)

OpenRouter-compatible gateways can use a custom base URL and API key env var:

model := godantic.NewOpenRouterModelWithBaseURL(
"my-model",
"https://gateway.example.com/v1/chat/completions",
"MY_GATEWAY_API_KEY",
nil,
nil,
)

Different providers support different content shapes. For example, one provider may support a media part that another provider cannot represent exactly.

Provider adapters convert stored godantic history into the closest provider format and may emit models.HistoryWarning values when content is adapted or skipped.

response, err := agent.Run(request, history)
for _, warning := range response.Warnings {
log.Printf("history warning: %s: %s", warning.Type, warning.Message)
}

Tools are passed into every model request:

response, err := model.Model_Request(request, tools, history)

Provider adapters translate models.FunctionDeclaration into each provider’s function/tool declaration format. The returned models.Model_Response may contain text parts and function-call parts.

for _, part := range response.Parts {
if part.FunctionCall != nil {
fmt.Println("model requested", part.FunctionCall.Name)
}
}

Implementing a custom model is useful for:

  • An internal model gateway.
  • A self-hosted inference server.
  • Tests that should not call real providers.
  • A provider not yet included in godantic.
type StaticModel struct{}
func (m *StaticModel) Model_Request(
request models.Model_Request,
tools []models.FunctionDeclaration,
history []stores.Message,
) (models.Model_Response, error) {
text := "hello from a custom model"
return models.Model_Response{Parts: []models.Model_Part{{Text: &text}}}, nil
}
func (m *StaticModel) Stream_Model_Request(
request models.Model_Request,
tools []models.FunctionDeclaration,
history []stores.Message,
) (<-chan models.Model_Response, <-chan error) {
responses := make(chan models.Model_Response, 1)
errors := make(chan error, 1)
go func() {
defer close(responses)
defer close(errors)
response, err := m.Model_Request(request, tools, history)
if err != nil {
errors <- err
return
}
responses <- response
}()
return responses, errors
}

Use it normally:

agent := godantic.Create_Agent(&StaticModel{}, tools)

Fake models make session tests deterministic.

type FakeModel struct{ Text string }
func (m *FakeModel) Model_Request(models.Model_Request, []models.FunctionDeclaration, []stores.Message) (models.Model_Response, error) {
return models.Model_Response{Parts: []models.Model_Part{{Text: &m.Text}}}, nil
}

Use SQLite :memory: or a custom in-memory store for fast tests.