fix: apply the review items for #752 and #757 at merge

The launch-id check is pure, so it now runs before the context warning and the
swap confirmation: nobody agrees to evict a model only to get the 400. Also the
search-box and in-use comments, the model-plain-colon wording, and the wiki's
order of the picker's marks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-04 16:53:26 +01:00
1 parent f7dfe091c5
commit 6232dffe03
5 files changed
+61 -34

No files matched your search

+6 -5
View File
@@ -1034,16 +1034,17 @@
<div class="modal-body">
<p class="form-hint" id="customModelPickHint"></p>
<!-- Case-insensitive filter over the rendered rows (app.filterCustomModelPick):
a display layer only, the rows themselves are never re-rendered. Reset and
focused on every open, same in-memory rule as the rail's search box. -->
a display layer only, the rows themselves are never re-rendered. Reset on every
open and focused only on non-touch devices, same in-memory rule as the rail's
search box. -->
<input type="search" id="customModelPickSearch" class="session-sidebar-filter-input custom-model-pick-search"
placeholder="Search models" aria-label="Search models"
autocomplete="off" autocapitalize="off" spellcheck="false" enterkeyhint="search"
oninput="app.filterCustomModelPick(this.value)">
<p class="form-hint custom-model-pick-no-matches" id="customModelPickNoMatches" role="status" hidden>No models match</p>
<!-- Shown only when no row carries a loaded/in-use/last-used mark AND the endpoint
answered that it is not llama-swap (see _openCustomModelPickModal): it says out
loud WHY nothing is marked, in the user's language, rather than leaving an
<!-- Shown only when no row carries a loaded/in-use/last-used mark AND the
running-status probe answered `isLlamaSwap: false` (see
_openCustomModelPickModal): it says out loud WHY nothing is marked, in the user's language, rather than leaving an
alphabetical wall that looks like the question was ignored. -->
<p class="form-hint custom-model-pick-unknown" id="customModelPickUnknown" role="status" hidden>Nothing is marked: this endpoint did not report which model it has loaded, and none of your running sessions uses one. Pick the model to launch.</p>
<div id="customModelPickList" class="run-mode-custom-models"></div>
+24 -23
View File
@@ -1548,6 +1548,30 @@ export function registerSessionRoutes(
const contextLength = resolveCustomModelContextLength(endpoint, body.modelId);
const slotCount = endpoint.modelSlotCounts?.[body.modelId];
// A CLI whose config alone cannot select the model also gets its `model` launch param
// forced (pi/omp `custom/<id>`, grok's block name, and codex now carries its bare
// selected id too). The argv engine DROPS a token that
// fails its pattern rather than quoting it, which would silently launch the CLI on its
// own default provider again, so refuse an id the pattern cannot carry up front.
// The check runs on the PURE build result, before applyCustomModelInjection below:
// the forced launch id only comes out of that build, and writing first would mean a
// refused id already replaced the config dir a live codex session uses as CODEX_HOME.
// It also runs before the two confirmations, so nobody agrees to evict a model only
// to be told the id was never usable.
const modelSpec = entry.launch.params.model;
const injection = buildCustomModelInjection(entry, endpoint, body.modelId, contextLength);
const forcedLaunchModel = injection.kind === 'unsupported' ? undefined : injection.launchModel;
if (
forcedLaunchModel !== undefined &&
modelSpec?.type === 'token' &&
!matchesPattern(modelSpec.pattern, forcedLaunchModel)
) {
return createErrorResponse(
ApiErrorCode.INVALID_INPUT,
`Model id ${JSON.stringify(body.modelId)} cannot be passed to ${session.mode} on its command line`
);
}
// Some CLIs (today: only claude) carry enough of their own fixed system-prompt/tool-
// schema overhead that a small enough real context guarantees a first-message failure
// no matter what CLAUDE_CODE_MAX_CONTEXT_TOKENS says — confirmed live at ~36.4K tokens
@@ -1611,29 +1635,6 @@ export function registerSessionRoutes(
}
}
// A CLI whose config alone cannot select the model also gets its `model` launch param
// forced (pi/omp `custom/<id>`, grok's block name, and codex now carries its bare
// selected id too). The argv engine DROPS a token that
// fails its pattern rather than quoting it, which would silently launch the CLI on its
// own default provider again, so refuse an id the pattern cannot carry up front.
// The check runs on the PURE build result, before applyCustomModelInjection below:
// the forced launch id only comes out of that build, and writing first would mean a
// refused id already replaced the config dir a live codex session uses as CODEX_HOME.
const modelSpec = entry.launch.params.model;
const injection = buildCustomModelInjection(entry, endpoint, body.modelId, contextLength);
if (injection.kind === 'unsupported') {
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, `${session.mode} has no known custom-model mechanism`);
}
if (
injection.launchModel !== undefined &&
modelSpec?.type === 'token' &&
!matchesPattern(modelSpec.pattern, injection.launchModel)
) {
return createErrorResponse(
ApiErrorCode.INVALID_INPUT,
`Model id ${JSON.stringify(body.modelId)} cannot be passed to ${session.mode} on its command line`
);
}
const applied = applyCustomModelInjection(
entry,
endpoint,