fix: fixing the prompt in one
This commit is contained in:
@ -6,10 +6,9 @@ const { savePrompt, saveError } = require("../controller/generate");
|
||||
/**
|
||||
* Injects file contents into message content when file tags are present
|
||||
* @param {string} content - The message content to process
|
||||
* @returns {string} The processed content with file contents injected
|
||||
* @returns {Promise<string>} The processed content with file contents injected
|
||||
*/
|
||||
|
||||
function injectFileContent(content) {
|
||||
async function injectFileContent(content) {
|
||||
let processedContent = content;
|
||||
|
||||
// First, handle <selected_files> block
|
||||
@ -19,7 +18,7 @@ function injectFileContent(content) {
|
||||
if (selectedFilesMatch) {
|
||||
const fileListBlock = selectedFilesMatch[1];
|
||||
|
||||
// Skip injection if it already contains <file> blocks
|
||||
// Skip injection if it already contains <file> tags
|
||||
const containsFileTags = fileListBlock.includes("<file path=");
|
||||
if (!containsFileTags) {
|
||||
const filePaths = fileListBlock
|
||||
@ -28,8 +27,8 @@ function injectFileContent(content) {
|
||||
.filter((line) => line && line.startsWith("- "))
|
||||
.map((line) => line.replace(/^- /, ""));
|
||||
|
||||
const fileBlocks = filePaths
|
||||
.map(async (filePath) => {
|
||||
const fileBlocks = await Promise.all(
|
||||
filePaths.map(async (filePath) => {
|
||||
try {
|
||||
const resolvedPath = path.resolve(process.cwd(), filePath);
|
||||
const fileContent = fs.readFileSync(resolvedPath, "utf-8");
|
||||
@ -39,26 +38,24 @@ function injectFileContent(content) {
|
||||
console.warn(
|
||||
`⚠️ Failed to read file: ${filePath} → ${error.message}`,
|
||||
);
|
||||
const errorDetails = {
|
||||
await saveError({
|
||||
error_message: error.message,
|
||||
details: {
|
||||
message: error.message,
|
||||
request: null,
|
||||
response: error.response?.data,
|
||||
stack: error.stack,
|
||||
};
|
||||
|
||||
await saveError({
|
||||
error_message: error.message,
|
||||
details: errorDetails,
|
||||
},
|
||||
});
|
||||
return `<file path="${filePath}" language="text">\n[Error: File not found or unreadable]\n</file>`;
|
||||
}
|
||||
})
|
||||
.join("\n\n");
|
||||
}),
|
||||
);
|
||||
|
||||
// Replace the original <selected_files> block with injected file tags
|
||||
// Replace the <selected_files> block with the injected file tags
|
||||
processedContent = processedContent.replace(
|
||||
selectedFilesMatch[0],
|
||||
fileBlocks,
|
||||
fileBlocks.join("\n\n"),
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
@ -67,34 +64,34 @@ function injectFileContent(content) {
|
||||
}
|
||||
}
|
||||
|
||||
// Then, safely resolve and inject content into any <file path="..."> tags (without inner content)
|
||||
// Inject content into empty <file> tags
|
||||
const fileTagRegex = /<file path="(.+?)"(?: language="(.+?)")?>\s*<\/file>/g;
|
||||
processedContent = processedContent.replace(
|
||||
fileTagRegex,
|
||||
async (_, filePath, lang) => {
|
||||
const matches = [...processedContent.matchAll(fileTagRegex)];
|
||||
|
||||
for (const match of matches) {
|
||||
const [fullTag, filePath, lang] = match;
|
||||
try {
|
||||
const resolvedPath = path.resolve(process.cwd(), filePath);
|
||||
const fileContent = fs.readFileSync(resolvedPath, "utf-8");
|
||||
return `<file path="${filePath}" language="${lang || "text"}">\n${fileContent}\n</file>`;
|
||||
const replacement = `<file path="${filePath}" language="${lang || "text"}">\n${fileContent}\n</file>`;
|
||||
processedContent = processedContent.replace(fullTag, replacement);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`⚠️ Failed to inject <file> tag for ${filePath}: ${error.message}`,
|
||||
);
|
||||
const errorDetails = {
|
||||
await saveError({
|
||||
error_message: error.message,
|
||||
details: {
|
||||
message: error.message,
|
||||
request: null,
|
||||
response: error.response?.data,
|
||||
stack: error.stack,
|
||||
};
|
||||
|
||||
await saveError({
|
||||
error_message: error.message,
|
||||
details: errorDetails,
|
||||
});
|
||||
return `<file path="${filePath}" language="${lang || "text"}">\n[Error: File not found or unreadable]\n</file>`;
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
const replacement = `<file path="${filePath}" language="${lang || "text"}">\n[Error: File not found or unreadable]\n</file>`;
|
||||
processedContent = processedContent.replace(fullTag, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
return processedContent;
|
||||
}
|
||||
@ -104,7 +101,6 @@ function injectFileContent(content) {
|
||||
* Handles both chat-style and prompt-style requests to Ollama
|
||||
*/
|
||||
async function handleGenerate(req, res) {
|
||||
// Log the complete request for debugging
|
||||
try {
|
||||
const requestData = {
|
||||
method: req.method,
|
||||
@ -119,9 +115,7 @@ async function handleGenerate(req, res) {
|
||||
},
|
||||
};
|
||||
|
||||
// Validate request body
|
||||
if (!requestData.body) {
|
||||
// Save request data even if body is empty
|
||||
await savePrompt({
|
||||
model: requestData.body?.model || "codellama:7b",
|
||||
prompt: null,
|
||||
@ -131,9 +125,9 @@ async function handleGenerate(req, res) {
|
||||
throw new Error("Request body is required");
|
||||
}
|
||||
|
||||
// Determine request type and validate required fields
|
||||
const isChatRequest =
|
||||
requestData.body.messages && Array.isArray(requestData.body.messages);
|
||||
|
||||
if (
|
||||
isChatRequest &&
|
||||
(!requestData.body.messages.length ||
|
||||
@ -147,45 +141,42 @@ async function handleGenerate(req, res) {
|
||||
throw new Error("Prompt request must include a prompt field");
|
||||
}
|
||||
|
||||
// Set defaults and validate model
|
||||
const model = requestData.body.model || "codellama:7b";
|
||||
const stream =
|
||||
requestData.body.stream !== undefined ? requestData.body.stream : true;
|
||||
|
||||
// Clean and prepare the prompt/messages
|
||||
const cleanedRequest = {
|
||||
model,
|
||||
stream,
|
||||
...(isChatRequest
|
||||
? {
|
||||
messages: requestData.body.messages.map((msg) => ({
|
||||
messages: await Promise.all(
|
||||
requestData.body.messages.map(async (msg) => ({
|
||||
role: msg.role || "user",
|
||||
content:
|
||||
msg.role === "user" && typeof msg.content === "string"
|
||||
? injectFileContent(msg.content.trim())
|
||||
? await injectFileContent(msg.content.trim())
|
||||
: msg.content.trim(),
|
||||
})),
|
||||
),
|
||||
}
|
||||
: {
|
||||
prompt: injectFileContent(requestData.body.prompt.trim()),
|
||||
prompt: await injectFileContent(requestData.body.prompt.trim()),
|
||||
}),
|
||||
};
|
||||
|
||||
// Save the complete request data to database
|
||||
await savePrompt({
|
||||
model,
|
||||
prompt: isChatRequest ? null : cleanedRequest.prompt,
|
||||
messages: isChatRequest ? cleanedRequest.messages : null,
|
||||
request_data: requestData, // Save all request data for debugging/tracking
|
||||
request_data: requestData,
|
||||
});
|
||||
|
||||
// Prepare Ollama endpoint and payload
|
||||
const ollamaUrl = isChatRequest
|
||||
? "http://localhost:11434/api/chat"
|
||||
: "http://localhost:11434/api/generate";
|
||||
|
||||
if (stream) {
|
||||
// Handle streaming response
|
||||
const ollamaResponse = await axios.post(ollamaUrl, cleanedRequest, {
|
||||
responseType: "stream",
|
||||
headers: {
|
||||
@ -197,11 +188,9 @@ async function handleGenerate(req, res) {
|
||||
res.setHeader("Content-Type", "application/x-ndjson");
|
||||
res.setHeader("Transfer-Encoding", "chunked");
|
||||
|
||||
let responseContent = "";
|
||||
ollamaResponse.data.on("data", (chunk) => {
|
||||
try {
|
||||
const data = JSON.parse(chunk.toString());
|
||||
responseContent += data.response || "";
|
||||
res.write(JSON.stringify(data) + "\n");
|
||||
} catch (err) {
|
||||
console.error("Error parsing chunk:", err);
|
||||
@ -233,12 +222,10 @@ async function handleGenerate(req, res) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Handle non-streaming response
|
||||
const ollamaResponse = await axios.post(ollamaUrl, cleanedRequest);
|
||||
res.status(ollamaResponse.status).json(ollamaResponse.data);
|
||||
}
|
||||
} catch (error) {
|
||||
// Enhanced error handling
|
||||
const errorDetails = {
|
||||
message: error.message,
|
||||
request: requestData,
|
||||
|
Reference in New Issue
Block a user