aichat

package module
v0.0.0-...-fafaaed Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const DefaultModelID = "anthropic/claude-sonnet-4-5"

DefaultModelID is the chat backend's default, mirroring captain pkg/ai (Anthropic claude-sonnet-4 is captain's NewAnthropic default).

Variables

This section is empty.

Functions

func MCPTools

func MCPTools(ctx context.Context, g *genkit.Genkit, servers []MCPServer) ([]ai.ToolRef, error)

MCPTools connects to the configured MCP servers via Genkit's MCP host and returns their active tools as ToolRefs. Returns nil when no servers configured.

func ValidateEffort

func ValidateEffort(e Effort) error

ValidateEffort rejects unknown effort values (fail loud).

Types

type Approval

type Approval struct {
	ID       string `json:"id"`
	Approved *bool  `json:"approved,omitempty"`
	Reason   string `json:"reason,omitempty"`
}

Approval is the AI SDK v6 tool-approval envelope carried on a tool part. When the user responds, Approved is set; until then it is nil.

type ApprovalPolicy

type ApprovalPolicy func(toolName string, input any) bool

ApprovalPolicy reports whether a tool call must be approved by the user before it executes. Returning true pauses the call for human-in-the-loop approval; false runs it automatically.

type ChatRequest

type ChatRequest struct {
	ID              string      `json:"id,omitempty"`
	Messages        []UIMessage `json:"messages"`
	Model           string      `json:"model,omitempty"`
	ReasoningEffort Effort      `json:"reasoningEffort,omitempty"`
	// ThreadID, when set (carried in the transport body), names the persisted
	// conversation this turn belongs to. Distinct from ID, which is the AI SDK
	// client chat id and not a server thread.
	ThreadID string `json:"threadId,omitempty"`
}

ChatRequest is the body POSTed by the AI SDK DefaultChatTransport. messages is the running UIMessage list; model and reasoningEffort are optional per-request overrides carried in the transport `body`.

type ClickyToolset

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

ClickyToolset adapts a Cobra command tree into Genkit tools backed by clicky's in-process RPC executor. Operations are discovered once via the converter; each becomes a dynamic Genkit tool whose input schema is the operation's JSON schema.

func NewClickyToolset

func NewClickyToolset(rootCmd *cobra.Command) (*ClickyToolset, error)

NewClickyToolset converts rootCmd into an RPC service and wires an enabled in-process executor. SkipPreRun avoids re-running cobra root hooks per call.

func (*ClickyToolset) DefineTools

func (t *ClickyToolset) DefineTools(g *genkit.Genkit) []ai.ToolRef

DefineTools registers each runnable operation as a Genkit tool on g and returns them as ToolRefs ready for ai.WithTools. Non-runnable group commands and cobra built-ins (completion/help) are skipped; operation names are sanitized into the provider-safe identifier charset.

type Effort

type Effort string

Effort is the per-request reasoning effort, translated per provider through Genkit's model config (Anthropic thinking budget, OpenAI reasoning_effort, Gemini thinkingConfig). Non-reasoning models ignore it.

const (
	EffortNone   Effort = ""
	EffortLow    Effort = "low"
	EffortMedium Effort = "medium"
	EffortHigh   Effort = "high"
)

type MCPServer

type MCPServer struct {
	Name           string
	Command        string            // stdio: executable
	Args           []string          // stdio: args
	Env            []string          // stdio: env
	URL            string            // remote: base URL (SSE / streamable HTTP)
	Headers        map[string]string // remote: headers
	StreamableHTTP bool              // remote: use streamable HTTP instead of SSE
}

MCPServer configures one external MCP server the chat backend consumes as a tool source. Exactly one transport must be set.

type Model

type Model struct {
	ID            string
	Provider      Provider
	Label         string // human-friendly menu label
	Reasoning     bool   // model honours Effort
	ContextWindow int    // max context tokens, for a usage gauge's denominator
}

Model describes one entry in the chat model menu. ID is the full Genkit "provider/model" id passed to ai.WithModelName.

func Catalog

func Catalog() []Model

Catalog returns the configured model menu.

func LookupModel

func LookupModel(id string) (Model, error)

LookupModel resolves a "provider/model" id against the catalog. Returns an error listing the menu on miss — fail loud, never silently substitute.

type ModelInfo

type ModelInfo struct {
	ID            string `json:"id"`
	Provider      string `json:"provider"`
	Label         string `json:"label"`
	Reasoning     bool   `json:"reasoning"`
	Configured    bool   `json:"configured"`
	ContextWindow int    `json:"contextWindow"`
}

ModelInfo is the JSON shape served at GET /api/chat/models so a client model selector can be data-driven. Configured reports whether the model's provider has an API key (selectable) vs merely catalogued.

func CatalogInfo

func CatalogInfo(registered []Provider) []ModelInfo

CatalogInfo returns the model menu annotated with whether each model's provider is among the registered providers (i.e. selectable). The order mirrors the catalog so the client can render a stable, grouped menu.

type Options

