Commit Graph

1425 Commits

Author SHA1 Message Date
diegosouzapw
71452e0405 feat(db): migrate core.ts to SqliteAdapter multi-driver factory 2026-05-20 19:14:45 -03:00
diegosouzapw
48c9b4a986 feat(db): add driverFactory with better-sqlite3 → node:sqlite → sql.js cascade 2026-05-20 17:47:21 -03:00
diegosouzapw
e8751299d3 feat(db): add sqljsAdapter (WASM fallback for any environment) 2026-05-20 17:44:10 -03:00
diegosouzapw
e989d9cfa0 feat(db): add nodeSqliteAdapter (node:sqlite built-in fallback) 2026-05-20 17:41:28 -03:00
diegosouzapw
c51c2db8f8 feat(db): add betterSqliteAdapter wrapper 2026-05-20 17:38:55 -03:00
diegosouzapw
0bb0c9dfda feat(db): add SqliteAdapter interface for multi-driver support 2026-05-20 17:35:46 -03:00
Raxxoor
18e27038e2 feat: align Antigravity 2.0.1 support (#2443)
Integrated into release/v3.8.1
2026-05-20 16:35:30 -03:00
Gi99lin
a0d2dee0c5 fix(jules): Jules API parity and cloud-agent provider registration (#2438)
Integrated into release/v3.8.1
2026-05-20 16:35:20 -03:00
Anton
8670950da3 chore(i18n): refresh fr/es/de locales + add missing settings.update key (#2437)
Integrated into release/v3.8.1
2026-05-20 16:35:16 -03:00
The DT
688bc580b5 feat: Enhance extractBearer to support x-api-key for anthropic api style auth (#2436)
Integrated into release/v3.8.1
2026-05-20 16:35:11 -03:00
Anton
d42161566d feat(memory): wire createMemory to upsertSemanticMemoryPoint (Qdrant) (#2439)
Integrated into release/v3.8.1
2026-05-20 16:35:05 -03:00
Gi99lin
f16fb03cb8 fix(antigravity): IDE vs SDK client profile fingerprint parity (#2433)
Integrated into release/v3.8.1 — applied review suggestion (deduplicate removeHeaderCaseInsensitive)
2026-05-20 12:20:48 -03:00
diegosouzapw
0efaf1cca7 fix(security): post-review hardening batch — command injection, CSP, auth gaps, error sanitization, resilience
- plugin.mjs: replace execSync string-template with spawnSync arg-array (command injection)
- electron/main.js: gate unsafe-eval on !app.isPackaged instead of URL substring; merge duplicate connect-src
- budget/bulk, resilience/reset: add requireManagementAuth guard
- gemini-web, claude-web, copilot-web executors: route catch-block messages through sanitizeErrorMessage
- oauth route, agents/tasks routes: route catch-block errors through sanitizeErrorMessage
- codex.ts: return null (not error-object) from refreshCredentials on failure
- tokenRefresh.ts: safe unknown-error access in catch block
- combo.ts: reset exhaustedProviders per set-retry iteration so providers get a second chance
- circuitBreaker.ts: persist and restore lastFailureKind via options JSON column
2026-05-20 11:11:13 -03:00
Diego Rodrigues de Sa e Souza
f5073604b3 Release/v3.8.0 (#2430)
* fix(cli-tools): guard modelId type before calling indexOf

E2E shakedown v3.8.0: cli-tools quebrava com TypeError quando dynamicModels
continha entradas sem .id (objeto retornado diretamente em vez de string).

* fix(offline): avoid SSR/CSR hydration mismatch on navigator.onLine

Replace useState+lazy-initializer with useSyncExternalStore so the server
snapshot (() => false) and client snapshot (() => navigator.onLine) are
declared separately. React hydrates with the server value and switches to
the real online status client-side without a mismatch.

* chore(i18n): add missing en.json keys for translator, cli-tools, memory, onboarding

Adds 58 missing keys identified by the new dashboard audit script:
- cliTools: 18 custom CLI builder keys (CustomCliCard)
- translator: 24 keys covering stream transformer, live monitor, test bench
- memory: 12 health/pagination/dialog keys
- onboarding.tier: 8 keys for the tier tour walkthrough

Also adds scripts/i18n/audit-dashboard-pages.mjs which scans all dashboard
pages, reports t() calls referencing missing en.json keys, and flags
candidate hardcoded JSX/attribute strings.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 1)

Subagents refactored 8 high-impact dashboard pages, replacing 81 of the
407 hardcoded English/PT strings flagged by the audit with proper
useTranslations() lookups. Added 73 corresponding keys to en.json across
the home, apiManager, providers, settings, and usage namespaces.

Pages affected:
- BudgetTab (27 → 0)
- HomePageClient (2 → 0)
- RoutingTab (25 → 7)
- ResilienceTab (38 → 18)
- SystemStorageTab (42 → 21)
- providers/[id] (17 → 15)
- ApiManagerPageClient (14 → 13)
- OneproxyTab (13 → 10)

Also adds two helper scripts:
- scripts/i18n/extract-keys-from-diff.mjs — extracts new keys from git diff
- scripts/i18n/merge-keys.mjs — merges a pending-keys JSON into en.json

Remaining hardcoded strings will be addressed in follow-up rounds.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 2)

Continues round 1 (commit 8d34f4c65). Round-2 subagents refactored
additional dashboard pages, replacing 77 more hardcoded strings with
useTranslations() lookups. Added 79 corresponding keys to en.json
across the a2aDashboard, agents, analytics, apiManager, cliTools,
common, and settings namespaces.

Pages affected:
- a2a/page (new useTranslations + 6 keys)
- agent-skills/page (new useTranslations + 9 keys)
- AutoRoutingAnalyticsTab (new useTranslations + 6 keys)
- AppearanceTab (8 → 6 remaining)
- OneproxyTab (10 → 0)
- ResilienceTab (18 → 0 missing key)
- RoutingTab (7 → 0 missing key)
- VisionBridgeSettingsTab (new useTranslations + 6 keys)
- CopilotToolCard (7 → 0 missing key)
- ApiManagerPageClient (13 → 0 missing key)
- gamification/admin (new useTranslations + 7 keys)

Hardcoded total: 326 → 249. Real missing keys: 0 (the 6 still flagged
are false positives in exampleTemplates.tsx where t is passed as a
parameter — keys exist at translator.templatePayloads.*).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 3)

Round-3 subagents and manual edits refactored 9 more dashboard pages
(plus 2 small extras), replacing ~80 hardcoded strings with
useTranslations() lookups. Added 79 corresponding keys to en.json
across analytics, cloudAgents, combos, common, health, settings, and
usage namespaces.

Pages affected:
- analytics/ComboHealthTab (new useTranslations + 15 keys)
- analytics/CompressionAnalyticsTab (new useTranslations + 11 keys)
- settings/SystemStorageTab (21 → 0 missing key)
- tokens/page (new useTranslations + 13 keys)
- usage/BudgetTab (9 missing fixed)
- health/page (manual: 6 keys)
- cloud-agents/page (manual: 3 keys)
- combos/page (manual: 1 key)

Hardcoded total: 249 → 164. Real missing keys: 0 (6 remaining are
exampleTemplates.tsx false positives).

Also adds scripts/i18n/build-pending-from-missing.mjs which reads
_audit.json and locates English values from HEAD to rebuild
_pending-keys.json after race-condition resets between subagent edits.

* chore(i18n): localize remaining dashboard settings labels

Replace hardcoded labels in compression and resilience settings with
translation lookups to continue the dashboard i18n cleanup.

Add the v3.8.0 dashboard shakedown runbook to document the manual
smoke-test process and known dev environment pitfalls.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 4)

Round-4 subagent + manual key-resolution refactored remaining strings in
3 high-traffic settings/API tabs, plus extracted English values for
keys that were already added as t() calls but lost during the previous
en.json race-condition resets.

Pages affected:
- api-manager/ApiManagerPageClient (7 → 0 missing key)
- settings/CompressionSettingsTab (8 → 0 missing key)
- settings/MemorySkillsTab (8 → 0 missing key)
- settings/ResilienceTab (4 more keys recovered)

Hardcoded total: 164 → 140. Real missing keys: 0 (6 remaining are the
exampleTemplates.tsx false positives — t passed as parameter).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 5)

Round-5 agent began processing the remaining smaller dashboard files.
Added 5 more keys to en.json for providers/[id]/page.tsx OAuth flow
labels and the cross-OS auto-detection hint.

Pages affected:
- providers/[id]/page.tsx (5 keys)

Hardcoded total: 140 → 136. Real missing keys: 0.

* chore(i18n): resolve last 2 missing providers/[id] keys

Adds providerDetailMyClaudeAccountPlaceholder and
providerDetailPathAutoDetected — the final user-visible labels in the
providers/[id] page that the round-5 subagent rewrote to t() calls
without yet adding to en.json.

Real missing keys: 0 (6 remaining are exampleTemplates.tsx false
positives — t is passed as a parameter so the audit cannot resolve the
namespace; keys do exist at translator.templatePayloads.*).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 6 — 10 parallel agents)

Round-6 dispatched 10 parallel subagents covering all 57 remaining
dashboard files. Each agent worked on a disjoint file set to avoid
en.json race conditions. Added ~60 new i18n keys across 9 namespaces
covering small UI labels, table headers, search placeholders, and
empty-state messages.

Major changes:
- analytics: SearchAnalyticsTab, ProviderUtilizationTab, DiversityScoreCard, CompressionAnalyticsTab (new useTranslations + keys)
- batch: BatchDetailModal, BatchListTab, FileDetailModal, FilesListTab (new useTranslations + keys)
- settings: CliproxyapiSettingsTab, PayloadRulesTab, ModelCooldownsCard, AppearanceTab, PricingTab (mostly new useTranslations)
- endpoint: TokenSaverCard, ApiEndpointsTab, EndpointPageClient
- cache: CachePerformance, IdempotencyLayer, ReasoningCacheTab, MediaPageClient, page
- combos: IntelligentComboPanel, page
- playground: ChatPlayground, SearchPlayground
- providers: ProviderCard
- onboarding: TierFlowDiagram
- changelog: ChangelogViewer
- home: ProviderTopology, TierCoverageWidget, BootstrapBanner, BadgeToast
- usage: BudgetTab, BudgetTelemetryCards, QuotaTable
- quotaShare: QuotaSharePageClient
- profile: page
- leaderboard: page
- skills: page

Hardcoded total: 131 → 60. Real missing keys: 0 plus 1 false-positive
for combos.modePack (lookup via prop-passed t).

* chore(i18n): finalize round-6 keys for batch/cache/endpoint/usage

Adds the remaining keys produced by parallel agents A4, A6, A8, A9:
- common: batch-related labels (BatchDetailModal, BatchListTab,
  FileDetailModal, FilesListTab, page) + profile/leaderboard
- cache: hit rate, latency, retry, avg chars
- endpoint: token saver, API endpoints, copy URL, cloud/local labels
- usage: noSpend, activeSessions, quotaAlerts, budget timing
- skills: install/marketplace/filter
- proxyRegistry/quotaShare/mcpDashboard: misc labels

Hardcoded total: 60 → 48. Real missing keys: 0 (modePack remaining is a
false positive — combos.modePack exists but the audit can't resolve it
since IntelligentComboPanel receives t as a prop).

* fix(playground): dedupe filteredModels to avoid duplicate React key warning

The /v1/models endpoint can return the same model id twice (e.g., when a
model is listed by both an alias and its canonical provider), which made
the <Select> emit two <option> elements with the same key — triggering
"Encountered two children with the same key, codex/gpt-5.5".

Replace the chained filter + map with a single pass that skips ids
already added.

* fix(playground): guard against non-string model ids before .split/.startsWith

The /v1/models endpoint can include synthetic entries (combos, locals,
in-progress imports) with a null/undefined id. The playground used to
call m.id.split("/") in the provider-discovery loop, which threw on the
first non-string entry; the surrounding .catch(() => {}) silently
swallowed the error, so the provider/model/account dropdowns ended up
empty even though /v1/models returned thousands of valid entries.

- Skip entries without a string id before split/startsWith.
- Log the rejection in the .catch handler so future regressions are
  visible in DevTools instead of silently emptying the UI.

* fix(playground): guard ChatPlayground filteredModels for non-string ids

Same root cause as commit 49fe356b9: ChatPlayground filtered models
with m.id.startsWith(...) which crashed on null/undefined ids returned
by /v1/models (synthetic combo entries). Apply the same defensive guard
and dedupe used in the parent page.

* fix(claude): drop orphan tool_result after fixToolAdjacency strip (discussion #2410)

Discussion #2410 reports Claude returning 400 for sequences like:
  assistant: tool_use(id=X)
  user: <plain text>           ← breaks adjacency
  user: tool_result(id=X)

The previous round added `fixToolAdjacency` (commit 44d9abac9) which
correctly strips the orphan tool_use from the assistant message. But
that left the now-unmatched tool_result intact, so the upstream
rejected the request with:

  messages.N.content.M: unexpected `tool_use_id` found in `tool_result`
  blocks: X. Each tool_result block must have a corresponding tool_use
  block in the previous message.

Fix: after running `fixToolAdjacency`, re-run `fixToolPairs` to drop
the orphaned tool_result blocks. All three call sites updated:
  - contextManager.purifyHistory (both inside the binary-search loop
    and the final pass)
  - BaseExecutor message-prep (Claude path)
  - claudeCodeCompatible request signer

Also tightens an unrelated dynamic-key access in
readNestedString (claudeCodeCompatible) to satisfy the prototype-
pollution scanner triggered by the post-tool semgrep hook.

* fix(mitm): point runtime manager re-export to js entrypoint

Use the emitted `.js` path for the runtime manager re-export so dynamic
runtime loading resolves correctly outside the Turbopack alias handling.

* docs: add AgentRouter setup guide (#2422)

Integrated into release/v3.8.0 — AgentRouter setup guide docs.

* feat: add new feature on combos - falloverBeforeRetry (#2417)

Integrated into release/v3.8.0 — falloverBeforeRetry for per-model quota skipping in combos.

* feat(batch): implement 10 feature requests harvested  (#2414)

Integrated into release/v3.8.0 — batch of 10 feature requests: llama.cpp local provider, upstream error exposure, Termux detection, providers rotate CLI, t3.chat web skeleton, Zed Docker integration, Kiro multi-account OAuth isolation, auto-combo cost blending, auto-combo context filter, combo provider-level exhaustion tracking (#1731). Conflicts with #2417 (falloverBeforeRetry) resolved.

* fix(gamification): resolve SQL bug, auth gap, pagination, and anomaly scoring (#2421)

Integrated into release/v3.8.0 — 6 critical gamification bug fixes: SQL SELECT in checkActionCountBadges, federation auth enforcement, leaderboard pagination offset, real z-score computation, addXp level calculation, and barrel index.ts

* docs(changelog): add post-release entries for #2414 #2417 #2421 #2422

- feat(batch): T3-Chat-Web executor, exhaustedProviders set (#1731), Zed Docker
- feat(combos): falloverBeforeRetry + setTry loop (#2417 — @hartmark)
- fix(gamification): SQL SELECT bug, federation auth, pagination, z-score (#2421 — @oyi77)
- docs: AgentRouter setup guide (#2422 — @leninejunior)

* fix(security): resolve CodeQL random/password-hash alerts and sync docs & tests

* feat/fix: integrate PRs #2423, #2425, #2427, #2428 with test & security fixes

* docs(changelog): credit contributors for PRs #2423, #2425, #2427, #2428

* fix(mitm): drop .js extension on manager.runtime re-export for webpack build (#2425)

Merged into release/v3.8.0

* fix: persist STORAGE_ENCRYPTION_KEY across upgrades (closes #1622) (#2428)

Merged into release/v3.8.0

* fix: auto-reset apiKeyHealth on successful connection test (#2427)

Merged into release/v3.8.0

* fix: support Antigravity image generation, Add Gemini 3.5 Flash (#2423)

Merged into release/v3.8.0

---------

Co-authored-by: diegosouzapw <diego.souza.pw@gmail.com>
Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Anton <39598727+NomenAK@users.noreply.github.com>
Co-authored-by: Chewji <126886556+Chewji9875@users.noreply.github.com>
Co-authored-by: clousky2020 <33016567+clousky2020@users.noreply.github.com>
Co-authored-by: backryun <bakryun0718@proton.me>
2026-05-20 09:12:49 -03:00
diegosouzapw
dd790c38a2 refactor(gamification): raise federation token hashing cost
Increase PBKDF2 iterations for federation auth and server API key
hashes to better resist brute-force attacks and keep hashing behavior
aligned across leaderboard, score, and server connection flows.

Regenerate auto-generated docs entries for the Kiro setup,
gamification, and dashboard shakedown guides.
2026-05-20 02:21:37 -03:00
Diego Rodrigues de Sa e Souza
6248699ce5 Release/v3.8.0 — full changelog with 660+ commits (#2419)
* fix(cli-tools): guard modelId type before calling indexOf

E2E shakedown v3.8.0: cli-tools quebrava com TypeError quando dynamicModels
continha entradas sem .id (objeto retornado diretamente em vez de string).

* fix(offline): avoid SSR/CSR hydration mismatch on navigator.onLine

Replace useState+lazy-initializer with useSyncExternalStore so the server
snapshot (() => false) and client snapshot (() => navigator.onLine) are
declared separately. React hydrates with the server value and switches to
the real online status client-side without a mismatch.

* chore(i18n): add missing en.json keys for translator, cli-tools, memory, onboarding

Adds 58 missing keys identified by the new dashboard audit script:
- cliTools: 18 custom CLI builder keys (CustomCliCard)
- translator: 24 keys covering stream transformer, live monitor, test bench
- memory: 12 health/pagination/dialog keys
- onboarding.tier: 8 keys for the tier tour walkthrough

Also adds scripts/i18n/audit-dashboard-pages.mjs which scans all dashboard
pages, reports t() calls referencing missing en.json keys, and flags
candidate hardcoded JSX/attribute strings.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 1)

Subagents refactored 8 high-impact dashboard pages, replacing 81 of the
407 hardcoded English/PT strings flagged by the audit with proper
useTranslations() lookups. Added 73 corresponding keys to en.json across
the home, apiManager, providers, settings, and usage namespaces.

Pages affected:
- BudgetTab (27 → 0)
- HomePageClient (2 → 0)
- RoutingTab (25 → 7)
- ResilienceTab (38 → 18)
- SystemStorageTab (42 → 21)
- providers/[id] (17 → 15)
- ApiManagerPageClient (14 → 13)
- OneproxyTab (13 → 10)

Also adds two helper scripts:
- scripts/i18n/extract-keys-from-diff.mjs — extracts new keys from git diff
- scripts/i18n/merge-keys.mjs — merges a pending-keys JSON into en.json

Remaining hardcoded strings will be addressed in follow-up rounds.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 2)

Continues round 1 (commit 8d34f4c65). Round-2 subagents refactored
additional dashboard pages, replacing 77 more hardcoded strings with
useTranslations() lookups. Added 79 corresponding keys to en.json
across the a2aDashboard, agents, analytics, apiManager, cliTools,
common, and settings namespaces.

Pages affected:
- a2a/page (new useTranslations + 6 keys)
- agent-skills/page (new useTranslations + 9 keys)
- AutoRoutingAnalyticsTab (new useTranslations + 6 keys)
- AppearanceTab (8 → 6 remaining)
- OneproxyTab (10 → 0)
- ResilienceTab (18 → 0 missing key)
- RoutingTab (7 → 0 missing key)
- VisionBridgeSettingsTab (new useTranslations + 6 keys)
- CopilotToolCard (7 → 0 missing key)
- ApiManagerPageClient (13 → 0 missing key)
- gamification/admin (new useTranslations + 7 keys)

Hardcoded total: 326 → 249. Real missing keys: 0 (the 6 still flagged
are false positives in exampleTemplates.tsx where t is passed as a
parameter — keys exist at translator.templatePayloads.*).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 3)

Round-3 subagents and manual edits refactored 9 more dashboard pages
(plus 2 small extras), replacing ~80 hardcoded strings with
useTranslations() lookups. Added 79 corresponding keys to en.json
across analytics, cloudAgents, combos, common, health, settings, and
usage namespaces.

Pages affected:
- analytics/ComboHealthTab (new useTranslations + 15 keys)
- analytics/CompressionAnalyticsTab (new useTranslations + 11 keys)
- settings/SystemStorageTab (21 → 0 missing key)
- tokens/page (new useTranslations + 13 keys)
- usage/BudgetTab (9 missing fixed)
- health/page (manual: 6 keys)
- cloud-agents/page (manual: 3 keys)
- combos/page (manual: 1 key)

Hardcoded total: 249 → 164. Real missing keys: 0 (6 remaining are
exampleTemplates.tsx false positives).

Also adds scripts/i18n/build-pending-from-missing.mjs which reads
_audit.json and locates English values from HEAD to rebuild
_pending-keys.json after race-condition resets between subagent edits.

* chore(i18n): localize remaining dashboard settings labels

Replace hardcoded labels in compression and resilience settings with
translation lookups to continue the dashboard i18n cleanup.

Add the v3.8.0 dashboard shakedown runbook to document the manual
smoke-test process and known dev environment pitfalls.

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 4)

Round-4 subagent + manual key-resolution refactored remaining strings in
3 high-traffic settings/API tabs, plus extracted English values for
keys that were already added as t() calls but lost during the previous
en.json race-condition resets.

Pages affected:
- api-manager/ApiManagerPageClient (7 → 0 missing key)
- settings/CompressionSettingsTab (8 → 0 missing key)
- settings/MemorySkillsTab (8 → 0 missing key)
- settings/ResilienceTab (4 more keys recovered)

Hardcoded total: 164 → 140. Real missing keys: 0 (6 remaining are the
exampleTemplates.tsx false positives — t passed as parameter).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 5)

Round-5 agent began processing the remaining smaller dashboard files.
Added 5 more keys to en.json for providers/[id]/page.tsx OAuth flow
labels and the cross-OS auto-detection hint.

Pages affected:
- providers/[id]/page.tsx (5 keys)

Hardcoded total: 140 → 136. Real missing keys: 0.

* chore(i18n): resolve last 2 missing providers/[id] keys

Adds providerDetailMyClaudeAccountPlaceholder and
providerDetailPathAutoDetected — the final user-visible labels in the
providers/[id] page that the round-5 subagent rewrote to t() calls
without yet adding to en.json.

Real missing keys: 0 (6 remaining are exampleTemplates.tsx false
positives — t is passed as a parameter so the audit cannot resolve the
namespace; keys do exist at translator.templatePayloads.*).

* chore(i18n): replace hardcoded UI text with t() calls across dashboard (round 6 — 10 parallel agents)

Round-6 dispatched 10 parallel subagents covering all 57 remaining
dashboard files. Each agent worked on a disjoint file set to avoid
en.json race conditions. Added ~60 new i18n keys across 9 namespaces
covering small UI labels, table headers, search placeholders, and
empty-state messages.

Major changes:
- analytics: SearchAnalyticsTab, ProviderUtilizationTab, DiversityScoreCard, CompressionAnalyticsTab (new useTranslations + keys)
- batch: BatchDetailModal, BatchListTab, FileDetailModal, FilesListTab (new useTranslations + keys)
- settings: CliproxyapiSettingsTab, PayloadRulesTab, ModelCooldownsCard, AppearanceTab, PricingTab (mostly new useTranslations)
- endpoint: TokenSaverCard, ApiEndpointsTab, EndpointPageClient
- cache: CachePerformance, IdempotencyLayer, ReasoningCacheTab, MediaPageClient, page
- combos: IntelligentComboPanel, page
- playground: ChatPlayground, SearchPlayground
- providers: ProviderCard
- onboarding: TierFlowDiagram
- changelog: ChangelogViewer
- home: ProviderTopology, TierCoverageWidget, BootstrapBanner, BadgeToast
- usage: BudgetTab, BudgetTelemetryCards, QuotaTable
- quotaShare: QuotaSharePageClient
- profile: page
- leaderboard: page
- skills: page

Hardcoded total: 131 → 60. Real missing keys: 0 plus 1 false-positive
for combos.modePack (lookup via prop-passed t).

* chore(i18n): finalize round-6 keys for batch/cache/endpoint/usage

Adds the remaining keys produced by parallel agents A4, A6, A8, A9:
- common: batch-related labels (BatchDetailModal, BatchListTab,
  FileDetailModal, FilesListTab, page) + profile/leaderboard
- cache: hit rate, latency, retry, avg chars
- endpoint: token saver, API endpoints, copy URL, cloud/local labels
- usage: noSpend, activeSessions, quotaAlerts, budget timing
- skills: install/marketplace/filter
- proxyRegistry/quotaShare/mcpDashboard: misc labels

Hardcoded total: 60 → 48. Real missing keys: 0 (modePack remaining is a
false positive — combos.modePack exists but the audit can't resolve it
since IntelligentComboPanel receives t as a prop).

* fix(playground): dedupe filteredModels to avoid duplicate React key warning

The /v1/models endpoint can return the same model id twice (e.g., when a
model is listed by both an alias and its canonical provider), which made
the <Select> emit two <option> elements with the same key — triggering
"Encountered two children with the same key, codex/gpt-5.5".

Replace the chained filter + map with a single pass that skips ids
already added.

* fix(playground): guard against non-string model ids before .split/.startsWith

The /v1/models endpoint can include synthetic entries (combos, locals,
in-progress imports) with a null/undefined id. The playground used to
call m.id.split("/") in the provider-discovery loop, which threw on the
first non-string entry; the surrounding .catch(() => {}) silently
swallowed the error, so the provider/model/account dropdowns ended up
empty even though /v1/models returned thousands of valid entries.

- Skip entries without a string id before split/startsWith.
- Log the rejection in the .catch handler so future regressions are
  visible in DevTools instead of silently emptying the UI.

* fix(playground): guard ChatPlayground filteredModels for non-string ids

Same root cause as commit 49fe356b9: ChatPlayground filtered models
with m.id.startsWith(...) which crashed on null/undefined ids returned
by /v1/models (synthetic combo entries). Apply the same defensive guard
and dedupe used in the parent page.

* fix(claude): drop orphan tool_result after fixToolAdjacency strip (discussion #2410)

Discussion #2410 reports Claude returning 400 for sequences like:
  assistant: tool_use(id=X)
  user: <plain text>           ← breaks adjacency
  user: tool_result(id=X)

The previous round added `fixToolAdjacency` (commit 44d9abac9) which
correctly strips the orphan tool_use from the assistant message. But
that left the now-unmatched tool_result intact, so the upstream
rejected the request with:

  messages.N.content.M: unexpected `tool_use_id` found in `tool_result`
  blocks: X. Each tool_result block must have a corresponding tool_use
  block in the previous message.

Fix: after running `fixToolAdjacency`, re-run `fixToolPairs` to drop
the orphaned tool_result blocks. All three call sites updated:
  - contextManager.purifyHistory (both inside the binary-search loop
    and the final pass)
  - BaseExecutor message-prep (Claude path)
  - claudeCodeCompatible request signer

Also tightens an unrelated dynamic-key access in
readNestedString (claudeCodeCompatible) to satisfy the prototype-
pollution scanner triggered by the post-tool semgrep hook.

* fix(mitm): point runtime manager re-export to js entrypoint

Use the emitted `.js` path for the runtime manager re-export so dynamic
runtime loading resolves correctly outside the Turbopack alias handling.

* docs: add AgentRouter setup guide (#2422)

Integrated into release/v3.8.0 — AgentRouter setup guide docs.

* feat: add new feature on combos - falloverBeforeRetry (#2417)

Integrated into release/v3.8.0 — falloverBeforeRetry for per-model quota skipping in combos.

* feat(batch): implement 10 feature requests harvested  (#2414)

Integrated into release/v3.8.0 — batch of 10 feature requests: llama.cpp local provider, upstream error exposure, Termux detection, providers rotate CLI, t3.chat web skeleton, Zed Docker integration, Kiro multi-account OAuth isolation, auto-combo cost blending, auto-combo context filter, combo provider-level exhaustion tracking (#1731). Conflicts with #2417 (falloverBeforeRetry) resolved.

* fix(gamification): resolve SQL bug, auth gap, pagination, and anomaly scoring (#2421)

Integrated into release/v3.8.0 — 6 critical gamification bug fixes: SQL SELECT in checkActionCountBadges, federation auth enforcement, leaderboard pagination offset, real z-score computation, addXp level calculation, and barrel index.ts

* docs(changelog): add post-release entries for #2414 #2417 #2421 #2422

- feat(batch): T3-Chat-Web executor, exhaustedProviders set (#1731), Zed Docker
- feat(combos): falloverBeforeRetry + setTry loop (#2417 — @hartmark)
- fix(gamification): SQL SELECT bug, federation auth, pagination, z-score (#2421 — @oyi77)
- docs: AgentRouter setup guide (#2422 — @leninejunior)

* fix(security): resolve CodeQL random/password-hash alerts and sync docs & tests

---------

Co-authored-by: diegosouzapw <diego.souza.pw@gmail.com>
Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
2026-05-20 02:05:50 -03:00
diegosouzapw
ae07f437b1 fix(providers): add missing isLocalProvider import and update changelog 2026-05-19 10:12:56 -03:00
clousky2020
2ae523b12c feat(T07): API Key health tracking with A3 guard, dashboard notification, and toast navigation fixes (#2412)
Integrated into release/v3.8.0
2026-05-19 09:50:51 -03:00
Benson K B
6959e067fa Merge branch 'main' resolving upstream conflicts (#2408)
Integrated into release/v3.8.0
2026-05-19 09:48:16 -03:00
Paijo
81fb3f50e8 feat: gamification & leaderboard system (#2405)
Integrated into release/v3.8.0
2026-05-19 09:46:20 -03:00
diegosouzapw
4b2e9b780a fix(db): detect missing better-sqlite3 native binding from bun/skipped postinstall (#2358)
`bun add -g omniroute` (and any runtime that does not reliably run the
better-sqlite3 postinstall script) leaves the *.node binary undownloaded.
The `bindings()` loader then throws "Could not locate the bindings file"
BEFORE any DLOPEN happens, which the previous detector missed — the user
saw a generic 500 page instead of the friendly "Run npm rebuild
better-sqlite3" guide.

Extended isNativeSqliteLoadError() to recognise:
- "Could not locate the bindings file" (bindings module preflight)
- "Cannot find module 'better-sqlite3'" (package not even installed)
- code === "MODULE_NOT_FOUND" (Node loader fallback)

isNativeSqliteLoadError is now exported so tests can pin the contract; the
detector covers both the "wrong NODE_MODULE_VERSION" and "binary never
shipped" failure modes operators have hit in practice.
2026-05-19 04:05:36 -03:00
diegosouzapw
ca42874098 fix(providers): skip CLI runtime check for kilocode OAuth-based provider (#2404)
The kilocode provider uses OAuth device flow + direct HTTPS to api.kilo.ai
and never depends on the local kilocode CLI binary at runtime. The connection
test was hard-failing with "Local CLI runtime is not installed" even when the
OAuth token itself was perfectly valid, blocking all kilocode setups on hosts
where the CLI binary was not also installed.

Removed kilocode from CLI_RUNTIME_PROVIDER_MAP and extracted the constant to
a dedicated module so unit tests can pin the contract without dragging the
full Next.js route + DB initialization into the test runtime.

CLI Tools integration (/api/cli-tools/kilo-settings, used to configure the
Kilo VSCode extension to point at OmniRoute) keeps its own runtime check
since it actually does need the CLI binary to be present.
2026-05-19 04:04:26 -03:00
diegosouzapw
3957c4d76b chore: merge main into release/v3.8.0
Sincroniza release/v3.8.0 com tudo aplicado em main:
- CodeQL #243/#244/#245 (PR #2391)
- CodeQL #246 HMAC sessionPoolKey (PR #2394)
- CodeQL #247 drop hashing sessionPoolKey (PR #2396)
- Restore 9router acknowledgment (PR #2393)
- Dependabot: electron 42.1.0 (PR #2397)
- Dependabot: production group bumps (PR #2398)
- Dependabot: development group bumps (PR #2399)
2026-05-19 01:22:47 -03:00
Cong Vu Chi
65105feeaf fix(kiro): enable Google OAuth login option (#2392)
Integrated into release/v3.8.0 — enables Google OAuth login button in Kiro auth modal
2026-05-18 23:44:04 -03:00
diegosouzapw
fec6164e92 fix(security): resolve CodeQL alerts #243/#244/#245
#243 (js/request-forgery, high) — providers/bulk/route.ts
- Replace `fetch(\${origin}/api/providers/validate)` (where origin came from
  spoofable `new URL(request.url).origin`) with a direct in-process call to
  validateProviderApiKey. Eliminates the SSRF vector and the HTTP round-trip
  through the same app.
- Resolve proxy once outside the loop and reuse via runWithProxyContext.
- Drop now-unused passthroughAuthHeaders helper.

#244 (js/resource-exhaustion, warn) — copilot-web.ts::solveHashcash
- Clamp upstream-supplied `difficulty` to [1, 8] before `"0".repeat(difficulty)`
  so a malicious/buggy server can't force a huge prefix allocation or push the
  10M-iteration loop into effectively unbounded work.

#245 (js/insufficient-password-hash, warn) — copilot-web.ts::getSession
- Dedupe the inline `createHash("sha256").update(accessToken)` call by reusing
  the existing sessionPoolKey helper.
- Rename its parameter from `accessToken` to `token` and document that the
  input is a high-entropy OAuth bearer used only as an in-memory Map key —
  bcrypt/scrypt/argon2 would be incorrect here, and SHA-256:16 is an
  appropriate fingerprint per docs/security/PUBLIC_CREDS.md.

Tests
- Export solveHashcash and add unit tests asserting it returns null for
  out-of-range / non-integer difficulty and produces a numeric nonce for the
  common difficulty=1 case.
- All 26 tests in copilot-web-executor.test.ts and providers-bulk-route.test.ts
  continue to pass; sessionPoolKey contract (SHA-256:16) preserved.
2026-05-18 23:27:34 -03:00
Paijo
0de964d42b feat(providers): add Gemini Web cookie-based provider (#2380)
Integrated into release/v3.8.0 — adds Gemini Web cookie-based provider with error sanitization fix applied
2026-05-18 22:55:49 -03:00
Diego Rodrigues de Sa e Souza
fa3ee31f06 fix(dashboard): address PR #2384 follow-up review issues (#2389)
- BudgetTab: compute projectionOverBudget per key (HIGH)
- ProviderLimits: convert outer button to div role=button to fix invalid HTML nesting
- Runtime: externalize all strings via next-intl (runtime namespace)
- QuotaShare: externalize all strings via next-intl (quotaShare namespace)
- Add /api/usage/budget/bulk endpoint and switch BudgetTab to single fetch (avoid N+1)

Co-authored-by: diegosouzapw <diego.souza.pw@gmail.com>
2026-05-18 22:52:13 -03:00
diegosouzapw
1c4d850441 fix(build): import Monaco ESM API to fix webpack nls.messages-loader error
Replace import("monaco-editor") with import("monaco-editor/esm/vs/editor/editor.api")
in MonacoEditor.tsx. The root package entry resolves to the minified bundle
(min/vs/editor/editor.main.js) which requires the monaco-editor-webpack-plugin
loader "vs/nls.messages-loader". The ESM API module has no such dependency and
satisfies loader.config({ monaco }) identically.
2026-05-18 19:40:10 -03:00
diegosouzapw
62f609755a fix(types): add explicit cast to silence TS7053 on FREE_PROVIDERS string index
noImplicitAny check rejects FREE_PROVIDERS[resolvedId] because resolveProviderId
returns string but FREE_PROVIDERS has literal key types. Cast to
Record<string, {noAuth?: boolean} | undefined> to express the intent clearly.
2026-05-18 19:30:01 -03:00
diegosouzapw
c9dc205c74 fix(ci): add Zod validation to cli-tools routes and refresh i18n translations for CLAUDE.md
Adds `.safeParse()` to cli-tools/apply and cli-tools/config POST handlers to
satisfy the check:route-validation:t06 CI gate. Regenerates all 41 locale
translations of CLAUDE.md to clear the i18n strict-drift check failure.
2026-05-18 19:19:30 -03:00
Diego Rodrigues de Sa e Souza
eb83eaf25f refactor(dashboard): nav, providers, endpoint, runtime, quota, pricing, budget redesign + quota sharing preview (#2384)
* refactor(dashboard): sidebar subtitles, providers UX, monaco self-host

Sidebar:
- Add subtitleKey to all ~50 menu items so every entry shows a short
  description line (previously only 7 had subtitles).
- Inject 50 new sidebar.*Subtitle keys across all 42 i18n locales
  (en/pt-BR translated; remaining locales fall back to English).
- Fix DATA_÷IC glitch: replace invalid Material Symbols icon
  "data_compression" with "compress" on analytics-compression.
- Rename "Compression Combos" -> "Engine Combos" to avoid truncation
  and disambiguate from the OmniProxy Combos item.

Auto-routing banner:
- Move AutoRoutingBanner from DashboardLayout (rendered on every page)
  to /home only, so it no longer follows the user across the dashboard.

Monaco editor:
- Add shared MonacoEditor wrapper that calls loader.config({ monaco })
  to load Monaco from the bundled monaco-editor package instead of the
  jsdelivr CDN (blocked by CSP script-src 'self'), fixing the
  "Monaco initialization: error" runtime error.
- Migrate the 5 direct dynamic imports of @monaco-editor/react to the
  wrapper (playground, search-tools, translator).

Providers page UX:
- Replace the static legend + 4-stat divider + duplicate filter chips
  with a single row of clickable category pills with embedded counters
  (All, Free, OAuth, API Key, IDE, Compatible, Web Cookie, Search,
  Audio, Local, Cloud Agent).
- Remove redundant per-section Free only / Configured only toggles and
  the Zed Import button from the OAuth section header.
- Introduce a dedicated "IDE Providers" section (Cursor, Zed, Trae)
  rendered under OAuth Providers; exclude IDE_PROVIDER_IDS from OAuth
  to avoid duplication.
- Add zed and trae providers, plus IDE_PROVIDER_IDS set.
- Move the Zed keychain import to /dashboard/providers/zed as a
  contextual Card, instead of cluttering every OAuth section header.
- Extend test-batch route and validation schema with mode: "ide".

* feat(dashboard): add token saver controls to endpoint and context pages

Expose the Token Saver master settings from the endpoint page and
surface its disabled state across the Caveman and RTK context pages.

Update default compression behavior to start disabled with lighter
intensity presets, and add Caveman input compression controls so users
can configure input and output modes separately.

Tighten provider page section rendering by gating compatible, free,
oauth, and api key blocks behind their visibility checks and simplify
several summary labels.

* feat(dashboard): add runtime page and rename limits to quota

Introduce a dedicated runtime observability page for circuit
breakers, cooldowns, lockouts, sessions, and quota alerts.

Split provider quota out of the old limits route, add a redirect from
`/dashboard/limits` to `/dashboard/quota`, and update sidebar/header
labels and i18n keys to match the new navigation.

Enhance provider quota filtering state and remove the tier coverage
widget from the dashboard home view.

* feat(dashboard): redesign budget page and add quota sharing preview

Budget (/dashboard/costs/budget) gets a full rewrite:
- Hero with 6 KPIs (today, month, projected EOM, blocked, at-risk, active)
- Status pills with counts (blocked/alerting/warning/safe/no-limit)
- Templates row (localStorage) with bulk-apply to selected keys
- Multi-key table with checkbox selection and colored progress bar
- Expandable rows with projection card and per-provider cost breakdown
  (last 30d via /api/usage/analytics?apiKeyIds=) plus inline edit form

Quota sharing (/dashboard/costs/quota-share) is new and ships as a beta
UI preview backed by localStorage. Pool persistence in the DB and
request-pipeline enforcement are intentionally deferred to a follow-up.
The page lets operators:
- Create pools from a provider connection + quota window
- Edit allocations per API key with % split and equal-split helper
- Toggle hard/soft/burst policy intent
Donut chart rendered with inline SVG; allocation editor in a modal.

Sidebar gets the new "Quota Sharing" entry under Costs Parameters; i18n
keys propagated across all 41 locales with PT-BR translation.

---------

Co-authored-by: diegosouzapw <diego.souza.pw@gmail.com>
2026-05-18 18:53:00 -03:00
diegosouzapw
04d44f6262 fix(security): sanitize error messages, fix ReDoS patterns, harden OAuth callback
Error message sanitization (Hard Rule #12):
- claude-auth/export, codex-auth/export, gemini-cli-auth/export routes: replace
  raw err.message with sanitizeErrorMessage() from open-sse/utils/error.ts
- imageGeneration, musicGeneration, videoGeneration handlers: import
  sanitizeErrorMessage and replace all err.message in return values
- veoaifree-web executor: replace raw upstream response data in errResp() calls
  with static strings

OAuth callback page (callback/page.tsx):
- Remove useSearchParams/Suspense dependency that caused hydration failures in
  popup windows navigating back from Google OAuth (COOP header severs opener)
- Use window.location.search directly in useEffect with three send methods:
  postMessage, BroadcastChannel, localStorage
- Fix postMessage target from "*" to window.location.origin (semgrep finding)
- Move setCurrentUrl call to manual-only branch to avoid unnecessary renders

copilot-web executor:
- Move accessToken from WebSocket URL query string to Authorization header
  (avoids credential exposure in server logs)
- Add MAX_POOL_SIZE=100 cap to sessionPool with LRU eviction of oldest entry

CodeQL ReDoS fixes (js/polynomial-redos #233-240):
- Replace while(s.endsWith("/")) s=s.slice(0,-1) pattern (O(n²) allocations)
  with index-based loop (O(n) time, single final slice) in:
  bin/cli/api.mjs, all 6 cli-helper config generators, opencode-provider

Gemini OAuth:
- mapTokens: add idToken field to fix "missing id_token" export error
2026-05-18 17:42:09 -03:00
diegosouzapw
5ce3f7f4d6 chore: merge release/v3.8.0 into PR branch 2026-05-18 15:48:43 -03:00
diegosouzapw
5098d8fd7e chore: resolve conflicts with release/v3.8.0 2026-05-18 15:34:49 -03:00
diegosouzapw
b7316d56e8 style(providers): reformat provider validation calls for readability
Wrap long function signatures and validation requests across multiple
lines to match project formatting conventions and improve scanability.
2026-05-18 14:33:56 -03:00
diegosouzapw
5ed96f5072 fix(routing): implement embedding combos, local provider validation bypass, and resolve migration collisions 2026-05-18 14:33:56 -03:00
oyi77
55160bc52a feat(content): add Haiper, Leonardo, Ideogram, Suno, Udio providers
5 new content generation providers with full handler implementations:

Video: haiper (gen2), leonardo (phoenix)
Image: haiper (gen2), leonardo (phoenix/sdxl), ideogram (V3/V2A)
Music: suno (chirp-v3-5/v4), udio (web wrapper)

All async handlers: 5s poll interval, 5 min timeout (60 polls).
Auth: API key (haiper/leonardo/ideogram), cookie (suno/udio).

Closes #2376

Co-Authored-By: OpenClaude (mimo-v2.5-pro) <openclaude@gitlawb.com>
2026-05-18 23:41:27 +07:00
diegosouzapw
b17fd87470 fix(rate-limiter): Redis is now opt-in via REDIS_URL (#2357)
Docker images launched without a sibling Redis container used to spam
'[REDIS] Error: connect ECONNREFUSED 127.0.0.1:6379' for every
rate-limit and API-key-auth cache lookup. The root cause was a default
of process.env.REDIS_URL || 'redis://localhost:6379' that turned the
opt-in cache into a hard dependency.

Three coordinated changes:

1. src/shared/utils/rateLimiter.ts — gate Redis on REDIS_URL being
   explicitly set. getRedisClient() returns null when disabled; the
   single connection-error handler dedupes via a redisErrorLogged latch
   so a sustained outage produces one warn instead of per-request flood.
   checkRateLimit() routes to the existing in-memory store on both the
   'disabled' and 'test' paths.

2. src/lib/db/apiKeys.ts — short-circuit Redis-backed auth cache reads
   and writes when getRedisClient() returns null. SQLite remains
   authoritative; the cache is purely an optimization.

3. Same file — replace the wildcard scope matcher's dynamic RegExp
   compilation with a deterministic segment walker. Eliminates the
   ReDoS surface on operator-supplied scope patterns and silences the
   Semgrep js/regex-injection advisory that previously blocked edits to
   this file.

Single-instance deployments now work silently out of the box;
multi-instance setups continue to use Redis when REDIS_URL is set.
2026-05-18 10:57:23 -03:00
diegosouzapw
f2e368830a fix(combo): guard target.modelStr against non-string before .startsWith (#2359)
Combo dispatch and the combo test button used to crash with
'TypeError: e.startsWith is not a function' when a step's modelStr
failed to resolve (regression after #2338 added per-account LKGP
routing for local/Docker providers). The TypeScript annotation says
the field is always a string, but malformed combo rows leaked through
to the dispatch path.

Two defensive boundary guards:

1. open-sse/services/combo.ts LKGP fallback findIndex — type-check
   target.modelStr before calling startsWith.

2. src/app/api/combos/test/route.ts testComboTarget — coerce
   target.modelStr at the entry, surface a clean 'Combo step is
   missing a model id' error instead of crashing.

Regression test parses the source and asserts no unguarded
target.modelStr.<string-method> usages remain in combo.ts, so a
future refactor that reintroduces the pattern fails loudly.
2026-05-18 10:56:27 -03:00
Mrinal Joshi
400dbc386a fix(claude-oauth): enable system-transforms pipeline for native claude executor
The native claude OAuth path (base.ts:794 applySystemTransformPipeline)
early-exited because DEFAULT_SYSTEM_TRANSFORMS_CONFIG.providers[claude]
was {enabled:false, pipeline:[]}. Result: third-party-agent fingerprints
(github.com/anomalyco/opencode, 'You are OpenCode', 'Here is some useful
information about the environment...') leaked into /v1/messages system
blocks, triggering Anthropic billing-gate:
  [400] Third-party apps now draw from extra usage, not plan limits.

Mirror the cc-bridge defaults:
- DEFAULT_PARAGRAPH_REMOVAL_ANCHORS + OPENWEBUI_PARAGRAPH_ANCHORS
- DEFAULT_IDENTITY_PREFIXES   + OPENWEBUI_IDENTITY_PREFIXES
- DEFAULT_TEXT_REPLACEMENTS as replace_text ops (allOccurrences:true)
- obfuscate_words

Omit prepend_system_block + inject_billing_header — base.ts:759-784
already handles those on the native claude OAuth path.

UI mirror RoutingTab.tsx and snapshot in system-transforms.test.ts
updated for parity. 56/56 transform-related tests pass.

Verified end-to-end 2026-05-18 after npm run build:cli + restart:
- request v8tq04 -> 200 in 1.84s
- request shape {max_tokens:32000, reasoning_effort:high} -> 200 in 1.99s
- x-omniroute-provider=cc (claude-code OAuth pool, account 62875e01)
- telemetry: [SystemTransforms] claude-native: drop_paragraph_if_contains,
  drop_paragraph_if_starts_with, replace_text, replace_text, obfuscate_words
2026-05-18 13:25:30 +01:00
diegosouzapw
33928afec0 fix(ui/tooltip): render in portal + clamp to viewport (#2352)
When the shared <Tooltip> appeared inside a modal (combo editor) or any
ancestor with overflow:hidden/auto, long labels were clipped — the
absolute-positioned <span> stayed inside the modal's stacking context.

Render the tooltip via createPortal to document.body by default
(usePortal prop, defaults to true). Coordinates are computed from the
trigger's getBoundingClientRect on each show and written directly to
the tooltip ref's .style — that avoids the cascading-render warning
that setState-inside-effect triggers, while still doing one synchronous
measure-and-position pass before the user sees any flicker.

Coordinates are clamped to the viewport bounds so a trigger near the
right edge produces a tooltip that stays on-screen instead of bleeding
off. Adds an optional multiline prop that swaps the legacy
whitespace-nowrap clamp for max-w-xs whitespace-normal break-words for
explanation strings (combo strategy help, etc.).

Backward compat: existing call sites do not need to change; the portal
+ clamp behavior is transparent to consumers.
2026-05-18 09:18:25 -03:00
diegosouzapw
5da9b1b778 fix(auto-routing): replace bare getSettings() with getCachedSettings (#2346)
The auto-routing path in src/sse/handlers/chat.ts called `getSettings()`
on every `auto` / `auto/\*` request, but the symbol was never imported in
this module (only `getCachedSettings` was). The runtime ReferenceError
crashed the request with a 500 before any routing could happen.

Replace the call with `getCachedSettings` (already imported, identical
return shape, plus the cached variant benefits the auto-routing hot path).
A regression-guard test scans chat.ts to fail loudly if a future refactor
re-introduces the unimported call pattern.
2026-05-18 09:08:52 -03:00
Paijo
c4fe3d63be feat(content): extend providers with video, audio, TTS, music capabilities (#2369)
Integrated into release/v3.8.0
2026-05-18 08:37:44 -03:00
Paijo
dd24571949 feat(providers): add Veo AI Free as web wrapper provider (#2366)
Integrated into release/v3.8.0
2026-05-18 08:35:34 -03:00
Paijo
41b7f13b27 feat(providers): add Replicate as free provider (#2364)
Integrated into release/v3.8.0
2026-05-18 08:34:00 -03:00
diegosouzapw
2bbd0fff45 Merge feat/gemini-auth-ui (PR3 Gemini) into release/v3.8.0
# Conflicts:
#	src/app/(dashboard)/dashboard/providers/[id]/page.tsx
#	src/i18n/messages/en.json
2026-05-18 03:21:56 -03:00
diegosouzapw
1dae73cfef Merge feat/gemini-auth-api-routes (PR2 Gemini) into release/v3.8.0
# Conflicts:
#	src/shared/validation/schemas.ts
2026-05-18 03:01:51 -03:00
diegosouzapw
f67c7d9383 Merge feat/gemini-auth-libs (PR1 Gemini) into release/v3.8.0 2026-05-18 02:58:51 -03:00
diegosouzapw
855dc86ea8 fix(dashboard): add missing comma in Gemini i18n JSON (PR3) 2026-05-18 02:45:51 -03:00
diegosouzapw
b3cb5b68d8 feat(dashboard): add Gemini CLI auth import/export UI + i18n (PR3) 2026-05-18 02:43:15 -03:00