HERMES-GIELIE/api
nesquena-hermes 6745827eb5 fix(#5979 follow-up): preserve custom-proxy vendor namespace on cold-catalog sends
The earlier #5979 fix (PR #5980, exp-v0.52.53) resolved the WARM-catalog and
config-declared cases, but b3nw confirmed truncation persists on exp-v0.52.55/56.

Root cause (reproduced on master, confirmed by Codex + Fable):
b3nw's config is provider: custom:llm-proxy, model.default: x-ai/grok-4.5, no
models[] allowlist. His DEFAULT (x-ai/grok-4.5) preserves via config-declaration,
but a model he SELECTS in the picker that isn't the default (x-ai/grok-composer-2.5-fast)
truncates on every COLD send. The send path (api/streaming.py:7857) calls
resolve_model_provider without warming the catalog, and the #1855 chat/start fast
path deliberately skips the catalog when a session already has a persisted
model+provider -- so 'cold at send' is the designed state after any restart /
settings-save / cache-expiry, not a rare race. With provenance None and no config
declaration, the #5980 tri-state fell through to the LEGACY family strip
(if prefix in _PROVIDER_MODELS and _is_first_party_model: return bare), and
grok-composer-2.5-fast had graduated into the x-ai first-party catalog -> stripped.

Fix (two changes, both advisor-verified):
1. Flip the custom-arm cold default from family-strip to PRESERVE-verbatim
   (api/config.py). For an explicit custom / custom:<slug> proxy the strip now
   requires POSITIVE provenance (endpoint advertises only the bare id, #433). A
   wrong strip destroys routing info the user can't recover; a wrong preserve
   fails loudly and self-heals on warm. This also honours _endpoint_advertised_model_ids's
   own documented 'None -> preserve verbatim' contract and removes the data-driven
   flaw where a model graduating into the static catalog silently flips routing.
2. Network-free provenance warm on the send path
   (warm_models_catalog_provenance_if_cold, called in streaming.py before the
   resolve). prefer_cache=True republishes provenance from the durable disk cache
   (no live probe, no _cfg_lock held on the worker thread -> no lock-order
   deadlock), so #433's bare-only-strip stays exact whenever a disk cache exists.

Residual (accepted, strictly better than master): a #433-shaped wrong-preserve
now requires memory cold AND disk cache absent/invalid (first run, post-config-save
window, schema/version bump). It fails loudly and heals on the next /api/models or
session-visit rebuild. Under master b3nw's failure was the mirror image but silent,
recurring every send, and unfixable short of declaring every model in config.

Supersedes rodboev's #5996, which targeted the providers.<slug> arm and does not
cover b3nw's actual custom:llm-proxy config (confirmed by Codex).

Tests: rewrite the cold-fallback test (strip -> preserve), sharpen the
foreign-profile test so trusted-strip vs ignored-preserve genuinely diverge, add
b3nw's exact cold non-declared custom:slug case, and add three warm-helper tests
(publishes-from-disk, noop-when-warm, never-live-rebuilds). 64 resolver+sprint40
tests pass; b3nw end-to-end verified; #433 positive-provenance strip verified.

Thanks @b3nw for the CLI-vs-WebUI comparison that localized it.
2026-07-13 01:43:17 +00:00
..
__init__.py
agent_health.py Single-flight remote gateway health probe to stop cold-cache stampede 2026-07-09 03:54:10 +00:00
agent_sessions.py Release exp-v0.52.40: ACP sessions in sidebar (#5939) + date-stamped Claude 3.0 reasoning fix (#5934) (#5951) 2026-07-11 15:20:41 -07:00
auth.py Release exp-v0.52.43: trusted-header auth / reverse-proxy SSO (#5568, #3351) (#5956) 2026-07-11 16:34:14 -07:00
auth_oidc.py fix(#3825): harden oidc endpoint and claim validation 2026-06-30 20:59:19 -04:00
background.py
background_process.py Merge remote-tracking branch 'origin/master' into paperclip/pr-5732 2026-07-09 09:43:54 +08:00
clarify.py stage #4524: clarify 409-terminal (id-guarded, loading-cleared) + SSE-notify on expiry (#4504) + v0.51.534 CHANGELOG 2026-06-20 05:36:56 +00:00
commands.py fix(webui): guard non-dict resolve_moa_preset result in resolve_moa_config 2026-07-01 07:54:48 -05:00
compression_anchor.py Address compaction marker and redaction review 2026-06-26 00:12:09 +00:00
compression_recovery.py Live Stream: add compression recovery action 2026-07-04 21:42:32 +08:00
config.py fix(#5979 follow-up): preserve custom-proxy vendor namespace on cold-catalog sends 2026-07-13 01:43:17 +00:00
crash_visibility.py fix(webui): crash visibility — faulthandler + thread excepthook + exit audit (#4633) 2026-07-01 18:01:39 +00:00
dashboard_probe.py
extensions.py fix: prefer IPv4 for extension gallery downloads to prevent timeout on broken IPv6 2026-07-03 20:26:18 +00:00
gateway_chat.py Preserve latest session on wakeup pause clear 2026-07-10 13:20:40 +08:00
gateway_restart.py fix(health): preserve restart failure contract and proofs (#5156) 2026-06-29 03:44:06 +00:00
gateway_watcher.py fix(sessions): open state.db read-only for lineage reads + watcher projection 2026-07-08 20:17:45 +00:00
goals.py
helpers.py Release exp-v0.52.43: trusted-header auth / reverse-proxy SSO (#5568, #3351) (#5956) 2026-07-11 16:34:14 -07:00
kanban_bridge.py rebase(#2814): resolve i18n onto current master + add kanban_view_* keys to all 13 locales 2026-06-23 23:40:45 +00:00
metering.py
models.py Release exp-v0.52.48: post-compression context metering (#5872, #4685) (#5977) 2026-07-11 20:41:43 -07:00
oauth.py Release Batch D: terminal resource-leak fix + fsync atomic writers (#5835, #5843) (#5848) 2026-07-09 10:54:06 -07:00
office_documents.py #5142: office-doc preview + safe docx editing (#540), rebased on master; optional deps 2026-07-02 01:15:57 +00:00
onboarding.py Release exp-v0.52.42: ?profile= deep links (#5730) + Russian locale refresh (#5778) (#5953) 2026-07-11 15:58:47 -07:00
passkeys.py Release Batch D: terminal resource-leak fix + fsync atomic writers (#5835, #5843) (#5848) 2026-07-09 10:54:06 -07:00
paths.py
plugin_providers.py
plugins.py
profiles.py fix(#5696): revert profiles cache TTL 60s->4s (stale profile rows); contributor-flagged follow-up 2026-07-06 20:40:08 +00:00
providers.py Require fingerprint evidence for wakeup credential recovery 2026-07-10 12:23:02 +08:00
request_diagnostics.py perf(webui/session-load-latency) tier4: fix CI failures — lint B009/B905 + _emit_slow format args 2026-07-09 04:22:21 +00:00
rollback.py fix(#4410): pre-check workspace leaf type via lstat + close fd on non-regular (Codex gate v2) 2026-06-18 19:22:29 +00:00
route_approvals.py fix(#5000): relay mirrored gateway approvals after stream loss 2026-06-27 06:03:24 +00:00
route_session_list_cache.py feat: add Webhooks sidebar filter parity 2026-06-30 17:06:31 +00:00
routes.py Release exp-v0.52.48: post-compression context metering (#5872, #4685) (#5977) 2026-07-11 20:41:43 -07:00
run_journal.py fix(#4812): re-sync idle no-cursor SSE subscriber on run completing during keepalive wait 2026-07-10 20:15:49 +00:00
runner_client.py fix(gateway): correct approval URL and thread session history into runs API (#4479) 2026-06-19 13:16:39 -04:00
runtime_adapter.py
session_discoverability.py Release Batch D: terminal resource-leak fix + fsync atomic writers (#5835, #5843) (#5848) 2026-07-09 10:54:06 -07:00
session_events.py
session_export_html.py #4968: export chat to self-contained themed HTML, rebased on master 2026-07-02 02:36:09 +00:00
session_lifecycle.py fix(#5543): fire-and-forget commit_session_memory + drain-safe managed stop 2026-07-04 21:40:21 +00:00
session_ops.py fix(#5563): align forked context to display for large (compacted) sessions 2026-07-04 20:55:06 +00:00
session_recovery.py Merge latest master into compression recovery action 2026-07-05 10:23:15 +08:00
shares.py fix(share): reject dict-valued text-blocks and dict titles (re-gate edge) 2026-07-11 02:14:07 +00:00
skill_usage.py
sse_chunked.py stage #4447: opt-in chunked SSE for buffering proxies (#4447) + v0.51.524 CHANGELOG 2026-06-19 22:09:17 +00:00
startup.py
state_sync.py fix(state-sync): mirror WebUI API call counts 2026-07-07 19:48:19 +00:00
streaming.py fix(#5979 follow-up): preserve custom-proxy vendor namespace on cold-catalog sends 2026-07-13 01:43:17 +00:00
system_health.py fix: keep psutil optional for system health 2026-06-26 20:49:13 +00:00
terminal.py Release Batch D: terminal resource-leak fix + fsync atomic writers (#5835, #5843) (#5848) 2026-07-09 10:54:06 -07:00
todo_state.py
turn_journal.py
updates.py Release exp-v0.52.44: Docker/no-git image update notices (#5733, #2729) (#5958) 2026-07-11 16:46:13 -07:00
upload.py Release: write Office upload sidecars (#5734, #540) (#5859) 2026-07-09 15:57:21 -07:00
usage.py
webui_session_db.py fix: preserve compression recovery child markers in sidecar rebuild 2026-07-05 06:45:50 +08:00
workspace.py #5142: office-doc preview + safe docx editing (#540), rebased on master; optional deps 2026-07-02 01:15:57 +00:00
workspace_git.py fix(workspace-git): hide git subprocess console windows on Windows (#5692) 2026-07-07 02:07:39 +00:00
worktrees.py Release Batch A: worktree cli-shadow + atomic settings.json + state.db read-only (#5832, #5829, #5833) (#5837) 2026-07-09 09:04:59 -07:00