feat(providers): add Logfare as a free OpenAI-compatible provider (#10644) - #10987
diegosouzapw merged 62 commits into
Conversation
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>
…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>
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>
164c703 to
3a7714f
Compare
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>
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>
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>
|
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 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 strengthening:
|
|
Addressed both optional review points from diegosouzapw:
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).
211f2b9 to
b5d88cd
Compare
|
Addressed both optional review points from diegosouzapw: 1. readez/route.ts revert — already resolvedThe 2. Test strengthening — added ✅Added discovery-path assertions to
Plus: merge conflict resolution — rebased onto current Verified: 4/4 logfare tests + 4/4 providers-constants-split tests pass. |
…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!
…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!
…e forever / 159 migrations)
2dd2033
into
diegosouzapw:release/v3.8.50
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.
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.
…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!
…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.
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
open-sse/config/providers/registry/logfare/index.tsbaseUrl/v1/chat/completions,modelsUrl/v1/models,passthroughModels: trueopen-sse/config/providers/index.tsREGISTRYsrc/shared/constants/providers/apikey/gateways.tsfreeNote+apiHintdocumenting the request-logging policy with ToS / privacy / consent linkssrc/shared/constants/providers.tsAGGREGATOR_PROVIDER_IDSsrc/app/api/providers/[id]/models/discovery/providerSets.ts/v1/modelscatalog)public/providers/logfare.png+ProviderIcon.tsxlogfare.ai/static/img/favicon.png) registered inKNOWN_PNGSdocs/getting-started/FREE-TIERS-GUIDE.mdtests/unit/logfare-registry.test.tsVerification
logfare.ai/v1/modelsreturned 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 orphansgetProviderById('logfare')resolves withhasFree: trueEnd-to-end (dev server + production build, real key)
logfare.ai/v1/modelskiro-autoanswered correctly with reasoning + real token usagechat.completion.chunkdeltas)Notes for reviewers
/v1/modelsis 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 401API key required). This is how Logfare is designed (public catalog, keyed inference) — not a bug in our integration./consent). Documented on the provider card and in the free-tiers guide, per the issue's request.kimi-k3/deepseek-v4-prowere intermittently returning 503 from Logfare's side during testing (their service, not ours) —kiro-autowas reliable.Separate base-branch build fix included
fix(dashboard): resolve missing getConnection import in utilization route—src/app/api/usage/utilization/route.tsimportedgetConnectionfrom@/lib/db/connections, a module that never existed (the import was added by #10939 without creating the file). This breaks any production build onrelease/v3.8.50. Fixed to use the realgetProviderConnectionByIdfrom@/lib/db/providers(same shape). Kept as a separate commit so it can be cherry-picked independently.