coder-agent 2.8.2 → 2.8.3
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/dist/agent.js +59 -0
- package/package.json +1 -1
package/dist/agent.js
CHANGED
|
@@ -463,6 +463,50 @@ async function callGeminiAPIWithRotation(apiKey, params, maxRetries = 3, initial
|
|
|
463
463
|
processChunk(value);
|
|
464
464
|
}
|
|
465
465
|
}
|
|
466
|
+
// Flush remaining buffer in case the final chunk didn't end with a newline
|
|
467
|
+
if (buffer.trim()) {
|
|
468
|
+
const trimmed = buffer.trim();
|
|
469
|
+
if (trimmed.startsWith("data: ") && trimmed !== "data: [DONE]") {
|
|
470
|
+
try {
|
|
471
|
+
const parsed = JSON.parse(trimmed.slice(6));
|
|
472
|
+
const choice = parsed.choices?.[0];
|
|
473
|
+
if (choice) {
|
|
474
|
+
const content = choice.delta?.content;
|
|
475
|
+
if (content) {
|
|
476
|
+
if (!silent) {
|
|
477
|
+
pushToTypewriter(content);
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
accumulatedContent += content;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const toolCalls = choice.delta?.tool_calls;
|
|
484
|
+
if (toolCalls) {
|
|
485
|
+
for (const tc of toolCalls) {
|
|
486
|
+
const idx = tc.index ?? 0;
|
|
487
|
+
if (!accumulatedToolCalls[idx]) {
|
|
488
|
+
accumulatedToolCalls[idx] = {
|
|
489
|
+
id: tc.id || "",
|
|
490
|
+
type: "function",
|
|
491
|
+
function: { name: "", arguments: "" }
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (tc.id)
|
|
495
|
+
accumulatedToolCalls[idx].id = tc.id;
|
|
496
|
+
if (tc.function?.name) {
|
|
497
|
+
accumulatedToolCalls[idx].function.name += tc.function.name;
|
|
498
|
+
}
|
|
499
|
+
if (tc.function?.arguments) {
|
|
500
|
+
accumulatedToolCalls[idx].function.arguments += tc.function.arguments;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
catch { }
|
|
507
|
+
}
|
|
508
|
+
buffer = "";
|
|
509
|
+
}
|
|
466
510
|
// Wait for the typewriter to finish writing before returning
|
|
467
511
|
if (typewriterActive && !silent) {
|
|
468
512
|
await new Promise((resolve) => {
|
|
@@ -627,6 +671,7 @@ export class Agent {
|
|
|
627
671
|
let iterations = 0;
|
|
628
672
|
const MAX_ITERATIONS = 12;
|
|
629
673
|
let waitCount = 0;
|
|
674
|
+
let emptyResponseRetries = 0;
|
|
630
675
|
const MAX_WAITS = 3;
|
|
631
676
|
const modifiedFiles = new Set();
|
|
632
677
|
let cleanContent = "";
|
|
@@ -710,8 +755,22 @@ export class Agent {
|
|
|
710
755
|
cleanContent = cleanContent.trim();
|
|
711
756
|
// ── No tool calls → final answer ─────────────────────────────────────
|
|
712
757
|
if (toolCalls.length === 0) {
|
|
758
|
+
if (cleanContent === "") {
|
|
759
|
+
if (emptyResponseRetries < 3) {
|
|
760
|
+
emptyResponseRetries++;
|
|
761
|
+
console.log(chalk.hex('#ff9f0a')(`\n⚠ Warning: Received empty response from API. Retrying (attempt ${emptyResponseRetries}/3)...`));
|
|
762
|
+
this.memory.getAll().pop(); // remove empty assistant message
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
console.log(chalk.hex('#ff453a')('\n✕ error: Received consecutive empty responses from Gemini API. Exiting.'));
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
713
770
|
break;
|
|
714
771
|
}
|
|
772
|
+
// Reset empty response retries on a successful non-empty turn
|
|
773
|
+
emptyResponseRetries = 0;
|
|
715
774
|
// ── Phase 2: Tool Execution ───────────────────────────────────────────
|
|
716
775
|
const statusLines = [];
|
|
717
776
|
for (const toolCall of toolCalls) {
|