Registered `edit.input` and `eval.code` alongside `write.content` so the reveal controller decodes those top-level string arguments incrementally between throttled full-JSON parses.
Added a regression test covering multi-key extraction so the wire-up survives future additions.
Refs #4043
Added incremental decoding for streamed write content so preview args update below the full JSON parse throttle.
Added a regression test covering sub-throttle content growth in ToolArgsRevealController.
Fixes#4043
AGENTS.md forbids inline `await import()` — move `fs`, `path`, and `prompt`
to top-level namespace/named imports. The `prompt-templates` module import
already registers the Handlebars helper as a side-effect, so the render
calls still resolve the new `renderYieldSchema` helper.
- Updated exact substring match assertions to use word-boundary regular expressions.
- Prevents false-positive test failures when target strings overlap with other generated text.
The eval tool's live agent()/parallel() subagent progress tree
(renderAgentProgressEvents) mutates on almost every progress tick: each
subagent's row inserts/removes a "current tool" line as it starts/stops a
tool call, and ticks its status icon/stats/duration in place. Meanwhile
options.isPartial holds true for the whole eval() cell — progress ticks
never carry an async completed/failed state, so the update handler keeps
passing isPartial: true throughout.
evalToolRenderer never opted out of the transcript's stable-prefix ratchet
for partial results, so ToolExecutionComponent.isTranscriptBlockCommitStable()
reported the block commit-stable during that churn. That let
deriveLiveCommitState promote still-mutating agent rows into native
scrollback (a "slow ticker"), and the renderer's committed-prefix resync
then repeatedly re-showed the frame tail under its "duplication, never
loss" contract — producing overlapping/duplicated subagent rows in the
TUI under heavy concurrent agent()/parallel() fan-out.
Set provisionalPartialResult: true on evalToolRenderer, the same opt-out
sshToolRenderer already uses for this class of bug (see the "pinned
expanded pending preview commit-unstable" fix). The block now stays
commit-unstable until the eval cell settles, keeping agent-progress rows
in the live, repaintable region for their whole lifetime.
Added eval-commit-stability.test.ts covering: partial → commit-unstable,
settled → commit-stable, non-opted-in tools (bash) unaffected, and
commit-unstable held across row-count/content churn between two partial
ticks.
Op: correct
Restores: spec:eval agent-progress rows must not be promoted into native scrollback while still mutating
- Removed the canonical model variant indexing, selection, and tracking logic from the model registry and resolver.
- Eliminated the `canonical` sub-command, tab view, search tokens, and equivalence configuration structures from the CLI and model selector components.
- Refined model identification, lookup, and provider fallback resolution to bind exclusively to standard, raw model IDs.
- Relocated the equivalence utility script within the catalog package to support script-only policy generation.
Preserved the referenced model's OpenAI-compatible reasoning-effort support when openai-models-list discovery enriches a thin /v1/models payload. The discovered model still keeps conservative proxy-local store and developer-role defaults, but known reasoning models like gpt-5 no longer force supportsReasoningEffort false and trigger the omitReasoningEffort request path.
Added a regression assertion that a thin proxied gpt-5 keeps supportsReasoningEffort true and omitReasoningEffort false after reference enrichment.
Fixes#3983
Thin OpenAI-compatible proxies that omit context_length / max_model_len on
/v1/models made every discovered model fall back to
DISCOVERY_DEFAULT_CONTEXT_WINDOW (128K/33K), even when the id matched a
bundled model with a much larger intrinsic window. discoverProxyModels
and discoverLiteLLMModels already resolve ids against the bundled
reference index; discoverOpenAIModelsList (which also backs lm-studio
discovery) now does the same.
Behavior:
- Build the reference index once outside the loop and resolve each item
via resolveModelReference().
- contextWindow precedence keeps provider-reported values authoritative:
item.max_model_len ?? item.context_length ?? nativeMetadata?.contextWindow
?? reference?.contextWindow ?? DISCOVERY_DEFAULT_CONTEXT_WINDOW.
- maxTokens uses reference?.maxTokens when available, otherwise the
api-specific discovery default, capped at contextWindow so a bundled
ref for a larger sibling can never over-request output tokens.
- name / reasoning / thinking / input inherit from the reference; native
lm-studio metadata still wins for input modality.
- Provider-specific baseUrl, headers, and local-unknown cost stay local.
- OpenAI-compat flags stay conservative (supportsStore / supportsDeveloperRole
/ supportsReasoningEffort all false) to match the proxy sibling.
Also updated two pre-existing regression tests that used
deepseek-v4-pro / deepseek-r1 / DeepSeek-V4-Flash as stand-in "fictional"
ids to exercise the default-fallback branch. Those model names have since
been added to the bundled catalog, so the tests were renamed to
vllm-lab-fork-* ids that unambiguously miss the reference index while
preserving each test's original default-fallback intent.
Fixes#3983
Added a cross-turn tool-call loop guard that hashes canonical tool names and arguments, ignores intent metadata, and injects a hidden redirect when identical calls reach the configured threshold.
Fixes#3971
- Introduced an `#editVariantCache` to memoize resolved edit modes for model variants.
- Replaced the generic `shallowStringRecord` helper with specialized, type-safe parsing methods for model variants and roles.
- Invalidated the cached edit variants during settings rebuilds and verified correct cache refreshment across project directories.
- Moved Streamable HTTP request and notify timeout cleanup after response body consumption.\n- Added regression coverage for stalled request JSON bodies and stalled notify error bodies.\n\nFixes #3974