Skip to content

fix(prompt): preserve nested media interpolation - #4290

Merged
codeshaunted merged 4 commits into
canaryfrom
avery/b-1039
Jul 31, 2026
Merged

fix(prompt): preserve nested media interpolation#4290
codeshaunted merged 4 commits into
canaryfrom
avery/b-1039

Conversation

@codeshaunted

@codeshaunted codeshaunted commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • assemble built-in prompt tags in the VM so nested image, audio, video, and PDF values remain structural PromptAst media
  • reuse recursive ToString traversal with a prompt-specific sink; parent overrides own their subtree and ordinary string interpolation remains unchanged
  • cover nested classes, arrays, maps, all media kinds, and ToString precedence in native BAML tests, plus a Rust assertion over the actual PromptAst nodes

Addresses B-1039.

Tests

  • cargo test -p baml_tests --test prompt_tag_runtime
  • baml test -i root.prompt_tag_runtime::*
  • cargo test -p bex_vm
  • cargo test -p bex_engine --test backtick_strings
  • cargo test -p sys_llm media
  • cargo test -p baml_tests baml_std
  • cargo test -p baml_tests --test baml_src bytecode
  • cargo clippy -p bex_vm -p sys_ops -p baml_tests --tests -- -D warnings
  • repository pre-commit hooks

Summary by CodeRabbit

  • New Features
    • Prompt templates now preserve embedded media with consistent URL rendering, including nested media inside classes, arrays, and maps.
    • Prompt assembly now preserves role metadata in the rendered prompt and associated structured metadata.
  • Bug Fixes
    • Media interpolation now only processes recognized media values, avoiding incorrect decoding from unrelated objects.
    • Custom ToString conversions and redaction overrides correctly apply to media-containing values.
    • Structural rendering continues to respect truncation and cycle-detection behavior.
  • Tests
    • Added and updated runtime tests covering nested media, media + ToString overrides/redaction, and role/metadata preservation, with assertions based on rendered prompt text and JSON metadata.

@linear

linear Bot commented Jul 30, 2026

Copy link
Copy Markdown

B-1039

@vercel

vercel Bot commented Jul 30, 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 31, 2026 6:25pm
promptfiddle2 Ready Ready Preview Jul 31, 2026 6:25pm

Request Review

@vercel
vercel Bot temporarily deployed to Preview – beps July 30, 2026 19:41 Inactive
@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.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (2)
  • baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded_unoptimized.snap is excluded by !**/*.snap

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e8de380-9ffc-45b1-8dc6-e6be648afad5

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
📝 Walkthrough

Walkthrough

Prompt tagged-template assembly now runs in the BEX VM, preserving roles and nested media while applying baml.ToString behavior. Structural rendering uses sinks, media class validation was added, and runtime tests cover nested media, role metadata, and overrides.

Changes

Prompt AST media assembly

Layer / File(s) Summary
Prompt assembly contract
baml_language/crates/baml_builtins2/.../llm_types.baml, baml_language/crates/sys_ops/src/lib.rs
Prompt values are passed directly to native assemble_prompt_ast; the previous value-rendering helper and sys_ops implementation are removed.
Sink-based structural rendering
baml_language/crates/bex_vm/src/package_baml/root.rs, baml_language/crates/bex_vm/src/package_baml/json.rs
Structural and override-aware rendering streams into a sink, while media extraction validates recognized media classes.
BEX VM prompt assembly
baml_language/crates/bex_vm/src/package_baml/llm.rs, baml_language/crates/bex_vm/src/package_baml/mod.rs
The VM assembles role-based messages and content nodes, preserves role metadata, supports media values, and handles deferred rendering through continuations.
Media interpolation validation
baml_language/crates/baml_tests/...
Runtime tests verify role metadata, media nested in classes, arrays, and maps, plus nested and parent baml.ToString overrides.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Poem

A rabbit hops where prompts compile,
With media nestled row by row.
Roles split messages in style,
Sinks let ToString smoothly flow.
“REDACTED!” thumps the ground—
AST carrots all around!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing prompt handling to preserve nested media interpolation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch avery/b-1039

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.

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 30, 2026 19:49 Inactive
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

Binary size checks passed

7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
baml-cli Linux 🔒 27.4 MB 11.6 MB file 27.4 MB -12.2 KB (-0.0%) OK
packed-program Linux 🔒 17.7 MB 7.3 MB file 17.7 MB +23.1 KB (+0.1%) OK
baml-cli macOS 🔒 21.3 MB 10.2 MB file 21.3 MB -35.0 KB (-0.2%) OK
packed-program macOS 🔒 13.8 MB 6.4 MB file 13.8 MB -4.6 KB (-0.0%) OK
baml-cli Windows 🔒 22.9 MB 10.4 MB file 23.0 MB -54.9 KB (-0.2%) OK
packed-program Windows 🔒 14.8 MB 6.5 MB file 14.8 MB -14.3 KB (-0.1%) OK
bridge_wasm WASM 16.8 MB 🔒 4.6 MB gzip 4.6 MB -41.8 KB (-0.9%) OK

🔒 = 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

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
baml_language/crates/bex_vm/src/package_baml/llm.rs (1)

16-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unit tests for PromptContentSink::push_text's merge logic.

This adjacent-string-merging logic (and the Arc::try_unwrap fallback path) is pure, VM-independent, and easy to unit-test in isolation, but no #[cfg(test)] coverage was added here — coverage is deferred to the integration-style baml_tests crate (layer 4). As per coding guidelines, **/*.rs changes should prefer unit tests over integration tests where possible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/crates/bex_vm/src/package_baml/llm.rs` around lines 16 - 59,
Add focused unit tests in the module containing PromptContentSink, under a
#[cfg(test)] section, covering push_text merging consecutive string parts,
preserving non-string parts while appending text, and handling shared Arc values
through the Arc::try_unwrap fallback. Keep the tests VM-independent and assert
the resulting PromptAstSimple structure after into_content.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@baml_language/crates/bex_vm/src/package_baml/llm.rs`:
- Around line 61-79: Update prompt_role_name and the role-marker handling in
finish() to extract and propagate both Role.name and Role.metadata, returning
metadata converted with the existing json::value_to_serde helper. Use the
extracted metadata in both PromptAst::Message constructions instead of
serde_json::Value::Null, while preserving null metadata for non-role messages.

