Disable only Remend's incomplete-HTML stripping in message/tool content and reasoning rendering. Keep TeX, source data, and sanitization unchanged; unfinished HTML can display literally.
PR #266 identified the less-than comparison trigger. This uses an independently authored renderer configuration fix rather than its TeX-spacing workaround, with streaming, incremental, literal-code, and safety regressions.
A connect that fell back to typed model ids replaced the stored model list
with the typed ids alone, then pruned the user pins against it. A transient
/models failure (503, timeout) therefore deleted every discovered model, its
detected metadata, and its pins, and answered 200.
- DiscoverResult carries the endpoint's HTTP status. A 401/403 fails the
connect even when ids are typed: a rejected key is not a missing model list.
- A failed probe keeps the stored snapshot for the SAME base URL, so the
prune cannot delete pins for a probe that failed. A new base URL starts
clean, so an older endpoint's models never follow the URL.
- Comment corrections: the route contract and the CustomProviderSettings
fields described the behaviour from before the manual-ids change.
- tests/custom-provider-route.test.ts covers the four branches: transient
failure, rejected key, new endpoint with no model list, working probe.
tsc and eslint clean. Suite: 2554 tests, 2 failures, both also failing on
6959482 (render-sidebar date drift, subscription-auth install artifact).
Hosted OpenAI-compatible APIs often serve chat but not GET /models
(Volcengine Ark Agent Plan returns 404), so connect failed. Accept a
typed list of model IDs: merged into discovered models when /models
works, used alone when it does not. The typed list is stored as
customProvider.manualModels so reconnects and pin saves keep it.
A local endpoint that publishes no limits — LM Studio's /models says nothing —
left every model on the 8192/4096 defaults with no way to say "this one has a
131k window". Each discovered model now gets three optional pins in the
endpoint editor: context window, max output tokens, thinking (auto/on/off).
A pin always wins: user pin → what the endpoint published → compiled default.
Blank means no opinion, so discovery keeps ruling wherever you don't pin. Pins
live in customProvider.overrides keyed by model id, stored apart from the
discovery snapshot: a reconnect refreshes the models and prunes the pins of
models that vanished while keeping the rest.
Pins are written by PATCH /api/custom-provider, which never probes — the whole
point is configuring a server that isn't answering /models correctly. Connect
still probes and still fails loudly when the endpoint is down. A pin under 2048
tokens is rejected on the write side and clamped up on the read path, matching
the compaction-floor discipline.
Connecting was one-way: POST could only replace the base URL, and the only
escape was hand-editing settings.json. DELETE now mirrors POST — drop the
stored section, delete the reserved key, unregister the provider from
piModels() — and the connect editor grows a Disconnect beside Connect,
following the stored-key rows' Delete pattern (quiet text, one click, no
confirm, only once there is an endpoint to remove).