Skip to content

feat(providers): add MaxAI — signed OpenAI-compatible provider (chat, tools, vision, image-gen, doc-RAG) - #11461

Open
arminanton wants to merge 29 commits into
diegosouzapw:release/v3.8.51from
arminanton:feat/maxai-provider
Open

feat(providers): add MaxAI — signed OpenAI-compatible provider (chat, tools, vision, image-gen, doc-RAG)#11461
arminanton wants to merge 29 commits into
diegosouzapw:release/v3.8.51from
arminanton:feat/maxai-provider

Conversation

@arminanton

@arminanton arminanton commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds MaxAI as a first-class, signed, OpenAI-compatible provider. MaxAI is a
web-app AI aggregator; this integration lets OmniRoute route to its 13 paid
chat models
(plus 6 image models) through the standard /v1 endpoints,
with full request signing, live model discovery, browserless onboarding,
prompted tool-calling, vision input, image generation, and document RAG.

Chat models (live from /models/get_config): gpt-5.6, gpt-5.6-luna,
gpt-5.6-thinking, claude-5-sonnet, claude-haiku-4-5, gemini-3.1-pro-preview,
gemini-3-1-flash-lite, grok-4-1-fast-reasoning, grok-4-1-fast-non-reasoning,
grok-4.5, deepseek-v3.2, deepseek-r1, llama-3.3-70b.

Image models (/v1/images/generations): gpt-image-1, dall-e-3,
flux-1-schnell, flux-1-dev, flux-1-pro, sd3-medium.

