opencode.ai/zen/v1 rejects non-browser clients (urllib) with 403
error_code 1010 while curl on the same key succeeds. The 403 was
treated as an auth-level failure and two of them crystallized a
misleading ALL_ACCOUNTS_INACTIVE on the free pool.
- errorClassifier: new FINGERPRINT_REJECTION type; a 403 carrying
error_code 1010 / browser_signature_banned is the CDN refusing the
client TLS/UA signature, not the account credentials.
- combo/targetExhaustion: fingerprint rejections skip auth-level
exhaustion so remaining targets stay eligible.
- auth: resolveTerminalConnectionStatus no longer treats the
fingerprint rejection as a terminal banned account state.
UA passthrough is deliberately untouched: #5997/#5720 make the
forward-only behavior load-bearing.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
Replace literal <app-name> and <org-slug> with HTML entities (< >)
in the denoRelayOrgDomainHint translation key for all 43 locale files.
The React Flight (RSC) protocol parser interprets unclosed angle-bracket
tokens as HTML tags, causing INVALID_MESSAGE: UNCLOSED_TAG errors when
rendering the DenoRelayModal component on /dashboard/system/proxy.
Add regression test suite (tests/unit/i18n-deno-relay-unclosed-tag.test.ts)
covering four axes: valid JSON (no BOM), key existence, no raw angle brackets,
and correct HTML entities in all locales.
Both tables (002_mcp_a2a_tables.sql) store their row timestamp in
created_at; the cleanup queries used WHERE timestamp < ? which does not
exist, so every boot-time cleanup logged:
Error cleaning mcp_tool_audit: SqliteError: no such column: timestamp
Error cleaning a2a_task_events: SqliteError: no such column: timestamp
and retention pruning for these two tables never ran. Fix the DELETE
columns and align the log labels/doc comments with the real table names.
Adds source-level invariant tests (cleanup-column-fix.test.mjs) asserting
the created_at column for both tables.
process.uptime() returns a number, but the handler ran it through a
string-only toString() helper that fell back to "unknown" for anything
that wasn't already a string -- so every real uptime value was
discarded, 100% reproducibly.
Also stop masking upstream fetch failures as fake healthy defaults:
when /api/monitoring/health, /api/resilience, or /api/rate-limits
can't be reached, the tool now reports which source failed (via a new
optional `degraded` field) instead of returning zeros/empty arrays
indistinguishable from genuine "no data".
Regression coverage dispatches through the real MCP handler (client.callTool)
rather than asserting on the mock directly, since the prior mock-only
tests could never have caught either bug.
* fix(memory): allow OMNIROUTE_STRICT_SYSTEM_PROVIDERS to extend the system-first provider list
PROVIDERS_SYSTEM_MUST_BE_FIRST (added in #6225 for #6135) gates both the
memory-injection placement fix and the #7293 hoistLeadingSystemMessage
translator fix, but was hardcoded to xiaomi-mimo/mimo only. Self-hosted
deployments routing other strict backends (e.g. a custom OpenAI-compatible
connection in front of a self-hosted Qwen3.5+/3.6 model, whose chat template
rejects any non-leading system message the same way) had no way to opt in
without forking and rebuilding the image.
Adds OMNIROUTE_STRICT_SYSTEM_PROVIDERS (comma-separated, case-insensitive
provider ids) to extend the built-in set at read time, mirroring the
injectable-env pattern already used in src/lib/memory/typedDecay.ts. No
behavior change for anyone who doesn't set it.
* chore: fix changelog fragment PR number
Add examples/quickstart/ with minimal copy-paste scripts that let new
users get a response from a local OmniRoute server in under a minute,
without needing to read the full docs first.
Files added:
- examples/quickstart/python_requests.py (requests library)
- examples/quickstart/nodejs_axios.js (axios)
- examples/quickstart/curl_terminal.sh (bash one-liner)
- examples/quickstart/php_curl.php (cURL extension)
- examples/quickstart/README.md (table + key-settings cheatsheet)
README.md: add one sub-line pointer to examples/quickstart/ below the
existing zero-config curl snippet, matching the surrounding <sub> style.
* fix(i18n): re-escape CC discovery-alias angle brackets for next-intl
Restore #8747 HTML-entity escaping for claude/<provider>/<model> in the
three CC discovery-alias message keys so next-intl stops logging
INVALID_MESSAGE: UNCLOSED_TAG on provider detail pages after the bulk
entity-unescape regression.
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore(i18n): align conflict context with release
* fix(i18n): cover localized CC alias placeholders
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>