Skip to content

Commit e6b235b

Browse files
committed
fix(website): wrap the timeline, run integrations as a reel, fix blog cards
The timeline set six 15rem columns in a flex row with overflow-x:auto, which needs 90rem and so scrolled sideways on any normal laptop. It is a wrapping grid now, and the rule that carries the dots moves from the container onto each item so a wrapped row still gets a line above it. Column gap is zero and the items carry their own right padding, so the rule stays continuous. Integrations move from a card grid to a reel. Any single integration is a weak signal and the whole moving line is the strong one, so the count is doing the argument. It pauses on hover and on keyboard focus, since the names are links. The list grows from 8 to 26: Open WebUI, Dify, LibreChat, RAGFlow, Continue, big-AGI, Nextcloud, Frigate, promptfoo, Mods, TypingMind, baibot, k8sgpt- operator and others. Each was admitted only after opening that project's own repository or docs and reading the line that names LocalAI. The ones that failed that test are listed in the data file so nobody re-adds them. The blog cards were hand-written, which is how one of them came to advertise "Porting vLLM to C++", a post that does not exist, and how all three linked to the blog index instead of an article. They range over the posts now. The section intro used the "a changelog tells you what moved, these posts show you what it does" shape, which is the standard machine-written antithesis. It states what the posts contain instead, including the perplexity regression that APEX costs, because publishing the price is the actual claim. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude Code:claude-opus-5[1m]
1 parent 0bedc75 commit e6b235b

3 files changed

Lines changed: 126 additions & 29 deletions

File tree

website/data/ecosystem.yaml

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,35 +55,107 @@ contributors:
5555

