teapot-coding-agent 0.27.1 → 0.27.2

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.
@@ -439,7 +439,26 @@ export class Agent {
439
439
  * (#59) — the same trap #38 documented for editing history.
440
440
  */
441
441
  isLive() {
442
- return this.status === "running" || this.parkedByTool || this.pendingPrompts.length > 0;
442
+ // #127: a MANUAL compaction on an idle agent was rewriting `messages` — a
443
+ // large, non-cancellable operation — while `isLive()` reported false, so the
444
+ // UI offered "start".
445
+ //
446
+ // #133: and the reverse — after a STOP with prompts still queued, `live` stayed
447
+ // true forever, so the controls kept offering "stop" for an agent that was
448
+ // already stopped, and no amount of reloading helped. Measured:
449
+ //
450
+ // after stop : status = stopped live = true pendingPrompts = 1
451
+ //
452
+ // A queued prompt is not work in progress: it is waiting for the operator to
453
+ // press start. #9 settled that a stop must neither deliver nor silently
454
+ // DISCARD those prompts, so they are kept — but keeping them must not make the
455
+ // agent read as running. A stop outranks them.
456
+ if (this.stopRequested)
457
+ return false;
458
+ return (this.status === "running" ||
459
+ this.parkedByTool ||
460
+ this.pendingPrompts.length > 0 ||
461
+ this.compactPhase !== "");
443
462
  }
444
463
  /**
445
464
  * A background shell (bash background=true) finished. Two channels:
@@ -2927,14 +2946,40 @@ export class Agent {
2927
2946
  }
2928
2947
  /** Ask the model for dense continuation notes over the compacted range. */
2929
2948
  async summarize(old, onDelta) {
2930
- const transcript = old
2949
+ const full = old
2931
2950
  .map((m) => {
2932
2951
  const who = m.role === "tool" ? "tool" : m.role;
2933
2952
  const tc = m.tool_calls?.map((t) => `\n[calls ${t.function.name}(${t.function.arguments})]`).join("");
2934
2953
  return `${who}: ${m.content ?? ""}${tc}`;
2935
2954
  })
2936
- .join("\n\n")
2937
- .slice(-120_000);
2955
+ .join("\n\n");
2956
+ // #127: this was a bare `.slice(-120_000)` — the TAIL only.
2957
+ //
2958
+ // The question the issue raises is the right one: when a compaction starts,
2959
+ // the context window opens dramatically, and the summarizer saw only the last
2960
+ // 120k characters of what it was asked to summarise. Anything older was not
2961
+ // summarised and not kept — it was silently DISCARDED. So the original user
2962
+ // requirement, which sits at the very front of the history, was the single
2963
+ // most likely thing to be lost, and losing it is the one failure compaction
2964
+ // cannot recover from: the summary is now the only record.
2965
+ //
2966
+ // Head + tail, with the seam marked so the model can tell a gap from a
2967
+ // boundary. The head is where the goal, the constraints and the original ask
2968
+ // live; the tail is where the recent state and any in-flight error do.
2969
+ const BUDGET = 120_000;
2970
+ const HEAD = Math.floor(BUDGET * 0.35);
2971
+ const TAIL = BUDGET - HEAD;
2972
+ let transcript;
2973
+ if (full.length <= BUDGET) {
2974
+ transcript = full;
2975
+ }
2976
+ else {
2977
+ transcript = [
2978
+ full.slice(0, HEAD),
2979
+ `\n\n[... ${full.length - BUDGET} characters elided from the middle of this history ...]\n\n`,
2980
+ full.slice(full.length - TAIL),
2981
+ ].join("");
2982
+ }
2938
2983
  const fn = this.opts.chatFn ?? chat;
2939
2984
  // Structured sections (Claude Code style): fixed headings survive MULTIPLE
2940
2985
  // successive compactions far better than free-form prose — each pass knows
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teapot-coding-agent",
3
- "version": "0.27.1",
3
+ "version": "0.27.2",
4
4
  "description": "A lightweight, always-on multi-agent harness for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",