Skip to main content

Ficelle

Ficelle is a standalone local OpenAI-compatible strict-zero model router for agent clients. Codex, Cursor, Continue, Open WebUI, Hermes, and custom scripts all point at the same local endpoint — no host application is required (one recipe per client). Claude Code speaks the Anthropic protocol and cannot point at Ficelle directly yet; its page says what works today. Hermes is one optional, first-class integration among them: where it is installed, it sees Ficelle as one of its LLM providers.

It exposes http://127.0.0.1:8646/v1 with stable virtual models such as ficelle/auto-orchestrator, ficelle/auto-tools, ficelle/auto-json, ficelle/auto-compression, ficelle/auto-long, ficelle/auto-fast, and capability-specific virtual models for coding, reasoning, multimodal, vision, video, and audio routing. ficelle/auto-coding fails closed unless Ficelle has published a current signed certification for the exact provider deployment.

Current status

Ficelle is at v0.3.4: usable for local real-use, installable from a pinned bootstrap or from PyPI, and deliberately conservative about provider costs.

Solid today:

  • local OpenAI-compatible /v1/models and /v1/chat/completions endpoints;
  • strict-zero default routing: free pricing required, tools required by default, no paid fallback;
  • OpenRouter and Nous/RMS provider support;
  • NVIDIA NIM, Mistral, Groq, Gemini (Google AI Studio), and Cerebras as credential-gated free_quota providers (enabled but dormant without a key), not strict-zero;
  • Cavoti as a credential-gated free_quota relay (four tier entries — cavoti_basic, cavoti_gpt_premium, cavoti_claude_plus, cavoti_claude_premium, EU/Germany node) that resells paid frontier models (Claude/GPT/DeepSeek/GLM/Grok) under a free Pro quota — a grey-market relay, not a first-party free tier and not strict-zero, dormant without a key. The tiers share one daily dollar pool (shared_account scope) and carry a per-tier burn_weight so routing prefers the cheapest tier;
  • SiliconFlow as a credential-gated free_quota provider exposing one genuinely-free model (nex-agi/Nex-N2-Pro, 262K context, tools) through an id allowlist (its catalog ships no pricing) — an independent free quota that aggregates with OpenRouter for the same model; not strict-zero, dormant without a key;
  • Ollama Cloud as a credential-gated free_quota provider admitting its cloud catalogue without an allowlist, with runtime model-only quarantine when a listed model becomes subscription-only — preview quota, not strict-zero, dormant without a key;
  • GitHub Models as a free_quota integration that is wired and tested but dormant — not registered in the default config (absent from the UI, routes nothing): its free tier hard-caps request input at 8000/4000 tokens, so no free model reaches the 128k usable-input floor; the definition (GITHUB_MODELS_PROVIDER_DEF) stays in the tree, one edit from activation if GitHub raises the cap;
  • OpenCode Zen as a credential-gated free_model provider exposing only explicit allowlisted FreeModel IDs (deepseek-v4-flash-free, mimo-v2.5-free, nemotron-3-ultra-free, north-mini-code-free), like OpenRouter free models rather than provider-wide FreeQuota, dormant without a key;
  • Kilo Code (Kilo AI Gateway) as a credential-gated free_model provider on a non-standard path (/api/gateway, no /v1); the free pool requires both the provider's isFree=true marker and strict-zero catalog pricing, with no allowlist to maintain (provider_free_catalog_pricing proof — disagreements, paid, and sparse rows fail closed); never strict-zero, dormant without a key;
  • Cohere (OpenAI Compatibility API) as a credential-gated free_quota provider (dormant without a key) exposing the Command chat models that support tools and ≥128K context (its /v1/models ships no pricing/context, so a per-provider id allowlist scopes the free pool, like SiliconFlow); not strict-zero;
  • Naraya / NaraRouter (OpenAI-compatible gateway) as a credential-gated free_quota provider (dormant without a key), a third-party reseller router whose sparse /v1/models ships no pricing, so a mandatory id allowlist (require_model_id_allowlist, fail-closed) scopes the free pool to five fast open-weight chat models (the resold Claude/GPT/Gemini are excluded as unusably throttled); free_scope: provider (one 5M-tokens/day quota); not strict-zero;
  • OrcaRouter (free_model) as a credential-gated official free-id pool: every catalog id ending in -free, plus orcarouter/free. Paid Claude/GPT rows and sparse fusion aliases stay out; no hand-maintained allowlist. Hetzner Inference is registered as credential-gated free_quota; Ficelle follows its definitive authenticated catalog without a hard-coded model list, while capability and context filters still fail closed;
  • macOS LaunchAgent and Linux systemd --user lifecycle through the ficelle CLI;
  • conservative setup wrapper through scripts/install-ficelle.py and ficelle-setup;
  • Hermes provider plugin template for the ficelle provider;
  • admin UI and machine-readable /admin/status.json;
  • request routing logs, last-route state, provider/model errors, cooldowns, quarantine, benchmarks, canaries, audit log, and virtual model rollback;
  • per-request token accounting with a windowed savings estimate on the admin Requests page (Spent $0.00 under strict-zero, Est. saved at the routed models' own paid-sibling rates, recorded at catalog refresh);
  • default-off native context compression controls with dry-run reporting, local CCR retrieval, admin observability, and live-zone limited to low-risk real-use pending evidence.

Deliberately not done yet:

  • no paid fallback;
  • no quota-based providers enabled by default;
  • no native macOS app before the CLI/package path is stable.

Architecture at a glance

OpenAI-compatible client / optional Hermes integration
          |
          v
http://127.0.0.1:8646/v1
          |
          v
Ficelle router
  |- config + virtual profiles
  |- strict-zero catalog filtering
  |- provider credential resolution
  |- model scoring and fallback
  |- cooldowns / quarantine / failure classification
  |- benchmarks / canaries / verified capability state
  `- admin API + dashboard + logs
          |
          v
OpenRouter / Nous / future gated providers

Runtime state lives under ~/.ficelle/ by default, independently of any client integration. Provider secrets are resolved from the environment / Ficelle keychain (~/.ficelle/ficelle-secrets.keychain-db on macOS) and must never be committed.

Repository layout

.
├── AGENTS.md                         # operating rules for autonomous coding agents
├── CLAUDE.md                         # Claude Code entrypoint, points to AGENTS.md
├── README.md                         # this overview
├── config.example.json               # safe example runtime config
├── ficelle_router.py                 # legacy compatibility entrypoint
├── scripts/install-ficelle.py        # source-checkout setup wrapper
├── scripts/compression-dogfood-report.py # local compression real-use metrics
├── src/ficelle/
│   ├── cli.py                        # ficelle CLI and LaunchAgent lifecycle
│   ├── install.py                    # ficelle-setup package installer
│   ├── router.py                     # HTTP router, admin UI/API, selection engine
│   ├── service.py                    # platform service backend abstraction
│   └── assets/hermes-plugin/         # packaged Hermes plugins
├── plugins/ficelle-compression/      # source Hermes retrieval tool plugin
├── plugins/model-providers/ficelle/  # source Hermes provider plugin template
├── skills/ficelle-router/            # Hermes skill for operating Ficelle
├── tests/                            # pytest regression suite
└── docs/                             # product, architecture, PRDs, runbooks

Install for local development

cd ~/Projets/ficelle
python -m pip install -e '.[dev]'

Run local checks:

python -m pytest -q
python -m compileall src ficelle_router.py

Standalone setup

Ficelle needs Python 3.11+, but it does not require Hermes. The open Core is published as ficelle-router:

uv tool install ficelle-router      # or: pip install ficelle-router
ficelle-setup --skip-package --target generic

Run interactively, setup ends by offering to paste your OpenRouter key (hidden input; routing uses your own key — nothing serves without one) and then runs ficelle demo, so the first routed completion happens inside the install session. Scripted or declined, the equivalent manual steps are:

ficelle set-key openrouter   # or pipe it: ficelle set-key openrouter --stdin
ficelle doctor --text
ficelle health
ficelle models

For end users the pinned bootstrap in docs/install.md stays the recommended path: it is the only one that verifies the wheel it installs against a SHA-256 pinned in the script. An authorized source checkout also works:

git clone https://github.com/TheBlueHouse75/ficelle.git
cd ficelle
python scripts/install-ficelle.py --target generic

Then point any OpenAI-compatible client at http://127.0.0.1:8646/v1:

from openai import OpenAI

client = OpenAI(
    base_url="http://127.0.0.1:8646/v1",
    api_key="ficelle-local",
)

The public bootstrap installs the private Ficelle Pro wheel when a licence key is present:

(
  read -s FICELLE_LICENSE_KEY
  export FICELLE_LICENSE_KEY
  curl -fsSL https://raw.githubusercontent.com/TheBlueHouse75/ficelle-open-core/v0.3.4/scripts/bootstrap-ficelle.py | python3 - --target generic
)

That command does not require cloning this repo and keeps the key out of argv and shell history. The bootstrap downloads the private wheel, selects a target, installs into a target-aware Python, and runs the packaged setup flow. --target auto is the default: it uses the Hermes integration when a reliable local Hermes signal is found, and otherwise installs the generic standalone target. Use --target generic or --target hermes to make the launch target explicit.

Dry-run first when validating a new environment:

python scripts/install-ficelle.py --dry-run
python scripts/bootstrap-ficelle.py \
  --wheel-url ficelle-pro/dist/ficelle_pro-0.3.4-py3-none-any.whl \
  --target generic \
  --dry-run

After package installation, the same setup flow is available as:

ficelle-setup --skip-package --target generic

The setup wrapper starts with readable preflight checks, installs the package when requested, starts the selected local service backend, and runs doctor, health, and models smoke checks. It always passes FICELLE_HOME (default ~/.ficelle) to the service; generic and OpenClaw targets do not inherit or create HERMES_HOME.

For a safer first pass on a new machine:

python scripts/install-ficelle.py --preflight-only
python scripts/install-ficelle.py --dry-run --target generic

Only the Hermes target installs the packaged provider/tool plugins. Hermes config remains opt-in: --target hermes --configure-hermes writes a ready snippet to ~/.hermes/ficelle/hermes-config.snippet.yaml, creates ~/.hermes/config.yaml only when absent, or updates an existing Ficelle-managed block with a timestamped backup. Existing unmanaged configs are left untouched. ficelle-setup --target hermes --rollback restores the latest available integration backups; paths without a backup are always left untouched.

When upgrading from the former layout, setup implicitly copies ~/.hermes/ficelle/ to ~/.ficelle/ only when no Ficelle home was explicitly selected and the destination is absent, empty, or contains only credential files. Existing credentials and the legacy source are preserved; a destination containing runtime data is left untouched.

Today, the managed service backends are macOS LaunchAgent, Linux systemd --user, and a Windows per-user Scheduled Task (no elevation required; provider secrets resolve through the Windows Credential Manager). The Windows and Linux backends still need clean-host validation before public release claims.

See docs/install.md for source, wheel, dry-run, Hermes config, and verification details.

CLI commands

ficelle install
ficelle start
ficelle stop
ficelle restart
ficelle status
ficelle refresh
ficelle health
ficelle models
ficelle doctor --json
ficelle canary
ficelle synthetic-health run --depth deep --json
ficelle export

synthetic-health is the deep, sequential user-view health harness for weekly reference-installation runs. It exercises every configured virtual profile and every invokable strict-zero model through the loopback API, then correlates responses with route logs and state. Scheduling is disabled until explicitly installed. See docs/components/synthetic-health.md.

Useful local endpoints:

curl -s http://127.0.0.1:8646/health
curl -s http://127.0.0.1:8646/admin/status.json | python -m json.tool
curl -s http://127.0.0.1:8646/v1/models | python -m json.tool

Optional Hermes integration

Hermes is not required to run Ficelle. With --target auto, setup selects Hermes only when it detects a Hermes Python/runtime, CLI, config, or agent directory. --target hermes selects it explicitly, installs the Ficelle provider and compression plugins with idempotent backups, and passes HERMES_HOME only to that integration. The provider name is ficelle, with display label Ficelle FREE.

Export the recommended Hermes YAML:

ficelle export --target hermes

Setup makes Ficelle the main Hermes route through ficelle/auto-orchestrator and also installs specialized auxiliary slots:

model:
  provider: "custom"
  base_url: "http://127.0.0.1:8646/v1"
  model: "ficelle/auto-orchestrator"
auxiliary:
  title_generation:
    provider: "ficelle"
    model: "ficelle/auto-fast"
  compression:
    provider: "ficelle"
    model: "ficelle/auto-compression"
  web_extract:
    provider: "ficelle"
    model: "ficelle/auto-json"

ficelle/auto-compression is the Hermes compaction slot. ficelle/auto-long means large-context routing and is intentionally not the default compression recommendation.

Experimental OpenClaw integration

ficelle-setup --target openclaw installs the standalone service without Hermes files or environment. OpenClaw integration is experimental: review and merge the export from /admin/export/openclaw manually.

Documentation

Start with docs/README.md.

Key docs:

Provider policy

Enabled by default (strict-zero catalog):

  • OpenRouter;
  • Nous/RMS.

Enabled but credential-gated free_quota (dormant without a key, never strict-zero):

  • NVIDIA NIM;
  • Mistral. Unlike NVIDIA NIM, Mistral bills the same model IDs if the account carries a billing budget, so keep the account on the Experiment plan with no budget; the anti-false-free guard quarantines any model the runtime reports as billed.
  • Groq. Same posture as Mistral: bills the same model IDs if the account carries a billing budget, so keep the account on the free tier with no budget; its free tier is rate-limited (~30 RPM), so expect more rate-limit cooldowns.
  • Gemini (Google AI Studio). Same billing posture (free tier, no budget) and a tighter rate limit (~15 RPM, 1500 RPD on Flash). Off unless GEMINI_API_KEY is configured.
  • SiliconFlow. An OpenAI-compatible aggregator whose /v1/models ships no pricing, so a per-provider id allowlist restricts the free pool to the one genuinely-free model (nex-agi/Nex-N2-Pro, 262K context, tools). An independent free quota that aggregates with OpenRouter's copy of the same model. Keep the account with no paid top-up; the anti-false-free guard quarantines any model the runtime reports as billed. Off unless SILICONFLOW_API_KEY is configured.
  • Ollama Cloud. An OpenAI-compatible endpoint (https://ollama.com/v1, not /api/v1) whose /v1/models is admitted as the cloud free-quota catalogue (free_scope: provider, no allowlist). A listed model can later require a subscription: HTTP 403 requires a subscription / upgrade for access quarantines only that model, raises a Control Center notice, and does not pause the rest of Ollama. The account-wide preview quota remains unpublished and unstable, and Ollama meters it by GPU time, not tokens — generic quota cooldown/probe recovery handles exhaustion. Open point: commercial use of the free tier is not confirmed in Ollama's ToS. Off unless OLLAMA_API_KEY is configured.
  • Cohere (OpenAI Compatibility API). Its Compatibility /v1/models is OpenAI-shaped but sparse (no pricing or context) and mixes chat models with embeddings, rerank, transcribe, and vision, so a per-provider id allowlist restricts the free pool to the Command chat models that support tools and ≥128K context (command-a-03-2025, command-a-plus-05-2026, command-a-reasoning-08-2025, command-r-08-2024, command-r-plus-08-2024, command-r7b-12-2024, command-r7b-arabic-02-2025, north-mini-code-1-0; verified live 2026-06-21). Keep the account with no paid budget; the anti-false-free guard quarantines any model the runtime reports as billed. The free tier is rate-limited (~20 RPM, ~1000 calls/month), so expect more rate-limit cooldowns. Off unless COHERE_API_KEY (or CO_API_KEY) is configured.
  • Naraya / NaraRouter (OpenAI-compatible gateway, https://router.naraya.ai/v1). A third-party reseller router (like OpenRouter) that resells premium models at low IDR prices; its /v1/models is sparse with no pricing, so a mandatory per-provider id allowlist (require_model_id_allowlist, fail-closed) restricts the free pool to five open-weight chat models confirmed live 2026-06-21 to answer fast (1-5s) with tools and ≥252K context (mistral-large, mistral-medium-3-5, minimax-m3, deepseek-v4-flash-naraya, qwen3.7-max-naraya). The resold premium models (Claude/GPT/Gemini) are excluded: live they were throttled to a 22-43s time-to-first-byte, unusable for an agent. One 5M-tokens/day quota is shared account-wide (free_scope: provider), and no quota headers are exposed (consumption is visible only on the Naraya dashboard). Create the key with no credit card so the free pool cannot spill into paid pay-as-you-go. Off unless NARAYA_API_KEY is configured.

Enabled but credential-gated free_model (dormant without a key, model allowlist only):

  • OpenCode Zen. An OpenAI-compatible gateway whose /zen/v1/models catalog is sparse and whose Free models are model-specific, not provider-wide quota. Ficelle routes only explicit allowlist entries: deepseek-v4-flash-free, mimo-v2.5-free, nemotron-3-ultra-free, and north-mini-code-free after a live smoke on 2026-06-20. Ended free promotions are quarantined model-scoped. Off unless OPENCODE_ZEN_API_KEY is configured.
  • Kilo Code (Kilo AI Gateway). An OpenAI-compatible aggregator on a non-standard path (/api/gateway/chat/completions, no /v1). Its rich catalog exposes per-model pricing and an isFree flag, so Ficelle requires both signals to agree: isFree=true and strict-zero prompt/completion pricing. There is no allowlist to maintain; a newly-added model routes with no code change only when both provider signals agree and the normal tools/context gates pass. Rows marked paid, sparse-pricing rows, and contradictions such as isFree=false with $0 pricing fail closed. The dedicated provider_free_catalog_pricing proof keeps the provider FreeModel (a credential-gated opt-in outside the default strict-zero pool) while retaining strict-zero pricing evidence. Paid or billable routes return HTTP 402 at zero balance and are quarantined model-scoped; keep the account at 0 credits so paid/flipped models fail closed. Off unless KILO_API_KEY is configured. Reverified 2026-08-21 after stealth/ox-alpha exposed $0 pricing with isFree=false and returned 402 while an isFree=true control route succeeded; the :free models' commercial-use rights are unconfirmed.

Wired but not registered (dormant, absent from the admin UI, routes nothing):

  • GitHub Models. The integration is complete and tested but is deliberately not registered in the default config, because its free tier hard-caps request input at 8000 tokens (low/high tier) or 4000 (custom tier) and 403s the top reasoning models (o1/o3) — verified live 2026-06-21 — so no free model reaches the 128k usable-input floor, even though its non-standard /catalog/models reports each model's much larger native window. The provider definition (GITHUB_MODELS_PROVIDER_DEF) and its support code (non-standard catalog fetcher, credential path, tests) stay in the tree so it is one edit away from activation if GitHub raises the cap. Tools are confirmed working; auth would be a GitHub PAT scoped models:read (GITHUB_MODELS_API_KEY; the ambient GITHUB_TOKEN is intentionally not auto-resolved).

Rules:

  • default routing must never create silent spend;
  • allow_paid_fallback stays false unless explicitly changed and documented;
  • provider keys stay in the environment / Ficelle keychain, never repo files;
  • auth diagnostics are presence-only and redacted;
  • catalog claims must be separated from benchmark/canary-verified capability state.

Security

  • No secrets in this repository.
  • No provider keys in config, state fixtures, docs, screenshots, or logs committed to git.
  • Runtime state lives under ~/.ficelle/, outside the repo.
  • Route logs should contain request IDs, selected models, statuses, reasons, latency, and redacted details, not prompts or credentials.
  • Admin surfaces are local-only for the MVP.

Development workflow

Read AGENTS.md before changing code. The short version:

  1. Inspect existing code and docs before editing.
  2. Keep the diff minimal.
  3. Update docs with behavior changes.
  4. Run relevant tests/checks.
  5. Verify git diff --check and git status before handing off.
  6. Do not push without explicit approval.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ficelle_router-0.3.4.tar.gz (678.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ficelle_router-0.3.4-py3-none-any.whl (688.2 kB view details)

Uploaded Python 3

File details

Details for the file ficelle_router-0.3.4.tar.gz.

File metadata

  • Download URL: ficelle_router-0.3.4.tar.gz
  • Upload date:
  • Size: 678.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ficelle_router-0.3.4.tar.gz
Algorithm Hash digest
SHA256 8b9b7bbd6a948ebe5e032da305d3c550cc13c03e1e0cf69f485aabf0e9db67a7
MD5 8337ae672751bbf62b2d4fb59d243085
BLAKE2b-256 fbef54c7189d25484625c08b90318e6f7f08dd6b71b35fcbffffd1ebc2e9dafc

See more details on using hashes here.

Provenance

The following attestation bundles were made for ficelle_router-0.3.4.tar.gz:

Publisher: publish-pypi.yml on TheBlueHouse75/ficelle-open-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ficelle_router-0.3.4-py3-none-any.whl.

File metadata

  • Download URL: ficelle_router-0.3.4-py3-none-any.whl
  • Upload date:
  • Size: 688.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ficelle_router-0.3.4-py3-none-any.whl
Algorithm Hash digest
SHA256 637d8b79bc1bae7521149e00cfac8e84469474955da906345309a1c8ec718aa3
MD5 4257988ea0be0fd84ae57c3fa9f64344
BLAKE2b-256 dd3cab38ca68baa6420adfa1a3917961aa30d62931c76cced7ce40d183239b67

See more details on using hashes here.

Provenance

The following attestation bundles were made for ficelle_router-0.3.4-py3-none-any.whl:

Publisher: publish-pypi.yml on TheBlueHouse75/ficelle-open-core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.6

2 files

This release

0.3.4 This release

2 files

0.2.0

2 files

0.1.8

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page