Documentation
¶
Overview ¶
Package agent implements LLM-driven test failure analysis using pluggable LLM providers. The LLMProvider and LLMSession interfaces (defined in provider.go) abstract the underlying LLM backend; built-in implementations exist for the GitHub Copilot SDK (this file) and the Anthropic Claude API (claude_provider.go).
Index ¶
- Constants
- func BuildDomainPrompt() (string, error)
- func BuildInitialPrompt(manifest, testError, testOutput, siblingTests, dataDir string, ...) string
- func BuildReviewPrompt(rendered string) string
- func BuildSystemMessageConfig() (*copilot.SystemMessageConfig, error)
- func BuildSystemPrompt() (string, error)
- func NewKustoTool(client KustoClient) copilot.Tool
- func RenderMarkdown(chain *HydratedChain, testName string) string
- func TableToMarkdown(t *tabular.Table) string
- func Validate(chain *HydratedChain) error
- type ADXKustoClient
- type AgentConfig
- type AnalyzeOptions
- type AnalyzeResult
- type CachingKustoClient
- type ChainLink
- type ClaudeConfig
- type ClaudeProvider
- type ClaudeSession
- type CopilotClient
- type DiscoveryItem
- type DraftChain
- type HydratedChain
- type HydratedDiscovery
- type HydratedLink
- type HydratedProofItem
- type Hydrator
- type KustoClient
- type LLMProvider
- type LLMSession
- type ProofItem
- type ProviderSessionConfig
- type Session
- type SessionConfig
- type ToolDefinition
- type ValidationContext
- type ValidationProblem
- type ValidationResult
Constants ¶
const ( // CopilotAuthModeLoggedIn uses the developer's GitHub CLI session. CopilotAuthModeLoggedIn = "logged-in" // CopilotAuthModeToken reads a GitHub token from a file. CopilotAuthModeToken = "token" // CopilotAuthModeBYOK uses an Azure Entra token against a model endpoint. CopilotAuthModeBYOK = "byok" )
const ( // DefaultClaudeModel is the default Anthropic model used when no // model override is specified. DefaultClaudeModel = "claude-sonnet-4-20250514" // ClaudeBackendAPI selects the direct Anthropic API backend (requires an API key). ClaudeBackendAPI = "api" // ClaudeBackendVertex selects Google Vertex AI as the backend // (uses Application Default Credentials for keyless auth). ClaudeBackendVertex = "vertex" )
const FirstChainQuestion = "Why did this test fail?"
FirstChainQuestion is the required question for the first link in the causal chain.
const IdentityPrompt = "You are a senior SRE specializing in Azure Red Hat OpenShift (ARO-HCP). " +
"Your task is to perform root-cause analysis on failed e2e tests by examining " +
"diagnostic data, querying Azure Data Explorer (Kusto), and reading source code."
IdentityPrompt is the shared identity section text used by all providers. Callers pass this to ProviderSessionConfig.IdentityPrompt so prompt composition is centralized in the caller rather than scattered across providers.
const TonePrompt = "Be precise, evidence-driven, and thorough. Every claim must be backed by " +
"data from tool calls. Prefer structured output over prose. When uncertain, " +
"investigate further rather than speculate."
TonePrompt is the shared tone section text used by all providers. Callers pass this to ProviderSessionConfig.TonePrompt so prompt composition is centralized in the caller rather than scattered across providers.
Variables ¶
This section is empty.
Functions ¶
func BuildDomainPrompt ¶
BuildDomainPrompt returns only the domain-specific content (system.md, references, exemplars) without the identity or tone preamble. This is the preferred function for callers that pass the prompt through the provider-neutral ProviderSessionConfig — each provider is responsible for incorporating the shared identity and tone sections in its native format (e.g. Copilot section overrides, Claude system message prefix).
func BuildInitialPrompt ¶
func BuildInitialPrompt(manifest, testError, testOutput, siblingTests, dataDir string, worktreePaths map[string]string) string
BuildInitialPrompt creates the initial user prompt for an analysis run, including the manifest, test logs, and available source code worktrees.
func BuildReviewPrompt ¶
BuildReviewPrompt constructs the prompt sent to the agent during review rounds, asking it to review and re-emit the analysis.
func BuildSystemMessageConfig ¶
func BuildSystemMessageConfig() (*copilot.SystemMessageConfig, error)
BuildSystemMessageConfig assembles a Copilot-specific SystemMessageConfig in "customize" mode. It uses the same shared content as BuildSystemPrompt but packages it into Copilot SDK section overrides.
Section strategy (from design review):
- SectionIdentity: replace with our domain identity
- SectionTone: replace with our analysis tone
- SectionCodeChangeRules: remove (agent doesn't write code)
- SectionToolInstructions: keep (SDK manages tool descriptions)
- SectionToolEfficiency: keep
- SectionSafety: keep
- SectionCustomInstructions: append domain content (references, exemplars, output schema)
func BuildSystemPrompt ¶
BuildSystemPrompt returns the complete system prompt as a plain string, suitable for providers that accept a single system prompt (e.g. Claude). It combines the identity, tone, and domain-specific content (system.md, references, exemplars) into one string.
func NewKustoTool ¶
func NewKustoTool(client KustoClient) copilot.Tool
NewKustoTool creates a kusto_query Copilot SDK tool backed by the given client.
func RenderMarkdown ¶
func RenderMarkdown(chain *HydratedChain, testName string) string
RenderMarkdown produces a low-fidelity markdown document from a hydrated analysis chain. This is used to show the agent the full rendered output — including query result tables — so it can review narrative coherence, evidence quality, and depth before finalizing.
func TableToMarkdown ¶
TableToMarkdown renders a tabular.Table as a markdown table. If the table is nil or has no columns, the string "(no results)" is returned.
func Validate ¶
func Validate(chain *HydratedChain) error
Validate checks hydration-specific requirements on a hydrated chain: - Every kusto proof has a non-empty share URI (generated during hydration) This is a lightweight post-hydration check; structural validation (non-empty summary, claims, proof items, etc.) is performed earlier by ValidateDraft.
Types ¶
type ADXKustoClient ¶
type ADXKustoClient struct {
// contains filtered or unexported fields
}
ADXKustoClient wraps an Azure Data Explorer client to implement KustoClient. It executes queries against a specific database and formats results as markdown.
func NewADXKustoClient ¶
func NewADXKustoClient(credential azcore.TokenCredential, clusterURI, database string) (*ADXKustoClient, error)
NewADXKustoClient creates a KustoClient that queries a specific ADX cluster and database. The client is created using the provided credential and cluster URI. The caller is responsible for calling Close when done.
func (*ADXKustoClient) Close ¶
func (c *ADXKustoClient) Close() error
Close releases the underlying Kusto client resources.
type AgentConfig ¶
type AgentConfig struct {
// AuthMode is one of "logged-in", "token", or "byok".
AuthMode string
// GitHubTokenFile is the path to a file containing a GitHub token (token mode).
GitHubTokenFile string
// ModelEndpoint is the Azure AI Foundry endpoint URL (byok mode).
ModelEndpoint string
// ModelDeployment is the model deployment name (byok mode).
ModelDeployment string
// AzureCredential is used to acquire Entra tokens for BYOK sessions.
AzureCredential azcore.TokenCredential
// Model overrides the default model for Copilot sessions.
Model string
// MaxRounds is the maximum number of tool-call rounds per session.
MaxRounds int
// Verbosity is the log verbosity level from the CLI. When >= 5,
// the Copilot CLI subprocess is started with --log-level=debug and
// all session events are traced.
Verbosity int
}
AgentConfig configures the agent's auth and model settings. This is the superset of configuration options — callers populate only the fields relevant to their auth mode.
type AnalyzeOptions ¶
type AnalyzeOptions struct {
// Manifest is the raw manifest.json content.
Manifest []byte
// TestName is the name of the failed test (used for rendering).
TestName string
// TestError is the content of test_logs/error.log, or empty.
TestError string
// TestOutput is the content of test_logs/output.log, or empty.
TestOutput string
// SiblingTests is the content of sibling_tests.json, or empty.
SiblingTests string
// DataDir is the root of the structured data directory.
DataDir string
// WorktreePaths maps repository names to local filesystem paths.
WorktreePaths map[string]string
// KustoCluster is the Kusto cluster URI for hydration share links.
KustoCluster string
// KustoDatabase is the Kusto database name.
KustoDatabase string
// MaxValidationRounds is the maximum number of parse/validate correction
// rounds per validate-draft cycle. Zero defaults to 10.
MaxValidationRounds int
// ReviewRounds is the number of review passes. Zero defaults to 3.
ReviewRounds int
// NodeConsoleLogs maps console log filenames to their contents.
// Used for validating and hydrating node_console_log proof items.
NodeConsoleLogs map[string]string
// NodeConsoleLogURLs maps console log filenames to artifact download URLs.
// Used for populating ArtifactURL on hydrated node_console_log proof items.
NodeConsoleLogURLs map[string]string
}
AnalyzeOptions configures a single analysis run.
type AnalyzeResult ¶
type AnalyzeResult struct {
// HydratedChain is the fully validated and hydrated causal chain.
HydratedChain *HydratedChain
// DraftChain is the last validated draft before the final hydration.
DraftChain *DraftChain
}
AnalyzeResult contains the output of a successful analysis.
func Analyze ¶
func Analyze(ctx context.Context, logger logr.Logger, session LLMSession, kustoClient KustoClient, opts AnalyzeOptions) (*AnalyzeResult, error)
Analyze runs the full agentic analysis loop: initial prompt, validate-draft, hydrate, and review rounds. It requires an already-created Session and KustoClient. The caller is responsible for session lifecycle (create, save conversation, delete/disconnect) and Kusto client lifecycle (create, close).
The function sends the initial prompt, validates and corrects the agent's output, hydrates proof items with real query results and code excerpts, then runs review rounds where the agent sees its rendered output and can refine it.
type CachingKustoClient ¶
type CachingKustoClient struct {
// contains filtered or unexported fields
}
CachingKustoClient wraps a KustoClient and caches successful query results in memory, keyed by the KQL query string. This avoids re-running identical queries across validation and hydration rounds. Only successful results are cached; errors are always retried against the underlying client.
func NewCachingKustoClient ¶
func NewCachingKustoClient(delegate KustoClient) *CachingKustoClient
NewCachingKustoClient wraps the given client with an in-memory query cache.
type ChainLink ¶
type ChainLink struct {
Question string `json:"question"`
Answer string `json:"answer"`
Notes string `json:"notes,omitempty"`
Proof []ProofItem `json:"proof"`
}
ChainLink is one link in the causal why-chain. Each link poses a "why?" question and provides an answer backed by proof. The first link's question is always "Why did this test fail?"; subsequent questions follow naturally from the previous answer.
type ClaudeConfig ¶
type ClaudeConfig struct {
// APIKeyFile is the path to a file containing the Anthropic API key.
// If empty, the ANTHROPIC_API_KEY environment variable is used.
// Only used when Backend is "api" (the default).
APIKeyFile string
// Model is the Anthropic model to use (e.g. "claude-sonnet-4-20250514").
// Defaults to DefaultClaudeModel.
Model string
// Backend selects the API backend: "api" for the direct Anthropic
// API (default) or "vertex" for Google Vertex AI.
Backend string
// VertexProject is the GCP project ID. Required when Backend is "vertex".
VertexProject string
// VertexRegion is the GCP region (e.g. "us-east5"). Required when Backend is "vertex".
VertexRegion string
}
ClaudeConfig holds configuration for the Anthropic Claude provider.
type ClaudeProvider ¶
type ClaudeProvider struct {
// contains filtered or unexported fields
}
ClaudeProvider implements LLMProvider using the Anthropic Messages API. It manages a single anthropic.Client and creates ClaudeSession instances for individual analysis runs.
func NewClaudeProvider ¶
func NewClaudeProvider(ctx context.Context, cfg *ClaudeConfig) (*ClaudeProvider, error)
NewClaudeProvider creates a ClaudeProvider configured with the given API key and model settings. When the Vertex AI backend is selected, ctx is used to initialise Google Application Default Credentials.
func (*ClaudeProvider) CreateProviderSession ¶
func (p *ClaudeProvider) CreateProviderSession(ctx context.Context, logger logr.Logger, cfg ProviderSessionConfig) (LLMSession, error)
CreateProviderSession creates a new ClaudeSession for an analysis run. It concatenates cfg.IdentityPrompt, cfg.TonePrompt, and cfg.SystemPrompt into a single system message. All three fields are set centrally by the caller (e.g. analyze_cmd.go).
func (*ClaudeProvider) Stop ¶
func (p *ClaudeProvider) Stop() error
Stop is a no-op for the Claude provider — the HTTP client has no long-running subprocess to shut down.
type ClaudeSession ¶
type ClaudeSession struct {
// contains filtered or unexported fields
}
ClaudeSession implements LLMSession using the Anthropic Messages API. It maintains the conversation history and handles the tool-use loop internally within SendAndWait.
func (*ClaudeSession) Delete ¶
func (s *ClaudeSession) Delete(_ context.Context) error
Delete is a no-op for the Claude provider — there is no server-side session state to delete.
func (*ClaudeSession) Disconnect ¶
func (s *ClaudeSession) Disconnect() error
Disconnect is a no-op for the Claude provider — there is no persistent session state to disconnect from.
func (*ClaudeSession) SaveConversation ¶
func (s *ClaudeSession) SaveConversation(path string)
SaveConversation writes the conversation history to a JSON file.
func (*ClaudeSession) SendAndWait ¶
SendAndWait sends a user prompt and blocks until Claude finishes responding, including any tool-use rounds. It implements the tool-use loop: when Claude returns tool_use content blocks, the session calls the corresponding handler, sends the tool_result back, and waits for the next response.
func (*ClaudeSession) SessionID ¶
func (s *ClaudeSession) SessionID() string
SessionID returns the unique identifier for this session.
type CopilotClient ¶
type CopilotClient struct {
// contains filtered or unexported fields
}
CopilotClient wraps a copilot.Client that manages the Copilot CLI process. It implements the LLMProvider interface via CreateProviderSession, and also exposes a Copilot-specific CreateSession for callers that need direct access to copilot.SessionConfig. One instance is created per process lifetime.
func NewCopilotClient ¶
func NewCopilotClient(cfg *AgentConfig) (*CopilotClient, error)
NewCopilotClient creates a CopilotClient configured for the given auth mode. The underlying CLI process is started lazily on first session creation (AutoStart defaults to true).
func (*CopilotClient) CreateProviderSession ¶
func (c *CopilotClient) CreateProviderSession(ctx context.Context, logger logr.Logger, cfg ProviderSessionConfig) (LLMSession, error)
CreateProviderSession creates a new Copilot session from a provider-neutral configuration. This is the LLMProvider interface implementation. It converts ToolDefinition values to copilot.Tool values and builds a Copilot SystemMessageConfig from the provider-neutral system prompt.
func (*CopilotClient) CreateSession ¶
func (c *CopilotClient) CreateSession(ctx context.Context, logger logr.Logger, cfg SessionConfig) (*Session, error)
CreateSession creates a new Copilot session for an analysis run.
func (*CopilotClient) Stop ¶
func (c *CopilotClient) Stop() error
Stop shuts down the Copilot CLI process and releases all resources.
type DiscoveryItem ¶
type DiscoveryItem struct {
// Label is a human-readable description of what this discovery item establishes.
Label string `json:"label"`
// KQL is an agent-authored Kusto query whose results establish provenance
// for constants used in proof queries.
KQL string `json:"kql"`
}
DiscoveryItem is an agent-authored KQL query with a label, used to establish provenance for constants in proof queries that are not already covered by the pre-gathered data directory (which is embedded automatically during hydration).
type DraftChain ¶
type DraftChain struct {
RootCause string `json:"root_cause"`
Summary string `json:"summary"`
Notes string `json:"notes,omitempty"`
Discovery []DiscoveryItem `json:"discovery,omitempty"`
Chain []ChainLink `json:"chain"`
Suggestions []string `json:"suggestions,omitempty"`
}
DraftChain is the structured output the agent must produce as its final message. This is the pre-hydration format — KQL queries have no share URIs or result tables yet.
func ParseDraftChain ¶
func ParseDraftChain(output string) (*DraftChain, error)
ParseDraftChain parses the agent's final output as a DraftChain.
func ValidateDraftLoop ¶
func ValidateDraftLoop( ctx context.Context, logger logr.Logger, session LLMSession, kustoClient KustoClient, vc *ValidationContext, output string, maxRounds int, ) (*DraftChain, string, error)
ValidateDraftLoop parses and validates the agent's output, sending correction feedback for up to maxRounds iterations. It returns the validated draft chain and the raw output string (which may have been updated by agent corrections).
type HydratedChain ¶
type HydratedChain struct {
RootCause string `json:"root_cause"`
Summary string `json:"summary"`
Notes string `json:"notes,omitempty"`
Discovery []HydratedDiscovery `json:"discovery,omitempty"`
Chain []HydratedLink `json:"chain"`
Suggestions []string `json:"suggestions,omitempty"`
}
HydratedChain extends DraftChain with query results and share URIs.
type HydratedDiscovery ¶
type HydratedDiscovery struct {
Directory string `json:"directory,omitempty"`
Label string `json:"label"`
KQL string `json:"kql"`
Table *tabular.Table `json:"table,omitempty"`
}
HydratedDiscovery is a single leaf query directory from a discovery path, hydrated with its README summary, KQL, share URI, and parsed query results.
type HydratedLink ¶
type HydratedLink struct {
Question string `json:"question"`
Answer string `json:"answer"`
Notes string `json:"notes,omitempty"`
Proof []HydratedProofItem `json:"proof"`
}
HydratedLink is a chain link with hydrated proof items.
type HydratedProofItem ¶
type HydratedProofItem struct {
ProofItem
// Kusto proof fields populated during hydration
Table *tabular.Table `json:"table,omitempty"`
// Code proof field populated during hydration by reading the worktree
CodeExcerpt string `json:"code_excerpt,omitempty"`
// Log proof field populated during hydration by extracting lines from test logs
// or node console logs.
LogExcerpt string `json:"log_excerpt,omitempty"`
// ArtifactURL is the download link for node console log proofs, populated
// during hydration from the manifest's node_console_logs entries.
ArtifactURL string `json:"artifact_url,omitempty"`
}
HydratedProofItem extends ProofItem with fields populated during hydration.
type Hydrator ¶
type Hydrator struct {
// contains filtered or unexported fields
}
Hydrator takes a draft chain produced by the agent and populates share URIs and result tables for all Kusto proofs by re-running the queries deterministically.
func NewHydrator ¶
func NewHydrator(kustoClient KustoClient, kustoEndpoint, kustoDatabase string, worktreePaths map[string]string, testError, testOutput string, nodeConsoleLogs, nodeConsoleLogURLs map[string]string, dataDir string) *Hydrator
NewHydrator creates a Hydrator with the given Kusto client, cluster details, worktree paths for resolving code proof excerpts, test log contents for resolving log proof excerpts, node console log contents and URLs for resolving node_console_log proof excerpts, and data directory for resolving discovery paths.
func (*Hydrator) Hydrate ¶
func (h *Hydrator) Hydrate(ctx context.Context, draft *DraftChain) (*HydratedChain, error)
Hydrate takes a DraftChain and produces a HydratedChain by re-running all KQL queries and generating share URIs.
type KustoClient ¶
type KustoClient interface {
// Query executes a KQL query and returns the result as a tabular.Table.
Query(ctx context.Context, kql string) (*tabular.Table, error)
}
KustoClient is the interface for executing KQL queries against Azure Data Explorer.
type LLMProvider ¶
type LLMProvider interface {
// CreateProviderSession creates a new LLM session configured for
// analysis. The provider translates the provider-neutral
// ProviderSessionConfig into its native format (e.g. copilot
// SessionConfig sections, Anthropic MessageNewParams).
CreateProviderSession(ctx context.Context, logger logr.Logger, cfg ProviderSessionConfig) (LLMSession, error)
// Stop shuts down the provider and releases all resources.
Stop() error
}
LLMProvider creates and manages LLM sessions for a specific backend. Implementations handle provider-specific authentication, client lifecycle, and session creation. The two built-in implementations are CopilotClient (GitHub Copilot SDK) and ClaudeProvider (Anthropic API).
type LLMSession ¶
type LLMSession interface {
// SendAndWait sends a user prompt and blocks until the model finishes
// responding, including any tool-use rounds. Returns the final
// assistant text content.
SendAndWait(ctx context.Context, prompt string) (string, error)
// SaveConversation writes the conversation history to a JSON file at
// the given path. This is best-effort: implementations should log
// errors rather than return them.
SaveConversation(path string)
// SessionID returns a unique identifier for this session.
SessionID() string
// Disconnect releases in-memory session resources while preserving
// on-disk state for potential later resumption.
Disconnect() error
// Delete permanently removes all session data.
Delete(ctx context.Context) error
}
LLMSession is a single conversation with an LLM. Implementations handle provider-specific message protocols, tool-use loops, and conversation state management. The Analyze function and ValidateDraftLoop accept this interface rather than a concrete session type.
type ProofItem ¶
type ProofItem struct {
Type string `json:"type"` // "kusto", "code", "log"
// Kusto proof fields
KQL string `json:"kql,omitempty"`
Note string `json:"note,omitempty"`
// Code proof fields (File is also used by node_console_log log proofs to
// specify which console log file to reference)
Repo string `json:"repo,omitempty"`
File string `json:"file,omitempty"`
Lines [2]int `json:"lines,omitempty"` // 1-indexed, inclusive; used by code and log proofs
// Log proof fields
Source string `json:"source,omitempty"` // "error", "output", or "node_console_log"
}
ProofItem is evidence supporting a chain link claim.
type ProviderSessionConfig ¶
type ProviderSessionConfig struct {
// IdentityPrompt carries the identity/role instructions that tell
// the model who it is (e.g. "You are a senior SRE …").
IdentityPrompt string
// TonePrompt carries the tone/style instructions that tell the
// model how to respond (e.g. "Be precise, evidence-driven …").
TonePrompt string
// SystemPrompt carries domain-specific content (system.md, references,
// exemplars) built by BuildDomainPrompt.
SystemPrompt string
// Tools are provider-neutral tool definitions. Each provider converts
// them to its native tool format (e.g. copilot.Tool, Anthropic tool
// params).
Tools []ToolDefinition
// WorkingDirectory is the workspace root. Providers that support
// file-access tools scope operations to this directory.
WorkingDirectory string
// Model overrides the provider's default model for this session.
// When empty, the provider uses its configured default.
Model string
}
ProviderSessionConfig holds provider-neutral configuration for creating an LLM session. Each LLMProvider translates these fields into its native format during CreateProviderSession.
The prompt is split into three parts so the caller can assemble the full prompt centrally while each provider applies them in its native format:
- IdentityPrompt: who the model is (role, specialization).
- TonePrompt: how the model should respond (style, evidence rules).
- SystemPrompt: domain-specific content (system.md, references, exemplars) built by BuildDomainPrompt.
For example, the Copilot provider maps IdentityPrompt and TonePrompt to SDK section overrides, while the Claude provider concatenates all three into a single system message.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session wraps a copilot.Session for a single analysis run. It snapshots the full conversation history after every successful SendAndWait so that the conversation can be saved even if the CLI process is no longer available (e.g. after ctrl-C kills the subprocess).
func (*Session) Disconnect ¶
Disconnect releases in-memory session resources. Session state is preserved on disk and can be resumed later.
func (*Session) SaveConversation ¶
SaveConversation writes the most recent conversation snapshot to a JSON file at the given path. Because messages are snapshotted after every successful turn, this works even after the CLI subprocess has exited. This is best-effort: errors are logged but not returned.
func (*Session) SendAndWait ¶
SendAndWait sends a prompt to the session and blocks until the agent is idle. If ctx is cancelled, the in-flight work is aborted. Returns the final assistant message content.
type SessionConfig ¶
type SessionConfig struct {
// WorkingDirectory is the workspace root for the Copilot session.
// Tool operations (read_file, grep, bash, glob) are relative to this directory.
WorkingDirectory string
// SystemMessage configures system prompt customization.
SystemMessage *copilot.SystemMessageConfig
// Tools are custom tools (e.g. kusto_query) registered on this session.
Tools []copilot.Tool
// Model overrides the default model for this session.
Model string
}
SessionConfig configures a new analysis session.
type ToolDefinition ¶
type ToolDefinition struct {
// Name is the tool's unique identifier (e.g. "kusto_query").
Name string
// Description explains what the tool does. This is shown to the model
// to help it decide when and how to use the tool.
Description string
// ParamSchema is the JSON Schema for the tool's input parameters,
// serialized as a JSON object. Example:
//
// {"type":"object","properties":{"kql":{"type":"string",
// "description":"The KQL query to execute."}},"required":["kql"]}
ParamSchema json.RawMessage
// Handler executes the tool with the given JSON-encoded parameters
// and returns the text result. The context carries cancellation and
// tracing information from the provider's session.
Handler func(ctx context.Context, params json.RawMessage) (string, error)
}
ToolDefinition is a provider-neutral description of a tool that can be called by the LLM during a conversation. Each LLMProvider converts this to its native tool format.
The ParamSchema field holds a standard JSON Schema object describing the tool's input parameters. The Handler function is called when the model invokes the tool, receiving the raw JSON arguments and returning a text result for the model to consume.
func NewKustoToolDefinition ¶
func NewKustoToolDefinition(client KustoClient) ToolDefinition
NewKustoToolDefinition creates a provider-neutral ToolDefinition for the kusto_query tool. This is the preferred factory for use with LLMProvider implementations; each provider converts it to its native tool format.
type ValidationContext ¶
type ValidationContext struct {
// ValidRepos is the set of repository names that have source code worktrees available.
ValidRepos map[string]bool
// WorktreePaths maps repository names to local filesystem paths for their git worktrees.
WorktreePaths map[string]string
// DataDir is the root of the gathered data directory (for discovery path validation).
DataDir string
// TestError is the contents of the test error.log file.
TestError string
// TestOutput is the contents of the test output.log file.
TestOutput string
// NodeConsoleLogs maps console log filenames to their contents.
// Used for validating node_console_log proof items.
NodeConsoleLogs map[string]string
}
ValidationContext holds the data needed to validate a DraftChain beyond structural checks — file system paths, log contents, and worktree locations.
type ValidationProblem ¶
type ValidationProblem struct {
// Category is a machine-readable identifier for the type of problem.
Category string `json:"category"`
// Chain is the chain link index where the problem was found, or -1 for top-level issues.
Chain int `json:"chain"`
// Proof is the proof item index (0-based) where the problem was found, or -1 if N/A.
Proof int `json:"proof"`
// Detail is the human-readable description of the problem.
Detail string `json:"detail"`
}
ValidationProblem describes a single structured validation issue found in a DraftChain.
type ValidationResult ¶
type ValidationResult struct {
// Problems is the list of validation issues found.
Problems []ValidationProblem
// Feedback is the human-readable text suitable for sending to the agent as
// a correction prompt. It is empty when there are no problems.
Feedback string
}
ValidationResult holds the structured output of ValidateDraft.
func ValidateDraft ¶
func ValidateDraft(ctx context.Context, client KustoClient, draft *DraftChain, vc *ValidationContext) ValidationResult
ValidateDraft checks a DraftChain for structural problems and executes every KQL snippet against the provided Kusto client. It validates log proof line ranges against actual log contents, code proof line ranges against actual source files, and discovery paths against the data directory. It returns a ValidationResult containing structured problems and a human-readable feedback string for sending back to the agent.