Skip to content

test(sdk_tests): cover interface types (BEP-044) at the SDK boundary#3939

Open
sxlijin wants to merge 1 commit into
canaryfrom
sam/sdk-tests-interfaces
Open

test(sdk_tests): cover interface types (BEP-044) at the SDK boundary#3939
sxlijin wants to merge 1 commit into
canaryfrom
sam/sdk-tests-interfaces

Conversation

@sxlijin

@sxlijin sxlijin commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Adds SDK e2e coverage for what happens when BAML functions receive and return interface-typed values.

Changes

  • New fixture sdk_tests/fixtures/type_shapes/baml_src/ns_interfaces/types.baml: a Shape interface with three implementors (Square/Rect via in-body implements, Circle via out-of-body implements Shape for), functions returning Shape, functions receiving Shape (with engine-side area() dispatch), and round trips in bare, list, optional, and class-field (ShapeBox) positions.
  • Python tests (roundtrip_tests/test_interfaces.py, 17 tests) and TypeScript tests (roundtrip_interfaces.test.ts, 16 tests), each pinning that SDK's current behavior.

Behavior findings (pinned by these tests)

Interface positions codegen as typing.Any / unknown (client_codegen.rs: TirTy::Interface(..) => cg::Ty::BuiltinUnknown); the values crossing the boundary are concrete class instances.

  1. Interface returns work in both SDKs — the host receives the concrete implementing class, for both implements forms.
  2. Interface parameters diverge between SDKs. The python bridge encodes host instances by their runtime class, so the engine dispatches interface methods correctly and round trips preserve the concrete class everywhere. The nodejs bridge encodes by the declared codegen type (unknown), so class identity is lost: interface-method dispatch panics with VM internal error: virtual call could not resolve interface method, and round-tripped interface positions come back as plain objects. Receiving interfaces is effectively unusable from the node SDK today.
  3. No encode-time conformance check in either SDK: passing a non-implementor (or a primitive) into an interface param only fails inside the VM at dispatch time, as a BamlPanic, not as a host-side TypeError.
  4. Impl-method host bindings are dead in both SDKs: sdkgen emits area/area_async bindings on implementing classes under user.interfaces.Square.area, but the engine registers interface-impl methods under a synthetic Shape$for$Square name, so calling the binding panics with Function not found.

The KNOWN-GAP tests pin current behavior deliberately, so fixing any of these flips a test and forces an intentional pin update.

Test plan

  • cargo nextest run -p sdk_test_python_pydantic2 -p sdk_test_typescript_node — 29/29 pass locally (pytest/ruff/pyright, vitest/tsc/esm_output/attw across all fixtures).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added roundtrip interface coverage for Python and TypeScript Node SDKs.
    • Verified interface values preserve concrete implementing class identity across returns, parameters, and nested contexts (lists, optionals, and fields).
    • Added assertions for interface dispatch behavior, including pinned expected failures for unsupported parameter encoding and missing host bindings.

@vercel

vercel Bot commented Jul 8, 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, Comment Jul 8, 2026 4:30am
promptfiddle Ready Ready Preview, Comment Jul 8, 2026 4:30am
promptfiddle2 Ready Ready Preview, Comment Jul 8, 2026 4:30am

Request Review

@github-actions

github-actions Bot commented Jul 8, 2026

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 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3048ca34-6010-435b-9c67-606566de5890

📥 Commits

Reviewing files that changed from the base of the PR and between e94c57d and 725e5b7.

📒 Files selected for processing (3)
  • baml_language/sdk_tests/crates/python_pydantic2/type_shapes/customizable/roundtrip_tests/test_interfaces.py
  • baml_language/sdk_tests/crates/typescript_node/type_shapes/customizable/roundtrip_interfaces.test.ts
  • baml_language/sdk_tests/fixtures/type_shapes/baml_src/ns_interfaces/types.baml
🚧 Files skipped from review as they are similar to previous changes (3)
  • baml_language/sdk_tests/fixtures/type_shapes/baml_src/ns_interfaces/types.baml
  • baml_language/sdk_tests/crates/python_pydantic2/type_shapes/customizable/roundtrip_tests/test_interfaces.py
  • baml_language/sdk_tests/crates/typescript_node/type_shapes/customizable/roundtrip_interfaces.test.ts

📝 Walkthrough

Walkthrough

This PR adds a BAML interface fixture plus Python and TypeScript SDK tests covering interface-typed returns, parameter dispatch, and roundtrip behavior, including pinned known-gap failures.

