diff options
| author | Adam Malczewski <[email protected]> | 2026-06-11 14:49:14 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-11 14:49:14 +0900 |
| commit | 35937cee7f838e414eb8147c67205e01d85a4da0 (patch) | |
| tree | fe4bd741618bbe97509be0a0566af50034d07611 | |
| parent | bfbad3af79cab23f52be0f6388311a5798b7fd04 (diff) | |
| download | dispatch-35937cee7f838e414eb8147c67205e01d85a4da0.tar.gz dispatch-35937cee7f838e414eb8147c67205e01d85a4da0.zip | |
docs: CR-3 resolution courier (timer field + manual-warm reset) + tasks
| -rw-r--r-- | frontend-cache-warming-handoff.md | 26 | ||||
| -rw-r--r-- | tasks.md | 14 |
2 files changed, 39 insertions, 1 deletions
diff --git a/frontend-cache-warming-handoff.md b/frontend-cache-warming-handoff.md index dedb13d..67ff374 100644 --- a/frontend-cache-warming-handoff.md +++ b/frontend-cache-warming-handoff.md @@ -63,3 +63,29 @@ track cross-turn state there: already shows it — just relabel/position as desired. Types: `@dispatch/transport-contract` `WarmResponse` now carries `expectedCacheRate` (additive). + +## CR-3 — DONE (next-warm timestamps + manual-warm resets the timer) +Both asks from `backend-handoff-cache-warming-timer.md` are implemented (commit `bfbad3a`). No +contract bump (uses the `custom` escape hatch, as you suggested). + +**Ask 1 — authoritative timestamps on the `cache-warming` surface.** The conversation-scoped spec now +includes a `custom` field: +```ts +{ kind: "custom", rendererId: "cache-warming-timer", + payload: { nextWarmAt: number | null, lastWarmAt: number | null } } // epoch-ms +``` +- `nextWarmAt` = epoch-ms the next AUTOMATIC warm will fire, or `null` when not scheduled (disabled, + or a turn is generating so the timer is cancelled). Drive your countdown off this directly. +- `lastWarmAt` = epoch-ms of the most recent completed warm, or `null` if none. Use its changes for + the history. (The hit-% for that warm is the `last cache rate` / `cache retention` stats in the + same spec.) +- Pushed via the normal surface `update` on every change (warm complete, toggle, interval, turn + start/settle). You can drop the FE-side best-effort countdown anchor. + +**Ask 2 — a manual `POST /chat/warm` now resets the cycle + refreshes the surface.** Implemented via +an inversion (no new endpoint, no change to the `/chat/warm` request/response): the backend's warm +service emits an internal event that the cache-warming extension consumes, so a manual warm now +re-arms the automatic timer (new `nextWarmAt`), updates `lastPct`/`lastWarmAt`, and **pushes a surface +`update`**. So after a "Warm now" click you'll get an authoritative surface `update` — you can drop the +workaround of reading the % from the HTTP response (though the HTTP `WarmResponse` is still returned and +fine to use for immediate feedback). Live-verified against Claude haiku. @@ -5,7 +5,7 @@ > Keep this lean and current; do not let it re-accrete a step-by-step changelog. ## Status (current) -`tsc -b` EXIT 0 · biome clean · **784 vitest + 109 bun = 893 tests**. +`tsc -b` EXIT 0 · biome clean · **800 vitest + 109 bun = 909 tests**. Built and verified live (full-fidelity: every feature is a manifest-loaded extension through the host): @@ -179,6 +179,18 @@ arm-on-settle/cancel-on-start; `pct = round(clamp(cacheRead/input,0,1)*100)`). unchanged). **FE courier:** `frontend-cache-warming-handoff.md` (this repo) — the web must render the `number` field kind + send/handle `conversationId` on the surface WS protocol. +## Cache warming — FE CR-3 (DONE) +FE asked (dispatch-web `backend-handoff-cache-warming-timer.md`): expose next/last-warm timestamps + +make a manual warm reset the timer/refresh the surface. Done via an **inversion** (commit `bfbad3a`): +session-orchestrator `warm()` (the single chokepoint for manual `/chat/warm` AND the auto timer) emits +a `warmCompleted` bus event; cache-warming subscribes and does all post-warm handling — so manual +warms re-arm the timer + push a surface update with **no transport-http change** (core can't depend on +the standard cache-warming ext). Added `nextWarmAt`/`lastWarmAt` state + a `custom` +`rendererId:"cache-warming-timer"` surface field (no ui-contract bump). Caught + fixed a wiring bug +(`createWarmService` missed the `emit` dep → `deps.emit?.` silently no-oped; made it required). +Live-verified vs claude haiku (manual warm logs `warm complete` ~2s after the turn, not the 4-min +timer). FE handoff updated. (FE CR-1 table + CR-2 catalog `scope` flag still open, not requested.) + ## Open items - **`prefix.fingerprint` / `warm|real` cache-bust attributes (deferred):** decoupled from dedup by the content-addressed decision; also gated on cache-warming being |
