mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-13 18:52:18 +03:00
cffaeebb2700934ed65322a32f965ba9877cfc9f
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bd472200d5 |
[v3.8.50] Fix Z.ai web browser transport and model capabilities (#8451)
* fix: complete Z.ai web browser transport * refactor: address Z.ai review feedback * test(zai-web): reconcile the #8014 endpoint guard with the chats/new + signed flow Rebasing onto release/v3.8.49 pulled in #8503, which repointed CHAT_URL to /api/v2/chat/completions and added an endpoint probe. This branch already targets v2, so the executor conflict resolved to this branch's superset (NEW_CHAT_URL + signature constants alongside the same v2 CHAT_URL). The two tests needed adapting, because #8503's assertions assume the pre-rework flow: - executor-zai-web.test.ts: the completion URL now carries the request signature as a query string, so an exact-equality check on the endpoint can never match. Assert the v2 prefix instead. - zai-web-chat-endpoint-8014-probe.test.ts: the probe drove the executor with a bare cookie credential and no captcha proof, which now routes through the browser transport — fetch was never called and the probe captured nothing. Supplied a direct-path credential, and matched on pathname across all requests (the executor also probes the homepage for the frontend version and calls /api/v1/chats/new first). The guard's intent is unchanged and slightly strengthened: it now asserts no request reaches the stale unversioned path and that exactly one completions request is issued, against v2. 54/54 across the zai suites; typecheck:core and eslint clean. * fix(zai-web): surface upstream error frames instead of finishing empty Reported on this PR: HTTP 200, `out=0`, stream "complete", no content and no diagnosis. Cause. HTTP-level failures are already handled — fetchUpstream turns any !ok response into a makeErrorResult with the sanitized body. The gap is a 200 whose SSE body carries an error payload: parseZaiFrame returns null for it, drainSseDeltas drops it, and buildZaiStreamingBody then closes with an empty assistant message + stop + [DONE]. The caller reads that as a successful empty completion, so a rejected signature, an expired captcha and a stale token all look identical — which is why this had to be diagnosed by reading code rather than logs. Hard Rule #6. Fix. parseZaiFrame now classifies an affirmatively error-shaped frame (`error` at the top level or under `data`, string or {detail|message|msg}) as a terminal delta, checked before the delta paths so it cannot fall through to the "no usable delta" null. The stream emits it as `[Z.ai error] <message>`, matching the mid-stream convention the other web executors already use (zed-hosted's createErrorChunk) — the 200 is on the wire, so the status cannot change, but the caller must not be left reading a blank success. Content streamed before the failure is preserved. Message goes through sanitizeErrorMessage (Rule #12). Deliberately NOT changed: a contentless frame still parses to null. That is live-validated behaviour, not an oversight — z.ai emits phase frames with no delta_content, and executor-zai-web.test.ts pins it ("returns null for frames with no usable delta"). Treating "nothing parseable arrived" as a failure would invent policy on top of an observed protocol and risk false errors on the happy path, so this only adds recognition of explicit error frames. Tests (TDD, RED then GREEN): zai-web-silent-empty-repro.test.ts — 7 cases. Error frame classified and terminal; surfaced through the stream with the upstream's own text; surfaced after partial content without losing it; plus a REGRESSION GUARD that contentless/phase-only frames are still skipped, and two controls that the happy path and reasoning-only output are untouched. The guard and controls passed before the fix; the four error cases did not. 94/94 across the zai + stream suites; typecheck:core, eslint and check:file-size clean. * refactor(sse): extract the zai-web transports so the complexity ratchet holds The v3.8.49 merge-train rebaseline (#8686) set the ceiling to the tip's own measurement, leaving zero headroom, so this branch's +5 cyclomatic / +3 cognitive own-growth had nowhere to sit once rebased onto it. Eight violations, all in code this branch introduces, resolved by extraction — no behaviour change: - `execute` (152 lines, complexity 25, cognitive 20) now delegates to `resolveZaiRequest()` for the four client-error rejections and to a `fetchViaSignedApi()` method for the CAPTCHA/signature path, so it reads as "validate, pick a transport, shape the response". - `fetchThroughBrowser` (126 lines, cognitive 16) hands its image decoding to `resolveZaiBrowserAttachments()`, its Playwright options to `buildZaiBrowserChatOptions()`, and its call-log payload to `buildZaiBrowserAuditBody()`. - `configureZaiBrowserEffort` (cognitive 35 — the worst of the set) repeated a wrap-and-relabel try/catch four times inside an if/else. `runStage`, which already existed one function below, is now module-scoped and reused, and the toggle collapses to `checked !== config.enabled` (same four cases). - `validateWebCookieProvider` (complexity 19) moves its can-we-probe-this cascade into `resolveWebCookieProbe()`, which returns either a rejection or the URL + headers to use. - `acquireBrowserContext`'s creation closure (complexity 17) hands cookie and localStorage seeding to `seedContextSession()`. That last extraction also clears a violation that predates this branch — `acquireBrowserContext` was already over the 80-line ceiling — so cyclomatic lands at 2187 against a baseline of 2188. Verified: check:complexity-ratchets green both metrics; typecheck:core clean; ESLint clean on all four files; 85 tests across the zai-web, web-cookie validation, browser-pool and model-test-runner suites pass. * fix(zai-web): surface upstream errors on the non-streaming path collectZaiNonStreaming ignored delta.error — a 200 whose SSE body carries an error frame (rejected signature, expired captcha, stale token) came back as a successful empty completion. Now it throws on an error frame, matching the streaming path's [Z.ai error] convention; the caller's existing try/catch returns makeErrorResult(502) instead of an empty 200. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: backryun <busan011@ormbiz.co.kr> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> |
||
|
|
16c566d146 | fix(copilot-web): restore browser authentication (#9984) | ||
|
|
a25d5f1ef6 |
Release v3.8.13 (#3327)
* chore(release): open v3.8.13 development cycle Bump 3.8.12 → 3.8.13 across package.json, lockfile, electron/, open-sse/, and docs/reference/openapi.yaml; add the [3.8.13] cycle placeholder to the root CHANGELOG and the 41 i18n mirrors. Integration branch for the v3.8.13 cycle — fixes/features land here via per-issue PRs and it merges to main at release time. * fix(ci): skip auto-deploy when VPS host is unreachable from the runner (#3299) Integrated into release/v3.8.13 * fix(dev): auto-rebuild better-sqlite3 on Node ABI mismatch at dev startup (#3301) Integrated into release/v3.8.13 * feat(api): accept path-scoped API keys on client API routes (#3300) Integrated into release/v3.8.13 * fix(sse): harden against empty responses causing Copilot Chat failures (#3297) Integrated into release/v3.8.13 * fix(api): remove Completions.me rickroll provider (discussion #3293) (#3302) Integrated into release/v3.8.13 * fix(opencode-provider): extract contextLength from live model catalog (#3298) Integrated into release/v3.8.13 * feat(web-cookie): self-service login infrastructure + auto-refresh daemon (#3292) Integrated into release/v3.8.13 * docs(changelog): record the v3.8.13 PRs merged this round (#3292/#3300/#3297/#3298/#3301/#3302/#3299) * fix(auth): harden URL token extraction — drop query-string fallback, gate to client routes (security follow-up to #3300) (#3309) Security follow-up to #3300 — integrated into release/v3.8.13 * docs: rename resolve-issues → review-issues skill references * fix(dashboard): keep no-auth providers visible under 'Show configured only' (#3290) (#3312) no-auth providers (opencode, duckduckgo-web, theoldllm, veoaifree-web) never create a DB connection row so stats.total stays 0, which the configured-only filter treated as 'unconfigured' and hid them — even though they are always usable and appear unconditionally in /v1/models. filterConfiguredProviderEntries now treats displayAuthType === 'no-auth' as configured. Co-authored-by: uniQta <uniQta@users.noreply.github.com> * fix(cli): resolve update paths relative to script + recursive backup (#3295) (#3313) omniroute update always failed on a global install: - getCurrentVersion() read package.json from process.cwd(), which on a global npm/brew install is the user's working dir, not the package root → null → 'Could not determine current version'. - createBackup() resolved bin/ from cwd too, and passed the 'cli' directory to copyFileSync → EISDIR, swallowed by the catch → 'Failed to create backup'. Both now resolve package.json/bin relative to the script via import.meta.url, and the backup uses cpSync({recursive:true}) so the cli/ directory is copied. Co-authored-by: uniQta <uniQta@users.noreply.github.com> * fix(theoldllm): read upstream body once to avoid [502] body-already-read (#3296) (#3314) On the cached-token path the executor never enters the refresh branch, so the same upstream Response was read with .text() twice (token-rejection check + final body). A Response body is single-use, so the second read threw 'Body is unusable: Body has already been read', caught and surfaced as [502]. Read the body once into finalBody and only re-read after a token-rejection refetch. Co-authored-by: onizukashonan14-png <onizukashonan14-png@users.noreply.github.com> * fix(sse): strip leaked internal tool envelopes from streaming output (#3311) Integrated into release/v3.8.13 * fix(sse): expose Claude + Gemini budget tiers in the antigravity catalog (#3184) (#3303) Integrated into release/v3.8.13 (#3184) * fix(catalog): compute combo context_length from known targets only (#3304) Integrated into release/v3.8.13 — live contextLength + known-targets combo context (#3298 follow-up) * chore(i18n): add message keys for proxy UI + vscode/ollama endpoint (#3307) Integrated into release/v3.8.13 — i18n message keys for proxy UI + vscode/ollama * feat(dashboard): i18n the proxy settings UI (#3310) Integrated into release/v3.8.13 — i18n the proxy settings UI * feat(api): model catalog enrichment + MCP model-catalog tools (#3306) Integrated into release/v3.8.13 — model catalog enrichment + MCP model-catalog tools, reconciled with #3309 URL-token hardening * test(catalog): align Antigravity preview-alias test with #3303 budget tiers #3303 added the Gemini `-high`/`-low` budget tiers to ANTIGRAVITY_PUBLIC_MODELS (user-callable on the Antigravity OAuth backend, verified via #3184), but did not update the catalog-route test that asserted `antigravity/gemini-3.1-pro-high` must NOT be exposed. The assertion now reflects the intended behavior — the client-visible budget alias IS surfaced — while keeping the legacy `gemini-claude-*` alias keys unexposed. Caught running the full catalog suite on the merged release HEAD (the #3303 round only ran the antigravity-aliases and usage-hardening files). * docs(changelog): record the 6 PRs merged this review round into v3.8.13 #3306/#3307/#3310 (New Features — VS Code split: catalog+MCP, i18n keys, proxy UI i18n), #3311/#3303/#3304 (Bug Fixes — SSE envelope sanitizer, antigravity budget tiers, combo known-targets context_length). * chore(release): finalize v3.8.13 changelog and cleanup Finalize the v3.8.13 changelog with release date, maintenance notes, and contributor credits. Update MCP docs to reference the correct tool inventory diagram, exclude nested .claude worktrees from ESLint scans, and tighten a response sanitizer type guard. * fix(dashboard): refresh connections after provider auth import (#3320) Integrated into release/v3.8.13 — refresh connections after provider auth import * fix(codex): strip client-only params on native /responses passthrough (#3317) (#3325) A /v1/responses request against the built-in codex/ provider does an openai-responses -> openai-responses passthrough (CodexExecutor.transformRequest returns the body early for _nativeCodexPassthrough). It forwarded client-only fields verbatim and the Codex upstream rejected them with 400 Unsupported parameter: prompt_cache_retention / safety_identifier / user — breaking Factory Droid (which injects all three). The chat-completions path already strips these (base.ts #1884, openai-responses translator #2770) but the passthrough skips translation. Strip the three fields in the shared block before the passthrough return; user is removed unconditionally since Codex /responses always rejects it. Co-authored-by: tycronk20 <tycronk20@users.noreply.github.com> * fix(dashboard): normalize agent-bridge /state response to stop page crash (#3318) (#3326) The Agent Bridge page seeded a well-shaped initialData default then replaced it wholesale with the raw /api/tools/agent-bridge/state response. The route returns { server, agents } but the UI reads { serverState, agentStates, bypassPatterns, mappings }, so serverState became undefined and AgentBridgeServerCard crashed on serverState.running — surfaced as the full-page 'Internal Server Error' boundary (client render error, not a real 5xx). Add a shared normalizeAgentBridgeState() that maps the route shape into the page contract (server.running/certExists -> serverState) and always returns safe defaults (never undefined serverState). Wired into both the SSR loader (page.tsx) and the polling hook. The legacy 'agents' entry shape differs from AgentStateEntry so it is not coerced; full route<->page contract reconciliation (port, upstreamCa, bypassPatterns, mappings, agentStates) is a follow-up. Co-authored-by: tycronk20 <tycronk20@users.noreply.github.com> * docs: VS Code/Ollama endpoints + env & i18n tooling (#3319) Integrated into release/v3.8.13 — VS Code/Ollama docs + env & i18n tooling * feat(provider): test-all endpoint, rate-limit overrides, visibility f… (#3267) Integrated into release/v3.8.13 — provider test-all endpoint, rate-limit overrides, model visibility * feat: auto-combo optimization, playground model dropdown, only-configured toggle (#3322) Integrated into release/v3.8.13 — auto-combo candidate expansion + playground dropdown + only-configured toggle * feat(api): VS Code Copilot Ollama-compatible BYOK endpoint (#3316) Integrated into release/v3.8.13 — VS Code Copilot Ollama-compatible BYOK endpoint (reconciled with #3306/#3309 auth hardening) * chore(release): document #3320 in the v3.8.13 changelog + contributor credits --------- Co-authored-by: Felipe Almeman <4226997+zhiru@users.noreply.github.com> Co-authored-by: Wilson <pedbookmed@gmail.com> Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com> Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com> Co-authored-by: uniQta <uniQta@users.noreply.github.com> Co-authored-by: onizukashonan14-png <onizukashonan14-png@users.noreply.github.com> Co-authored-by: tycronk20 <tycronk20@users.noreply.github.com> Co-authored-by: Vinayrnani <vinayrnani@gmail.com> |