openai-code
Version:
An unofficial proxy layer that lets you use Anthropic Claude Code with any OpenAI API backend.
93 lines (79 loc) • 3.41 kB
JavaScript
import { addToIndex, search, getByPath, storeToDisk, updateByPath, loadFromDisk, removeByPath, needsUpdate } from './vectordb.mjs'
import { safeReadFileSync, getAllSourceFilePaths } from './fs.mjs';
import { createEmbedding } from './openai.mjs';
import { escapeContent } from './prompts.mjs';
export const embedSingleDocument = async (filePath, _content) => {
console.log("- Embedding single document:", filePath, "...")
const content = _content ? _content : safeReadFileSync(filePath, 'utf-8')
if (content === null) {
return null
}
return createEmbedding(content)
}
/**
* For every request, before searching the vector database,
* this function ensures all relevant code files are added.
*
* It parses the extractedContext to get a list of file paths,
* reads the file content for each path that is not yet indexed,
* creates an embedding for the content, and adds it to the index.
*/
export const indexRelevantCodeFromContext = async (workingDirectory) => {
console.log("- Updating Vector Database index from context:", workingDirectory)
const absoluteFilePaths = getAllSourceFilePaths(workingDirectory)
let allDocuments = loadFromDisk(workingDirectory)
for (const filePath of absoluteFilePaths) {
const existingDocument = getByPath(filePath)
// Check if the file is not indexed or if it is recently updated
if (!existingDocument || existingDocument.recentlyUpdated) {
try {
const embedding = await embedSingleDocument(filePath)
if (!existingDocument) {
addToIndex(filePath, embedding)
} else {
updateByPath(filePath, embedding)
}
} catch (error) {
console.error(`Error indexing file ${filePath}:`, error)
}
}
}
// leftover documents that are not in the context should be removed
const pathsToRemove = allDocuments.filter(doc => !absoluteFilePaths.includes(doc.path))
for (const doc of pathsToRemove) {
try {
// remove document from index
removeByPath(doc.path);
console.log(`Removed document from index: ${doc.path}`)
} catch (error) {
console.error(`Error removing document ${doc.path}:`, error)
}
}
allDocuments = loadFromDisk(workingDirectory)
// any (outside) change: update embedding
for (const document of allDocuments) {
try {
// safely read the file content
const content = safeReadFileSync(document.path, 'utf-8')
// check if the document needs an update
if (needsUpdate(document.path)) {
const newEmbedding = await createEmbedding(content)
updateByPath(document.path, newEmbedding)
console.log(`Updated document in index: ${document.path}`)
}
} catch (error) {
console.error(`Error processing document ${document.path}:`, error)
}
}
storeToDisk(workingDirectory)
console.log("- Finished updating Vector Database index from context:", workingDirectory)
}
export const getRelevantCodeForPrompt = async (queryText, topK = 3) => {
const embedding = await createEmbedding(queryText)
const results = search({ embedding }, topK)
let formatted = ''
for (const result of results) {
formatted += `<maybe_relevant_code comment="This is just top ${topK} candidates. Look further if necessary."><path>${result.path}</path><code>${escapeContent(result.source)}</code></maybe_relevant_code>\n`
}
return formatted
}