Commit graph

4217 commits

Author SHA1 Message Date
Bryan Helmkamp
c3cdefa5ea
refactor(events): simplify backward pagination internals
- Extract a shared fetch_run_events_page helper so the three client
  paging loops (full list, until, tail) no longer repeat the request/
  convert/has_more skeleton; fold the tail loop's two descending-order
  checks into one and drop its redundant had_events flag.
- Skip the latest-seq lookup in list_events_before_with_limit when the
  caller supplies a before_seq cursor, so a cold projection cache costs
  at most one full history scan per pagination session instead of one
  per page.
- Remove the dead before_seq max(1) clamp and the passthrough order()
  accessor from EventListParams.
- Document the CLI --tail 0 --follow seeding trick and the reader
  event_seq placeholder invariant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:34:02 -04:00
Release Repro
59d5b317dc
Simplify LLM error mapping and validate reasoning_effort parsing
- Return InvalidRequest (400) for unsupported speed too, matching the
  reasoning_effort check and the complete()/stream() doc comments
- Centralize fabro_llm::Error -> ApiError mapping in a From impl so the
  completions handler, playground handler, and Error::Llm arm agree on
  the InvalidRequest -> 400 / else -> 502 split
- Reject unparseable reasoning_effort values with 400 instead of
  silently dropping them
- Add classify_sdk_invalid_request test per fabro-workflow convention

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:29:12 -04:00
Bryan Helmkamp
0e4244a24a
refactor: simplify and harden the seek-based event listing
- Unify list_events_from with list_events_from_with_limit so projection
  replay shares the seek path instead of duplicating the decode loop
- Bound the event scan with keys::run_events_range instead of an
  unbounded range plus a manual prefix break, so slatedb never touches
  SSTs belonging to other runs or namespaces
- Store reader event_seq as None instead of a valid-looking sentinel of
  1, so appends through a reader-built inner fail as ReadOnly rather
  than writing duplicate sequences
- Borrow keys during scans instead of allocating a String per entry,
  drop a dead branch in cached_events_from, collapse recover_next_seq's
  single-caller parameters, and document the zero-padded key ordering
  invariant the seek depends on

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:29:06 -04:00
Bryan Helmkamp
af27e98e1c
refactor: simplify parallel handler and overview parsing
- Extract emit_branch_completed() to replace three near-identical
  ParallelBranchCompleted constructions; status now reads consistently
  from outcome.status
- Add context_diff_public() so parallel.rs and manager_loop.rs share the
  diff-minus-engine-internal-keys step; move context_diff tests next to
  the function in context.rs
- Replace fan_in's dead BranchShape struct with the canonical
  Vec<ParallelBranchResult> (from_value moves, so no payload cloning)
- Narrow parseParallelOverview to ParallelBranchSummary {id, status};
  its only consumer renders just those fields
- Drop helpers.test.ts's duplicate envelope() fixture in favor of the
  shared makeEventEnvelope

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:28:58 -04:00
Bryan Helmkamp
7b7606e4f0
Merge pull request #609 from fabro-sh/fix/typed-completion-reasoning-effort
Validate completion reasoning effort values
2026-07-24 08:19:01 -04:00
Bryan Helmkamp
40d6992148
Trim redundant reasoning effort request tests
The unknown-value rejection test duplicated strum coverage in
fabro-model and the HTTP 422 test in fabro-server. Keep only the
field-type assertion, using the same field-pinning idiom as
stage_model_usage_round_trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:13:54 -04:00
Bryan Helmkamp
9708ca8177
feat(llm): add Fireworks AI as an opt-in provider
Adds a disabled-by-default `fireworks` provider to the built-in catalog,
served through the existing openai_compatible adapter/codec. The curated
roster covers Kimi K2.7 Code (default), Kimi K2.6, DeepSeek V4 Pro/Flash,
GLM 5.2, MiniMax M2.7, Qwen 3.7 Plus, and GPT-OSS 120B/20B (small
default + probe), with serverless pricing including cached-input rates.

All api_ids were verified live against /chat/completions (Fireworks'
GET /v1/models only returns a featured subset), and serverless responses
were confirmed to report prompt_tokens_details.cached_tokens, so cache
billing works through the existing codec path.