5656
integrations:
5757
note: "These projects reference LocalAI in their own repository or documentation."
58+
# Admission rule: the project's OWN repository or official docs must name
59+
# LocalAI as a provider, backend or integration. A blog post saying so is not
60+
# enough, and neither is a generic "any OpenAI-compatible server" line that
61+
# never names us. Every entry below was opened and read before being added,
62+
# and the quote that justifies it is in the pull request that added it.
63+
#
64+
# Deliberately excluded after checking: LiteLLM, n8n, Home Assistant core,
65+
# BionicGPT, Semantic Kernel, Spring AI, Jan, CrewAI, Haystack, Onyx,
66+
# SillyTavern, Portkey and Kong all have zero mentions in their own repos.
67+
# PrivateGPT and Langflow name us only in passing comparisons or a tooltip.
68+
# Tools4AI has a LocalAI processor whose methods return null.
5869
projects:
5970
- name: AnythingLLM
6071
by: Mintplex Labs
6172
url: https://github.com/Mintplex-Labs/anything-llm
6273
what: "Runs LocalAI as a model provider for its chat and document workspaces."
63-
- name: langchain4j
64-
url: https://github.com/langchain4j/langchain4j
65-
what: "Ships a LocalAI module, so JVM applications can target it directly."
6674
- name: LangChain
6775
url: https://python.langchain.com/docs/integrations/providers/localai/
6876
what: "Documents LocalAI as a provider in the Python integrations."
77+
- name: LlamaIndex
78+
url: https://docs.llamaindex.ai/en/stable/examples/llm/localai/
79+
what: "Documents LocalAI as an OpenAI-compatible LLM you can point it at."
80+
- name: Open WebUI
81+
url: https://docs.openwebui.com/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible
82+
what: "Connects to LocalAI as an OpenAI-compatible local server."
83+
- name: Dify
84+
by: LangGenius
85+
url: https://marketplace.dify.ai/plugin/langgenius/localai
86+
what: "Ships an official LocalAI plugin for inference and embeddings."
87+
- name: LibreChat
88+
url: https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/speech
89+
what: "Uses LocalAI as a speech provider for text to speech."
90+
- name: RAGFlow
91+
by: InfiniFlow
92+
url: https://ragflow.io/docs/supported_models
93+
what: "Lists LocalAI as a model provider, and ships a driver for it including rerank."
6994
- name: Flowise
7095
by: FlowiseAI
7196
url: https://github.com/FlowiseAI/Flowise
7297
what: "Offers LocalAI as a node for chat and embeddings in its visual builder."
73-
- name: AIKit
74-
by: Sertac Ozercan
75-
url: https://github.com/sozercan/aikit
76-
what: "Builds fine-tuned models into images that serve through LocalAI."
98+
- name: Continue
99+
url: https://docs.continue.dev/customize/model-providers/top-level/openai
100+
what: "Lists LocalAI among the OpenAI-compatible providers the editor can target."
101+
- name: big-AGI
102+
url: https://github.com/enricoros/big-AGI/blob/main/docs/config-local-localai.md
103+
what: "Adds LocalAI as a model source, with its own setup page and env vars."
77104
- name: K8sGPT
78105
by: CNCF Sandbox
79106
url: https://docs.k8sgpt.ai/reference/providers/backend/
80107
what: "Lists LocalAI as an analysis backend, alongside Bedrock and Azure OpenAI."
81-
- name: LlamaIndex
82-
url: https://docs.llamaindex.ai/en/stable/examples/llm/localai/
83-
what: "Documents LocalAI as an OpenAI-compatible LLM you can point it at."
108+
- name: k8sgpt-operator
109+
by: k8sgpt-ai
110+
url: https://github.com/k8sgpt-ai/k8sgpt-operator
111+
what: "Sets LocalAI as the backend on the K8sGPT custom resource, with no OpenAI secret."
112+
- name: Nextcloud
113+
url: https://apps.nextcloud.com/apps/integration_openai
114+
what: "Points its text, image and speech features at a self-hosted LocalAI."
115+
- name: Frigate
116+
url: https://github.com/blakeblackshear/frigate/blob/dev/docs/docs/configuration/genai/config.md
117+
what: "Names LocalAI as a server for its generative AI features."
118+
# Present in the dev branch docs source; not yet on the published site.
84119
- name: Kairos
85120
url: https://github.com/kairos-io/kairos
86121
what: "Ships LocalAI as part of its immutable Linux distribution."
122+
- name: AIKit
123+
by: Sertac Ozercan
124+
url: https://github.com/sozercan/aikit
125+
what: "Builds fine-tuned models into images that serve through LocalAI."
126+
- name: langchain4j
127+
url: https://github.com/langchain4j/langchain4j
128+
what: "Ships a LocalAI module, so JVM applications can target it directly."
129+
- name: promptfoo
130+
url: https://www.promptfoo.dev/docs/providers/localai/
131+
what: "Provides a localai: prefix so evals run against chat, completion and embeddings."
132+
- name: Mods
133+
by: Charm
134+
url: https://github.com/charmbracelet/mods
135+
what: "Reads a LocalAI endpoint from its config, so the CLI pipes shell output to a local model."
136+
- name: TypingMind
137+
url: https://docs.typingmind.com/manage-and-connect-ai-models/local-ai
138+
what: "Documents pointing a custom model endpoint at a LocalAI server."
139+
- name: baibot
140+
by: etke.cc
141+
url: https://github.com/etkecc/baibot/blob/main/docs/providers.md
142+
what: "Has a first-class localai provider for text, speech to text and text to speech."
143+
- name: LLM Vision
144+
by: Home Assistant
145+
url: https://github.com/valentinfrlch/ha-llmvision
146+
what: "Lists LocalAI as a provider for analysing camera images and video feeds."
147+
- name: VoxInput
148+
url: https://github.com/richiejp/VoxInput
149+
what: "Sends desktop voice input to LocalAI for transcription and a realtime assistant."
150+
- name: Obsidian BMO Chatbot
151+
url: https://github.com/longy2k/obsidian-bmo-chatbot
152+
what: "Lists LocalAI as a self-hosted endpoint for the note-taking chat plugin."
153+
- name: ShellOracle
154+
url: https://github.com/djcopley/ShellOracle
155+
what: "Ships a LocalAI provider for turning natural language into shell commands."
156+
- name: QA-Pilot
157+
url: https://github.com/reid41/QA-Pilot
158+
what: "Runs its repository chat against a LocalAI base URL."
87159

