Documentation
¶
Overview ¶
Package ai defines the provider interface and shared types for the AI subsystem. Both structured git-ops (commit messages, conflict resolution) and the conversational chat box consume these types.
Index ¶
- Constants
- func QuoteUntrusted(s string) string
- func SanitizeBranchName(name string) string
- func SanitizeCommitMessage(msg string) string
- func SanitizeExternalContent(content string) string
- func SanitizeFilePath(path string) string
- type AIProvider
- type AuditEntry
- type AuditLogger
- type Builder
- func (b *Builder) ForBisect(ctx context.Context, good, bad string) (GitContext, error)
- func (b *Builder) ForChangelog(ctx context.Context, fromRef, toRef string) (GitContext, error)
- func (b *Builder) ForChat(ctx context.Context) (GitContext, error)
- func (b *Builder) ForCommit(ctx context.Context) (GitContext, error)
- func (b *Builder) ForConflict(ctx context.Context, files []string) (GitContext, error)
- func (b *Builder) ForPR(ctx context.Context, targetBranch string) (GitContext, error)
- func (b *Builder) ForRebase(ctx context.Context, onto string) (GitContext, error)
- func (b *Builder) ForReview(ctx context.Context, opts git.DiffOpts) (GitContext, error)
- func (b *Builder) ForSplit(ctx context.Context, commitHash string) (GitContext, error)
- type ChatMessage
- type ClaudeProvider
- func (p *ClaudeProvider) Available(_ context.Context) (bool, error)
- func (p *ClaudeProvider) Close() error
- func (p *ClaudeProvider) Complete(ctx context.Context, req CompletionRequest) (CompletionResponse, error)
- func (p *ClaudeProvider) CompleteStream(ctx context.Context, req CompletionRequest) (<-chan StreamChunk, error)
- func (p *ClaudeProvider) Name() string
- type CompletionRequest
- type CompletionResponse
- type ConflictFile
- type ConflictRegion
- type CopilotProvider
- func (p *CopilotProvider) Available(ctx context.Context) (bool, error)
- func (p *CopilotProvider) Close() error
- func (p *CopilotProvider) Complete(ctx context.Context, req CompletionRequest) (CompletionResponse, error)
- func (p *CopilotProvider) CompleteStream(ctx context.Context, req CompletionRequest) (<-chan StreamChunk, error)
- func (p *CopilotProvider) Name() string
- type GitContext
- type Redactor
- type Registry
- type StreamChunk
- type TokenUsage
- type ToolCall
- type ToolDefinition
Constants ¶
const ( ExternalDataStart = "[EXTERNAL_DATA_START]" ExternalDataEnd = "[EXTERNAL_DATA_END]" )
Boundary markers used to delimit external/untrusted content embedded in LLM prompts. The markers are intentionally distinctive so that the model can recognise where data stops and instructions resume.
const RedactedPlaceholder = "[REDACTED]"
RedactedPlaceholder is the replacement text for detected secrets.
Variables ¶
This section is empty.
Functions ¶
func QuoteUntrusted ¶
QuoteUntrusted quotes a single-line value for safe embedding in a prompt. It uses Go's %q verb which escapes control characters and wraps in double quotes, preventing any embedded content from altering prompt structure.
func SanitizeBranchName ¶
SanitizeBranchName removes control characters from a branch name and validates that it is non-empty. Branch names in prompts are additionally quoted via QuoteUntrusted at the call site.
func SanitizeCommitMessage ¶
SanitizeCommitMessage removes control characters (except newlines) from a commit message and truncates it if it exceeds maxCommitMessageLen.
func SanitizeExternalContent ¶
SanitizeExternalContent wraps untrusted, potentially multi-line content (issue bodies, PR descriptions, file contents, diffs) in boundary markers with a preamble instructing the model to treat it as data.
Any occurrences of the boundary markers within the content itself are neutralised to prevent delimiter injection attacks.
func SanitizeFilePath ¶
SanitizeFilePath removes control characters from a file path.
Types ¶
type AIProvider ¶
type AIProvider interface {
// Name returns a human-readable identifier for this provider (e.g. "openai").
Name() string
// Available reports whether the provider is configured and reachable.
Available(ctx context.Context) (bool, error)
// Complete sends a one-shot completion request and blocks until the full
// response is ready.
Complete(ctx context.Context, req CompletionRequest) (CompletionResponse, error)
// CompleteStream sends a completion request and returns a channel that
// delivers incremental chunks. The channel is closed when the response is
// finished or an error occurs.
CompleteStream(ctx context.Context, req CompletionRequest) (<-chan StreamChunk, error)
// Close releases any resources held by the provider (HTTP clients, etc.).
Close() error
}
AIProvider is the interface every AI backend (OpenAI, Anthropic, Ollama, …) must implement. It covers one-shot completions, streaming completions, and lifecycle management.
type AuditEntry ¶
type AuditEntry struct {
Timestamp time.Time `json:"timestamp"`
Operation string `json:"operation"` // "conflict_resolve", "commit_message", "chat", etc.
Provider string `json:"provider"` // "copilot", "claude"
Result string `json:"result"` // "accepted", "rejected", "modified", "error"
Error string `json:"error,omitempty"`
FilesSent []string `json:"files_sent"` // Paths sent to AI
Redactions int `json:"redactions"` // Number of redactions applied
TokensIn int `json:"tokens_in"`
TokensOut int `json:"tokens_out"`
}
AuditEntry captures a single AI operation.
type AuditLogger ¶
type AuditLogger struct {
// contains filtered or unexported fields
}
AuditLogger records every AI operation for transparency and debugging. Entries are appended to a structured log file with automatic rotation.
func NewAuditLogger ¶
func NewAuditLogger(path string) (*AuditLogger, error)
NewAuditLogger creates a logger writing to the given path. If path is empty, uses default: ~/.config/grut/ai-audit.log
func (*AuditLogger) Close ¶
func (a *AuditLogger) Close() error
Close flushes and closes the underlying file.
func (*AuditLogger) Log ¶
func (a *AuditLogger) Log(entry AuditEntry) error
Log appends an entry to the audit log. Thread-safe.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder constructs GitContext objects from repository state, managing token budgets to stay within provider limits.
func NewBuilder ¶
NewBuilder creates a context builder with the given git client, optional redactor (may be nil to skip redaction), and maximum token budget. A maxTokens of 0 or negative means no limit.
Security: if redactor is nil, a default redactor with built-in secret patterns is created to ensure fail-closed behavior — file contents are never sent to AI providers without redaction (CWE-200).
func (*Builder) ForBisect ¶
ForBisect builds context for bisect analysis. Includes diff between good/bad and candidate commits.
func (*Builder) ForChangelog ¶
ForChangelog builds context for changelog generation. Includes all commits between two refs.
func (*Builder) ForChat ¶
func (b *Builder) ForChat(ctx context.Context) (GitContext, error)
ForChat builds lightweight context for the chat box. Includes only branch name and working tree status — no diffs or file contents.
func (*Builder) ForCommit ¶
func (b *Builder) ForCommit(ctx context.Context) (GitContext, error)
ForCommit builds context for commit message generation. Includes staged diff, recent commits (for style matching), and branch name.
func (*Builder) ForConflict ¶
ForConflict builds context for merge conflict resolution. Includes conflict file contents, branch histories, and surrounding context.
func (*Builder) ForPR ¶
ForPR builds context for PR description generation. Includes diff vs target branch and all branch commits.
func (*Builder) ForRebase ¶
ForRebase builds context for rebase assistance. Includes commits to rebase and their diffs.
type ChatMessage ¶
type ChatMessage struct {
// Role is one of "user", "assistant", "tool", or "system".
Role string
// Content is the textual body of the message.
Content string
// ToolID identifies the tool invocation this message responds to. Set
// when Role is "tool".
ToolID string
// ToolCalls is populated when Role is "assistant" and the model invokes
// one or more tools.
ToolCalls []ToolCall
}
ChatMessage represents a single turn in a multi-turn conversation.
type ClaudeProvider ¶
type ClaudeProvider struct {
// contains filtered or unexported fields
}
ClaudeProvider implements AIProvider using the Anthropic Claude API via the anthropic-sdk-go SDK.
func NewClaudeProvider ¶
func NewClaudeProvider(model string, maxTokens int) *ClaudeProvider
NewClaudeProvider creates a ClaudeProvider. model defaults to claude-sonnet-4-20250514 when empty; maxTokens defaults to 8192 when <= 0. The SDK reads ANTHROPIC_API_KEY from the environment automatically.
func (*ClaudeProvider) Available ¶
func (p *ClaudeProvider) Available(_ context.Context) (bool, error)
Available reports true when the ANTHROPIC_API_KEY env var is set.
func (*ClaudeProvider) Close ¶
func (p *ClaudeProvider) Close() error
Close releases resources. The SDK client is stateless, so this is a no-op.
func (*ClaudeProvider) Complete ¶
func (p *ClaudeProvider) Complete(ctx context.Context, req CompletionRequest) (CompletionResponse, error)
Complete sends a one-shot completion request and blocks until the full response is ready.
func (*ClaudeProvider) CompleteStream ¶
func (p *ClaudeProvider) CompleteStream(ctx context.Context, req CompletionRequest) (<-chan StreamChunk, error)
CompleteStream sends a completion request and returns a channel that delivers incremental StreamChunks. The channel is closed when the response completes or an error occurs.
type CompletionRequest ¶
type CompletionRequest struct {
// Operation identifies the high-level task, e.g. "conflict_resolve",
// "commit_message", or "chat".
Operation string
// SystemPrompt is the system-level instruction prepended to the
// conversation.
SystemPrompt string
// GitContext supplies structured repository state for git-ops callers.
GitContext GitContext
// Messages carries a multi-turn conversation for the chat box.
Messages []ChatMessage
// UserPrompt is a single user turn, used by git-ops callers that don't
// need multi-turn history.
UserPrompt string
// Tools lists function-calling tool definitions available to the model.
Tools []ToolDefinition
// MaxTokens caps the number of tokens the model may generate.
MaxTokens int
// Temperature controls output randomness (0 = deterministic, 1 = creative).
Temperature float64
}
CompletionRequest carries everything the provider needs to produce a response. Fields are selectively populated depending on the caller: git-ops fill GitContext; the chat box fills Messages.
type CompletionResponse ¶
type CompletionResponse struct {
// Metadata holds provider-specific key/value pairs (model name, request
// ID, etc.).
Metadata map[string]string
// Content is the model-generated text.
Content string
// FinishReason indicates why generation stopped:
// "stop", "length", "tool_calls", or "error".
FinishReason string
// ToolCalls contains any function calls the model wants to invoke.
ToolCalls []ToolCall
// TokensUsed reports input/output token counts for the request.
TokensUsed TokenUsage
}
CompletionResponse is the provider's reply to a CompletionRequest.
type ConflictFile ¶
type ConflictFile struct {
// Path is the repository-relative file path.
Path string
// OursContent is the full file content from the current branch.
OursContent string
// TheirsContent is the full file content from the incoming branch.
TheirsContent string
// BaseContent is the full file content from the common ancestor.
BaseContent string
// ConflictMarkers lists the individual conflict regions within the file.
ConflictMarkers []ConflictRegion
}
ConflictFile describes a single file with unresolved merge conflicts.
type ConflictRegion ¶
type ConflictRegion struct {
// Ours is the text from the current branch within this region.
Ours string
// Theirs is the text from the incoming branch within this region.
Theirs string
// Base is the text from the common ancestor within this region, if
// available (diff3 style).
Base string
// StartLine is the 1-based line where the conflict begins.
StartLine int
// EndLine is the 1-based line where the conflict ends (inclusive).
EndLine int
}
ConflictRegion marks a single conflict hunk inside a file.
type CopilotProvider ¶
type CopilotProvider struct {
// contains filtered or unexported fields
}
--------------------------------------------------------------------------- CopilotProvider --------------------------------------------------------------------------- CopilotProvider implements AIProvider using the official GitHub Copilot SDK (github.com/github/copilot-sdk/go). It manages a Copilot CLI client that is lazily started on first use and creates per-request sessions.
Tool-calling note: The SDK manages tool execution internally via registered handlers. Since the AIProvider interface provides ToolDefinition without execution logic, tool definitions in CompletionRequest.Tools are not forwarded to the SDK. Callers relying on intermediate ToolCalls in the CompletionResponse should be aware this provider does not produce them.
func NewCopilotProvider ¶
func NewCopilotProvider(model string) (*CopilotProvider, error)
NewCopilotProvider creates a CopilotProvider backed by the Copilot SDK. If model is empty the SDK / server selects a default model. Auth is handled by the SDK: if GITHUB_TOKEN is set it is passed directly; otherwise the SDK falls back to gh CLI / stored OAuth tokens.
func (*CopilotProvider) Available ¶
func (p *CopilotProvider) Available(ctx context.Context) (bool, error)
Available reports whether the Copilot SDK can authenticate. It lazily starts the underlying CLI client and queries auth status.
func (*CopilotProvider) Close ¶
func (p *CopilotProvider) Close() error
Close stops the Copilot CLI client if it was started.
func (*CopilotProvider) Complete ¶
func (p *CopilotProvider) Complete(ctx context.Context, req CompletionRequest) (CompletionResponse, error)
Complete sends a one-shot completion request via the Copilot SDK and blocks until the full response is ready.
func (*CopilotProvider) CompleteStream ¶
func (p *CopilotProvider) CompleteStream(ctx context.Context, req CompletionRequest) (<-chan StreamChunk, error)
CompleteStream sends a streaming completion request and returns a channel that delivers incremental chunks. The channel is closed when the response finishes or an error occurs.
type GitContext ¶
type GitContext struct {
// RepoRoot is the absolute path to the repository root.
RepoRoot string
// CurrentBranch is the checked-out branch.
CurrentBranch string
// TargetBranch is the branch being merged into or compared against.
TargetBranch string
// Diffs contains file-level diff information (staged or unstaged).
Diffs []git.FileDiff
// Conflicts lists files with unresolved merge conflicts.
Conflicts []ConflictFile
// Log holds recent commit history for context.
Log []git.Commit
// FileContents maps file paths to their full text, used when the model
// needs to see entire files rather than just diffs.
FileContents map[string]string
// Status lists the working tree and index status of tracked files.
Status []git.FileStatus
}
GitContext provides structured repository state to AI-powered git operations. Callers populate only the fields relevant to the operation (e.g. Diffs for commit messages, Conflicts for merge resolution).
type Redactor ¶
type Redactor struct {
// contains filtered or unexported fields
}
Redactor sanitises content before it reaches AI providers, removing secrets and excluding sensitive files.
func NewRedactor ¶
NewRedactor creates a Redactor from the given user-supplied file-exclusion patterns, merged with the built-in patterns that are always active. All secret-matching regexes are compiled once at construction time.
func (*Redactor) RedactContent ¶
RedactContent scans content for secret patterns and replaces each match with [REDACTED]. It returns the sanitised content and the total number of redactions performed.
func (*Redactor) ShouldExcludeFile ¶
ShouldExcludeFile reports whether the given file path matches any exclusion pattern and should not be sent to AI. Matching is performed against the base name of the path, so "config/.env.local" is caught by the ".env.*" pattern.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry manages registered AI providers and resolves the active one based on configuration (primary + fallback).
func NewRegistry ¶
NewRegistry creates a registry configured with the given AI settings. It does NOT register any providers — call Register() to add them.
func (*Registry) Get ¶
func (r *Registry) Get(ctx context.Context) (AIProvider, error)
Get returns the first available provider: tries primary, then fallback. Returns an error if neither is registered or available.
func (*Registry) GetByName ¶
func (r *Registry) GetByName(name string) (AIProvider, bool)
GetByName returns a specific provider by name, or false if not found.
func (*Registry) PrimaryName ¶
PrimaryName returns the configured primary provider name.
func (*Registry) Register ¶
func (r *Registry) Register(name string, p AIProvider)
Register adds a provider under the given name. If a provider with that name already exists, it is replaced.
type StreamChunk ¶
type StreamChunk struct {
// Err carries any error that terminated the stream.
Err error
// TokensUsed is set only on the final chunk (Done == true).
TokensUsed *TokenUsage
// Delta contains the new text fragment.
Delta string
// ToolCalls contains incremental tool-call data, if any.
ToolCalls []ToolCall
// Done is true on the final chunk.
Done bool
}
StreamChunk is a single incremental piece of a streaming response.
type TokenUsage ¶
type TokenUsage struct {
// InputTokens is the number of prompt tokens sent.
InputTokens int
// OutputTokens is the number of tokens the model generated.
OutputTokens int
}
TokenUsage tracks how many tokens a request consumed.
type ToolCall ¶
type ToolCall struct {
// Arguments are the parsed function arguments.
Arguments map[string]any
// ID is a provider-assigned identifier used to correlate tool results
// back to the call.
ID string
// Name is the function to invoke (must match a ToolDefinition.Name).
Name string
}
ToolCall represents a single function invocation requested by the model.
type ToolDefinition ¶
type ToolDefinition struct {
// Parameters is a JSON Schema object describing the function's arguments.
Parameters map[string]any
// Name is the function name the model references in a ToolCall.
Name string
// Description explains what the tool does, helping the model decide when
// to call it.
Description string
}
ToolDefinition describes a function the model may call.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package middleware provides AIGitClient, a transparent wrapper around git.GitClient that intercepts operations with AI enhancements while delegating all other methods to the inner client.
|
Package middleware provides AIGitClient, a transparent wrapper around git.GitClient that intercepts operations with AI enhancements while delegating all other methods to the inner client. |
|
Package ops implements AI-powered git operations that compose the core provider and context types from the ai package.
|
Package ops implements AI-powered git operations that compose the core provider and context types from the ai package. |