type Options struct {
	// RootCmd is the Cobra command tree whose operations become AI tools
	// (executed in-process via clicky's RPC executor). Optional.
	RootCmd *cobra.Command
	// MCPServers are external MCP servers consumed as additional tools. Optional.
	MCPServers []MCPServer
	// System is the agent's system prompt. A default is used when empty.
	System string
	// Threads persists conversations for the thread endpoints. When nil, those
	// endpoints report 501 and /api/chat stays stateless. Optional.
	Threads ThreadStore
	// RequireApprovalFor lists tool names that must be approved by the user
	// before they execute (human-in-the-loop). Tools not listed run
	// automatically. Ignored when ApprovalPolicy is set. Optional.
	RequireApprovalFor []string
	// ApprovalPolicy gates tool execution behind user approval with arbitrary
	// logic (e.g. by name prefix or input). Takes precedence over
	// RequireApprovalFor. Optional.
	ApprovalPolicy ApprovalPolicy
}

Options configures a chat Server.

type Provider

type Provider string

Provider is a Genkit provider name (the prefix of a "provider/model" id).

const (
	ProviderAnthropic Provider = "anthropic"
	ProviderOpenAI    Provider = "openai"
	ProviderGoogle    Provider = "googleai"
)

func ProviderOf

func ProviderOf(id string) Provider

ProviderOf extracts the provider from a "provider/model" id without requiring the model to be in the catalog.

type Server

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

Server is an AI-SDK-compatible chat backend. It serves POST /api/chat as the v6 UI Message Stream protocol, backed by Genkit + clicky operations + MCP.

func NewServer

func NewServer(opts Options) *Server

NewServer builds a chat server. Genkit init and tool discovery happen lazily on the first request so construction never fails on missing API keys.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the http.Handler serving the chat API: POST /api/chat (the streaming turn), GET /api/chat/models (the model menu), and the thread endpoints when a ThreadStore is configured. Mount it as a subtree (e.g. mux.Handle("/api/chat/", srv.Handler())) so the nested routes resolve.

type Thread

type Thread struct {
	ID        string      `json:"id"`
	Title     string      `json:"title"`
	CreatedAt time.Time   `json:"createdAt"`
	UpdatedAt time.Time   `json:"updatedAt"`
	Messages  []UIMessage `json:"messages"`

	// Cumulative usage across all turns in this thread.
	TotalInputTokens  int     `json:"totalInputTokens"`
	TotalOutputTokens int     `json:"totalOutputTokens"`
	TotalCostUsd      float64 `json:"totalCostUsd"`
	// LastContextTokens is the most recent turn's input-token count, which
	// approximates current context-window occupancy for a usage gauge.
	LastContextTokens int `json:"lastContextTokens"`
}

Thread is one persisted conversation: an ordered list of UIMessages plus metadata for a thread picker and accumulated token-usage/cost totals.

type ThreadStore

type ThreadStore interface {
	Create(ctx context.Context, title string) (*Thread, error)
	List(ctx context.Context) ([]*Thread, error)
	Get(ctx context.Context, id string) (*Thread, error)
	AppendMessage(ctx context.Context, id string, m UIMessage) error
	// AddUsage accumulates one turn's token usage and cost onto a thread and
	// returns the updated thread so the caller can report cumulative totals.
	AddUsage(ctx context.Context, id string, u TurnUsage) (*Thread, error)
}

ThreadStore persists conversations so a client can list past threads and resume them. Implementations must be safe for concurrent use. There is no silent in-memory fallback: when Options.Threads is nil the thread endpoints report 501 rather than pretending to persist (see CLAUDE.md CW-3).

func NewMemThreadStore

func NewMemThreadStore() ThreadStore

NewMemThreadStore returns an in-memory ThreadStore. Suitable for demos and single-process deployments; swap for a DB-backed store in production.

type TurnUsage

type TurnUsage struct {
	InputTokens  int
	OutputTokens int
	CostUSD      float64
}

TurnUsage is one generation's token usage and computed cost, accumulated onto a Thread by AddUsage.

type UIMessage

type UIMessage struct {
	ID    string   `json:"id,omitempty"`
	Role  string   `json:"role"`
	Parts []UIPart `json:"parts"`
}

UIMessage is the AI SDK v6 client message: a role plus typed parts.

type UIPart

type UIPart struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`

	// file parts
	MediaType string `json:"mediaType,omitempty"`
	URL       string `json:"url,omitempty"`
	Filename  string `json:"filename,omitempty"`

	// tool parts
	ToolName   string          `json:"toolName,omitempty"`
	ToolCallID string          `json:"toolCallId,omitempty"`
	State      string          `json:"state,omitempty"`
	Input      json.RawMessage `json:"input,omitempty"`
	Output     json.RawMessage `json:"output,omitempty"`
	Approval   *Approval       `json:"approval,omitempty"`
}

UIPart is one part of a UIMessage. It models the union of the part shapes we consume: text, reasoning, file (multimodal input), and tool parts (typed `tool-<name>` or `dynamic-tool`, which is how clicky operations surface).

Jump to

Keyboard shortcuts

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