88160
press:
89161
note: "Written about LocalAI, by people who do not work on it."

website/layouts/index.html

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -429,14 +429,22 @@ <h3 class="eco__h rv">{{ .Site.Params.contributors }} people have put code in th
429429
<p class="eco__names rv">Some of them do it from a desk at {{ delimit $co ", " " and " | safeHTML }}.
430430
Others from labs at {{ delimit $ac ", " " and " | safeHTML }}.</p>
431431
<p class="eco__note rv">That is where they work, not who sent them.
432-
<a href="{{ .Site.Params.github }}/graphs/contributors">The commit history is public &#8599;</a></p>
432+
<a href="{{ .Site.Params.github }}/graphs/contributors">Check out the full contributor list, 200+ and growing &#8599;</a></p>
433433

434-
<h3 class="eco__h rv mt3">And these projects integrate it</h3>
435-
<p class="eco__note rv">Each one names LocalAI in its own repository or documentation.</p>
436-
<div class="eco eco--int rv">
437-
{{- range .Site.Data.ecosystem.integrations.projects }}
438-
<a href="{{ .url }}"><b>{{ .name }}</b>{{ with .by }}<em>{{ . }}</em>{{ end }}<span>{{ .what }}</span></a>
439-
{{- end }}
434+
{{/* The list runs as a marquee because the count is the argument: any one
435+
of these is a weak signal, and the whole moving line is the strong one.
436+
It pauses on hover so the links stay usable. */}}
437+
<h3 class="eco__h rv mt3">And many projects integrate it</h3>
438+
<p class="eco__note rv">Click any name to see where they say so.</p>
439+
<div class="reel reel--int rv">
440+
<div class="reel__t">
441+
{{- range .Site.Data.ecosystem.integrations.projects }}
442+
<a href="{{ .url }}">{{ .name }}</a>
443+
{{- end }}
444+
{{- range .Site.Data.ecosystem.integrations.projects }}
445+
<a href="{{ .url }}" tabindex="-1" aria-hidden="true">{{ .name }}</a>
446+
{{- end }}
447+
</div>
440448
</div>
441449
<p class="eco__aside rv">Using LocalAI at work? Add your organisation to
442450
<a href="{{ .Site.Params.github }}/blob/master/ADOPTERS.md">ADOPTERS.md</a>.</p>
@@ -491,15 +499,17 @@ <h3 class="eco__h rv mt3">Written about elsewhere</h3>
491499
<div class="shell">
492500
<div class="bars rv" aria-hidden="true"><i></i><i></i><i></i><i></i></div>
493501
<p class="kicker rv">From the team</p>
494-
<h2 class="rv mt1" style="max-width:20ch">Every release gets written up and demonstrated.</h2>
495-
<p class="lede rv mt2">A changelog tells you what moved. These posts show you what it does, with a recording you can watch and a command you can run.</p>
502+
<h2 class="rv mt1" style="max-width:22ch">We publish the numbers, including the ones that cost us.</h2>
503+
<p class="lede rv mt2">APEX takes a 35B model from 64.6 GB to 12.2 GB, and from 30.4 to 74.4 tokens a second. Perplexity goes from 6.537 to 7.088. That trade is in the post too, with the command that produced it.</p>
504+
{{/* Pulled from the posts themselves. The cards used to be hand-written,
505+
which is how one of them ended up advertising a post that did not
506+
exist, and how all three linked to the index instead of the article. */}}
496507
<div class="cards">
497-
<a class="cd rv" href="/blog/"><p class="cd__k">Release · v4.8.0</p><h3>What landed in LocalAI 4.8</h3>
498-
<p>The audio.cpp backend, Valkey vector search, configurable VAE tiling, and a faster realtime path.</p><span class="cd__go">Read the post →</span></a>
499-
<a class="cd rv" href="/blog/"><p class="cd__k">Engineering</p><h3>Porting vLLM to C++</h3>
500-
<p>What paged attention looks like without a Python runtime, and what it cost us to get there.</p><span class="cd__go">Read the post →</span></a>
501-
<a class="cd rv" href="/blog/"><p class="cd__k">Benchmarks</p><h3>How APEX beats Q8_0 at a third of the size</h3>
502-
<p>Per-tensor, per-layer precision for mixture-of-experts models, measured against the alternatives.</p><span class="cd__go">Read the post →</span></a>
508+
{{- range first 3 (where .Site.RegularPages "Section" "blog") }}
509+
<a class="cd rv" href="{{ .RelPermalink }}">
510+
<p class="cd__k">{{ .Date.Format "2 January 2006" }}</p><h3>{{ .Title }}</h3>
511+
<p>{{ .Params.summary | truncate 155 }}</p><span class="cd__go">Read the post →</span></a>
512+
{{- end }}
503513
</div>
504514
</div>
505515
</section>

