idk
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { Ollama } from "ollama";
|
||||
import type { Message } from "ollama";
|
||||
import type { DiffChunk, ChunkReview, ReviewResult, AggregatedReview, Finding } from "./types.ts";
|
||||
import type {
|
||||
DiffChunk,
|
||||
ChunkReview,
|
||||
ReviewResult,
|
||||
AggregatedReview,
|
||||
Finding,
|
||||
} from "./types.ts";
|
||||
import type { ToolServer } from "./mcp.ts";
|
||||
|
||||
const ollama = new Ollama({ host: process.env.OLLAMA_HOST });
|
||||
@@ -21,7 +27,10 @@ When you are done gathering context and ready to report your findings, you MUST
|
||||
|
||||
Do not include any text outside the JSON object.`;
|
||||
|
||||
export function buildReviewPrompt(chunk: DiffChunk, userPrompt: string): string {
|
||||
export function buildReviewPrompt(
|
||||
chunk: DiffChunk,
|
||||
userPrompt: string,
|
||||
): string {
|
||||
return `${userPrompt}
|
||||
|
||||
File: ${chunk.filename} (${chunk.language})
|
||||
@@ -38,7 +47,8 @@ function parseReviewResult(content: string): ReviewResult | null {
|
||||
.trim();
|
||||
try {
|
||||
const parsed = JSON.parse(stripped);
|
||||
if (!Array.isArray(parsed.issues) || typeof parsed.summary !== "string") return null;
|
||||
if (!Array.isArray(parsed.issues) || typeof parsed.summary !== "string")
|
||||
return null;
|
||||
return parsed as ReviewResult;
|
||||
} catch {
|
||||
return null;
|
||||
@@ -52,6 +62,7 @@ export async function reviewChunk(
|
||||
contextWindow: number,
|
||||
mcpServer: ToolServer,
|
||||
): Promise<ChunkReview> {
|
||||
console.log(`Reviewing chunk from ${chunk.filename} with model ${model}...`);
|
||||
mcpServer.resetCallCount();
|
||||
|
||||
const messages: Message[] = [
|
||||
@@ -69,6 +80,7 @@ export async function reviewChunk(
|
||||
tools: forceConclusion ? undefined : mcpServer.tools,
|
||||
format: "json",
|
||||
stream: false,
|
||||
keep_alive: -1,
|
||||
options: { num_ctx: contextWindow, temperature: 0.2 },
|
||||
});
|
||||
|
||||
@@ -76,21 +88,30 @@ export async function reviewChunk(
|
||||
|
||||
// Model called one or more tools
|
||||
if (msg.tool_calls && msg.tool_calls.length > 0) {
|
||||
messages.push({ role: "assistant", content: msg.content ?? "", tool_calls: msg.tool_calls });
|
||||
messages.push({
|
||||
role: "assistant",
|
||||
content: msg.content ?? "",
|
||||
tool_calls: msg.tool_calls,
|
||||
});
|
||||
|
||||
for (const call of msg.tool_calls) {
|
||||
const result = await mcpServer.execute(
|
||||
call.function.name,
|
||||
call.function.arguments as Record<string, unknown>,
|
||||
);
|
||||
messages.push({ role: "tool", content: result, tool_name: call.function.name });
|
||||
messages.push({
|
||||
role: "tool",
|
||||
content: result,
|
||||
tool_name: call.function.name,
|
||||
});
|
||||
}
|
||||
|
||||
if (mcpServer.atLimit) {
|
||||
forceConclusion = true;
|
||||
messages.push({
|
||||
role: "user",
|
||||
content: "You have reached the tool call limit. Respond now with your final JSON review.",
|
||||
content:
|
||||
"You have reached the tool call limit. Respond now with your final JSON review.",
|
||||
});
|
||||
}
|
||||
continue;
|
||||
@@ -121,16 +142,23 @@ export async function reviewChunk(
|
||||
// Second failure — return raw content as summary rather than crash
|
||||
return {
|
||||
chunk,
|
||||
result: { issues: [], summary: `[parse error] ${content.slice(0, 500)}` },
|
||||
result: {
|
||||
issues: [],
|
||||
summary: `[parse error] ${content.slice(0, 500)}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Empty response — shouldn't happen, but bail rather than loop forever
|
||||
return { chunk, result: { issues: [], summary: "[empty response from model]" } };
|
||||
return {
|
||||
chunk,
|
||||
result: { issues: [], summary: "[empty response from model]" },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function aggregateFindings(results: ChunkReview[]): AggregatedReview {
|
||||
console.log(`Aggregating findings from ${results.length} reviewed chunks...`);
|
||||
const findings: Finding[] = results.flatMap(({ chunk, result }) =>
|
||||
result.issues.map((issue) => ({ ...issue, filename: chunk.filename })),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user