FIREWORKS_API_KEY is registered as an optional vault secret; provider
login, vault storage, and diagnostics probing are catalog-driven and
need no code changes. Includes catalog/install tests, two live e2e
tests, an integrations docs page, and a provider logo for the web UI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:03:39 -04:00
Bryan Helmkamp
8f0ecfb170
fix(store): reuse shared run projections 2026-07-24 07:49:58 -04:00
Bryan Helmkamp
4bd9753217
Expose model reasoning effort controls 2026-07-24 07:44:40 -04:00
Bryan Helmkamp
9afd456c06
Merge pull request #610 from fabro-sh/feat/portable-model-aliases
Add portable model aliases
2026-07-24 07:39:05 -04:00
Bryan Helmkamp
a7e3bcec7c
Merge pull request #613 from fabro-sh/feat/poolside-provider-logo
Add Poolside provider logo
2026-07-24 07:38:56 -04:00
Bryan Helmkamp
142862f342
Expose detailed completion token usage 2026-07-24 07:36:56 -04:00
Bryan Helmkamp
1c1ea53093
fix: prefer ready providers during preflight 2026-07-24 07:28:51 -04:00
Bryan Helmkamp
0cc4a01882
Forward reasoning effort for structured completions 2026-07-24 07:28:06 -04:00
Bryan Helmkamp
377eb961ec
feat: add Poolside provider logo
Adapted from poolside's official favicon mark: monochrome
fill="currentColor" at 24x24 to match the other provider logos, with the
brand's gradient-fade tail preserved via the original alpha mask.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 07:26:22 -04:00
Bryan Helmkamp
bb1afae363
feat(events): add backward cursor pagination 2026-07-24 07:23:23 -04:00
Bryan Helmkamp
5aebb17fa2
Return bad request for unsupported reasoning effort 2026-07-24 07:22:47 -04:00
Bryan Helmkamp
3cfac20343
test: capture preflight provider routing gap 2026-07-24 07:12:01 -04:00
Bryan Helmkamp
05fa485637
feat: add portable GLM and DeepSeek aliases 2026-07-24 07:07:56 -04:00
Bryan Helmkamp
673a7064fe
Validate completion reasoning effort 2026-07-24 07:04:31 -04:00
Bryan Helmkamp
7216c49e44
docs: align parallel strategy with typed StageOutcome results
Review follow-ups: the ParallelBranchResult snippet showed status as
String (it is StageOutcome), and the cancellation section implied a
cancelled branch status that the type does not have — cancelled-while-
waiting branches record a failed outcome (reason "branch cancelled")
and the handler returns Error::Cancelled to the run executor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 07:00:44 -04:00
Bryan Helmkamp
e3011481a1
fix(store): make event history pagination linear 2026-07-24 06:56:44 -04:00
Bryan Helmkamp
4621149b6e
Merge remote-tracking branch 'origin/main' into feat/shared-checkout-parallel 2026-07-24 06:54:32 -04:00
Bryan Helmkamp
558c1010f8
Regenerate TS client to drop duplicated method from merge
The merge of main kept two copies of testProviderCredentials in the
generated models-api.ts; regeneration is authoritative.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 06:44:56 -04:00
Bryan Helmkamp
27cf30ff8b
feat: add GPT-5.6 name aliases 2026-07-24 06:33:22 -04:00
Bryan Helmkamp
85f3286c66
Merge branch 'main' into feat/shared-checkout-parallel 2026-07-24 06:29:57 -04:00
Bryan Helmkamp
0a39ba9e06
Shared-checkout parallel execution (recovered from run 01KY7YH7RYCJ1BDVTTP96ZA4HV)
Cumulative implement + simplify_fable diff recovered from the run's meta
branch (fabro/meta/01KY7YH7RYCJ1BDVTTP96ZA4HV, stage 006 diff.patch).
The run validated this tree clean: cargo nextest (7,007 passed), clippy,
fmt, TS client regen + typecheck, web tests (679 passed), docs check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 06:19:11 -04:00
fabro-releases[bot]
df3c834581 Bump version to 0.304.0-nightly.0 2026-07-24 01:48:13 +00:00
Bryan Helmkamp
5aaddd344e
Merge pull request #606 from fabro-sh/fix/cancellation-interrupt-lifecycle
Harden cancellation and interrupt lifecycles
2026-07-23 21:33:24 -04:00
Bryan Helmkamp
22238575ac
fix: report delete-specific run errors 2026-07-23 21:27:58 -04:00
Bryan Helmkamp
9adf24348b
refactor: simplify cancellation lifecycle code from review
- Extract the quadruplicated watchdog check-and-clear logic in
  schedule_worker_cancel_escalation into ManagedRun methods
  (escalation_still_current, clear_escalation_for)
- Derive strum::IntoStaticStr for WorkerRef instead of a hand-written
  variant-to-string match in kind()
- Use the generated AgentControlState constant instead of the raw
  "waiting_for_steer" literal in run-detail.tsx