---

Nitpick comments:
In `@baml_language/crates/bex_vm/src/package_baml/llm.rs`:
- Around line 16-59: Add focused unit tests in the module containing
PromptContentSink, under a #[cfg(test)] section, covering push_text merging
consecutive string parts, preserving non-string parts while appending text, and
handling shared Arc values through the Arc::try_unwrap fallback. Keep the tests
VM-independent and assert the resulting PromptAstSimple structure after
into_content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d1b07f3a-2a3b-47fe-b0f6-ae01efa3ce35

📥 Commits

Reviewing files that changed from the base of the PR and between 8f1fa6f and 34a14e1.

⛔ Files ignored due to path filters (9)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/crates/baml_cli/src/snapshots/baml_cli__describe_command_tests__render_builtin_namespace_llm.snap is excluded by !**/*.snap
  • baml_language/crates/baml_cli/src/snapshots/baml_cli__describe_command_tests__render_builtin_package_listing.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/prompt_tag_runtime.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____03_ppir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/src/compiler2_tir/snapshots/baml_tests__compiler2_tir__phase5__snapshot_baml_package_items.snap is excluded by !**/*.snap
📒 Files selected for processing (9)
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/llm_types.baml
  • baml_language/crates/baml_tests/Cargo.toml
  • baml_language/crates/baml_tests/baml_src/ns_prompt_tag_runtime/prompt_tag_runtime.baml
  • baml_language/crates/baml_tests/tests/prompt_tag_runtime.rs
  • baml_language/crates/bex_vm/src/package_baml/json.rs
  • baml_language/crates/bex_vm/src/package_baml/llm.rs
  • baml_language/crates/bex_vm/src/package_baml/mod.rs
  • baml_language/crates/bex_vm/src/package_baml/root.rs
  • baml_language/crates/sys_ops/src/lib.rs
💤 Files with no reviewable changes (1)
  • baml_language/crates/sys_ops/src/lib.rs

Comment thread baml_language/crates/bex_vm/src/package_baml/llm.rs Outdated
@vercel
vercel Bot temporarily deployed to Preview – beps July 30, 2026 21:27 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 30, 2026 21:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – beps July 30, 2026 21:43 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 30, 2026 21:50 Inactive

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@baml_language/crates/bex_vm/src/package_baml/llm.rs`:
- Around line 37-41: Run the required Rust validation for the changes around the
prompt-part mutation logic, including cargo test --lib, and ensure the tests
complete successfully before finalizing the PR.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5e10b1b1-3038-4d9e-a4a0-850731b107d5

📥 Commits

Reviewing files that changed from the base of the PR and between 0bbce9c and 4bf16ea.

📒 Files selected for processing (2)
  • baml_language/crates/baml_tests/tests/prompt_tag_runtime.rs
  • baml_language/crates/bex_vm/src/package_baml/llm.rs

Comment thread baml_language/crates/bex_vm/src/package_baml/llm.rs
@vercel
vercel Bot temporarily deployed to Preview – beps July 31, 2026 18:20 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 31, 2026 18:25 Inactive
@codeshaunted
codeshaunted added this pull request to the merge queue Jul 31, 2026
Merged via the queue into canary with commit 098a8ce Jul 31, 2026
83 checks passed
@codeshaunted
codeshaunted deleted the avery/b-1039 branch July 31, 2026 19:01
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.

1 participant