Documentation
¶
Overview ¶
Package ai puts an assistant inside rig without being one: every turn runs the user's own opencode or Claude Code, with rig's MCP server as its tools, the project directory as its only workspace, and rig's guard rails between it and the environments.
Index ¶
- Constants
- Variables
- func ChangeConfig(key, value string) error
- func CloseSession(dataDir, id string) error
- func CompletePrompt(hint, text string) string
- func ConfigFile() (string, error)
- func DeniedPath(rel string, extra []string) bool
- func DescribePrompt(hint, before, want string) string
- func LastPrompt(dir string) string
- func Quoted(message, quote string) bool
- func SaveConfig(c Config) error
- func Serve(path string, handle func(Request) Reply) (close func(), err error)
- func SocketPath() string
- func SystemPrompt(s Scope) string
- type Config
- type Event
- type Message
- type Reply
- type Request
- type Risk
- type Runner
- func (r *Runner) Complete(ctx context.Context, hint, text string) (string, error)
- func (r *Runner) Describe(ctx context.Context, hint, before, want string) (string, error)
- func (r *Runner) Models(ctx context.Context, fast bool) ([]string, error)
- func (r *Runner) Turn(ctx context.Context, s *Session, typed, screen string, on func(Event)) error
- type Scope
- type Session
- type Setup
Constants ¶
const ( BackendOpencode = "opencode" BackendClaude = "claude" )
const ( EnvLock = "RIG_AI_ENV" EnvDir = "RIG_AI_DIR" EnvSock = "RIG_AI_SOCK" EnvProtected = "RIG_AI_PROTECTED" EnvKube = "RIG_AI_KUBE" )
What rig's MCP server reads to know it serves an assistant, and with which bounds.
const DefaultFreeModel = "opencode/big-pickle"
Variables ¶
var DefaultDeny = []string{".env", ".env.*", "**/*.pem", "**/*.key", "**/id_rsa*", "**/id_ed25519*", "**/.git-credentials", "**/secrets/**"}
DefaultDeny keeps credentials out of reach in every project.
var ErrTurnFailed = errors.New("the assistant's turn failed")
ErrTurnFailed is a turn whose failure was already reported as an error event.
var Keys = []string{"backend", "provider", "model", "effort", "fast_model", "fast_url", "fast_api_key", "url", "api_key", "proxy", "autocomplete", "disabled"}
Keys are the settings `rig ai config key=value` takes, in the order it prints them.
var Providers = map[string]string{
"own": "the backend's own setup (your opencode config or Claude Code login)",
"opencode": "opencode's free models (opencode/big-pickle and the other -free ones)",
"openai": "any OpenAI-compatible endpoint: url, api_key, model",
"9router": "a 9router instance (OpenAI-compatible, default http://localhost:20128/v1)",
"deepseek": "DeepSeek's API: api_key (model deepseek-chat unless set)",
"anthropic": "an Anthropic-compatible endpoint for Claude Code: url, api_key",
}
Providers an API key can be set for; "own" leaves the backend on its own login and models.
Functions ¶
func ChangeConfig ¶
ChangeConfig sets one key in the saved setup, leaving RIG_AI_* overrides out of the file.
func CloseSession ¶
Close forgets a session: its transcript and its tool state.
func CompletePrompt ¶
CompletePrompt asks for the rest of what is being typed, nothing else.
func ConfigFile ¶
func DeniedPath ¶
DeniedPath tells whether rel, a slash path inside the project, is one of DefaultDeny or extra (globs: * within a name, ** across directories; a pattern without / matches a name at any depth).
func DescribePrompt ¶
func LastPrompt ¶
LastPrompt is the user's latest message, which tools check "user_request" quotes against.
func Quoted ¶
Quoted reports whether quote is the user's own words from their message: verbatim (case and spacing aside) and long enough not to match by accident.
func SaveConfig ¶
func Serve ¶
Serve answers requests on a unix socket until close is called; handle may block (a person deciding).
func SocketPath ¶
func SocketPath() string
SocketPath is one per rig process: short, since unix socket paths are capped near 100 bytes.
func SystemPrompt ¶
SystemPrompt is what every chat turn runs under.
Types ¶
type Config ¶
type Config struct {
Backend string `json:"backend,omitempty"`
Provider string `json:"provider,omitempty"`
Model string `json:"model,omitempty"`
FastModel string `json:"fast_model,omitempty"`
// Effort is the reasoning level of chat turns: Claude Code's --effort, opencode's --variant.
Effort string `json:"effort,omitempty"`
// FastURL and FastAPIKey point completions at an OpenAI-compatible endpoint of their own,
// one direct request instead of a backend run, whatever the chat goes through.
FastURL string `json:"fast_url,omitempty"`
FastAPIKey string `json:"fast_api_key,omitempty"`
URL string `json:"url,omitempty"`
APIKey string `json:"api_key,omitempty"`
Proxy string `json:"proxy,omitempty"`
// Autocomplete suggests the rest of a query while it is typed; off by default only when set false.
Autocomplete *bool `json:"autocomplete,omitempty"`
Disabled bool `json:"disabled,omitempty"`
}
Config is the user's AI setup, kept in ~/.config/rig/ai.json (it may hold an API key: mode 0600).
func LoadConfig ¶
LoadConfig reads the saved setup; RIG_AI_* variables override it for one run.
type Request ¶
type Request struct {
Op string `json:"op"`
Text string `json:"text,omitempty"`
Action string `json:"action,omitempty"`
Args map[string]string `json:"args,omitempty"`
}
Request is what rig's MCP server asks the rig that started the assistant: a person's go-ahead (op "approve") or an action in the UI (op "ui").
type Risk ¶
type Risk int
func Classify ¶
Classify rates a rig command line an assistant wants to run. Unknown commands count as changes, anything that runs arbitrary commands or reaches secrets as dangerous or refused.
func ClassifyQuery ¶
ClassifyQuery rates query text by its statements' leading words: SQL, a redis command, kubectl arguments, PromQL. UPDATE and DELETE without WHERE are dangerous.
type Runner ¶
type Runner struct {
Setup Setup
Scope Scope
// Self is this rig binary, which the backend starts as its MCP server.
Self string
// Sock is the bridge for approvals and UI actions; empty when nothing can answer.
Sock string
Kube bool
// contains filtered or unexported fields
}
Runner runs turns of one project and environment.
func (*Runner) Complete ¶
Complete returns what likely follows text, given hint about where it is typed. An API-key provider is asked directly (one request, fast); otherwise the backend runs once without tools.
func (*Runner) Describe ¶
Describe writes the input asked for in words: before is what is typed ahead of the description (a query's start, or nothing), want the description; it returns the whole input, before included.
type Scope ¶
type Scope struct {
Project string
Dir string
File string
Env string
Runtime string
Protected bool
Envs []string
// Deny are project paths the assistant must not read (rig.yaml ai.deny), on top of DefaultDeny.
Deny []string
// Extra is the project's own instructions (rig.yaml ai.instructions).
Extra string
}
Scope is what a session is bound to: one project directory and one environment.
type Session ¶
type Session struct {
ID string `json:"id"`
Backend string `json:"backend"`
BackendID string `json:"backend_id,omitempty"`
Env string `json:"env"`
Title string `json:"title"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
Messages []Message `json:"messages"`
// contains filtered or unexported fields
}
Session is one conversation: rig keeps the transcript to show and resume it, the backend keeps its own (BackendID) so a resumed turn carries the whole context.
func ListSessions ¶
ListSessions are the project's conversations, newest first.
func LoadSession ¶
func NewSession ¶
type Setup ¶
Setup is a Config resolved against this machine: which binary runs, with which model and endpoint.
func Resolve ¶
Resolve picks the backend (the configured one, else opencode, else Claude Code) and fills the provider's defaults. A provider with its own key needs opencode, except anthropic, which is Claude Code's.