* feat(skills): add Ponytail minimalism skill as external catalog entry
- Add 'external' SkillCategory + SkillArea
- Register ponytail (MIT, DietrichGebert/ponytail) in CURATED_SKILLS
- Generator: external skills carry content in custom block, no api/cli body
- Generate skills/ponytail/SKILL.md with original content preserved
- Update catalog test counts 45 -> 46
* fix(skills+memory): builtin handler fallback in executor, skip vector upsert for deleted memories
- skills: Next.js compiles SkillExecutor into multiple chunks (own singleton
each); route chunk lacked builtin handlers registered at startup via
instrumentation. execute() now falls back to builtinSkills registry, so
POST /api/skills/executions works for file_read/web_fetch/etc.
- memory: scheduleVectorUpsert is fire-and-forget and embeddings are slow;
health-check verify (create->delete test memory) left queued upserts
failing with 'memory not found' every 30s. Check existence before embedding
and skip quietly.
* fix(skills): encode tool names with @ and . for providers rejecting them
Skill tools were advertised as 'name@version' (e.g. test-fr2@1.0.0), but
DeepSeek/Groq/OpenAI reject function names not matching ^[a-zA-Z0-9_-]+$.
Names already valid are left untouched; invalid ones are reversibly encoded
as omr_skill_<base64url> and decoded in interception before registry lookup.
* fix(combos): include DB id column in combo records for dashboard links
getCombos() selected only data/sort_order/context_cache_protection, so
combos whose JSON blob lacked an id field returned id: undefined. The
dashboard then linked to /dashboard/combos/undefined and Combo Control
Center failed with 'Combo not found'. Merge the id column into parsed
rows (authoritative, only when the blob has no id).
* fix(skills): normalize flat skill schemas to object schema for Gemini/Claude
Stored skill schemas are flat property maps ({ text: { type: string } }),
which OpenAI-compatible providers tolerate but Gemini
(function_declarations[].parameters) rejects with 'Unknown name ... Cannot
find field'. Wrap bare maps into { type: 'object', properties: {...} } for
all three tool formats.
* fix(skills): warm registry cache before skill injection in chat path
injectSkills() lists the in-memory skillRegistry, which is empty after a
cold start until something calls loadFromDatabase(). The interception path
already warms the cache (#2815); the injection path did not, so skills
were silently skipped (no_enabled_skills) for the first requests after
restart. Warm the cache for the chat owner before injection.
---------
Co-authored-by: Egor <egorich-print@users.noreply.github.com>
* Fix custom tool output pairing during compression (#8932)
* Bypass proxy compaction for native Codex context
* fix(sse): extract Codex tool-call output repair to leaf module for file-size gate
repairMissingCodexToolCallOutputs (added by #8932 for custom_tool_call
pairing) pushed codex.ts past the frozen file-size baseline. Extract it
to open-sse/executors/codex/toolCallRepair.ts, leaving only the wiring
call in codex.ts. Rebaseline the test file's genuine +41 line growth
from #8932's new custom_tool_call_output coverage.
Co-authored-by: JxnLexn <JxnLexn@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: JxnLexn <JxnLexn@users.noreply.github.com>
The proxy subscription tab (System -> Proxy -> Subscriptions) displayed
Chinese text regardless of the selected language. The component called
useTranslations("settings") but bypassed t() for all ~50 UI strings.
- Replace every hardcoded Chinese string in SubscriptionTab.tsx with
t("proxySubscription.<key>") calls
- Add 53 new keys under settings.proxySubscription to en.json (English)
and zh-CN.json (Chinese) with full manual translations
- Propagate to all 41 other locales via generate-multilang.mjs (Google
Translate), per docs/guides/I18N.md workflow
All 42 locales at 100% i18n coverage with zero __MISSING__ markers.
* feat(alibaba): add free-tier routing with console quota and builtin allowlist
Classify DashScope free vs paid models via console quota API, a hardcoded
operator allowlist fallback, and per-connection drained tracking. Wire wildcard
combo expansion, model refresh, combo exhaustion, and audit redaction for
Alibaba console credentials.
* fix(routing): reset forced connection pin and persist Alibaba free-tier drain
Drop session affinity pins when a forced connection is excluded after 429,
and record Alibaba free-tier exhaustion on upstream 403 so per-key drained
lists stay accurate without blocking sibling keys.
* fix(alibaba): prefer live quota sync over static free-tier allowlist
Stop unioning the builtin text allowlist when a console quota snapshot exists,
treat expired quotaValidityPeriod as not_capable, and add a dated JSON pack plus
sync-alibaba-allowlist script for operator refresh without code edits.
* docs(alibaba): document free-tier console path + allowlist env overrides
Adds the 4 ALIBABA_FREE_TIER_*_FE_PATH / ALIBABA_FREE_TIER_ALLOWLIST_PATH
env vars (referenced by alibabaFreeTierQuotaFetcher.ts and
alibabaFreeTierAllowlist.ts) to .env.example and
docs/reference/ENVIRONMENT.md so the env/docs contract check passes.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* refactor(open-sse): split alibabaFreeTierQuotaFetcher.ts under file-size cap
Extract pure parsing/classification/eligibility-filtering logic into
alibabaFreeTierQuotaClassify.ts and shared types/primitives into
alibabaFreeTierQuotaTypes.ts, leaving the HTTP/console-fetch flow in the
original file. Public API is unchanged (re-exported), behavior is identical.
Co-authored-by: AndrianBalanescu <AndrianBalanescu@users.noreply.github.com>
* fix: resolve typecheck errors in alibaba-free-tier routing
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: AndrianBalanescu <AndrianBalanescu@users.noreply.github.com>
Co-authored-by: AndrianBalanescu <andrian@balanescu.dev>
* fix(antigravity): per-model quota + 30min credits_exhausted reprobe
- accountFallback.ts: hasPerModelQuota() now treats antigravity/agy as
per-model quota. A single-model 429 no longer cascades to all models
in the provider.
- connectionRecovery.ts: credits_exhausted removed from terminal set;
isCreditsExhaustedReprobeCandidate() with 30min default. Loads
active+inactive rows so inactive credits_exhausted accounts can recover.
- tests/unit/quota-connection-recovery.test.ts: 6 cases covering pure
helpers + tick wiring.
* fix(antigravity): persist projectId and prefer healthy accounts
Save Cloud Code projectId after runtime discovery, skip accounts missing
projectId when alternatives exist, and mark missing_project_id on 422.
* fix(antigravity): skip quota-exhausted models during account selection
Avoid repeatedly dispatching to Antigravity models that already report
exhausted quota, reducing wasted upstream calls and combo fallback latency.
---------
Co-authored-by: hermes <hermes@nous.local>
GithubExecutor.buildUrl() only consulted the static PROVIDER_MODELS registry
via getModelTargetFormat("gh", model), so a custom Copilot model (e.g.
gpt-5.6-terra/gpt-5.6-luna) with its dashboard "Target Format" set to
OpenAI Responses API always still routed to /chat/completions and got
rejected upstream with "model ... is not accessible via the
/chat/completions endpoint" — the setting had no effect on real routing.
chatCore already resolves the correct per-request targetFormat (including
the custom-model override) via resolveChatCoreTargetFormat(), but that value
was never threaded past chatCore into the executor's own URL-building
decision. Mirrors the zai/glm-coding-apikey fix (#7364) for the identical
class of bug: chatCore/executionCredentials.ts now surfaces the resolved
override onto providerSpecificData.targetFormat when it resolves to
openai-responses for the github provider, and GithubExecutor.buildUrl()
prefers that value over the static registry lookup when present.
Verified: 6 new regression tests plus all 95 pre-existing github/executor
tests green.
Co-authored-by: Wital <wital@example.com>
* fix(adobe-firefly): durable session, off-screen Chrome recovery, browser sign-in
Rebuild x-arp-session-id from Cookie pieces (sid/ark/forter) so aux_sid is never
sent as ARP. Sticky ARP + submit spacing reduce mid-batch colligo 408 thrash.
Add optional managed Chrome warm (off-screen headed by default; Forter rejects
headless) and POST /api/providers/{id}/login browser sign-in that returns JWT+Cookie
after a fresh SSO. Visible sign-in resets off-screen window placement and clears
prior Adobe session when adding another account.
* fix(adobe-firefly): cast Node Buffer to ArrayBuffer and harden chrome runtime null close
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix(docs): sync docs-counts gate and env var contract for adobe-firefly
Update executor/OAuth-provider counts in ARCHITECTURE.md and
CODEBASE_DOCUMENTATION.md to match the real code (89 executors, 21
OAuth providers), and document the Adobe Firefly Chrome-driven
session-refresh env vars in .env.example and ENVIRONMENT.md so the
env/docs contract tests pass.
Co-authored-by: artickc <artickc@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: artickc <artickc@users.noreply.github.com>
* feat(adobe-firefly): reference image attach + /v1/images/edits (follow-up #8006)
Upload source images to Firefly storage (POST /v2/storage/image) and attach
them as referenceBlobs on generate-async, matching live firefly.adobe.com
captures (usage:general for nano multi-ref; usage:subject for gpt-image).
Also wire built-in adobe-firefly through OpenAI-compatible POST /v1/images/edits
(multipart or JSON data URLs, up to 4 refs) so Media edit-with-references
and Open WebUI image-edit hit the same path as image2image generate.
Unit suite: tests/unit/adobe-firefly.test.ts 41/41.
* test(api): add route-level coverage for Adobe Firefly /v1/images/edits + fix typecheck/file-size drift
Covers the referenceBlobs upload path, the 4-reference cap error, and the
credentials/rate-limit branches added to the /v1/images/edits route for
adobe-firefly (#8510). Also fixes a Buffer/BodyInit typecheck mismatch in
uploadAdobeFireflyImage and corrects the adobeFireflyClient.ts file-size
baseline entry to match the gate's actual LOC count (it counts the trailing
newline, so the frozen value is 2317, not 2316), plus a testFrozen entry for
adobe-firefly.test.ts's own +159 line growth from this PR. Moves the
handleAdobeFireflyImageGeneration re-export out of the middle of the import
block in imageGeneration.ts for readability.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix: align three stub implementations with original code
- chatUrlMatcher: restore original 3-arg signature (u, matchDomain, chatUrl)
with PLACEHOLDER-aware path segment matching
- shouldUseGrokBrowserBacked: remove required param, restore env-var logic
checking both WEB_COOKIE_USE_BROWSER and OMNIROUTE_BROWSER_POOL
- browserPool.ts: add Turbopack rationale comment and join-trick helper
to satisfy the optional-import test assertions
- browserBackedChat.ts: replace any types with typed BrowserPoolModule interface
Verification: 40/40 browser node:test pass, typecheck:core 0 errors
* fix: remove duplicate getMod/modPromise in browserBackedChat stub
Two copies of the module proxy got committed — the typed BrowserPoolModule
version at lines 50-56 and a stale any-typed duplicate at lines 64-71.
Removed the duplicate, keeping the typed version.
Verification:
- 40/40 browser tests pass (both previously-failing suites now green)
- typecheck:core: 0 errors
- env kill switch (OMNIROUTE_BROWSER_POOL=off): verified
* fix(pr-8299): address all 5 review issues
Issue #1: Add @omniroute/browser-pool path to root tsconfig.json paths
Issue #2: Fix tryBackedChat fallback — call browserBackedChat outside if(loaded) guard
Issue #3: Fix grokClearance stub signature (signal?: AbortSignal) → string|null
Issue #4: Add comment clarifying async __resetBrowserPoolMetricsForTest vs upstream sync
Issue #5: Add test case for package-absent fallback in tryBackedChat
All 25 browser tests pass across 4 suites. typecheck:core passes.
* chore: move sqlite-vec to optionalDependencies, fix js-tiktoken static import
Both changes ensure native binary dependencies are properly categorized as optional:
- sqlite-vec: moved from dependencies to optionalDependencies. Only used via
lazy _require("sqlite-vec") in vectorStore.ts — zero static imports.
- js-tiktoken: already in optionalDependencies, import changed to createRequire
pattern to avoid crash when package is not installed (same pattern as sqlite-vec
in vectorStore.ts).
Resolves ScoutDeps findings from browser-pool pluginization audit.
* docs(issues): fix stale interfaces.ts path in browser-pool proposal
The proposal originally planned open-sse/interfaces/browserPool.ts for
the BrowserPoolProvider interface, but the shipped implementation puts
it in packages/browser-pool/src/interfaces.ts instead. Update the
references so the doc matches what was actually built — the stale
path was tripping check:fabricated-docs (--strict).
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
* fix: sync package-lock.json with playwright 1.62.0
Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
* test: keep browser warmup disabled in tryBackedChat unit tests
* fix(pr-8299): keep grokClearance on the evolved release implementation (rebase reconciliation)
---------
Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
* Feat: Busca Global de Modelos no Combo Builder
* Fix: assembleStandalone src and dest equality check on Windows
* fix(ui): i18n global model search + drop pnpm-lock + extract search panel
- Drop pnpm-lock.yaml (repo is npm-workspaces; package-lock.json is canonical).
- i18n: replace hardcoded Portuguese strings in the new global model search
UI (Combo Builder) with getI18nOrFallback()/t() EN-fallback calls; add the
10 new keys (builderModeStep, builderModeGlobal, builderGlobal*) to en.json
and propagate __MISSING__ placeholders to all 42 locales.
- Extract the mode-toggle + global-search panel JSX into a new
GlobalModelSearchPanel component, and the allGlobalModels/
filteredGlobalModels/add-step/add-all logic into pure, unit-tested helpers
(buildGlobalModelList, filterGlobalModelList, addGlobalModelStep,
addAllGlobalSearchMatches) in src/lib/combos/builderDraft.ts, keeping
combos/page.tsx under its frozen file-size budget.
- Revert the unrelated local-tooling .source/dynamic.ts one-liner to match
origin/release/v3.8.49.
- Add unit tests for the new builderDraft helpers.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: Gleisson de Jesus Santos <T034183@embasanet.ba.gov.br>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: ikelvingo <im.kelvinwong@gmail.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Base-red slice 6, rebased onto the advanced release/v3.8.49 (91fd5f9). The oauth
grok-cli #7610 guard was already fixed on the base by #8027 (it reads the warning
from grokCliAuthJson.ts) — dropped from this slice to avoid a conflicting duplicate.
Remaining two, still red on the current base:
- i18n #7258: the "focused repro" asserted zh-TW.json STILL carries raw __MISSING__:
placeholders. That backlog was filled (the "no locale has a raw __MISSING__: leaf"
invariant is the durable guard); retired the now-inverted repro.
- qianfan: Baidu renamed the product page (product/wenxinworkshop -> product-s/
qianfan_home); updated the expected website URL.
Validated (clean env): i18n 4/0, qianfan 5/0; oauth-modal-grok 2/0 already green on base.
Co-authored-by: Probe Test <probe@example.com>
* fix(dashboard): correct machine-translated Korean UI strings in ko.json
Fix 527 mistranslated values in the Korean locale, all verified against
the en.json source:
- Restore protected product/protocol names garbled by machine translation
(응록→ngrok, 인류/인류학→Anthropic, 쌍둥이자리→Gemini, 반중력→Antigravity,
꼬리비늘 깔때기→Tailscale Funnel, 진공→VACUUM, 우편번호→ZIP)
- Fix wrong-sense homonym translations (달리기→실행 중 for Running,
장애인→비활성화됨 for Disabled, 열쇠→키 for Key, 안타→적중 for Hits,
유물→아티팩트 for Artifacts, 건강검진→상태 확인 for Healthcheck)
- Repair translated identifiers that broke literal values (양말5→socks5,
볼록-세션-id→convex-session-id, 채팅/완료→chat/completions,
메시지/보내기→message/send JSON-RPC methods)
- Replace key-name dumps shipped as values ("Table Name", "Overview
Title", "Cli Tools Redirect Title" etc.) with real Korean translations
- Unify ngrok casing (Ngrok→ngrok) and trailing punctuation with the
English source; align terminology across fixes (공급자, 폴백, 사용자 정의)
All {placeholder} tokens, markdown, and protected terms preserved
verbatim; i18n UI coverage and ko validation gates pass.
* feat(ci): extend i18n glossary-consistency gate to ko
Follow-up to #8224 (ko.json mistranslation cleanup): the glossary gate
only checked zh-CN, leaving the Korean catalog unguarded against the
next machine-translation run reintroducing the garbage it fixed.
- Add scripts/i18n/glossary/ko.json: 9 canonical concepts (provider,
fallback, running/disabled states, key, export, healthcheck, port,
artifacts) plus protectedTermMistranslations for 10 verified garbled
renderings (응록→ngrok, 인류→Anthropic, 쌍둥이자리→Gemini,
반중력→Antigravity, 꼬리비늘→Tailscale, 진공→VACUUM, 양말5→socks5,
우편번호→ZIP, 클로드→Claude, 옴니루트→OmniRoute)
- Extend check-glossary-consistency.mjs to merge per-locale
protectedTermMistranslations from the glossary file with the legacy
zh-CN KNOWN_MISTRANSLATIONS map (behavior for zh-CN unchanged)
- Add ngrok/Anthropic/Claude/Gemini/Antigravity/Tailscale/VACUUM/
socks5/ZIP to protected-terms.json
- Wire --locale=ko into the i18n-glossary CI job and add the
i18n:check-glossary:ko npm script
- Tests: merge semantics (3 new unit tests), #8224 regression guards
for src + bin/cli ko catalogs, and real-file pass assertions for ko
Every enforced synonym/mistranslation was verified to have zero
occurrences in both real ko catalogs; collision-prone candidates
(안타 ⊂ 안타깝게도, 배우 ⊂ 배우기) were deliberately excluded.
The semantic cache signature (generateSignature) was computed over different
bodies at read-time vs write-time in handleChatCore. The cache read at Phase
9.1 uses the original body, but the writes at Phase 9.1 (non-streaming) and
Phase 9.2 (streaming) used the body after sanitizeChatRequestBody() and
injectMemoryAndSkills() mutated messages. Since the digest includes messages,
every request stored under a key no later request would look up — 0% hit
rate, every request billed.
Fix: snapshot bodyForCacheWrite right after the cache read and use it for
both write paths, so the write-time signature equals the read-time one.
TDD: tests/unit/cache-signature-roundtrip.test.ts proves the mutated body
produces a different signature (bug) and the preserved snapshot produces an
identical one (fix).
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
* fix(quality): green release/v3.8.50 base-reds — env-doc sync + file-size freeze (#9985)
Sweep base-reds from issue #9985 on release/v3.8.50:
- env-doc-sync: add COMMANDCODE_API_URL + ANTIGRAVITY_ALLOW_SIGNATURE_BYPASS to
.env.example and ENVIRONMENT.md (in code, missing from docs); add
OMNIROUTE_STRICT_SYSTEM_PROVIDERS + TLS_FINGERPRINT_PROVIDERS to ENVIRONMENT.md
(in .env.example, missing from doc). Restores the 3-way env contract.
- file-size: freeze open-sse/utils/proxyFetch.ts at 1207 (new proxied-TLS fetch
helper over the 1000 cap). Owner-authorized quick rebaseline; slim for v3.9.0.
Co-authored-by: OmniRoute maintenance <maintainers@omniroute.local>
* fix(quality): green open-sse+dashboard typecheck base-reds (#9985)
Release-equivalent fast-gates surface 5 real TS regressions inherited by the
base from merged Fal/guardrails/cursor work (fast-gates PR->release do not run
these, so they accrued on release/v3.8.50):
- open-sse/handlers/imageGeneration/providers/fal.ts: normalizeProviderImagePayload
missing 4th 'b64_json' arg (TS2554).
- open-sse/handlers/videoGeneration/falHandler.ts: narrow video to Record before .url.
- src/app/api/v1/images/generations/route.ts: type the toJsonErrorPayload read.
- src/lib/guardrails/visionBridgeHelpers.ts: cast through unknown for UA fetch.
- src/lib/providers/mergeProviderModelListing.ts: drop index-signature requirement
that made interface RegistryModel[] unassignable (TS2322, from #9911).
All fixed in source (keeps the gates meaningful); each reproduces on the base tip.
Co-authored-by: OmniRoute maintenance <maintainers@omniroute.local>
* fix(quality): allowlist onnxruntime-node in dependency allowlist (#9985)
check:deps base-red — onnxruntime-node is a real production dep (transformers
embedding path) landed via the LLMLingua/transformers bump (#9962) without an
allowlist entry. Legit package: microsoft onnxruntime, verified in registry.
* fix(quality): rebaseline CodeQL ratchet 1->2 for #9940 fingerprint alerts (#9985)
Base-red: 2nd js/insufficient-password-hash alert on chatBodyAdmission API-key
fingerprints (sha256->16-hex admission-lane key), not password verification.
Reproduces on release/v3.8.50 tip. Owner-authorized rebaseline (revisit v3.9.0).
* fix(quality): green release/v3.8.50 unit base-reds (#9985)
8 unit-test base-reds reproducing on the pristine release tip, fixed in-source
(fast-gates PR->release do not run the unit suite, so these accrued silently):
- ServiceSupervisor: spawn-failure now resolves with error status (was throwing);
health-probe-failure path still rejects. Distinct via spawnFailed flag.
- stream + responseSanitizer: numeric passthrough id preserved as string (was
regenerated chatcmpl-); finish chunk with empty delta no longer swallowed by
the emptyChoices guard.
- proxyFetch: genuine (non-abort) proxy transport failures keep the underlying
reason in the surfaced error.
- auto-combo builtinCatalog: advertised undefined-variant auto/* ids (auto/chat,
auto/best-chat, auto/pro-chat) materialize instead of throwing 'Unknown'.
- getTranslations en.json: add missing providers.iconUrlInvalid.
- optional-transformers-dependency.test: reconcile to #9962's deliberate
move of @huggingface/transformers to a regular dep (napi onnxruntime).
Co-authored-by: OmniRoute maintenance <maintainers@omniroute.local>
---------
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouzapw@gmail.com>
Co-authored-by: OmniRoute maintenance <maintainers@omniroute.local>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
* fix(deps): bump nanoid, dompurify for 2 new Dependabot alerts (#189, #190)
Bumps: nanoid ^3.3.17 (was transitive, now overridden), dompurify ^3.4.13
(with monaco-editor scoped override). Closes Dependabot #189, #190.
Remaining #182-#188 (js-yaml + mermaid) already closed by #9651 merge —
awaiting Dependabot re-scan.
npm audit → 0 vulnerabilities.
* fix(repo): harden .gitignore to also ignore a _tasks symlink (/_tasks)
_tasks is a SEPARATE nested git repo (gitignored). The pattern _tasks/ (trailing
slash) ignores only a directory, not a SYMLINK named _tasks. A self-referential
_tasks symlink can slip in via git add -A and, once pulled, checkout materializes
it over the real _tasks repo (destroying plans/specs/hands-off). Anchored /_tasks
ignores the symlink too, preventing re-capture.
* fix(services): stop embedded-service supervisor retry loop when binary cannot spawn
A non-spawnable supervised binary (ENOENT/EACCES, or an ELF on Windows
where spawn() throws EFTYPE synchronously) left the supervisor in
'starting' forever while the HealthChecker polled the dead port every
healthIntervalMs. Each failed probe fired a full ProxyFetch
dispatcher+native fetch pair, burning CPU and eventually collapsing the
server (observed: 24 warns/min against 127.0.0.1:8317 for 2 days).
- handle synchronous spawn() throws and the child 'error' event: stop
the poller and transition to an explicit error state
- transition to error and stop polling when FAILURE_THRESHOLD
consecutive health probes fail, including during startup
- waitForHealthy re-checks the state after its deadline so a
mid-startup error surfaces as a rejection instead of being overwritten
by 'running'
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@outlook.com>
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>
* feat(cursor): prefer live synced catalog for listing and Test All
When an active synced Cursor catalog exists, list only live models plus
injected auto routers (and customs). Keep the static registry as offline
fallback.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(cursor): send live-catalog model ids verbatim on AgentRun
Skip #7289 effort/reasoning splits when the exact id is in the active synced
Cursor catalog so AgentRun does not rewrite flattened live ids into missing
bases that return AI Model Not Found. Also wires auto-cost/balance/intelligence
to default + optimization for the injected routers.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: yansigit <yansigit@users.noreply.github.com>
* fix(deps): bump nanoid, dompurify for 2 new Dependabot alerts (#189, #190)
Bumps: nanoid ^3.3.17 (was transitive, now overridden), dompurify ^3.4.13
(with monaco-editor scoped override). Closes Dependabot #189, #190.
Remaining #182-#188 (js-yaml + mermaid) already closed by #9651 merge —
awaiting Dependabot re-scan.
npm audit → 0 vulnerabilities.
* fix(repo): harden .gitignore to also ignore a _tasks symlink (/_tasks)
_tasks is a SEPARATE nested git repo (gitignored). The pattern _tasks/ (trailing
slash) ignores only a directory, not a SYMLINK named _tasks. A self-referential
_tasks symlink can slip in via git add -A and, once pulled, checkout materializes
it over the real _tasks repo (destroying plans/specs/hands-off). Anchored /_tasks
ignores the symlink too, preventing re-capture.
* fix(antigravity): ban-safety hardening — bounded onboarding retries with jitter, gate the thought-signature bypass sentinel
- onboardAntigravityUser: cap retries 10->3 and jitter the delay (3-7s) so a
stuck loop cannot read as scripted automation to the upstream
- openai-to-gemini: the skip_thought_signature_validator sentinel is an
audit-trail risk; gate it behind ANTIGRAVITY_ALLOW_SIGNATURE_BYPASS (default
enabled for compatibility, set 0 to disable). Real signatures always win.
* test(antigravity): cover the signature-bypass sentinel gate (default on, env-disabled)
Adds tests/unit/translator-antigravity-signature-bypass.test.ts (2 tests, verified
locally with node --import tsx/esm) + CHANGELOG entry for the ban-safety hardening.
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@outlook.com>
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
Co-authored-by: benzntech <benzntech@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
npm ci / next build fail on Node 24/26 because the optional
@huggingface/transformers@3.5.2 pins onnxruntime-node@1.21.0, whose NAN
native code no longer compiles against newer V8 - npm silently skips the
whole optional subtree, and Turbopack fails the build with 'Module not
found: Can't resolve @huggingface/transformers' (lazy import in
src/lib/memory/embedding/transformersLocal.ts).
Fix: move @huggingface/transformers out of optionalDependencies (npm ci
can never skip it), bump to ^4.2.0, add onnxruntime-node ~1.24.3 (napi
prebuilds, no node-gyp). Verified on Node 26.6.0: npm ci + production
build succeed; both packages require() cleanly.
- auto/best-vision and auto/pro-vision now resolve to the vision CATEGORY
(candidate filter by capability) instead of the flat smart variant, so the
vision-bridge describe/reroute target can actually see images
(resolveBuiltinAutoSpec in builtinCatalog).
- vision candidate pool excludes registry entries whose catalog OVERSTATES
vision support (opencode-go/opencode-zen/tokenrouter are forced through the
vision bridge by isVisionBridgeForcedModel) in both the auto-combo candidate
filter (suffixComposition) and the vision router (visionBridgeRouter).
- reroute guard: an auto/* target is a virtual combo; a missing 'auto' provider
row (hasUsableCredentials=false) must never block the reroute.
- claude-wire backends (minimax, zai, ...) reject remote image URLs (MiniMax
403 2013): ensureBase64ImagesForClaudeWire resolves URLs to base64 before
rerouting, and the describe self-loop normalizes to base64 for those targets
(isClaudeWireFormatModel).
- self-loop describe uses a real DB-backed key (resolveSelfLoopApiKey) instead
of the sk_omniroute sentinel rejected by REQUIRE_API_KEY instances, and
bypasses the runtime's hooked global fetch via undici (ProxyFetch with a dead
local proxy would otherwise break every describe); compression is disabled
on the self-loop sub-request so image payloads are never mangled.
Tests: vision-bridge-auto-reroute (2), vision-bridge-selfloop-key (4),
vision-bridge-claude-wire (6), builtin-vision-spec (4),
vision-filter-excludes-forced (4).
Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>