Commit Graph

3952 Commits

Author SHA1 Message Date
diegosouzapw
3786e929d6 feat(api): add Claude Code auth import/export API routes + schemas (PR2) 2026-05-18 01:45:54 -03:00
diegosouzapw
c6a51605ce feat(oauth): add Gemini CLI auth import/export libs + CLI_TOOLS registration (PR1) 2026-05-18 01:12:44 -03:00
diegosouzapw
09fb5cdf34 feat(oauth): add Claude Code auth import/export libs + tests (PR1) 2026-05-18 01:07:38 -03:00
diegosouzapw
4eb5ba5fb8 docs(changelog): add entry for PR #2355 2026-05-18 00:25:07 -03:00
Raxxoor
f6364427ce fix: emit stream errors in client protocol (#2355)
Integrated into release/v3.8.0
2026-05-18 00:24:38 -03:00
diegosouzapw
7a40e0f547 docs(changelog): add entry for PR #2354 2026-05-17 22:59:23 -03:00
Cong Vu Chi
6d4ee4f85a fix: allow bracketed combo names (#2354)
Integrated into release/v3.8.0
2026-05-17 22:58:42 -03:00
diegosouzapw
749b945fdf docs(changelog): add entries for PRs #2351 #2350
- feat(claude-code): semantic passthrough (#2351 — thanks @terence71-glitch)
- fix(usage): flat cached_tokens/reasoning_tokens extraction (#2350 — thanks @TF0rd)
2026-05-17 21:12:11 -03:00
Tyler Ford
d6d585e200 fix: extract flat cached_tokens/reasoning_tokens from OpenAI-compatible usage objects (#2350)
Integrated into release/v3.8.0 — flat cached_tokens/reasoning_tokens extraction for Xiaomi MiMo and similar providers
2026-05-17 21:11:06 -03:00
terence71-glitch
db8a2dc735 fix: preserve Claude Code messages on direct routes (#2351)
Integrated into release/v3.8.0 — Claude Code semantic passthrough for /v1/messages payloads
2026-05-17 21:09:02 -03:00
diegosouzapw
9b8dc4d6db docs(changelog): add entries for PRs #2326 #2327 #2335 #2349 #2344 #2339 #2322 #2329 #2338 #2340 2026-05-17 20:15:02 -03:00
Paijo
1be18f5530 feat(providers): add Microsoft Copilot Web wrapper (#2340)
Integrated into release/v3.8.0 — fixed session pool security issue (per-token isolation) and added unit tests
2026-05-17 20:02:02 -03:00
Paijo
193e7a6417 feat(routing): LGKP remembers last good account per provider (#2338)
Integrated into release/v3.8.0 — added unit tests for connectionId-aware getLKGP/setLKGP
2026-05-17 19:54:32 -03:00
Michael
b191173ae1 Fix Providers empty state blocking first provider setup 2026-05-17 19:47:42 -03:00
backryun
1f27c344d4 chore: improve huggingface provider support (#2322)
Integrated into release/v3.8.0 — migrates HuggingFace to router.huggingface.co/v1 endpoint, adds dynamic model discovery, refreshes ASR/TTS catalog
2026-05-17 19:44:53 -03:00
Paijo
aefd9bbbc7 feat(providers): add Hackclub AI as free provider (#2339)
Integrated into release/v3.8.0 — adds Hackclub AI as free aggregator with 30+ models, auth optional
2026-05-17 19:43:58 -03:00
Paijo
c2451038a0 feat(providers): add GitHub Models as free provider (#2344)
Integrated into release/v3.8.0 — adds GitHub Models as a free provider with 14 models (GPT-4.1, o3, DeepSeek-R1, Llama 4, Grok 3 etc.)
2026-05-17 19:40:50 -03:00
Hernan Javier Ardila Sanchez
749197466f fix(translator): use reasoning cache before empty string fallback for DeepSeek tool_calls (#2349)
Integrated into release/v3.8.0 — fixes DeepSeek 400 errors by using cached reasoning_content before falling back to empty string for tool_call messages
2026-05-17 19:40:10 -03:00
terence71-glitch
0e2d04526c fix: honor Codex reasoning suffix aliases (#2335)
Integrated into release/v3.8.0 — fixes issue #2331: Codex model suffix aliases now correctly override client-injected reasoning defaults
2026-05-17 19:38:25 -03:00
thepigdestroyer
696e16b361 fix(claude): cap-aware thinking budget fit for max_tokens (#2327)
Integrated into release/v3.8.0 — fixes HTTP 400 max_tokens > 128000 from Anthropic when using high-effort thinking with Opus 4.7
2026-05-17 19:37:40 -03:00
thepigdestroyer
0f15797e01 fix(v1/messages): default to non-stream for Claude format when ambiguous (#2326)
Integrated into release/v3.8.0 — fixes STREAM_EARLY_EOF on POST /v1/messages when stream is omitted
2026-05-17 19:36:57 -03:00
Diego Rodrigues de Sa e Souza
891a9e4125 Merge pull request #2337 from diegosouzapw/worktree-fix+providers-missing-button-i18n
fix(providers): fix missing i18n keys and add 'Add Provider' button to empty state
2026-05-17 17:51:43 -03:00
Diego Rodrigues de Sa e Souza
9c69a20ea5 Merge pull request #2343 from diegosouzapw/feat/codex-auth-import-bulk
feat(codex): bulk import Codex auth.json — multi-file, paste, ZIP
2026-05-17 17:29:49 -03:00
diegosouzapw
3748b0238d chore(merge): resolve conflicts for bulk import — keep both schemas and all i18n keys 2026-05-17 17:28:41 -03:00
Diego Rodrigues de Sa e Souza
6e6cb5a0b5 Merge pull request #2336 from diegosouzapw/feat/codex-auth-import-single
feat(codex): import single Codex auth.json as OAuth connection
2026-05-17 17:14:52 -03:00
diegosouzapw
3227c9ffe3 chore(merge): resolve page.tsx conflict — keep ImportCodexAuthModal and ApplyCodexAuthModal 2026-05-17 17:13:50 -03:00
Diego Rodrigues de Sa e Souza
cf0006fd7b Merge pull request #2332 from diegosouzapw/feat/codex-auth-apply-modal
feat(codex-auth): rename export + gate Apply Local behind confirmation modal
2026-05-17 17:08:11 -03:00
diegosouzapw
25f3fe1ac5 feat(codex): bulk import Codex auth.json — multi-file, paste, ZIP
Adds three input modes for importing multiple Codex accounts at once,
all feeding a single partial-failure backend endpoint.

- `codexAuthZipExtract.ts`: safe ZIP extraction via fflate — rejects
  path traversal (../ and absolute paths), per-file 256 KB cap, 10 MB
  total cap, max 50 .json entries
- `POST /api/providers/codex-auth/zip-extract`: server-side ZIP
  extraction returning [{name, json, parseError}] to the client
- `POST /api/providers/codex-auth/import-bulk`: iterates entries,
  partial-failure semantics (always 200), per-entry audit log
  `provider.credentials.imported` + summary `bulk_imported`
- `importCodexAuthBulkSchema`: max 50 entries, email validation
- `<ImportCodexAuthModal>`: Single/Bulk top tabs; Bulk has Upload
  files, Paste list (JSON array or --- separator), ZIP sub-modes;
  live entry preview list; overwrite checkbox; result panel
- Install `fflate@0.8.3` (pure TypeScript, zero native deps)
- 29 unit tests: 12 ZIP safety cases + 17 schema/parser/shape cases
2026-05-17 16:52:43 -03:00
Diego Rodrigues de Sa e Souza
072e38e552 Merge pull request #2333 from diegosouzapw/worktree-fix+providers-missing-button-i18n
fix(providers): fix missing i18n keys and add 'Add Provider' button to empty state
2026-05-17 14:16:06 -03:00
diegosouzapw
8a6d681c15 feat(codex): import single Codex auth.json as OAuth connection
Adds an import flow that lets users bring an existing Codex auth.json
into OmniRoute without a fresh OAuth login. Both a file-upload tab and
a paste-JSON tab are supported.

- `codexAuthImport.ts`: pure parser + createConnectionFromAuthFile
  (conflict detection, overwriteExisting, JWT email/exp extraction)
- `POST /api/providers/codex-auth/import`: Zod-validated endpoint with
  audit log (`provider.credentials.imported`)
- `importCodexAuthSchema` in schemas.ts (discriminated union json/text,
  256 KB cap on paste source)
- `<ImportCodexAuthModal>` in providers/[id]/page.tsx with upload/paste
  tabs, email auto-detection, name/email/overwrite fields
- "Import auth" toolbar button shown only on the Codex provider page
- 29 unit tests (17 parser + 12 schema) — all passing
2026-05-17 14:04:48 -03:00
diegosouzapw
de5434a0a6 fix(providers): fix missing i18n keys and add 'Add Provider' button to empty state
- Add addFirstProvider, addFirstProviderDesc, learnMore to providers namespace in en.json
  (keys existed only in common namespace, causing raw key display on fresh installs)
- Add primary 'Add Provider' button to empty state that reveals provider grid
  (only 'Learn more' external link existed, leaving users with no way to add a provider)
- Remove || fallback strings now that i18n keys are correctly placed
2026-05-17 13:53:06 -03:00
diegosouzapw
634f50a04e feat(codex-auth): rename export to auth-{email}.json and gate Apply Local behind confirmation modal
Export filename change:
- Drop the redundant `codex-` prefix; embed the account email so multiple
  exported files can coexist in the same downloads folder.
- Email is extracted from the id_token JWT `email` claim, with fallback
  to connection.email and finally to the sanitized connection label.
- sanitizeFileNamePart now preserves @ so addresses survive intact
  (e.g. `auth-diego@example.com.json`).

Apply Local refinement:
- ApplyCodexAuthModal: confirmation modal showing the resolved target
  path, the side-by-side .bak location, and the centralized backup
  trail. User must tick a confirmation checkbox before Apply enables.
- writeCodexAuthFileToLocalCli now writes a side-by-side
  `auth-<timestamp>.bak` inside the .codex/ directory before replacing
  the live file, in addition to the existing centralized backup. Both
  inputs to the .bak path are server-controlled (dirname from the
  static CLI_TOOLS table; basename from a server-generated ISO
  timestamp), so no user input touches path APIs.
- apply-local route now emits a `provider.credentials.applied` audit
  event with the resolved authPath and savedBakPath, and routes all
  errors through sanitizeErrorMessage() per the security guide.

Tests: tests/unit/codexAuthFile.test.ts covers sanitization, JWT email
extraction, filename format for both branches (email/label), and the
ISO-timestamp .bak basename safety.

Scope: this is PR1 of the import/export work tracked under
_tasks/features-v3.8.0/importexport/. PR2 (import single) and PR3
(import bulk) will follow.
2026-05-17 13:32:29 -03:00
diegosouzapw
02564d5a5b chore(changelog): update missing entries for recent PRs and commits 2026-05-17 12:58:38 -03:00
diegosouzapw
fc9f8d91f7 feat(providers): bulk add API keys with Single/Bulk tabs
Mirrors the 9router UX (one textarea, name|apiKey per line) but goes
further: dedicated server-side endpoint with Zod validation, partial-
failure semantics, audit log, and provider whitelist.

UI (src/app/(dashboard)/dashboard/providers/[id]/page.tsx):
- AddApiKeyModal now switches between Single (existing behaviour) and
  Bulk Add via tab strip. Tabs hide for providers that don't support
  bulk (Vertex, web-session, OAuth, multi-field).
- Bulk pane: textarea, shared Priority + "validate each key" checkbox,
  result panel with per-line errors (truncated at 10).

Backend:
- POST /api/providers/bulk: iterates entries through createProviderConnection
  with the same provider-specific normalization as the single endpoint.
  Returns {success, failed, total, created, errors[]}. Optional pre-save
  validation via /api/providers/validate when validateKeys=true. Each
  entry succeeds/fails independently — no transaction rollback.
- Bulk audit event logged once per request plus per-entry success events.

Schemas:
- bulkCreateProviderSchema (src/shared/validation/schemas.ts): max 200
  entries, mandatory name+apiKey per entry, google-pse-search cx guard.
- supportsBulkApiKey() helper (src/shared/constants/providers.ts) with
  explicit deny-list for OAuth/web-session/multi-field providers.

Parser:
- parseBulkApiKeys() (src/shared/utils/bulkApiKeyParser.ts) handles
  CRLF, # comments, blank lines, pipe inside apiKey, empty-name fallback,
  and caps input at BULK_API_KEY_MAX_LINES (200) with a warning.

Tests:
- tests/unit/bulkApiKeyParser.test.ts: 12 cases (format, edge cases, cap)
- tests/unit/providers-bulk-route.test.ts: 12 cases (schema, whitelist,
  response shape, apiKey leak guard)

i18n:
- en.json: bulkTabSingle, bulkTabBulkAdd, bulkAddFormatHint,
  bulkValidateKeys, bulkAddAllKeys, bulkAddedCount, bulkFailedCount,
  adding
2026-05-17 11:30:49 -03:00
diegosouzapw
a45d9190db fix(security): resolve CodeQL ReDoS + URL sanitization alerts
- Replace replace(/\/+$/, "") with explicit while-endsWith loop to avoid
  polynomial backtracking on inputs with repeated trailing slashes
  (CodeQL js/polynomial-redos #233-240, 8 alerts):
  - @omniroute/opencode-provider/src/index.ts (normalizeBaseURL)
  - bin/cli/api.mjs (stripTrailingSlash)
  - src/lib/cli-helper/config-generator/{claude,cline,codex,continue,
    kilocode,opencode}.ts (6 generators with identical pattern)

- tests/live/deepseek-web-live.test.ts: assert hostname via URL parsing
  instead of String.includes() so the check is exact-match rather than
  substring (CodeQL js/incomplete-url-substring-sanitization #241).

Alert #242 (Array.prototype.includes against fixed needle constant
OPENWEBUI_PARAGRAPH_ANCHORS) dismissed as CodeQL false-positive — not a
URL sanitization callsite.
2026-05-17 07:43:32 -03:00
diegosouzapw
ca8f492240 fix(i18n): add missing providers.{allProviders,audioProviders,showFreeOnly} keys
PR #2314's category filter chips and free-only toggle on the providers
page reference these keys under the 'providers' namespace, but the keys
exist only under 'common'. Add them under 'providers' so the chips render
without 'MISSING_MESSAGE' console errors.
2026-05-17 05:51:57 -03:00
diegosouzapw
84cde3d009 chore(release): back-merge main into release/v3.8.0 after v3.8.0 cut
Sync release branch with main so next-cycle work starts from the same
point. Includes the v3.8.0 release merge commit (f57dcba59).
2026-05-17 03:07:05 -03:00
Diego Rodrigues de Sa e Souza
f57dcba59f Merge pull request #2248 from diegosouzapw/release/v3.8.0
Release v3.8.0
2026-05-17 03:06:43 -03:00
diegosouzapw
b2fe307128 chore: narrow .claude/ gitignore to runtime files only
The blanket .claude/ rule would block future additions to .claude/commands/
which is intentionally tracked. Replace with explicit list of runtime
artifacts: scheduled_tasks.lock, scheduled_tasks/, sessions/, state.json.
2026-05-17 03:05:31 -03:00
diegosouzapw
6fa745efcb chore: untrack .claude/scheduled_tasks.lock + ignore runtime artifacts
The lockfile is local Claude Code session state that was committed by
accident in 24b2e77a (#2265). Untrack it and add a narrow .gitignore rule
covering only runtime artifacts (lock, scheduled_tasks, sessions, state)
so shared command definitions at .claude/commands/ stay tracked.
2026-05-17 03:03:57 -03:00
diegosouzapw
440ca8e3cc Merge pull request #2314 from oyi77/feat/gitlawb-opengateway
feat: gitlawb opengateway provider + providers page filter chips

Three independent contributions from oyi77 bundled in this PR:

1. Gitlawb Opengateway provider (b83d1a0fc):
   - gitlawb (alias glb) — xiaomi-mimo endpoint with 5 MiMo models
   - gitlawb-gmi (alias glb-gmi) — gmi-cloud endpoint with 40+ models
   - Both flagged free tier, CLI-mimicking headers to avoid upstream
     rate limiting
   - 9 unit tests in tests/unit/gitlawb-provider.test.ts (all green)

2. hasFree flag (d7dcd233a): friendliai, chutes, featherless-ai now
   correctly surface free tier badge in the providers page.

3. UI additions (debf7cb28):
   - CollapsibleSection.tsx (coexists with our existing Collapsible.tsx —
     different API for different use cases)
   - Category filter chips bar on /dashboard/providers (auto-merged)
   - Free-only toggle on /dashboard/providers (auto-merged)
   - Extended filterConfiguredProviderEntries with showFreeOnly param
   - i18n tooltip keys for Caveman/RTK settings (union with our
     simpleMode/advancedMode/filterCatalog keys)
   - InfoTooltip + PresetSlider identical to PR #2316 versions
     (silent dedup by auto-merge)

Conflict resolution:
- src/shared/components/index.tsx: union — added CollapsibleSection
  export alongside our NoAuthProviderCard.
- src/i18n/messages/en.json: union — kept all our keys from #2316
  (simpleMode/advancedMode/filterCatalog/filterCatalogDesc) and added
  PR's tooltip keys (searchFilters, tooltipDedup, tooltipMaxChars,
  tooltipMaxLines, tooltipAutoTrigger, tooltipCompressionRate,
  tooltipMaxTokens, tooltipMinLength, tooltipMinSavings, ultraSettings,
  ultraSettingsDesc).

Closes #2314
2026-05-17 02:37:05 -03:00
diegosouzapw
43d4ea092c Merge pull request #2316 from oyi77/feat/ui-rework
feat(ui): simple/advanced mode for Caveman & RTK + newbie UX improvements

Adapts oyi77's UX rework on top of our refactor/pages overhaul. Layout
priority: our 9-section sidebar restructure stays; PR's additions
(subtitles, intros, simple/advanced toggles, empty states, error labels)
are integrated into our structure.

Conflict resolution:

- index.tsx: union — exports InfoTooltip, PresetSlider (new shared
  components from PR) alongside our NoAuthProviderCard.
- en.json: union — kept our "OmniSkills"/"AgentSkills" labels and
  "API Key Manager" naming; added PR's subtitleKey strings, settings
  intro keys, and empty state keys.
- sidebarVisibility.ts: kept our 9-section structure; added subtitleKey?:
  string to SidebarItemDefinition and mapped subtitle keys onto the 7
  matching items (endpoints, api-manager, combos, batch, context-caveman,
  context-rtk, webhooks).
- Sidebar.tsx: kept our collapsible-section rendering; integrated PR's
  subtitle support into resolveItem() and renderNavLink() label area.
- CavemanContextPageClient.tsx: took PR's version — adds SegmentedControl
  for simple/advanced mode (gates full settings tab in advanced).
- RtkContextPageClient.tsx: took PR's version — adds SegmentedControl +
  Collapsible filter catalog.
- settings/page.tsx: kept our redirect (we converted tabs→pages). Ported
  PR's intro text paragraphs to /settings/ai, /settings/routing, and
  /settings/resilience subpages using the auto-merged i18n keys.
- HomePageClient.tsx: kept ours — we removed Providers Overview card in
  the refactor, and PR's empty state for that card is now redundant.
  PR's equivalent empty state at /dashboard/providers (in
  providers/page.tsx) auto-merged cleanly and serves the same purpose.

Closes #2316
2026-05-17 02:13:22 -03:00
Diego Rodrigues de Sa e Souza
ee2a698dcb Merge pull request #2315 from diegosouzapw/refactor/pages
refactor(dashboard): pages overhaul, providers UX, OAuth token refresh fixes [deferred in develop]
2026-05-17 01:44:30 -03:00
diegosouzapw
317d146302 Merge release/v3.8.0 into refactor/pages
Resolves conflicts in 9 files to bring 181 commits from release/v3.8.0 into
the dashboard refactor branch ahead of merging back to release.

Layout strategy: our pages overhaul (tabs→pages, restructured sidebar,
removed redundant headers, OpenCode Free no-auth card) is the source of
truth. Release's functional additions are adapted into our layout.

Conflict resolution:

- package.json/package-lock.json: take release's deps (axios bump, CLI v4
  deps, tls-client-node/wreq-js move to optionalDependencies); re-add our
  @xyflow/react addition; regenerate lockfile.
- src/shared/constants/sidebarVisibility.ts: keep our 9-section restructure
  — release's new IDs (limits, media, cli-tools, agents, cloud-agents,
  memory, skills, agent-skills, context-*) are all already present in our
  groups.
- src/i18n/messages/en.json: auto-merge picked up all release's new keys
  (autoCatalog*, quotaCutoffs*, systemTransforms*, schema-coercion, vision);
  only naming conflict was OmniSkills/AgentSkills — kept ours (no space).
- src/app/(dashboard)/dashboard/HomePageClient.tsx: kept our Provider
  Topology card; ported release's TierCoverageWidget (placed before
  topology).
- src/app/(dashboard)/dashboard/settings/page.tsx: kept our redirect to
  /settings/general (we moved tabs to separate pages); release's sticky
  tab CSS change is moot in our structure.
- src/app/(dashboard)/dashboard/skills/page.tsx: rerere applied — release
  hardcoded "OmniSkills" h1 was already removed by our header-cleanup
  refactor.
- src/app/(dashboard)/dashboard/agent-skills/page.tsx: both branches
  created this file independently with identical data source; kept our
  Tailwind-themed 2-column grid (release's version used inline styles).
- src/app/(dashboard)/dashboard/batch/page.tsx: kept our single-tab
  structure (FilesListTab moved to /batch/files page); ported release's
  onRefresh prop addition.
- src/app/(dashboard)/dashboard/batch/files/page.tsx (not in conflict but
  updated): added batches fetch + batches prop to preserve release's
  feature of showing related batches in the file detail modal.

Pre-existing typecheck errors in open-sse/services/contextManager.ts
(lines 141, 154, 167) come from release/v3.8.0 and are not introduced by
this merge.
2026-05-17 01:14:21 -03:00
oyi77
a4a870cda3 feat(ui): add newbie-friendly UX improvements across dashboard
- Providers page: empty state with guided 'Add your first provider' card
- Providers page: home page shows only configured providers by default
- Settings: add intro text to Routing, Resilience, and AI tabs
- i18n: fix 'Api Key Mgmt' to 'API Key Management', remove duplicate key
- i18n: add keys for empty state, settings intros, free-only filter
2026-05-17 07:56:22 +07:00
diegosouzapw
2b624b1bf3 chore(changelog): add entries for PRs #2317, #2318, #2319 2026-05-16 21:51:48 -03:00
backryun
cf3262aee8 alibaba provider consolidation (#2319)
Integrated into release/v3.8.0 — consolidates Alibaba-related providers, updates model registries and docs.
2026-05-16 21:50:59 -03:00
backryun
926ff2b5db chore(providers): refresh provider metadata and ordering (#2318)
Integrated into release/v3.8.0 — refreshes provider model metadata, sorts dashboard provider entries by display name, and fixes docs generator relative links.
2026-05-16 21:48:01 -03:00
Raxxoor
5a7df8ac29 fix: harden stream readiness and build output (#2317)
Integrated into release/v3.8.0 — fixes stream readiness detection for OpenAI Responses API lifecycle events, GLM timeout, Provider Limits UI, and build output cleanup.
2026-05-16 21:47:40 -03:00
diegosouzapw
7fdcba9e05 fix(auth): return synthetic credentials for noAuth free providers
Requests to opencode (noAuth: true) were failing with "No credentials for
provider: opencode" because getProviderCredentials found no DB connections and
returned null — triggering the 400 error path in chatHelpers.

Inject a synthetic credential object (connectionId: "noauth", no apiKey/token)
before the regular connection lookup so the executor receives valid credentials
and skips the Authorization header. Also enable model import for noAuth providers
(canImportModels = true when isFreeNoAuth).
2026-05-16 21:31:03 -03:00