fabro/lib/crates/fabro-api/Cargo.toml
brynary-fabro[bot] c81fd1740b Extract fabro-model crate from fabro-llm (#109)
This PR extracts a new `fabro-model` crate from `fabro-llm`, isolating
the model catalog, provider identity types, and model metadata into a
focused, lightweight package. The new crate contains `Provider`,
`ModelId`, `ModelInfo` (and related structs), and the full catalog API
(`get_model_info`, `list_models`, `default_model_from_env`,
`build_fallback_chain`, etc.) — with only `serde` and `serde_json` as
runtime dependencies, no async runtime required.

The extraction follows a clean boundary: `fabro-llm` now depends on
`fabro-model` and re-exports `Provider` and `ModelId` at its root so
existing `fabro_llm::Provider` usage remains valid without a migration.
The `ProviderAdapter` trait, `StreamEventStream`, and
`validate_tool_choice` stay in `fabro-llm` since they depend on async
streaming types. All seven consumer crates (`fabro-agent`, `fabro-api`,
`fabro-cli`, `fabro-hooks`, `fabro-workflows`, `fabro-validate`, and
`fabro-llm` itself) are updated to import catalog functions and provider
types directly from `fabro_model` rather than `fabro_llm::catalog` or
`fabro_llm::provider`.

The most impactful dependency reduction is in `fabro-validate`, which
previously pulled in all of `fabro-llm` (tokio, reqwest, the full async
runtime) just to perform catalog lookups and validate provider names. It
now depends solely on `fabro-model`, eliminating that heavyweight
transitive closure. All other consumers retain their `fabro-llm`
dependency for client and streaming functionality, but gain a precise
import path for catalog and identity concerns.

### Fabro Details

<details>
<summary>Ran 9 stages in 21m 16s for $5.47</summary>

| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 0s | – | 0 |
| preflight_compile | 1m 10s | – | 0 |
| preflight_lint | 12s | – | 0 |
| implement | 13m 29s | $3.81 | 1 |
| simplify_opus | 5m 41s | $1.66 | 0 |
| simplify_gpt | 0s | – | 0 |
| verify | 15s | – | 0 |
| fmt | 1s | – | 0 |
| **Total** | **21m 16s** | **$5.47** | **1** |

</details>

<details>
<summary>Ran <code>ImplementAndSimplify.fabro</code> (12 nodes and 15
edges)</summary>

```dot
digraph ImplementAndSimplify {
    graph [
        goal="Implement and simplify",
        model_stylesheet="
            * { backend: api; model: claude-opus-4-6;}
        "
    ]
    rankdir=LR

    start [shape=Mdiamond, label="Start"]
    exit  [shape=Msquare, label="Exit"]

    toolchain         [label="Toolchain", shape=parallelogram, script="command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", max_retries=0]
    preflight_compile [label="Preflight Compile", shape=parallelogram, script="cargo check -q --workspace 2>&1", max_retries=0]
    preflight_lint    [label="Preflight Lint", shape=parallelogram, script="cargo clippy -q --workspace -- -D warnings 2>&1", max_retries=0]
    fix_lints         [label="Fix Lints", prompt="The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.", max_visits=3]
    implement         [label="Implement", prompt="Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan. Use red/green TDD."]
    simplify_opus     [label="Simplify (Opus)", prompt="@prompts/simplify.md"]
    simplify_gpt      [label="Simplify (GPT-54)", prompt="@prompts/simplify.md", model="gpt-54"]
    verify            [label="Verify", shape=parallelogram, script="cargo clippy -q --workspace -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1", goal_gate=true, retry_target="fixup"]
    fixup             [label="Fixup", prompt="The verify step failed. Read the build output from context and fix all clippy lint warnings and test failures.", max_visits=3]
    fmt               [label="Format", shape=parallelogram, script="cargo fmt --all 2>&1", max_retries=0]

    start -> toolchain
    toolchain -> preflight_compile [condition="outcome=success"]
    toolchain -> exit
    preflight_compile -> preflight_lint [condition="outcome=success"]
    preflight_compile -> exit
    preflight_lint -> implement [condition="outcome=success"]
    preflight_lint -> fix_lints
    fix_lints -> preflight_lint
    implement -> simplify_opus -> simplify_gpt -> verify
    verify -> fmt   [condition="outcome=success"]
    verify -> fixup
    fixup -> verify
    fmt -> exit
}

```

</details>

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

---------

Co-authored-by: Fabro <noreply@fabro.sh>
2026-03-19 22:26:47 -04:00

66 lines
No EOL
1.9 KiB
TOML

[package]
name = "fabro-api"
edition.workspace = true
version.workspace = true
license.workspace = true
description = "HTTP API server for Fabro pipelines"
[lib]
doctest = false
[dependencies]
fabro-config = { path = "../fabro-config", features = ["exedev"] }
fabro-graphviz = { path = "../fabro-graphviz" }
fabro-hooks = { path = "../fabro-hooks" }
fabro-interview = { path = "../fabro-interview" }
fabro-workflows = { path = "../fabro-workflows" }
fabro-sandbox = { path = "../fabro-sandbox", features = ["daytona"] }
fabro-github = { path = "../fabro-github" }
fabro-agent = { path = "../fabro-agent" }
fabro-llm = { path = "../fabro-llm" }
fabro-model = { path = "../fabro-model" }
fabro-retro = { path = "../fabro-retro" }
fabro-util = { path = "../fabro-util" }
fabro-db = { path = "../fabro-db" }
fabro-types = { path = "../fabro-types" }
chrono.workspace = true
futures-util.workspace = true
axum = "0.8"
dirs.workspace = true
sqlx.workspace = true
tower = "0.5"
tokio-stream = { workspace = true, features = ["sync"] }
base64.workspace = true
jsonwebtoken.workspace = true
tokio.workspace = true
tokio-rustls = "0.26"
rustls = { version = "0.23", default-features = false, features = ["std", "ring"] }
rustls-pemfile = "2"
rustls-pki-types = "1"
hyper = "1"
hyper-util = { version = "0.1", features = ["tokio", "server-auto", "http1", "http2"] }
tower-service = "0.3"
x509-parser = "0.16"
serde.workspace = true
serde_json.workspace = true
serde_yaml = "0.9"
anyhow.workspace = true
clap.workspace = true
toml.workspace = true
tracing.workspace = true
ulid.workspace = true
uuid.workspace = true
hmac.workspace = true
sha2.workspace = true
hex.workspace = true
reqwest.workspace = true
bytes = "1"
[dev-dependencies]
tokio = { workspace = true, features = ["test-util", "macros"] }
tower = "0.5"
http-body-util = "0.1"
tempfile = "3"
openapiv3 = "2"
serde_yaml = "0.9"
fabro-sandbox = { path = "../fabro-sandbox", features = ["exe"] }