Documentation
¶
Overview ¶
Package rag provides graph-backed entity resolution for parameter extraction.
The resolver translates natural language entity references (e.g., "rendering subsystem") into concrete graph entities (e.g., package "pkg/render") before the parameter extraction model sees them. This reduces the extraction model's job from "reason about the codebase" to "copy confirmed values into JSON fields."
Three resolution layers:
- Structural (in-memory, O(1)): exact name match against SymbolIndex + package names
- Semantic (Weaviate, ~5-15ms): vector similarity search (Phase 2, CRS-25)
- Behavioral (CRS history): cross-session learned constraints (Phase 3, CRS-25)
Index ¶
- Constants
- func BuildSearchText(sym *ast.Symbol) string
- func EnsureCodeSymbolSchema(ctx context.Context, client *weaviate.Client) error
- func GetCodeSymbolSchema() *models.Class
- func ResetCodeSymbolSchema(ctx context.Context, client *weaviate.Client) error
- func TokenizeQuery(query string) []string
- func WithExtractionContext(ctx context.Context, ec *ExtractionContext) context.Context
- type CombinedResolver
- type EmbedClient
- type ExtractionContext
- type IndexProgressFn
- type ResolvedEntity
- type Resolver
- type SemanticResolver
- type StructuralResolver
- type StructuralResult
- type SymbolStore
- func (s *SymbolStore) DeleteAll(ctx context.Context) error
- func (s *SymbolStore) DeleteByFile(ctx context.Context, filePath string) error
- func (s *SymbolStore) HasGraphHash(ctx context.Context, graphHash string) (bool, error)
- func (s *SymbolStore) IndexFileSymbols(ctx context.Context, idx *index.SymbolIndex, files []string, graphHash string) (int, error)
- func (s *SymbolStore) IndexSymbols(ctx context.Context, idx *index.SymbolIndex, graphHash string, ...) (int, error)
Constants ¶
const CodeSymbolClassName = "CodeSymbol"
CodeSymbolClassName is the Weaviate class name for code symbols.
Variables ¶
This section is empty.
Functions ¶
func BuildSearchText ¶
buildSearchText creates a natural language description of a symbol for embedding.
Description:
Combines the symbol's name, kind, package, signature, receiver, and doc comment into a sentence that the embedding model can vectorize meaningfully. CRS-26b: Enriched with receiver type (for method disambiguation) and doc comment (for semantic matching on conceptual queries). Examples: "function FindHotspots in package pkg/materials: func FindHotspots(ctx context.Context) ([]Hotspot, error). FindHotspots identifies functions with high PageRank scores." "method (Router) ServeHTTP in package pkg/server: func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request). ServeHTTP dispatches incoming HTTP requests to registered route handlers." "struct Material in package pkg/materials" "interface Renderer in package pkg/render"
Inputs:
sym - The symbol to describe. Must not be nil.
Outputs:
string - Natural language description suitable for text embedding.
BuildSearchText constructs a natural language description of a symbol suitable for text embedding. Exported for reuse by semantic search tools.
func EnsureCodeSymbolSchema ¶
EnsureCodeSymbolSchema creates the CodeSymbol class if it doesn't exist.
Description:
Checks if the CodeSymbol class exists in Weaviate and creates it if not. Idempotent — safe to call on every startup.
Inputs:
ctx - Context for cancellation. client - Weaviate client. Must not be nil.
Outputs:
error - Non-nil if schema creation fails.
Thread Safety: Safe for concurrent use.
func GetCodeSymbolSchema ¶
GetCodeSymbolSchema returns the Weaviate schema for the CodeSymbol class.
Description:
Defines the schema for storing code symbols in Weaviate for semantic search. CRS-26h: Uses vectorizer "none" — vectors are pre-computed by the orchestrator's /v1/embed endpoint and supplied at insert time. This avoids the container networking issue where Weaviate cannot reach Ollama on the host.
Outputs:
*models.Class - The Weaviate class definition.
Thread Safety: Stateless, safe for concurrent use.
func ResetCodeSymbolSchema ¶
ResetCodeSymbolSchema drops and recreates the CodeSymbol class in O(1), regardless of object count. Replaces batch delete which hangs on 300K+ objects.
Description:
CRS-26n: Single-project (one dataSpace at a time) means schema drop+recreate is safe. The class is deleted atomically then recreated via EnsureCodeSymbolSchema. Brief millisecond window where class doesn't exist — query callers already handle nil SymbolStore gracefully.
Inputs:
ctx - Context for cancellation. client - Weaviate client. Must not be nil.
Outputs:
error - Non-nil if schema recreation fails.
Thread Safety: Safe for concurrent use.
func TokenizeQuery ¶
TokenizeQuery extracts candidate entity names from a natural language query.
Description:
Splits a query into tokens that might be code entity references (symbol names, package names, file paths). Handles quoted strings, CamelCase splitting, snake_case splitting, and path-like tokens. Filters stopwords and common tool verbs.
Inputs:
query - Natural language query (e.g., "find hotspots in the rendering subsystem")
Outputs:
[]string - Candidate entity tokens, deduplicated, order preserved.
Thread Safety: Stateless, safe for concurrent use.
func WithExtractionContext ¶
func WithExtractionContext(ctx context.Context, ec *ExtractionContext) context.Context
WithExtractionContext attaches resolved entities to a context for use by the param extractor.
Description:
The execute phase calls this after resolving entities, before passing the context to ExtractParams. The param extractor retrieves it via ExtractionContextFromCtx and injects resolved entities into the LLM prompt.
Inputs:
ctx - Parent context. ec - Resolved entities and graph metadata.
Outputs:
context.Context - Context carrying the extraction context.
Thread Safety: Safe for concurrent use (context is immutable).
Types ¶
type CombinedResolver ¶
type CombinedResolver struct {
// contains filtered or unexported fields
}
CombinedResolver chains structural (Layer 1) and semantic (Layer 2) resolution.
Description:
First runs the StructuralResolver for O(1) exact matches. Then passes unresolved tokens to the SemanticResolver for nearText vector search. If Weaviate is unavailable, gracefully degrades to structural-only.
Thread Safety: Safe for concurrent use after construction.
func NewCombinedResolver ¶
func NewCombinedResolver(structural *StructuralResolver, semantic *SemanticResolver) *CombinedResolver
NewCombinedResolver creates a resolver that chains structural and semantic layers.
Inputs:
structural - Layer 1 resolver. Must not be nil. semantic - Layer 2 resolver. May be nil (degrades to structural-only).
Outputs:
*CombinedResolver - Ready to resolve queries.
Thread Safety: Safe for concurrent use after construction.
func (*CombinedResolver) Resolve ¶
func (c *CombinedResolver) Resolve(ctx context.Context, query string) *ExtractionContext
Resolve runs both resolution layers and returns merged results.
Description:
Structural resolution (O(1), ~0ms): exact name matching.
Semantic resolution (~5-15ms): nearText vector search for remaining tokens.
Merge results, deduplicating by resolved value.
If the semantic resolver is nil or Weaviate is unavailable, only structural results are returned (graceful degradation).
Inputs:
ctx - Context for cancellation and tracing. query - Natural language query.
Outputs:
*ExtractionContext - Merged resolved entities from both layers.
Thread Safety: Safe for concurrent use.
func (*CombinedResolver) Structural ¶
func (c *CombinedResolver) Structural() *StructuralResolver
Structural returns the underlying structural resolver for direct access.
type EmbedClient ¶
type EmbedClient struct {
// contains filtered or unexported fields
}
EmbedClient calls the orchestrator's /v1/embed endpoint for vector computation.
Description:
CRS-26i: Routes embedding requests through the orchestrator, which has network access to Ollama on the host. This solves the container networking issue where Weaviate/trace cannot reach Ollama directly.
Thread Safety: Safe for concurrent use after construction.
func NewEmbedClient ¶
func NewEmbedClient(orchestratorURL, model string) (*EmbedClient, error)
NewEmbedClient creates an EmbedClient for the orchestrator's /v1/embed endpoint.
Inputs:
orchestratorURL - Base URL of the orchestrator (e.g., "http://orchestrator:8081"). Must not be empty. model - Embedding model name (e.g., "nomic-embed-text-v2-moe"). If empty, defaults to "nomic-embed-text-v2-moe".
Outputs:
*EmbedClient - The configured client. error - Non-nil if orchestratorURL is empty.
Thread Safety: Safe for concurrent use after construction.
func (*EmbedClient) EmbedDocuments ¶
EmbedDocuments returns vectors for document texts using "search_document: " prefix.
Description:
Batches texts in chunks of 100 to avoid OOM. Each batch is sent to the orchestrator's /v1/embed endpoint with the "search_document: " prefix, which is required by nomic-embed-text models for document indexing.
Inputs:
ctx - Context for cancellation and tracing. texts - Document texts to embed. Must not be empty.
Outputs:
[][]float32 - One vector per input text, in the same order. error - Non-nil if the request fails or texts is empty.
Thread Safety: Safe for concurrent use.
func (*EmbedClient) EmbedQuery ¶
EmbedQuery returns a vector for a query text using "search_query: " prefix.
Description:
Used at query time by the SemanticResolver to embed the user's search tokens before running nearVector queries against Weaviate.
Inputs:
ctx - Context for cancellation and tracing. query - Query text to embed. Must not be empty.
Outputs:
[]float32 - The query embedding vector. error - Non-nil if the request fails or query is empty.
Thread Safety: Safe for concurrent use.
type ExtractionContext ¶
type ExtractionContext struct {
// ResolvedEntities are query tokens resolved against the graph.
ResolvedEntities []ResolvedEntity `json:"resolved_entities,omitempty"`
// PackageNames are available packages in the graph (for LLM prompt grounding).
// Limited to top packages by symbol count to avoid prompt bloat.
PackageNames []string `json:"package_names,omitempty"`
// SymbolCount is the total number of symbols in the graph.
SymbolCount int `json:"symbol_count"`
}
ExtractionContext provides resolved entities and graph metadata to the parameter extractor. This is the bridge between the RAG resolver and the LLM extraction prompt.
func ExtractionContextFromCtx ¶
func ExtractionContextFromCtx(ctx context.Context) *ExtractionContext
ExtractionContextFromCtx retrieves resolved entities from a context.
Outputs:
*ExtractionContext - The resolved entities, or nil if not set.
Thread Safety: Safe for concurrent use.
type IndexProgressFn ¶
IndexProgressFn is a callback for reporting indexing progress.
Description:
Called at key phases during IndexSymbols: after collecting symbols, after embedding, and after each Weaviate batch insert.
Inputs:
phase - Current phase: "collecting", "embedding", "inserting". batchesCompleted - Number of batches completed (inserting phase). batchesTotal - Total number of batches (inserting phase). symbolsTotal - Total number of symbols being indexed.
type ResolvedEntity ¶
type ResolvedEntity struct {
// Raw is the original token from the query (e.g., "materials").
Raw string `json:"raw"`
// Kind classifies the entity: "package", "symbol", "file".
Kind string `json:"kind"`
// Resolved is the concrete graph entity (e.g., "pkg/materials").
Resolved string `json:"resolved"`
// Confidence is how certain the resolution is (0.0 to 1.0).
// Structural matches get 1.0, semantic matches get the vector similarity score.
Confidence float64 `json:"confidence"`
// Candidates lists alternative matches when resolution is ambiguous.
Candidates []string `json:"candidates,omitempty"`
// Layer indicates which resolution layer produced this match.
// "structural", "semantic", or "behavioral".
Layer string `json:"layer"`
}
ResolvedEntity represents a query token resolved against the code graph.
type Resolver ¶
type Resolver interface {
// Resolve resolves a query into grounded entities from the code graph.
//
// Inputs:
// ctx - Context for cancellation and tracing.
// query - Natural language query.
//
// Outputs:
// *ExtractionContext - Resolved entities and graph metadata.
Resolve(ctx context.Context, query string) *ExtractionContext
}
Resolver is the interface for RAG entity resolution.
Both StructuralResolver (Layer 1) and CombinedResolver (Layers 1+2) implement this. The execute phase depends on this interface, not concrete types.
type SemanticResolver ¶
type SemanticResolver struct {
// contains filtered or unexported fields
}
SemanticResolver resolves query tokens against Weaviate's vector index.
This is Layer 2 of the three-layer RAG resolution. It handles fuzzy/conceptual matches like "rendering subsystem" → "pkg/render" using pre-computed embeddings. CRS-26j: Uses nearVector queries with vectors from the orchestrator's /v1/embed endpoint, replacing the previous nearText approach that required Weaviate to reach Ollama directly (broken in containers).
Thread Safety: Safe for concurrent use after construction.
func NewSemanticResolver ¶
func NewSemanticResolver(client *weaviate.Client, dataSpace string, embedder *EmbedClient) (*SemanticResolver, error)
NewSemanticResolver creates a resolver backed by Weaviate nearVector search.
Inputs:
client - Weaviate client. Must not be nil. dataSpace - Project isolation key. Must not be empty. embedder - Embedding client for query vectorization. Must not be nil.
Outputs:
*SemanticResolver - Ready to resolve queries. error - Non-nil if client is nil, dataSpace is empty, or embedder is nil.
Thread Safety: Safe for concurrent use after construction.
func (*SemanticResolver) IsAvailable ¶
func (r *SemanticResolver) IsAvailable(ctx context.Context) bool
IsAvailable checks if the semantic resolver can serve queries.
Description:
Returns false if Weaviate is unavailable, allowing callers to skip semantic resolution and fall back to structural-only. Results are cached for 30 seconds to avoid per-query network health checks.
Inputs:
ctx - Context for cancellation.
Outputs:
bool - True if Weaviate is reachable.
Thread Safety: Safe for concurrent use.
func (*SemanticResolver) Resolve ¶
func (r *SemanticResolver) Resolve(ctx context.Context, unresolvedTokens []string, alreadyResolved map[string]bool) ([]ResolvedEntity, error)
Resolve runs nearVector search for unresolved tokens and returns additional entities.
Description:
Takes the tokens that the StructuralResolver couldn't resolve and searches Weaviate for semantically similar code symbols. Returns resolved entities with confidence based on cosine distance. Only returns results above the minimum similarity threshold. Results are deduplicated against entities already resolved by the structural layer. Individual token search failures are logged and skipped — the function returns partial results rather than failing entirely. The returned error is always nil in the current implementation (reserved for future use).
Inputs:
ctx - Context for cancellation and tracing. unresolvedTokens - Tokens that the structural resolver couldn't match. alreadyResolved - Set of resolved values from structural resolution (for dedup).
Outputs:
[]ResolvedEntity - Semantically resolved entities (may be partial on per-token failures). error - Currently always nil. Individual token failures are logged, not propagated.
Thread Safety: Safe for concurrent use.
type StructuralResolver ¶
type StructuralResolver struct {
// contains filtered or unexported fields
}
StructuralResolver resolves query tokens against the SymbolIndex and package names.
This is Layer 1 of the three-layer RAG resolution. It handles exact and prefix matches with O(1) lookups, covering 60-70% of entity resolution queries.
Thread Safety: Safe for concurrent use after construction.
func NewStructuralResolver ¶
func NewStructuralResolver(idx *index.SymbolIndex) *StructuralResolver
NewStructuralResolver creates a resolver from a SymbolIndex.
Description:
Extracts unique package names from all symbols in the index and builds lookup structures for exact, prefix, and last-segment matching.
Inputs:
idx - The symbol index to resolve against. Must not be nil.
Outputs:
*StructuralResolver - Ready to resolve queries.
Thread Safety: Safe for concurrent use after construction.
func (*StructuralResolver) PackageNames ¶
func (r *StructuralResolver) PackageNames() []string
PackageNames returns all known package names.
Thread Safety: Safe for concurrent use.
func (*StructuralResolver) Resolve ¶
func (r *StructuralResolver) Resolve(ctx context.Context, query string) *ExtractionContext
Resolve resolves a query into grounded entities from the code graph.
Description:
Tokenizes the query, then checks each token against: 1. Package names (exact match, last-segment match, prefix match) 2. Symbol names (exact match via SymbolIndex) 3. File paths (suffix match via SymbolIndex) Returns resolved entities with confidence scores. Structural matches get confidence 1.0 (exact) or 0.9 (prefix/segment).
Inputs:
ctx - Context for cancellation and tracing. query - Natural language query.
Outputs:
*ExtractionContext - Resolved entities and graph metadata for the param extractor.
Thread Safety: Safe for concurrent use.
func (*StructuralResolver) ResolveDetailed ¶
func (r *StructuralResolver) ResolveDetailed(ctx context.Context, query string) (*ExtractionContext, *StructuralResult)
ResolveDetailed resolves a query and also returns unresolved tokens for Layer 2.
Description:
Same as Resolve but additionally returns tokens that couldn't be matched structurally. The CombinedResolver uses these as input for semantic search.
Inputs:
ctx - Context for cancellation and tracing. query - Natural language query.
Outputs:
*ExtractionContext - Resolved entities and graph metadata. *StructuralResult - Full result including unresolved tokens.
Thread Safety: Safe for concurrent use.
type StructuralResult ¶
type StructuralResult struct {
// UnresolvedTokens are tokens that couldn't be matched structurally.
// These are candidates for semantic resolution (Layer 2).
UnresolvedTokens []string
// ResolvedSet contains the resolved values for deduplication.
ResolvedSet map[string]bool
}
StructuralResult holds the output of structural resolution including unresolved tokens.
type SymbolStore ¶
type SymbolStore struct {
// contains filtered or unexported fields
}
SymbolStore handles batch indexing and deletion of code symbols in Weaviate.
This is the write side of the semantic resolution layer. Symbols are indexed during graph init and refreshed when files change.
CRS-26i: Supports pre-computed vectors via EmbedClient. When embedder is set, vectors are computed by the orchestrator before Weaviate insertion. When nil, symbols are inserted without vectors (graceful degradation — search won't work but indexing doesn't crash).
Thread Safety: Safe for concurrent use.
func NewSymbolStore ¶
func NewSymbolStore(client *weaviate.Client, dataSpace string, embedder *EmbedClient) (*SymbolStore, error)
NewSymbolStore creates a new symbol store.
Inputs:
client - Weaviate client. Must not be nil. dataSpace - Project isolation key. Must not be empty. embedder - Embedding client for pre-computing vectors. May be nil (graceful degradation).
Outputs:
*SymbolStore - The configured store. error - Non-nil if client is nil or dataSpace is empty.
Thread Safety: Safe for concurrent use after construction.
func (*SymbolStore) DeleteAll ¶
func (s *SymbolStore) DeleteAll(ctx context.Context) error
DeleteAll removes all symbols for this data space.
Description:
Used before full re-index when the graph hash changes.
Inputs:
ctx - Context for cancellation.
Outputs:
error - Non-nil if deletion fails.
Thread Safety: Safe for concurrent use.
func (*SymbolStore) DeleteByFile ¶
func (s *SymbolStore) DeleteByFile(ctx context.Context, filePath string) error
DeleteByFile removes all symbols for a given file path.
Description:
Used during incremental graph refresh — when a file changes, delete its old symbols before re-indexing the new ones.
Inputs:
ctx - Context for cancellation. filePath - The file path whose symbols to delete.
Outputs:
error - Non-nil if deletion fails.
Thread Safety: Safe for concurrent use.
func (*SymbolStore) HasGraphHash ¶
HasGraphHash checks if the current Weaviate data matches the given graph hash.
Description:
Queries for any symbol with this graphHash + dataSpace. If found, the graph hasn't changed and we can skip re-indexing (~5ms check vs ~30s full index).
Inputs:
ctx - Context for cancellation. graphHash - Hash to check against.
Outputs:
bool - True if Weaviate already has symbols for this graph hash. error - Non-nil if the query fails.
Thread Safety: Safe for concurrent use.
func (*SymbolStore) IndexFileSymbols ¶
func (s *SymbolStore) IndexFileSymbols(ctx context.Context, idx *index.SymbolIndex, files []string, graphHash string) (int, error)
IndexFileSymbols indexes exported symbols from specific files into Weaviate.
Description:
Used during incremental graph refresh (CRS-25b). After a file changes, its old symbols are deleted via DeleteByFile and new symbols are indexed via this method. Only indexes exported symbols, matching the behavior of IndexSymbols.
Inputs:
ctx - Context for cancellation. idx - Symbol index to read from (already refreshed). files - File paths whose symbols to index. graphHash - Current graph hash for the symbols.
Outputs:
int - Number of symbols indexed. error - Non-nil if batch insert fails.
Thread Safety: Safe for concurrent use.
func (*SymbolStore) IndexSymbols ¶
func (s *SymbolStore) IndexSymbols(ctx context.Context, idx *index.SymbolIndex, graphHash string, onProgress IndexProgressFn) (int, error)
IndexSymbols batch-inserts symbols from the SymbolIndex into Weaviate.
Description:
Iterates all exported symbols from the index, builds a searchText (natural language description), and batch-inserts into the CodeSymbol class. Only indexes exported symbols to keep the collection focused.
Inputs:
ctx - Context for cancellation. idx - Symbol index to read from. graphHash - Hash identifying this graph version (for skip-on-match optimization). onProgress - Optional callback for progress reporting. May be nil.
Outputs:
int - Number of symbols indexed. error - Non-nil if batch insert fails.
Thread Safety: Safe for concurrent use.