Ficelle
A local, OpenAI-compatible router that keeps your AI agents running, and never lets
them overspend. Point any OpenAI-compatible client at http://127.0.0.1:8646/v1
(nothing to import, no account) and your agent fails over across providers and can never
run up a surprise bill.
Ficelle sells reliability, not "free AI": it routes to free LLM capacity, fails over when a provider rate-limits or breaks, and enforces a strict-zero wall so it never makes a paid call.
Why Ficelle
- Reliability: multi-provider auto-fallback, per-reason cooldowns, and quota-recovery probes, so one provider's outage doesn't stop your agent.
- Strict-zero billing safety: paid fallback is hardcoded off; a model that tries to bill is auto-quarantined. No surprise invoices.
- Local control plane: the router, configuration, and stored API keys stay on your machine. Ficelle is not a hosted proxy; prompts are sent directly to the upstream provider you choose.
- OpenAI-compatible: drop-in
/v1/modelsand/v1/chat/completions, with stable virtual models (ficelle/auto-tools,ficelle/auto-json,ficelle/auto-reasoning,ficelle/auto-long, …).
What to route to free models
Free models are not a drop-in replacement for a frontier model on every task, and this
project does not pretend otherwise. Across a 76-task benchmark against gpt-5, free
routing was quality-safe (tied or better) on:
| Workload | Quality-safe | Virtual model |
|---|---|---|
| Classification, labelling, triage | 100% | ficelle/auto-fast |
| Structured extraction to JSON | 95% | ficelle/auto-json |
| Reasoning and code | 94% | ficelle/auto-reasoning |
| Polished long-form writing | 50% | keep your paid model |
Route the first three through Ficelle and keep the budget for the writing. Method and raw numbers: the benchmark write-up.
Quick start
Install the versioned open Core from its GitHub Release:
curl -fsSL https://raw.githubusercontent.com/TheBlueHouse75/ficelle-open-core/v0.1.8/scripts/bootstrap-ficelle.py | python3 -
~/.local/bin/ficelle doctor --text
The installer uses an isolated runtime and auto-detects Hermes; Ficelle remains fully standalone when Hermes is absent. To install Pro after purchase without putting the key in shell history, enter it silently before running the same command:
(
read -s FICELLE_LICENSE_KEY
export FICELLE_LICENSE_KEY
curl -fsSL https://raw.githubusercontent.com/TheBlueHouse75/ficelle-open-core/v0.1.8/scripts/bootstrap-ficelle.py | python3 -
)
Add a provider key — nothing routes without one
Ficelle routes with your provider accounts and ships no keys of its own, so a fresh install cannot serve a single completion until you store one. It prompts for the key with hidden input and keeps it out of your shell history:
ficelle set-key openrouter # create a key at https://openrouter.ai/keys
ficelle set-key nous # create a key at https://portal.nousresearch.com/
One is enough; Ficelle fails over across whichever providers you have configured.
Keys stay on your machine, in your OS secret store or ~/.ficelle/.env.
ficelle models reads the providers' public catalogs, which they serve without
credentials — so a long model list does not mean a request can be served.
ficelle doctor --text reports which providers are actually configured:
ficelle doctor --text
ficelle health
curl -s http://127.0.0.1:8646/admin/status.json | python3 -m json.tool
Point your client at http://127.0.0.1:8646/v1.
The local endpoint works with the OpenAI client without a hosted Ficelle account:
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8646/v1",
api_key="ficelle-local",
)
See the failover, without waiting for an outage
ficelle demo
Sends one real completion with the model that was about to answer forced to fail, and shows what happens next:
Only the outage is simulated. The candidate order, the failure classification and
the answer all come from the same code path that serves your agents, and the run
writes nothing: no cooldown, no route log. ficelle demo --json prints the same
run as a payload.
The recording passes --knock-out 2, which fails the two leading candidates
instead of one, so the reroute crosses a provider boundary rather than landing on
the next model of the same provider. Every fabricated attempt is labelled on its
own line whichever number you use. It is an unedited capture of a real run against
the free pool: re-running it gives different models, a different latency, and a
different sentence back.
ficelle-setup --target auto selects Hermes only when it detects a reliable local
Hermes signal; otherwise it selects the same standalone generic target. The explicit
launch targets are generic and hermes.
Updates
Ficelle checks for a newer verified Core release in the background after startup. The local Admin Control Center displays the release notes and offers a one-click install; the equivalent CLI commands are:
ficelle update --check
ficelle update --install
The updater downloads the release wheel, verifies its SHA-256, keeps a backup of the
installed package, runs import/service smoke checks, and restarts the managed user
service. A failed update restores the previous package. It never stores a Pro license
key. A paid release can advertise a compatible authenticated Pro artifact in Ficelle's
compact release manifest. For production, authorization: "entitlement" lets the
license service authorize the already-cached signed entitlement token; Core never sends
the user's license key or persists a new update secret. authorization: "bearer" is
available for managed deployments through the short-lived FICELLE_UPDATE_PRO_TOKEN.
The default check source is the latest GitHub Release. A deployment can point the Core at
its own HTTPS manifest with FICELLE_UPDATE_MANIFEST_URL. The compact manifest shape is:
{
"version": "0.1.7",
"release_url": "https://ficelle.ai/releases/0.1.7",
"core": {
"wheel_url": "https://downloads.example/ficelle_router-0.1.7-py3-none-any.whl",
"sha256": "<64 hexadecimal characters>"
},
"pro": {
"wheel_url": "https://downloads.example/ficelle_pro-0.1.7-py3-none-any.whl",
"sha256": "<64 hexadecimal characters>",
"authorization": "bearer"
}
}
Update checks are non-blocking and can be disabled for a managed environment with
FICELLE_DISABLE_UPDATE_CHECK=1.
How it works
OpenAI-compatible client → 127.0.0.1:8646/v1 → Ficelle router
├─ strict-zero catalog filtering
├─ provider credential resolution
├─ model scoring + fallback
├─ cooldowns / quarantine / failure classification
└─ admin API + dashboard + logs
↓
free LLM providers
Runtime state lives under ~/.ficelle/. Provider secrets resolve from the environment /
Ficelle keychain (~/.ficelle/ficelle-secrets.keychain-db on macOS) and are never
written to the repository. On first setup after an upgrade, legacy
~/.hermes/ficelle/ state is copied only when no Ficelle home was explicitly selected
and ~/.ficelle/ has no runtime data (absent, empty, or credential-only). Existing
credentials and the legacy source are preserved.
Open core & Ficelle Pro
This repository is the open core (Business Source License 1.1): the routing engine, the strict-zero safety model, the provider-adapter framework, and reference providers (OpenRouter, Nous). It runs standalone as the free tier.
Ficelle Pro is a separate, licensed package that adds the maintained value:
- the full curated provider pool, kept working as providers change their terms;
- compound-model fusion routing;
- native request compression;
- continuous provider-integration updates and support.
The paywall never sits on the core loop: routing, strict-zero, and free-provider access stay free and open. The Pro pack is not part of this repository; the core runs fully without it. Pricing and purchase live on the website.
Optional Hermes integration
Hermes is not required. If you want the integration and Hermes is not installed yet, use its official installer, which launches the setup wizard:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
Then ficelle-setup --target hermes installs the Ficelle provider and compression
plugins with backups. Hermes config is still opt-in:
ficelle-setup --target hermes --configure-hermes. To restore the latest available
plugin/config backups, run ficelle-setup --target hermes --rollback; paths without
backups are left untouched.
The provider name is ficelle. Start with low-risk auxiliary slots before any main-model
experiment:
auxiliary:
title_generation: { provider: "ficelle", model: "ficelle/auto-fast" }
compression: { provider: "ficelle", model: "ficelle/auto-compression" }
web_extract: { provider: "ficelle", model: "ficelle/auto-json" }
Export the recommended YAML with ficelle export --target hermes.
License
The open core is licensed under the Business Source License 1.1 (see the LICENSE file):
you may use, modify, redistribute, and self-host it; you may not offer it to third parties
as a competing hosted service. Each released version converts to the Apache License 2.0
four years after its publication.
Contributing and support
See CONTRIBUTING.md for the development workflow. Report security
issues privately using SECURITY.md. For installation or billing support,
email support@weesperneonflow.ai.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ficelle_router-0.1.8.tar.gz.
File metadata
- Download URL: ficelle_router-0.1.8.tar.gz
- Upload date:
- Size: 514.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e4989c73f8aff6e753b0c3d2e6edabcee743fd0f86d6221891dcddbe56fdbbb
|
|
| MD5 |
2c2336c0cd516b04ad23365fdb00374a
|
|
| BLAKE2b-256 |
b60503ee2285f40a5cbe3ae937d3e6a59947ede49ec73d6a91ecd051a54bb300
|
Provenance
The following attestation bundles were made for ficelle_router-0.1.8.tar.gz:
Publisher:
publish-pypi.yml on TheBlueHouse75/ficelle-open-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ficelle_router-0.1.8.tar.gz -
Subject digest:
5e4989c73f8aff6e753b0c3d2e6edabcee743fd0f86d6221891dcddbe56fdbbb - Sigstore transparency entry: 2369234650
- Sigstore integration time:
-
Permalink:
TheBlueHouse75/ficelle-open-core@604bae5676accf972bbbeb0049df7219b26b3028 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/TheBlueHouse75
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@604bae5676accf972bbbeb0049df7219b26b3028 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ficelle_router-0.1.8-py3-none-any.whl.
File metadata
- Download URL: ficelle_router-0.1.8-py3-none-any.whl
- Upload date:
- Size: 539.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8799ce2ab8bfba024600ecf69290f2ba665a787d844cd76f290f9549ead8b0a1
|
|
| MD5 |
7ef6a88426456dcbcffbcff6b4588409
|
|
| BLAKE2b-256 |
a491f88ca2ad2f5e771300b9a620d6349dace6bcb3222e1c840fda0f7df5906c
|
Provenance
The following attestation bundles were made for ficelle_router-0.1.8-py3-none-any.whl:
Publisher:
publish-pypi.yml on TheBlueHouse75/ficelle-open-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ficelle_router-0.1.8-py3-none-any.whl -
Subject digest:
8799ce2ab8bfba024600ecf69290f2ba665a787d844cd76f290f9549ead8b0a1 - Sigstore transparency entry: 2369234800
- Sigstore integration time:
-
Permalink:
TheBlueHouse75/ficelle-open-core@604bae5676accf972bbbeb0049df7219b26b3028 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/TheBlueHouse75
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@604bae5676accf972bbbeb0049df7219b26b3028 -
Trigger Event:
release
-
Statement type: