Documentation
¶
Index ¶
- Constants
- Variables
- func EnrichComponents(ctx context.Context, p LLMProvider, components []CodeNode, ...) (map[string]ComponentEnrichment, error)
- func FetchTEIDimension(baseURL string) (int, error)
- func PingFalkorDB(addr string) error
- func PingOllama(baseURL, apiKey string) error
- func PingTEI(baseURL string) error
- func PluginsByLanguage() map[Language]*LanguagePlugin
- func RegisterLanguage(p *LanguagePlugin)
- func RegisteredExtensions() []string
- func VerifyComponentImports(root string, components []ComponentNode, pairs map[string]map[string]int) map[string]bool
- type AnalysisService
- func (a *AnalysisService) DeadCandidates(ctx context.Context, limit int) ([]DeadCandidate, DeadCodeSummary, error)
- func (a *AnalysisService) Hubs(ctx context.Context, t HubThresholds, limit int) ([]HubScore, error)
- func (a *AnalysisService) Impact(ctx context.Context, symbol string, maxDepth int) (*ImpactReport, error)
- type BuilderOption
- type CallGraph
- type CallSite
- type CallerTier
- type CodeChatResult
- type CodeContext
- type CodeContextBuilder
- type CodeContextBuilderParams
- type CodeEdge
- type CodeNode
- type ComponentEnrichment
- type ComponentImpact
- type ComponentNode
- type ComponentScope
- type Config
- type DeadCandidate
- type DeadCodeSummary
- type Embedder
- type Engine
- type ErrEmbeddingFailed
- type ErrFalkorDBUnavailable
- type ErrInvalidQuery
- type ErrLLMUnavailable
- type ErrRetrievalTimeout
- type ErrSymbolNotFound
- type ErrTEIUnavailable
- type ErrWorkspaceNotFound
- type ExtractResult
- type Extractor
- type FalkorClient
- func (c *FalkorClient) Close() error
- func (c *FalkorClient) CreateCodeEdge(_ context.Context, edge CodeEdge) error
- func (c *FalkorClient) CreateCodeEdgeBatch(_ context.Context, edges []CodeEdge) error
- func (c *FalkorClient) DeleteCodeByFile(_ context.Context, filePath string) error
- func (c *FalkorClient) DeleteOrphanComponents(_ context.Context) (int64, error)
- func (c *FalkorClient) GetCallGraph(_ context.Context, qualifiedName, direction string, depth int, maxResults int) (*CallGraph, error)
- func (c *FalkorClient) GetComponentTree(ctx context.Context, workspaceRoot string) ([]ComponentNode, error)
- func (c *FalkorClient) GetComponentsSymbolSummaries(_ context.Context) (map[string][]string, error)
- func (c *FalkorClient) GetFileHashes(_ context.Context) (map[string]string, error)
- func (c *FalkorClient) Graph() *falkordb.Graph
- func (c *FalkorClient) Name() string
- func (c *FalkorClient) Schema() error
- func (c *FalkorClient) SearchCodeBM25(_ context.Context, queryText, kind string, scopeComponentNames []string, ...) ([]CodeNode, error)
- func (c *FalkorClient) SearchCodeSemantic(_ context.Context, embedding []float64, kind string, ...) ([]CodeNode, error)
- func (c *FalkorClient) UpdateComponentMeta(_ context.Context, filePath, newName, role, description string) error
- func (c *FalkorClient) UpsertCodeNode(_ context.Context, node CodeNode) (string, error)
- func (c *FalkorClient) UpsertCodeNodeBatch(_ context.Context, nodes []CodeNode) ([]string, error)
- type GoQualifier
- type HubScore
- type HubThresholds
- type ImpactReport
- type IndexRequest
- type IndexResult
- type Indexer
- type IndexerOption
- type JSQualifier
- type LLMEvent
- type LLMEventType
- type LLMMessage
- type LLMParams
- type LLMProvider
- type Language
- type LanguagePlugin
- type OllamaProvider
- type ParseResult
- type Parser
- type PythonQualifier
- type RerankClient
- type RiskLevel
- type RustQualifier
- type SymbolQualifier
- type SymbolRef
- type TEIEmbedder
Constants ¶
const CodeChatSystemPrompt = `` /* 418-byte string literal not displayed */
CodeChatSystemPrompt instructs the synthesis LLM to answer strictly from retrieved code context. Exported so downstream chat implementations (TUI, Terminalator) share one prompt instead of drifting copies.
const (
DefaultRRFK = 60
)
Retrieval tuning constants.
const DefaultVectorDimension = 768
DefaultVectorDimension is the fallback embedding dimension used when the caller does not specify one. It matches the BAAI/bge-base-en-v1.5 TEI model.
Variables ¶
var GoPlugin = &LanguagePlugin{ Name: LangGo, Extensions: []string{".go"}, NewParser: func() (*Parser, error) { return NewParser(LangGo) }, NewExtractor: func() (*Extractor, error) { return NewExtractor(LangGo) }, Qualifier: &GoQualifier{}, RuntimeEntryNames: []string{"main", "init"}, TestFileSuffixes: []string{"_test.go"}, FuncDefPattern: `(?m)^\s*func\s+(?:\([^)]*\)\s*)?%s\s*\(`, }
var JavaScriptPlugin = &LanguagePlugin{ Name: LangJavaScript, Extensions: []string{".js", ".jsx", ".mjs"}, NewParser: func() (*Parser, error) { return NewParser(LangJavaScript) }, NewExtractor: func() (*Extractor, error) { return NewExtractor(LangJavaScript) }, Qualifier: &JSQualifier{}, RuntimeEntryNames: nil, TestFileSuffixes: []string{ ".test.js", ".test.jsx", ".test.mjs", ".spec.js", ".spec.jsx", ".spec.mjs", }, FuncDefPattern: `(?m)^\s*(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s*%s\s*\(`, }
var PythonPlugin = &LanguagePlugin{ Name: LangPython, Extensions: []string{".py", ".pyw"}, NewParser: func() (*Parser, error) { return NewParser(LangPython) }, NewExtractor: func() (*Extractor, error) { return NewExtractor(LangPython) }, Qualifier: &PythonQualifier{}, RuntimeEntryNames: nil, TestFileSuffixes: []string{"_test.py"}, TestFilePrefixes: []string{"test_"}, FuncDefPattern: `(?m)^\s*(?:async\s+)?def\s+%s\s*\(`, }
var RustPlugin = &LanguagePlugin{ Name: LangRust, Extensions: []string{".rs"}, NewParser: func() (*Parser, error) { return NewParser(LangRust) }, NewExtractor: func() (*Extractor, error) { return NewExtractor(LangRust) }, Qualifier: &RustQualifier{}, RuntimeEntryNames: []string{"main"}, TestFileSuffixes: nil, FuncDefPattern: `(?m)^\s*(?:pub\s+)?fn\s+%s\b`, }
Functions ¶
func EnrichComponents ¶
func EnrichComponents( ctx context.Context, p LLMProvider, components []CodeNode, symbolSummaries map[string][]string, ) (map[string]ComponentEnrichment, error)
EnrichComponents calls the LLM once with a batched prompt to generate human-readable names, roles, and descriptions for each component. Returns a map from directory path → enrichment. On failure the caller should keep the path-based names.
func FetchTEIDimension ¶
FetchTEIDimension discovers the model's embedding dimension by sending a single probe embedding request and measuring the returned vector length.
func PingFalkorDB ¶
PingFalkorDB verifies that a FalkorDB instance is reachable at addr. It returns a clear error for connection failures vs non-FalkorDB servers.
func PingOllama ¶
PingOllama verifies the Ollama endpoint is reachable. It checks the /api/tags endpoint (local) or simply that the base URL responds. Model availability is checked at runtime when the user actually sends a chat request.
func PluginsByLanguage ¶ added in v0.2.0
func PluginsByLanguage() map[Language]*LanguagePlugin
PluginsByLanguage returns one plugin per registered language (extensions share a plugin; the map is deduplicated by Name).
func RegisterLanguage ¶
func RegisterLanguage(p *LanguagePlugin)
RegisterLanguage registers a language plugin for all its file extensions.
func RegisteredExtensions ¶
func RegisteredExtensions() []string
RegisteredExtensions returns all registered file extensions.
func VerifyComponentImports ¶ added in v0.2.0
func VerifyComponentImports(root string, components []ComponentNode, pairs map[string]map[string]int) map[string]bool
VerifyComponentImports checks each claimed component dependency (fromComponent → toComponent) against the claiming component's sources: does ANY file under the from-directory import the to-package's path?
Import path derivation (Go-first): module name from go.mod at root + "/" + toDir relative path. Root-level components map to the bare module. If go.mod is absent (non-Go workspace), nothing can be corroborated — every pair is returned as verified=true to preserve legacy behavior, since dropping real edges is worse than tolerating phantoms.
Returns a set of "from/to" keys that passed corroboration.
Types ¶
type AnalysisService ¶ added in v0.2.0
type AnalysisService struct {
// contains filtered or unexported fields
}
AnalysisService runs structural analyses over an existing code graph. Safe to share across goroutines; the underlying client pools connections.
workspaceRoot enables text-level verification: the code graph only sees call expressions, so method-values (`mux.Handle("/", s.chat)`), runtime entry points (main/init), and interface dispatch are invisible to it and would otherwise surface as false "dead" candidates. When a workspace root is provided, candidates are confirmed against raw text references before being reported.
func NewAnalysisService ¶ added in v0.2.0
func NewAnalysisService(client *FalkorClient, workspaceRoot string) *AnalysisService
NewAnalysisService creates an analyzer bound to a connected client. Pass workspaceRoot (the indexed project path) to enable text-level verification of dead-code candidates; pass "" to skip it.
func (*AnalysisService) DeadCandidates ¶ added in v0.2.0
func (a *AnalysisService) DeadCandidates(ctx context.Context, limit int) ([]DeadCandidate, DeadCodeSummary, error)
DeadCandidates lists unexported functions/methods with zero inbound CALLS edges AND — when a workspace root was provided — zero textual references in the indexed sources. Two-stage verification kills the dominant false positives that pure call-graph analysis cannot see:
- runtime entry points (main/init) are excluded up front
- method-value registrations (`mux.Handle("/", s.chat)`) carry no CALLS edge but DO contain the name as text → dropped as referenced
- same-file helpers referenced before/after definition → dropped
Remaining candidates survived both structural AND raw-text checks; they still warrant a human glance (implicit interface satisfaction leaves no textual trace), but precision jumps from ~7% to near-total.
func (*AnalysisService) Hubs ¶ added in v0.2.0
func (a *AnalysisService) Hubs(ctx context.Context, t HubThresholds, limit int) ([]HubScore, error)
Hubs returns callable symbols ranked by total degree (fan-in + fan-out), most-connected first. Symbols below t.Medium total degree are omitted; pass limit ≤ 0 for the default 25.
func (*AnalysisService) Impact ¶ added in v0.2.0
func (a *AnalysisService) Impact(ctx context.Context, symbol string, maxDepth int) (*ImpactReport, error)
Impact computes the blast radius of changing a symbol: every function/ method that transitively calls it, within maxDepth hops, grouped by depth and by owning component, with a transparent risk rating.
Resolution: pass an exact qualified_name, or a bare name — bare names are unambiguous only when exactly one definition exists; otherwise an error lists the candidates so the caller can disambiguate (never guess).
type BuilderOption ¶
type BuilderOption func(*CodeContextBuilder)
BuilderOption configures optional CodeContextBuilder behavior.
func WithBuilderLogger ¶
func WithBuilderLogger(l *slog.Logger) BuilderOption
WithBuilderLogger sets a logger for retrieval diagnostics (search failures, degenerate embeddings, rerank problems). If unset, the builder runs silent.
func WithWorkspaceRoot ¶ added in v0.2.0
func WithWorkspaceRoot(root string) BuilderOption
WithWorkspaceRoot enables import-corroboration for component dependency lists fetched during retrieval scope resolution.
type CallGraph ¶
type CallGraph struct {
Root string `json:"root"` // qualified_name
Direction string `json:"direction"` // forward | reverse
Depth int `json:"depth"`
Nodes []CodeNode `json:"nodes"`
Edges []CodeEdge `json:"edges"`
}
CallGraph represents a function's call hierarchy.
type CallSite ¶
type CallSite struct {
CalleeName string // function/method name being called: "HandleLogin", "GetUser"
Object string // receiver/object for method calls: "db", "s", "" for bare calls
Line int // line where the call happens (1-based)
IsMethodCall bool // true = obj.Method(), false = Function()
}
CallSite represents a function or method call found in source code.
type CallerTier ¶ added in v0.2.0
CallerTier groups every distinct caller found at a given hop distance. Depth 1 = direct callers; 2 = their callers; etc.
type CodeChatResult ¶
type CodeChatResult struct {
Query string
Context string // raw context sent to the LLM
Answer string // LLM-synthesized answer (or context if no LLM)
Sources []CodeNode
Error string
// ScopeResolved is false when a ComponentScope was requested but matched
// no component in the graph (stale name after re-enrichment, typo, or
// removed directory). Results are then empty for that reason — UIs should
// refresh their component list instead of showing "not enough context".
ScopeResolved bool
}
CodeChatResult is the output of a single code-chat query.
type CodeContext ¶
type CodeContext struct {
Nodes []CodeNode
Query string
Content string // formatted context string for LLM consumption
// ScopeResolved reports whether a requested ComponentScope actually
// matched a component in the graph. False + non-nil scope means the
// caller used a stale/unknown name (e.g. after LLM enrichment renamed
// it) — results are empty for that reason, NOT because the question
// was hard. Surfaces in CodeChatResult so UIs can self-heal.
ScopeResolved bool
}
CodeContext is the result of a code retrieval pipeline.
type CodeContextBuilder ¶
type CodeContextBuilder struct {
// contains filtered or unexported fields
}
CodeContextBuilder retrieves relevant code symbols for a natural language query. Pipeline: embed query -> semantic + BM25 (concurrent) -> callgraph BFS -> RRF fusion -> cross-encoder rerank -> format.
func NewCodeContextBuilder ¶
func NewCodeContextBuilder(client *FalkorClient, embedder Embedder, rerankURL, rerankToken string, opts ...BuilderOption) *CodeContextBuilder
NewCodeContextBuilder creates a builder backed by the given FalkorDB client and embedder. rerankURL and rerankToken are optional; if empty, reranking is skipped.
func (*CodeContextBuilder) Build ¶
func (b *CodeContextBuilder) Build(ctx context.Context, params CodeContextBuilderParams) (CodeContext, error)
Build runs the code retrieval pipeline.
type CodeContextBuilderParams ¶
type CodeContextBuilderParams struct {
Query string
Scope *ComponentScope // nil = unscoped (search all symbols)
}
CodeContextBuilderParams holds the user query and workspace information.
type CodeEdge ¶
type CodeEdge struct {
SourceUID string `json:"source_uid"`
TargetUID string `json:"target_uid"`
Type string `json:"type"` // DEFINES | CALLS | IMPLEMENTS | IMPORTS | CONTAINS | PART_OF | HAS_METHOD
Line int `json:"line,omitempty"` // for CALLS: line where call happens
// CALLS-edge extras. SourceQName/TargetQName carry qualified names so
// consumers never have to join UIDs against the node list (GetCallGraph
// populates them; creation paths leave them empty). Object records the
// receiver expression of a method call (`db` in db.SaveUser(x)) as a
// disambiguation hint for same-name methods.
SourceQName string `json:"source_qname,omitempty"`
TargetQName string `json:"target_qname,omitempty"`
Object string `json:"object,omitempty"`
}
CodeEdge represents a relationship between two code entities.
type CodeNode ¶
type CodeNode struct {
UID string `json:"uid,omitempty"`
Name string `json:"name"`
QualifiedName string `json:"qualified_name"`
Kind string `json:"kind"` // function | method | struct | interface | class | trait | constant | variable | file | package | component
FilePath string `json:"file_path"`
StartLine int `json:"start_line"`
EndLine int `json:"end_line"`
Signature string `json:"signature"`
Receiver string `json:"receiver,omitempty"` // methods only
Language string `json:"language"`
IsExported bool `json:"is_exported"`
DocComment string `json:"doc_comment"`
Role string `json:"role,omitempty"`
FileHash string `json:"file_hash,omitempty"` // file nodes only
IndexedAt int64 `json:"indexed_at"`
Embedding []float32 `json:"code_embedding,omitempty"`
Score float64 `json:"score,omitempty"` // search relevance score (not stored in DB)
}
CodeNode represents a code entity in the knowledge graph.
func DetectComponents ¶
DetectComponents groups symbols by directory into component CodeNodes. Each unique directory becomes a component. The name is set to the relative directory path; if an LLM provider is configured the indexer overwrites it with a human-readable name via EnrichComponents.
type ComponentEnrichment ¶
type ComponentEnrichment struct {
Dir string `json:"dir"`
Name string `json:"name"`
Role string `json:"role"`
Description string `json:"description"`
}
ComponentEnrichment holds the LLM-generated metadata for a component.
type ComponentImpact ¶ added in v0.2.0
ComponentImpact aggregates how many callers fall inside one component.
type ComponentNode ¶
type ComponentNode struct {
Name string `json:"name"`
Role string `json:"role"`
Description string `json:"description"`
Color string `json:"color"`
FilePath string `json:"file_path"`
FileCount int `json:"file_count"`
Symbols []string `json:"symbols"`
Downstream []string `json:"downstream"`
Upstream []string `json:"upstream"`
// Dependency claims that could NOT be corroborated by an import in the
// claiming component's sources. Same-name call resolution fabricates
// these routinely (measured live: generic .Error()/.Subscribe() calls
// wired onto wrong-package twins). Kept visible — hints, not silence —
// but excluded from Downstream/Upstream so cards stay trustworthy.
// Empty when no workspace root was available for verification.
UnverifiedDownstream []string `json:"unverified_downstream,omitempty"`
UnverifiedUpstream []string `json:"unverified_upstream,omitempty"`
}
ComponentNode represents a detected component.
type ComponentScope ¶
type ComponentScope struct {
Name string // component name to focus on
IncludeDeps bool // also search symbols from dependency components
MaxDeps int // cap on dependency components (0 = no cap)
}
ComponentScope restricts retrieval to symbols belonging to a specific component. When passed to Engine.Ask, the retrieval pipeline filters semantic and BM25 results to only include symbols with PART_OF edges to the named component (and optionally its direct dependencies).
type Config ¶
type Config struct {
// Service URLs (required)
FalkorDBAddr string // e.g. "localhost:6382"
TEIURL string // e.g. "http://localhost:8085"
// Graph name (default: "argus")
GraphName string
// Reranker (optional)
RerankURL string
RerankToken string
// LLM (optional — only for chat synthesis and component enrichment)
LLMBaseURL string
LLMModel string
LLMAPIKey string
// Tuning
Workers int // Indexer workers (default 8)
RRFK int // RRF k parameter (default 60)
SemanticLimit int // Semantic search result limit (default 20)
BM25Limit int // BM25 search result limit (default 20)
CallGraphDepth int // BFS expansion depth (default 2)
ResultCap int // Final result cap (default 30)
// WorkspaceRoot enables text-level verification (dead-code scan) and
// import-corroborated component dependencies. Empty = legacy behavior.
WorkspaceRoot string
// Optional logger for indexer and retrieval diagnostics.
// If nil, both run silent.
Logger *slog.Logger
}
Config holds all service configuration and tuning parameters for the Argus engine.
type DeadCandidate ¶ added in v0.2.0
type DeadCandidate struct {
Name string `json:"name"`
QualifiedName string `json:"qualified_name"`
Kind string `json:"kind"`
Language string `json:"language"`
FilePath string `json:"file_path"`
StartLine int `json:"start_line"`
Reason string `json:"reason"`
}
DeadCandidate is a symbol that appears unreachable from within the indexed project: zero inbound CALLS and unexported.
type DeadCodeSummary ¶ added in v0.2.0
type DeadCodeSummary struct {
GraphCandidates int `json:"graph_candidates"`
DroppedAsReferenced int `json:"dropped_as_referenced"`
TestOnly []DeadCandidate `json:"test_only,omitempty"`
VerifiedDead []DeadCandidate `json:"verified_dead"`
// Unverified > 0 means no workspace root was configured, so candidates
// could not be text-checked. Treat VerifiedDead as raw graph hints only.
Unverified int `json:"unverified,omitempty"`
}
DeadCodeSummary reports what the dead-code pass saw, so callers can show "N candidates, M confirmed after text verification" instead of a bare list.
type Embedder ¶
type Embedder interface {
Embed(ctx context.Context, texts []string) ([][]float32, error)
Dimension() int
}
Embedder turns text into dense vectors for semantic search.
type Engine ¶
type Engine struct {
Client *FalkorClient
Embedder Embedder
Indexer *Indexer
Config Config
// contains filtered or unexported fields
}
Engine is the fully wired Argus engine with indexing, retrieval, and chat.
func New ¶
New creates a fully wired Engine from the given Config.
Construction order matters: the TEI embedder is created first so its auto-detected embedding dimension can size the FalkorDB vector index. Creating the client first would hardcode the dimension and break every embedding write against non-768 TEI models (e.g. bge-m3).
func (*Engine) Ask ¶
func (e *Engine) Ask(ctx context.Context, query string, scope ...*ComponentScope) (CodeChatResult, error)
Ask runs the code retrieval pipeline and optionally calls the LLM to synthesize an answer. If no LLM is configured, it returns the raw formatted context as the answer. An optional ComponentScope restricts retrieval to symbols belonging to the named component.
type ErrEmbeddingFailed ¶
type ErrEmbeddingFailed struct {
Cause error
}
ErrEmbeddingFailed is returned when text-to-vector conversion fails.
func (ErrEmbeddingFailed) Error ¶
func (e ErrEmbeddingFailed) Error() string
func (ErrEmbeddingFailed) Unwrap ¶
func (e ErrEmbeddingFailed) Unwrap() error
type ErrFalkorDBUnavailable ¶
type ErrFalkorDBUnavailable struct {
}
ErrFalkorDBUnavailable is returned when FalkorDB cannot be reached.
func (ErrFalkorDBUnavailable) Error ¶
func (e ErrFalkorDBUnavailable) Error() string
func (ErrFalkorDBUnavailable) Unwrap ¶
func (e ErrFalkorDBUnavailable) Unwrap() error
type ErrInvalidQuery ¶
type ErrInvalidQuery struct {
Query string
}
ErrInvalidQuery is returned when the query is empty or too short.
func (ErrInvalidQuery) Error ¶
func (e ErrInvalidQuery) Error() string
type ErrLLMUnavailable ¶
type ErrLLMUnavailable struct {
}
ErrLLMUnavailable is returned when the LLM provider cannot be reached.
func (ErrLLMUnavailable) Error ¶
func (e ErrLLMUnavailable) Error() string
func (ErrLLMUnavailable) Unwrap ¶
func (e ErrLLMUnavailable) Unwrap() error
type ErrRetrievalTimeout ¶
ErrRetrievalTimeout is returned when the retrieval pipeline exceeds its deadline.
func (ErrRetrievalTimeout) Error ¶
func (e ErrRetrievalTimeout) Error() string
type ErrSymbolNotFound ¶
type ErrSymbolNotFound struct {
QualifiedName string
}
ErrSymbolNotFound is returned when a specific symbol cannot be located.
func (ErrSymbolNotFound) Error ¶
func (e ErrSymbolNotFound) Error() string
type ErrTEIUnavailable ¶
type ErrTEIUnavailable struct {
}
ErrTEIUnavailable is returned when the Text Embeddings Inference service cannot be reached.
func (ErrTEIUnavailable) Error ¶
func (e ErrTEIUnavailable) Error() string
func (ErrTEIUnavailable) Unwrap ¶
func (e ErrTEIUnavailable) Unwrap() error
type ErrWorkspaceNotFound ¶
type ErrWorkspaceNotFound struct{}
ErrWorkspaceNotFound is returned when a workspace has no indexed code.
func (ErrWorkspaceNotFound) Error ¶
func (e ErrWorkspaceNotFound) Error() string
type ExtractResult ¶
type ExtractResult struct {
FileNode CodeNode // kind: "file"
Symbols []CodeNode // functions, methods, structs, interfaces
Edges []CodeEdge // DEFINES edges (file → symbol)
Calls []CallSite // function/method call sites
}
ExtractResult holds everything extracted from a single file.
type Extractor ¶
type Extractor struct {
// contains filtered or unexported fields
}
Extractor runs tree-sitter queries against parsed AST to produce CodeNodes and CodeEdges.
func NewExtractor ¶
NewExtractor creates an extractor for a given language.
func NewExtractorFromBytes ¶
NewExtractorFromBytes creates an extractor from raw query bytes (useful for tests).
func NewExtractorFromBytesWithLang ¶
NewExtractorFromBytesWithLang creates an extractor from raw query bytes for a specific language.
func (*Extractor) Extract ¶
func (e *Extractor) Extract(result *ParseResult) (*ExtractResult, error)
Extract runs the query against the parsed tree and builds nodes + edges.
type FalkorClient ¶
type FalkorClient struct {
// contains filtered or unexported fields
}
FalkorClient manages a connection to FalkorDB for code intelligence operations.
func NewFalkorClient ¶
func NewFalkorClient(addr, graphName string) (*FalkorClient, error)
NewFalkorClient creates a new client connected to the given FalkorDB instance with the default vector dimension (768). Use NewFalkorClientDim when the embedder produces a different dimension, or the vector index will reject every embedding write.
func NewFalkorClientDim ¶
func NewFalkorClientDim(addr, graphName string, dim int) (*FalkorClient, error)
NewFalkorClientDim creates a client whose :Code vector index matches dim. The dimension MUST equal the embedder's Dimension() — TEI models vary (bge-base=768, bge-m3=1024, ...) and a mismatch fails all embedding writes.
func (*FalkorClient) Close ¶
func (c *FalkorClient) Close() error
Close closes the connection to FalkorDB.
func (*FalkorClient) CreateCodeEdge ¶
func (c *FalkorClient) CreateCodeEdge(_ context.Context, edge CodeEdge) error
CreateCodeEdge creates a direct edge between two :Code nodes.
func (*FalkorClient) CreateCodeEdgeBatch ¶
func (c *FalkorClient) CreateCodeEdgeBatch(_ context.Context, edges []CodeEdge) error
CreateCodeEdgeBatch creates multiple edges in batches, grouped by edge type.
func (*FalkorClient) DeleteCodeByFile ¶
func (c *FalkorClient) DeleteCodeByFile(_ context.Context, filePath string) error
DeleteCodeByFile removes all :Code nodes for a given file path. DETACH DELETE also removes all connected edges automatically.
func (*FalkorClient) DeleteOrphanComponents ¶
func (c *FalkorClient) DeleteOrphanComponents(_ context.Context) (int64, error)
UpdateComponentMeta updates a component's name, role, description, and qualified_name after LLM enrichment.
The node is matched on file_path — the stable natural key shared with UpsertCodeNode's MERGE — NEVER on the mutable qualified_name. Renaming component A to a name component B will later also receive makes qname-based matching hijack the wrong node (observed live: both api dirs DeleteOrphanComponents removes :Code component nodes that no longer have any symbols attached via PART_OF (ghosts left when a directory's last file disappears). Returns the number removed.
func (*FalkorClient) GetCallGraph ¶
func (c *FalkorClient) GetCallGraph(_ context.Context, qualifiedName, direction string, depth int, maxResults int) (*CallGraph, error)
GetCallGraph traverses CALLS edges forward or reverse from a function.
func (*FalkorClient) GetComponentTree ¶
func (c *FalkorClient) GetComponentTree(ctx context.Context, workspaceRoot string) ([]ComponentNode, error)
GetComponentTree returns all components with their child symbols and dependency lists. When workspaceRoot is non-empty, cross-component CALLS claims are corroborated against imports in the claiming component's sources: uncorroborated pairs (typically same-name resolution artifacts) move to UnverifiedDownstream/Upstream instead of polluting the trusted lists. Pass "" for legacy unfiltered behavior.
func (*FalkorClient) GetComponentsSymbolSummaries ¶
GetComponentsSymbolSummaries returns each component's CURRENT full symbol list as one-line descriptions, keyed by component file_path.
func (*FalkorClient) GetFileHashes ¶
GetFileHashes returns a map[filePath]fileHash for incremental reindexing.
func (*FalkorClient) Graph ¶
func (c *FalkorClient) Graph() *falkordb.Graph
Graph returns the underlying FalkorDB graph for raw queries.
func (*FalkorClient) Name ¶
func (c *FalkorClient) Name() string
Name returns the graph name this client operates on.
func (*FalkorClient) Schema ¶
func (c *FalkorClient) Schema() error
Schema creates all required indexes for :Code nodes.
func (*FalkorClient) SearchCodeBM25 ¶
func (c *FalkorClient) SearchCodeBM25(_ context.Context, queryText, kind string, scopeComponentNames []string, limit int) ([]CodeNode, error)
SearchCodeBM25 performs full-text search over :Code node names. Unlike the ANN path, the fulltext yield is not candidate-capped, so every text match flows through the scope filter before ordering — scoped BM25 has no starvation problem and needs no over-fetch.
func (*FalkorClient) SearchCodeSemantic ¶
func (c *FalkorClient) SearchCodeSemantic(_ context.Context, embedding []float64, kind string, scopeComponentNames []string, limit int) ([]CodeNode, error)
SearchCodeSemantic performs vector similarity search over :Code nodes. When scopeComponentNames is non-empty, results are restricted to symbols with PART_OF edges into those components. Scope filtering happens AFTER the ANN query (FalkorDB cannot pre-filter vector search), so scoped calls over-fetch internally — see scopeOverfetchK.
func (*FalkorClient) UpdateComponentMeta ¶
func (c *FalkorClient) UpdateComponentMeta(_ context.Context, filePath, newName, role, description string) error
converged onto one node). file_path cannot collide.
func (*FalkorClient) UpsertCodeNode ¶
UpsertCodeNode creates or updates a :Code node using its natural key. Nodes with an empty Embedding are stored without the code_embedding property (Cypher NULL assignment removes the attribute).
func (*FalkorClient) UpsertCodeNodeBatch ¶
UpsertCodeNodeBatch creates or updates multiple :Code nodes in batches. Returns the UID for each node in the same order as the input slice.
type GoQualifier ¶
type GoQualifier struct{}
GoQualifier produces Go-style qualified names: "module/pkg.(*Receiver).Name"
func (*GoQualifier) DiscoverRoot ¶
func (q *GoQualifier) DiscoverRoot(projectPath string) (string, error)
func (*GoQualifier) Qualify ¶
func (q *GoQualifier) Qualify(pkg, receiver, name, kind string) string
type HubScore ¶ added in v0.2.0
type HubScore struct {
Name string `json:"name"`
QualifiedName string `json:"qualified_name"`
Kind string `json:"kind"`
FilePath string `json:"file_path"`
StartLine int `json:"start_line"`
FanIn int `json:"fan_in"`
FanOut int `json:"fan_out"`
TotalDegree int `json:"total_degree"`
Junction bool `json:"junction"` // high fan-in AND high fan-out
Risk RiskLevel `json:"risk"`
// resolution merges same-name call sites onto one node, so FanIn/FanOut
// may be inflated by traffic belonging to siblings. Generic method names
// (String/Close/Error/Get…) hit this constantly. Confidence: treat
// numbers as upper bounds; distinctive names are reliable.
SharedDefinitions int `json:"shared_definitions"`
}
HubScore describes a symbol's positional importance in the call graph.
fan-in = distinct callers (how much depends on it) fan-out = distinct callees (how much it depends on)
High values on BOTH axes mark junction points — busy intersections where a change fans out in every direction.
type HubThresholds ¶ added in v0.2.0
type HubThresholds struct {
Medium int // total degree ≥ this → medium
High int // total degree ≥ this → high
Critical int // total degree ≥ this → critical
JunctionFanIn int // fan-in ≥ this AND…
JunctionFanOut int // …fan-out ≥ this → junction escalation
}
HubThresholds sets the degree cutoffs for hub classification. Zero fields fall back to defaults (see DefaultHubThresholds).
func DefaultHubThresholds ¶ added in v0.2.0
func DefaultHubThresholds() HubThresholds
DefaultHubThresholds returns transparent, documented cutoffs rather than magic numbers buried in queries.
type ImpactReport ¶ added in v0.2.0
type ImpactReport struct {
Query string `json:"query"`
Root SymbolRef `json:"root"`
MaxDepth int `json:"max_depth"`
Tiers []CallerTier `json:"tiers"`
TotalCallers int `json:"total_callers"`
Components []ComponentImpact `json:"components"`
Risk RiskLevel `json:"risk"`
RiskReasons []string `json:"risk_reasons"`
}
ImpactReport answers: "this symbol changed — what is affected, how far does it reach, and how risky is that?"
type IndexRequest ¶
type IndexRequest struct {
Path string
Languages []string // e.g. ["go", "rust"]
Ignore []string // e.g. [".git", "vendor"]
}
IndexRequest configures what to index.
type IndexResult ¶
type IndexResult struct {
FilesProcessed int
NodesCreated int
EdgesCreated int
Errors []error
Duration time.Duration
}
IndexResult reports what was indexed.
type Indexer ¶
type Indexer struct {
// contains filtered or unexported fields
}
Indexer orchestrates code indexing: walk → parse → extract → qualify → embed → store.
func NewIndexer ¶
func NewIndexer(client *FalkorClient, embedder Embedder, workers int, opts ...IndexerOption) (*Indexer, error)
NewIndexer creates a new indexer. embedder is required for semantic search.
func (*Indexer) Index ¶
func (idx *Indexer) Index(ctx context.Context, req IndexRequest) (*IndexResult, error)
Index indexes a directory of source code into FalkorDB.
type IndexerOption ¶
type IndexerOption func(*Indexer)
IndexerOption configures optional Indexer behavior.
func WithLogger ¶
func WithLogger(l *slog.Logger) IndexerOption
WithLogger sets a logger for diagnostic output. If nil, the indexer runs silently.
func WithProvider ¶
func WithProvider(p LLMProvider) IndexerOption
WithProvider enables LLM-based component enrichment during indexing.
type JSQualifier ¶
type JSQualifier struct{}
JSQualifier produces JS-style qualified names: "src/api.js::handleLogin"
func (*JSQualifier) DiscoverRoot ¶
func (q *JSQualifier) DiscoverRoot(projectPath string) (string, error)
func (*JSQualifier) Qualify ¶
func (q *JSQualifier) Qualify(pkg, receiver, name, kind string) string
type LLMEvent ¶
type LLMEvent struct {
Type LLMEventType
Delta string
Error error
}
LLMEvent is a single streaming event from an LLM provider.
type LLMEventType ¶
type LLMEventType string
LLMEventType identifies the kind of streaming event.
const ( LLMEventTextDelta LLMEventType = "text_delta" LLMEventFinish LLMEventType = "finish" LLMEventError LLMEventType = "error" )
type LLMMessage ¶
LLMMessage is a single message in an LLM conversation.
type LLMParams ¶
type LLMParams struct {
Messages []LLMMessage
Temperature *float64
Seed *int
}
LLMParams configures an LLM completion request.
type LLMProvider ¶
type LLMProvider interface {
Stream(ctx context.Context, params LLMParams) (iter.Seq[*LLMEvent], error)
}
LLMProvider is the interface for LLM backends used during component enrichment. Implement this with Ollama, OpenAI, Anthropic, or any other provider.
type Language ¶
type Language string
Language represents a supported programming language.
func DetectLanguage ¶
DetectLanguage guesses the language from a file extension.
type LanguagePlugin ¶
type LanguagePlugin struct {
Name Language
Extensions []string
NewParser func() (*Parser, error)
NewExtractor func() (*Extractor, error)
Qualifier SymbolQualifier
// RuntimeEntryNames are functions invoked by the language runtime
// rather than by project code (invisible to any call graph).
RuntimeEntryNames []string
// Test-file conventions, used to split references into production vs
// test buckets. Empty = the language has no file-level test convention
// (e.g. Rust tests are inline via #[cfg(test)]).
TestFileSuffixes []string
TestFilePrefixes []string
// FuncDefPattern is a regexp template (%s = quoted symbol name)
// matching a DEFINITION line for a symbol — used by text verification
// to ignore a candidate's own declaration while counting references.
FuncDefPattern string
}
LanguagePlugin bundles everything needed to support one programming language.
func LookupByExtension ¶
func LookupByExtension(ext string) (*LanguagePlugin, bool)
LookupByExtension returns the plugin for a file extension (e.g. ".go").
func (*LanguagePlugin) DefinitionLineRe ¶ added in v0.2.0
func (p *LanguagePlugin) DefinitionLineRe(symbol string) *regexp.Regexp
DefinitionLineRe compiles this language's definition-line pattern for the given symbol name.
func (*LanguagePlugin) IsTestFileName ¶ added in v0.2.0
func (p *LanguagePlugin) IsTestFileName(fileName string) bool
IsTestFileName reports whether fileName matches this language's test-file conventions. A plugin with no conventions never classifies tests.
type OllamaProvider ¶
type OllamaProvider struct {
// contains filtered or unexported fields
}
OllamaProvider implements LLMProvider using Ollama's native /api/chat endpoint.
func NewOllamaProvider ¶
func NewOllamaProvider(baseURL, model, apiKey string) *OllamaProvider
NewOllamaProvider creates an Ollama provider. baseURL: e.g. "http://localhost:11434" or Ollama Cloud URL. model: e.g. "qwen2.5-coder:14b". apiKey: optional Bearer token for authenticated endpoints.
type ParseResult ¶
type ParseResult struct {
Tree *sitter.Tree
Src []byte
Lang Language
TsLang *sitter.Language // raw tree-sitter language for query execution
}
ParseResult holds the output of parsing a single file.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser wraps tree-sitter with language-specific setup.
func (*Parser) ParseBytes ¶
func (p *Parser) ParseBytes(src []byte) (*ParseResult, error)
ParseBytes parses source code from a byte slice (useful for tests).
type PythonQualifier ¶
type PythonQualifier struct{}
PythonQualifier produces Python-style qualified names: "package.module.ClassName.method"
func (*PythonQualifier) DiscoverRoot ¶
func (q *PythonQualifier) DiscoverRoot(projectPath string) (string, error)
func (*PythonQualifier) Qualify ¶
func (q *PythonQualifier) Qualify(pkg, receiver, name, kind string) string
type RerankClient ¶
type RerankClient struct {
// contains filtered or unexported fields
}
RerankClient calls a TEI (text-embeddings-inference) cross-encoder /rerank endpoint. A cross-encoder scores each (query, text) pair jointly, giving far sharper relevance than the bi-encoder cosine used for the candidate search — so it pulls the answer-bearing facts to the top, letting us safely keep a focused top-K instead of dumping the full RRF tail.
func NewRerankClient ¶
func NewRerankClient(url, token string) *RerankClient
NewRerankClient creates a client for a TEI cross-encoder reranking endpoint. The token is optional and used for authenticated endpoints (e.g. Hugging Face Inference).
type RiskLevel ¶ added in v0.2.0
type RiskLevel string
RiskLevel classifies how risky/interesting a structural finding is.
type RustQualifier ¶
type RustQualifier struct{}
RustQualifier produces Rust-style qualified names: "crate::module::Name"
func (*RustQualifier) DiscoverRoot ¶
func (q *RustQualifier) DiscoverRoot(projectPath string) (string, error)
func (*RustQualifier) Qualify ¶
func (q *RustQualifier) Qualify(pkg, receiver, name, kind string) string
type SymbolQualifier ¶
type SymbolQualifier interface {
// Qualify builds a globally unique qualified name.
// Go: "github.com/user/repo/internal/api.(*Server).HandleChat"
// Rust: "crate::auth::service::AuthService::validate"
// JS: "src/api.js::handleLogin"
Qualify(pkg, receiver, name, kind string) string
// DiscoverRoot finds the project module/package root.
// Go: reads go.mod → module path
// Rust: reads Cargo.toml → crate name
// JS: reads package.json → name (or uses directory)
DiscoverRoot(projectPath string) (modulePath string, err error)
}
SymbolQualifier builds language-specific qualified names.
type SymbolRef ¶ added in v0.2.0
type SymbolRef struct {
Name string `json:"name"`
QualifiedName string `json:"qualified_name"`
Kind string `json:"kind"`
FilePath string `json:"file_path"`
StartLine int `json:"start_line"`
Component string `json:"component,omitempty"`
}
SymbolRef identifies a code symbol with its citation and home component.
type TEIEmbedder ¶
type TEIEmbedder struct {
// contains filtered or unexported fields
}
TEIEmbedder calls a Text Embeddings Inference (TEI) service.
func NewTEIEmbedder ¶
func NewTEIEmbedder(baseURL string, dimension int) (*TEIEmbedder, error)
NewTEIEmbedder creates a TEI embedder with the given endpoint and dimension. dimension must match the model loaded in TEI and the FalkorDB vector index.
func NewTEIEmbedderAuto ¶
func NewTEIEmbedderAuto(baseURL string) (*TEIEmbedder, error)
NewTEIEmbedderAuto queries TEI for its model dimension and creates an embedder automatically.
func (*TEIEmbedder) Close ¶
func (e *TEIEmbedder) Close() error
Close closes the HTTP client used by this embedder.
func (*TEIEmbedder) Dimension ¶
func (e *TEIEmbedder) Dimension() int
Dimension returns the vector dimension this embedder produces.