Commit graph

22 commits

Author SHA1 Message Date
Bryan Helmkamp
619cb44e3c
Import lithos-llm types directly instead of through fabro-types
fabro-types no longer re-exports the lithos catalog and request types
(ProviderId, ModelId, ModelHandle, Message, ContentPart, TokenCounts,
Cost, Speed, ReasoningEffort, ReasoningOutput, and the rest). Every
crate that uses them depends on lithos-llm and names them there, and
the fabro-api progenitor replacements point at the lithos paths.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 10:03:08 -06:00
Bryan Helmkamp
fa3e485c95
Name built-in providers through lithos catalog::builtin
lithos-llm now ships the built-in provider ids and constructors, so
fabro-types drops its provider_ids module and every caller uses
lithos_llm::catalog::builtin directly. The crates that name a provider
now depend on lithos-llm themselves.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:48:37 -06:00
Bryan Helmkamp
3a998196ff
Answer catalog questions with the lithos catalog queries
fabro-llm's catalog module held some 250 lines of listing and picking
helpers over lithos data: enabled and listed providers, model lookup by
id, alias, or wire id, matches ranked as the resolver ranks, default and
probe models, the small utility model across ready providers, the nearest
model on another provider, and cost by handle. lithos-llm now answers all
of those on `Catalog` and `CatalogProvider` through `Offering`, so the
helpers and the `ModelEntry` wrapper go.

What stays in Fabro's catalog module is its own: building the catalog from
the operator overlay, and reading the agent harness and
`reasoning_by_default` from the shared `metadata.agent` namespace. The
passthrough selection policy in `selection.rs` keeps its rules and calls
lithos for the lookups.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:26:40 -06:00
Bryan Helmkamp
2a2fc41807
Read catalog policy from lithos core fields and metadata.agent
Fabro's policy layer restated the lithos built-ins under `metadata.fabro`:
enabled flags, credentials, display facts, probe and small-default roles,
and agent profiles. lithos-llm now carries every one of those as a core
field or under the shared `metadata.agent` namespace, so the layer and its
typed view go:

- Delete `fabro-policy.toml` and `FABRO_POLICY_TOML`. The catalog is the
  lithos built-ins plus the operator's `[llm]` overlay, nothing between.
- Delete `fabro_types::catalog_policy`. `enabled`, `stands_in_for`,
  `api_key_url`, `family`, the cutoffs, `estimated_output_tps`,
  `small_default`, and `probe` are read from lithos accessors; the agent
  profile and `reasoning_by_default` come from `metadata.agent`, which
  Pebble reads too.
- `catalog::provider`, `enabled_providers`, and `listed_providers` return
  the lithos `CatalogProvider` directly; `ModelEntry` loses its policy
  field and gains `agent_profile()`.
- Test fixtures move `[providers.x.metadata.fabro] enabled = true` onto
  the provider table, drop `credentials` lists in favor of the secret name
  lithos derives from the provider id, and spell `agent_profile` as
  `metadata.agent.profile`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:20:12 -06:00
Bryan Helmkamp
6dfc96d3fd
Resolve provider secrets through lithos conventional credentials
lithos-llm now owns which named secrets each provider reads and how they
shape into its auth scheme, including a derived `<PROVIDER>_API_KEY` for
operator-defined providers. Fabro's job shrinks to supplying the store:
`VaultCredentialSource` hands lithos a lookup that reads the process
environment, then the vault, under the same conventional names.

What Fabro still adds on top: the Codex OAuth credential in the vault,
refreshed and persisted when it expires; `{{ secrets.NAME }}` tokens in a
provider's `default_headers`, resolved against the vault and re-sent as
credential headers; and OpenAI organization and project headers from the
environment.

Deleted with the `metadata.fabro.credentials` list: `CredentialRef`,
`CredentialResolver`, `EnvCredentialSource` (now
`VaultCredentialSource::environment_only`), and the `env_var_names` /
`expected_vault_secret_name` helpers, replaced by `secret_names` and
`expected_secret_name` over the lithos table. `openai-codex` joins the
first-party provider id constants.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:00:08 -06:00
Bryan Helmkamp
e557774b0b
Rebuild fabro-llm on lithos-llm and adopt its stream contract in fabro-agent
fabro-llm is now a thin integration crate: catalog construction from the
lithos built-ins, the Fabro policy layer, and operator overlays; client
construction from catalog plus credentials; a Fabro `ModelResolver` that
enforces `metadata.fabro` policy; model selection; a server gateway
adapter; attachment inlining middleware; reasoning normalization;
one-shot structured output; probe wiring; and catalog API views. The
in-house codecs, transports, providers, tool loop, retry, cost, and
token-count code are deleted along with the wire snapshots that covered
them.

