Documentation
¶
Overview ¶
Package llmkit is a multi-vendor AI client. One factory resolves a model name such as "gpt-5", "claude-sonnet-4-5", "llama3.2:3b" or "openrouter/openai/gpt-4o" to a provider, and callers program against small single-method interfaces:
chat, err := llmkit.Open[llmkit.Chatter]("gpt-5")
resp, err := chat.Chat(ctx, &llmkit.Request{Messages: []llmkit.Message{llmkit.UserText("hi")}})
Every type in this package is an alias of the same name in package core, so provider packages and applications share one set of types.
Example ¶
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"github.com/richardwooding/llmkit"
"github.com/richardwooding/llmkit/openaicompat"
)
func fakeServer() *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var req struct {
Stream bool `json:"stream"`
Messages []struct {
Role string `json:"role"`
} `json:"messages"`
}
_ = json.NewDecoder(r.Body).Decode(&req)
switch {
case req.Stream:
w.Header().Set("Content-Type", "text/event-stream")
_, _ = io.WriteString(w, "data: {\"choices\":[{\"delta\":{\"content\":\"Hello\"}}]}\n\n"+
"data: {\"choices\":[{\"delta\":{\"content\":\", world\"},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n")
case len(req.Messages) == 1:
_, _ = io.WriteString(w, `{"choices":[{"message":{"role":"assistant","tool_calls":[{"id":"c1","type":"function","function":{"name":"weather","arguments":"{\"city\":\"Cape Town\"}"}}]},"finish_reason":"tool_calls"}]}`)
default:
_, _ = io.WriteString(w, `{"choices":[{"message":{"role":"assistant","content":"It is 24°C in Cape Town."},"finish_reason":"stop"}]}`)
}
}))
}
func main() {
srv := fakeServer()
defer srv.Close()
// Any OpenAI-compatible server can be registered under its own prefix.
llmkit.Register(openaicompat.NewProvider(openaicompat.Config{ID: "demo", BaseURL: srv.URL, KeyOptional: true}))
chat, err := llmkit.Open[llmkit.Chatter]("demo/my-model")
if err != nil {
panic(err)
}
req := &llmkit.Request{
Messages: []llmkit.Message{llmkit.UserText("What's the weather in Cape Town?")},
Tools: []llmkit.Tool{{
Name: "weather",
Parameters: json.RawMessage(`{"type":"object","properties":{"city":{"type":"string"}}}`),
}},
}
tools := map[string]llmkit.ToolFunc{
"weather": func(_ context.Context, args json.RawMessage) (string, error) {
var in struct{ City string }
_ = json.Unmarshal(args, &in)
return "24°C in " + in.City, nil
},
}
resp, err := llmkit.RunTools(context.Background(), chat, req, tools, 5)
if err != nil {
panic(err)
}
fmt.Println(resp.Text())
stream, _ := llmkit.Open[llmkit.Streamer]("demo/my-model")
for chunk, err := range stream.Stream(context.Background(), &llmkit.Request{Messages: []llmkit.Message{llmkit.UserText("Say hello")}}) {
if err != nil {
panic(err)
}
if chunk.Kind == llmkit.ChunkText {
fmt.Print(chunk.Text)
}
}
fmt.Println()
}
Output: It is 24°C in Cape Town. Hello, world
Index ¶
- Constants
- Variables
- func As[T any](c core.Client) (T, error)
- func Collect(seq iter.Seq2[core.Chunk, error]) (*core.Response, error)
- func New(model string, opts ...core.Option) (core.Client, error)
- func Open[T any](model string, opts ...core.Option) (T, error)
- func OpenWith[T any](r *Registry, model string, opts ...core.Option) (T, error)
- func ParseModel(s string) (core.Provider, string, error)
- func Register(p core.Provider, aliases ...string)
- func RunTools(ctx context.Context, c core.Chatter, req *core.Request, ...) (*core.Response, error)
- func SetFallback(id string)
- type APIError
- type AudioPart
- type Chatter
- type Chunk
- type ChunkKind
- type Client
- type Config
- type EmbedInputType
- type EmbedRequest
- type EmbedResponse
- type Embedder
- type FilePart
- type FinishReason
- type ImagePart
- type Message
- type MultimodalEmbedRequest
- type MultimodalEmbedder
- type Option
- type Part
- type Provider
- type ReasoningConfig
- type ReasoningPart
- type Registry
- func (r *Registry) Lookup(id string) (core.Provider, bool)
- func (r *Registry) New(model string, opts ...core.Option) (core.Client, error)
- func (r *Registry) ParseModel(s string) (core.Provider, string, error)
- func (r *Registry) Providers() []core.Provider
- func (r *Registry) Register(p core.Provider, aliases ...string)
- func (r *Registry) SetFallback(id string)
- type Request
- type RerankRequest
- type RerankResponse
- type RerankResult
- type Reranker
- type Response
- type ResponseFormat
- type Role
- type Streamer
- type TextPart
- type Tool
- type ToolCall
- type ToolCallDelta
- type ToolChoice
- type ToolChoiceMode
- type ToolFunc
- type ToolResult
- type Usage
Examples ¶
Constants ¶
const ( RoleSystem = core.RoleSystem RoleUser = core.RoleUser RoleAssistant = core.RoleAssistant RoleTool = core.RoleTool )
Roles.
const ( ToolChoiceAuto = core.ToolChoiceAuto ToolChoiceNone = core.ToolChoiceNone ToolChoiceRequired = core.ToolChoiceRequired ToolChoiceNamed = core.ToolChoiceNamed )
Tool choice modes.
const ( FormatJSON = core.FormatJSON FormatJSONSchema = core.FormatJSONSchema )
Response formats.
const ( FinishStop = core.FinishStop FinishLength = core.FinishLength FinishToolCalls = core.FinishToolCalls FinishContentFilter = core.FinishContentFilter FinishOther = core.FinishOther )
Finish reasons.
const ( ChunkText = core.ChunkText ChunkReasoning = core.ChunkReasoning ChunkToolCall = core.ChunkToolCall ChunkFinish = core.ChunkFinish )
Chunk kinds.
const ( EmbedQuery = core.EmbedQuery EmbedDocument = core.EmbedDocument )
Embedding input types.
const DefaultProviderEnv = "LLMKIT_DEFAULT_PROVIDER"
DefaultProviderEnv names the environment variable consulted for the fallback provider when a bare model name matches nothing.
Variables ¶
var ( ErrUnsupported = core.ErrUnsupported ErrUnknownProvider = core.ErrUnknownProvider ErrMissingAPIKey = core.ErrMissingAPIKey ErrRateLimited = core.ErrRateLimited ErrContextLength = core.ErrContextLength ErrToolLoopExceeded = core.ErrToolLoopExceeded )
Sentinel errors.
var ( Text = core.Text Image = core.Image ImageURL = core.ImageURL Audio = core.Audio File = core.File FileURL = core.FileURL ToolResultText = core.ToolResultText System = core.System User = core.User UserText = core.UserText Assistant = core.Assistant ToolResults = core.ToolResults )
Message constructors.
var ( WithAPIKey = core.WithAPIKey WithBaseURL = core.WithBaseURL WithHTTPClient = core.WithHTTPClient WithHeader = core.WithHeader WithTimeout = core.WithTimeout WithValue = core.WithValue NewConfig = core.NewConfig )
Options.
var Default = newDefault()
Default is the registry used by the package-level functions. Providers are listed in bare-name match priority: strict prefixes first, then Ollama (tagged names and the fallback), then Hugging Face ("org/model" names).
Functions ¶
func Collect ¶
Collect drains a stream into a Response, concatenating text and reasoning deltas and reassembling tool-call arguments by index.
func Open ¶
Open resolves model and asserts the client to T, typically Chatter, Streamer, Embedder or an interface combining them.
func ParseModel ¶
ParseModel resolves a model name against the Default registry.
Example ¶
package main
import (
"fmt"
"github.com/richardwooding/llmkit"
)
func main() {
for _, name := range []string{"gpt-5", "claude-sonnet-4-5", "llama3.2:3b", "openrouter/openai/gpt-4o", "meta-llama/Llama-3.3-70B-Instruct"} {
p, model, err := llmkit.ParseModel(name)
if err != nil {
fmt.Println(name, "→", err)
continue
}
fmt.Printf("%-36s → %s / %s\n", name, p.ID(), model)
}
}
Output: gpt-5 → openai / gpt-5 claude-sonnet-4-5 → anthropic / claude-sonnet-4-5 llama3.2:3b → ollama / llama3.2:3b openrouter/openai/gpt-4o → openrouter / openai/gpt-4o meta-llama/Llama-3.3-70B-Instruct → huggingface / meta-llama/Llama-3.3-70B-Instruct
func RunTools ¶
func RunTools(ctx context.Context, c core.Chatter, req *core.Request, tools map[string]ToolFunc, maxIter int) (*core.Response, error)
RunTools chats until the model stops requesting tools or maxIter calls have been made, appending assistant and tool messages to req.Messages as it goes. Tool errors and unknown tool names are fed back to the model as error results; context errors abort. Usage across iterations is summed.
func SetFallback ¶
func SetFallback(id string)
SetFallback sets the Default registry's fallback provider.
Types ¶
type EmbedInputType ¶
type EmbedInputType = core.EmbedInputType
EmbedInputType is an alias of core.EmbedInputType.
type EmbedRequest ¶
type EmbedRequest = core.EmbedRequest
EmbedRequest is an alias of core.EmbedRequest.
type EmbedResponse ¶
type EmbedResponse = core.EmbedResponse
EmbedResponse is an alias of core.EmbedResponse.
type FinishReason ¶
type FinishReason = core.FinishReason
FinishReason is an alias of core.FinishReason.
type MultimodalEmbedRequest ¶ added in v0.2.0
type MultimodalEmbedRequest = core.MultimodalEmbedRequest
MultimodalEmbedRequest is an alias of core.MultimodalEmbedRequest.
type MultimodalEmbedder ¶ added in v0.2.0
type MultimodalEmbedder = core.MultimodalEmbedder
MultimodalEmbedder is an alias of core.MultimodalEmbedder.
type ReasoningConfig ¶
type ReasoningConfig = core.ReasoningConfig
ReasoningConfig is an alias of core.ReasoningConfig.
type ReasoningPart ¶
type ReasoningPart = core.ReasoningPart
ReasoningPart is an alias of core.ReasoningPart.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry resolves model names to providers. Registration order is match priority for bare names.
func NewRegistry ¶
NewRegistry builds a Registry holding providers in the given order.
func (*Registry) ParseModel ¶
ParseModel splits "<provider>/<model>" or resolves a bare "<model>" to the provider that claims it, then the fallback.
func (*Registry) Register ¶
Register adds a provider under its ID and any aliases, replacing an earlier provider with the same ID.
func (*Registry) SetFallback ¶
SetFallback names the provider used for bare model names nothing claims. It takes precedence over LLMKIT_DEFAULT_PROVIDER.
type RerankRequest ¶ added in v0.2.0
type RerankRequest = core.RerankRequest
RerankRequest is an alias of core.RerankRequest.
type RerankResponse ¶ added in v0.2.0
type RerankResponse = core.RerankResponse
RerankResponse is an alias of core.RerankResponse.
type RerankResult ¶ added in v0.2.0
type RerankResult = core.RerankResult
RerankResult is an alias of core.RerankResult.
type ResponseFormat ¶
type ResponseFormat = core.ResponseFormat
ResponseFormat is an alias of core.ResponseFormat.
type ToolCallDelta ¶
type ToolCallDelta = core.ToolCallDelta
ToolCallDelta is an alias of core.ToolCallDelta.
type ToolChoiceMode ¶
type ToolChoiceMode = core.ToolChoiceMode
ToolChoiceMode is an alias of core.ToolChoiceMode.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package anthropic talks to the Claude Messages API at api.anthropic.com.
|
Package anthropic talks to the Claude Messages API at api.anthropic.com. |
|
cmd
|
|
|
llmkit
command
Command llmkit is a small CLI over the llmkit library: chat with any supported model, stream the reply, or embed text.
|
Command llmkit is a small CLI over the llmkit library: chat with any supported model, stream the reply, or embed text. |
|
Package cohere is the Cohere v2 provider: Command chat models with tools, streaming and thinking, plus Embed models.
|
Package cohere is the Cohere v2 provider: Command chat models with tools, streaming and thinking, plus Embed models. |
|
Package core holds the provider-neutral types, interfaces and errors shared by every llmkit provider.
|
Package core holds the provider-neutral types, interfaces and errors shared by every llmkit provider. |
|
Package deepseek is the DeepSeek chat provider (OpenAI-compatible, no embeddings).
|
Package deepseek is the DeepSeek chat provider (OpenAI-compatible, no embeddings). |
|
Package groq is the Groq chat provider (OpenAI-compatible, no embeddings).
|
Package groq is the Groq chat provider (OpenAI-compatible, no embeddings). |
|
Package huggingface is the Hugging Face Inference Providers router (OpenAI-compatible chat plus feature-extraction embeddings).
|
Package huggingface is the Hugging Face Inference Providers router (OpenAI-compatible chat plus feature-extraction embeddings). |
|
internal
|
|
|
httpx
Package httpx is the shared HTTP plumbing for llmkit providers: JSON and streaming POSTs, SSE and NDJSON readers, and error-envelope decoding.
|
Package httpx is the shared HTTP plumbing for llmkit providers: JSON and streaming POSTs, SSE and NDJSON readers, and error-envelope decoding. |
|
Package ollama talks to a local or remote Ollama daemon over its native /api/chat and /api/embed endpoints.
|
Package ollama talks to a local or remote Ollama daemon over its native /api/chat and /api/embed endpoints. |
|
Package openai talks to the OpenAI platform: chat over the Responses API (POST /responses) and vectors over POST /embeddings.
|
Package openai talks to the OpenAI platform: chat over the Responses API (POST /responses) and vectors over POST /embeddings. |
|
Package openaicompat implements the OpenAI Chat Completions wire format that DeepSeek, Groq, x.ai, OpenRouter, Hugging Face and many self-hosted servers speak.
|
Package openaicompat implements the OpenAI Chat Completions wire format that DeepSeek, Groq, x.ai, OpenRouter, Hugging Face and many self-hosted servers speak. |
|
Package openrouter is the OpenRouter provider (OpenAI-compatible with embeddings).
|
Package openrouter is the OpenRouter provider (OpenAI-compatible with embeddings). |
|
Package vertex talks to Gemini and Google embedding models on Vertex AI over REST, authenticating with OAuth2 access tokens (Application Default Credentials by default).
|
Package vertex talks to Gemini and Google embedding models on Vertex AI over REST, authenticating with OAuth2 access tokens (Application Default Credentials by default). |
|
Package voyage is the Voyage AI embeddings provider.
|
Package voyage is the Voyage AI embeddings provider. |
|
Package xai is the x.ai Grok chat provider (OpenAI-compatible, no embeddings).
|
Package xai is the x.ai Grok chat provider (OpenAI-compatible, no embeddings). |