Documentation
¶
Index ¶
- Constants
- Variables
- func AppendShellContextIfConfigured(ctx context.Context, configDir, shellContextName, prompt string, ...) (string, error)
- func ApplyFlagOverrides(tConf *Configurations, tf internal.TextFlags)
- func ApplyProfileOverrides(tConf *Configurations, tf internal.TextFlags)
- func CanonicalModelString(vendor, family, modelVersion string) string
- func CreateQuerier(ctx context.Context, conf Configurations) (models.Querier, error)
- func MigrateOldChatConfig(configDirPath string) error
- func QueryCommand(deps QueryCommandDeps) *internal.Command
- type AgentSettings
- type CallUsageRecorder
- type CompletedModelCall
- type Configurations
- type CostManager
- type LoadedSkillRuntime
- type ModelNamer
- type ModelStepResult
- type Profile
- type Querier
- func (q *Querier[C]) Query(ctx context.Context) error
- func (q *Querier[C]) SetChatID(chatID string)
- func (q *Querier[C]) SetSummarizer(s models.Summarizer)
- func (q *Querier[C]) SuppressCompletionNotification() bool
- func (q *Querier[C]) TextQuery(ctx context.Context, chat pub_models.Chat) (pub_models.Chat, error)
- type QueryCommandDeps
- type QuerySession
- type ShellContextDefinition
- type ShellContextRenderer
- type SkillLoader
- type Stoploss
- type ToolCall
- type ToolCallRecorder
- type ToolDecision
Constants ¶
const DefaultHandoverInstructions = "You are approaching the context window limit. Summarize your work and prepare for handover."
DefaultHandoverInstructions is the user message injected into the chat when the token stoploss limit is crossed and no custom message is configured.
Variables ¶
var Default = Configurations{ Model: "gpt-5.2", SystemPrompt: "You are an assistant for a CLI tool. Answer concisely and informatively. Prefer markdown if possible.", Raw: false, UseTools: false, ToolOutputRuneLimit: 21600, SaveReplyAsConv: true, UseLookback: false, SummarizeConversations: true, Stoploss: &Stoploss{ MaxTokens: 0, MaxTokensHandoverMsg: DefaultHandoverInstructions, }, CmdModePrompt: "You are an assistant for a CLI tool aiding with cli tool suggestions. Write ONLY the command and nothing else. Disregard any queries asking for anything except a bash command. Do not shell escape single or double quotes.", }
Functions ¶
func AppendShellContextIfConfigured ¶
func AppendShellContextIfConfigured(ctx context.Context, configDir, shellContextName, prompt string, r ShellContextRenderer) (string, error)
AppendShellContextIfConfigured inserts the rendered shell context block into prompt.
Insertion rule:
- if rendered is non-empty: "<shell context>\n" + rendered + "\n</shell context>\n" + <original-prompt-with-leading-whitespace-trimmed>
func ApplyFlagOverrides ¶ added in v1.11.0
func ApplyFlagOverrides(tConf *Configurations, tf internal.TextFlags)
ApplyFlagOverrides applies the CLI flag values onto the file-loaded configuration.
The default flags are needed to ensure that the configuration isn't being overwritten by the default flags. Meaning: Only set the value of tConf to the flag, if it's not the default, leave the configuration found in file. If there is no check if the flagSet is default, there may be a case where default > file, which breaks the configuration convention flags > file > default
func ApplyProfileOverrides ¶ added in v1.11.0
func ApplyProfileOverrides(tConf *Configurations, tf internal.TextFlags)
ApplyProfileOverrides re-applies the flags that may overrule profile configurations.
func CanonicalModelString ¶ added in v1.10.13
CanonicalModelString is the inverse of vendorType. Given a (vendor, family, modelVersion) triplet — typically parsed from a config filename — it returns the canonical model identifier that can be placed in a profile's "model" field and correctly routed.
func CreateQuerier ¶ added in v1.11.0
CreateQuerier by checking the model for which vendor to use, then initiating a TextQuerier
func MigrateOldChatConfig ¶ added in v1.11.0
MigrateOldChatConfig by first checking if file chatConfig exists, then reading + copying the fields to the new text.Configrations struct. Then write the file as textConfig. For the remaining fields, create vendor specific gpt4TurboPreview struct and write that to gpt4TurboPreview.json.
func QueryCommand ¶ added in v1.11.0
func QueryCommand(deps QueryCommandDeps) *internal.Command
QueryCommand builds the query command.
Types ¶
type AgentSettings ¶ added in v1.10.23
type AgentSettings struct {
Logger *slog.Logger
Level slog.Level
RuneLimit int
UsageRecorder pub_models.CallUsageRecorder
ToolCallRecorder pub_models.ToolCallRecorder
// StrictMcpStartup marks the servers in Configurations.McpServers as
// explicitly requested and load-bearing: a startup failure fails the whole
// setup with a typed error instead of warn-and-degrade. pkg/agent sets it
// when WithMcpServers was used; the CLI path never sets it (worklog
// 2026-09-05-error-propagation, D13).
StrictMcpStartup bool
}
AgentSettings carries agent-only runtime settings into the querier. It is never serialized to textConfig.json; a nil Logger or recorder disables that channel (worklog 2026-08-15-agent-slog-output, D7).
type CallUsageRecorder ¶ added in v1.10.4
type CallUsageRecorder = pub_models.CallUsageRecorder
The recorder types are canonical in pkg/text/models (worklog 26-08-11-clai-prometheus-metrics). The aliases keep internal references unchanged while exposing the seam to embedded consumers through the public package.
type CompletedModelCall ¶ added in v1.10.4
type CompletedModelCall = pub_models.CompletedModelCall
The recorder types are canonical in pkg/text/models (worklog 26-08-11-clai-prometheus-metrics). The aliases keep internal references unchanged while exposing the seam to embedded consumers through the public package.
type Configurations ¶
type Configurations struct {
Model string `json:"model"`
SystemPrompt string `json:"system-prompt"`
Raw bool `json:"raw"`
UseTools bool `json:"use-tools"`
UseSkills bool `json:"-"`
// CmdModePrompt is kept only for backwards compatibility with old config files.
// It is ignored by clai as the `cmd` command has been removed.
CmdModePrompt string `json:"cmd-mode-prompt"`
// ToolOutputRuneLimit limits the amount of runes a tool may return
// before clai truncates the output. Zero means no limit.
ToolOutputRuneLimit int `json:"tool-output-rune-limit"`
SaveReplyAsConv bool `json:"save-reply-as-prompt"`
ConfigDir string `json:"-"`
StdinReplace string `json:"-"`
Stream bool `json:"-"`
ReplyMode bool `json:"-"`
// DirReplyMode marks a directory-scoped reply (-dre). Unlike a plain -re (which
// forks a fresh promoted id and must not record), -dre continues the bound
// conversation in place, so it DOES upsert the directory history (see finalizer).
DirReplyMode bool `json:"-"`
Glob string `json:"-"`
InitialChat pub_models.Chat `json:"-"`
UseProfile string `json:"-"`
ProfilePath string `json:"-"`
ProfileUseSkillsSet bool `json:"-"`
RequestedToolGlobs []string `json:"-"`
// CmdBan is the per-run command ban list for the freetext command tools
// (cmd, async_cmd; legacy aliases freetext_command, async_cmd_run).
// Commands matching an entry are
// refused before spawn (worklog 2026-08-02-cmd-ban-list). The cascade is
// purely additive: textConfig.json + profile cmd-ban + flag -cmd-ban +
// agent API; no source removes another source's bans.
CmdBan []string `json:"cmd-ban"`
// SummarizeConversations launches the in-flight conversation summarizer
// on a conversation's first persist (worklog
// 2026-09-09-conversation-summaries, D12).
SummarizeConversations bool `json:"summarize-conversations"`
// SummaryModel is the model the conversation summarizer uses; empty means
// the resolution ladder (D22). The migrate tag surfaces the empty key in
// upgraded files, so it must never carry omitempty.
SummaryModel string `json:"summary-model" migrate:"true"`
// SummaryJoinTimeout bounds the finalizer's wait for the in-flight
// summary; zero means defaultSummaryJoinTimeout.
SummaryJoinTimeout time.Duration `json:"-"`
// CostWarnf receives the cost manager's and the cost enricher's
// warnings; nil keeps ancli.Warnf. A querier whose output is discarded
// routes them to its own trace (worklog
// 2026-09-09-conversation-summaries, R2-03).
CostWarnf func(format string, a ...any) `json:"-"`
// ErrOut replaces the process stderr for the querier's MCP log sink; nil
// keeps os.Stderr. A querier that may outlive its caller (the abandoned
// in-flight summarizer) must never read the global stream (R2-09).
ErrOut io.Writer `json:"-"`
// TrustInput is the trusted input reader the composition root threads
// through setup (the same reader skills.TrustPrompter reads from); the
// authorization phase's printed-URL fallback reads a pasted
// authorization code from it rather than the process standard input
// directly (worklog 2026-10-02-mcp-connection-cost, phase 5). Nil
// disables the paste fallback for the run.
TrustInput io.Reader `json:"-"`
// ShellContext is a context definition name for ASC (auto-append shell context).
// When non-empty, clai will load <configDir>/shellContexts/<name>.json and insert
// the rendered template block into the system prompt instead of the user prompt.
ShellContext string `json:"-"`
// PostProccessedPrompt which has had it\'s strings replaced etc
PostProccessedPrompt string `json:"-"`
// These are to allow tools to be injected via public package.
Tools []pub_models.LLMTool `json:"-"`
McpServers []pub_models.McpServer `json:"-"`
// SkipAmbientMcpServers skips discovery of <configDir>/mcpServers/*.json;
// servers passed in McpServers still start and keep their explicit or
// ambient posture (worklog 2026-09-09-conversation-summaries, D18).
SkipAmbientMcpServers bool `json:"-"`
BaseTools map[string]pub_models.LLMTool `json:"-"`
RegisteredTools map[string]struct{} `json:"-"`
MaxToolCalls *int `json:"max-tool-calls,omitempty"`
// Stoploss is the token stoploss policy for the run. Nil or
// MaxTokens <= 0 disables the stoploss (no handover injection).
Stoploss *Stoploss `json:"stoploss,omitempty"`
// AgentSettings carries agent-only runtime settings (slog logger, level,
// rune cap, recorder hooks) from pkg/agent into the querier. json:"-"
// keeps it out of textConfig.json and the presence-based config merge
// (worklog 2026-08-15-agent-slog-output, D7).
AgentSettings *AgentSettings `json:"-"`
// Out writer. Normally stdout, but may also be a file when invoked as a package
Out io.Writer `json:"-"`
// ResponseFormat configures structured output (json_object, json_schema).
// When nil, no response_format is sent (defaults to text).
ResponseFormat *pub_models.ResponseFormat `json:"-"`
SkillsDescriptor string `json:"-"`
SkillLoader SkillLoader `json:"-"`
// UseLookback gates the opt-in conversation lookback: the recent-conversations
// descriptor plus the search/inspect/read tools. Resolved as
// CLI (-lb/-lookback boolean) > profile (use_lookback) > default (false), and is only
// effectively true when the CWD binding has recorded history.
UseLookback bool `json:"use_lookback"`
// LookbackDescriptor is the dir-scoped recent-conversations block injected into
// the system prompt when the lookback is active.
LookbackDescriptor string `json:"-"`
// LookbackCWD is the canonical session working directory captured at setup,
// used as the default search anchor for search_conversations.
LookbackCWD string `json:"-"`
// OutputIsTerminal decides the auth-timeout parameter's
// terminal-dependent default: a mid-run authorization wait is bounded
// when the session's output is a terminal, fail-fast otherwise, unless
// a server's auth_timeout_seconds overrides it either way (worklog
// 2026-10-02-mcp-connection-cost, phase 6, D22). nil means unset:
// NewQuerier then derives it from the querier's own terminal check and
// assigns it, without overwriting a caller-supplied value (R2-09). A
// caller that cannot observe its own terminal-ness (every pkg/agent SDK
// consumer, whose writer is always io.Discard) sets this explicitly
// through pkg/agent.WithOutputIsTerminal instead of relying on the
// writer-derived default.
OutputIsTerminal *bool `json:"-"`
}
Configurations used to setup the requirements of text models
func SetupQuerier ¶ added in v1.11.0
func SetupQuerier(ctx context.Context, confDir string, tf internal.TextFlags, args []string, trustInput io.Reader) (models.Querier, *Configurations, error)
SetupQuerier composes the full text-querier path: config load, flag and profile cascades, glob/tool/skill/lookback setup, prompt construction and vendor routing. trustInput is the reader for interactive skill-trust prompts (the composition root passes the wizard's input source; text cannot import setup).
func (*Configurations) LoadResponseFormat ¶ added in v1.10.9
func (c *Configurations) LoadResponseFormat(path string) error
LoadResponseFormat loads a response_format JSON file from disk and sets it on the configuration. The file must follow the response_format shape. This layer is vendor-agnostic: when a vendor can explain a rejection better it does so through generic.ErrorHandler (see the -rf call site).
func (Configurations) OutputIsTerminalOrDefault ¶ added in v1.11.2
func (c Configurations) OutputIsTerminalOrDefault() bool
OutputIsTerminalOrDefault resolves OutputIsTerminal: the explicit value when set, false (the conservative, fail-fast posture) when unset.
func (*Configurations) ProfileOverrides ¶
func (c *Configurations) ProfileOverrides() error
func (*Configurations) SetupInitialChat ¶
func (c *Configurations) SetupInitialChat(args []string) error
SetupInitialChat by doing all sorts of organically grown stuff. Don\'t touch this code too closely. Something will break, most likely.
func (Configurations) UsingProfile ¶
func (c Configurations) UsingProfile() bool
type CostManager ¶ added in v1.10.4
type CostManager interface {
// Start the cost manager. Will return with errors on errCh and close readyCh once there is
// a token price for the model
Start(ctx context.Context) (readyCh <-chan struct{}, errCh <-chan error)
// Enrich the chat with cost for the chat
Enrich(chat pub_models.Chat) (pub_models.Chat, error)
}
type LoadedSkillRuntime ¶ added in v1.10.10
type ModelNamer ¶ added in v1.10.4
type ModelNamer interface {
ModelName() string
}
type ModelStepResult ¶ added in v1.10.4
type ModelStepResult struct {
AssistantText string
ToolCalls []pub_models.Call
Usage *pub_models.Usage
StopRequested bool
EndedNormally bool
}
type Profile ¶
type Profile struct {
Name string `json:"name"`
Model string `json:"model"`
UseTools bool `json:"use_tools"`
UseSkills *bool `json:"use_skills,omitempty"`
Tools []string `json:"tools"`
// CmdBan merges onto the file base in ProfileOverrides. An omitted or
// explicitly empty list contributes nothing (purely additive cascade,
// worklog 2026-08-02-cmd-ban-list R1-04 revision).
CmdBan []string `json:"cmd-ban,omitempty"`
Prompt string `json:"prompt"`
SaveReplyAsConv *bool `json:"save-reply-as-conv,omitempty"`
McpServers map[string]pub_models.McpServer `json:"mcp_servers,omitempty"`
ShellContext string `json:"shell_context,omitempty"`
UseLookback *bool `json:"use_lookback,omitempty"`
}
Profile which allows for specialized ai configurations for specific tasks
type Querier ¶
type Querier[C models.StreamCompleter] struct { Raw bool Model C // contains filtered or unexported fields }
func NewQuerier ¶
func NewQuerier[C models.StreamCompleter](ctx context.Context, userConf Configurations, dfault C) (Querier[C], error)
func (*Querier[C]) Query ¶
Query using the underlying model to stream completions and then print the output from the model to stdout. Blocking operation.
func (*Querier[C]) SetSummarizer ¶ added in v1.11.1
func (q *Querier[C]) SetSummarizer(s models.Summarizer)
SetSummarizer attaches the in-flight conversation summarizer.
func (*Querier[C]) SuppressCompletionNotification ¶ added in v1.10.19
func (*Querier[C]) TextQuery ¶
func (q *Querier[C]) TextQuery(ctx context.Context, chat pub_models.Chat) (pub_models.Chat, error)
type QueryCommandDeps ¶ added in v1.11.0
type QueryCommandDeps struct {
ConfigPrep func() (confDir string, err error)
TrustInput func() io.Reader
// ApplyMediaOverrides hands the media-tool flags to the domains owning
// those tools (internal/audio today), which text must not import.
ApplyMediaOverrides func(internal.MediaToolFlags) error
// NewSummarizer builds the in-flight conversation summarizer; nil or a
// constructor error attaches nothing (worklog
// 2026-09-09-conversation-summaries, D26).
NewSummarizer func(confDir string) (models.Summarizer, error)
}
QueryCommandDeps are the composition-root collaborators the query command needs: config prep lives in internal/setup (which imports text, so text cannot call it), and TrustInput hands over the wizard's mutable input reader for skill-trust prompts, read at setup time.
type QuerySession ¶ added in v1.10.4
type QuerySession struct {
Chat pub_models.Chat
StartedAt time.Time
FinishedAt time.Time
PendingText strings.Builder
PendingReasoning strings.Builder
FinalAssistantText string
FinalReasoningText string
FinalUsage *pub_models.Usage
CompletedCalls []CompletedModelCall
ToolCallsUsed int
// PostHandoverToolCallsUsed counts tool calls made after the token
// stoploss handover fired. It is the phase counter for the
// max-tool-calls-after-handover wrap-up budget: the handover starts a
// fresh allowance that pre-handover consumption never eats into.
PostHandoverToolCallsUsed int
// HandoverRequested is set once the token stoploss has injected the
// handover user message. It switches the tool-budget phase: the
// wrap-up allowance (max-tool-calls-after-handover) replaces the
// pre-handover max-tool-calls budget.
HandoverRequested bool
ShouldSaveReply bool
Raw bool
Finalized bool
Failed bool
SawAnyText bool
SawStopEvent bool
LikelyGeminiPreview bool
Line string
LineCount int
}
func (*QuerySession) AppendPendingText ¶ added in v1.10.4
func (s *QuerySession) AppendPendingText(token string)
func (*QuerySession) FlushPendingTextToFinal ¶ added in v1.10.4
func (s *QuerySession) FlushPendingTextToFinal()
func (*QuerySession) PendingTextString ¶ added in v1.10.4
func (s *QuerySession) PendingTextString() string
func (*QuerySession) ResetPendingText ¶ added in v1.10.4
func (s *QuerySession) ResetPendingText()
type ShellContextDefinition ¶
type ShellContextDefinition struct {
Shell string `json:"shell"`
TimeoutMS int `json:"timeout_ms"`
TimedOutValue string `json:"timed_out_value"`
ErrorValue string `json:"error_value"`
Template string `json:"template"`
Vars map[string]string `json:"vars"`
}
func LoadShellContextDefinition ¶
func LoadShellContextDefinition(configDir, name string) (ShellContextDefinition, error)
LoadShellContextDefinition reads <configDir>/shellContexts/<name>.json.
Templates written by older setup editors carry literal "\n" sequences (architecture/shell-context.md, "Newline encoding"): rehydrate them here so both encodings render identically. Var commands are never rehydrated, since a shell command may legitimately contain literal backslash escapes.
type ShellContextRenderer ¶
type ShellContextRenderer struct {
RunVar func(ctx context.Context, shell, cmd string, timeout time.Duration) (string, error)
Warnf func(format string, args ...any)
}
func (ShellContextRenderer) Render ¶
func (r ShellContextRenderer) Render(ctx context.Context, ctxName string, def ShellContextDefinition) (string, error)
type SkillLoader ¶ added in v1.10.10
type SkillLoader interface {
LoadSkill(context.Context, string, string, map[string]pub_models.LLMTool) (LoadedSkillRuntime, error)
}
type Stoploss ¶ added in v1.10.20
type Stoploss struct {
MaxTokens int `json:"max-tokens"`
MaxTokensHandoverMsg string `json:"max-tokens-handover-instructions"`
MaxToolCallsAfterHandover int `json:"max-tool-calls-after-handover" migrate:"true"`
}
Stoploss is the token stoploss policy. MaxTokens <= 0 disables the stoploss. MaxTokensHandoverMsg is the user message injected into the chat when the limit is crossed; empty means the default message (DefaultHandoverInstructions). MaxToolCallsAfterHandover is the wrap-up tool-call budget for the post-handover phase: <= 0 (or absent) means unlimited tool calls after the handover fires. It carries migrate:"true" so the presence-based config migration surfaces it in upgraded files as an explicit 0 (and never omitempty, or the rewrite would drop the zero).
func (*Stoploss) HandoverInstructions ¶ added in v1.10.20
HandoverInstructions returns the message to inject when the stoploss limit is crossed: the configured message, or DefaultHandoverInstructions when the configured message is empty.
type ToolCall ¶ added in v1.10.22
type ToolCall = pub_models.ToolCall
The recorder types are canonical in pkg/text/models (worklog 26-08-11-clai-prometheus-metrics). The aliases keep internal references unchanged while exposing the seam to embedded consumers through the public package.
type ToolCallRecorder ¶ added in v1.10.22
type ToolCallRecorder = pub_models.ToolCallRecorder
The recorder types are canonical in pkg/text/models (worklog 26-08-11-clai-prometheus-metrics). The aliases keep internal references unchanged while exposing the seam to embedded consumers through the public package.
type ToolDecision ¶ added in v1.10.4
type ToolDecision struct {
PatchedCall pub_models.Call
SkipExecution bool
TreatAsReturnToUser bool
}
Source Files
¶
- call_usage_recorder.go
- cmd.go
- conf.go
- conf_profile.go
- conf_shell_context_patch.go
- config_migration.go
- cost_enricher.go
- create_querier.go
- debug_trace.go
- finalizer.go
- mcp_http_schema_cache.go
- mcp_log_sink.go
- mcp_oauth.go
- mcp_startup.go
- querier.go
- querier_cmd_mode.go
- querier_setup.go
- querier_setup_tools.go
- querier_tool.go
- session.go
- session_runner.go
- setup_querier.go
- shell_context.go
- shell_context_apply.go
- slog_output.go
- stoploss.go
- summary_launch.go
- tail_buffer.go
- tool_executor.go
- tool_executor_lookback.go
- tooling.go
- vendor_error_handler.go