Documentation
¶
Overview ¶
Package locagent implements a LocAgent-style LLM-driven agent loop on top of code-graph's structural primitives. The published LocAgent (ACL 2025, arXiv 2503.09089) achieves 92.7% file-level localization on Loc-Bench by letting an LLM iteratively call graph-traversal tools (search_entity, explore_graph_structure, read_code_file).
This package provides the equivalent in-process: an LLM session with tool-use enabled, where the tool implementations directly call into our internal/store + internal/ranking + internal/localize packages without round-tripping through MCP. The agent runs in the MCP server process; results return as a single MCP response.
Tradeoffs vs the primitives-only code_localize tool:
- Adds an LLM call dependency (ANTHROPIC_API_KEY) at query time
- Higher latency per query (multi-turn, ~5-15 turns typical)
- Should achieve LocAgent's published F1 lift over substring-only primitives because the LLM does intelligent narrowing the primitives can't do alone
Use code_localize for fast/deterministic primitives and code_localize_agent for accuracy-prioritized localization.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RewriteIssue ¶
func RewriteIssue(ctx context.Context, client *anthropic.Client, issue string) (string, int, int, error)
RewriteIssue calls the LLM to extract a focused list of search terms from a verbose issue description. Returns the rewritten query plus the input/output tokens consumed (so the caller can attribute cost).
On any error, returns the original issue with a non-nil error. Caller is expected to fall back to the original on error rather than failing the whole run.
Types ¶
type EpisodicHit ¶
type EpisodicHit struct {
QName string `json:"qualified_name"` // {org}/{repo}#{pr}
Title string `json:"title"`
ChangedFiles []string `json:"changed_files"`
Score float64 `json:"score"`
MergedAt string `json:"merged_at,omitempty"`
}
EpisodicHit summarizes one retrieved past resolution for the prompt.
type LocalizedEntity ¶
type LocalizedEntity struct {
QualifiedName string `json:"qualified_name"`
FilePath string `json:"file_path"`
Reason string `json:"reason,omitempty"`
}
LocalizedEntity is the agent's final output entry. Format mirrors localize.LocalizedEntity for caller compatibility.
type Result ¶
type Result struct {
Entities []LocalizedEntity `json:"entities"`
Iterations [][]LocalizedEntity `json:"iterations,omitempty"`
Turns int `json:"turns"`
StopReason string `json:"stop_reason"` // "finalized", "max_turns", "no_finalize", "error"
Transcript []TranscriptEntry `json:"transcript,omitempty"`
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
}
Result is the full agent run result, including a transcript of tool calls for auditability.
Iterations holds per-iteration entity lists when the agent runs in multi-iteration mode (LOCAGENT_ITERATIONS>=2). Iterations[i] is the finalized entity list of the i-th independent agent run BEFORE MRR aggregation. Empty for single-shot runs (iter=1) and for legacy callers that don't need per-iteration data. Surfaced for the Plan 4 Loc-Bench failure-audit pipeline so the audit can distinguish:
- "rescued by iter 2" (entity appears only in Iterations[1])
- "iter 1 was sufficient" (entity appears in Iterations[0] at high rank)
- "iter 2 inconsistent with iter 1" (top-1 differs across iterations — signal that the case is on the boundary of agent capability).
The protocol is independent-sampling-with-MRR-aggregation: each iteration calls runOnce() with identical args (no conditioning on prior iteration results); aggregateByMRR(Iterations, topK) produces Entities. See runWithConsistency for the implementation.
func Run ¶
Run executes the agent. With LOCAGENT_ITERATIONS=N (default 2, max 3), runs the agent N times at temperature 1.0 (Anthropic API default) and aggregates results by mean reciprocal rank (MRR), matching the LocAgent paper's self-consistency strategy (Section 3.2, "Confidence Estimation Based on Consistency"). With N=1, behaves as a single-iteration agent (legacy behavior).
MRR aggregation: for each iteration, an entity at rank R contributes 1/(R+1) to its score. Final score = sum across iterations. Ties broken by iteration count (entities seen in more iterations rank higher).
Cost: scales linearly with N — 2 iterations = ~2x tokens.
type TranscriptEntry ¶
type TranscriptEntry struct {
Turn int `json:"turn"`
Kind string `json:"kind"` // "tool_call" | "tool_result" | "text" | "finalize"
ToolName string `json:"tool_name,omitempty"`
Summary string `json:"summary"` // human-readable summary of input/output
}
TranscriptEntry is one step of the agent's execution.