Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1de60d74fd |
+7
-66
@@ -148,9 +148,6 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise<AgentResult> {
|
|||||||
let pendingModeNudge = false;
|
let pendingModeNudge = false;
|
||||||
let calledOutputTool = false;
|
let calledOutputTool = false;
|
||||||
let addedContinueNudge = false;
|
let addedContinueNudge = false;
|
||||||
let reportProgressCount = 0;
|
|
||||||
let editCommentCount = 0;
|
|
||||||
let selectedModeName = "";
|
|
||||||
|
|
||||||
while (iterations < MAX_ITERATIONS) {
|
while (iterations < MAX_ITERATIONS) {
|
||||||
iterations++;
|
iterations++;
|
||||||
@@ -177,7 +174,7 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise<AgentResult> {
|
|||||||
options: { num_ctx: numCtx, temperature: 0.1 },
|
options: { num_ctx: numCtx, temperature: 0.1 },
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
delaysMs: [3_000, 8_000],
|
delaysMs: [3_000, 8_000, 15_000, 30_000, 600_000], // up to 6 attempts over ~16 minutes
|
||||||
shouldRetry: (err) => {
|
shouldRetry: (err) => {
|
||||||
const msg = err instanceof Error ? err.message : String(err);
|
const msg = err instanceof Error ? err.message : String(err);
|
||||||
return /unexpected EOF|XML syntax error|ECONNRESET|ETIMEDOUT|fetch failed/i.test(msg);
|
return /unexpected EOF|XML syntax error|ECONNRESET|ETIMEDOUT|fetch failed/i.test(msg);
|
||||||
@@ -225,16 +222,13 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise<AgentResult> {
|
|||||||
"» model stopped before completing task — nudging to continue",
|
"» model stopped before completing task — nudging to continue",
|
||||||
);
|
);
|
||||||
addedContinueNudge = true;
|
addedContinueNudge = true;
|
||||||
const isReview =
|
|
||||||
selectedModeName === "Review" || selectedModeName === "IncrementalReview";
|
|
||||||
messages.push({
|
messages.push({
|
||||||
role: "user",
|
role: "user",
|
||||||
content:
|
content:
|
||||||
"Your task is not complete yet. Continue executing the workflow — " +
|
"Your task is not complete yet. Continue executing the workflow — " +
|
||||||
"call the next required tool to finish. " +
|
"call the next required tool to finish. " +
|
||||||
(isReview
|
"Do not stop until you have submitted a review (create_pull_request_review) " +
|
||||||
? "Do not stop until you have submitted a review via create_pull_request_review."
|
"or called report_progress with a final summary.",
|
||||||
: "Do not stop until you have submitted a review (create_pull_request_review) or called report_progress with a final summary."),
|
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -285,51 +279,6 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise<AgentResult> {
|
|||||||
role: "tool",
|
role: "tool",
|
||||||
content: result,
|
content: result,
|
||||||
});
|
});
|
||||||
|
|
||||||
// After checkout_pr returns, extract and pin the diffPath as a user
|
|
||||||
// message. Only tool messages are pruned — user messages survive context
|
|
||||||
// pressure — so the model retains the exact diff file path and knows how
|
|
||||||
// to call read_file with offset/limit to read diff ranges.
|
|
||||||
if (toolName === "checkout_pr") {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(result) as Record<string, unknown>;
|
|
||||||
if (typeof parsed?.diffPath === "string") {
|
|
||||||
const dp = parsed.diffPath;
|
|
||||||
messages.push({
|
|
||||||
role: "user",
|
|
||||||
content:
|
|
||||||
`The diff file is at: ${dp}\n\n` +
|
|
||||||
`Read each file's diff by calling read_file on this path with start_line/end_line from the TOC.\n` +
|
|
||||||
`Example — for "device.ts (163 lines, 1146-1308)": read_file(path="${dp}", start_line=1146, end_line=1308)\n` +
|
|
||||||
`IMPORTANT: Do NOT call read_file on source files (apps/..., packages/...). ` +
|
|
||||||
`Use read_file on the diff file path above with the TOC line ranges.`,
|
|
||||||
});
|
|
||||||
log.info(`» pinned diffPath to context: ${dp}`);
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// best-effort: if checkout_pr result isn't JSON, skip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// report_progress called repeatedly means the model is stuck.
|
|
||||||
if (toolName === "report_progress") {
|
|
||||||
reportProgressCount++;
|
|
||||||
if (reportProgressCount >= 2) {
|
|
||||||
log.info("» report_progress loop — stopping");
|
|
||||||
await unloadModel(ollama, model);
|
|
||||||
return { success: true };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// edit_issue_comment called repeatedly means the model is stuck.
|
|
||||||
if (toolName === "edit_issue_comment") {
|
|
||||||
editCommentCount++;
|
|
||||||
if (editCommentCount >= 2) {
|
|
||||||
log.info("» edit_issue_comment loop — stopping");
|
|
||||||
await unloadModel(ollama, model);
|
|
||||||
return { success: true };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// After the FIRST select_mode call, nudge the model to act on the guidance.
|
// After the FIRST select_mode call, nudge the model to act on the guidance.
|
||||||
@@ -352,26 +301,18 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise<AgentResult> {
|
|||||||
// best-effort
|
// best-effort
|
||||||
}
|
}
|
||||||
|
|
||||||
const isReviewMode =
|
const firstStep =
|
||||||
selectedMode === "Review" || selectedMode === "IncrementalReview";
|
selectedMode === "Review" || selectedMode === "IncrementalReview"
|
||||||
|
? "Your first tool call must be checkout_pr with the PR number from the event context."
|
||||||
selectedModeName = selectedMode;
|
|
||||||
|
|
||||||
const firstStep = isReviewMode
|
|
||||||
? "Your first tool call must be checkout_pr. After that: (1) read diff ranges from the returned diffPath using the TOC line numbers — do NOT read full source files one-by-one, that will exhaust your context window; (2) every inline comment MUST identify a specific problem — never write praise or 'looks good' observations."
|
|
||||||
: "Call the first tool required by the workflow now.";
|
: "Call the first tool required by the workflow now.";
|
||||||
|
|
||||||
const endCondition = isReviewMode
|
|
||||||
? "Your ONLY valid final action is create_pull_request_review. Do NOT call report_progress — the mode workflow explicitly forbids it."
|
|
||||||
: "Execute the complete workflow step by step until you call create_pull_request_review or report_progress.";
|
|
||||||
|
|
||||||
messages.push({
|
messages.push({
|
||||||
role: "user",
|
role: "user",
|
||||||
content:
|
content:
|
||||||
`Good. You have selected ${selectedMode || "a"} mode and received the workflow. ` +
|
`Good. You have selected ${selectedMode || "a"} mode and received the workflow. ` +
|
||||||
"Do NOT call select_mode again. " +
|
"Do NOT call select_mode again. " +
|
||||||
`${firstStep} ` +
|
`${firstStep} ` +
|
||||||
endCondition,
|
"Execute the complete workflow step by step until you call create_pull_request_review or report_progress.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user