phase: 160_tool_budget_telemetry
All green. Final report: **Phase 160 completion pass — verified (final verification; all 5 tasks already in `complete/`)** - **Verified, no code defects found:** budget trailers (`TOOL_BUDGET_REMAINING/LAST/SPENT`), cap-path rejection + `ROUND_CAP_FALLBACK_ANSWER` + `ROUND_CAP_WRAPUP_INSTRUCTION`, `done.budget_exhausted` (ABSENT-when-false), `rounds=/cap_hit=` log fields, `agent_max_rounds=10` default, frontend Continue button + restore + shared-page exclusion, mock markers. - **Tests/lint:** `uv run pytest` 153/153 green (EXIT 0); `uv run pytest --cov=app --cov-report=term-missing` TOTAL **99%** (>90%); `uv run ruff check .` clean; `uv run pyright` 0 errors/0 warnings. - **Criteria:** ① decreasing trailer pinned by unit tests (9→…→spent) ✅ ② cap path ends readable, no tool lines after cap (E2E) ✅ ③ `budget_exhausted` true-only-on-cap, absent otherwise (integration) ✅ ④ Continue button → one fresh `continue` turn, fresh budget, record intact (E2E) ✅ ⑤ flag survives refresh; shared chat never renders it (`shared.js` has no `budget_exhausted` path) ✅ ⑥ `max_rounds=0` byte-identical single `tools=None` request; default still 10 ✅ ⑦ full suite/coverage/lint green ✅ ⑧ `test_tool_budget_telemetry.py` **7/7** in isolation; all 6 regression E2E suites green in isolation ✅ ⑨ commit + phase move = harness (I make no git history/index changes). - **Docs:** README.md — fixed: the "Continue researching" button and cap behavior were undocumented (added a Chat-section paragraph + an Agent-tools-section paragraph, incl. the phase-71 recorded-revision note); env-var table, commands, and architecture all verified consistent otherwise. AGENTS.md — verified consistent, no changes needed. - **Decisions:** no code changes required — phase was fully implemented; only README docs added. No live-infrastructure touched. - **Next pending phase:** `161_reasoning_bubble`.
This commit is contained in:
@@ -796,9 +796,15 @@ def test_retry_last_turn_is_byte_unchanged() -> None:
|
||||
#: task-01 idle-settle ``markLastEditable()`` mark pass (work item 3
|
||||
#: call sites — the in-flight guard's at-rest landing), and the
|
||||
#: task-03 aborted-settle mark pair (the 300s guard's ``aborted``
|
||||
#: catch branch — a timed-out turn must not strand the question).
|
||||
#: The ``reask`` path is consumed as-is. A diff here is a contract
|
||||
#: violation for the phase's remaining tasks.
|
||||
#: catch branch — a timed-out turn must not strand the question);
|
||||
#: plus the phase-160 (task 04, TODO L4) sanctioned additions:
|
||||
#: the done settle's ``budget_exhausted`` meta key (the additive
|
||||
#: done-frame marker — ``undefined`` drops the key, so every non-cap
|
||||
#: record stays byte-identical) and the flag-gated
|
||||
#: ``appendContinueButton`` (the "Continue researching" affordance —
|
||||
#: ABSENT on every other turn). The ``reask`` path is consumed as-is.
|
||||
#: A diff here is a contract violation for the phase's remaining
|
||||
#: tasks.
|
||||
PINNED_RUN_TURN = """function runTurn(text, { reask = false, image = null } = {}) {
|
||||
if (!reask) {
|
||||
// Phase 123 (task 02, TODO L6): the attached image rides the user
|
||||
@@ -1181,6 +1187,12 @@ PINNED_RUN_TURN = """function runTurn(text, { reask = false, image = null } = {}
|
||||
// row exactly as it looked live.
|
||||
related: ev.related?.length ? ev.related : undefined,
|
||||
suggestions: ev.suggestions,
|
||||
// Phase 160 (task 04, TODO L4): the cap-reached marker
|
||||
// persists with the turn — `undefined` drops the key from
|
||||
// the JSON (the house optional-meta pattern, the
|
||||
// answer_image line above is the precedent), so every
|
||||
// non-cap record stays byte-identical to pre-phase.
|
||||
budget_exhausted: ev.budget_exhausted || undefined,
|
||||
}, leavePartialIndex);
|
||||
lastBrainWrap = wrap; // this bubble is now the last brain answer
|
||||
// Phase 130 (task 02): the row order is the DOM order — the
|
||||
@@ -1191,6 +1203,20 @@ PINNED_RUN_TURN = """function runTurn(text, { reask = false, image = null } = {}
|
||||
appendTuneButton(wrap); // every completed brain bubble is tunable
|
||||
markLastRetryable(); // phase 49: the Retry button is last-bubble-only
|
||||
markLastEditable(); // phase 159: the done turn's question is editable (the in-flight guard no-ops here — the runTurn idle settle lands it)
|
||||
// Phase 160 (task 04, TODO L4): a cap-reached answer offers
|
||||
// the one-click continuation — first, every earlier bubble's
|
||||
// continue button is cleared (the markLastRetryable
|
||||
// remove-first pattern: the moment a newer turn lands, an old
|
||||
// bubble's stale affordance is gone — its "continue" would
|
||||
// append to a history the conversation already moved past),
|
||||
// then the button is appended ONLY when the done frame is
|
||||
// flagged (ABSENT on every other turn, so the button never
|
||||
// appears elsewhere); the row order stays Tune → Retry →
|
||||
// Continue → Save-as-doc (the insertion order phase 130
|
||||
// relies on — markLastEditable above acts on the user
|
||||
// bubble, so the brain bubble's row order is unchanged).
|
||||
messagesEl.querySelectorAll(".continue-btn").forEach((b) => b.remove());
|
||||
if (ev.budget_exhausted) appendContinueButton(wrap);
|
||||
// Phase 59: the RAW persisted markdown (never the rendered
|
||||
// HTML) — exactly the string rememberBrainTurn stores above,
|
||||
// so a reload (the restore path) offers the identical draft.
|
||||
@@ -1397,13 +1423,16 @@ PINNED_RUN_TURN = """function runTurn(text, { reask = false, image = null } = {}
|
||||
|
||||
|
||||
def test_run_turn_is_pinned_at_phase_159_state() -> None:
|
||||
"""``runTurn`` is pinned at exactly the state phase 159 left it
|
||||
(task 02 consumes its ``reask`` path AS-IS — the phase's "NOT
|
||||
touched" contract): the full source must match the pin — the
|
||||
``reask`` path, the turn-local resets, the SSE contract, the
|
||||
save points, and the sanctioned additions (the task-01
|
||||
``lastUserWrap`` assignment + the idle-settle mark pass, and the
|
||||
task-03 aborted-settle mark pair) included."""
|
||||
"""``runTurn`` is pinned at exactly the state phase 159 left it,
|
||||
plus phase 160 (task 04)'s sanctioned additions (task 02 consumes
|
||||
its ``reask`` path AS-IS — the phase's "NOT touched" contract;
|
||||
the phase-160 additions are the done settle's additive
|
||||
``budget_exhausted`` meta key + the flag-gated Continue button):
|
||||
the full source must match the pin — the ``reask`` path, the
|
||||
turn-local resets, the SSE contract, the save points, and the
|
||||
sanctioned additions (the task-01 ``lastUserWrap`` assignment +
|
||||
the idle-settle mark pass, the task-03 aborted-settle mark pair,
|
||||
and the phase-160 done-settle pair) included."""
|
||||
assert _fn_source(_js(), "runTurn") == PINNED_RUN_TURN
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user