@abhinav2203/coderag 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +196 -0
- package/dist/adapters/codeflow-core.d.ts +10 -0
- package/dist/adapters/codeflow-core.js +212 -0
- package/dist/adapters/codeflow-core.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +179 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors/index.d.ts +17 -0
- package/dist/errors/index.js +35 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/documents.d.ts +16 -0
- package/dist/indexer/documents.js +148 -0
- package/dist/indexer/documents.js.map +1 -0
- package/dist/indexer/embedder.d.ts +7 -0
- package/dist/indexer/embedder.js +12 -0
- package/dist/indexer/embedder.js.map +1 -0
- package/dist/indexer/git-hook.d.ts +2 -0
- package/dist/indexer/git-hook.js +53 -0
- package/dist/indexer/git-hook.js.map +1 -0
- package/dist/indexer/indexer.d.ts +22 -0
- package/dist/indexer/indexer.js +108 -0
- package/dist/indexer/indexer.js.map +1 -0
- package/dist/llm/context-builder.d.ts +7 -0
- package/dist/llm/context-builder.js +93 -0
- package/dist/llm/context-builder.js.map +1 -0
- package/dist/llm/prompt.d.ts +3 -0
- package/dist/llm/prompt.js +80 -0
- package/dist/llm/prompt.js.map +1 -0
- package/dist/llm/transports.d.ts +23 -0
- package/dist/llm/transports.js +271 -0
- package/dist/llm/transports.js.map +1 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +70 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/retrieval/page-index.d.ts +3 -0
- package/dist/retrieval/page-index.js +26 -0
- package/dist/retrieval/page-index.js.map +1 -0
- package/dist/retrieval/search.d.ts +20 -0
- package/dist/retrieval/search.js +164 -0
- package/dist/retrieval/search.js.map +1 -0
- package/dist/retrieval/traversal.d.ts +6 -0
- package/dist/retrieval/traversal.js +29 -0
- package/dist/retrieval/traversal.js.map +1 -0
- package/dist/service/coderag.d.ts +58 -0
- package/dist/service/coderag.js +208 -0
- package/dist/service/coderag.js.map +1 -0
- package/dist/service/config.d.ts +13 -0
- package/dist/service/config.js +130 -0
- package/dist/service/config.js.map +1 -0
- package/dist/service/http-metrics.d.ts +8 -0
- package/dist/service/http-metrics.js +36 -0
- package/dist/service/http-metrics.js.map +1 -0
- package/dist/service/http.d.ts +11 -0
- package/dist/service/http.js +262 -0
- package/dist/service/http.js.map +1 -0
- package/dist/store/file-cache.d.ts +6 -0
- package/dist/store/file-cache.js +24 -0
- package/dist/store/file-cache.js.map +1 -0
- package/dist/store/index-lock.d.ts +14 -0
- package/dist/store/index-lock.js +112 -0
- package/dist/store/index-lock.js.map +1 -0
- package/dist/store/manifest-store.d.ts +16 -0
- package/dist/store/manifest-store.js +49 -0
- package/dist/store/manifest-store.js.map +1 -0
- package/dist/store/vector-store.d.ts +18 -0
- package/dist/store/vector-store.js +140 -0
- package/dist/store/vector-store.js.map +1 -0
- package/dist/types.d.ts +251 -0
- package/dist/types.js +63 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/filesystem.d.ts +8 -0
- package/dist/utils/filesystem.js +38 -0
- package/dist/utils/filesystem.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +19 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.js +151 -0
- package/dist/utils/text.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
const serialize = (value) => JSON.stringify(value, null, 2);
|
|
5
|
+
const DEPTH_SCHEMA = z.number().int().min(0).optional();
|
|
6
|
+
/**
|
|
7
|
+
* Creates the stdio MCP server that exposes CodeRag retrieval tools.
|
|
8
|
+
*/
|
|
9
|
+
export const createMcpServer = (coderag) => {
|
|
10
|
+
const server = new McpServer({
|
|
11
|
+
name: "coderag",
|
|
12
|
+
version: "0.1.0"
|
|
13
|
+
});
|
|
14
|
+
server.registerTool("query", {
|
|
15
|
+
title: "Query repository",
|
|
16
|
+
description: "Answer a natural-language question about the indexed repository.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
question: z.string().min(1),
|
|
19
|
+
depth: DEPTH_SCHEMA
|
|
20
|
+
}
|
|
21
|
+
}, async ({ question, depth }) => ({
|
|
22
|
+
content: [{ type: "text", text: serialize(await coderag.query(question, { depth })) }]
|
|
23
|
+
}));
|
|
24
|
+
server.registerTool("lookup", {
|
|
25
|
+
title: "Lookup node",
|
|
26
|
+
description: "Lookup a graph node by id, name, or file path.",
|
|
27
|
+
inputSchema: {
|
|
28
|
+
identifier: z.string().min(1)
|
|
29
|
+
}
|
|
30
|
+
}, async ({ identifier }) => ({
|
|
31
|
+
content: [{ type: "text", text: serialize(await coderag.lookup(identifier)) }]
|
|
32
|
+
}));
|
|
33
|
+
server.registerTool("explain", {
|
|
34
|
+
title: "Explain node",
|
|
35
|
+
description: "Explain what a node does and how it relates to the graph.",
|
|
36
|
+
inputSchema: {
|
|
37
|
+
identifier: z.string().min(1),
|
|
38
|
+
depth: DEPTH_SCHEMA
|
|
39
|
+
}
|
|
40
|
+
}, async ({ identifier, depth }) => ({
|
|
41
|
+
content: [{ type: "text", text: serialize(await coderag.explain(identifier, depth)) }]
|
|
42
|
+
}));
|
|
43
|
+
server.registerTool("impact", {
|
|
44
|
+
title: "Impact analysis",
|
|
45
|
+
description: "Show what depends on a node.",
|
|
46
|
+
inputSchema: {
|
|
47
|
+
identifier: z.string().min(1),
|
|
48
|
+
depth: DEPTH_SCHEMA
|
|
49
|
+
}
|
|
50
|
+
}, async ({ identifier, depth }) => ({
|
|
51
|
+
content: [{ type: "text", text: serialize(await coderag.impact(identifier, depth)) }]
|
|
52
|
+
}));
|
|
53
|
+
server.registerTool("status", {
|
|
54
|
+
title: "Indexer status",
|
|
55
|
+
description: "Return repository indexing and LLM status.",
|
|
56
|
+
inputSchema: {}
|
|
57
|
+
}, async () => ({
|
|
58
|
+
content: [{ type: "text", text: serialize(await coderag.status()) }]
|
|
59
|
+
}));
|
|
60
|
+
return server;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Connects the CodeRag MCP server to stdio for local tool execution.
|
|
64
|
+
*/
|
|
65
|
+
export const serveStdioMcpServer = async (coderag) => {
|
|
66
|
+
const server = createMcpServer(coderag);
|
|
67
|
+
const transport = new StdioServerTransport();
|
|
68
|
+
await server.connect(transport);
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { GraphSnapshot, IndexedNodeDocument, RetrievedNodeContext } from "../types.js";
|
|
2
|
+
import { FileCache } from "../store/file-cache.js";
|
|
3
|
+
export declare const createRetrievedNodeContext: (repoPath: string, fileCache: FileCache, snapshot: GraphSnapshot, document: IndexedNodeDocument, relationship: RetrievedNodeContext["relationship"], sourceNodeId?: string) => Promise<RetrievedNodeContext>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { uniqueNumbers } from "../utils/text.js";
|
|
3
|
+
const edgeKeyFor = (fromNodeId, toNodeId) => `calls:${fromNodeId}:${toNodeId}`;
|
|
4
|
+
export const createRetrievedNodeContext = async (repoPath, fileCache, snapshot, document, relationship, sourceNodeId) => {
|
|
5
|
+
const fullFileContent = await fileCache.read(path.join(repoPath, document.filePath));
|
|
6
|
+
let callSiteLines = [];
|
|
7
|
+
if (sourceNodeId && relationship === "calls") {
|
|
8
|
+
callSiteLines = snapshot.callSites[edgeKeyFor(sourceNodeId, document.nodeId)]?.lineNumbers ?? [];
|
|
9
|
+
}
|
|
10
|
+
if (sourceNodeId && relationship === "called-by") {
|
|
11
|
+
callSiteLines = snapshot.callSites[edgeKeyFor(document.nodeId, sourceNodeId)]?.lineNumbers ?? [];
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
nodeId: document.nodeId,
|
|
15
|
+
name: document.name,
|
|
16
|
+
kind: document.kind,
|
|
17
|
+
filePath: document.filePath,
|
|
18
|
+
fullFileContent,
|
|
19
|
+
startLine: document.startLine,
|
|
20
|
+
endLine: document.endLine,
|
|
21
|
+
callSiteLines: uniqueNumbers(callSiteLines),
|
|
22
|
+
doc: document.doc,
|
|
23
|
+
relationship
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=page-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-index.js","sourceRoot":"","sources":["../../src/retrieval/page-index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,UAAU,GAAG,CAAC,UAAkB,EAAE,QAAgB,EAAU,EAAE,CAAC,SAAS,UAAU,IAAI,QAAQ,EAAE,CAAC;AAEvG,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,EAC7C,QAAgB,EAChB,SAAoB,EACpB,QAAuB,EACvB,QAA6B,EAC7B,YAAkD,EAClD,YAAqB,EACU,EAAE;IACjC,MAAM,eAAe,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAErF,IAAI,aAAa,GAAa,EAAE,CAAC;IACjC,IAAI,YAAY,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;QAC7C,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,IAAI,EAAE,CAAC;IACnG,CAAC;IAED,IAAI,YAAY,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;QACjD,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,WAAW,IAAI,EAAE,CAAC;IACnG,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,eAAe;QACf,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC;QAC3C,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,YAAY;KACb,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EmbeddingProvider, IndexedNodeDocument, RetrievalConfig, VectorStore } from "../types.js";
|
|
2
|
+
export declare const calculateIdfScore: (queryTokens: string[], candidateTokens: string[], documentFrequency: Map<string, number>, documentCount: number) => number;
|
|
3
|
+
export declare const calculateFieldScore: (question: string, document: IndexedNodeDocument) => number;
|
|
4
|
+
export interface SearchResult {
|
|
5
|
+
document: IndexedNodeDocument;
|
|
6
|
+
vectorScore: number;
|
|
7
|
+
lexicalScore: number;
|
|
8
|
+
fieldScore: number;
|
|
9
|
+
coverageScore: number;
|
|
10
|
+
idfScore: number;
|
|
11
|
+
finalScore: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Builds a hybrid candidate set from the vector store and lexical ranking, then scores it.
|
|
15
|
+
*/
|
|
16
|
+
export declare const searchDocuments: (question: string, documents: Record<string, IndexedNodeDocument>, embeddingProvider: EmbeddingProvider, retrieval: RetrievalConfig, vectorStore?: VectorStore) => Promise<SearchResult[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Applies a smaller rerank pass that strongly favors exact symbol and path resolution.
|
|
19
|
+
*/
|
|
20
|
+
export declare const rerankResults: (question: string, results: SearchResult[], retrieval: RetrievalConfig) => SearchResult[];
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { cosineSimilarity, lexicalOverlapScore, tokenizeMeaningfully, weightedTokenScore } from "../utils/text.js";
|
|
2
|
+
const SEMANTIC_MULTIPLIER = 3;
|
|
3
|
+
const LEXICAL_MULTIPLIER = 4;
|
|
4
|
+
const QUERY_SYNONYMS = new Map([
|
|
5
|
+
["concurrent", ["lock", "shared", "process"]],
|
|
6
|
+
["corruption", ["lock", "stale", "safe"]],
|
|
7
|
+
["retry", ["backoff", "wait"]],
|
|
8
|
+
["retri", ["backoff", "wait"]],
|
|
9
|
+
["request", ["http", "post", "json"]],
|
|
10
|
+
["server", ["http", "transport"]],
|
|
11
|
+
["model", ["llm", "transport"]],
|
|
12
|
+
["index", ["manifest", "snapshot", "lock"]]
|
|
13
|
+
]);
|
|
14
|
+
const LARGE_NODE_LINE_THRESHOLD = 500;
|
|
15
|
+
const MAX_LARGE_NODE_PENALTY = 0.12;
|
|
16
|
+
const buildSearchText = (document) => [document.name, document.filePath, document.summary, document.signature, document.doc, document.sourceText]
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.join("\n");
|
|
19
|
+
const isSymbolLikeQuery = (question) => !question.includes(" ") || question.includes("/") || question.includes(".") || question.includes("_");
|
|
20
|
+
const normalizeQuestion = (question) => question.trim().toLowerCase();
|
|
21
|
+
const expandQuestion = (question) => {
|
|
22
|
+
const expandedTokens = tokenizeMeaningfully(question).flatMap((token) => [token, ...(QUERY_SYNONYMS.get(token) ?? [])]);
|
|
23
|
+
return [question, ...expandedTokens].join(" ").trim();
|
|
24
|
+
};
|
|
25
|
+
const calculateLargeNodePenalty = (document) => {
|
|
26
|
+
const lineSpan = document.endLine - document.startLine + 1;
|
|
27
|
+
if (lineSpan <= LARGE_NODE_LINE_THRESHOLD) {
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
return Math.min(MAX_LARGE_NODE_PENALTY, Math.log2(lineSpan / LARGE_NODE_LINE_THRESHOLD + 1) * 0.04);
|
|
31
|
+
};
|
|
32
|
+
const calculateDocumentFrequency = (documents) => {
|
|
33
|
+
const frequencyByToken = new Map();
|
|
34
|
+
for (const document of documents) {
|
|
35
|
+
const tokens = new Set(tokenizeMeaningfully(buildSearchText(document)));
|
|
36
|
+
for (const token of tokens) {
|
|
37
|
+
frequencyByToken.set(token, (frequencyByToken.get(token) ?? 0) + 1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return frequencyByToken;
|
|
41
|
+
};
|
|
42
|
+
export const calculateIdfScore = (queryTokens, candidateTokens, documentFrequency, documentCount) => {
|
|
43
|
+
if (queryTokens.length === 0 || candidateTokens.length === 0) {
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
const uniqueQueryTokens = [...new Set(queryTokens)];
|
|
47
|
+
const matchedWeight = uniqueQueryTokens.reduce((score, token) => {
|
|
48
|
+
const hasMatch = candidateTokens.some((candidateToken) => candidateToken === token);
|
|
49
|
+
if (!hasMatch) {
|
|
50
|
+
return score;
|
|
51
|
+
}
|
|
52
|
+
const frequency = documentFrequency.get(token) ?? documentCount;
|
|
53
|
+
return score + Math.log((documentCount + 1) / (frequency + 1)) + 1;
|
|
54
|
+
}, 0);
|
|
55
|
+
const maxWeight = uniqueQueryTokens.reduce((score, token) => {
|
|
56
|
+
const frequency = documentFrequency.get(token) ?? documentCount;
|
|
57
|
+
return score + Math.log((documentCount + 1) / (frequency + 1)) + 1;
|
|
58
|
+
}, 0);
|
|
59
|
+
return matchedWeight / maxWeight;
|
|
60
|
+
};
|
|
61
|
+
export const calculateFieldScore = (question, document) => {
|
|
62
|
+
const nameScore = lexicalOverlapScore(question, document.name);
|
|
63
|
+
const pathScore = lexicalOverlapScore(question, document.filePath);
|
|
64
|
+
const summaryScore = lexicalOverlapScore(question, document.summary);
|
|
65
|
+
const signatureScore = lexicalOverlapScore(question, document.signature ?? "");
|
|
66
|
+
return nameScore * 0.35 + summaryScore * 0.3 + pathScore * 0.2 + signatureScore * 0.15;
|
|
67
|
+
};
|
|
68
|
+
const calculateInitialLexicalScore = (question, document) => calculateFieldScore(question, document) + lexicalOverlapScore(question, document.doc) * 0.2;
|
|
69
|
+
const selectLexicalCandidates = (question, documents, retrieval) => [...documents]
|
|
70
|
+
.sort((left, right) => calculateInitialLexicalScore(question, right) - calculateInitialLexicalScore(question, left))
|
|
71
|
+
.slice(0, Math.max(retrieval.topK * LEXICAL_MULTIPLIER, retrieval.rerankK));
|
|
72
|
+
const collectSemanticCandidates = async (queryVector, retrieval, vectorStore) => {
|
|
73
|
+
if (!vectorStore) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
return await vectorStore.search(queryVector, Math.max(retrieval.topK * SEMANTIC_MULTIPLIER, retrieval.rerankK));
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const mergeCandidates = (documents, semanticCandidates, lexicalCandidates) => {
|
|
84
|
+
const mergedByNodeId = new Map();
|
|
85
|
+
for (const candidate of [...semanticCandidates, ...lexicalCandidates]) {
|
|
86
|
+
mergedByNodeId.set(candidate.nodeId, documents[candidate.nodeId] ?? candidate);
|
|
87
|
+
}
|
|
88
|
+
return [...mergedByNodeId.values()];
|
|
89
|
+
};
|
|
90
|
+
const scoreDocument = (question, queryVector, queryTokens, document, documentFrequency, documentCount) => {
|
|
91
|
+
const normalizedQuestion = normalizeQuestion(question);
|
|
92
|
+
const searchText = buildSearchText(document);
|
|
93
|
+
const candidateTokens = tokenizeMeaningfully(searchText);
|
|
94
|
+
const vectorScore = cosineSimilarity(queryVector, document.vector);
|
|
95
|
+
const lexicalScore = lexicalOverlapScore(question, searchText);
|
|
96
|
+
const fieldScore = calculateFieldScore(question, document);
|
|
97
|
+
const coverageScore = weightedTokenScore(queryTokens, candidateTokens);
|
|
98
|
+
const idfScore = calculateIdfScore(queryTokens, candidateTokens, documentFrequency, documentCount);
|
|
99
|
+
const symbolLikeQuery = isSymbolLikeQuery(question);
|
|
100
|
+
const exactNameBoost = Number(normalizedQuestion.includes(document.name.toLowerCase())) * (symbolLikeQuery ? 0.18 : 0.04);
|
|
101
|
+
const exactPathBoost = normalizedQuestion.includes(document.filePath.toLowerCase()) && symbolLikeQuery ? 0.14 : 0;
|
|
102
|
+
const symbolBoost = symbolLikeQuery && (exactNameBoost > 0 || exactPathBoost > 0) ? 0.1 : 0;
|
|
103
|
+
const largeNodePenalty = calculateLargeNodePenalty(document);
|
|
104
|
+
const finalScore = vectorScore * 0.28 +
|
|
105
|
+
lexicalScore * 0.18 +
|
|
106
|
+
fieldScore * 0.24 +
|
|
107
|
+
coverageScore * 0.15 +
|
|
108
|
+
idfScore * 0.05 +
|
|
109
|
+
exactNameBoost +
|
|
110
|
+
exactPathBoost +
|
|
111
|
+
symbolBoost -
|
|
112
|
+
largeNodePenalty;
|
|
113
|
+
return {
|
|
114
|
+
document,
|
|
115
|
+
vectorScore,
|
|
116
|
+
lexicalScore,
|
|
117
|
+
fieldScore,
|
|
118
|
+
coverageScore,
|
|
119
|
+
idfScore,
|
|
120
|
+
finalScore
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Builds a hybrid candidate set from the vector store and lexical ranking, then scores it.
|
|
125
|
+
*/
|
|
126
|
+
export const searchDocuments = async (question, documents, embeddingProvider, retrieval, vectorStore) => {
|
|
127
|
+
const documentList = Object.values(documents);
|
|
128
|
+
const expandedQuestion = expandQuestion(question);
|
|
129
|
+
const queryVector = await embeddingProvider.embed(expandedQuestion);
|
|
130
|
+
const queryTokens = tokenizeMeaningfully(expandedQuestion);
|
|
131
|
+
const semanticCandidates = await collectSemanticCandidates(queryVector, retrieval, vectorStore);
|
|
132
|
+
const lexicalCandidates = selectLexicalCandidates(expandedQuestion, documentList, retrieval);
|
|
133
|
+
const candidates = mergeCandidates(documents, semanticCandidates, lexicalCandidates);
|
|
134
|
+
const candidatePool = candidates.length > 0 ? candidates : documentList;
|
|
135
|
+
const documentFrequency = calculateDocumentFrequency(documentList);
|
|
136
|
+
return candidatePool
|
|
137
|
+
.map((document) => scoreDocument(expandedQuestion, queryVector, queryTokens, document, documentFrequency, documentList.length))
|
|
138
|
+
.sort((left, right) => right.finalScore - left.finalScore)
|
|
139
|
+
.slice(0, Math.max(retrieval.topK, retrieval.rerankK));
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Applies a smaller rerank pass that strongly favors exact symbol and path resolution.
|
|
143
|
+
*/
|
|
144
|
+
export const rerankResults = (question, results, retrieval) => {
|
|
145
|
+
const normalizedQuestion = normalizeQuestion(question);
|
|
146
|
+
const symbolLikeQuery = isSymbolLikeQuery(question);
|
|
147
|
+
return results
|
|
148
|
+
.map((result) => {
|
|
149
|
+
const exactNameMatch = normalizedQuestion === result.document.name.toLowerCase() ? 0.2 : 0;
|
|
150
|
+
const exactPathMatch = normalizedQuestion === result.document.filePath.toLowerCase() ? 0.18 : 0;
|
|
151
|
+
const directMentionBoost = normalizedQuestion.includes(result.document.name.toLowerCase())
|
|
152
|
+
? symbolLikeQuery
|
|
153
|
+
? 0.08
|
|
154
|
+
: 0.02
|
|
155
|
+
: 0;
|
|
156
|
+
return {
|
|
157
|
+
...result,
|
|
158
|
+
finalScore: result.finalScore + exactNameMatch + exactPathMatch + directMentionBoost
|
|
159
|
+
};
|
|
160
|
+
})
|
|
161
|
+
.sort((left, right) => right.finalScore - left.finalScore)
|
|
162
|
+
.slice(0, retrieval.rerankK);
|
|
163
|
+
};
|
|
164
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/retrieval/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BlueprintNode } from "@abhinav2203/codeflow-core/schema";
|
|
2
|
+
import type { GraphSnapshot } from "../types.js";
|
|
3
|
+
export declare const traverseDependencies: (snapshot: GraphSnapshot, nodeId: string, depth: number) => {
|
|
4
|
+
dependencies: BlueprintNode[];
|
|
5
|
+
dependents: BlueprintNode[];
|
|
6
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const traverseDependencies = (snapshot, nodeId, depth) => {
|
|
2
|
+
const dependencies = new Map();
|
|
3
|
+
const dependents = new Map();
|
|
4
|
+
const walk = (rootNodeId, currentNodeId, remainingDepth, direction, collector) => {
|
|
5
|
+
if (remainingDepth <= 0) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const candidateEdges = snapshot.graph.edges.filter((edge) => direction === "outgoing" ? edge.from === currentNodeId : edge.to === currentNodeId);
|
|
9
|
+
for (const edge of candidateEdges) {
|
|
10
|
+
const nextNodeId = direction === "outgoing" ? edge.to : edge.from;
|
|
11
|
+
if (nextNodeId === rootNodeId) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const node = snapshot.graph.nodes.find((candidate) => candidate.id === nextNodeId);
|
|
15
|
+
if (!node || collector.has(node.id)) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
collector.set(node.id, node);
|
|
19
|
+
walk(rootNodeId, node.id, remainingDepth - 1, direction, collector);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
walk(nodeId, nodeId, depth, "outgoing", dependencies);
|
|
23
|
+
walk(nodeId, nodeId, depth, "incoming", dependents);
|
|
24
|
+
return {
|
|
25
|
+
dependencies: [...dependencies.values()],
|
|
26
|
+
dependents: [...dependents.values()]
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=traversal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traversal.js","sourceRoot":"","sources":["../../src/retrieval/traversal.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,QAAuB,EACvB,MAAc,EACd,KAAa,EAIb,EAAE;IACF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;IACtD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEpD,MAAM,IAAI,GAAG,CACX,UAAkB,EAClB,aAAqB,EACrB,cAAsB,EACtB,SAAkC,EAClC,SAAqC,EACrC,EAAE;QACF,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC1D,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CACnF,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAClE,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;gBAC9B,SAAS;YACX,CAAC;YAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;YACnF,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,cAAc,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAEpD,OAAO;QACL,YAAY,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;QACxC,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;KACrC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { CodeRagConfig, ExplainResult, ImpactResult, IndexSummary, LookupResult, QueryOptions, QueryResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* High-level service API for indexing and querying a code repository.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CodeRag {
|
|
6
|
+
private readonly config;
|
|
7
|
+
private readonly indexer;
|
|
8
|
+
private readonly manifestStore;
|
|
9
|
+
private readonly fileCache;
|
|
10
|
+
private activeIndexPromise?;
|
|
11
|
+
private loadedState?;
|
|
12
|
+
constructor(config: CodeRagConfig);
|
|
13
|
+
private hydrateState;
|
|
14
|
+
private runIndex;
|
|
15
|
+
private ensureLoadedState;
|
|
16
|
+
private findNodeOrThrow;
|
|
17
|
+
/**
|
|
18
|
+
* Builds or rebuilds the on-disk index for the configured repository.
|
|
19
|
+
* If docsPath is provided, reads .md files from that directory (named by node ID)
|
|
20
|
+
* and uses their content as the embedding text instead of generating thin markdown.
|
|
21
|
+
*/
|
|
22
|
+
index(options?: {
|
|
23
|
+
docsPath?: string;
|
|
24
|
+
}): Promise<IndexSummary>;
|
|
25
|
+
/**
|
|
26
|
+
* Reindexes the repository, incrementally by default.
|
|
27
|
+
* If docsPath is provided, reads .md files from that directory (named by node ID)
|
|
28
|
+
* and uses their content as the embedding text instead of generating thin markdown.
|
|
29
|
+
*/
|
|
30
|
+
reindex(options?: {
|
|
31
|
+
full?: boolean;
|
|
32
|
+
docsPath?: string;
|
|
33
|
+
}): Promise<IndexSummary>;
|
|
34
|
+
/**
|
|
35
|
+
* Returns the current repository and runtime status.
|
|
36
|
+
*/
|
|
37
|
+
status(): Promise<Record<string, unknown>>;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves a graph node by identifier and returns its local graph context.
|
|
40
|
+
*/
|
|
41
|
+
lookup(identifier: string): Promise<LookupResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Summarizes a node and its surrounding dependencies.
|
|
44
|
+
*/
|
|
45
|
+
explain(identifier: string, depth?: number): Promise<ExplainResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Returns the upstream impact of changing a node.
|
|
48
|
+
*/
|
|
49
|
+
impact(identifier: string, depth?: number): Promise<ImpactResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Answers a natural-language question with retrieved context and an optional LLM answer.
|
|
52
|
+
*/
|
|
53
|
+
query(question: string, options?: QueryOptions): Promise<QueryResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Releases resources held by the service.
|
|
56
|
+
*/
|
|
57
|
+
close(): Promise<void>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { NotFoundError } from "../errors/index.js";
|
|
2
|
+
import { buildContextPackage } from "../llm/context-builder.js";
|
|
3
|
+
import { buildMessages } from "../llm/prompt.js";
|
|
4
|
+
import { RepoIndexer } from "../indexer/indexer.js";
|
|
5
|
+
import { rerankResults, searchDocuments } from "../retrieval/search.js";
|
|
6
|
+
import { traverseDependencies } from "../retrieval/traversal.js";
|
|
7
|
+
import { FileCache } from "../store/file-cache.js";
|
|
8
|
+
import { ManifestStore } from "../store/manifest-store.js";
|
|
9
|
+
const fallbackAnswerFromContext = (context) => {
|
|
10
|
+
if (!context.primaryNode) {
|
|
11
|
+
return "No matching code node was found in the current index.";
|
|
12
|
+
}
|
|
13
|
+
const relatedNames = context.relatedNodes.map((node) => node.name);
|
|
14
|
+
const relationshipSummary = relatedNames.length > 0 ? ` Related nodes: ${relatedNames.join(", ")}.` : "";
|
|
15
|
+
return `${context.graphSummary}${relationshipSummary}`;
|
|
16
|
+
};
|
|
17
|
+
const isStateLoaded = (snapshot, documents) => Boolean(snapshot) && Object.keys(documents).length > 0;
|
|
18
|
+
/**
|
|
19
|
+
* High-level service API for indexing and querying a code repository.
|
|
20
|
+
*/
|
|
21
|
+
export class CodeRag {
|
|
22
|
+
config;
|
|
23
|
+
indexer;
|
|
24
|
+
manifestStore;
|
|
25
|
+
fileCache = new FileCache();
|
|
26
|
+
activeIndexPromise;
|
|
27
|
+
loadedState;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.config = config;
|
|
30
|
+
this.indexer = new RepoIndexer(config);
|
|
31
|
+
this.manifestStore = new ManifestStore(config.storageRoot);
|
|
32
|
+
}
|
|
33
|
+
hydrateState(snapshot, documents) {
|
|
34
|
+
const state = { snapshot, documents };
|
|
35
|
+
this.loadedState = state;
|
|
36
|
+
return state;
|
|
37
|
+
}
|
|
38
|
+
async runIndex(forceFull, docsPath) {
|
|
39
|
+
if (!this.activeIndexPromise) {
|
|
40
|
+
this.activeIndexPromise = this.indexer
|
|
41
|
+
.index(forceFull, docsPath)
|
|
42
|
+
.then(async (summary) => {
|
|
43
|
+
const documents = await this.manifestStore.loadDocuments();
|
|
44
|
+
this.hydrateState(summary.snapshot, documents);
|
|
45
|
+
return summary;
|
|
46
|
+
})
|
|
47
|
+
.finally(() => {
|
|
48
|
+
this.activeIndexPromise = undefined;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return this.activeIndexPromise;
|
|
52
|
+
}
|
|
53
|
+
async ensureLoadedState() {
|
|
54
|
+
if (this.loadedState) {
|
|
55
|
+
return this.loadedState;
|
|
56
|
+
}
|
|
57
|
+
const state = await this.indexer.loadState();
|
|
58
|
+
if (isStateLoaded(state.snapshot, state.documents)) {
|
|
59
|
+
return this.hydrateState(state.snapshot, state.documents);
|
|
60
|
+
}
|
|
61
|
+
const waitedState = await this.indexer.waitForUnlockedState();
|
|
62
|
+
if (isStateLoaded(waitedState.snapshot, waitedState.documents)) {
|
|
63
|
+
return this.hydrateState(waitedState.snapshot, waitedState.documents);
|
|
64
|
+
}
|
|
65
|
+
await this.runIndex(false);
|
|
66
|
+
return this.loadedState;
|
|
67
|
+
}
|
|
68
|
+
findNodeOrThrow(identifier, snapshot) {
|
|
69
|
+
const normalizedIdentifier = identifier.toLowerCase();
|
|
70
|
+
const exactMatch = snapshot.graph.nodes.find((node) => node.id === identifier) ??
|
|
71
|
+
snapshot.graph.nodes.find((node) => node.name.toLowerCase() === normalizedIdentifier) ??
|
|
72
|
+
snapshot.graph.nodes.find((node) => node.path?.toLowerCase() === normalizedIdentifier);
|
|
73
|
+
if (exactMatch) {
|
|
74
|
+
return exactMatch;
|
|
75
|
+
}
|
|
76
|
+
const fuzzyMatch = snapshot.graph.nodes.find((node) => node.name.toLowerCase().includes(normalizedIdentifier) ||
|
|
77
|
+
node.path?.toLowerCase().includes(normalizedIdentifier));
|
|
78
|
+
if (!fuzzyMatch) {
|
|
79
|
+
throw new NotFoundError(`Unable to resolve a graph node for "${identifier}".`);
|
|
80
|
+
}
|
|
81
|
+
return fuzzyMatch;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Builds or rebuilds the on-disk index for the configured repository.
|
|
85
|
+
* If docsPath is provided, reads .md files from that directory (named by node ID)
|
|
86
|
+
* and uses their content as the embedding text instead of generating thin markdown.
|
|
87
|
+
*/
|
|
88
|
+
async index(options) {
|
|
89
|
+
return this.runIndex(true, options?.docsPath);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Reindexes the repository, incrementally by default.
|
|
93
|
+
* If docsPath is provided, reads .md files from that directory (named by node ID)
|
|
94
|
+
* and uses their content as the embedding text instead of generating thin markdown.
|
|
95
|
+
*/
|
|
96
|
+
async reindex(options) {
|
|
97
|
+
return this.runIndex(Boolean(options?.full), options?.docsPath);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Returns the current repository and runtime status.
|
|
101
|
+
*/
|
|
102
|
+
async status() {
|
|
103
|
+
const state = await this.indexer.loadState();
|
|
104
|
+
return {
|
|
105
|
+
indexed: Boolean(state.snapshot),
|
|
106
|
+
indexedNodeCount: Object.keys(state.documents).length,
|
|
107
|
+
generatedAt: state.snapshot?.generatedAt ?? null,
|
|
108
|
+
repoPath: this.config.repoPath,
|
|
109
|
+
storageRoot: this.config.storageRoot,
|
|
110
|
+
provider: state.snapshot?.provider ?? this.config.graphProvider?.name ?? null,
|
|
111
|
+
llmEnabled: this.config.llm.enabled
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Resolves a graph node by identifier and returns its local graph context.
|
|
116
|
+
*/
|
|
117
|
+
async lookup(identifier) {
|
|
118
|
+
const { snapshot, documents } = await this.ensureLoadedState();
|
|
119
|
+
const node = this.findNodeOrThrow(identifier, snapshot);
|
|
120
|
+
return {
|
|
121
|
+
node,
|
|
122
|
+
span: snapshot.sourceSpans[node.id],
|
|
123
|
+
outgoingEdges: snapshot.graph.edges.filter((edge) => edge.from === node.id),
|
|
124
|
+
incomingEdges: snapshot.graph.edges.filter((edge) => edge.to === node.id),
|
|
125
|
+
doc: documents[node.id]
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Summarizes a node and its surrounding dependencies.
|
|
130
|
+
*/
|
|
131
|
+
async explain(identifier, depth = this.config.traversal.defaultDepth) {
|
|
132
|
+
const { snapshot } = await this.ensureLoadedState();
|
|
133
|
+
const node = this.findNodeOrThrow(identifier, snapshot);
|
|
134
|
+
const { dependencies, dependents } = traverseDependencies(snapshot, node.id, depth);
|
|
135
|
+
return {
|
|
136
|
+
node,
|
|
137
|
+
summary: `${node.summary} Dependencies: ${dependencies.map((candidate) => candidate.name).join(", ") || "none"}. Dependents: ${dependents.map((candidate) => candidate.name).join(", ") || "none"}.`,
|
|
138
|
+
dependencies,
|
|
139
|
+
dependents,
|
|
140
|
+
span: snapshot.sourceSpans[node.id]
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Returns the upstream impact of changing a node.
|
|
145
|
+
*/
|
|
146
|
+
async impact(identifier, depth = this.config.traversal.defaultDepth) {
|
|
147
|
+
const { snapshot } = await this.ensureLoadedState();
|
|
148
|
+
const node = this.findNodeOrThrow(identifier, snapshot);
|
|
149
|
+
const { dependents } = traverseDependencies(snapshot, node.id, depth);
|
|
150
|
+
return {
|
|
151
|
+
node,
|
|
152
|
+
impactedNodes: dependents,
|
|
153
|
+
graphSummary: dependents.length > 0
|
|
154
|
+
? `${node.name} is upstream of ${dependents.map((candidate) => candidate.name).join(", ")}.`
|
|
155
|
+
: `${node.name} has no upstream dependents within depth ${depth}.`
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Answers a natural-language question with retrieved context and an optional LLM answer.
|
|
160
|
+
*/
|
|
161
|
+
async query(question, options = {}) {
|
|
162
|
+
const { snapshot, documents } = await this.ensureLoadedState();
|
|
163
|
+
const embeddingProvider = this.config.embeddingProvider;
|
|
164
|
+
if (!embeddingProvider) {
|
|
165
|
+
throw new NotFoundError("No embedding provider is configured.");
|
|
166
|
+
}
|
|
167
|
+
const searchResults = rerankResults(question, await searchDocuments(question, documents, embeddingProvider, this.config.retrieval, this.config.vectorStore), this.config.retrieval);
|
|
168
|
+
const primaryDocument = searchResults[0]?.document;
|
|
169
|
+
const primaryNode = primaryDocument
|
|
170
|
+
? snapshot.graph.nodes.find((node) => node.id === primaryDocument.nodeId)
|
|
171
|
+
: undefined;
|
|
172
|
+
const depth = Math.min(options.depth ?? this.config.traversal.defaultDepth, this.config.traversal.maxDepth);
|
|
173
|
+
const { dependencies, dependents } = primaryNode
|
|
174
|
+
? traverseDependencies(snapshot, primaryNode.id, depth)
|
|
175
|
+
: { dependencies: [], dependents: [] };
|
|
176
|
+
const answerMode = options.includeAnswer === false || !this.config.llm.enabled || !this.config.llmTransport ? "context-only" : "llm";
|
|
177
|
+
const context = await buildContextPackage(question, this.config.repoPath, snapshot, documents, this.config.retrieval, this.fileCache, primaryNode, dependencies, dependents, answerMode);
|
|
178
|
+
if (answerMode === "context-only") {
|
|
179
|
+
return {
|
|
180
|
+
question,
|
|
181
|
+
answerMode,
|
|
182
|
+
answer: fallbackAnswerFromContext(context),
|
|
183
|
+
context
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const llmResponse = await this.config.llmTransport.generate({
|
|
187
|
+
question,
|
|
188
|
+
model: this.config.llm.model,
|
|
189
|
+
stream: Boolean(options.onToken),
|
|
190
|
+
context,
|
|
191
|
+
messages: buildMessages(question, context)
|
|
192
|
+
}, options.onToken);
|
|
193
|
+
return {
|
|
194
|
+
question,
|
|
195
|
+
answerMode,
|
|
196
|
+
answer: llmResponse.answer,
|
|
197
|
+
context
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Releases resources held by the service.
|
|
202
|
+
*/
|
|
203
|
+
async close() {
|
|
204
|
+
this.fileCache.clear();
|
|
205
|
+
await this.config.vectorStore?.close();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=coderag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coderag.js","sourceRoot":"","sources":["../../src/service/coderag.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAmB3D,MAAM,yBAAyB,GAAG,CAAC,OAAuB,EAAU,EAAE;IACpE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACzB,OAAO,uDAAuD,CAAC;IACjE,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACzG,OAAO,GAAG,OAAO,CAAC,YAAY,GAAG,mBAAmB,EAAE,CAAC;AACzD,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CACpB,QAA8B,EAC9B,SAA8C,EACnB,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAEvF;;GAEG;AACH,MAAM,OAAO,OAAO;IAOW;IANZ,OAAO,CAAc;IACrB,aAAa,CAAgB;IAC7B,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IACrC,kBAAkB,CAAyB;IAC3C,WAAW,CAAe;IAElC,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;QAChD,IAAI,CAAC,OAAO,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC7D,CAAC;IAEO,YAAY,CAAC,QAAuB,EAAE,SAA8C;QAC1F,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,SAAkB,EAAE,QAAiB;QAC1D,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO;iBACnC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC;iBAC1B,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;gBACtB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;gBAC3D,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;gBAC/C,OAAO,OAAO,CAAC;YACjB,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE;gBACZ,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;YACtC,CAAC,CAAC,CAAC;QACP,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,WAAW,CAAC;QAC1B,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC7C,IAAI,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAC9D,IAAI,aAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,WAAY,CAAC;IAC3B,CAAC;IAEO,eAAe,CAAC,UAAkB,EAAE,QAAuB;QACjE,MAAM,oBAAoB,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QACtD,MAAM,UAAU,GACd,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,UAAU,CAAC;YAC3D,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,oBAAoB,CAAC;YACrF,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,oBAAoB,CAAC,CAAC;QAEzF,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAC1C,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YACtD,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAC1D,CAAC;QACF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,aAAa,CAAC,uCAAuC,UAAU,IAAI,CAAC,CAAC;QACjF,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,OAA+B;QACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,OAA+C;QAC3D,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC7C,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;YAChC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM;YACrD,WAAW,EAAE,KAAK,CAAC,QAAQ,EAAE,WAAW,IAAI,IAAI;YAChD,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,IAAI,IAAI;YAC7E,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;SACpC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,UAAkB;QAC7B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAExD,OAAO;YACL,IAAI;YACJ,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC3E,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YACzE,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;SACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,UAAkB,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY;QAC1E,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACxD,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAEpF,OAAO;YACL,IAAI;YACJ,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,kBAAkB,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,iBAAiB,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG;YACpM,YAAY;YACZ,UAAU;YACV,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;SACpC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY;QACzE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACxD,MAAM,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAEtE,OAAO;YACL,IAAI;YACJ,aAAa,EAAE,UAAU;YACzB,YAAY,EACV,UAAU,CAAC,MAAM,GAAG,CAAC;gBACnB,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,mBAAmB,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;gBAC5F,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,4CAA4C,KAAK,GAAG;SACvE,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,UAAwB,EAAE;QACtD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/D,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;QACxD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,aAAa,CAAC,sCAAsC,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,aAAa,GAAG,aAAa,CACjC,QAAQ,EACR,MAAM,eAAe,CACnB,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,IAAI,CAAC,MAAM,CAAC,SAAS,EACrB,IAAI,CAAC,MAAM,CAAC,WAAW,CACxB,EACD,IAAI,CAAC,MAAM,CAAC,SAAS,CACtB,CAAC;QACF,MAAM,eAAe,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;QACnD,MAAM,WAAW,GAAG,eAAe;YACjC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,eAAe,CAAC,MAAM,CAAC;YACzE,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC5G,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,WAAW;YAC9C,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC;YACvD,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QACzC,MAAM,UAAU,GACd,OAAO,CAAC,aAAa,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC;QACpH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CACvC,QAAQ,EACR,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,QAAQ,EACR,SAAS,EACT,IAAI,CAAC,MAAM,CAAC,SAAS,EACrB,IAAI,CAAC,SAAS,EACd,WAAW,EACX,YAAY,EACZ,UAAU,EACV,UAAU,CACX,CAAC;QAEF,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;YAClC,OAAO;gBACL,QAAQ;gBACR,UAAU;gBACV,MAAM,EAAE,yBAAyB,CAAC,OAAO,CAAC;gBAC1C,OAAO;aACR,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAa,CAAC,QAAQ,CAC1D;YACE,QAAQ;YACR,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK;YAC5B,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;YAChC,OAAO;YACP,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC;SAC3C,EACD,OAAO,CAAC,OAAO,CAChB,CAAC;QAEF,OAAO;YACL,QAAQ;YACR,UAAU;YACV,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;CACF"}
|