Commit graph

24 commits

Author SHA1 Message Date
Bryan Helmkamp
34d83db801
feat(model): support open provider catalog data (#245)
## Summary

This PR moves Fabro’s provider/model catalog toward settings-driven
provider identity by replacing the closed provider schema at the
API/auth/model boundary with `ProviderId`, then loading built-in
provider and model metadata from embedded per-provider TOML files.

The immediate result is that built-ins now use the same settings-shaped
catalog data that custom providers will use later, while request-serving
paths still keep the existing bootstrap/default catalog behavior until
the resolved-catalog plumbing lands.

## Changes

- Replaces API-facing provider enum usage with string-backed
`ProviderId`, including OpenAPI/progenitor replacements and regenerated
TypeScript client models.
- Routes model, auth, billing, CLI, server, and workflow call sites
through provider IDs where they cross product identity boundaries.
- Builds `Catalog` from settings-shaped provider/model data with
validation for adapter keys, OpenAI-compatible `base_url`, duplicate
aliases, provider defaults, disabled entries, model controls, and
per-speed cost rows.
- Replaces `catalog.json` with embedded provider TOML files under
`lib/crates/fabro-model/src/catalog/providers/`.
- Adds an explicit `fabro_model::bootstrap_catalog` hatch for
setup/install paths and extends the dev policy test to keep bootstrap
access contained.
- Preserves public training and knowledge-cutoff labels in LLM model
settings while still accepting bare TOML dates.

## Verification

- `cargo nextest run -p fabro-model -p fabro-config -p fabro-api` — 416
passed
- `cargo nextest run -p fabro-dev --features dev
bootstrap_catalog_references_stay_in_allowlist` — 1 passed
- `cargo +nightly-2026-04-14 fmt --check --all`
- `cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D
warnings`
- `cargo build --workspace`
- `git diff --check`

---

[![Compound
Engineering](https://img.shields.io/badge/Compound_Engineering-6366f1)](https://github.com/EveryInc/compound-engineering-plugin)
🤖 Generated with GPT-5 via [Codex](https://openai.com/codex)
2026-05-12 15:42:49 -04:00
fabro-sh-0530[bot]
10de9fd16c
Add foundation for settings-driven LLM catalog (#207)
## Summary

This lays the groundwork for settings-driven LLM providers and models
without switching production routing yet. The new schemas and shared
vocabulary let later catalog construction treat provider/model identity
as data while keeping adapter behavior and control values Rust-owned.

## What changed

- Added `[llm.providers]` and `[llm.models]` settings layers with sparse
per-entry merging, whole-array replacement for credential/alias/control
lists, TOML date support for `knowledge_cutoff`, and typed `credential:`
/ `env:` references that reject literal secrets.
- Added `ProviderId`, `ModelId`, and a shared `ReasoningEffort` enum in
`fabro-model`, plus adapter metadata for `anthropic`, `openai`,
`gemini`, and `openai_compatible`.
- Added a matching `fabro-llm` adapter factory registry with parity
tests to keep metadata keys and factory keys in sync.
- Added `[run.model.controls]` defaults through config resolution and
runtime settings types.
- Added a workspace policy test to prevent future `bootstrap_catalog`
use outside install/test-support paths.

### Plan Summary

- This is the foundation slice of the settings-driven catalog plan.
- Production still uses the existing `Provider` enum and
`Catalog::builtin()` call paths.
- ProviderId routing, OpenAPI regeneration, auth resolver changes,
resolved `Arc<Catalog>` injection, typed request speed, and per-speed
billing are deferred follow-ups.

⚒️ Generated with [Fabro](https://fabro.sh)

---------

Co-authored-by: Fabro <noreply@fabro.sh>
Co-authored-by: fabro-bot <fabro-bot@fabro.sh>
Co-authored-by: Bryan Helmkamp <bryan@brynary.com>
2026-05-12 10:01:57 -04:00
Bryan Helmkamp
be084c1944
refactor(dev): decouple CLI reference generation
Expose the CLI reference renderer through a hidden fabro subcommand so fabro-dev can refresh docs without linking fabro-cli. Gate the fabro-dev binary behind the dev feature and update the cargo dev alias to opt into it explicitly.
2026-05-06 12:31:02 -04:00
Bryan Helmkamp
45bebb1fd8
fix(dev): avoid repeated cargo dev rebuilds
Scrub Cargo build-script environment from nested cargo commands so cargo dev does not poison fingerprints, and preserve unchanged SPA asset files while refreshing embedded assets.
2026-05-06 11:35:03 -04:00
Bryan Helmkamp
24b8f1ec04
fix(docs): use MDX comment syntax for generated fences
Mintlify parses pages as MDX and rejects HTML-style `<!-- ... -->`
comments, which broke the docs deployment on cli.mdx with a parse
error. Switch the generator fences (and the matching markers in the
two reference pages and the dev test fixtures) to `{/* ... */}` so
Mintlify can parse them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 01:27:43 -04:00
Bryan Helmkamp
be9d9284be
feat(dev): add bench-tests command for capturing per-test timing CSV
Runs the workspace test suite N times via `cargo nextest run --no-fail-fast`
and appends one row per testcase to a CSV (git_sha, run_index, started_at,
binary, package, classname, test_name, status, duration_ms). Group ≈ package
is derived from the JUnit testsuite name.

The lenient `[profile.bench]` (with junit.path) is synthesized at runtime to
target/bench-tests/nextest-tool.toml and passed via `--tool-config-file`, so
nothing needs to be added to .config/nextest.toml.

Intended use: collect samples on the current checkout, switch SHAs, collect
again, then diff/aggregate externally to hunt slowdowns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 09:18:00 -07:00
Bryan Helmkamp
c224a4517f
fix(docker): grant server access to mounted socket
When the packaged container starts as root, map the mounted Docker socket's group into the container and add the unprivileged fabro user before dropping privileges. This lets Docker sandboxes work with socket mounts from OrbStack, Docker Desktop, and Linux daemons whose socket GID varies by host.
2026-04-27 11:12:44 -07:00
Bryan Helmkamp
d2d962f201
Merge remote-tracking branch 'origin/main' 2026-04-27 07:01:53 -07:00
Bryan Helmkamp
5765547f51
feat(dev): gitignore embedded spa assets 2026-04-26 21:31:11 -04:00
Bryan Helmkamp
54c5f30586
docs: move published docs under docs/public
Relocate the Mintlify tree to docs/public and consolidate internal docs under docs/internal. Update build scripts, tests, CI filters, README references, and local docs skills to follow the new layout.
2026-04-26 21:19:46 -04:00
Bryan Helmkamp
bbe4d3c68c
refactor(dev): align cargo dev command modules
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
2026-04-25 19:50:31 -04:00
Bryan Helmkamp
d37f75a878
feat(dev): group cargo dev spa and docs commands 2026-04-25 19:40:59 -04:00
Bryan Helmkamp
05e5623b2b
chore(dev): default docker-build tag to fabro-sh/fabro
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 19:40:59 -04:00
Bryan Helmkamp
a4c04a296e
chore: move docker-context/ staging dir under tmp/
Keeps the repo root tidy. The staged Linux musl binaries used by
the Dockerfile and the release pipeline now live at
tmp/docker-context/<arch>/fabro instead of docker-context/<arch>/fabro.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 12:37:45 -04:00
Bryan Helmkamp
11be286fa1
refactor(dev): simplify generated docs tooling
Share the real CLI parser with reference generation, reuse option metadata flattening, and centralize dev command execution helpers.
2026-04-24 18:41:00 -04:00
Bryan Helmkamp
a4ee62a8a4
refactor(dev): dedupe shared helpers, remove check-boundary
Consolidate workspace_root, PlannedCommand, shell_arg, markdown_cell, and
replace_generated_region into commands/mod.rs; unify fabro_dev/output_text/
write_file/read_file into tests/it/main.rs. Drop the abandoned check-boundary
subcommand.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:10:31 -04:00
Bryan Helmkamp
5e28ec0f82
Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.github/workflows/nightly.yml
#	bin/dev/release.sh
2026-04-24 17:04:55 -04:00
Bryan Helmkamp
12ea5341bb
feat(dev): generate options reference
Add a settings reference generator backed by OptionsMetadata on the sparse config layer structs. The generated user-configuration page is fenced and checked in CI alongside the CLI reference.
2026-04-24 16:49:16 -04:00
Bryan Helmkamp
0f3c28db87
feat(dev): generate CLI reference
Add a cargo dev generator for the CLI reference and gate the generated docs in CI. The generator reads the fabro clap command tree through a narrow public reference surface so CLI docs drift is caught without exposing runtime command internals.
2026-04-24 16:35:06 -04:00
Bryan Helmkamp
f52ef5aa07
feat(dev): port SPA asset tooling 2026-04-24 16:05:29 -04:00
Bryan Helmkamp
a03c689a44
feat(dev): port release automation 2026-04-24 16:00:25 -04:00
Bryan Helmkamp
0daf4d7b5c
feat(dev): port docker build workflow 2026-04-24 15:55:03 -04:00
Bryan Helmkamp
99257846d1
feat(dev): enforce CLI boundary with cargo dev 2026-04-24 15:50:01 -04:00
Bryan Helmkamp
99d2adb216
feat(dev): add fabro-dev scaffold
Introduce the internal fabro-dev CLI shell and cargo dev alias so follow-up units can port development scripts behind typed clap subcommands.
2026-04-24 15:43:30 -04:00