website/static/css/site.css

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,15 @@ h2{font-size:clamp(2.1rem,5vw,3.9rem)}
288288
.reel span::before{content:"/ ";color:var(--cyan)}
289289
@keyframes roll{to{transform:translateX(-50%)}}
290290

291+
/* Integrations reel. Same motion as the engines reel, but the items are links,
292+
so it stops on hover or keyboard focus and the names stay clickable. */
293+
.reel--int .reel__t{animation-duration:64s}
294+
.reel--int:hover .reel__t,.reel--int:focus-within .reel__t{animation-play-state:paused}
295+
.reel--int a{font-family:'Geist Mono',monospace;font-size:.78rem;color:var(--dim);white-space:nowrap;
296+
transition:color .18s}
297+
.reel--int a::before{content:"/ ";color:var(--cyan)}
298+
.reel--int a:hover,.reel--int a:focus-visible{color:var(--ink)}
299+
291300
/* apex */
292301
.tw{overflow-x:auto;margin-top:2.2rem;border:1px solid var(--p-line);border-radius:8px;background:#fff}
293302
table{border-collapse:collapse;width:100%;min-width:640px;font-variant-numeric:tabular-nums}
@@ -344,10 +353,16 @@ tbody tr:hover td{background:rgba(95,205,228,.10)}
344353
letter-spacing:-.02em;color:var(--cyan);font-variant-numeric:tabular-nums}
345354
.big span{font-family:'Geist Mono',monospace;font-size:.58rem;letter-spacing:.11em;
346355
text-transform:uppercase;color:var(--faint)}
347-
.tl{margin-top:2.6rem;border-top:1px solid var(--line2);overflow-x:auto}
348-
.tl__t{display:flex;gap:0;min-width:min-content;padding-top:1.4rem}
349-
.tl__i{flex:0 0 15rem;padding:0 1.3rem 0 0;position:relative}
350-
.tl__i::before{content:"";position:absolute;left:0;top:-1.4rem;width:7px;height:7px;border-radius:50%;
356+
/* Six 15rem columns need 90rem, so the old flex row scrolled sideways on any
357+
normal laptop. It wraps into a grid instead, and the rule that carried the
358+
dots moves from the container onto each item so a wrapped row still gets a
359+
line above it. */
360+
.tl{margin-top:2.6rem}
361+
/* Zero column gap so the borders of adjacent items meet and the rule reads as
362+
one continuous line; the items carry their own right padding instead. */
363+
.tl__t{display:grid;grid-template-columns:repeat(auto-fit,minmax(13.5rem,1fr));gap:1.7rem 0}
364+
.tl__i{padding:1.4rem 1.3rem 0 0;position:relative;border-top:1px solid var(--line2)}
365+
.tl__i::before{content:"";position:absolute;left:0;top:0;width:7px;height:7px;border-radius:50%;
351366
background:var(--cyan);transform:translateY(-50%) scale(0);transition:transform .45s cubic-bezier(.16,1,.3,1)}
352367
.in .tl__i::before{transform:translateY(-50%) scale(1)}
353368
.tl__i:nth-child(1)::before{transition-delay:.05s}.tl__i:nth-child(2)::before{transition-delay:.13s}

0 commit comments

Comments
 (0)