Skip to content

feat(sdkgen)!: generate only reachable stdlib types in Python and TypeScript SDKs - #5006

Closed
sxlijin wants to merge 4 commits into
sxlijin/sdkgen-disable-stdlib-functionsfrom
sxlijin/sdkgen-reachable-stdlib-types
Closed

sxlijin wants to merge 4 commits into
sxlijin/sdkgen-disable-stdlib-functionsfrom
sxlijin/sdkgen-reachable-stdlib-types

Conversation

@sxlijin

@sxlijin sxlijin commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Final shrinking pass for baml_sdk LoC by only generating stdlib types if they are reachable from the user's code

  • Roots:
    • every generated function and every user type;
    • the always-kept namespaces:
      • baml.media (Image, Audio, Video, Pdf), which are bridge-owned classes;
      • baml.errors, baml.panics, ai.errors and ai.stream. The runtime hands the host error, panic and stream-event values (for example ai.stream.Done) that no signature names, and decoding them needs these typemap entries.
  • Edges: class properties and methods; function arguments, return types, throws and watchers; alias targets, including through generics, unions, maps, callables and futures. A type token (Ty::Type) reaches the bridge-owned reflect.Type.

The PR also keeps pruned namespaces importable:

  • The Python baml package always re-exports BamlError, BamlPanic and UNSET.
  • An otherwise empty TypeScript index.ts gets export {};, because tsc rejects imports from an empty script.
image

@sxlijin
sxlijin added this pull request to stack #5007 September 26, 2026 21:16
@vercel

vercel Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
developer-docs Ready Ready Preview Sep 28, 2026 5:45pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: ddd8e137-0c83-49f6-a276-31479fa5f1d2

📥 Commits

Reviewing files that changed from the base of the PR and between 88fa664 and e7977aa.

📒 Files selected for processing (2)
  • baml_language/sdks/python/rust/sdkgen_python_pydantic2/src/lib.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/lib.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

SDK generation now removes unreachable built-in types while retaining types reached through declarations. Python runtime and stub output share bridge re-exports for the baml leaf, including when it is empty. TypeScript output adds export {}; when a generated namespace has no declarations.

Changes

SDK built-in filtering and output

Layer / File(s) Summary
Built-in type reachability
baml_language/crates/baml_sdkgen_types/src/lib.rs, baml_language/crates/baml_sdkgen_types/src/reachable.rs
Adds and exports symbol-pool filtering for built-in types. The traversal follows declaration type references and retains built-ins in specified namespaces. Tests cover reachable types, cycles, and retained namespaces.
Python SDK filtering and package re-exports
baml_language/sdks/python/rust/sdkgen_python_pydantic2/src/lib.rs, baml_language/sdks/python/rust/sdkgen_python_pydantic2/src/leaf.rs
Python generation filters unreachable built-in types. Runtime and stub rendering share root re-export handling, including for empty leaves. Tests check retained types and error-wrapper re-exports.
TypeScript SDK filtering and empty modules
baml_language/sdks/typescript/sdkgen_typescript_shared/src/lib.rs
TypeScript generation filters unreachable built-in types and adds export {}; when a generated namespace has no declarations. Tests check reachable types and empty output.

Priority: ➖ Normal

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

Change: Feature

Suggested reviewers: aaronvg

Merge Risk: ⚪ Minimal · up to e7977

No identified issue blocks merging after normal checks.

Architecture Summary

Architecture risk: 🔵 Low · up to e7977

The change affects 1 system.

Changed systems: baml_language

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — baml_language (service) was modified; 5 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in baml_language/crates/baml_sdkgen_types/src/lib.rs: Declares the private reachable module.
  • observed — Modified behavior in baml_language/crates/baml_sdkgen_types/src/lib.rs: Re-exports reachable::without_unreachable_builtin_types publicly.
  • observed — Modified behavior in baml_language/sdks/python/rust/sdkgen_python_pydantic2/src/leaf.rs: Added BAML_ROOT_REEXPORTS and baml_root_reexports, which return the bridge re-export import for the baml leaf and an empty string for other leaves. Empty runtime leaf bodies now return that re-export when applicable instead of always returning an empty string.
  • observed — Modified behavior in baml_language/sdks/python/rust/sdkgen_python_pydantic2/src/leaf.rs: Runtime rendering now appends the shared helper’s re-export text instead of performing an inline leaf check and constructing the import there.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.38% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 29 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: generating only reachable standard-library types in the Python and TypeScript SDKs. The breaking-change marker is appropriate because the pul…
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

A rabbit checks the types in rows,
Keeps each path that reachability shows.
The unused names hop out of sight,
While root-leaf imports stay in flight.
Empty modules still stand upright,
Then carrots mark the build complete.

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

@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.

@blacksmith-sh

This comment has been minimized.

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Binary size checks failed

❌ 2 violations · ✅ 1 passed

⚠️ Please fix the size gate issues or acknowledge them by updating baselines.

Artifact Platform File Gzip Gated on Baseline Delta Status
✅ baml-cli Linux 🔒 61.1 MB 25.4 MB file 73.1 MB -11.9 MB (-16.3%) OK
❌ packed-program Linux 🔒 40.1 MB 15.9 MB file 28.9 MB +11.2 MB (+38.7%) FAIL
❌ bridge_wasm WASM 28.2 MB 🔒 7.8 MB gzip 5.8 MB +2.1 MB (+35.8%) FAIL

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

