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 AppendAudit(file string, e AuditEntry) error
- func ChangeConfig(key, value string) error
- func CloseSession(dataDir, id string) error
- func CompletePrompt(hint, text string) string
- func ConfigFile() (string, error)
- func Connect(f Found) 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 SecretName(n string) bool
- func Serve(path string, handle func(Request) Reply) (close func(), err error)
- func SocketPath() string
- func SplitNext(text string) (rest, next string)
- func SystemPrompt(s Scope) string
- type Agent
- type AuditEntry
- type Config
- type Event
- type Found
- type LocalServer
- type Message
- type Redactor
- type Reply
- type Request
- type Risk
- type Runner
- func (r *Runner) Ask(ctx context.Context, prompt string) (string, error)
- 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" // EnvBareTools has the MCP server list its tools without the rig_ prefix (opencode adds the server's name) EnvBareTools = "RIG_MCP_BARE" // EnvAgent names the rig.yaml agent the server acts as; EnvTools and EnvApprove are its globs, comma-separated. EnvAgent = "RIG_AI_AGENT" EnvTools = "RIG_AI_TOOLS" EnvApprove = "RIG_AI_APPROVE" )
What rig's MCP server reads to know it serves an assistant, and with which bounds.
const DefaultFreeModel = "opencode/big-pickle"
const EnvAudit = "RIG_AI_AUDIT"
EnvAudit is where rig's MCP server appends what the assistant ran (AuditEntry lines).
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", "redact"}
Keys are the settings `rig ai config key=value` takes, in the order it prints them.
var LocalProviders = map[string]string{"ollama": "http://localhost:11434/v1", "lmstudio": "http://localhost:1234/v1"}
LocalProviders are the providers that run on this machine, with their OpenAI-compatible endpoints.
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",
"ollama": "a local Ollama (default http://localhost:11434/v1): model, no key",
"lmstudio": "a local LM Studio server (default http://localhost:1234/v1): model, no key",
}
Providers an API key can be set for; "own" leaves the backend on its own login and models.
Functions ¶
func AppendAudit ¶ added in v0.6.0
func AppendAudit(file string, e AuditEntry) error
AppendAudit adds e to file as one JSON line; the output is cut to its last 400 bytes.
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 Connect ¶ added in v0.7.0
Connect points the saved setup at a found backend as the user has it set up: its own login, config and model (opencode without a model gets its free ones). Other settings are kept.
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 SecretName ¶ added in v0.6.0
SecretName is whether a variable or field named n holds a secret, by its name.
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 SplitNext ¶ added in v0.23.0
SplitNext takes the "NEXT: ..." line the system prompt asks answers to end with off text.
func SystemPrompt ¶
SystemPrompt is what every chat turn runs under.
Types ¶
type Agent ¶ added in v0.26.0
Agent is a rig.yaml agent: it reads files but never edits or runs a shell, and reaches rig only through the tools its globs allow, as itself.
type AuditEntry ¶ added in v0.6.0
type AuditEntry struct {
At time.Time `json:"at"`
Env string `json:"env"`
Command string `json:"command"`
Risk string `json:"risk"`
// Result is ok, failed, declined (by the user) or refused (by rig).
Result string `json:"result"`
By string `json:"confirmed_by,omitempty"`
Output string `json:"output,omitempty"`
}
AuditEntry is one action the assistant ran, or tried to, on an environment.
func ReadAudit ¶ added in v0.6.0
func ReadAudit(file string) ([]AuditEntry, error)
ReadAudit returns file's entries, oldest first; a missing file has none.
func (AuditEntry) String ¶ added in v0.6.0
func (e AuditEntry) String() string
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"`
// Redact replaces secrets with <secret:NAME> in everything sent to the model; on unless set false.
Redact *bool `json:"redact,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 Found ¶ added in v0.7.0
type Found struct {
Backend, Bin, Model string
// Ready is whether it has a login or a model to run with; opencode always does (free models).
Ready bool
}
Found is an AI tool installed on this machine, with the model its own config picks.
type LocalServer ¶ added in v0.6.0
LocalServer is a model server found running on this machine.
func DetectLocal ¶ added in v0.6.0
func DetectLocal(ctx context.Context) []LocalServer
DetectLocal finds the local model servers (LocalProviders) that answer, with the models they serve.
type Redactor ¶ added in v0.6.0
type Redactor struct {
// contains filtered or unexported fields
}
Redactor puts <secret:NAME> in place of secrets in text bound for a model: the values rig knows to be secret (Known), then whatever goxang/scrub's packs take for a credential (URL passwords, key=value pairs, JWTs, cloud tokens, bearer headers, private keys, card numbers, PINs). A nil Redactor redacts nothing.
func NewRedactor ¶ added in v0.6.0
NewRedactor redacts the values of known (name → value) wherever they appear.
type Reply ¶
type Reply struct {
OK bool `json:"ok"`
Text string `json:"text,omitempty"`
// NoOne is an "approve" nobody could be asked (no terminal): the user's quoted words decide.
NoOne bool `json:"no_one,omitempty"`
}
Reply answers a Request. For an "approve", Text names who said yes, or why not.
type Request ¶
type Request struct {
Op string `json:"op"`
Text string `json:"text,omitempty"`
// Command is the exact action an "approve" is for, which "always allow" remembers.
Command string `json:"command,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
// Redactor takes the secrets out of every prompt; nil sends them as they are (redact=false).
Redactor *Redactor
// AuditFile is the JSONL file every action of the assistant is appended to.
AuditFile string
// Agent, when set, runs turns as that agent.
Agent *Agent
// contains filtered or unexported fields
}
Runner runs turns of one project and environment.
func (*Runner) Ask ¶ added in v0.6.0
Ask puts one question to the chat model, without tools, and returns its whole answer.
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 ¶
func (r *Runner) Describe(ctx context.Context, hint, before, want string, check func(context.Context, string) error) (string, error)
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.
check, when not nil, tries the answer (compiles it, runs it where that is safe); an answer that fails goes back to the model with the error, up to three tries. After the last, the answer is returned with the error.
type Scope ¶
type Scope struct {
Project string
Dir string
File string
Env string
Runtime string
Protected bool
ReadOnly 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"`
// Next is what the last answer suggests the user asks next
Next string `json:"next,omitempty"`
// 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.
func (Setup) AutocompleteOn ¶
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package agents fires rig.yaml agents on their events and schedules.
|
Package agents fires rig.yaml agents on their events and schedules. |
|
Package router gives an AI a small fixed set of meta-tools over the Engine (find, call, query, read, open, skill, docs, file, ui) instead of one tool per action, so forty plugins do not flood its context.
|
Package router gives an AI a small fixed set of meta-tools over the Engine (find, call, query, read, open, skill, docs, file, ui) instead of one tool per action, so forty plugins do not flood its context. |