Changes

Interface Fixture and Roundtrip Tests

Layer / File(s) Summary
Shape interface fixture and functions
baml_language/sdk_tests/fixtures/type_shapes/baml_src/ns_interfaces/types.baml
Defines Shape, its implementors, ShapeBox, and helper functions for return, dispatch, and roundtrip paths.
Python roundtrip and dispatch tests
baml_language/sdk_tests/crates/python_pydantic2/type_shapes/customizable/roundtrip_tests/test_interfaces.py
Adds tests for concrete-class preservation and pinned known-gap panics in return, parameter, and nested interface positions.
TypeScript dispatch and known-gap tests
baml_language/sdk_tests/crates/typescript_node/type_shapes/customizable/roundtrip_interfaces.test.ts
Adds setup and assertions for interface dispatch failures, non-implementor inputs, and non-callable impl-method bindings.
TypeScript roundtrip tests
baml_language/sdk_tests/crates/typescript_node/type_shapes/customizable/roundtrip_interfaces.test.ts
Adds round-trip assertions for interface-typed values, lists, optionals, and interface fields inside a container class.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Test Suite
  participant BAML Runtime
  participant Encode/FFI Boundary
  participant Engine

  Test Suite->>BAML Runtime: call Shape-typed function
  BAML Runtime->>Encode/FFI Boundary: encode value across boundary
  Encode/FFI Boundary->>Engine: dispatch area() on Shape
  alt concrete implementor
    Engine-->>Encode/FFI Boundary: resolved result
    Encode/FFI Boundary-->>BAML Runtime: decoded value
    BAML Runtime-->>Test Suite: concrete class instance or result
  else non-implementor or lost class identity
    Engine-->>Encode/FFI Boundary: dispatch failure
    Encode/FFI Boundary-->>BAML Runtime: error propagated
    BAML Runtime-->>Test Suite: throw or reject
  end
Loading

Poem

A rabbit met a Shape today,
And tested every hop and way.
Square and Circle crossed the gate,
Roundtrips, dispatch, all stayed straight. 🐇

🚥 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 accurately summarizes the new SDK boundary test coverage for interface types and BEP-044.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 sam/sdk-tests-interfaces

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.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e94c57d438

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

import pytest

import baml_sdk # noqa: F401 — initializes the BAML runtime
from baml_core.errors import BamlPanic

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Import BamlPanic from the generated SDK

In the Python SDK test fixture, this module is collected inside the generated per-fixture environment, whose pyproject installs baml_bridge and exposes the public error wrappers through baml_sdk.baml (as the existing error/cancellation tests do). There is no packaged baml_core.errors module in that environment, so pytest fails during collection with ModuleNotFoundError before any of the new interface tests can run.

Useful? React with 👍 / 👎.

Adds a `ns_interfaces` fixture: an interface with in-body and
out-of-body `implements` forms, functions that return and receive
interface-typed values, and round trips in bare, list, optional, and
class-field positions.

Host tests pin the current per-SDK behavior, which diverges:

- python: fully working — interface returns and params carry the
  concrete class across the boundary and the engine dispatches
  interface methods on host-constructed instances.
- nodejs: returns work, but inbound encode is driven by the declared
  codegen type (`unknown` for interface positions), so class identity
  is lost — interface-method dispatch panics and round-tripped values
  come back as plain objects.

Both SDKs emit host bindings for interface-impl methods that the
engine registers under a synthetic `Iface$for$Class` name, so calling
them panics with "Function not found" (also pinned).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Binary size checks passed

7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
baml-cli Linux 🔒 21.9 MB 9.4 MB file 21.5 MB +355.1 KB (+1.6%) OK
packed-program Linux 🔒 15.9 MB 6.7 MB file 15.6 MB +258.2 KB (+1.7%) OK
baml-cli macOS 🔒 16.9 MB 8.1 MB file 16.6 MB +298.3 KB (+1.8%) OK
packed-program macOS 🔒 12.3 MB 5.8 MB file 12.1 MB +198.9 KB (+1.6%) OK
baml-cli Windows 🔒 18.4 MB 8.4 MB file 18.1 MB +300.0 KB (+1.7%) OK
packed-program Windows 🔒 13.2 MB 5.9 MB file 13.0 MB +202.9 KB (+1.6%) OK
bridge_wasm WASM 14.6 MB 🔒 4.2 MB gzip 4.1 MB +93.0 KB (+2.3%) 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

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