Details & how to fix

Violations:

  • packed-program (Linux) file_bytes: 40.1 MB exceeds limit of 29.8 MB (exceeded by +10.4 MB, policy: max_file_bytes)
  • packed-program (Linux) file_delta_pct: +38.7% exceeds limit of 3.0% (exceeded by +35.7pp, policy: max_delta_pct)
  • bridge_wasm (WASM) gzip_bytes: 7.8 MB exceeds limit of 5.9 MB (exceeded by +2.0 MB, policy: max_gzip_bytes)
  • bridge_wasm (WASM) gzip_delta_pct: +35.8% exceeds limit of 3.0% (exceeded by +32.8pp, policy: max_delta_pct)

Add/update baselines:

.ci/size-gate/wasm32-unknown-unknown.toml:

[artifacts.bridge_wasm]
file_bytes = 28221460
gzip_bytes = 7834305

.ci/size-gate/x86_64-unknown-linux-gnu.toml:

[artifacts.packed-program]
file_bytes = 40142856
gzip_bytes = 15871097

Generated by cargo size-gate · workflow run

@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 9302453 to c7d3618 Compare September 26, 2026 23:24
@sxlijin sxlijin changed the title Omit unreachable built-in types from Python and TypeScript SDKs feat(sdkgen)!: generate only reachable stdlib types in Python and TypeScript SDKs Sep 26, 2026
@sxlijin
sxlijin marked this pull request as ready for review September 26, 2026 23:35
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-26T23:39:02.106687Z c7d3618 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: c7d3618b96

ℹ️ 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".

Comment on lines +35 to +38
let referenced = match ty {
Ty::Type => Some(&reflect_type),
_ => named_reference(ty),
};

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 Preserve types that can escape through unknown

When a generated function exposes unknown, a value of any built-in class can cross the SDK boundary even though its static signature contains no named reference—for example, function f() -> unknown { baml.time.Duration.from_seconds(1) }. This traversal treats Ty::Unknown as having no reachability edges, so baml.time.Duration is removed from the generated typemap; Python then fails in _decode_class with Unknown class FQN, while TypeScript silently returns a plain object instead of the generated instance. Detecting an exposed unknown needs to conservatively retain possible built-in runtime values (or otherwise provide a decoder fallback that preserves them).

Useful? React with 👍 / 👎.

@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from c7d3618 to 50941a2 Compare September 27, 2026 20:31
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 50941a2 to 19994d2 Compare September 27, 2026 20:43
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch 2 times, most recently from 08bf58a to 3b1a88a Compare September 27, 2026 20:59
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 3b1a88a to cc2263d Compare September 27, 2026 20:59
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from cc2263d to 88fa664 Compare September 28, 2026 06:49
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 88fa664 to e7977aa Compare September 28, 2026 07:24
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from e7977aa to 195ec57 Compare September 28, 2026 09:05
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 195ec57 to 7386141 Compare September 28, 2026 16:03
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 7386141 to 756572c Compare September 28, 2026 16:04
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 756572c to 571721f Compare September 28, 2026 16:08
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 571721f to 9358ca3 Compare September 28, 2026 16:31
@sxlijin
sxlijin added this pull request to the merge queue Sep 28, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue because a pull request earlier in the stack was removed Sep 28, 2026
sxlijin and others added 4 commits September 28, 2026 10:27
Generated SDKs now emit a built-in type only when it is reachable from a
generated declaration. The roots are every kept function, every user
type, and the baml.media types (always exposed as bridge-owned classes);
reachability follows class properties and methods, function signatures
(arguments, return, throws, watchers), and alias targets.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Pruning can leave a namespace with no declarations:

- Python: the `baml` package re-exports BamlError, BamlPanic, and UNSET
  even when no built-in type is generated there.
- TypeScript: an otherwise empty `index.ts` gets `export {};`, since tsc
  refuses to import from an empty script.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signature reachability misses stdlib values the runtime hands the host
on its own. Always generate the types in baml.errors, baml.panics,
ai.errors, and ai.stream (errors, panics, and stream events) alongside
baml.media, and treat a type token (Ty::Type) as a reference to the
bridge-owned reflect.Type class.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Replace the catch-all in the reachability walk with an exhaustive match
over type variants, so a new variant needs an explicit decision. Media
now reaches the `baml.media` classes SDKs render for it (all four for
generic media), alongside type tokens reaching `reflect.Type`. Add a test
for function argument and return types reached through reified generic
arguments (user and stdlib generics), map values, unions, callables,
futures, interface arguments, and throws.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sxlijin
sxlijin force-pushed the sxlijin/sdkgen-reachable-stdlib-types branch from 59b887d to b2bd13d Compare September 28, 2026 17:27
@blacksmith-sh

blacksmith-sh Bot commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
bex_engine/
telemetry::failure_tests::disk_error_with_full_file_queue_and_chunk_pool_does_not_fail_
application
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

This branch was successfully deployed

1 active deployment
Preview – developer-docs — b2bd13db Deployed Sep 28, 2026 by vercel[bot]
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