Documentation
¶
Index ¶
- Constants
- Variables
- func EnsureLocalEmbedderModel(ctx context.Context) error
- func ProbeImageSupport(ctx context.Context, p Provider, modelID string) (supports bool, definitive bool, err error)
- func ValidateCredentials(ctx context.Context, providerID, apiKey, baseURL string) error
- type AnthropicProvider
- type CatalogModel
- type ContentPart
- type Embedder
- type LocalEmbedder
- func (e *LocalEmbedder) Close() error
- func (e *LocalEmbedder) Embed(ctx context.Context, inputs []string) ([][]float32, error)
- func (e *LocalEmbedder) EmbedModel() string
- func (e *LocalEmbedder) EnsureModelDownloaded(ctx context.Context) error
- func (e *LocalEmbedder) ID() string
- func (e *LocalEmbedder) Models() []ModelInfo
- func (e *LocalEmbedder) StreamChat(ctx context.Context, req StreamRequest) (<-chan StreamEvent, error)
- type MessageImage
- type ModelInfo
- type ModelMessage
- type ModelRefresher
- type OpenAIProvider
- func NewEmbedProvider(providerID, apiKey, model string) (*OpenAIProvider, error)
- func NewEmbedProviderWithConfig(providerID, apiKey, model, baseURL string) (*OpenAIProvider, error)
- func NewOllamaProvider() *OpenAIProvider
- func NewOpenAIProvider() *OpenAIProvider
- func NewOpenRouterProvider() *OpenAIProvider
- func (p *OpenAIProvider) Embed(ctx context.Context, inputs []string) ([][]float32, error)
- func (p *OpenAIProvider) EmbedModel() string
- func (p *OpenAIProvider) ID() string
- func (p *OpenAIProvider) Models() []ModelInfo
- func (p *OpenAIProvider) RefreshModels()
- func (p *OpenAIProvider) StreamChat(ctx context.Context, req StreamRequest) (<-chan StreamEvent, error)
- type Provider
- type Registry
- func (r *Registry) Default() Provider
- func (r *Registry) Get(id string) Provider
- func (r *Registry) List() []string
- func (r *Registry) ListModels() []ModelInfo
- func (r *Registry) ModelSupportsImages(modelID string) bool
- func (r *Registry) RefreshModels()
- func (r *Registry) Register(p Provider)
- func (r *Registry) RegisterCustomModel(modelID, providerID string)
- func (r *Registry) ReplaceProviders(providers map[string]Provider)
- func (r *Registry) ResolveProvider(modelID string) Provider
- func (r *Registry) UnregisterCustomModel(modelID string)
- type StreamEvent
- type StreamEventType
- type StreamRequest
- type TokenUsage
- type ToolDefinition
Constants ¶
const EmbedModelID = "all-MiniLM-L6-v2"
EmbedModelID is the default model identifier returned by EmbedModel().
const LocalEmbedderProvider = "local"
LocalEmbedderProvider is the provider ID for the inbuilt, no-dependency embedder that runs a sentence-embedding model in-process. It needs no API key and no network access. It is the only embedder ogcode supports — agentic memory embeddings are always produced locally.
Variables ¶
var AnthropicModels = []CatalogModel{ {ID: "claude-opus-4-7", Name: "Claude Opus 4.7", ActiveByDefault: true, InputPricePerM: 15, OutputPricePerM: 75, SupportsImages: true}, {ID: "claude-opus-4-6", Name: "Claude Opus 4.6", ActiveByDefault: true, InputPricePerM: 15, OutputPricePerM: 75, SupportsImages: true}, {ID: "claude-sonnet-4-6", Name: "Claude Sonnet 4.6", ActiveByDefault: true, InputPricePerM: 3, OutputPricePerM: 15, SupportsImages: true}, {ID: "claude-haiku-4-5-20251001", Name: "Claude Haiku 4.5", ActiveByDefault: true, InputPricePerM: 0.80, OutputPricePerM: 4, SupportsImages: true}, {ID: "claude-opus-4-5-20251101", Name: "Claude Opus 4.5", ActiveByDefault: false, InputPricePerM: 15, OutputPricePerM: 75, SupportsImages: true}, {ID: "claude-opus-4-1-20250805", Name: "Claude Opus 4.1", ActiveByDefault: false, InputPricePerM: 15, OutputPricePerM: 75, SupportsImages: true}, {ID: "claude-sonnet-4-5-20250929", Name: "Claude Sonnet 4.5", ActiveByDefault: false, InputPricePerM: 3, OutputPricePerM: 15, SupportsImages: true}, {ID: "claude-opus-4-20250514", Name: "Claude Opus 4", ActiveByDefault: false, InputPricePerM: 15, OutputPricePerM: 75, SupportsImages: true}, {ID: "claude-sonnet-4-20250514", Name: "Claude Sonnet 4", ActiveByDefault: false, InputPricePerM: 3, OutputPricePerM: 15, SupportsImages: true}, }
AnthropicModels is the authoritative list of Anthropic models. Maintained by contributors — see file header for instructions. All listed Claude models are multimodal and accept image input.
var OpenAIModels = []CatalogModel{ {ID: "gpt-5", Name: "GPT-5", ActiveByDefault: true, InputPricePerM: 10, OutputPricePerM: 30, SupportsImages: true}, {ID: "gpt-5-mini", Name: "GPT-5 Mini", ActiveByDefault: true, InputPricePerM: 1.50, OutputPricePerM: 6, SupportsImages: true}, {ID: "gpt-5-nano", Name: "GPT-5 Nano", ActiveByDefault: false, InputPricePerM: 0.10, OutputPricePerM: 0.40, SupportsImages: true}, {ID: "gpt-4.1", Name: "GPT-4.1", ActiveByDefault: true, InputPricePerM: 2, OutputPricePerM: 8, SupportsImages: true}, {ID: "gpt-4.1-mini", Name: "GPT-4.1 Mini", ActiveByDefault: true, InputPricePerM: 0.40, OutputPricePerM: 1.60, SupportsImages: true}, {ID: "gpt-4.1-nano", Name: "GPT-4.1 Nano", ActiveByDefault: false, InputPricePerM: 0.10, OutputPricePerM: 0.40, SupportsImages: true}, {ID: "gpt-4o", Name: "GPT-4o", ActiveByDefault: false, InputPricePerM: 2.50, OutputPricePerM: 10, SupportsImages: true}, {ID: "gpt-4o-mini", Name: "GPT-4o Mini", ActiveByDefault: false, InputPricePerM: 0.15, OutputPricePerM: 0.60, SupportsImages: true}, {ID: "o4-mini", Name: "o4 Mini", ActiveByDefault: true, InputPricePerM: 1.10, OutputPricePerM: 4.40, SupportsImages: true}, {ID: "o3", Name: "o3", ActiveByDefault: true, InputPricePerM: 10, OutputPricePerM: 40, SupportsImages: true}, {ID: "o3-mini", Name: "o3 Mini", ActiveByDefault: false, InputPricePerM: 1.10, OutputPricePerM: 4.40}, {ID: "o1", Name: "o1", ActiveByDefault: false, InputPricePerM: 15, OutputPricePerM: 60, SupportsImages: true}, {ID: "o1-mini", Name: "o1 Mini", ActiveByDefault: false, InputPricePerM: 1.50, OutputPricePerM: 6}, }
OpenAIModels is the authoritative list of OpenAI models. Maintained by contributors — see file header for instructions. SupportsImages marks multimodal models. The o*-mini reasoning models are text-only; the GPT-4o/4.1/5 families and o1/o3/o4-mini accept images.
var ProviderPriority = []string{"anthropic", "openai", "openrouter", "ollama"}
ProviderPriority is the stable order used to choose a default provider when a session does not specify a model.
Functions ¶
func EnsureLocalEmbedderModel ¶ added in v0.11.0
EnsureLocalEmbedderModel performs a blocking preflight that guarantees the inbuilt local embedder's model weights are present on disk in the default cache directory. It downloads the ~86 MB ONNX file on first use; subsequent calls hit the cache and return immediately.
Call this once at server startup (before serving requests) so the one-time download completes up front, regardless of whether agentic memory is enabled at boot — the local embedder is the default and may be enabled at runtime via the settings UI without a restart. A non-nil error means the download could not complete (e.g. no network); the caller may continue, as the next Embed call will retry.
func ProbeImageSupport ¶ added in v0.6.0
func ProbeImageSupport(ctx context.Context, p Provider, modelID string) (supports bool, definitive bool, err error)
ProbeImageSupport sends a single minimal image to the model and reports whether it was accepted. Return values:
- (true, true, nil): the model accepted the image and responded.
- (false, true, nil): the provider rejected the request for an image/modality reason.
- (false, false, err): inconclusive (network/auth/rate-limit/etc.) — do NOT cache; retry later.
func ValidateCredentials ¶ added in v0.10.0
ValidateCredentials makes a minimal chat request with the given credentials to confirm the provider accepts them. It returns nil when the credentials work, or an error describing the failure. Used by the settings/onboarding "test key" flow. The caller is responsible for any timeout via ctx.
Types ¶
type AnthropicProvider ¶
type AnthropicProvider struct {
// contains filtered or unexported fields
}
AnthropicProvider implements Provider for the Anthropic Messages API.
func NewAnthropicProvider ¶
func NewAnthropicProvider() *AnthropicProvider
func (*AnthropicProvider) ID ¶
func (p *AnthropicProvider) ID() string
func (*AnthropicProvider) Models ¶
func (p *AnthropicProvider) Models() []ModelInfo
func (*AnthropicProvider) StreamChat ¶
func (p *AnthropicProvider) StreamChat(ctx context.Context, req StreamRequest) (<-chan StreamEvent, error)
type CatalogModel ¶ added in v0.2.3
type CatalogModel struct {
ID string
Name string
ActiveByDefault bool
InputPricePerM float64 // USD per 1M input tokens (0 = unknown)
OutputPricePerM float64 // USD per 1M output tokens (0 = unknown)
SupportsImages bool // whether the model accepts image input
}
CatalogModel is a statically-known model for a provider that does not expose a live /v1/models discovery endpoint.
type ContentPart ¶
type Embedder ¶ added in v0.2.1
type Embedder interface {
// Embed returns embedding vectors for the given input strings.
Embed(ctx context.Context, inputs []string) ([][]float32, error)
EmbedModel() string
}
Embedder is an optional interface that providers can implement to support text embeddings (used for agentic memory semantic recall).
type LocalEmbedder ¶ added in v0.11.0
type LocalEmbedder struct {
// contains filtered or unexported fields
}
LocalEmbedder is a provider.Embedder implementation that runs a sentence-embedding model entirely in-process — no API key, no network call (after the one-time model download), no separate model server.
The small tokenizer/config assets are embedded in the binary (see internal/provider/embedmodel) and lazily materialized to a cache directory on first use. The large ONNX weight file (~86 MB) is downloaded from Hugging Face on first use rather than embedded, so the distributable binary stays small — mirroring ogcode's search-bridge download pattern.
It uses Hugot's pure-Go backend (GoMLX simplego), so the binary stays CGO-free and self-contained. The default model is sentence-transformers/all-MiniLM-L6-v2, producing 384-dim embeddings.
func NewLocalEmbedder ¶ added in v0.11.0
func NewLocalEmbedder(cacheDir string) *LocalEmbedder
NewLocalEmbedder creates a LocalEmbedder. cacheDir overrides the default materialization location (~/.ogcode/embed-model) when non-empty.
func (*LocalEmbedder) Close ¶ added in v0.11.0
func (e *LocalEmbedder) Close() error
Close releases the Hugot session and model resources. Safe to call multiple times.
func (*LocalEmbedder) Embed ¶ added in v0.11.0
Embed returns embedding vectors for the given inputs. It lazily initializes the model on first call. Inference is serialized because the pure-Go GoMLX backend is not safe for concurrent use from multiple goroutines.
func (*LocalEmbedder) EmbedModel ¶ added in v0.11.0
func (e *LocalEmbedder) EmbedModel() string
EmbedModel returns the identifier of the model used for embeddings.
func (*LocalEmbedder) EnsureModelDownloaded ¶ added in v0.11.0
func (e *LocalEmbedder) EnsureModelDownloaded(ctx context.Context) error
EnsureModelDownloaded guarantees the local embedder's model weights are present on disk (downloading them on first use and verifying the SHA-256) but does NOT build the inference pipeline. It is meant for a startup preflight: call it once at server boot so the one-time ~86 MB download completes before the server accepts requests. A LocalEmbedder later used for inference (e.g. by agentic memory) shares the same cache directory, finds the cached model, and only pays the pipeline-build cost — never re-downloading.
It is idempotent: a sidecar marker records the verified hash so subsequent calls skip both the download and the full-file hash check, returning immediately. Safe to call concurrently with init/Embed on another instance sharing the same cache directory (file writes are idempotent and the final rename is atomic).
func (*LocalEmbedder) ID ¶ added in v0.11.0
func (e *LocalEmbedder) ID() string
ID returns the provider identifier.
func (*LocalEmbedder) Models ¶ added in v0.11.0
func (e *LocalEmbedder) Models() []ModelInfo
Models returns an empty model list: the local embedder is embedding-only and not selectable as a chat provider.
func (*LocalEmbedder) StreamChat ¶ added in v0.11.0
func (e *LocalEmbedder) StreamChat(ctx context.Context, req StreamRequest) (<-chan StreamEvent, error)
StreamChat is not supported — the local embedder is embedding-only.
type MessageImage ¶ added in v0.6.0
MessageImage is an image attached to a message, carried provider-neutrally. Data is base64-encoded image bytes; MediaType is e.g. "image/jpeg".
type ModelInfo ¶
type ModelInfo struct {
ID string `json:"id"`
Name string `json:"name"`
ProviderID string `json:"providerId"`
Default bool `json:"default"`
ActiveByDefault bool `json:"activeByDefault"`
InputPricePerM float64 `json:"inputPricePerM"`
OutputPricePerM float64 `json:"outputPricePerM"`
SupportsImages bool `json:"supportsImages"`
}
type ModelMessage ¶
type ModelMessage struct {
Role string `json:"role"`
Content json.RawMessage `json:"content,omitempty"`
ToolCalls json.RawMessage `json:"tool_calls,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
Name string `json:"name,omitempty"`
// Images carries image attachments for a tool-result message. Providers
// render these per their API: Anthropic embeds them in the tool_result
// content block; OpenAI-family inject a follow-up user message.
Images []MessageImage `json:"images,omitempty"`
}
type ModelRefresher ¶ added in v0.1.3
type ModelRefresher interface {
RefreshModels()
}
ModelRefresher is an optional interface that providers can implement to support dynamic model list refreshing.
type OpenAIProvider ¶
type OpenAIProvider struct {
// contains filtered or unexported fields
}
OpenAIProvider implements Provider for the OpenAI Chat Completions API. Also used for OpenRouter and Ollama (same API format, different base URL).
func NewEmbedProvider ¶ added in v0.2.1
func NewEmbedProvider(providerID, apiKey, model string) (*OpenAIProvider, error)
NewEmbedProvider creates an OpenAIProvider configured for embedding. providerID must be "openai", "openrouter", or "ollama". If apiKey is non-empty it overrides the env var key. If model is non-empty it is stored as the provider model (used for embedding). Deprecated: Use NewEmbedProviderWithConfig for full control over baseURL.
func NewEmbedProviderWithConfig ¶ added in v0.8.1
func NewEmbedProviderWithConfig(providerID, apiKey, model, baseURL string) (*OpenAIProvider, error)
NewEmbedProviderWithConfig creates an OpenAIProvider configured for embedding with optional apiKey, model, and baseURL overrides. Env-var values are used as the base; non-empty parameters override them.
func NewOllamaProvider ¶
func NewOllamaProvider() *OpenAIProvider
NewOllamaProvider creates an OpenAI-compatible provider for Ollama. When OLLAMA_BASE_URL points to a cloud endpoint (not localhost), the model list is fetched dynamically from /v1/models. For local Ollama, a static fallback list is used.
func NewOpenAIProvider ¶
func NewOpenAIProvider() *OpenAIProvider
func NewOpenRouterProvider ¶
func NewOpenRouterProvider() *OpenAIProvider
NewOpenRouterProvider creates an OpenAI-compatible provider for OpenRouter.
func (*OpenAIProvider) EmbedModel ¶ added in v0.2.1
func (p *OpenAIProvider) EmbedModel() string
func (*OpenAIProvider) ID ¶
func (p *OpenAIProvider) ID() string
func (*OpenAIProvider) Models ¶
func (p *OpenAIProvider) Models() []ModelInfo
func (*OpenAIProvider) RefreshModels ¶ added in v0.1.3
func (p *OpenAIProvider) RefreshModels()
RefreshModels clears the cached model list so the next call to Models() will re-fetch from the endpoint (for cloud providers). Not safe to call concurrently with Models().
func (*OpenAIProvider) StreamChat ¶
func (p *OpenAIProvider) StreamChat(ctx context.Context, req StreamRequest) (<-chan StreamEvent, error)
type Provider ¶
type Provider interface {
ID() string
Models() []ModelInfo
StreamChat(ctx context.Context, req StreamRequest) (<-chan StreamEvent, error)
}
func NewEmbedder ¶ added in v0.11.0
func NewEmbedder() Provider
NewEmbedder returns the inbuilt local embedder. ogcode no longer supports third-party embedders (OpenAI, OpenRouter, Ollama) for agentic memory — the pure-Go all-MiniLM-L6-v2 model runs in-process with zero configuration. The returned provider also satisfies Embedder.
func NewProviderWithConfig ¶ added in v0.2.1
NewProviderWithConfig creates a Provider with explicit credentials, used when credentials come from the DB rather than environment variables. providerID must be "anthropic", "openai", "openrouter", or "ollama". Env-var values are used as the base; apiKey and baseURL override them when non-empty.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
func NewRegistry ¶
func NewRegistry() *Registry
func (*Registry) Default ¶ added in v0.10.0
Default returns the highest-priority registered provider, or nil if the registry has no providers.
func (*Registry) ListModels ¶
func (*Registry) ModelSupportsImages ¶ added in v0.6.0
ModelSupportsImages reports whether the given model accepts image input. Unknown models default to false.
func (*Registry) RefreshModels ¶ added in v0.1.3
func (r *Registry) RefreshModels()
RefreshModels clears cached model lists for all providers that support it, forcing re-fetch on next Models() call.
func (*Registry) RegisterCustomModel ¶
func (*Registry) ReplaceProviders ¶ added in v0.10.0
ReplaceProviders atomically swaps the set of registered providers. Custom model routing (RegisterCustomModel) is preserved. Used to apply provider credential changes from the settings/onboarding UI without a server restart.
func (*Registry) ResolveProvider ¶
func (*Registry) UnregisterCustomModel ¶
type StreamEvent ¶
type StreamEvent struct {
Type StreamEventType `json:"type"`
Text string `json:"text,omitempty"`
ToolCallID string `json:"toolCallId,omitempty"`
ToolName string `json:"toolName,omitempty"`
ToolInput json.RawMessage `json:"toolInput,omitempty"`
FinishReason *string `json:"finishReason,omitempty"`
Usage *TokenUsage `json:"usage,omitempty"`
Error string `json:"error,omitempty"`
}
type StreamEventType ¶
type StreamEventType string
const ( EventTextDelta StreamEventType = "text-delta" EventToolCallStart StreamEventType = "tool-call-start" EventToolCallDelta StreamEventType = "tool-call-delta" EventToolCallEnd StreamEventType = "tool-call-end" EventReasoning StreamEventType = "reasoning" EventFinish StreamEventType = "finish" EventUsage StreamEventType = "usage" EventError StreamEventType = "error" )
type StreamRequest ¶
type StreamRequest struct {
Model string `json:"model"`
System []string `json:"system"`
Messages []ModelMessage `json:"messages"`
Tools []ToolDefinition `json:"tools"`
Temperature float64 `json:"temperature,omitempty"`
MaxTokens int `json:"maxTokens,omitempty"`
Abort context.Context `json:"-"`
}
type TokenUsage ¶
type TokenUsage struct {
InputTokens int `json:"inputTokens,omitempty"`
OutputTokens int `json:"outputTokens,omitempty"`
ReasoningTokens int `json:"reasoningTokens,omitempty"`
CacheReadTokens int `json:"cacheReadTokens,omitempty"`
CacheWriteTokens int `json:"cacheWriteTokens,omitempty"`
}
TokenUsage carries per-message token accounting from a provider. Fields are non-zero where the provider reports them.
type ToolDefinition ¶
type ToolDefinition struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters json.RawMessage `json:"parameters"`
}
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package embedmodel bundles a sentence-embedding model so agentic memory works with zero external dependencies — no API key, no network call (after the one-time model download), no separate model server required.
|
Package embedmodel bundles a sentence-embedding model so agentic memory works with zero external dependencies — no API key, no network call (after the one-time model download), no separate model server required. |