fabro-agent consumes lithos `StreamEvent`s and `Response`s directly.
Retry is split: lithos's retry middleware handles failures before any
visible output, and the agent replays the turn after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Scott Werner
fbba98defd Add tag support to Git run targets 2026-08-26 11:16:37 -04:00
Bryan Helmkamp
401acb6cdf
Record tool output byte counts 2026-08-24 12:46:27 -04:00
Bryan Helmkamp
3217a05aad
Merge origin/main into feat/venice-search-provider 2026-08-21 21:04:28 -04:00
Bryan Helmkamp
cfa8ae92c0
style: apply pinned rustfmt 2026-08-21 19:34:38 -04:00
Jesse Proudman
53efde3930 feat(search): add Venice backend for web_search
Brave stays the default. Shops that already vault VENICE_API_KEY
can drop BRAVE_SEARCH_API_KEY by setting
[server.integrations.search] provider = "venice".

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 12:31:03 -07:00
Scott Werner
8c45b870b4 Check out exact sandbox commits 2026-08-14 17:10:46 -04:00
Bryan Helmkamp
24f9ac6bd1
refactor(model): rename Kimi provider to Moonshot 2026-07-31 09:00:52 -04:00
Bryan Helmkamp
d931ae6105
fix(agent): simplify GPT-5.6 tool routing 2026-07-25 11:49:40 -04:00
Bryan Helmkamp
4d5458b64c
test(agent): honor Docker shell integration preconditions 2026-07-24 22:35:51 -04:00
Bryan Helmkamp
c803354309
refactor(agent): streamline shell outcome reporting 2026-07-24 21:50:07 -04:00
Bryan Helmkamp
392b8dd27b
fix(agent): report real shell process outcomes
The shell executor rendered every returned ExecResult and returned
Ok(output), so nonzero exits, timeouts, and cancellations reached
execute_one_tool() as successes. That false ToolResult propagated
consistently: agent.tool.completed recorded is_error: false, the success
post-tool hook ran, Anthropic saw is_error: false, OpenAI Responses saw a
completed function-call output, and CLI/web rendered a successful tool
call.

ExecResult::is_success() is now the authoritative predicate. The executor
runs through exec_command_streaming() with a sink callback, so it keeps
the production providers' stream provenance and partial-output capture,
and drops the exec 2>&1 prefix that merged stderr into stdout before
Fabro could report it. Model-facing text labels termination, exit code,
duration, and either separate stdout/stderr sections or one combined
section when the provider cannot separate streams.

Session-bound dispatch also emits a typed agent.tool.process.completed
event carrying the process metadata, streams_separated, and bounded
redacted output tails. It is subordinate diagnostic data: the following
agent.tool.completed remains the one tool-protocol completion and the
authoritative owner of is_error, so consumers need no new row.

Nonzero, timed-out, and cancelled commands intentionally change from
successful to failed tool results, and PostToolUseFailure replaces
PostToolUse for them. On Docker the agent shell tool now uses the
streaming path's bash -lc supervisor, which terminates the process group
on timeout instead of leaving container-side processes running.

The public shell schema is unchanged and pinned by an exact assertion.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 21:24:16 -04:00
Bryan Helmkamp
4ce57f8aae
refactor: simplify profile builder and drop dead tool plumbing
Follow-up cleanup on the profile-builder refactor.

AgentProfileBuilder::build now borrows instead of consuming, removing the
builder.clone().build() dance at all seven call sites. Deletes
with_command_timeouts, which had no caller but its own test, and the
with_summarizer constructors on all three profiles, whose only remaining
caller was each profile's own new().

Replaces the fifth copy of the profile-kind match (guardrails.rs) with the
builder, and swaps the parity matrix's hand-maintained provider list for
Catalog::effective_agent_profile so a new catalog provider cannot silently
skip the matrix. Collapses web_search_provider_test! into a secrets = arm
on provider_test! and uses EnvVars::BRAVE_SEARCH_API_KEY over a literal.

Drops the Brave key from the Ask Fabro session: AskFabroToolAccessPolicy
denies web_search, and both tools() and the prompt are filtered through
that policy, so the vault read only registered an uncallable tool.

Makes NativeToolOptions::for_profile match exhaustively so a new profile
kind must state its timeout, restores Anthropic's borrowed prompt sections
and Gemini's static prompt (placeholder substitution rather than format!
over 110 lines with doubled braces), and introduces WEB_SEARCH_TOOL_NAME
for the registry lookups that keep tool availability and prompt guidance
in sync.

Updates the product docs, which still described web_search as always
registered and as erroring at call time when unconfigured.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 17:32:33 -04:00
Bryan Helmkamp
e15defe4c5
refactor: centralize agent profile tool configuration 2026-07-24 14:06:29 -04:00
Bryan Helmkamp
84c5468722
Merge remote-tracking branch 'origin/main' into fix/cancellation-interrupt-lifecycle
# Conflicts:
#	lib/components/fabro-agent/src/subagent.rs
#	lib/components/fabro-agent/tests/it/parity_matrix.rs
2026-07-23 20:55:25 -04:00
Bryan Helmkamp
cdf1dce4f8
fix(agent): remove dead execution limits 2026-07-23 19:36:29 -04:00
Scott Werner
47bc772f7b refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00