Skip to content

feat(providers): add Logfare as a free OpenAI-compatible provider (#10644) - #10987

Merged
diegosouzapw merged 62 commits into
diegosouzapw:release/v3.8.50from
jonlwheat2-gif:feat/10644-logfare-provider
Aug 23, 2026
Merged

diegosouzapw merged 62 commits into
diegosouzapw:release/v3.8.50from
jonlwheat2-gif:feat/10644-logfare-provider

Conversation

@jonlwheat2-gif

Copy link
Copy Markdown
Contributor

Adds Logfare.ai as a free OpenAI-compatible provider

Closes #10644

Adds Logfare (https://logfare.ai) — a free LLM inference gateway — as a first-class provider with a Free badge, the real Logfare logo on the card, live model discovery, and full chat/streaming support through the existing OpenAI-compatible path.

What was added

File Change
open-sse/config/providers/registry/logfare/index.ts Runtime registry entry: baseUrl /v1/chat/completions, modelsUrl /v1/models, passthroughModels: true
open-sse/config/providers/index.ts Registered in REGISTRY
src/shared/constants/providers/apikey/gateways.ts Dashboard card: Free badge, freeNote + apiHint documenting the request-logging policy with ToS / privacy / consent links
src/shared/constants/providers.ts Added to AGGREGATOR_PROVIDER_IDS
src/app/api/providers/[id]/models/discovery/providerSets.ts Live-discovery membership (keyed openai-style with a real /v1/models catalog)
public/providers/logfare.png + ProviderIcon.tsx Real Logfare logo (128×128, from logfare.ai/static/img/favicon.png) registered in KNOWN_PNGS
docs/getting-started/FREE-TIERS-GUIDE.md Listed under recurring/uncapped free access
tests/unit/logfare-registry.test.ts Unit test (dahl-registry pattern)

Verification

  • ✅ Live probe before implementing: logfare.ai/v1/models returned HTTP 200 with a genuine catalog — 20 models, 11 chat-capable (kimi-k3, deepseek-v4-pro, glm-5.2, kiro-auto, …). This is a real, working service.
  • ✅ check:provider-consistency — 268 registry entries, 0 orphans
  • ✅ Zod catalog validation passes; getProviderById('logfare') resolves with hasFree: true
  • ✅ Unit tests: logfare + dahl + free-tier wave — all pass
  • ✅ Dashboard typecheck — identical to the pre-existing baseline, zero errors in touched files
  • ✅ Provider-assets budget: logo 17.8 KiB / 128×128 (limits: 128 KiB / 256px)

End-to-end (dev server + production build, real key)

Step Result
Create Logfare connection ✅
Model discovery ✅ 20 models live-imported from logfare.ai/v1/models
Chat completion via proxy ✅ kiro-auto answered correctly with reasoning + real token usage
Streaming via proxy ✅ SSE chunks flowed (chat.completion.chunk deltas)

Notes for reviewers

  1. Logfare's /v1/models is public — the dashboard "Validate" button probes /models (HTTP 200), so even a junk key reports "valid" there. The real auth gate is on chat completions (bad keys get a 401 API key required). This is how Logfare is designed (public catalog, keyed inference) — not a bug in our integration.
  2. Logfare has an explicit request-logging policy — every prompt/completion is logged for research (opt-out at /consent). Documented on the provider card and in the free-tiers guide, per the issue's request.
  3. kimi-k3 / deepseek-v4-pro were intermittently returning 503 from Logfare's side during testing (their service, not ours) — kiro-auto was reliable.

Separate base-branch build fix included

fix(dashboard): resolve missing getConnection import in utilization route — src/app/api/usage/utilization/route.ts imported getConnection from @/lib/db/connections, a module that never existed (the import was added by #10939 without creating the file). This breaks any production build on release/v3.8.50. Fixed to use the real getProviderConnectionById from @/lib/db/providers (same shape). Kept as a separate commit so it can be cherry-picked independently.

jonlwheat2-gif added a commit to jonlwheat2-gif/OmniRoute that referenced this pull request Aug 21, 2026
Adds the logfare row (API key, aggregator) to the auto-generated provider
catalog, matching the providers.ts change from PR diegosouzapw#10987. The doc was last
generated 2026-08-20, so regeneration also syncs pre-existing drift since
then (freebuff row, magnific replacing freepik, cursor/devin-cli note
updates, executors 105 -> 106, total 346 -> 348 providers).

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
jonlwheat2-gif added a commit to jonlwheat2-gif/OmniRoute that referenced this pull request Aug 21, 2026
…e-size

check:docs-counts (STRICT in quality.yml) requires README/AGENTS/llm.txt/
package.json and the four provider-diagram SVGs to mention the live catalog
count — the logfare addition (diegosouzapw#10987) moves it 346 -> 348, and the llm.txt
i18n mirrors (42 exact copies) follow the root. check:file-size requires the
gateways.ts frozen limit to move 1298 -> 1321 for the logfare catalog entry
(same god-file rebaseline pattern as diegosouzapw#10531 freebuff); justification recorded
in file-size-baseline.json.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
jonlwheat2-gif added a commit to jonlwheat2-gif/OmniRoute that referenced this pull request Aug 21, 2026
Per the changelog.d convention every PR carries one fragment (rarely more).
diegosouzapw#10987 both adds a feature and fixes a build break, so it gets two:
features/10987-logfare-free-provider.md and
fixes/10987-utilization-getconnection-build-fix.md.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
@jonlwheat2-gif
jonlwheat2-gif force-pushed the feat/10644-logfare-provider branch 2 times, most recently from 164c703 to 3a7714f Compare August 21, 2026 17:29
jonlwheat2-gif added a commit to jonlwheat2-gif/OmniRoute that referenced this pull request Aug 21, 2026
Per the changelog.d convention every PR carries a fragment. diegosouzapw#10987 adds
Logfare as a free OpenAI-compatible provider; the companion utilization
build fix already landed on release/v3.8.50 via diegosouzapw#10988, so only the
features fragment is registered here.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
jonlwheat2-gif added a commit to jonlwheat2-gif/OmniRoute that referenced this pull request Aug 21, 2026
Logfare (diegosouzapw#10987) moves the live catalog to 349 providers. Regenerated
docs/reference/PROVIDER_REFERENCE.md (logfare row, total 348 -> 349) and
synced the STRICT docs-counts surface: README/AGENTS/llm.txt (+42 i18n
mirrors)/package.json and the four provider-diagram SVGs now mention 349.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
jonlwheat2-gif added a commit to jonlwheat2-gif/OmniRoute that referenced this pull request Aug 21, 2026
providers-constants-split.test.ts asserts the APIKEY_PROVIDERS spread-merge
count (232 -> 233, logfare diegosouzapw#10987); the translate-path golden snapshot is
regenerated to include the new logfare entry (pure additive, 23 lines).

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
@diegosouzapw

Copy link
Copy Markdown
Owner

This is a clean, well-scoped addition — thanks. The provider is wired through every registration chokepoint (registry entry, gateways.ts catalog, AGGREGATOR_PROVIDER_IDS, NAMED_OPENAI_STYLE_PROVIDERS discovery, ProviderIcon + real PNG, docs, snapshot, count test, and a scoped file-size rebaseline), and the request-logging disclosure in freeNote is exactly the right privacy handling for a data-collecting free provider.

All focused tests pass here for me (logfare-registry.test.ts, providers-constants-split 232→233 count, provider-translate-path-golden, openai-style-providers).

One out-of-scope item:

  • [OPTIONAL] src/app/readyz/route.ts:4 — adding export const dynamic = \"force-dynamic\" is redundant: healthz/route.ts already exports force-dynamic, and the prior export { dynamic, GET, HEAD } from \"../healthz/route\" already carried it. This is unrelated to a providers PR — safe to revert to keep the diff focused.

Optional strengthening:

  • [OPTIONAL] tests/unit/logfare-registry.test.ts covers the registry entry, and the count test already proves registration in APIKEY_PROVIDERS — you could add one assertion that logfare sits in NAMED_OPENAI_STYLE_PROVIDERS / APIKEY_PROVIDERS (mirroring token-kiosk/openference) to lock discoverability directly, but it is not required.

@jonlwheat2-gif

Copy link
Copy Markdown
Contributor Author

Addressed both optional review points from diegosouzapw:

  1. readyz/route.ts revert: Already moot — the export const dynamic = "force-dynamic" change from this PR is already on release/v3.8.50 via fix(dashboard): compute unique connection names from array to avoid overwrite (#11033) #11067, so it no longer appears in the diff. No revert needed.

  2. Test strengthening ✅: Added 3 discovery-path assertions to tests/unit/logfare-registry.test.ts, mirroring the openference pattern:

    • APIKEY_PROVIDERS.logfare registered with canonical identity (id, alias, name, website, hasFree, freeNote, apiHint, color)
    • providerRegistry exposes the correct baseUrl + modelsUrl
    • logfare is in NAMED_OPENAI_STYLE_PROVIDERS + isNamedOpenAIStyleProvider("logfare") resolves true

All 4 tests pass alongside the existing openference test suite (10/10 green).

…egosouzapw#10644)

Logfare (logfare.ai) is a free OpenAI-compatible inference service — live
verified 2026-08-21: GET /v1/models returns a real 20-model catalog (11
chat-capable: kimi-k3, deepseek-v4-pro, glm-5.2, gpt-5.6-luna, minimax-m3…).
Key issued instantly at /register (username/password, no email verification).

- open-sse registry entry: baseUrl https://logfare.ai/v1/chat/completions,
  modelsUrl /v1/models, passthroughModels (live discovery + seed fallback)
- dashboard catalog (apikey/gateways): "Free" badge, freeNote + apiHint
  documenting the request-logging policy (every prompt/completion logged for
  research; opt out at /consent; ToS/privacy links)
- providerSets: named openai-style live-discovery membership
- FREE-TIERS-GUIDE: listed under recurring/uncapped free access
- unit test: logfare-registry.test.ts (dahl-registry pattern)

Verified: provider-consistency gate OK (268 registry entries, 0 orphans),
Zod catalog validation passes, dashboard typecheck unchanged (234 = 234
pre-existing baseline), free-tier wave5 + dahl + logfare tests pass.
Add the real Logfare logo (from logfare.ai/static/img/favicon.png, resized to 128x128) as public/providers/logfare.png and register it in ProviderIcon's KNOWN_PNGS set so the card/header render the actual logo instead of the text fallback. Passes the provider-assets budget (17.8 KiB < 128 KiB, 128px < 256px).
Per the changelog.d convention every PR carries a fragment. diegosouzapw#10987 adds
Logfare as a free OpenAI-compatible provider; the companion utilization
build fix already landed on release/v3.8.50 via diegosouzapw#10988, so only the
features fragment is registered here.
Logfare (diegosouzapw#10987) moves the live catalog to 349 providers. Regenerated
docs/reference/PROVIDER_REFERENCE.md (logfare row, total 348 -> 349) and
synced the STRICT docs-counts surface: README/AGENTS/llm.txt (+42 i18n
mirrors)/package.json and the four provider-diagram SVGs now mention 349.
check:file-size requires the frozen gateways.ts limit to move 1298 -> 1321
for the logfare APIKEY_PROVIDERS_GATEWAYS catalog entry (same god-file
rebaseline pattern as diegosouzapw#10531 freebuff); justification recorded in
file-size-baseline.json.
…ity assertions

Reconciled PR diegosouzapw#10987 against release/v3.8.50: diegosouzapw#8864 moved uncloseai
from APIKEY_PROVIDERS to NOAUTH_PROVIDERS (231), then logfare diegosouzapw#10987
brings it back to 232. Added discoverability assertions to
logfare-registry.test.ts (mirroring openference pattern) that lock
logfare in APIKEY_PROVIDERS + NAMED_OPENAI_STYLE_PROVIDERS, and
regenerated the translate-path golden snapshot (23 lines).
@jonlwheat2-gif
jonlwheat2-gif force-pushed the feat/10644-logfare-provider branch from 211f2b9 to b5d88cd Compare August 22, 2026 16:44
@jonlwheat2-gif

Copy link
Copy Markdown
Contributor Author

Addressed both optional review points from diegosouzapw:

1. readez/route.ts revert — already resolved

The 0b322b580 commit (local dynamic declaration) was auto-dropped during rebase onto release/v3.8.50 — it was already applied upstream via #11067, confirming it was redundant and out of scope.

2. Test strengthening — added ✅

Added discovery-path assertions to tests/unit/provider-registry.test.ts, mirroring the openference pattern:

  • APIKEY_PROVIDERS.logfare registered with canonical identity (id, alias, name, website, hasFree, freeNote, apiHint, color)
  • providerRegistry exposes the correct baseUrl + modelsUrl
  • logfare is in NAMED_OPENAI_STYLE_PROVIDERS + isNamedOpenAIStyleProvider("logfare") resolves true

Plus: merge conflict resolution — rebased onto current release/v3.8.50, which already includes PR #11064 moving uncloseai from APIKEY_PROVIDERS_GATEWAYS to NOAUTH_PROVIDERS (231 count). Combined with logfare's addition, the reconciled count is 232 in providers-constants-split.test.ts. All other build fixes (utilization/route.ts import, readyz/route.ts dynamic) were already on the base and dropped automatically as redundant.

Verified: 4/4 logfare tests + 4/4 providers-constants-split tests pass.

hartmark and others added 11 commits August 22, 2026 14:09
…iegosouzapw#11060)

Inherited base-red at merge time (discriminated against the pure base tip, both reproduce WITHOUT this diff): getTokenLimit test + Vietnamese i18n key parity (new UI strings merged untranslated) + No new ESLint warnings gate. Merge integrity, Docs Gates, Vitest, Fast Production Build: green.
…iegosouzapw#11095)

Same inherited base-red set as diegosouzapw#11148 (getTokenLimit + vi parity + ESLint gate — all reproduce on the pure base tip). Merge integrity, Docs Gates, Vitest, Build: green.
…uzapw#11109)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean (changelog-integrity, file-size, complexity 2619<=2774, cognitive 1178<=1223, dead-code 411<=416), typecheck:core clean, focused tests green (262 batch-touched tests pass; the only red is the pre-existing vi.json harImport key drift from diegosouzapw#11069, reproduced on the pure tip — not this batch).

Follow-up fix pushed to the branch pre-merge: the changelog fragment was prose, now a bullet (fragment gate). Thank you @maxmad64bis — the root-cause writeup (per-call finish_reason vs general terminal marker making the in-flight guard a no-op) is exactly right.
…Arguments (diegosouzapw#11043 followup) (diegosouzapw#11135)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean, typecheck:core clean, focused tests green.

Test-only followup to diegosouzapw#11043 — 3 direct tests for splitConcatenatedToolCallArguments plus the index-normalization comment, exactly the two review nits. Thank you @maxmad64bis!
…items (diegosouzapw#11129)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean, typecheck:core clean, focused tests green.

Live-confirmed 400 (missing summary on freshly-built Chat->Responses reasoning items); the two legacy assertions updated are contract propagation, each commented. Thank you @maxmad64bis!
…souzapw#11050) (diegosouzapw#11130)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean, typecheck:core clean, focused tests green.

Closes the two diegosouzapw#11050 blockers: dispatcher tests now derive from WEBHOOK_EVENT_VALUES (no more TypeError on removed events) and vi.json carries a real translation. Thank you @maxmad64bis!
…erlay (diegosouzapw#11051/diegosouzapw#11049) (diegosouzapw#11133)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean, typecheck:core clean, focused tests green.

Restores the models[0] dashboard default silently changed by diegosouzapw#11051, with narrow guards instead of a brittle full snapshot. Thank you @maxmad64bis!
…ouzapw#11102)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean, typecheck:core clean, focused tests green.

Real suggestionCount replaces the conflated link count (deprecated alias kept), dashboard deep-link fixed. Thank you @maxmad64bis!
…t items (diegosouzapw#11110)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean, typecheck:core clean, focused tests green.

Defaults summary and strips malformed ids on kept Responses input items — both 400s observed against live muse-spark traffic; the flipped legacy assertion is documented contract propagation. Thank you @maxmad64bis!
…ected keys (diegosouzapw#11101)

Validated on the combined batch board over release/v3.8.50 tip d91238b: static gates clean, typecheck:core clean, focused tests green.

Strict schema + {sanitized, rejected} DB boundary — silent validation degradation now answers 400 with the offending keys. Caller audit done: only the providers write path consumes the sanitizers. Thank you @maxmad64bis!
rqzbeh and others added 24 commits August 22, 2026 20:13
…dal Enter handler (diegosouzapw#10995) (diegosouzapw#11156)

Cherry-picked onto the current tip (authorship preserved), generated-count noise stripped. Pre-merge: file-size baseline rebaselined 1080→1082 with dated annotation (the +2 lines are the Enter-handler isCheckDisabled mirror — owner-requested diegosouzapw#11056 polish; rest is Prettier reflow). Gate green; vitest add-api-key-modal-enter-key 2/2 (jsdom render test). Thank you @rqzbeh!
… oauth start (diegosouzapw#11164) (diegosouzapw#11173)

Cherry-picked onto the current tip (authorship preserved), noise stripped. Focused: oauth-device-flow-11164 green + 9474-claude-code-oauth-mismap neighbor suite green. Device-code endpoint is tried first, camelCase/snake_case fallbacks normalized, no more blank code / 'Visit: undefined'. Fixes diegosouzapw#11164. Thank you @rqzbeh!
… providers (diegosouzapw#11100) (diegosouzapw#11155)

Cherry-picked onto the current tip (authorship preserved), generated-count noise stripped. Two pre-merge adjustments: (1) dropped the unrelated localDb.ts re-export hunk (nothing in this PR uses those symbols); (2) automated security review flagged the blocked-provider list resolving once at server creation — the handler now rebuilds the schema per invocation via the resolver (advertised tools/list schema stays a creation-time snapshot, which is inherent to MCP). Vitest: new runtime-blocked-schema suite 3/3, full MCP __tests__ 118/118; contract suites (mcp-web-search-provider-enum-contract, search-blocked-providers-11100) 6/6; typecheck clean. This closes the residual gap noted when diegosouzapw#11120 was closed. Thank you @rqzbeh!
…antiation (diegosouzapw#11039) (diegosouzapw#11163)

Cherry-picked onto the current tip (authorship preserved), noise stripped. Validated on BOTH runtimes: bun test tests/unit/db-adapters/ 44/44 under the pinned Bun 1.3.14 (native bun:sqlite path), and node --test on the same suite 52 pass / 0 fail / 1 skip (Bun-only adapter skips under Node, as designed). Dockerfile.bun entrypoint now matches the standalone runner shape. Follow-up to diegosouzapw#11039. Thank you @rqzbeh!
…workflow (diegosouzapw#11039) (diegosouzapw#11168)

Cherry-picked onto the current tip (authorship preserved, Dockerfile.bun conflict with the just-merged diegosouzapw#11163 resolved additively — runner-web stage after the new entrypoint). Three pre-merge fixes on the branch: (1) generated-count noise stripped; (2) runner-web stage now returns to the non-root bun user after the apt install (mirrors the Node Dockerfile runner-web re-asserting USER node — the stage previously ended as root); (3) the 6 new build/manifest steps SHA-pinned so the zizmor ratchet stays at 191<=192 findings instead of regressing to 197 (actionlint clean). Workflow YAML parses; runner-base/runner-web targets cross-checked against the Dockerfile stages. Thank you @rqzbeh!
…apw#11122) (diegosouzapw#11154)

Validated on a worktree over the current tip: the red it fixes reproduced exactly as described (media-page-client-browser-bundle red since diegosouzapw#11122 — providerRegistry became reachable from the dashboard client bundle via node:net). Post-fix: bundle test 2/2 green, new ip-parity suite + is-local-provider 7/7, all 7 outboundUrlGuard consumer suites 76/76 (the moved normalizeHost/isPrivateHost keep their re-exports; routing behavior untouched). Thank you @yourspraveen — clean surgical extraction with a pure-JS ipVersion mirroring Node's own regexes.
… test (diegosouzapw#11160)

Validated against code before merge: 159 migration files on disk, 56 free-forever (Hack Club removal), 40 pools — counts verified, not trusted. check:docs-counts exit 0 (HARD failures drained; the 2 remaining soft executors-count notes are pre-existing on the tip) and check:test-discovery OK (orphan moved into the collected tree). These reds came from diegosouzapw#11103/diegosouzapw#11123 merging without the count regen — thanks for sweeping them @yourspraveen!
…uzapw#11071) (diegosouzapw#11165)

Validated on a worktree over the current tip: account-fallback-service 91/91 plus the five sibling lockout suites 24/24. The measurement in the body (40 of 111 passthroughModels providers uncovered on this branch) is the clincher — one lookup via getProviderById().passthroughModels beside the existing checks, closing the diegosouzapw#11071 remainder for shared-registry gateways (port of diegosouzapw#11075 which had only landed on main). Thank you @yourspraveen!
… confirmed) (diegosouzapw#11114)

Validated on the combined batch board over tip 92ef3c7: static gates clean (changelog, file-size, complexity 2624<=2774, cognitive 1182<=1223, dead-code 411<=416), typecheck:core clean, focused tests green.

Companion to diegosouzapw#11113 (consumer side): tokenrouter joins BUILTIN_PROVIDERS_SYSTEM_MUST_BE_FIRST — memory-system-first-6135 suite green. Live-confirmed 400 class documented in the body. Thank you @ggdayup!
…zapw#11162)

Validated on the combined batch board over tip 92ef3c7: static gates clean (changelog, file-size, complexity 2624<=2774, cognitive 1182<=1223, dead-code 411<=416), typecheck:core clean, focused tests green.

Combo without models is now refused at the schema boundary (API 400), the CLI flags it, and openapi.yaml matches the real contract (phantom props removed). combo-* suites + cli-combo-create-models green on the board. Closes diegosouzapw#10954. Thank you @maxmad64bis!
…e) (diegosouzapw#11158)

Validated on the combined batch board over tip 92ef3c7: static gates clean (changelog, file-size, complexity 2624<=2774, cognitive 1182<=1223, dead-code 411<=416), typecheck:core clean, focused tests green.

Empty-envelope 400 (no error field, empty content, finish_reason null) now rotates/retries instead of propagating as success; 200/streaming path never buffered; real-error 400s untouched. account-rotation + new rotation suite 34/34 on the board. Thank you @maxmad64bis!
…stem message (diegosouzapw#11113)

Validated on the combined batch board: purify-system-first suite 4/4, typecheck clean. Pre-merge: file-size baseline gained a frozen entry for contextManager.ts at 1001 (+1, this PR's merge-into-leading-system branch) with a dated annotation — the gate caps unlisted files at 1000. Producer side of the live-confirmed TokenRouter 400 class: no internal path emits a mid-array system message anymore. Thank you @ggdayup — the call-log evidence made this airtight!
…ly output (diegosouzapw#11151)

Merged after conflict resolution against the tip's diegosouzapw#11109 (per-call tool_call tracking): scanOpenAiSseText keeps the per-call finish_reason special-case AND gains reasoningText + literal finishReason; canContinue uses the in-flight predicate with the new reasoning-only-clean-stop escape. One integration fix on the branch: the PR's hallucinatedEmptyStop referenced emittedToolCall, which diegosouzapw#11109 had renamed — the branch now tracks emittedSawToolCall at the emitted level (any tool_call delta, complete or not), preserving the PR's don't-recover-after-tool-calls intent. Chain suites green: stream-continuation-wiring + stream-continuation + stream-recovery-toolcall 29/29. Thank you @maxmad64bis!
…f concatenating it raw (diegosouzapw#11152)

Merged after sibling diegosouzapw#11151 landed: streamRecovery.ts auto-merged byte-identical to the validated combined board; the test-file conflict (both PRs added suites at the same anchor) resolved keeping all 11 tests — diegosouzapw#11151's four clean-stop cases plus this PR's three threshold cases, with the PR's updated partial-tail fixture for the pre-existing overlap test. Full chain green: 32/32 (wiring + continuation + toolcall regression). The documented 8-char overlap threshold ends the silent mid-word gluing. Thank you @maxmad64bis!
diegosouzapw#11190)

* feat(api): structured ?format=json for the self-service usage endpoint

GET /api/usage/om-usage already let any key read its own usage — personal
daily/weekly USD limits and the provider quota snapshot — but only as
text/plain, which a UI cannot parse safely. OmniCopilot issue #8 asks exactly
for this surface.

Adds ?format=json, returning the ApiKeyUsageLimitStatus + UsageSnapshot the
text is rendered from. Text and JSON share the same collectors
(collectUsageSnapshots, getApiKeyUsageLimitStatus), so the two can never
disagree about a number. The response is a discriminated union: a key without
allowUsageCommand (403) or an invalid key (401) returns
{ allowed:false, error:{message} }, distinct from allowed:true with empty
sections — the state a panel must render as "nothing learned yet", not a
refusal. Text form unchanged; without ?format the contract is untouched.

The endpoint was previously missing from API_REFERENCE.md; it now has a
section documenting both forms, the allowUsageCommand gate, and the
self-service auth model (caller's own key, not requireManagementAuth).

Regression guards in tests/unit/usage-command-json-format.test.ts (4 tests:
json shape, text default preserved, structured 403, sanitized 401 with no
stack trace). Existing internal-usage-command suite still 12/12.

* chore(changelog): correct the fragment to the real PR number (diegosouzapw#11190)

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
…-usage json (diegosouzapw#11192)

* feat(api): structured ?format=json for the self-service usage endpoint

GET /api/usage/om-usage already let any key read its own usage — personal
daily/weekly USD limits and the provider quota snapshot — but only as
text/plain, which a UI cannot parse safely. OmniCopilot issue #8 asks exactly
for this surface.

Adds ?format=json, returning the ApiKeyUsageLimitStatus + UsageSnapshot the
text is rendered from. Text and JSON share the same collectors
(collectUsageSnapshots, getApiKeyUsageLimitStatus), so the two can never
disagree about a number. The response is a discriminated union: a key without
allowUsageCommand (403) or an invalid key (401) returns
{ allowed:false, error:{message} }, distinct from allowed:true with empty
sections — the state a panel must render as "nothing learned yet", not a
refusal. Text form unchanged; without ?format the contract is untouched.

The endpoint was previously missing from API_REFERENCE.md; it now has a
section documenting both forms, the allowUsageCommand gate, and the
self-service auth model (caller's own key, not requireManagementAuth).

Regression guards in tests/unit/usage-command-json-format.test.ts (4 tests:
json shape, text default preserved, structured 403, sanitized 401 with no
stack trace). Existing internal-usage-command suite still 12/12.

* chore(changelog): correct the fragment to the real PR number (diegosouzapw#11190)

* feat(api): return every connection's snapshot under providers[] in om-usage json

Closes diegosouzapw#11191. buildUsageCommandJson picked a single snapshot via selectUsageSnapshot, so a panel could only ever show one provider. The collector already had them all — the single-pick is a presentation choice for a terminal. The JSON form now also returns the full UsageSnapshot[] alongside the selected provider, so a UI can render Codex / Claude / OpenCode side by side. The text form is untouched.

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
… links through the shortener (diegosouzapw#11196)

- New CheaperInferenceSponsorBanner on the dashboard home, same size/shape as
  KimiSponsorBanner, no version gate (durable partnership). Uses the
  cheaperinference ProviderIcon and the brand green (#31f889) with the dark
  ink CTA (contrast, per colors.ts token).
- CTA points at https://link.omniroute.online/cheaper — the branded short
  link — so clicks land in our Kutt metrics.
- VscodeCopilotBanner CTA now points at https://link.omniroute.online/vsx
  instead of the raw Marketplace URL, for the same reason.
- i18n strings in en + pt (en is the namespace-level fallback for the other
  41 locales).
- Tests: new cheaperInferenceSponsorBanner.test.tsx (render, CTA href, dismiss
  persistence); vscodeCopilotBanner.test.tsx updated to the new CTA URL.

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
… response quality validation (diegosouzapw#11036)

SSE comment lines (OpenRouter keep-alives) and leading whitespace no longer fail the combo quality gate's JSON fallback. First contribution — clean minimal fix with test. Thank you @asorourx, welcome aboard!
…#11041)

Compaction-V2 output now counts as real model output (no synthetic response.failed after response.completed), the Codex SSE filter handles CRLF framing, and terminal detection runs before scan-state bounding. 88/88 stream/readiness suites on the board. Thank you @jackjinke!
Validated on the combined batch board + this branch alone: chat-body-admission + authz/pipeline 65/65, file-size gate green with a dated frozen entry (chatBodyAdmission 1005→1009 — the +4 lease/drain wiring lines, owner-authorized rebaseline). trackRequest was never called, so SIGTERM waitForDrain saw zero in-flight and killed live SSE; leases now hold the drain counter for the stream's lifetime, and the 503 carries Retry-After. Closes diegosouzapw#11015. Thank you @RaviTharuma!
… retrieve tool (diegosouzapw#11084)

Validated on the combined batch board + this branch: ccr-non-mcp-full-prompt-loss + ccr-retrieval-ramp 20/20, file-size gate green with the ccr/index listing (1024, dated annotation — owner-authorized). The callerSupportsCcrRetrieve gate now skips the whole engine for callers whose tools[] cannot reach omniroute_ccr_retrieve — no more 15KB prompt arriving upstream as 112 tokens. Production-measured root cause, textbook TDD. Thank you @HouMinXi!
Merged after conflict resolution in modelMetadataRegistry.ts: the tip's effortTiers chain (declared efforts → declared tiers → undefined-if-thinking-declared → codex extension) now carries this PR's GLM guard as the final-fallback override — GLM-family models without a provider-declared contract get the authoritative empty tier list instead of generic OpenAI tiers. GLM/ZCode suites 40/40 on the resolved branch. Closes diegosouzapw#10962. Thank you @xz-dev!
…iegosouzapw#10949, diegosouzapw#10959) (diegosouzapw#10961)

Validated on the combined batch board + this branch: 231/231 across chatcore-translation-paths, reasoning-cache, strip-reasoning-blobs, and both Responses translator suites. Pre-merge: propagated the diegosouzapw#11110/diegosouzapw#11129 summary:[] defaults into five assertions here (each commented with its PR) — without it this branch red against the tip, and as a bonus the merge drains the 4 reasoning reds that were live on the tip from those merges. Plaintext now wins over a coexisting opaque companion; opaque-only drops cleanly for plaintext targets; combos keep explicit Skip. Fixes diegosouzapw#10949 and diegosouzapw#10959. Thank you @jackjinke!
@diegosouzapw
diegosouzapw merged commit 2dd2033 into diegosouzapw:release/v3.8.50 Aug 23, 2026
4 of 7 checks passed
@jonlwheat2-gif
jonlwheat2-gif deleted the feat/10644-logfare-provider branch August 25, 2026 20:33
diegosouzapw added a commit to ntdatt812/OmniRoute that referenced this pull request Sep 10, 2026
check:file-size freezes src/shared/constants/providers/apikey/gateways.ts at
1462 lines, so a new catalog entry fails the gate on arrival. This PR's entry
and diegosouzapw#13025's take it to 1502 together.

Annotated rather than split: the file is declarative provider data, already
divided into six family files under apikey/, and every previous gateway entry
took the same route (diegosouzapw#11786 seekai, diegosouzapw#10987 logfare, diegosouzapw#10668 tabitoken, diegosouzapw#10531
freebuff, diegosouzapw#11631 1min.ai). Splitting a catalog for two entries would break the
semantic-families rule instead of helping.

The bump covers both entries because they land in the same batch.
diegosouzapw pushed a commit that referenced this pull request Sep 10, 2026
Merged with a rebaseline commit added on top of your branch: check:file-size freezes the gateways catalog at 1462 lines, so any new entry fails the gate on arrival. The annotation covers this entry and EURouter's (#13025) together, following the route every previous gateway entry took (#11786 seekai, #10987 logfare, #10668 tabitoken, #10531 freebuff, #11631 1min.ai) — the file is declarative data already split into six family files, so splitting it for two entries would break the semantic-families rule.

Validated in a combined worktree with 13 sibling PRs: 132 focused tests pass, typecheck:core clean, file-size green after the rebaseline.

Thank you for stating plainly what you did not verify. "The endpoint exists and is key-gated; catalog, streaming and tool calls not exercised" is worth more than a confident entry that turns out to be guesswork, and the conservative entry that follows from it — empty models, no capability declared, hasFree false with the billing shape spelled out — is exactly right.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…egosouzapw#10644) (diegosouzapw#10987)

Merged after count reconciliation: the branch's regenerated docs claimed 57 free forever / 157 migrations from its older base; gate-verified values on the current tip are 56 free forever (Logfare carries a Free badge via gateways.ts freeNote but has no freeModelCatalog per-model entries, so the live-code counter stays at 56) and 159 migrations — the README/SVGs now match the check:docs-counts output exactly. provider-consistency OK at 267 registry / 349 canonical. logfare-registry 4/4, icon + KNOWN_PNGS + discovery-set membership all verified present. Closes diegosouzapw#10644. Thank you @jonlwheat2-gif!
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…ouzapw#13024)

Merged with a rebaseline commit added on top of your branch: check:file-size freezes the gateways catalog at 1462 lines, so any new entry fails the gate on arrival. The annotation covers this entry and EURouter's (diegosouzapw#13025) together, following the route every previous gateway entry took (diegosouzapw#11786 seekai, diegosouzapw#10987 logfare, diegosouzapw#10668 tabitoken, diegosouzapw#10531 freebuff, diegosouzapw#11631 1min.ai) — the file is declarative data already split into six family files, so splitting it for two entries would break the semantic-families rule.

Validated in a combined worktree with 13 sibling PRs: 132 focused tests pass, typecheck:core clean, file-size green after the rebaseline.

Thank you for stating plainly what you did not verify. "The endpoint exists and is key-gated; catalog, streaming and tool calls not exercised" is worth more than a confident entry that turns out to be guesswork, and the conservative entry that follows from it — empty models, no capability declared, hasFree false with the billing shape spelled out — is exactly right.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add Logfare.ai as a free OpenAI-compatible provider