teapot-coding-agent 0.26.4 → 0.26.6
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/agent.js +55 -0
- package/package.json +1 -1
- package/public/assets/{index-CfHZpzkw.js → index-CKBUDXip.js} +19 -19
- package/public/assets/index-CKBUDXip.js.map +1 -0
- package/public/assets/{shiki-Cy1X9klC.js → shiki-D5eh0mCl.js} +2 -2
- package/public/assets/{shiki-Cy1X9klC.js.map → shiki-D5eh0mCl.js.map} +1 -1
- package/public/index.html +1 -1
- package/public/assets/index-CfHZpzkw.js.map +0 -1
package/dist/agent/agent.js
CHANGED
|
@@ -536,6 +536,43 @@ export class Agent {
|
|
|
536
536
|
async load() {
|
|
537
537
|
await this.ensureReady();
|
|
538
538
|
}
|
|
539
|
+
/**
|
|
540
|
+
* Answer tool_calls in a RESTORED history that have no tool_result (#54).
|
|
541
|
+
*
|
|
542
|
+
* The ordinary backstop (`answerUnansweredToolCalls`) works on an assistant
|
|
543
|
+
* turn inside a live loop. After a restart there is no loop: the call is in
|
|
544
|
+
* the log, the process that was running it is gone, and nothing else will ever
|
|
545
|
+
* write its result.
|
|
546
|
+
*/
|
|
547
|
+
async answerUnansweredRestoredCalls() {
|
|
548
|
+
const seen = new Set();
|
|
549
|
+
for (const ev of await readEvents(this.log.filePath)) {
|
|
550
|
+
const d = (ev.data ?? {});
|
|
551
|
+
const id = d.callId ? String(d.callId) : null;
|
|
552
|
+
if (!id)
|
|
553
|
+
continue;
|
|
554
|
+
if (ev.type === "tool_call")
|
|
555
|
+
seen.add(id);
|
|
556
|
+
else if (ev.type === "tool_result")
|
|
557
|
+
seen.delete(id);
|
|
558
|
+
}
|
|
559
|
+
for (const id of seen) {
|
|
560
|
+
await this.log.append("tool_result", this.currentSession, this.currentBranch, {
|
|
561
|
+
callId: id,
|
|
562
|
+
name: "unknown",
|
|
563
|
+
ok: false,
|
|
564
|
+
durationMs: 0,
|
|
565
|
+
result: "not completed — the agent restarted while this tool was running",
|
|
566
|
+
synthesized: true,
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
if (seen.size)
|
|
570
|
+
await this.log.append("system_note", this.currentSession, this.currentBranch, {
|
|
571
|
+
event: "unfinished-tools-closed",
|
|
572
|
+
count: seen.size,
|
|
573
|
+
detail: "a restart left these tool calls without a result; they are marked not completed (#54)",
|
|
574
|
+
});
|
|
575
|
+
}
|
|
539
576
|
/** harness-managed files inside the session directory */
|
|
540
577
|
get goalFile() {
|
|
541
578
|
return path.join(this.opts.sessionDir, "goal.md");
|
|
@@ -705,6 +742,24 @@ export class Agent {
|
|
|
705
742
|
// seen and acted on that output, and the pruned form keeps the head plus
|
|
706
743
|
// a marker, exactly as it did live.
|
|
707
744
|
this.maybePrune();
|
|
745
|
+
// #54: answer tool_calls the log says are still open.
|
|
746
|
+
//
|
|
747
|
+
// The restore path rebuilds `msgs` straight from the log, so a call whose
|
|
748
|
+
// process died mid-command comes back as an assistant turn with
|
|
749
|
+
// `tool_calls` and NO matching `tool_result`. Nothing ever answers it —
|
|
750
|
+
// not `stop()` (there is no turn to stop) and not `dispose()` (the process
|
|
751
|
+
// is already gone). The row then renders as still running for good.
|
|
752
|
+
//
|
|
753
|
+
// Measured across every session log: 43,483 tool_calls, and 4 unanswered —
|
|
754
|
+
// every one a `bash`, each followed immediately by
|
|
755
|
+
// `session-restored` / `idle->stopped disposed`. The shape is a restart
|
|
756
|
+
// (or a crash) landing while a long command was in flight, which is
|
|
757
|
+
// precisely when a human is most likely to notice "it never finished".
|
|
758
|
+
//
|
|
759
|
+
// So close them ON RESTORE, before the restored history is used. This is
|
|
760
|
+
// the same backstop as the mid-turn paths, reached from the one place
|
|
761
|
+
// those could not: after the process is gone.
|
|
762
|
+
await this.answerUnansweredRestoredCalls();
|
|
708
763
|
await this.log.append("system_note", this.currentSession, this.currentBranch, {
|
|
709
764
|
event: "session-restored",
|
|
710
765
|
branch: last.branch,
|