teapot-coding-agent 0.29.17 → 0.29.18
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 +40 -1
- package/dist/agent/tools.js +28 -0
- package/package.json +1 -1
- package/public/assets/index-CqiIqNke.js +30 -0
- package/public/assets/index-CqiIqNke.js.map +1 -0
- package/public/assets/{shiki-Bfg_Oj76.js → shiki-Dxm8LTBG.js} +2 -2
- package/public/assets/{shiki-Bfg_Oj76.js.map → shiki-Dxm8LTBG.js.map} +1 -1
- package/public/index.html +1 -1
- package/public/assets/index-BPcSJBPR.js +0 -30
- package/public/assets/index-BPcSJBPR.js.map +0 -1
package/dist/agent/agent.js
CHANGED
|
@@ -10,7 +10,7 @@ import { promises as fs, existsSync, readFileSync, readdirSync, statSync } from
|
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { EventLog, readEvents } from "../log/events.js";
|
|
12
12
|
import { chat, chatStream } from "./llm.js";
|
|
13
|
-
import { executeTool, toolSpecs, currentSkills, safeJoin, isContextOverflow, hasRunningBgShells } from "./tools.js";
|
|
13
|
+
import { executeTool, toolSpecs, currentSkills, safeJoin, isContextOverflow, hasRunningBgShells, killBgShells } from "./tools.js";
|
|
14
14
|
import { effortChoosable } from "./llm.js";
|
|
15
15
|
import { skillRootsFingerprint, foreignSkillRoots } from "./skills.js";
|
|
16
16
|
import { bus } from "../bus.js";
|
|
@@ -685,6 +685,15 @@ export class Agent {
|
|
|
685
685
|
this.pendingPrompts.length > 0 ||
|
|
686
686
|
this.compactPhase !== "" ||
|
|
687
687
|
this.retrySleeping ||
|
|
688
|
+
// #158: a BACKGROUND job is work in flight, and `stop()` now ends it. The
|
|
689
|
+
// round that started it deliberately ended (the loop breaks rather than
|
|
690
|
+
// nagging — see hasRunningBgShells in loop()), so the status reads "idle"
|
|
691
|
+
// while a dev server / watcher / long build is still running. Without this
|
|
692
|
+
// the UI offered "▶ start" and there was no stop control for the one thing
|
|
693
|
+
// the operator most needs to stop. Note this is checked AFTER stopRequested:
|
|
694
|
+
// once stopped, the jobs are already dead, so `live` must go false or the
|
|
695
|
+
// button would offer stop forever (#133).
|
|
696
|
+
hasRunningBgShells(this.toolCtx.cwd) ||
|
|
688
697
|
// ask_user: the loop is parked on the operator's answer — stoppable work
|
|
689
698
|
// in flight, not idleness. Without this the UI offered "start", and
|
|
690
699
|
// pressing it cleared awaitingUser, silently discarding the open question
|
|
@@ -1677,6 +1686,13 @@ export class Agent {
|
|
|
1677
1686
|
// without aborting toolCtx.signal the park ran to its full timeout
|
|
1678
1687
|
this.abort?.abort();
|
|
1679
1688
|
this.toolAbort.abort();
|
|
1689
|
+
// #158: and the BACKGROUND shells, which neither signal above reaches. A job
|
|
1690
|
+
// spawned with `background: true` is `detached` and its spawning tool returned
|
|
1691
|
+
// long ago, so `toolAbort` has nothing on the stack to abort: the agent parked
|
|
1692
|
+
// in its "wait for the job" idle state, the job kept running, and `stop()` —
|
|
1693
|
+
// the control the operator pressed for exactly this — ended nothing. MEASURED:
|
|
1694
|
+
// `sleep 300` outlived both stop() and dispose().
|
|
1695
|
+
killBgShells(this.toolCtx.cwd);
|
|
1680
1696
|
this.wake?.();
|
|
1681
1697
|
// #86: the status write is DEFERRED onto the run chain, so it can land
|
|
1682
1698
|
// AFTER a start() that followed it. Observed: `idle -> stopped -> running ->
|
|
@@ -3666,6 +3682,29 @@ export class Agent {
|
|
|
3666
3682
|
onDelta
|
|
3667
3683
|
? (s) => onDelta(s.text)
|
|
3668
3684
|
: undefined);
|
|
3685
|
+
// Record what the summarizer itself cost, especially `cachedInputTokens`.
|
|
3686
|
+
//
|
|
3687
|
+
// This is the ONLY way to observe the property the whole replay-the-prefix shape
|
|
3688
|
+
// exists for: the summarizer is supposed to be served from the provider's KV
|
|
3689
|
+
// cache because its input is a byte-identical prefix of the request the
|
|
3690
|
+
// conversation just made. Without this line the claim was UNVERIFIABLE — a
|
|
3691
|
+
// compaction event reported tokensBefore/tokensAfter (the CONVERSATION's size)
|
|
3692
|
+
// and nothing at all about the call that produced the summary, so a shape that
|
|
3693
|
+
// silently stopped sharing the prefix would look identical in the log.
|
|
3694
|
+
//
|
|
3695
|
+
// MEASURED on the session that prompted this: the 12k-line history had 2342
|
|
3696
|
+
// usage events, none of them the summarizer's.
|
|
3697
|
+
if (res.usage) {
|
|
3698
|
+
const u = res.usage;
|
|
3699
|
+
this.stats.inputTokens += u.inputTokens ?? 0;
|
|
3700
|
+
this.stats.outputTokens += u.outputTokens ?? 0;
|
|
3701
|
+
this.stats.cachedInputTokens += u.cachedInputTokens ?? 0;
|
|
3702
|
+
await this.log.append("usage", this.currentSession, this.currentBranch, {
|
|
3703
|
+
...u,
|
|
3704
|
+
// distinguishes it from a conversation turn when reading the log back
|
|
3705
|
+
kind: "summarize",
|
|
3706
|
+
});
|
|
3707
|
+
}
|
|
3669
3708
|
return this.formatCompactSummary(res.message.content ?? "");
|
|
3670
3709
|
}
|
|
3671
3710
|
/** strip the <analysis> scratchpad — it improves thinking but must not
|
package/dist/agent/tools.js
CHANGED
|
@@ -301,6 +301,34 @@ export function hasRunningBgShells(cwd) {
|
|
|
301
301
|
}
|
|
302
302
|
return false;
|
|
303
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Kill every background shell for one workspace and forget the jobs (#158).
|
|
306
|
+
*
|
|
307
|
+
* `stop()` left these running. They are spawned `detached: true` for group-killing
|
|
308
|
+
* and are NOT covered by `toolAbort` (that signal only reaches a tool that is
|
|
309
|
+
* still on the stack), so pressing stop on an agent that had parked its round on
|
|
310
|
+
* a background job killed nothing: the loop sat in its deliberate "wait for the
|
|
311
|
+
* job" idle state while the job kept burning CPU, and no control could end it.
|
|
312
|
+
*
|
|
313
|
+
* MEASURED: `sleep 300` outlived both `stop()` and `dispose()`.
|
|
314
|
+
*
|
|
315
|
+
* Returns how many were actually killed, so a caller can report it.
|
|
316
|
+
*/
|
|
317
|
+
export function killBgShells(cwd) {
|
|
318
|
+
const m = bgShellsByWs.get(cwd);
|
|
319
|
+
if (!m)
|
|
320
|
+
return 0;
|
|
321
|
+
let killed = 0;
|
|
322
|
+
for (const [id, sh] of m) {
|
|
323
|
+
if (!sh.exited) {
|
|
324
|
+
describeKill(killTree(sh.child));
|
|
325
|
+
killed++;
|
|
326
|
+
}
|
|
327
|
+
bgReadCursors.delete(id);
|
|
328
|
+
}
|
|
329
|
+
m.clear();
|
|
330
|
+
return killed;
|
|
331
|
+
}
|
|
304
332
|
/** Run a command in its own process group; kill the whole group on timeout. */
|
|
305
333
|
function runShell(cmd, ctx, timeoutMs) {
|
|
306
334
|
return new Promise((resolve) => {
|