mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-03 08:06:01 +08:00
* feat(inspector): add operator inspection API * docs(inspector): assign product service ownership * test(inspector): ratchet diagnostic contracts * feat(inspector): add debug panel shell * test(inspector): cover debug panel shell e2e * fix(inspector): stop diagnostics when panel closes * feat(inspector): add prompt inspection * fix(inspector): follow current webui ownership * feat(inspector): add model call statistics * test(inspector): cover model statistics e2e * fix(inspector): avoid uncollected tool metrics * test(inspector): cover prompt diagnostics e2e * test(inspector): align statistics e2e scope * fix(inspector): redact prompt metadata * fix(inspector): preserve per-call model identity * fix(inspector): classify prompt instruction sources * test(inspector): assert reported token usage * feat(inspector): add activity timeline and turn navigation * test(inspector): cover activity timeline in browser * fix(inspector): read current run before publishing activity * feat(inspector): add bounded tool execution details * test(inspector): cover bounded tool details in browser * fix(inspector): validate retained tool result sizes * test(inspector): add security and operator coverage * test(inspector): cover browser workflows end to end * fix(inspector): address review feedback * fix(inspector): retry transient snapshot failures * fix(inspector): address prompt diagnostic review findings * fix(inspector): follow debug query navigation * feat(inspector): complete frontend diagnostics * test(inspector): cover frontend parity in browser * fix(inspector): preserve stream terminal state * fix(inspector): capture full capability surface * fix(inspector): scope projection activity to its run * fix(inspector): harden activity diagnostics * fix(inspector): bound tool result diagnostic capture * fix(inspector): harden tool diagnostic pipeline * fix(llm): request usage for NEAR AI streams * fix(inspector): address prompt diagnostic review feedback * fix(webui): harden inspector stream coverage * fix(inspector): preserve debug session statistics * fix(inspector): keep diagnostics active while hidden * test(e2e): cover hidden inspector observation * fix inspector model call stats review findings * fix inspector refresh and truncation regressions * fix(inspector): address activity timeline review feedback * fix(inspector): harden activity lifecycle handling * fix(composition): move tool diagnostics to loop host * fix(inspector): keep a settled stream live and complete locale parity A live diagnostic update's debounced snapshot refresh was announcing LOADING, so an open, healthy stream read as "Connecting" indefinitely once a run settled — the settling stats update is the last one. That refresh is now a background read. Incomplete snapshot statistics no longer accumulate as real zeros, browser-session inspector state is namespaced by the authenticated caller, an evicted pinned run rejoins the latest turn instead of the oldest, tool status is localized, and the inspector strings now cover all ten locales. * test(inspector): put the inspector locale sidecar under the parity gate The inspector's English copy is registered from its lazy chunk instead of src/i18n/en.ts, so the all-locale parity test — which derives the required key set from en.ts — never covered those keys; a locale could drop one and fall back to English silently. The test now treats the English key set as the union of en.ts and a declared sidecar list. Keeping the copy in en.ts is not an option: measured, it puts /chat at 217.4 KB gzip against a 217.0 KB budget. * fix(inspector): reject malformed model breakdowns and correct locale copy A `calls_per_model` entry with a negative or non-integer `calls` passed the statistics decoder and was then coerced to zero during accumulation without marking the breakdown truncated, presenting a fabricated "0 calls" for a model. Every entry is now validated before a record is accepted. German turn navigation used "Zug" (a train, or a game move); it now reads "Runde", with the determiner agreement that noun requires. Spanish and Portuguese tool-status values were written feminine against a masculine "Estado"/"Status" label. * fix(inspector): bound the model breakdown before scanning and retaining it The statistics decoder validated every calls_per_model entry but never the array length, so an out-of-contract response was scanned in full and then retained by the accumulator for up to 128 runs. The host truncates this breakdown at MAX_MODELS_IN_STATS and reports it as truncated, so a longer array cannot conform; the client now mirrors that ceiling and rejects the record before the scan. * fix(inspector): align turn navigation with host diagnostic retention The browser offered 32 turns of navigation per thread while the host retained diagnostics for 2 runs per session, so every turn past the second rendered blank. Each layer was individually correct and the e2e scenario stopped at two turns, so nothing saw the dead zone. Retention moves to 4 and the navigation window mirrors it, pinned by a new architecture gate that reads both constants; the scenario now walks back two turns and asserts real activity. Retention is a ceiling as well as a default, and capture is unconditional, so 4 is a resident memory choice — roughly 80 MB worst case across the eight tracked sessions. * fix(composition): delimit the i18n bundle guard with an i18n-owned marker The guard sliced the concatenated chunk bundle from the i18n provider up to `QueryClient`, a symbol another module owns, so the segment's extent tracked Rollup's chunk boundaries. A split that merely folded react-query into the entry chunk removed that marker from everything appended after the provider and failed an i18n guard with no i18n change. It now ends on the AVAILABLE_LANGUAGES literal that follows the provider in the same module; string literals survive minification, and every existing assertion holds against the tighter segment. * fix(architecture): resolve the inspector gate's SPA path through crate_path The gate joined a family-nested literal onto the workspace root, the idiom crate_path exists to replace: a crate family move would have turned this into a read failure rather than a resolved path. It now names the SPA file in the logical flat spelling and resolves it, and the assertion reports the resolved path so the message still points at a file that exists. * test(inspector): follow a pinned turn explicitly when a new turn arrives The multi-turn scenario assumed the panel would jump to an arriving turn, but a selection the operator navigated to is deliberately sticky: the new turn widens the window without yanking them off the turn they are reading. The scenario now asserts that guarantee, then clicks Latest to follow, then walks back two turns as before. Verified by running the inspector scenarios locally rather than by reading, which is how this slipped through the first time.