Skip to content

Prototype BEPv4 Agent lifecycle and providers - #4235

Draft
aaronvg wants to merge 23 commits into
canaryfrom
aaron/custom-llm-providers-v4
Draft

Prototype BEPv4 Agent lifecycle and providers#4235
aaronvg wants to merge 23 commits into
canaryfrom
aaron/custom-llm-providers-v4

Conversation

@aaronvg

@aaronvg aaronvg commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • define the BEPv4 normal model lifecycle as Task<T> + ai.run.Agent<T> + an AgentProvider with begin<T>, step<T>, and submit
  • remove the parallel Completion/Generation provider hierarchy: providers perform one model step, while Agent owns looping, application tool execution, callbacks, budgets, handoffs, and terminal outcomes
  • implement OpenAI Responses, Anthropic Messages, Google AI, Google Vertex, and Claude Code providers in baml_src_temp2
  • support native structured output, strict schemas, result-tool output, prompt/SAP fallback, arrays, unions, structural media, parallel tool calls, and save/resume
  • make provider steps and tool-result submission transactional; validate malformed tool batches, provider-instance ownership, provider configuration, and nominal-plus-structural output fingerprints before effects
  • reorganize ai_scenarios into zero-argument runnable examples with assertions in tests/, scenario-local utilities, explicit custom runners, goal-oriented comments, and //# graph regions
  • expand workflow graphs through task.run(...), concrete generic runner dispatch, interface implementations, and method calls
  • merge the current canary, taking its newer CLI and type-system work while preserving explicit raw-source loading for baml_src_temp2

Why

The previous prototype allowed normal model work to be described through overlapping Completion, Generation, Provider, and Runner abstractions. That made ownership unclear and risked recursive provider -> runner -> provider execution.

This design has one ordinary lifecycle:

  1. the task renders the prompt and declares T
  2. the Agent asks its provider for one step
  3. the Agent executes or returns tool calls
  4. the Agent submits correlated results and repeats until it returns Done<T>, Handoff, or BudgetReached

Streaming, realtime sessions, background jobs, batch work, transcription, caches, and external harnesses remain explicit separate lifecycles because they do not obey the same one-step protocol.

Usage

Every public scenario is zero-argument and can be run directly:

baml run --from crates/baml_tests/baml_src_temp2 ai_scenarios.observe_an_agent

The provider configuration and integration tests under ai_scenarios cover OpenAI Responses only—there is no Chat Completions implementation.

Diff size

Against the merged canary: 28,961 additions and 1,033 deletions across 281 files. Nineteen binary snapshot files are excluded from the line totals.

Area Files Added Removed
BEPv4 design docs 20 3,873 0
Temp2 Agent API and support 53 4,510 0
Temp2 scenarios and tests 115 8,065 0
Temp2 providers 45 8,821 0
Rust compiler and CLI 19 2,126 336
BAML stdlib support 4 1,026 664
Fixtures, snapshots, and config 25 540 33

Swift realtime support is present after the canary merge, but canary now contains the same Swift changes, so there is no remaining Swift diff in this PR.

Validation

  • cargo fmt --all -- --check
  • cargo build -p baml_cli
  • cargo nextest run -p baml_cli -p sys_llm -p sys_ops --no-fail-fast — 989 passed
  • baml check --from crates/baml_tests/baml_src_temp2 — 212 files checked
  • offline temp2 suite — 156 passed
  • live OpenAI, Anthropic, Google AI, and Google Vertex matrix through infisical run --env=test -- ... — 25 passed
  • direct smoke run of ai_scenarios.observe_an_agent — passed

The branch is merged with origin/canary at fb2527cd2.


Note

High Risk
Large architectural shift in how model calls, tools, retries, and conversations behave, plus broad provider and compiler integration; regressions could affect auth, side-effect safety, and resumption semantics.

Overview
Introduces BEP-064 (BEPv4): a single normal lifecycle where ai.run.Agent drives AgentProvider (begin / step / submit), replacing overlapping Completion/Generation/provider loops. Direct LLM calls lower to a default Agent and unwrap Done<T>; streaming, jobs, realtime, and harnesses stay separate lifecycles.

Adds the ai stdlib surface in baml_builtins2: Task<T>, outcomes (Done, BudgetReached, Handoff, Interrupted), conversations, open ai.Failure + UnknownError, tool limits, prompt recipes, harness helpers, and internal Agent plumbing (tool dispatch, cancellation, output fingerprints, direct-call lowering).

The executable corpus in baml_src_temp2 gains multi-vendor AgentProvider implementations (OpenAI Responses, Anthropic, Google, Vertex, Claude Code), reorganized ai_scenarios, and provider request tests—grounded by new design docs under _plan/bepv4 (guides, error model, namespace layout). Minor comment tweak in dedent.rs; .baml/.gitignore now ignores all files under .baml/.

Reviewed by Cursor Bugbot for commit 43c8201. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview Jul 30, 2026 5:34pm
old-promptfiddle Ready Ready Preview Jul 30, 2026 5:34pm
promptfiddle Building Building Preview Jul 30, 2026 5:34pm
promptfiddle2 Ready Ready Preview Jul 30, 2026 5:34pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9282cd93-649e-4509-bda8-0f8749818f3f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch aaron/custom-llm-providers-v4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…oviders-v4

# Conflicts:
#	baml_language/crates/baml_compiler2_tir/src/builder.rs
#	baml_language/crates/baml_compiler2_tir/src/inference.rs
#	baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded.snap
#	baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded_unoptimized.snap
@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

Comment thread baml_language/crates/baml_cli/src/playground_command.rs
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

⚠️ Missing size-gate report(s):

  • linux (job result: success)
  • macos (job result: success)
  • windows (job result: success)
  • wasm (job result: success)

The unified report below only reflects platforms that produced output.

Binary size checks passed

Artifact Platform File Gzip Gated on Baseline Delta Status

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

}
}

function task<T>(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should probably be methods on Task itself:
Task.new and Task.named or something like that

// The empty root capability. Specific operations require a narrower provider
// interface so a realtime channel cannot accidentally promise a final T.
interface Provider {
function name(self) -> string throws never { "provider" }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should not default

}
}

interface GenerationProvider requires Provider {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between CompletionProvider and GenerationProvider? Could probably be deduped

(input * price.input_per_million + output * price.output_per_million) / 1000000.0
}

function aggregate_usage(responses: ResponseMetadata[]) -> Usage throws never {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this used? how is it used? does impl of runners call this automatically for the ones we support?

@@ -0,0 +1,42 @@
// Provider-owned continuation state. Concrete implementations retain wire

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

messages stuff should probably go in its own namespace like ns_chat or something: it is an implementation part for multi-turn runners not a base part of the framework

…oviders-v4

# Conflicts:
#	baml_language/crates/baml_cli/src/check_command.rs
#	baml_language/crates/baml_cli/src/commands.rs
#	baml_language/crates/baml_cli/src/describe_command.rs
#	baml_language/crates/baml_cli/src/format.rs
#	baml_language/crates/baml_cli/src/generate.rs
#	baml_language/crates/baml_cli/src/pack_command.rs
#	baml_language/crates/baml_cli/src/run_command.rs
#	baml_language/crates/baml_cli/src/test_command.rs

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5143590. Configure here.

@aaronvg aaronvg changed the title Prototype BEPv4 task and runner model Prototype BEPv4 Agent lifecycle and providers Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants