eino

package
v1.4.13 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package eino contains the Eino-backed chat model wrapper used by all AI agents in versus-incident. It is the ONLY package in the codebase that imports concrete model SDKs — every concrete AI agent (detect, analyze, ...) goes through these helpers so a future framework swap only touches this package.

There is no `framework` knob in the config (Eino is the framework). The MODEL backend, however, IS selectable: `agent.ai.provider` chooses among the providers registered in provider.go (openai by default). The provider registry is the single chokepoint for concrete model imports.

Index

Constants

View Source
const DefaultProvider = "openai"

DefaultProvider is the model backend used when AgentAIConfig.Provider is empty. It is the OSS default and preserves the historical OpenAI behaviour byte-for-byte (JSON-mode, MaxCompletionTokens, AuthKeyFunc transport, the test-only Options.BaseURL seam).

Variables

This section is empty.

Functions

func IsSupportedProvider added in v1.4.4

func IsSupportedProvider(name string) bool

IsSupportedProvider reports whether name (case-insensitive, with the empty string normalised to DefaultProvider) is a registered chat provider. It is the boundary validator the enterprise control API gates writes on.

func NewChatModel

func NewChatModel(ctx context.Context, cfg config.AgentAIConfig, opts Options) (model.BaseChatModel, error)

NewChatModel builds an Eino ChatModel configured for JSON-mode structured output. cfg must already be the *resolved* per-task config (see AgentAIConfig.Resolve) — this helper does not look at the per-task sub-blocks.

The concrete model backend is selected by cfg.Provider via the provider registry (provider.go); an empty provider defaults to openai and an unsupported one fails fast. Model must be set; APIKey may be empty (the provider client errors at call time, not construction time, which is fine for tests).

func NewEmbedder added in v1.4.4

func NewEmbedder(ctx context.Context, cfg config.AgentAIConfig, opts Options) (core.Embedder, error)

NewEmbedder builds a core.Embedder for the configured provider. cfg.Provider selects the backend (empty defaults to openai); an unsupported provider fails fast with a clear error. cfg.Model must be set (the embedding model id, e.g. "text-embedding-3-small"); APIKey may be empty (a local/unauthenticated server accepts it, a remote one errors at call time — convenient for tests).

The openai path is OpenAI-compatible, so pointing opts.BaseURL at a local server (Ollama / vLLM / LocalAI) keeps embeddings in the operator's VPC; the dedicated ollama provider does the same against a native Ollama daemon.

func NewToolCallingChatModel

func NewToolCallingChatModel(ctx context.Context, cfg config.AgentAIConfig, opts Options) (model.ToolCallingChatModel, error)

NewToolCallingChatModel mirrors NewChatModel but returns the tool-calling variant. The analyze agent needs WithTools to register its read-only tool catalog; detect uses the base helper above.

IMPORTANT: this helper deliberately does NOT force JSON-mode. With tools bound, the model alternates between tool_calls (JSON, never content) and a final assistant message; forcing JSON-mode causes providers to reject the tool-call turns.

func SupportedProviders added in v1.4.4

func SupportedProviders() []string

SupportedProviders is the exported, sorted list of registered chat providers. It lets a consumer (e.g. the enterprise runtime AI-settings API) validate an operator-supplied provider on WRITE against the SAME registry the model builders use, so an unknown value is rejected at the boundary rather than relying solely on the Holder's runtime fail-closed.

Types

type Holder added in v1.4.4

type Holder[T any] struct {
	// contains filtered or unexported fields
}

Holder lazily builds and caches a model artifact of type T (a chat model, a tool-calling chat model, an embedder, or a higher-level agent that wraps one), rebuilding only when the effective signature changes. It is concurrency-safe: agent ticks and an operator's runtime change can race, so every Get is mutex-guarded.

func NewChatModelHolder added in v1.4.4

func NewChatModelHolder(base config.AgentAIConfig, opts Options, rt RuntimeAI) *Holder[model.BaseChatModel]

NewChatModelHolder is the shared entrypoint for the tool-free, JSON-mode chat path (detect, slo-advisor). It rebuilds the model on a provider / model / state change and returns model.BaseChatModel.

func NewEmbedderHolder added in v1.4.4

func NewEmbedderHolder(base config.AgentAIConfig, opts Options, rt RuntimeAI) *Holder[core.Embedder]

NewEmbedderHolder mirrors the chat holders for the embedding path. Runtime provider overrides are validated against the (smaller) embedding registry, so a runtime switch to a chat-only provider (deepseek, claude, qwen) fails closed to the configured embedding provider.

func NewModelHolder added in v1.4.4

func NewModelHolder[T any](base config.AgentAIConfig, opts Options, rt RuntimeAI, build func(ctx context.Context, cfg config.AgentAIConfig, opts Options) (T, error)) *Holder[T]

NewModelHolder builds a Holder for an arbitrary artifact whose backend is a CHAT provider (runtime provider overrides are validated against the chat registry). build receives a copy of base with Provider already resolved to the effective provider for the current signature; callers route their construction (e.g. NewToolCallingChatModel + a ReAct agent) through it.

func NewToolCallingChatModelHolder added in v1.4.4

func NewToolCallingChatModelHolder(base config.AgentAIConfig, opts Options, rt RuntimeAI) *Holder[model.ToolCallingChatModel]

NewToolCallingChatModelHolder is the shared entrypoint for the tool-calling analyze path. It returns model.ToolCallingChatModel; the caller binds tools.

func (*Holder[T]) Current added in v1.4.4

func (h *Holder[T]) Current() T

Current returns the most recently built artifact without consulting the runtime signature (no rebuild). It returns the zero value when nothing has been built yet. Used by structural guards that need the concrete built model, never on the hot path.

func (*Holder[T]) Get added in v1.4.4

func (h *Holder[T]) Get(ctx context.Context) (T, error)

Get returns the model for the current effective signature, rebuilding it only when the signature has changed since the last build. A build error is returned to the caller and the previously-cached model (if any) is left untouched, so a transient failure never poisons a healthy holder.

type Options

type Options struct {
	HTTPClient *http.Client
	BaseURL    string
	Timeout    time.Duration

	// AuthKeyFunc is an OPTIONAL per-request Authorization override. When
	// non-nil the outbound transport calls it for every request: if it
	// returns ok the request's Authorization header is replaced with
	// "Bearer <key>" AFTER the SDK set its YAML-keyed header (so the
	// override wins); ok=false leaves the YAML-keyed header untouched. When
	// nil the transport is a plain pass-through and the client is used
	// exactly as before — this is the OSS byte-for-byte path. The package
	// stays generic: it knows nothing about who supplies the key (the agent
	// package injects a function backed by its runtime AISettingsResolver,
	// which avoids an import cycle because eino never imports agent).
	AuthKeyFunc func(ctx context.Context) (key string, ok bool)
}

BaseURL is overridable for tests. Production code passes "" to use the Eino / go-openai default (https://api.openai.com/v1). The agent admin endpoints never expose this; only the chatmodel test sets it to point at an httptest server.

type RuntimeAI added in v1.4.4

type RuntimeAI struct {
	// Provider returns a runtime provider override for ctx. ok=false ⇒ no
	// opinion (use the configured provider). An unknown/unsupported value
	// FAILS CLOSED: the Holder keeps the configured provider and logs once
	// per distinct bad value — it never crashes and never silently falls
	// back to openai.
	Provider func(ctx context.Context) (provider string, ok bool)

	// Enabled folds the runtime enable state into the signature so a toggle
	// rebuilds. ok=false ⇒ not folded. Optional.
	Enabled func(ctx context.Context) (enabled bool, ok bool)

	// KeySet folds whether a runtime key override is currently present into
	// the signature so a set⟷clear transition rebuilds. ok=false ⇒ not
	// folded. The key VALUE is never part of the signature (it hot-reloads
	// through the transport). Optional.
	KeySet func(ctx context.Context) (set bool, ok bool)
}

RuntimeAI is the optional set of runtime override signals folded into a Holder's rebuild signature. Every func MAY be nil; a zero RuntimeAI is the community default (no overrides ⇒ the configured provider, built once, never rebuilt).

Provider composes with the existing per-request key override: the key VALUE still hot-reloads through the AuthKeyFunc transport WITHOUT a rebuild (it is NOT part of the signature); only the provider, the model id, and the enable/key-presence STATE force a rebuild.

Jump to

Keyboard shortcuts

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