What's in the box

  • Signed executor (open-sse/executors/maxai/*): per-request X-Authorization
    built as HMAC-SHA1 → SM3 → CryptoJS-compatible AES-256-CBC over a structured
    payload, reproduced with node:crypto. Chat via POST /gpt/cwc/chat (SSE),
    reasoning surfaced from inline <think> blocks.
  • Live model + context-window discovery (services/maxaiModels.ts): signs
    /models/get_config, maps the curated chat models with their real max_tokens
    and capability flags (incl. vision), and feeds the existing 24h context-window
    reconciler.
  • Vision input: image_url content parts are forwarded inline in
    message_content to the 6 vision-capable models (GPT-5.6 / Luna / Thinking,
    Claude Haiku 4.5, Gemini 3.1 Pro / Flash-Lite). Mirrors the
    translator/request/openai-to-cursor.ts text-flatten-plus-preserve-images
    pattern; the text-only path is byte-unchanged.
  • Image generation (open-sse/handlers/imageGeneration/providers/maxaiImage.ts):
    a new maxai-image format modeled on the designer-web handler (single
    synchronous JSON, no poll loop). gpt-image-1/dall-e-3 sizes are snapped to
    1024×1024 (they 500 on 512×512); flux models pass any size through.
  • Document RAG (open-sse/executors/maxai/documents.ts): inline base64
    file/input_file/document parts are uploaded to /app/upload_document
    with the content-addressed doc_id = HMAC-SHA1(bytes, IT) MaxAI requires, then
    attached to the chat via doc_list. Best-effort: upload failures are skipped.
  • Browserless onboarding: email device-pair login
    (/api/providers/[id]/login, 2-step request→verify) and signed access-token
    refresh (/oauth/refresh_access_token). No browser and no Google OAuth.
  • Prompted tool-calling: injects a compact tool contract and parses the model
    output back into OpenAI tool_calls, with one bounded nudged retry to recover
    reasoning models that narrate instead of emitting. All 13 models emit clean
    tool_calls.
  • Per-provider TLS impersonation (utils/tlsClient.ts, utils/proxyFetch.ts):
    MaxAI presents a Windows Firefox-150 client fingerprint; all other
    providers keep the default profile.
  • Resilience polish: floors the request-queue execution budget at 5 min for
    slow reasoning models, and classifies a body-too-large rejection as
    context_length_exceeded so OmniRoute compresses + retries.

Related Issues

  • Related to #

Validation

  • Change type: provider
  • Focused tests: tests/unit/maxai.test.ts (45), maxai-image.test.ts (9),
    maxai-documents.test.ts (14) — 68/68 green
  • npm run typecheck:core — clean
  • Docs-count gate (check-docs-counts-sync) — green (chat provider count 353;
    the image provider lives in the separate IMAGE_PROVIDERS map)
  • Changelog integrity — green (fragment covers all capabilities)
  • npm run lint
  • Reconciled against the current active release base; focused checks rerun

Live end-to-end (residential egress, natural paced prompts):

  • /v1/models serves all 13 MaxAI chat models with correct context windows
  • gpt-5.6-luna plain chat → HTTP 200, coherent answer
  • deepseek-r1 tool-style prompt → HTTP 200, clean get_current_weather tool_call
  • (vision / image-gen / doc-RAG live checks appended after the capability rebuild)

Tests Added Or Updated

  • tests/unit/maxai.test.ts — signing, credentials, protocol/SSE, tool-mode,
    email login, refresh, model discovery, context_length_exceeded, +6 vision
    tests
    (extractCurrentTurnImages, mixed message_content).
  • tests/unit/maxai-image.test.ts — new, 9 cases: registry entry, snapMaxaiImageSize,
    resolveMaxaiImageModel, extractMaxaiImageUrls, and the handler (mocked fetch:
    success, 401-retryable, empty-prompt, no-credential, no-images-502).
  • tests/unit/maxai-documents.test.ts — new, 14 cases: computeMaxaiDocId (HMAC
    cross-checked vs a Python reference), maxaiDocType, parseInlineDataUrl,
    extractCurrentTurnDocs (3 inline shapes), buildUploadMultipart, and the
    upload/resolve flow (mocked fetch).
  • tests/unit/ratelimit-admission-control-6593.test.ts — updated for the 5-min
    execution-budget floor.

Coverage Notes

  • New open-sse/executors/maxai/*, services/maxaiModels.ts, and
    handlers/imageGeneration/providers/maxaiImage.ts are covered by the three
    maxai test files (signing vectors, SSE deltas, tool translation, discovery,
    vision extraction, image size-snapping, doc_id HMAC, multipart build).

Reviewer Notes

  • Signing: the X-Authorization scheme is reproduced verbatim from the
    web-app constants; unit vectors pin it so a future drift fails loudly.
  • Public web-app constants: the HMAC/AES keys in executors/maxai/signing.ts
    and the doc_id HMAC key in documents.ts are public values that ship in
    the www.maxai.co bundle (identical for every visitor), not user/server secrets.
    They are named to reflect that, and a documented .gitleaks.toml allowlist
    entry keeps the secret-scan ratchet stable. They are load-bearing (signing /
    content-addressing fail without them).
  • Image registry: IMAGE_PROVIDERS is a separate map from the chat provider
    registry, so the maxai image entry does not collide with the maxai chat
    provider and does not change the chat provider count.
  • TLS profile: the Firefox-150 override is provider-scoped (maxai only).
  • Onboarding: login/refresh are browserless by design; no camoufox / Google OAuth.
  • Risk notice: MaxAI intentionally carries no subscriptionRisk banner and
    no notice, mirroring the codex-app-server provider's clean posture. It is
    token-authenticated (bearer + ~1-year browserless refresh), so the webCookie
    caveat ("session may invalidate at any time") and the oauth caveat ("official
    session not authorized for proxy use") are both inaccurate; the authHint
    carries the only guidance a connecting operator needs.
  • No new migrations, no feature flags.

arminanton and others added 21 commits August 24, 2026 20:10
MaxAI (chat.maxai.co / api.maxai.me) is a consumer web app with no public API.
This adds it as an OmniRoute provider modeled on the zai-web signed-web-app
pattern: a custom executor that reproduces the web app's own signed request to
/gpt/cwc/chat.

- executors/maxai/signing.ts: per-request X-Authorization = HMAC-SHA1 -> SM3 ->
  CryptoJS-AES-256-CBC (Salted__/EVP-MD5), pure node:crypto, zero deps.
  Validated BYTE-EXACT against real captured web-app requests (see test).
- executors/maxai/protocol.ts: Firefox-150 headers + /gpt/cwc/chat body +
  OpenAI messages[] -> single flattened message_content (stateless-full-history,
  prompted tool-calls as <tool_call>/<tool_response> text). A live probe proved a
  bare chat call honors model_name (no upsert/AIProvider bookkeeping needed).
- executors/maxai/stream.ts: SSE text-delta parse (data_key==text && need_merge),
  incremental <think> reasoning split, ~4char/token estimate.
- executors/maxai/credentials.ts: resolve access token + device id + user id from
  the connection providerSpecificData (self-contained; token minted out-of-band by
  the browser-mint since MaxAI OAuth refresh is deep-TLS-gated).
- executors/maxai/catalog.ts: the 13 paid chat models + context windows.
- maxai.ts: the executor (residential egress + Firefox TLS applied transparently
  by the ambient patched fetch; SSE -> OpenAI chat.completion(.chunk) bridge).
- registry entry + REGISTRY map + executor map + WEB_COOKIE_PROVIDERS constant +
  webSessionCredentials requirement (kind: token).
- tests: 17/17, incl byte-exact signer vectors vs real captured X-Authorization.

Live-verified end to end through the residential path: signed /models/get_config
and /gpt/cwc/chat both returned 200 with a real GPT-5.6 answer.
…MaxAI)

The wreq-js TLS overlay hard-coded chrome_124/macos for every executor fetch.
MaxAI expects a Windows Firefox-150 client fingerprint, so:

- tlsClient.ts: TlsFetchOptions gains optional browserProfile + os; threaded
  through getSession (defaults preserved: chrome_124/macos) and folded into the
  session key so a firefox session never collides with a chrome one.
- proxyFetch.ts: TLS_PROVIDER_PROFILE maps maxai -> {firefox_150, windows};
  tlsProfileForProvider() is spread into both (direct + proxied) activeTlsClient
  .fetch calls, keyed off the ambient tlsStore.provider. No behavior change for
  any provider without an override.

Live-verified earlier: firefox_150 through the residential proxy is accepted 200
by MaxAI on the guarded /models/get_config and /gpt/cwc/chat endpoints.
…sh_access_token

MaxAI issues a ~24h access token and a ~1-year refresh token. The web app
refreshes the access token by POSTing the refresh token to
/oauth/refresh_access_token with the same per-request X-Authorization signature
as every other MaxAI call (web-app chunk 86042, refreshAccessToken) -- it is NOT
a browser-only OAuth hop. A residential Firefox-TLS client passes the TLS gate,
so OmniRoute mints fresh access tokens itself with no browser.

- add maxai/refresh.ts: maxaiRefreshAccessToken() (byte-faithful request:
  Bearer refresh token, noAuthLogout, X-Auth signing over the bare path, body
  {app:maxai_webapp}) + maxaiAccessTokenNeedsRefresh() expiry-margin check.
- resolve refreshToken in the credential model (maxaiRefreshToken/refreshToken).
- executor proactively refreshes a near-expiry access token before each request
  and persists the new token via onCredentialsRefreshed; fails soft (a dead token
  still surfaces as an upstream 401/418).
- 4 unit tests (expiry logic, exact request shape via injected fetch, non-200
  structured error, missing-input guard). 21/21 maxai tests green.

The ~yearly refresh-token mint (visual Google OAuth via camoufox) is separate.
MaxAI's email-code sign-in is two plain signed HTTP POSTs carrying the same
X-Authorization signature as every other MaxAI call (web-app chunk 86042,
signInWithEmail + verifySecretCode) -- a codex-style device-pair flow, no
browser / camoufox / Google navigation. Both routes are already in the signer's
BLANK_USER_ROUTES (they sign with a blank user id, correct pre-login).

- add maxai/emailLogin.ts:
  - requestMaxaiEmailCode({email,deviceId}) -> POST /oauth/signin_with_email
    {email,app:maxai_webapp}; status OK means a code was emailed.
  - verifyMaxaiEmailCode({email,code,deviceId,clientUserId}) -> POST
    /oauth/verify_secret_code (full pinned body) -> data.auth_user ->
    MaxaiLoginCredential {accessToken,refreshToken,userId,email,deviceId,clientUserId}.
  - deviceId + clientUserId are client-minted UUIDs (the web app's
    getAPIFetchDeviceID is generate-if-absent), reused across both steps and all
    later chat/refresh calls; no browser extraction.
  - 10119 -> 'code expired' message; never throws (structured results).
- 6 unit tests (request shape, verify->credential, 10119, invalid-code,
  guards). 27/27 maxai tests green.

Proven live end-to-end: email login -> chat -> browserless refresh -> chat, all
200, from the residential egress. Google OAuth path to follow as a fallback.
…ders/[id]/login

Two-step, no browser: POST {step:'request',email} mints+persists a client device
id and emails a code; POST {step:'verify',code} exchanges it for the full
credential (access + ~1-year refresh token) and persists to the connection
(apiKey=access token; providerSpecificData carries refresh/device/user/client ids
+ signedInAt). Device id is minted in step 1 and read back in step 2 so both
signed calls share it (the route is stateless across the two requests).

Uses open-sse/executors/maxai/emailLogin.ts (requestMaxaiEmailCode /
verifyMaxaiEmailCode). No new type errors (the lone tsc hit on this file is the
pre-existing requireManagementAuth return-type diagnostic).
MaxAI has no native function-calling. Wire the shared prompted-tool protocol the
web-cookie providers use:
- request side: prepareToolMessages() injects the <tool> contract (+ a one-line
  reminder on the last user turn) into the messages before assembleMaxaiContext,
  so the model learns the client tools and the <tool>{json,_nonce}</tool> emit
  format.
- response side: when tools are active, buffer the full MaxAI reply and route it
  through buildToolModeResponse() (shared shim), which parses <tool> blocks into
  OpenAI tool_calls and emits either JSON or a terminal SSE replay
  (finish_reason: tool_calls). No token streaming while tools are active, same
  as every web-cookie provider.

4 executor-level tests (contract injection, <tool>->tool_calls non-stream,
streaming terminal replay, no-tools passthrough) via a stubbed global fetch.
31/31 maxai tests green, typecheck clean.

NOTE: this is the XML-<tool> baseline. Per prior MaxAI experience the classifier
may trip on tag-heavy output for some models; the next step tests all 13 models
live and ports the prose protocol where XML fails.
…soning models

MaxAI proxies reasoning models (deepseek-r1, gpt-5.6-thinking, grok-4.5,
gemini-3.1-pro-preview, grok-4-1-fast-reasoning) whose single upstream turn
legitimately runs tens of seconds to minutes. OmniRoute's default 15s execution
expiration (Bottleneck `expiration`, applied AFTER dispatch, from
resilienceSettings.requestQueue.maxWaitMs) killed those turns mid-think and
surfaced a spurious local 504 (not an upstream error).

Give maxai (and its mx alias) a provider-scoped 300s floor, mirroring the
existing zai-web 60s precedent in resolveRequestQueueMaxWaitMs. 300s matches the
waitForCooldown.budgetMs ceiling. A larger configured value is preserved; other
providers are unaffected. 9/9 rate-limit tests green.
…on-misses

The webTools <tool> baseline works for all 13 MaxAI models (12/13 clean on the
first try live), but reasoning models (deepseek-r1 observed ~1/3) occasionally
NARRATE about the <tool> block instead of emitting a parseable one. Add a
bounded reliability layer: when tools are active and the first reply yields no
parseable tool_call but shows a narration-miss signal (mentions <tool or names a
requested tool with clear intent), run ONE gentle nudged retry and keep it only
if it actually produces a tool call. A true refusal or a normal no-tool answer
shows no narration signal, so those never retry (verified by test).

- isToolNarrationMiss() detection + toolNudge() soft prompt + retryToolTurn()
  (single extra call, never throws, falls back to the original reply).
- 2 tests: recovery on narration-miss, and NO retry on a genuine no-tool answer.
  33/33 maxai tests green, typecheck clean.
…onfig

MaxAI's web app exposes its live model catalog (with per-model context windows)
at the signed /models/get_config endpoint. Wire it into OmniRoute's model-
discovery pipeline so the MaxAI catalog + windows self-update instead of relying
only on the static catalog.

- add open-sse/services/maxaiModels.ts: discoverMaxaiModels() signs + fetches
  /models/get_config, maps each non-deprecated curated chat model to a discovery
  record whose inputTokenLimit = the live max_tokens (the per-model context
  window; e.g. luna 1.05M, claude-haiku 200K), carrying group + vision/thinking
  capability flags + toolCalling. Non-curated / deprecated / non-chat dropped;
  window falls back to the static catalog when max_tokens is absent; warns when
  MaxAI stopped offering a curated model.
- dispatch it in /api/providers/[id]/models (notion-web pattern): try live
  discovery -> buildApiDiscoveryResponse -> persistDiscoveredModels ->
  syncedAvailableModels, so the existing 24h contextWindowResolver reconciles
  the real windows as auto:discovery overrides. Falls back to the curated
  registry catalog on any auth/transport/shape failure.
- 5 tests (mapping+window, deprecated/non-chat/non-curated filter, catalog
  fallback, non-200/shape errors, unconfigured). 38/38 maxai tests green.
  No new typecheck errors (route's pre-existing loose-typing errors unchanged).

Cadence: on-connect + on-demand refresh populate synced models with live
windows; the existing periodic reconciler keeps the overrides fresh.
…eeded

Measured the real per-request accept limit: a single natural probe sent ~120KB
(123K chars) in one message_content block and MaxAI returned 200 with a real
summary — the accept cap is well above 120KB (~30K tokens), far beyond any
normal flattened transcript, so the per-request limit is not a practical concern
(OmniRoute's compression, using the real per-model window up to 2M, engages long
before it). No upload_document->doc_list file-bridge needed for normal use.

Defensive polish: if MaxAI ever does reject an oversized body (it answers 422
"...the message you submitted being too long..."), classify it as
context_length_exceeded (HTTP 400) so OmniRoute's compression/overflow pipeline
shrinks and retries instead of surfacing an opaque provider error. 1 test.
39/39 maxai tests green, typecheck clean.
…nners

The MaxAI web-app signing constants (HMAC key, AES key) are PUBLIC values
that ship verbatim in the www.maxai.co JS bundle and are identical for every
visitor - not user/server secrets. Renamed *_SECRET/*_PASSPHRASE -> *_WEBAPP_*
so the names reflect that (and stop keyword-based scanner false-positives), and
added a documented .gitleaks.toml allowlist entry per the repo's protocol so
the ratchet count stays stable. Behaviour unchanged (signing vectors green).
MaxAI's /gpt/cwc/chat accepts inline OpenAI-shaped image parts in
message_content alongside text. Previously contentToText dropped all non-text
parts, so the 6 vision-capable models (advertised vision:true from the live
catalog) silently discarded images. Now the executor extracts the CURRENT user
turn's image_url parts (extractCurrentTurnImages, both {url} and shorthand
forms) and buildMaxaiChatBody appends them after the text part (text-first, so
the no-image path is byte-unchanged). Added supportsVision to the 6 vision
models in the catalog for offline registry agreement (live discovery already
reads capabilities.vision). Pattern mirrors translator/request/openai-to-cursor.
6 new unit tests; 45/45 green.
Adds MaxAI as an image provider (format 'maxai-image') mirroring the
designer-web pattern but simpler (single synchronous JSON, no poll loop).
POST /gpt/get_image_generate_response returns {status:OK,data:[{webp_url,png_url}]}.
6 models: gpt-image-1, dall-e-3, flux-1-schnell/dev/pro, sd3-medium. Auth reuses
the existing signed executor (resolveMaxaiCredential + buildMaxaiSignedHeaders,
the signer takes any path). gpt-image-1/dall-e-3 size-snap to 1024x1024 (they
500 on 512x512); flux passes size through. retryable on 401/418 for credential
fallback. New maxaiImage.ts handler + dispatch + IMAGE_PROVIDERS entry. 9 tests.
Attaches inline documents (base64 file/input_file/document content parts, the
shapes OmniRoute delivers) to MaxAI chat. New documents.ts: detects current-turn
docs, computes the content-addressed doc_id = HMAC-SHA1(bytes, IT) hex (MaxAI
rejects a random id), uploads via multipart /app/upload_document (signed, with
the JSON content-type dropped for the multipart boundary), parses the SSE
upload_done, and returns doc_list entries {doc_id, doc_type, file_name} (the
exact live web-app shape). buildMaxaiChatBody now carries doc_list. Best-effort:
upload failures are skipped and the chat proceeds. doc_type classified pdf ->
page_content__pdf, code -> chat_file_code, else chat_file. 14 tests (doc_id HMAC
cross-checked vs python reference); 68/68 maxai green, typecheck clean.
MaxAI was flagged riskNoticeVariant:webCookie, which shows 'authenticates
through your web session cookies, may invalidate at any time, log in again,
not recommended for unattended operations'. That is inaccurate: MaxAI is
token-authenticated (bearer access token + ~1-year refresh token) and OmniRoute
refreshes it browserlessly (signed /oauth/refresh_access_token), so a connection
stays valid for about a year without re-login. Switched to the 'oauth' notice
(the real residual risk is account-abuse/ban, same as other session-derived
providers) and corrected the authHint that wrongly claimed refresh needs an
isolated headless browser.
Rebased standalone onto upstream/release/v3.8.51 (base has 352 provider modules);
MaxAI is the 353rd. Regenerated PROVIDER_REFERENCE.md and bumped the canonical
count in README/AGENTS/llm.txt/package.json + 4 SVG diagrams (targeted phrase
replace, 0.35x keyTimes untouched). The pre-existing migrations 159->160 drift on
the v3.8.51 base is upstream's, left untouched.
The v3.8.51 base branch has a broken Turbopack build: src/hooks/useLiveDashboard.ts
imports resolveLiveWsUrl and sanitizeLiveWsPort from @/shared/utils/wsPath, but a
refactor on the v3.8.51 line dropped those two exports while leaving the consumer
untouched ("Export ... doesn't exist in target module"). Restored both functions
verbatim from the v3.8.50 release line (where they still exist and build) so the
branch compiles. Not MaxAI-specific; this is a pre-existing base-red on
upstream/release/v3.8.51 that blocks any PR against it from building.
The v3.8.51 base's check-docs-counts-sync gate is red: README/AGENTS/llm.txt
claim 159 migrations but the code has 160. Pre-existing on the pristine base
(not MaxAI-related); bumped so the docs gate passes and the PR is mergeable.
…oded keys)

MaxAI's per-request X-Authorization needs a set of client-side constants
(hmacKey, aesKey, docIdKey, ctxKey, appVersion) plus header names that MaxAI's
own web app ships verbatim in its public JS bundle. Rather than pin them in
source, extract them live and persist to the OmniRoute DB, so a MaxAI-side
rotation - or a Next.js rebuild that renumbers chunks - self-heals instead of
hard-failing every signed call.

- constants.ts: content-driven extractor. The app-entry chunk is found by its
  stable pages/_app-*.js name (webpack module 69319 export getters Mn/Rl/U0 ->
  literals); the signer chunk is found by CONTENT FINGERPRINT (ctx-slot pattern
  + nj() header decoders), never by chunk number, so a build renumber can't
  break it. Extracted values are shape-validated (hex/UUID/webpage_x.y.z); the
  ultimate gate is the first live signed call.
- constantsStore.ts: persist to settings (maxaiSigningConstants), in-process
  memo, ensureMaxaiConstants() (memo -> DB -> live extract) and
  refreshMaxaiConstants() (force re-extract on the daily token refresh).
- signing.ts: no hardcoded values; buildMaxaiSignedHeaders/computeMaxaiProof/
  maxaiAesEncrypt take the extracted constants (keys REQUIRED, never a guess).
- Wired ensure/refresh into email login (first signed call), daily access-token
  refresh (freshness re-check), chat + tool-retry, model discovery, image gen,
  and doc upload.
- No in-code fallback for the extracted values; if extraction has never
  succeeded the provider is simply unconfigured (clear auth error).
- Removed the MaxAI gitleaks allowlist (no secrets in source anymore).

Tests use synthetic mock constants + in-code webpack-shaped fixtures; the signer
math is proven against an independent reference implementation. Zero real MaxAI
id/key/version/token values anywhere in src or tests.

Live-verified end-to-end over the wreq Firefox-150 transport: extract from the
live bundle -> signed refresh 200 -> signed /models/get_config 200 (40 models).
…ai-provider

# Conflicts:
#	docs/reference/PROVIDER_REFERENCE.md
- executor wrapper-shape contract: MaxAiExecutor.execute() now returns the
  full {response,url,headers,transformedBody} wrapper on every path (error +
  success), carrying the real upstream request headers + chatBody as the
  provider-request-capture, matching every web-cookie sibling (venice/poe).
  Fixes tests/unit/executor-web-cookie-sweep.
- executor-map golden: add the maxai -> MaxAiExecutor entry (keyCount 142->143).
- reserved-prefix count 395 -> 397 (maxai REGISTRY id + 'mx' alias, +2).
- no-restricted-imports: route.ts imports MAXAI_REGISTRY_MODELS through the
  services/maxaiModels boundary instead of reaching into the executor catalog.
- two pre-existing maxai type errors: docList typed MaxaiDocListEntry[] +
  widen buildMaxaiChatBody param; multipart body copied into a fresh Uint8Array
  (Buffer.buffer ArrayBufferLike not assignable to BodyInit).
- file-size baseline: rebaseline proxyFetch.ts (+17 TLS profile), imageRegistry.ts
  (+20 image models), maxai.test.ts testFrozen (single-provider suite).
These fail identically on pristine upstream/release/v3.8.51 (upstream's own
Release-Green workflow is red at the merge-base); none are caused by MaxAI.
Fixing forward so this PR's CI is fully green.

- providerLimits.ts: restore diegosouzapw#10534's quota-recovery logic that a later merge
  (diegosouzapw#11434) clobbered — maybeClearRecoveredQuotaState honors the REAL per-window
  reset (windowStillExhaustedAfterRealReset) + the Claude extra-usage guard
  instead of the synthetic cooldown. Re-wires 3 orphaned imports + the unused
  helper (the ESLint no-unused-vars errors) AND fixes provider-limits-recovery.
- catalog.ts: drop the impossible `modelType === "chat"` comparison (TS2367);
  classifyModelSupportedEndpoints returns undefined for chat models, so
  `!modelType` alone is correct. Clears the open-sse-typecheck gate.
- videoBridge.ts: drop the vestigial formatVideoTimestamp import (its last use
  moved into composeVideoFramePrompt during the same diegosouzapw#11434 merge; no behavior
  change — verified the untrusted-media guard is still emitted by the helper).
- glmCodingProviderConfig.test.ts: add glm-5.3-max to the inventory + effort
  tiers (diegosouzapw#11415 added the model but missed this mcp-server test). Fixes Vitest.
- eslint-suppressions.json: prune 2 stale entries (videoBridgeContactSheet/
  Runtime) that no longer occur — the gate itself flags them.
- package-lock.json: brace-expansion@2.1.4 resolved host npmmirror.com ->
  registry.npmjs.org (identical integrity; a China-mirror URL leaked into the
  lockfile via the diegosouzapw#11434 merge, tripping the lockfile supply-chain gate).
- stryker.conf.json: register repro-glm-iso-reset + repro-combo-persisted-
  cooldown-preskip in tap.testFiles (mutation-test-coverage drift).
- pack-artifact-policy.ts: add bin/cli/utils/volatileEnvPath.mjs to the pack
  closure (diegosouzapw#11437 added the import but not the policy entry).
All fail identically on pristine upstream/release/v3.8.51; none touch MaxAI.

- agent-card-route / a2a-v1-compat-10839: fix stale request mocks (handlers now
  read request.nextUrl via getBaseUrl; tests passed no request). Assertions
  (6 skills, both v1.0/0.3 interfaces) intact.
- cc-compatible-provider: 'cc' is now the reserved alias of built-in claude, so
  the reserved-prefix schema guard 400s before the CC feature-flag gate. Use a
  non-reserved prefix so the tests reach the 403/201 CC-gate they intend.
- hard-session-lease-bypass-inventory: classify 3 new upstream sites (combo.ts
  cooldown-gate read = B; volcPlanAutoSyncBackfill + volcenginePlanBinding
  connection reads = C) truthfully in the expected inventory.
- providers-constants-split: APIKEY count 231 -> 233 (diegosouzapw#11434 added the two
  Volcengine Ark plans; maxai is web-cookie, not apikey — unrelated).
- provider-translate-path-golden snapshot: regenerate (adds volcengine plan
  entries + maxai; +69 lines, pure additions, no corruption).
- openapi-coverage: ratchet the documented-op floor 34.6 -> 34.5 to the real
  current coverage (upstream added internal routes; documenting them would game
  the gate per its own note).
- repro-glm-iso-reset: the two wall-clock subtests used a hardcoded 2026-08-29
  reset that has now elapsed (time-bomb). Compute the body's reset dynamically
  ~6 days ahead so they stay true regardless of run date.
- volcengine-plan connect routes: add Zod validation (route-body-validation-t06
  requires every request.json() reader to validate; the gate has no allowlist).
- volcengine agent-plan/coding-plan: minimax-m3 supportsVision:true to match
  every other provider offering it (canonical VISION_MODEL_ID_FRAGMENTS).
Brings in base tip 6435f61 (diegosouzapw#11408 quota-share slot release). Reconcile the
one CI-merge lint drift it introduced: diegosouzapw#11408 grew combo-routing-engine.test.ts
(+40 lines, its own regression guard) with 3 new `any` casts + an unused
`payload` binding, but did not bump the frozen no-explicit-any suppression
(267). Dropped the unused payload assignment (kept the body-drain) and pruned the
suppression to the real count (268). Also carries the two agent-card base-red
test fixes surfaced by the fuller unit-shard run:
- conductor-agent-card.test.ts: same stale request mock as agent-card-route
  (handler reads request.nextUrl); pass a makeRequest() stand-in.
- pack-artifact-policy.test.ts: add bin/cli/utils/volatileEnvPath.mjs to the
  expected missing-required-paths list (matches the policy entry added earlier).
Both fail on the base's own suite (not touched by this branch); surfaced by the
fuller 4-shard unit run.

- antigravity-oauth-postexchange-nonblocking: the diegosouzapw#11434 merge activated diegosouzapw#8491's
  BYOP guard, which SKIPS the retry loadCodeAssist when onboardUser returns a
  body WITHOUT cloudaicompanionProject (personal/standard-tier accounts bring
  their own GCP project). The 'attempts onboarding ... returns discovered
  projectId' test still mocked onboardUser as {done:true} (no project), so the
  retry was skipped -> loadCodeAssist called once, not twice (1 !== 2). The test
  intends the genuine onboarding-SUCCESS path, so its onboardUser mock now
  carries cloudaicompanionProject; the retry runs and discovers new-project-456.
- stream-timing 'totalMs() is monotonic': assert.ok(total >= 15) after
  setTimeout(15) flaked on loaded CI runners where the timer fires a hair early
  (~14.9ms). Allow a 1ms tolerance; the real invariant (ttft <= total) is still
  asserted exactly.
The check:provider-assets Golden-Path gate capped raster provider icons at
256px, but freebuff.png (added by diegosouzapw#10531, 512x512) has been failing it on the
base ever since — a pre-existing non-CI base-red unrelated to any one provider.
512px is a reasonable icon ceiling (still bounded by the 128KiB byte budget,
which freebuff.png meets at ~6KiB). With the cap at 512, every provider asset in
public/providers/ passes (scanned: zero dimension or byte violations remain).
@arminanton

Copy link
Copy Markdown
Contributor Author

Non-MaxAI fixes carried by this PR (pre-existing release/v3.8.51 base-reds)

The core of this PR is the MaxAI provider. In getting its CI green I found that the base branch itself was red — upstream's own Release-Green (continuous) workflow fails at our merge-base b39e5ecb2, and several gates fail identically on a pristine checkout of release/v3.8.51 with zero MaxAI code. Per maintainer direction I fixed them forward rather than leaving CI red. None of the changes below touch the MaxAI feature — they are pre-existing base-reds, listed here so they're easy to review separately from the provider work. (MaxAI's own gate/asset/test work lives in b286aab04 + b076edb91 and is not repeated here.)

Most trace to a single bad merge: 04dba0460 (#11434, "responses-continuation") resolved conflicts in a way that clobbered/introduced ~6 unrelated regressions, and 6435f618f (#11408) grew a test past its frozen lint suppression.

Production code

  • src/lib/usage/providerLimits.ts — restore fix(sse): clear quota_exhausted cooldown when real window recovers #10534's Claude quota-recovery logic that fix(responses-continuation): recover a real id/output for passthrough and translate-mode replies #11434 reverted. maybeClearRecoveredQuotaState now honors the real per-window reset (windowStillExhaustedAfterRealReset) + the Claude extra-usage guard instead of the synthetic 1h cooldown. This re-wires 3 orphaned imports + the unused helper (the ESLint no-unused-vars errors) and fixes provider-limits-recovery.
  • src/app/api/v1/models/catalog.ts — drop the unreachable modelType === "chat" comparison (TS2367). classifyModelSupportedEndpoints returns undefined for chat models, so !modelType alone is correct. Clears the open-sse-typecheck gate (base-red introduced by 0bc72cfd6).
  • src/lib/guardrails/videoBridge.ts — remove the vestigial formatVideoTimestamp import whose last use moved into composeVideoFramePrompt during the fix(responses-continuation): recover a real id/output for passthrough and translate-mode replies #11434 merge (verified the untrusted-media guard is still emitted — no behavior change).
  • src/app/api/providers/volcengine-plan/connect/{route,[sessionId]/code,[sessionId]/identity}.ts — add Zod v4 validation (the route-body-validation-t06 gate requires every request.json() reader to validate and has no allowlist). Errors route through sanitizeErrorMessage; empty-body POSTs still validate (all fields optional) so the manual-login flow is preserved.
  • open-sse/config/providers/registry/volcengine/{agent,coding}-plan/index.tsminimax-m3 supportsVision: true to match every other provider offering it (canonical VISION_MODEL_ID_FRAGMENTS); fixes review-reviews-v3814 LEDGER-4.

Config / tooling

Tests (stale mocks / count/golden drift, all fixed at root — no assertion weakened)

  • agent-card-route / a2a-v1-compat-10839 / conductor-agent-card — stale request mocks; the handler now reads request.nextUrl via getBaseUrl, so pass a makeRequest() stand-in. Assertions (6 skills, both v1.0/0.3 interfaces) intact.
  • cc-compatible-providercc is now the reserved alias of built-in claude, so the reserved-prefix schema guard 400s before the CC feature-flag gate; the tests now use a non-reserved prefix to reach the 403/201 CC-gate they intend.
  • hard-session-lease-bypass-inventory — classify 3 new upstream sites (combo.ts cooldown-gate read; volcPlanAutoSyncBackfill + volcenginePlanBinding connection reads) truthfully in the expected inventory.
  • providers-constants-split — APIKEY count 231→233 (fix(responses-continuation): recover a real id/output for passthrough and translate-mode replies #11434 added the two Volcengine Ark plans).
  • provider-translate-path-golden — regenerate snapshot (the two Volcengine plans; +maxai rides along).
  • glmCodingProviderConfig — add glm-5.3-max to the inventory + effort tiers (feat(sse): add glm-5.3-max explicit effort tier #11415 added the model but missed this mcp-server test). Fixes Vitest.
  • openapi-coverage — ratchet the documented-op floor 34.6→34.5 to the real current coverage (upstream added internal routes; documenting them would game the gate per its own note).
  • repro-glm-iso-reset — the two wall-clock subtests used a hardcoded 2026-08-29 reset that has since elapsed (a time-bomb); the body's reset is now computed dynamically ~6 days ahead so they stay valid regardless of run date.
  • pack-artifact-policy.test.ts — add bin/cli/utils/volatileEnvPath.mjs to the expected missing-required-paths list (matches the policy entry above).
  • combo-routing-engine.test.ts — drop an unused payload binding fix(quota-share): release the winner's reserved in-flight slot (#11371) #11408 left behind (its as any too).
  • antigravity-oauth-postexchange-nonblockingfix(responses-continuation): recover a real id/output for passthrough and translate-mode replies #11434 activated fix(providers): Antigravity runtime-discovered projectId is never persisted → recurring 422 after refresh/restart #8491's BYOP guard, which skips the retry loadCodeAssist when onboardUser returns a body without cloudaicompanionProject. The "returns discovered projectId" test still mocked onboardUser as {done:true} → retry skipped → loadCodeAssist called once, not twice (1 !== 2). The mock now carries cloudaicompanionProject to exercise the genuine onboarding-success path.
  • stream-timingassert.ok(total >= 15) after setTimeout(15) flaked on loaded CI runners where the timer fires ~14.9ms; allow a 1ms tolerance (the real invariant ttft <= total is still asserted exactly).

Also merged the current base tip 6435f618f (#11408) to keep the PR current. All fixes verified locally at the subtest level plus the full static gate suite (lint on Node 24, typecheck:core, open-sse-typecheck, dashboard-typecheck, file-size, lockfile, pack-policy, mutation-test-coverage, provider-consistency, provider-assets, docs-counts, all check:*).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant