@blockrun/franklin 3.15.36 → 3.15.38
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/loop.js +25 -4
- package/dist/tools/detach.js +15 -6
- package/package.json +1 -1
package/dist/agent/loop.js
CHANGED
|
@@ -403,6 +403,12 @@ export async function interactiveSession(config, getUserInput, onEvent, onAbortR
|
|
|
403
403
|
let turnCount = 0;
|
|
404
404
|
// Resume: hydrate history from the saved JSONL transcript.
|
|
405
405
|
// Sanitize to drop any orphaned tool_use / tool_result pairs from a crash.
|
|
406
|
+
// Carry over running totals from prior runs so resume preserves them — see
|
|
407
|
+
// the `let sessionInputTokens` comment below.
|
|
408
|
+
let resumedInputTokens = 0;
|
|
409
|
+
let resumedOutputTokens = 0;
|
|
410
|
+
let resumedCostUsd = 0;
|
|
411
|
+
let resumedSavedVsOpusUsd = 0;
|
|
406
412
|
if (config.resumeSessionId) {
|
|
407
413
|
const prior = loadSessionHistory(config.resumeSessionId);
|
|
408
414
|
if (prior.length > 0) {
|
|
@@ -411,6 +417,17 @@ export async function interactiveSession(config, getUserInput, onEvent, onAbortR
|
|
|
411
417
|
const meta = loadSessionMeta(config.resumeSessionId);
|
|
412
418
|
if (meta) {
|
|
413
419
|
turnCount = meta.turnCount ?? 0;
|
|
420
|
+
// Pre-3.15.38 these fell on the floor — every resume reset the
|
|
421
|
+
// running cost/token totals to zero, then `updateSessionMeta`
|
|
422
|
+
// wrote the new (smaller) numbers back over the historical
|
|
423
|
+
// values. Verified 2026-05-04 from a real session: efd5e412
|
|
424
|
+
// had $2.65 + 200K input tokens accumulated, then a resume
|
|
425
|
+
// rewrote the meta to {costUsd: 0, inputTokens: 0, ...}
|
|
426
|
+
// before the user ran their next turn.
|
|
427
|
+
resumedInputTokens = meta.inputTokens ?? 0;
|
|
428
|
+
resumedOutputTokens = meta.outputTokens ?? 0;
|
|
429
|
+
resumedCostUsd = meta.costUsd ?? 0;
|
|
430
|
+
resumedSavedVsOpusUsd = meta.savedVsOpusUsd ?? 0;
|
|
414
431
|
}
|
|
415
432
|
}
|
|
416
433
|
}
|
|
@@ -418,10 +435,14 @@ export async function interactiveSession(config, getUserInput, onEvent, onAbortR
|
|
|
418
435
|
let lastSessionActivity = Date.now();
|
|
419
436
|
let lastRoutedModel = ''; // last model chosen by router (for local elo)
|
|
420
437
|
let lastRoutedCategory = ''; // last category detected (for local elo)
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
438
|
+
// Session-cumulative counters. Seeded from prior session meta on resume so
|
|
439
|
+
// `franklin insights` and the status bar show the *true* session total
|
|
440
|
+
// across every restart, not just what happened since the latest process
|
|
441
|
+
// boot.
|
|
442
|
+
let sessionInputTokens = resumedInputTokens;
|
|
443
|
+
let sessionOutputTokens = resumedOutputTokens;
|
|
444
|
+
let sessionCostUsd = resumedCostUsd;
|
|
445
|
+
let sessionSavedVsOpus = resumedSavedVsOpusUsd;
|
|
425
446
|
// Per-tool call counts aggregated across every turn. Session-scope, not
|
|
426
447
|
// per-turn. Counts the *name* of each tool invocation only — no inputs,
|
|
427
448
|
// outputs, or paths. Fed into opt-in telemetry at session end.
|
package/dist/tools/detach.js
CHANGED
|
@@ -21,9 +21,15 @@ async function execute(input, ctx) {
|
|
|
21
21
|
`label: ${label}\n` +
|
|
22
22
|
`command: ${command}\n\n` +
|
|
23
23
|
`Inspect with:\n` +
|
|
24
|
-
` franklin task tail ${runId}
|
|
25
|
-
` franklin task wait ${runId}\n` +
|
|
26
|
-
` franklin task cancel ${runId}\n
|
|
24
|
+
` franklin task tail ${runId} # non-blocking status snapshot — safe inside Bash\n` +
|
|
25
|
+
` franklin task wait ${runId} --timeout-s 600 # block up to 10min; pair with Bash timeout >= same\n` +
|
|
26
|
+
` franklin task cancel ${runId}\n` +
|
|
27
|
+
`\n` +
|
|
28
|
+
`WARNING: do NOT call \`franklin task tail ${runId} --follow\` from a Bash tool — \`--follow\`\n` +
|
|
29
|
+
`blocks until the task reaches a terminal state, which routinely outlasts the Bash tool's\n` +
|
|
30
|
+
`default 2-minute timeout and gives you "command killed". Use \`franklin task tail <runId>\`\n` +
|
|
31
|
+
`(no flag) for non-blocking status, or \`franklin task wait\` with explicit \`--timeout-s\` plus\n` +
|
|
32
|
+
`a matching Bash \`timeout\`.\n`,
|
|
27
33
|
};
|
|
28
34
|
}
|
|
29
35
|
export const detachCapability = {
|
|
@@ -37,9 +43,12 @@ export const detachCapability = {
|
|
|
37
43
|
"complete), or anything you'd otherwise loop on turn-by-turn (which " +
|
|
38
44
|
"would burn turns and trip timeouts). The agent's job is to design and " +
|
|
39
45
|
"orchestrate, not to be the for-loop. Pair with a script that writes a " +
|
|
40
|
-
"checkpoint file so progress survives restarts.
|
|
41
|
-
"`franklin task tail <runId
|
|
42
|
-
"`
|
|
46
|
+
"checkpoint file so progress survives restarts. Inspect with " +
|
|
47
|
+
"`franklin task tail <runId>` (NON-blocking snapshot — safe inside " +
|
|
48
|
+
"Bash) — DO NOT use `--follow` from a Bash tool, it blocks until the " +
|
|
49
|
+
"task is done and will trip the Bash timeout. Block-until-done belongs " +
|
|
50
|
+
"in `franklin task wait <runId> --timeout-s N` paired with a matching " +
|
|
51
|
+
"Bash `timeout` parameter. ALWAYS prefer Detach over a single " +
|
|
43
52
|
"foreground Bash call with `sleep` inside a for/while/until loop — that " +
|
|
44
53
|
"antipattern blocks the agent for the full duration and looks frozen.",
|
|
45
54
|
input_schema: {
|
package/package.json
CHANGED