Commit graph

6 commits

Author SHA1 Message Date
Bryan Helmkamp
2ba04be181
feat(template): add source-aware diagnostics (#292)
## Summary

Template failures from `fabro run` and structural warnings from `fabro
validate` now preserve source provenance through rendering, workflow
transforms, API serialization, and CLI display. Diagnostics can point at
the actual workflow, import, or prompt file with node/attribute context
instead of surfacing MiniJinja's generic `<string>` source.

## What Changed

- Added named MiniJinja render APIs plus miette-aware `TemplateError`
metadata for source names, source text, spans, and labels.
- Reworked workflow template expansion so inline attributes, imported
workflows, and `@prompt` files render with file and owner context.
- Split strict run behavior from structural validate behavior: run-start
still hard-fails on missing inputs, while validate emits source-aware
warnings and continues linting.
- Extended validation diagnostics through Rust structs, OpenAPI, server
DTO mapping, and CLI rendering with optional source path, line, column,
span, and related metadata.
- Added regression coverage across template rendering, workflow
transforms, CLI output, and the server validate endpoint.

## Verification

- `cargo nextest run -p fabro-template`
- `ulimit -n 4096 && cargo nextest run -p fabro-workflow --no-fail-fast`
- `cargo nextest run -p fabro-cli
bare_fabro_with_unbound_inputs_validates_structurally_with_warning
run_rejects_unbound_template_inputs_before_creating_remote_run`
- `cargo nextest run -p fabro-server
validate_endpoint_returns_template_source_coordinates`
- `cargo build -p fabro-api`
- `cargo +nightly-2026-04-14 fmt --check --all`
- `cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D
warnings`

---

[![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)

---------

Co-authored-by: Aleksi Asikainen <1086393+salieri@users.noreply.github.com>
2026-05-16 18:47:37 -04:00
Bryan Helmkamp
a81eb09e78
feat(llm): add catalog controls and speed billing (#249)
## Summary

This PR advances the catalog-driven LLM work from fabro-sh/fabro#210 by
making the resolved model catalog the source of truth for provider
registration, request control validation, and billing identity. Runs now
preserve canonical provider/model/speed identity through pricing and API
responses instead of collapsing billing around provider API aliases or
model IDs alone.

## What Changed

- Register LLM provider adapters from the resolved catalog, including
custom OpenAI-compatible providers and their credential resolution
paths.
- Validate effective model request controls, including run-level
defaults and node overrides, before dispatching LLM requests.
- Add catalog-aware billing lookup that prices canonical `ModelRef`
values, uses base model costs for standard speed, applies per-speed cost
overrides, and returns an unknown estimate instead of silently billing
zero for unsupported combinations.
- Move Anthropic Opus fast-mode pricing into the built-in catalog for
`claude-opus-4-6` and `claude-opus-4-7`.
- Thread the injected catalog and effective speed controls through
workflow billing, including API-mode and CLI-mode handlers.
- Update billing APIs, server aggregation, generated clients, and the
web billing view to expose provider/model/speed billing identity and
keep standard and fast usage in separate rows.

## Notes for Review

Billing lookup intentionally uses canonical catalog model IDs. Provider
`api_id` substitution remains limited to provider request construction,
so aliases can be used on the wire without changing billing identity.
Event conversion paths that do not have catalog access now preserve
token counts with a null dollar estimate rather than falling back to the
bootstrap catalog.

## Verification

- `cargo build -p fabro-api`
- `cd lib/packages/fabro-api-client && bun run generate`
- `cargo +nightly-2026-04-14 fmt --check --all`
- `cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D
warnings`
- `ulimit -n 4096 && cargo nextest run -p fabro-model -p fabro-workflow
-p fabro-server -p fabro-api -p fabro-cli --no-fail-fast`
- `ulimit -n 4096 && cargo nextest run --workspace --no-fail-fast`
- `cd apps/fabro-web && bun run typecheck`
- `cd apps/fabro-web && bun test`
- `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)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:12:16 -04:00
Bryan Helmkamp
234bd5663e
Add ACP backend support (#237)
## Summary
Implemented ACP support as a first-class Fabro backend alongside `api`
and `cli`. This adds a new `fabro-acp` crate using the official ACP Rust
crates, routes `backend=\"acp\"` for agent and prompt nodes, adds
sandbox stdio support for local/Docker/test-support paths, emits ACP
workflow events/projections, updates server steerability handling,
validation, documentation, and black-box CLI coverage.

## Test Plan
Passed strict non-live verification:
- `ulimit -n 4096 && cargo nextest run -p fabro-workflow --run-ignored
all --no-fail-fast` — 1162 passed, 0 skipped.
- `ulimit -n 4096 && cargo nextest run -p fabro-acp -p fabro-sandbox -p
fabro-workflow -p fabro-validate -p fabro-store -p fabro-server -p
fabro-cli --run-ignored all --no-fail-fast -E 'not
test(daytona_streaming_live_smoke)'` — 3125 passed.
- `cargo build --workspace` — passed.
- `ulimit -n 4096 && cargo nextest run --workspace --run-ignored all
--no-fail-fast -E 'not test(daytona_streaming_live_smoke)'` — 5666
passed.
- `cargo +nightly-2026-04-14 fmt --check --all` — passed.
- `cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D
warnings` — passed.

Live-environment tests skipped/excluded under explicit user override:
- `daytona_streaming_live_smoke` was excluded from final nextest runs
because it requires live Daytona infrastructure and `DAYTONA_API_KEY`.
- Confirmed with `env -u DAYTONA_API_KEY cargo test -p fabro-sandbox
--features daytona --test daytona_streaming_live
daytona_streaming_live::daytona_streaming_live_smoke -- --ignored
--exact --nocapture`: failed fast with `DAYTONA_API_KEY must be set to
run this live smoke test`.
2026-05-11 23:39:43 -04:00
Bryan Helmkamp
66f06950ba
refactor: simplify Rust review cleanup
Centralize shared test setup and graph vocabularies, remove stringly event checks, and make server handler dependencies explicit.
2026-05-02 15:41:17 -04:00
Bryan Helmkamp
a479db981f
chore(validate): remove stale rule section dividers
Leftover from when rules.rs was a single 3500-line file. Numbering
was stale (Rule 23 and Rule 24 each appeared twice after the split)
and duplicated info already in the filename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:19:06 -04:00
Bryan Helmkamp
b1d560faf7
refactor(validate): split lint rules into modules 2026-05-02 13:44:55 -04:00