- Replace optimisticCancellationRunId state with a boolean; the
  component is keyed by run id, so the stored id could only ever be
  this run's own

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:15:35 -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
5cf1c7d183
Harden cancellation and interrupt lifecycles 2026-07-23 20:40:22 -04:00
Bryan Helmkamp
db473da2f3
Merge pull request #605 from fabro-sh/fix/remove-dead-agent-turn-limits
Remove dead agent execution limits
2026-07-23 20:15:39 -04:00
Bryan Helmkamp
7c771fc5d7
test(twin-openai): accept tool call histories 2026-07-23 20:11:21 -04:00
Bryan Helmkamp
67644c7c3c
Merge pull request #602 from fabro-sh/fix/openrouter-anthropic-prompt-caching
fix(llm): send cache_control breakpoints for Claude via OpenRouter
2026-07-23 20:06:10 -04:00
Bryan Helmkamp
43dcfa3b09
Merge pull request #604 from fabro-sh/fix/root-agent-todo-projection
Fix root-agent TODO projection ownership
2026-07-23 20:06:01 -04:00
Bryan Helmkamp
cdf1dce4f8
fix(agent): remove dead execution limits 2026-07-23 19:36:29 -04:00
Bryan Helmkamp
78718c101a
Merge remote-tracking branch 'origin/main' into fix/root-agent-todo-projection 2026-07-23 19:30:35 -04:00
Bryan Helmkamp
3c33e0fb69
Merge origin/main (three-layer crate layout) into fix/openrouter-anthropic-prompt-caching
The crate reorganization renamed lib/crates/ to lib/apps|components|foundation/.
Git followed all modified files across the rename; the only conflict was the
newly added codec/cache.rs, now placed at lib/components/fabro-llm/src/codec/cache.rs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 19:30:20 -04:00
Bryan Helmkamp
62c4ccaa93
Merge pull request #603 from fabro-sh/refactor/three-layer-crate-layout
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (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
Rust / Generated Docs (push) Waiting to run
refactor: organize crates into apps, components, and foundation
2026-07-23 19:27:55 -04:00
Bryan Helmkamp
d8d1c14116
Clarify stage TODO ownership and plan guidance 2026-07-23 18:23:37 -04:00
Bryan Helmkamp
e6e6fd21dd
test(llm): add live OpenRouter Claude prompt-caching round trip
Reuses run_multi_turn_cache_test — the same live cache verification the
anthropic, openai, and gemini routes already have. OpenRouter was the
one caching route with no live caller, which is exactly where the
missing-breakpoints bug hid: unit and wire tests prove we now send
cache_control, but only a live call proves OpenRouter forwards it to
Anthropic and cache reads actually appear.

Runs with: set -a && source .env && set +a && \
  cargo nextest run -p fabro-llm --profile e2e --run-ignored only \
  -E 'test(openrouter_claude_multi_turn_cache)'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:09:25 -04:00
Bryan Helmkamp
5c55b0c074
Fix stage TODO projection ownership 2026-07-23 18:05:22 -04:00
Bryan Helmkamp
e78f5ff957
Fix cancellation during subagent waits 2026-07-23 18:04:58 -04:00
Scott Werner
47bc772f7b refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00
Bryan Helmkamp
e5f0290229
fix(llm): send cache_control breakpoints for Claude via OpenRouter
Anthropic prompt caching is opt-in per request: without explicit
ephemeral cache_control breakpoints in the body, no cache writes or
reads ever happen. The OpenAI-compatible codec never emitted them, so
every run on openrouter Claude models billed the full conversation at
the uncached input rate on every turn (0 cache tokens on the billing
page, confirmed by OpenRouter's activity portal).

- Add a `cache_control_breakpoints` model feature declaring that a
  route only caches when the request marks the cacheable prefix; set it
  on the builtin OpenRouter Claude rows. Catalog build rejects the flag
  without `prompt_cache`.
- Teach the Chat Completions wire shape a parts-form content variant so
  a message can carry the annotation; unmarked messages keep the
  plain-string form for compatibility with strict servers.
- Mark the last system message (covers tools + system upstream) and the
  second-to-last user turn, counting tool results as user turns —
  mirroring the anthropic codec's placement so agent loops get
  incremental cache hits.
- Extract the shared placement/opt-out policy into codec::cache and
  refactor the anthropic codec onto it; anthropic wire snapshots are
  unchanged.
- Honor `provider_options.<name>.auto_cache = false` as an opt-out and
  consume the control key instead of merging it into the body.
- Mirror the new feature through settings (fabro-config), the OpenAPI
  schema, and the generated TypeScript client.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 17:55:41 -04:00
Bryan Helmkamp
d96381c897
Merge pull request #599 from fabro-sh/fabro/run/01KY7WQ92JWT90307EBQY6P2HV
Add `output_schema` support on command (parallelogram) nodes
2026-07-23 17:36:37 -04:00
Bryan Helmkamp
7bdee5b494
Merge remote-tracking branch 'origin/main' into pr-599
# Conflicts:
#	docs/public/agents/outputs.mdx
#	docs/public/reference/dot-language.mdx
2026-07-23 17:24:33 -04:00
Bryan Helmkamp
b558af070f
Merge pull request #601 from fabro-sh/fabro/run/01KY7Y01REECZ24XXTMBZ3PPV9
Provider-scoped model catalog: `(provider, model slug)` as stable ident…
2026-07-23 17:14:51 -04:00