fix(custom-model): address PR #430 pre-merge review (Ark0N)

Four blockers from the 2026-09-18 review:

- PUT /api/model-endpoints/:id now merges modelContextLengths/
  modelSizesGB back in from the stored record instead of trusting the
  editor's body, so renaming an endpoint or changing its default model
  no longer silently drops the context-window floor check and
  CLAUDE_CODE_MAX_CONTEXT_TOKENS injection.
- custom-model:swapped-out is now session-scoped (added to
  SESSION_PREFIXES) instead of broadcasting to every connected client.
- The quick-start custom-model path now hands setCustomModel() only
  the endpoint's own injected env vars, not the full merged set,
  matching the restart-in-place path — the full set put
  CLAUDE_CODE_EFFORT_LEVEL back after the Session constructor had
  already stripped it.
- The quick-start launchModel override for pi/grok/omp is now applied
  generically via the registry's legacyConfigField, mirroring
  Session._withCustomModelLaunchModel, instead of three hardcoded
  mode === '<id>' branches a future CLI's injection recipe would miss.

Also scopes the sticky-toast default (item 5): reverted the blanket
"all error toasts are sticky" default, which had no container cap or
eviction, back to a flat 3s; the one message that needs a moment to
read (a failed custom-model apply) now passes an explicit
duration: 0 at its own call site.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ea59JhUmHBm1gRCsiYF33R
This commit is contained in:
Devvyn
2026-09-18 20:16:07 +08:00
co-authored by Claude Sonnet 5
parent e2034177c5
commit 1f32128ca9
6 changed files with 59 additions and 34 deletions
+11 -11
View File
@@ -5485,19 +5485,19 @@ Object.assign(CodemanApp.prototype, {
},
/**
* `duration` defaults to 0 (sticky, no auto-dismiss) for `error` toasts and
* 3000ms for everything else — an error worth a distinct visual style is
* also worth reading before it vanishes, which a fixed 3s auto-dismiss
* does not guarantee: "Session started on the native backend — could not
* apply the custom endpoint: <the actual reason>" is exactly the kind of
* message that needs a moment to read, not a glance. Every toast gets an
* explicit close button regardless of duration, since a sticky one with no
* way to dismiss it would just pile up. A caller can still override either
* default via `opts.duration` (e.g. a deliberately brief success toast, or
* a non-error one that should also stay put).
* `duration` defaults to 3000ms for every toast type. A message worth
* reading rather than glancing at (e.g. "Session started on the native
* backend — could not apply the custom endpoint: <the actual reason>")
* passes an explicit `opts.duration: 0` at its own call site instead of
* widening the default: this used to default every `error` toast to
* sticky, and with no cap on `.toast-container` and no eviction, a
* repeatedly failing path (a flapping SSE reconnect, a poll loop) stacked
* sticky toasts off the bottom of the viewport where they could not be
* read or dismissed. Every toast still gets an explicit close button
* regardless of duration.
*/
showToast(message, type = 'info', opts = {}) {
const { duration = type === 'error' ? 0 : 3000, action } = opts;
const { duration = 3000, action } = opts;
const toast = document.createElement('div');
toast.className = `toast toast-${type}`;
+3 -1
View File
@@ -962,7 +962,9 @@ Object.assign(CodemanApp.prototype, {
if (!ok || !data || data.success === false) {
switchingToast?.dismiss();
const detail = data?.error ? `: ${data.error}` : res ? ` (HTTP ${res.status})` : ' (request failed)';
this.showToast(`Session started on the native backend — could not apply the custom endpoint${detail}`, 'error');
this.showToast(`Session started on the native backend — could not apply the custom endpoint${detail}`, 'error', {
duration: 0,
});
return;
}