@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,108 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { buildGraphSnapshot } from "../adapters/codeflow-core.js";
|
|
3
|
+
import { IndexingError } from "../errors/index.js";
|
|
4
|
+
import { ManifestStore } from "../store/manifest-store.js";
|
|
5
|
+
import { IndexLock } from "../store/index-lock.js";
|
|
6
|
+
import { buildIndexManifest, buildIndexedDocuments } from "./documents.js";
|
|
7
|
+
const diffNodeIds = (previousManifest, nextManifest) => {
|
|
8
|
+
if (!previousManifest) {
|
|
9
|
+
return {
|
|
10
|
+
removedNodeIds: [],
|
|
11
|
+
changedNodeIds: Object.keys(nextManifest.nodes)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const previousIds = new Set(Object.keys(previousManifest.nodes));
|
|
15
|
+
const nextIds = new Set(Object.keys(nextManifest.nodes));
|
|
16
|
+
const removedNodeIds = [...previousIds].filter((nodeId) => !nextIds.has(nodeId));
|
|
17
|
+
const changedNodeIds = Object.entries(nextManifest.nodes)
|
|
18
|
+
.filter(([nodeId, entry]) => {
|
|
19
|
+
const previousEntry = previousManifest.nodes[nodeId];
|
|
20
|
+
return !previousEntry || previousEntry.docHash !== entry.docHash || previousEntry.fileHash !== entry.fileHash;
|
|
21
|
+
})
|
|
22
|
+
.map(([nodeId]) => nodeId);
|
|
23
|
+
return {
|
|
24
|
+
removedNodeIds,
|
|
25
|
+
changedNodeIds
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const buildIndexSummary = (snapshot, manifest, documents) => ({
|
|
29
|
+
graph: snapshot.graph,
|
|
30
|
+
manifest,
|
|
31
|
+
snapshot,
|
|
32
|
+
indexedNodeCount: Object.keys(documents).length
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Indexes the repository graph and persists the resulting search documents.
|
|
36
|
+
*/
|
|
37
|
+
export class RepoIndexer {
|
|
38
|
+
config;
|
|
39
|
+
manifestStore;
|
|
40
|
+
indexLock;
|
|
41
|
+
constructor(config) {
|
|
42
|
+
this.config = config;
|
|
43
|
+
this.manifestStore = new ManifestStore(config.storageRoot);
|
|
44
|
+
this.indexLock = new IndexLock(config.storageRoot, config.locking, config.logger);
|
|
45
|
+
}
|
|
46
|
+
async loadState() {
|
|
47
|
+
const [manifest, snapshot, documents] = await Promise.all([
|
|
48
|
+
this.manifestStore.loadManifest(),
|
|
49
|
+
this.manifestStore.loadSnapshot(),
|
|
50
|
+
this.manifestStore.loadDocuments()
|
|
51
|
+
]);
|
|
52
|
+
return {
|
|
53
|
+
manifest,
|
|
54
|
+
snapshot,
|
|
55
|
+
documents
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async waitForUnlockedState() {
|
|
59
|
+
const waited = await this.indexLock.waitForRelease();
|
|
60
|
+
return {
|
|
61
|
+
waited,
|
|
62
|
+
...(await this.loadState())
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async index(forceFull = false, docsPath) {
|
|
66
|
+
const graphProvider = this.config.graphProvider;
|
|
67
|
+
const embeddingProvider = this.config.embeddingProvider;
|
|
68
|
+
const vectorStore = this.config.vectorStore;
|
|
69
|
+
if (!graphProvider || !embeddingProvider || !vectorStore) {
|
|
70
|
+
throw new IndexingError("CodeRag is missing required indexing dependencies.");
|
|
71
|
+
}
|
|
72
|
+
return this.indexLock.withLock("index", async () => {
|
|
73
|
+
const { manifest: previousManifest } = await this.loadState();
|
|
74
|
+
const snapshot = await buildGraphSnapshot(this.config.repoPath, graphProvider);
|
|
75
|
+
const documents = await buildIndexedDocuments(snapshot, embeddingProvider, docsPath);
|
|
76
|
+
const manifest = await buildIndexManifest(this.config.repoPath, snapshot, documents);
|
|
77
|
+
const { removedNodeIds, changedNodeIds } = diffNodeIds(previousManifest, manifest);
|
|
78
|
+
try {
|
|
79
|
+
if (forceFull || !previousManifest) {
|
|
80
|
+
await vectorStore.reset(Object.values(documents));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
await vectorStore.deleteByNodeIds(removedNodeIds);
|
|
84
|
+
await vectorStore.upsert(changedNodeIds
|
|
85
|
+
.map((nodeId) => documents[nodeId])
|
|
86
|
+
.filter((document) => Boolean(document)));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
throw new IndexingError("Failed to persist indexed documents to the vector store.", {
|
|
91
|
+
repoPath: this.config.repoPath
|
|
92
|
+
}, { cause: error });
|
|
93
|
+
}
|
|
94
|
+
await Promise.all([
|
|
95
|
+
this.manifestStore.saveManifest(manifest),
|
|
96
|
+
this.manifestStore.saveSnapshot(snapshot),
|
|
97
|
+
this.manifestStore.saveDocuments(documents)
|
|
98
|
+
]);
|
|
99
|
+
this.config.logger?.info("Indexed repository", {
|
|
100
|
+
repoPath: path.resolve(this.config.repoPath),
|
|
101
|
+
indexedNodeCount: Object.keys(documents).length,
|
|
102
|
+
fullReindex: forceFull || !previousManifest
|
|
103
|
+
});
|
|
104
|
+
return buildIndexSummary(snapshot, manifest, documents);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/indexer/indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BlueprintNode } from "@abhinav2203/codeflow-core/schema";
|
|
2
|
+
import type { ContextPackage, GraphSnapshot, IndexedNodeDocument, RetrievalConfig } from "../types.js";
|
|
3
|
+
import { FileCache } from "../store/file-cache.js";
|
|
4
|
+
/**
|
|
5
|
+
* Builds the final context package passed to the LLM or returned directly to the caller.
|
|
6
|
+
*/
|
|
7
|
+
export declare const buildContextPackage: (question: string, repoPath: string, snapshot: GraphSnapshot, documents: Record<string, IndexedNodeDocument>, retrieval: RetrievalConfig, fileCache: FileCache, primaryNode: BlueprintNode | undefined, dependencies: BlueprintNode[], dependents: BlueprintNode[], answerMode: ContextPackage["answerMode"]) => Promise<ContextPackage>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createRetrievedNodeContext } from "../retrieval/page-index.js";
|
|
2
|
+
const buildGraphSummary = (primaryNode, dependencies, dependents) => {
|
|
3
|
+
if (!primaryNode) {
|
|
4
|
+
return "No matching node was retrieved from the current repository index.";
|
|
5
|
+
}
|
|
6
|
+
const parts = [`Primary node: ${primaryNode.name}.`];
|
|
7
|
+
if (dependencies.length > 0) {
|
|
8
|
+
parts.push(`It depends on: ${dependencies.map((node) => node.name).join(", ")}.`);
|
|
9
|
+
}
|
|
10
|
+
if (dependents.length > 0) {
|
|
11
|
+
parts.push(`It is used by: ${dependents.map((node) => node.name).join(", ")}.`);
|
|
12
|
+
}
|
|
13
|
+
return parts.join(" ");
|
|
14
|
+
};
|
|
15
|
+
const truncateContext = (context, maxChars, warnings) => {
|
|
16
|
+
if (context.fullFileContent.length <= maxChars) {
|
|
17
|
+
return context;
|
|
18
|
+
}
|
|
19
|
+
warnings.push(`Truncated ${context.filePath} to stay within the context budget.`);
|
|
20
|
+
return {
|
|
21
|
+
...context,
|
|
22
|
+
fullFileContent: context.fullFileContent.slice(0, Math.max(0, maxChars))
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const fitPrimaryContext = (primaryContext, maxContextChars) => {
|
|
26
|
+
if (!primaryContext) {
|
|
27
|
+
return {
|
|
28
|
+
primaryContext: null,
|
|
29
|
+
remainingBudget: maxContextChars,
|
|
30
|
+
warnings: []
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const warnings = [];
|
|
34
|
+
const fittedPrimaryContext = truncateContext(primaryContext, maxContextChars, warnings);
|
|
35
|
+
return {
|
|
36
|
+
primaryContext: fittedPrimaryContext,
|
|
37
|
+
remainingBudget: Math.max(0, maxContextChars - fittedPrimaryContext.fullFileContent.length),
|
|
38
|
+
warnings
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const fitRelatedContexts = (relatedContexts, remainingBudget) => {
|
|
42
|
+
const warnings = [];
|
|
43
|
+
const fittedContexts = [];
|
|
44
|
+
let budget = remainingBudget;
|
|
45
|
+
for (const context of relatedContexts) {
|
|
46
|
+
if (budget <= 0) {
|
|
47
|
+
warnings.push(`Dropped file content for ${context.filePath} because the context budget was exhausted.`);
|
|
48
|
+
fittedContexts.push({
|
|
49
|
+
...context,
|
|
50
|
+
fullFileContent: ""
|
|
51
|
+
});
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const fittedContext = truncateContext(context, budget, warnings);
|
|
55
|
+
budget = Math.max(0, budget - fittedContext.fullFileContent.length);
|
|
56
|
+
fittedContexts.push(fittedContext);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
relatedContexts: fittedContexts,
|
|
60
|
+
warnings
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const buildRelatedContextPromises = (repoPath, fileCache, snapshot, documents, primaryNode, dependencies, dependents) => [
|
|
64
|
+
...dependencies
|
|
65
|
+
.map((node) => documents[node.id])
|
|
66
|
+
.filter((document) => Boolean(document))
|
|
67
|
+
.map((document) => createRetrievedNodeContext(repoPath, fileCache, snapshot, document, "calls", primaryNode?.id)),
|
|
68
|
+
...dependents
|
|
69
|
+
.map((node) => documents[node.id])
|
|
70
|
+
.filter((document) => Boolean(document))
|
|
71
|
+
.map((document) => createRetrievedNodeContext(repoPath, fileCache, snapshot, document, "called-by", primaryNode?.id))
|
|
72
|
+
];
|
|
73
|
+
/**
|
|
74
|
+
* Builds the final context package passed to the LLM or returned directly to the caller.
|
|
75
|
+
*/
|
|
76
|
+
export const buildContextPackage = async (question, repoPath, snapshot, documents, retrieval, fileCache, primaryNode, dependencies, dependents, answerMode) => {
|
|
77
|
+
const primaryDocument = primaryNode ? documents[primaryNode.id] : undefined;
|
|
78
|
+
const primaryContext = primaryDocument
|
|
79
|
+
? await createRetrievedNodeContext(repoPath, fileCache, snapshot, primaryDocument, "primary")
|
|
80
|
+
: null;
|
|
81
|
+
const resolvedRelatedContexts = await Promise.all(buildRelatedContextPromises(repoPath, fileCache, snapshot, documents, primaryNode, dependencies, dependents));
|
|
82
|
+
const primaryResult = fitPrimaryContext(primaryContext, retrieval.maxContextChars);
|
|
83
|
+
const relatedResult = fitRelatedContexts(resolvedRelatedContexts, primaryResult.remainingBudget);
|
|
84
|
+
return {
|
|
85
|
+
question,
|
|
86
|
+
answerMode,
|
|
87
|
+
primaryNode: primaryResult.primaryContext,
|
|
88
|
+
relatedNodes: relatedResult.relatedContexts,
|
|
89
|
+
graphSummary: buildGraphSummary(primaryNode, dependencies, dependents),
|
|
90
|
+
warnings: [...primaryResult.warnings, ...relatedResult.warnings]
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=context-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../src/llm/context-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const PRIMARY_DOC_CHAR_LIMIT = 1_200;
|
|
2
|
+
const PRIMARY_FILE_CHAR_LIMIT = 4_000;
|
|
3
|
+
const RELATED_DOC_CHAR_LIMIT = 320;
|
|
4
|
+
const RELATED_FILE_CHAR_LIMIT = 1_200;
|
|
5
|
+
const WARNING_CHAR_LIMIT = 160;
|
|
6
|
+
const MAX_WARNING_COUNT = 4;
|
|
7
|
+
const truncateText = (value, maxChars) => {
|
|
8
|
+
if (value.length <= maxChars) {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
return `${value.slice(0, Math.max(0, maxChars - 15)).trimEnd()}\n...[truncated]`;
|
|
12
|
+
};
|
|
13
|
+
const formatCallSiteLines = (lineNumbers) => lineNumbers.length > 0 ? lineNumbers.join(", ") : "none";
|
|
14
|
+
const formatNodeHeader = (node) => [
|
|
15
|
+
`name=${node.name}`,
|
|
16
|
+
`relationship=${node.relationship}`,
|
|
17
|
+
`kind=${node.kind}`,
|
|
18
|
+
`file=${node.filePath}:${node.startLine}-${node.endLine}`,
|
|
19
|
+
`callSites=${formatCallSiteLines(node.callSiteLines)}`
|
|
20
|
+
].join(" | ");
|
|
21
|
+
const formatDocSection = (label, value, maxChars) => value.trim().length === 0 ? "" : `${label}:\n${truncateText(value, maxChars)}`;
|
|
22
|
+
const formatFileSection = (value, maxChars) => value.trim().length === 0 ? "" : `File excerpt:\n${truncateText(value, maxChars)}`;
|
|
23
|
+
const joinSections = (sections) => sections.filter(Boolean).join("\n\n");
|
|
24
|
+
const formatPrimaryNode = (node) => joinSections([
|
|
25
|
+
`Primary node:\n${formatNodeHeader(node)}`,
|
|
26
|
+
formatDocSection("Primary doc", node.doc, PRIMARY_DOC_CHAR_LIMIT),
|
|
27
|
+
formatFileSection(node.fullFileContent, PRIMARY_FILE_CHAR_LIMIT)
|
|
28
|
+
]);
|
|
29
|
+
const shouldIncludeRelatedFile = (node, primaryNode, includedFiles) => !includedFiles.has(node.filePath) && node.filePath !== primaryNode?.filePath;
|
|
30
|
+
const formatRelatedNode = (node, primaryNode, includedFiles) => {
|
|
31
|
+
const includeFile = shouldIncludeRelatedFile(node, primaryNode, includedFiles);
|
|
32
|
+
if (includeFile) {
|
|
33
|
+
includedFiles.add(node.filePath);
|
|
34
|
+
}
|
|
35
|
+
return joinSections([
|
|
36
|
+
formatNodeHeader(node),
|
|
37
|
+
formatDocSection("Related doc", node.doc, RELATED_DOC_CHAR_LIMIT),
|
|
38
|
+
includeFile ? formatFileSection(node.fullFileContent, RELATED_FILE_CHAR_LIMIT) : ""
|
|
39
|
+
]);
|
|
40
|
+
};
|
|
41
|
+
const formatRelatedNodes = (relatedNodes, primaryNode) => {
|
|
42
|
+
if (relatedNodes.length === 0) {
|
|
43
|
+
return "Related nodes:\nnone";
|
|
44
|
+
}
|
|
45
|
+
const includedFiles = new Set(primaryNode ? [primaryNode.filePath] : []);
|
|
46
|
+
const entries = relatedNodes.map((node, index) => `${index + 1}. ${formatRelatedNode(node, primaryNode, includedFiles)}`);
|
|
47
|
+
return `Related nodes:\n${entries.join("\n\n")}`;
|
|
48
|
+
};
|
|
49
|
+
const formatWarnings = (warnings) => {
|
|
50
|
+
if (warnings.length === 0) {
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
53
|
+
const entries = warnings
|
|
54
|
+
.slice(0, MAX_WARNING_COUNT)
|
|
55
|
+
.map((warning, index) => `${index + 1}. ${truncateText(warning, WARNING_CHAR_LIMIT)}`);
|
|
56
|
+
return `Warnings:\n${entries.join("\n")}`;
|
|
57
|
+
};
|
|
58
|
+
const summarizeContext = (context) => joinSections([
|
|
59
|
+
`Graph summary:\n${context.graphSummary}`,
|
|
60
|
+
context.primaryNode ? formatPrimaryNode(context.primaryNode) : "Primary node:\nnone",
|
|
61
|
+
formatRelatedNodes(context.relatedNodes, context.primaryNode),
|
|
62
|
+
formatWarnings(context.warnings)
|
|
63
|
+
]);
|
|
64
|
+
export const buildSystemPrompt = () => [
|
|
65
|
+
"You are answering questions about a codebase.",
|
|
66
|
+
"Only use the provided repository context.",
|
|
67
|
+
"If the context is insufficient, say so plainly.",
|
|
68
|
+
"Do not invent functions, files, or behavior that is not present in the retrieved context."
|
|
69
|
+
].join(" ");
|
|
70
|
+
export const buildMessages = (question, context) => [
|
|
71
|
+
{
|
|
72
|
+
role: "system",
|
|
73
|
+
content: buildSystemPrompt()
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
role: "user",
|
|
77
|
+
content: `Question:\n${question}\n\n${summarizeContext(context)}`
|
|
78
|
+
}
|
|
79
|
+
];
|
|
80
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/llm/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { LlmConfig, LlmRequest, LlmResponse, LlmTransport } from "../types.js";
|
|
2
|
+
declare abstract class HttpLlmTransport implements LlmTransport {
|
|
3
|
+
abstract readonly kind: LlmTransport["kind"];
|
|
4
|
+
protected readonly config: LlmConfig;
|
|
5
|
+
constructor(config: LlmConfig);
|
|
6
|
+
protected postJson(pathname: string, body: unknown): Promise<Response>;
|
|
7
|
+
abstract generate(request: LlmRequest, onToken?: (token: string) => void): Promise<LlmResponse>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Talks to any model server that exposes the OpenAI chat completions contract.
|
|
11
|
+
*/
|
|
12
|
+
export declare class OpenAiCompatibleTransport extends HttpLlmTransport {
|
|
13
|
+
readonly kind: "openai-compatible";
|
|
14
|
+
generate(request: LlmRequest, onToken?: (token: string) => void): Promise<LlmResponse>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Talks to a custom JSON, NDJSON, or SSE endpoint that accepts the CodeRag payload.
|
|
18
|
+
*/
|
|
19
|
+
export declare class CustomHttpTransport extends HttpLlmTransport {
|
|
20
|
+
readonly kind: "custom-http";
|
|
21
|
+
generate(request: LlmRequest, onToken?: (token: string) => void): Promise<LlmResponse>;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { ConfigurationError, TransportError } from "../errors/index.js";
|
|
2
|
+
const RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
3
|
+
const MAX_HTTP_RETRIES = 3;
|
|
4
|
+
const RETRY_BASE_DELAY_MS = 150;
|
|
5
|
+
const buildHeaders = (config) => {
|
|
6
|
+
const headers = {
|
|
7
|
+
"content-type": "application/json",
|
|
8
|
+
...config.headers
|
|
9
|
+
};
|
|
10
|
+
if (config.apiKey) {
|
|
11
|
+
headers.authorization = `Bearer ${config.apiKey}`;
|
|
12
|
+
}
|
|
13
|
+
return headers;
|
|
14
|
+
};
|
|
15
|
+
const waitBeforeRetry = async (attempt) => {
|
|
16
|
+
const jitterMs = Math.floor(Math.random() * RETRY_BASE_DELAY_MS);
|
|
17
|
+
const delayMs = RETRY_BASE_DELAY_MS * 2 ** attempt + jitterMs;
|
|
18
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
19
|
+
};
|
|
20
|
+
const shouldRetryStatus = (status) => RETRYABLE_STATUS_CODES.has(status);
|
|
21
|
+
const mergeSystemMessagesIntoConversation = (messages) => {
|
|
22
|
+
const systemPrompt = messages
|
|
23
|
+
.filter((message) => message.role === "system")
|
|
24
|
+
.map((message) => message.content.trim())
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.join("\n\n");
|
|
27
|
+
if (!systemPrompt) {
|
|
28
|
+
return messages;
|
|
29
|
+
}
|
|
30
|
+
const nonSystemMessages = messages.filter((message) => message.role !== "system");
|
|
31
|
+
const firstUserMessageIndex = nonSystemMessages.findIndex((message) => message.role === "user");
|
|
32
|
+
if (firstUserMessageIndex === -1) {
|
|
33
|
+
return [{ role: "user", content: systemPrompt }, ...nonSystemMessages];
|
|
34
|
+
}
|
|
35
|
+
const firstUserMessage = nonSystemMessages[firstUserMessageIndex];
|
|
36
|
+
const mergedUserMessage = {
|
|
37
|
+
...firstUserMessage,
|
|
38
|
+
content: `${systemPrompt}\n\n${firstUserMessage.content}`.trim()
|
|
39
|
+
};
|
|
40
|
+
return [
|
|
41
|
+
...nonSystemMessages.slice(0, firstUserMessageIndex),
|
|
42
|
+
mergedUserMessage,
|
|
43
|
+
...nonSystemMessages.slice(firstUserMessageIndex + 1)
|
|
44
|
+
];
|
|
45
|
+
};
|
|
46
|
+
const isUnsupportedSystemRoleError = (error) => {
|
|
47
|
+
if (!(error instanceof TransportError)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const status = error.details?.status;
|
|
51
|
+
const body = error.details?.body;
|
|
52
|
+
return status === 400 && typeof body === "string" && body.toLowerCase().includes("system role not supported");
|
|
53
|
+
};
|
|
54
|
+
const buildRequestUrl = (baseUrl, pathname) => {
|
|
55
|
+
const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
56
|
+
if (pathname === "/" || pathname.length === 0) {
|
|
57
|
+
return new URL(normalizedBaseUrl);
|
|
58
|
+
}
|
|
59
|
+
const normalizedPath = pathname.replace(/^\/+/, "");
|
|
60
|
+
return new URL(normalizedPath, normalizedBaseUrl);
|
|
61
|
+
};
|
|
62
|
+
const readResponseText = async (response) => {
|
|
63
|
+
const text = await response.text();
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw new TransportError("LLM server returned an error response.", {
|
|
66
|
+
status: response.status,
|
|
67
|
+
body: text
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return text;
|
|
71
|
+
};
|
|
72
|
+
const extractAnswerToken = (payload) => {
|
|
73
|
+
if (typeof payload.token === "string") {
|
|
74
|
+
return payload.token;
|
|
75
|
+
}
|
|
76
|
+
if (typeof payload.answer === "string") {
|
|
77
|
+
return payload.answer;
|
|
78
|
+
}
|
|
79
|
+
const content = payload.choices?.[0]?.delta?.content;
|
|
80
|
+
return typeof content === "string" ? content : "";
|
|
81
|
+
};
|
|
82
|
+
const parseSseEvent = (rawEvent) => rawEvent
|
|
83
|
+
.split("\n")
|
|
84
|
+
.map((line) => line.trim())
|
|
85
|
+
.filter((line) => line.startsWith("data:"))
|
|
86
|
+
.map((line) => line.slice("data:".length).trim())
|
|
87
|
+
.filter((payload) => payload.length > 0 && payload !== "[DONE]");
|
|
88
|
+
const readSseResponse = async (response, onToken) => {
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
await readResponseText(response);
|
|
91
|
+
}
|
|
92
|
+
if (!response.body) {
|
|
93
|
+
throw new TransportError("SSE response did not include a body.");
|
|
94
|
+
}
|
|
95
|
+
const reader = response.body.getReader();
|
|
96
|
+
const decoder = new TextDecoder();
|
|
97
|
+
let buffer = "";
|
|
98
|
+
let answer = "";
|
|
99
|
+
while (true) {
|
|
100
|
+
const { value, done } = await reader.read();
|
|
101
|
+
if (done) {
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
buffer += decoder.decode(value, { stream: true });
|
|
105
|
+
const events = buffer.split(/\r?\n\r?\n/);
|
|
106
|
+
buffer = events.pop();
|
|
107
|
+
for (const event of events) {
|
|
108
|
+
for (const payload of parseSseEvent(event)) {
|
|
109
|
+
const token = extractAnswerToken(JSON.parse(payload));
|
|
110
|
+
if (!token) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
answer += token;
|
|
114
|
+
onToken?.(token);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (buffer.trim().length > 0) {
|
|
119
|
+
for (const payload of parseSseEvent(buffer)) {
|
|
120
|
+
const token = extractAnswerToken(JSON.parse(payload));
|
|
121
|
+
if (!token) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
answer += token;
|
|
125
|
+
onToken?.(token);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return { answer };
|
|
129
|
+
};
|
|
130
|
+
const readNdjsonResponse = async (response, onToken) => {
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
await readResponseText(response);
|
|
133
|
+
}
|
|
134
|
+
if (!response.body) {
|
|
135
|
+
const text = await readResponseText(response);
|
|
136
|
+
return { answer: text };
|
|
137
|
+
}
|
|
138
|
+
const reader = response.body.getReader();
|
|
139
|
+
const decoder = new TextDecoder();
|
|
140
|
+
let buffer = "";
|
|
141
|
+
let answer = "";
|
|
142
|
+
while (true) {
|
|
143
|
+
const { value, done } = await reader.read();
|
|
144
|
+
if (done) {
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
buffer += decoder.decode(value, { stream: true });
|
|
148
|
+
const lines = buffer.split(/\r?\n/);
|
|
149
|
+
buffer = lines.pop();
|
|
150
|
+
for (const line of lines.map((candidate) => candidate.trim()).filter(Boolean)) {
|
|
151
|
+
const token = extractAnswerToken(JSON.parse(line));
|
|
152
|
+
if (!token) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
answer += token;
|
|
156
|
+
onToken?.(token);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (buffer.trim().length > 0) {
|
|
160
|
+
const token = extractAnswerToken(JSON.parse(buffer.trim()));
|
|
161
|
+
if (token) {
|
|
162
|
+
answer += token;
|
|
163
|
+
onToken?.(token);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return { answer };
|
|
167
|
+
};
|
|
168
|
+
const readJsonAnswer = async (response) => {
|
|
169
|
+
const text = await readResponseText(response);
|
|
170
|
+
const parsed = JSON.parse(text);
|
|
171
|
+
if (typeof parsed.answer === "string") {
|
|
172
|
+
return { answer: parsed.answer };
|
|
173
|
+
}
|
|
174
|
+
const content = parsed.choices?.[0]?.message?.content;
|
|
175
|
+
if (typeof content === "string") {
|
|
176
|
+
return { answer: content };
|
|
177
|
+
}
|
|
178
|
+
throw new TransportError("LLM response did not contain a supported answer field.");
|
|
179
|
+
};
|
|
180
|
+
class HttpLlmTransport {
|
|
181
|
+
config;
|
|
182
|
+
constructor(config) {
|
|
183
|
+
if (!config.baseUrl) {
|
|
184
|
+
throw new ConfigurationError("LLM transport requires a baseUrl.");
|
|
185
|
+
}
|
|
186
|
+
this.config = config;
|
|
187
|
+
}
|
|
188
|
+
async postJson(pathname, body) {
|
|
189
|
+
let lastResponse;
|
|
190
|
+
let lastError = new Error("HTTP retry loop exhausted without a response.");
|
|
191
|
+
for (let attempt = 0; attempt < MAX_HTTP_RETRIES; attempt += 1) {
|
|
192
|
+
try {
|
|
193
|
+
const signal = AbortSignal.timeout(this.config.timeoutMs);
|
|
194
|
+
const response = await fetch(buildRequestUrl(this.config.baseUrl, pathname), {
|
|
195
|
+
method: "POST",
|
|
196
|
+
headers: buildHeaders(this.config),
|
|
197
|
+
body: JSON.stringify(body),
|
|
198
|
+
signal
|
|
199
|
+
});
|
|
200
|
+
if (!shouldRetryStatus(response.status)) {
|
|
201
|
+
return response;
|
|
202
|
+
}
|
|
203
|
+
lastResponse = response;
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
lastError = error;
|
|
207
|
+
}
|
|
208
|
+
if (attempt < MAX_HTTP_RETRIES - 1) {
|
|
209
|
+
await waitBeforeRetry(attempt);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (lastResponse) {
|
|
213
|
+
return lastResponse;
|
|
214
|
+
}
|
|
215
|
+
throw new TransportError("Failed to reach the configured LLM server.", {
|
|
216
|
+
baseUrl: this.config.baseUrl
|
|
217
|
+
}, { cause: lastError });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Talks to any model server that exposes the OpenAI chat completions contract.
|
|
222
|
+
*/
|
|
223
|
+
export class OpenAiCompatibleTransport extends HttpLlmTransport {
|
|
224
|
+
kind = "openai-compatible";
|
|
225
|
+
async generate(request, onToken) {
|
|
226
|
+
if (!this.config.model) {
|
|
227
|
+
throw new ConfigurationError("OpenAI-compatible transport requires a model.");
|
|
228
|
+
}
|
|
229
|
+
const execute = async (messages) => {
|
|
230
|
+
const response = await this.postJson("/chat/completions", {
|
|
231
|
+
model: this.config.model,
|
|
232
|
+
stream: request.stream,
|
|
233
|
+
messages
|
|
234
|
+
});
|
|
235
|
+
return request.stream ? readSseResponse(response, onToken) : readJsonAnswer(response);
|
|
236
|
+
};
|
|
237
|
+
try {
|
|
238
|
+
return await execute(request.messages);
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
if (!isUnsupportedSystemRoleError(error)) {
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
return execute(mergeSystemMessagesIntoConversation(request.messages));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Talks to a custom JSON, NDJSON, or SSE endpoint that accepts the CodeRag payload.
|
|
250
|
+
*/
|
|
251
|
+
export class CustomHttpTransport extends HttpLlmTransport {
|
|
252
|
+
kind = "custom-http";
|
|
253
|
+
async generate(request, onToken) {
|
|
254
|
+
const response = await this.postJson("/", {
|
|
255
|
+
question: request.question,
|
|
256
|
+
model: request.model ?? this.config.model,
|
|
257
|
+
stream: request.stream,
|
|
258
|
+
context: request.context,
|
|
259
|
+
messages: request.messages
|
|
260
|
+
});
|
|
261
|
+
const format = this.config.customHttpFormat;
|
|
262
|
+
if (format === "sse") {
|
|
263
|
+
return readSseResponse(response, onToken);
|
|
264
|
+
}
|
|
265
|
+
if (format === "ndjson") {
|
|
266
|
+
return readNdjsonResponse(response, onToken);
|
|
267
|
+
}
|
|
268
|
+
return readJsonAnswer(response);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=transports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transports.js","sourceRoot":"","sources":["../../src/llm/transports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { CodeRag } from "../service/coderag.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the stdio MCP server that exposes CodeRag retrieval tools.
|
|
5
|
+
*/
|
|
6
|
+
export declare const createMcpServer: (coderag: CodeRag) => McpServer;
|
|
7
|
+
/**
|
|
8
|
+
* Connects the CodeRag MCP server to stdio for local tool execution.
|
|
9
|
+
*/
|
|
10
|
+
export declare const serveStdioMcpServer: (coderag: CodeRag) => Promise<void>;
|