Skip to content

refactor(typescript): prepare the SDK for Node, Web, and Workers - #4051

Merged
sxlijin merged 1 commit into
canaryfrom
sam/typescript-runtime-matrix
Jul 16, 2026
Merged

sxlijin merged 1 commit into
canaryfrom
sam/typescript-runtime-matrix

Conversation

@sxlijin

@sxlijin sxlijin commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Consolidate the Node bridge and TypeScript generator under sdks/typescript so Node and Web can share the same SDK foundation.
  • Add typescript/web as a generator output and make the SDK test harness runtime-aware with vitest_node, vitest_web, and vitest_workers configurations.
  • Preserve the existing Node runtime behavior while staging browser and Workers suites for the implementation PR later in this stack.

Why

This isolates the TypeScript/Node refactor needed for multi-runtime testing from the shared Wasm bridge and browser/Workers implementations, so reviewers can verify that the existing Node SDK remains intact before the new runtime code lands.

Impact

This is stack 1 of 3 and is based directly on canary. The Web and Workers configurations are structural in this PR; their runtime implementations arrive in the later PRs.

Checks

  • mise run stow
  • mise run fmt
  • mise run clippy

Summary by CodeRabbit

  • New Features

    • Added TypeScript SDK support for Node.js and web targets.
    • Added synchronous and asynchronous function calls with cancellation support.
    • Added media types, streaming, host callbacks, runtime error details, and usage/trace collection.
    • Added configurable runtime package generation for browser-based SDKs.
  • Bug Fixes

    • Improved error decoding, handle lifecycle management, optional argument validation, and generic type handling.
  • Chores

    • Updated build, test, packaging, and release workflows to use the TypeScript SDK implementation.

@vercel

vercel Bot commented Jul 16, 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 16, 2026 5:05am
promptfiddle Ready Ready Preview, Comment Jul 16, 2026 5:05am
promptfiddle2 Ready Ready Preview, Comment Jul 16, 2026 5:05am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8ca825c2-1b2c-4c54-b61f-8a91878f0720

📥 Commits

Reviewing files that changed from the base of the PR and between 708799d and 4313734.

⛔ Files ignored due to path filters (47)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/index.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/index.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/native.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/native.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/proto/baml_cffi.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto/baml_cffi.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (135)
  • .github/workflows/build2-nodejs-sdk.reusable.yaml
  • .github/workflows/cargo-tests.reusable.yaml
  • .github/workflows/ci.yaml
  • .github/workflows/publish2-nodejs-sdk.yaml
  • .gitignore
  • baml_language/.config/nextest.toml
  • baml_language/Cargo.toml
  • baml_language/crates/baml_cli/Cargo.toml
  • baml_language/crates/baml_cli/src/generate.rs
  • baml_language/crates/baml_codegen_types/src/generator_fields.rs
  • baml_language/crates/bex_engine/src/lib.rs
  • baml_language/crates/bex_engine/tests/host_value_callable.rs
  • baml_language/crates/bridge_ctypes/README.md
  • baml_language/sdk_tests/DEVELOPMENT.md
  • baml_language/sdk_tests/README.md
  • baml_language/sdk_tests/crates/python_pydantic2/function_calls/customizable/test_methods_on_classes.py
  • baml_language/sdk_tests/crates/typescript/Cargo.toml
  • baml_language/sdk_tests/crates/typescript/build.rs
  • baml_language/sdk_tests/crates/typescript/docstrings_etc/customizable/main.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/cancellation.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/host_callables.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/methods_on_classes.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/optional_args.static.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/optional_args.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/runtime.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/stdlib_entrypoints.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/union_throws.test.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/replay_harness.node.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/streaming_e2e.node.test.ts
  • baml_language/sdk_tests/crates/typescript/setup.ps1
  • baml_language/sdk_tests/crates/typescript/setup.sh
  • baml_language/sdk_tests/crates/typescript/src/lib.rs
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_aliases.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_class_refs.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_complex_models.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_enums.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_forward_refs.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_generics.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_handles.node.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_lists.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_literals.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_maps.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_media.node.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_optional.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_primitives.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_recursion.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_routing.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_streams.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_symbol_collisions.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_unions.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_void.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/test_generic.test.ts
  • baml_language/sdk_tests/crates/typescript_node/build.rs
  • baml_language/sdk_tests/fixtures/function_calls/baml_src/main.baml
  • baml_language/sdk_tests/fixtures/function_calls/baml_src/ns_generic_tests/types.baml
  • baml_language/sdk_tests/harness_runner/Cargo.toml
  • baml_language/sdk_tests/harness_runner/src/lib.rs
  • baml_language/sdk_tests/harness_setup/Cargo.toml
  • baml_language/sdk_tests/harness_setup/src/lib.rs
  • baml_language/sdk_tests/harness_setup/src/templates/package.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig_web.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig_workers.json
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_node.config.ts
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_web.config.ts
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_workers.config.ts
  • baml_language/sdk_tests/harness_setup/src/typescript.rs
  • baml_language/sdk_tests/harness_setup/src/typescript_node.rs
  • baml_language/sdks/go/bridge_go/pkg/tests/host_callable_test.go
  • baml_language/sdks/nodejs/bridge_nodejs/typescript_src/generated-header.txt
  • baml_language/sdks/python/rust/bridge_python/src/host_value.rs
  • baml_language/sdks/typescript/bridge_typescript/.gitignore
  • baml_language/sdks/typescript/bridge_typescript/Cargo.toml
  • baml_language/sdks/typescript/bridge_typescript/build.rs
  • baml_language/sdks/typescript/bridge_typescript/package.json
  • baml_language/sdks/typescript/bridge_typescript/src/baml_call_context.rs
  • baml_language/sdks/typescript/bridge_typescript/src/errors.rs
  • baml_language/sdks/typescript/bridge_typescript/src/handle.rs
  • baml_language/sdks/typescript/bridge_typescript/src/host_value.rs
  • baml_language/sdks/typescript/bridge_typescript/src/lib.rs
  • baml_language/sdks/typescript/bridge_typescript/src/media.rs
  • baml_language/sdks/typescript/bridge_typescript/src/runtime.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/collector.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/host_span_manager.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/mod.rs
  • baml_language/sdks/typescript/bridge_typescript/tests/call_function.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/host_callable.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/run_vitest.rs
  • baml_language/sdks/typescript/bridge_typescript/tests/test_decode_call_result.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_decode_handle.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_engine.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_media.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_stream.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_typemap.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tsconfig.json
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/clean-dist.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/copy-native-dts.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/copy-proto.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/define_function.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/exit_hook.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/generated-header.txt
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/host_value_registry.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/index.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/native.d.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto/baml_cffi.d.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto/baml_cffi.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/stream.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/tag-generated-files.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/typemap.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/wire_ty.ts
  • baml_language/sdks/typescript/bridge_typescript/vitest.config.ts
  • baml_language/sdks/typescript/sdkgen_typescript_shared/Cargo.toml
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/class.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/enum_.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/function.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/method.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/mod.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/type_alias.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/typemap_file.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/leaf.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/lib.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/routing.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/sdkgen_typescript.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/sdkgen_typescript_web.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/translate_ty.rs
  • baml_language/stow.toml
  • pnpm-workspace.yaml
  • scripts/baml-language-version
  • tools/build
💤 Files with no reviewable changes (3)
  • baml_language/sdks/nodejs/bridge_nodejs/typescript_src/generated-header.txt
  • baml_language/sdk_tests/crates/typescript_node/build.rs
  • baml_language/sdk_tests/harness_setup/src/typescript_node.rs

📝 Walkthrough

Walkthrough

The PR migrates the Node.js SDK bridge to a shared TypeScript bridge workspace, adds runtime-configurable Node/Web SDK generation, introduces native runtime, handle, media, cancellation, tracing, and host-callable APIs, and expands the TypeScript SDK test harness across Node, Web, and Workers layouts.

Changes

TypeScript SDK bridge migration

Layer / File(s) Summary
Workspace and generator wiring
.github/workflows/*, baml_language/Cargo.toml, baml_language/crates/*, scripts/*, tools/build, pnpm-workspace.yaml
CI, release checks, workspace dependencies, output-type validation, and build routing now target the shared TypeScript bridge and generator paths.
Multi-runtime SDK test harness
baml_language/sdk_tests/crates/typescript/*, baml_language/sdk_tests/harness_setup/*, baml_language/sdk_tests/harness_runner/*
The TypeScript test crate and harness generate Node, Web, and Workers outputs with runtime-specific configs, setup scripts, scaffolded tests, and expanded fixture coverage.
Native bridge API and lifecycle
baml_language/sdks/typescript/bridge_typescript/src/*, baml_language/sdks/typescript/bridge_typescript/typescript_src/*
The bridge exposes runtime calls, cancellation, handles, media wrappers, host-callable dispatch, collectors, tracing, streams, type maps, wire types, and error conversion.
Shared TypeScript generator
baml_language/sdks/typescript/sdkgen_typescript_shared/src/*
Generator internals are renamed from Node-specific terminology, runtime package imports become configurable, and Node/Web adapter entrypoints are added.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SDKTestHarness
  participant TypeScriptGenerator
  participant TypeScriptBridge
  participant BamlRuntime
  SDKTestHarness->>TypeScriptGenerator: generate Node/Web/Workers SDK sources
  TypeScriptGenerator->>SDKTestHarness: write runtime-specific fixture outputs
  SDKTestHarness->>TypeScriptBridge: initialize runtime and encode calls
  TypeScriptBridge->>BamlRuntime: callFunction or callFunctionSync
  BamlRuntime-->>TypeScriptBridge: encoded result or error envelope
  TypeScriptBridge-->>SDKTestHarness: decoded SDK result
Loading

Possibly related PRs

Poem

A rabbit hops through TypeScript trails,
With native handles in tidy pails.
Node and Web now share one tune,
Workers dance beneath the moon.
Tests bloom bright, bridges hum—
“Ship the SDK!” the bunnies drum.

🚥 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 main refactor: preparing the TypeScript SDK for Node, Web, and Workers support.
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 sam/typescript-runtime-matrix

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: private package registry requires authentication. Disable ESLint in CodeRabbit settings or use public packages.

🔧 ast-grep (0.44.1)
baml_language/sdks/typescript/bridge_typescript/typescript_src/proto/baml_cffi.js

ast-grep timed out on this file


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.

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

@vercel
vercel Bot temporarily deployed to Preview – beps July 16, 2026 04:24 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 16, 2026 04:32 Inactive
@github-actions

github-actions Bot commented Jul 16, 2026 •

Copy link
Copy Markdown

Binary size checks passed

✅ 7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
✅ baml-cli Linux 🔒 22.8 MB 9.7 MB file 22.8 MB +58.0 KB (+0.3%) OK
✅ packed-program Linux 🔒 16.3 MB 6.8 MB file 16.3 MB +24.6 KB (+0.2%) OK
✅ baml-cli macOS 🔒 17.6 MB 8.5 MB file 17.5 MB +49.7 KB (+0.3%) OK
✅ packed-program macOS 🔒 12.6 MB 6.0 MB file 12.6 MB +32 B (+0.0%) OK
✅ baml-cli Windows 🔒 19.1 MB 8.7 MB file 18.7 MB +414.7 KB (+2.2%) OK
✅ packed-program Windows 🔒 13.5 MB 6.1 MB file 13.5 MB +5.6 KB (+0.0%) OK
✅ bridge_wasm WASM 15.2 MB 🔒 4.3 MB gzip 4.3 MB +3.6 KB (+0.1%) 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

@sxlijin
sxlijin force-pushed the sam/typescript-runtime-matrix branch from 8173b78 to 4313734 Compare July 16, 2026 04:43
@vercel
vercel Bot temporarily deployed to Preview – beps July 16, 2026 04:44 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 16, 2026 04:51 Inactive
@sxlijin
sxlijin marked this pull request as ready for review July 16, 2026 05:00
@sxlijin
sxlijin added this pull request to the merge queue Jul 16, 2026
@sxlijin
sxlijin removed this pull request from the merge queue due to a manual request Jul 16, 2026
@sxlijin
sxlijin added this pull request to the merge queue Jul 16, 2026
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 16, 2026 05:05 Inactive

@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: 43137347dc

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

use baml_codegen_types::SymbolPool;
pub use baml_codegen_types::{NamingConvention, OutputType};

const RUNTIME_PACKAGE: &str = "@boundaryml/baml-bridge-web";

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 Keep web generator disabled until runtime exists

When a user selects the newly accepted output_type = "typescript/web", the CLI now routes into this generator and every emitted SDK imports @boundaryml/baml-bridge-web. I checked the repo/package manifests with rg "baml-bridge-web" and there is no package providing that name (the only runtime package is @boundaryml/baml-bridge, and the web tests are explicitly ignored until the runtime lands), so generated web SDKs cannot install or typecheck. Either keep this output type unavailable until the web bridge package is added, or point it at an existing package.

Useful? React with 👍 / 👎.

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

🧹 Nitpick comments (7)
baml_language/sdks/typescript/bridge_typescript/src/baml_call_context.rs (1)

29-33: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Drain the active call IDs to avoid redundant cancellations and clones.

Cloning the vector leaves the IDs inside active_call_ids. If abort() is called multiple times, it will unnecessarily re-cancel the same IDs. Using std::mem::take clears the vector while returning its contents, preventing redundant cancellations and avoiding the allocation cost of cloning.

⚡ Proposed refactor
         let call_ids = self
             .active_call_ids
             .lock()
-            .map(|ids| ids.clone())
+            .map(|mut ids| std::mem::take(&mut *ids))
             .unwrap_or_default();
🤖 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/sdks/typescript/bridge_typescript/src/baml_call_context.rs`
around lines 29 - 33, Update the active call ID extraction in the relevant abort
flow to use std::mem::take on the locked active_call_ids vector instead of
cloning it. Ensure the vector is cleared while its contents are returned,
preserving the existing default behavior if the mutex is poisoned and preventing
repeated abort calls from re-canceling IDs.
baml_language/sdks/typescript/bridge_typescript/src/runtime.rs (1)

152-173: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add Rust unit tests for decode_args validation paths.

decode_args has real branching logic (zero call_id rejection, type_args translation, kwargs conversion) with no visible Rust unit tests covering it directly; coverage currently relies on the TS integration suite. As per path instructions, **/*.rs: "Prefer writing Rust 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/sdks/typescript/bridge_typescript/src/runtime.rs` around lines
152 - 173, Add Rust unit tests targeting the private decode_args function,
covering rejection of a zero call_id, successful type_args translation, kwargs
conversion, and malformed protobuf input. Construct representative
CallFunctionArgs protobuf payloads, invoke decode_args directly, and assert both
returned DecodedCallArgs fields and the expected errors while keeping existing
behavior unchanged.

Source: Path instructions

baml_language/sdks/typescript/bridge_typescript/src/handle.rs (1)

47-58: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a Rust unit test for the HandleKey bit round-trip.

to_u64/from_u64 is pure, napi-independent logic (no JS runtime needed) that underpins every handle key in the bridge — a regression here would silently corrupt keys. It's currently only exercised indirectly through TS integration tests (e.g. test_decode_handle.test.ts). As per coding guidelines, **/*.rs should prefer unit tests over integration tests where possible, and this is a case where a direct unit test is trivial to add.

✅ Suggested unit test
#[cfg(test)]
mod tests {
    use super::HandleKey;

    #[test]
    fn handle_key_round_trips() {
        for v in [0u64, 1, u32::MAX as u64, u64::MAX, 1u64 << 32, 0x1234_5678_9abc_def0] {
            assert_eq!(HandleKey::from_u64(v).to_u64(), v);
        }
    }
}
🤖 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/sdks/typescript/bridge_typescript/src/handle.rs` around lines
47 - 58, Add a Rust unit-test module near HandleKey that directly exercises
HandleKey::from_u64 and HandleKey::to_u64. Define a handle_key_round_trips test
covering zero, boundary values, u64::MAX, a 32-bit shift, and a representative
mixed-bit value, asserting each value round-trips unchanged without requiring a
napi or JavaScript runtime.

Source: Coding guidelines

baml_language/sdks/typescript/bridge_typescript/src/media.rs (1)

49-76: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Confusing error message field name in create_media.

c_string(value, context) (Line 56) passes the operation name ("fromUrl", "fromFile", "fromBase64") as the field argument, so a NUL byte in the value produces "fromUrl cannot contain NUL" instead of naming the actual offending value (url/file/base64 string). Consider passing a value-specific field label distinct from the context used for status_to_napi.

💡 Proposed fix
 fn create_media(
     constructor: MediaConstructor,
     media_kind: MediaTypeEnum,
     value: String,
     mime_type: Option<String>,
     context: &str,
 ) -> napi::Result<(u64, i32)> {
-    let value = c_string(value, context)?;
+    let value = c_string(value, "value")?;
     let mime_type = mime_type.map(|s| c_string(s, "mimeType")).transpose()?;
🤖 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/sdks/typescript/bridge_typescript/src/media.rs` around lines 49
- 76, Update create_media so the value passed to c_string uses a value-specific
field label (such as url, file, or base64) rather than context, while preserving
context for status_to_napi error reporting. Ensure NUL-byte errors identify the
offending media value field instead of the operation name.
baml_language/sdks/typescript/bridge_typescript/tests/host_callable.test.ts (1)

161-176: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test doesn't exercise real concurrency for the collision check.

caughtFirst fully resolves before caughtSecond starts, so the two registry entries are never live simultaneously — this doesn't actually stress the collision scenario the test name implies. Consider awaiting both concurrently.

♻️ Proposed fix for genuine concurrency
-        const caughtFirst = await callFunction(rt, 'CallCb', {
-            callback: (_x: number): string => { throw raisedFirst; },
-            x: 1,
-        }).catch(e => e);
-        const caughtSecond = await callFunction(rt, 'CallCb', {
-            callback: (_x: number): string => { throw raisedSecond; },
-            x: 2,
-        }).catch(e => e);
+        const [caughtFirst, caughtSecond] = await Promise.all([
+            callFunction(rt, 'CallCb', {
+                callback: (_x: number): string => { throw raisedFirst; },
+                x: 1,
+            }).catch(e => e),
+            callFunction(rt, 'CallCb', {
+                callback: (_x: number): string => { throw raisedSecond; },
+                x: 2,
+            }).catch(e => e),
+        ]);
🤖 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/sdks/typescript/bridge_typescript/tests/host_callable.test.ts`
around lines 161 - 176, Update the test around callFunction so both CallCb
invocations are started before awaiting either result, using concurrent promise
handling while preserving the separate raisedFirst and raisedSecond callbacks
and identity assertions. Ensure both registry entries remain active
simultaneously to validate that rapid concurrent errors do not collide.
baml_language/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts (2)

53-69: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider preserving the original function's parameter types.

The current generic signature (...args: unknown[]) => T discards the parameter types of the original function fn, which might result in a loss of type safety or IDE autocompletion for the wrapped function. You can preserve the exact signature by making the entire function type generic.

💡 Proposed refactor
-    traceFn<T>(name: string, fn: (...args: unknown[]) => T): (...args: unknown[]) => T {
+    traceFn<F extends (...args: any[]) => any>(name: string, fn: F): (...args: Parameters<F>) => ReturnType<F> {
         const self = this;
-        return function (this: unknown, ...args: unknown[]): T {
+        return function (this: unknown, ...args: Parameters<F>): ReturnType<F> {
             const mgr = self.cloneContext();
🤖 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/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts`
around lines 53 - 69, Update the traceFn method to be generic over the entire
function type, preserving fn’s parameter tuple and return type in the wrapped
function signature. Keep the existing context tracing, invocation, and
error-handling behavior unchanged while replacing the unknown[] parameter typing
with inferred function parameters.

71-87: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider preserving the original async function's parameter types.

Similar to traceFn, the generic signature here drops the original parameter types of the function being wrapped. Using Parameters<F> will retain type safety.

💡 Proposed refactor
-    traceFnAsync<T>(name: string, fn: (...args: unknown[]) => Promise<T>): (...args: unknown[]) => Promise<T> {
+    traceFnAsync<F extends (...args: any[]) => Promise<any>>(name: string, fn: F): (...args: Parameters<F>) => ReturnType<F> {
         const self = this;
-        return async function (this: unknown, ...args: unknown[]): Promise<T> {
+        return async function (this: unknown, ...args: Parameters<F>): ReturnType<F> {
             const mgr = self.cloneContext();
🤖 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/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts`
around lines 71 - 87, Update traceFnAsync to be generic over the wrapped
function type and derive its arguments from Parameters<F>, while preserving the
Promise return type and this binding behavior. Ensure the returned wrapper
accepts the original function’s parameter types instead of (...args: unknown[]),
matching the type-safety approach used by traceFn.
🤖 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/sdk_tests/crates/typescript/function_calls/customizable/cancellation.node.test.ts`:
- Around line 137-158: Update the reused-call-context test “surfaces a reused
call context as AbortError with BAML reason” to capture a start timestamp before
invoking callFunction and call expectFastCancellation(start) after verifying the
cancellation reason. Preserve the existing abort and rejection assertions.

In `@baml_language/sdks/typescript/bridge_typescript/src/host_value.rs`:
- Around line 129-140: Update register_host_callable to handle
REGISTRY.table.lock() poisoning explicitly instead of calling unwrap. Match the
lock result consistently with drop_registry_entry and host_dispatch_callback,
log the warning through the file’s existing mechanism, and return an appropriate
napi::Result error without panicking across the FFI boundary.

In
`@baml_language/sdks/typescript/bridge_typescript/typescript_src/define_function.ts`:
- Around line 234-239: Update typeArgsFor and the corresponding non-generic
handling near the later type-argument path to call resolveTypesOption even when
isGeneric is false. Reject any supplied $types value with the same strict
validation/error behavior as the generic path, while continuing to return no
type arguments when $types is absent.

In `@baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts`:
- Around line 81-84: Update wrapNativeError to inspect the native error’s
message and code, then return the corresponding typed subclass such as
BamlInvalidArgumentError or BamlClientError instead of always constructing
BamlError. Preserve the existing String(err) fallback for non-Error values and
ensure unmapped errors continue returning the generic BamlError.

In `@baml_language/sdks/typescript/bridge_typescript/typescript_src/wire_ty.ts`:
- Around line 141-167: Update outboundTyToBamlType to preserve wire-encoded
never and union types emitted by lowerTypeToWireTy instead of falling through to
undefined. Decode each representation into the corresponding BamlType token or
binding, while retaining the existing handling for primitive, collection,
optional, and class types.

---

Nitpick comments:
In `@baml_language/sdks/typescript/bridge_typescript/src/baml_call_context.rs`:
- Around line 29-33: Update the active call ID extraction in the relevant abort
flow to use std::mem::take on the locked active_call_ids vector instead of
cloning it. Ensure the vector is cleared while its contents are returned,
preserving the existing default behavior if the mutex is poisoned and preventing
repeated abort calls from re-canceling IDs.

In `@baml_language/sdks/typescript/bridge_typescript/src/handle.rs`:
- Around line 47-58: Add a Rust unit-test module near HandleKey that directly
exercises HandleKey::from_u64 and HandleKey::to_u64. Define a
handle_key_round_trips test covering zero, boundary values, u64::MAX, a 32-bit
shift, and a representative mixed-bit value, asserting each value round-trips
unchanged without requiring a napi or JavaScript runtime.

In `@baml_language/sdks/typescript/bridge_typescript/src/media.rs`:
- Around line 49-76: Update create_media so the value passed to c_string uses a
value-specific field label (such as url, file, or base64) rather than context,
while preserving context for status_to_napi error reporting. Ensure NUL-byte
errors identify the offending media value field instead of the operation name.

In `@baml_language/sdks/typescript/bridge_typescript/src/runtime.rs`:
- Around line 152-173: Add Rust unit tests targeting the private decode_args
function, covering rejection of a zero call_id, successful type_args
translation, kwargs conversion, and malformed protobuf input. Construct
representative CallFunctionArgs protobuf payloads, invoke decode_args directly,
and assert both returned DecodedCallArgs fields and the expected errors while
keeping existing behavior unchanged.

In `@baml_language/sdks/typescript/bridge_typescript/tests/host_callable.test.ts`:
- Around line 161-176: Update the test around callFunction so both CallCb
invocations are started before awaiting either result, using concurrent promise
handling while preserving the separate raisedFirst and raisedSecond callbacks
and identity assertions. Ensure both registry entries remain active
simultaneously to validate that rapid concurrent errors do not collide.

In
`@baml_language/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts`:
- Around line 53-69: Update the traceFn method to be generic over the entire
function type, preserving fn’s parameter tuple and return type in the wrapped
function signature. Keep the existing context tracing, invocation, and
error-handling behavior unchanged while replacing the unknown[] parameter typing
with inferred function parameters.
- Around line 71-87: Update traceFnAsync to be generic over the wrapped function
type and derive its arguments from Parameters<F>, while preserving the Promise
return type and this binding behavior. Ensure the returned wrapper accepts the
original function’s parameter types instead of (...args: unknown[]), matching
the type-safety approach used by traceFn.
🪄 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

Run ID: 8ca825c2-1b2c-4c54-b61f-8a91878f0720

📥 Commits

Reviewing files that changed from the base of the PR and between 708799d and 4313734.

⛔ Files ignored due to path filters (47)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/index.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/index.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/native.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/native.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/proto/baml_cffi.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto/baml_cffi.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (135)
  • .github/workflows/build2-nodejs-sdk.reusable.yaml
  • .github/workflows/cargo-tests.reusable.yaml
  • .github/workflows/ci.yaml
  • .github/workflows/publish2-nodejs-sdk.yaml
  • .gitignore
  • baml_language/.config/nextest.toml
  • baml_language/Cargo.toml
  • baml_language/crates/baml_cli/Cargo.toml
  • baml_language/crates/baml_cli/src/generate.rs
  • baml_language/crates/baml_codegen_types/src/generator_fields.rs
  • baml_language/crates/bex_engine/src/lib.rs
  • baml_language/crates/bex_engine/tests/host_value_callable.rs
  • baml_language/crates/bridge_ctypes/README.md
  • baml_language/sdk_tests/DEVELOPMENT.md
  • baml_language/sdk_tests/README.md
  • baml_language/sdk_tests/crates/python_pydantic2/function_calls/customizable/test_methods_on_classes.py
  • baml_language/sdk_tests/crates/typescript/Cargo.toml
  • baml_language/sdk_tests/crates/typescript/build.rs
  • baml_language/sdk_tests/crates/typescript/docstrings_etc/customizable/main.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/cancellation.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/host_callables.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/methods_on_classes.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/optional_args.static.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/optional_args.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/runtime.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/stdlib_entrypoints.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/union_throws.test.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/replay_harness.node.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/streaming_e2e.node.test.ts
  • baml_language/sdk_tests/crates/typescript/setup.ps1
  • baml_language/sdk_tests/crates/typescript/setup.sh
  • baml_language/sdk_tests/crates/typescript/src/lib.rs
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_aliases.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_class_refs.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_complex_models.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_enums.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_forward_refs.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_generics.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_handles.node.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_lists.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_literals.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_maps.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_media.node.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_optional.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_primitives.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_recursion.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_routing.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_streams.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_symbol_collisions.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_unions.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_void.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/test_generic.test.ts
  • baml_language/sdk_tests/crates/typescript_node/build.rs
  • baml_language/sdk_tests/fixtures/function_calls/baml_src/main.baml
  • baml_language/sdk_tests/fixtures/function_calls/baml_src/ns_generic_tests/types.baml
  • baml_language/sdk_tests/harness_runner/Cargo.toml
  • baml_language/sdk_tests/harness_runner/src/lib.rs
  • baml_language/sdk_tests/harness_setup/Cargo.toml
  • baml_language/sdk_tests/harness_setup/src/lib.rs
  • baml_language/sdk_tests/harness_setup/src/templates/package.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig_web.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig_workers.json
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_node.config.ts
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_web.config.ts
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_workers.config.ts
  • baml_language/sdk_tests/harness_setup/src/typescript.rs
  • baml_language/sdk_tests/harness_setup/src/typescript_node.rs
  • baml_language/sdks/go/bridge_go/pkg/tests/host_callable_test.go
  • baml_language/sdks/nodejs/bridge_nodejs/typescript_src/generated-header.txt
  • baml_language/sdks/python/rust/bridge_python/src/host_value.rs
  • baml_language/sdks/typescript/bridge_typescript/.gitignore
  • baml_language/sdks/typescript/bridge_typescript/Cargo.toml
  • baml_language/sdks/typescript/bridge_typescript/build.rs
  • baml_language/sdks/typescript/bridge_typescript/package.json
  • baml_language/sdks/typescript/bridge_typescript/src/baml_call_context.rs
  • baml_language/sdks/typescript/bridge_typescript/src/errors.rs
  • baml_language/sdks/typescript/bridge_typescript/src/handle.rs
  • baml_language/sdks/typescript/bridge_typescript/src/host_value.rs
  • baml_language/sdks/typescript/bridge_typescript/src/lib.rs
  • baml_language/sdks/typescript/bridge_typescript/src/media.rs
  • baml_language/sdks/typescript/bridge_typescript/src/runtime.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/collector.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/host_span_manager.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/mod.rs
  • baml_language/sdks/typescript/bridge_typescript/tests/call_function.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/host_callable.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/run_vitest.rs
  • baml_language/sdks/typescript/bridge_typescript/tests/test_decode_call_result.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_decode_handle.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_engine.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_media.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_stream.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_typemap.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tsconfig.json
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/clean-dist.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/copy-native-dts.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/copy-proto.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/define_function.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/exit_hook.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/generated-header.txt
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/host_value_registry.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/index.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/native.d.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto/baml_cffi.d.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto/baml_cffi.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/stream.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/tag-generated-files.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/typemap.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/wire_ty.ts
  • baml_language/sdks/typescript/bridge_typescript/vitest.config.ts
  • baml_language/sdks/typescript/sdkgen_typescript_shared/Cargo.toml
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/class.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/enum_.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/function.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/method.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/mod.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/type_alias.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/typemap_file.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/leaf.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/lib.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/routing.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/sdkgen_typescript.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/sdkgen_typescript_web.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/translate_ty.rs
  • baml_language/stow.toml
  • pnpm-workspace.yaml
  • scripts/baml-language-version
  • tools/build
💤 Files with no reviewable changes (3)
  • baml_language/sdks/nodejs/bridge_nodejs/typescript_src/generated-header.txt
  • baml_language/sdk_tests/crates/typescript_node/build.rs
  • baml_language/sdk_tests/harness_setup/src/typescript_node.rs

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

🧹 Nitpick comments (7)
baml_language/sdks/typescript/bridge_typescript/src/baml_call_context.rs (1)

29-33: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Drain the active call IDs to avoid redundant cancellations and clones.

Cloning the vector leaves the IDs inside active_call_ids. If abort() is called multiple times, it will unnecessarily re-cancel the same IDs. Using std::mem::take clears the vector while returning its contents, preventing redundant cancellations and avoiding the allocation cost of cloning.

⚡ Proposed refactor
         let call_ids = self
             .active_call_ids
             .lock()
-            .map(|ids| ids.clone())
+            .map(|mut ids| std::mem::take(&mut *ids))
             .unwrap_or_default();
🤖 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/sdks/typescript/bridge_typescript/src/baml_call_context.rs`
around lines 29 - 33, Update the active call ID extraction in the relevant abort
flow to use std::mem::take on the locked active_call_ids vector instead of
cloning it. Ensure the vector is cleared while its contents are returned,
preserving the existing default behavior if the mutex is poisoned and preventing
repeated abort calls from re-canceling IDs.
baml_language/sdks/typescript/bridge_typescript/src/runtime.rs (1)

152-173: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add Rust unit tests for decode_args validation paths.

decode_args has real branching logic (zero call_id rejection, type_args translation, kwargs conversion) with no visible Rust unit tests covering it directly; coverage currently relies on the TS integration suite. As per path instructions, **/*.rs: "Prefer writing Rust 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/sdks/typescript/bridge_typescript/src/runtime.rs` around lines
152 - 173, Add Rust unit tests targeting the private decode_args function,
covering rejection of a zero call_id, successful type_args translation, kwargs
conversion, and malformed protobuf input. Construct representative
CallFunctionArgs protobuf payloads, invoke decode_args directly, and assert both
returned DecodedCallArgs fields and the expected errors while keeping existing
behavior unchanged.

Source: Path instructions

baml_language/sdks/typescript/bridge_typescript/src/handle.rs (1)

47-58: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a Rust unit test for the HandleKey bit round-trip.

to_u64/from_u64 is pure, napi-independent logic (no JS runtime needed) that underpins every handle key in the bridge — a regression here would silently corrupt keys. It's currently only exercised indirectly through TS integration tests (e.g. test_decode_handle.test.ts). As per coding guidelines, **/*.rs should prefer unit tests over integration tests where possible, and this is a case where a direct unit test is trivial to add.

✅ Suggested unit test
#[cfg(test)]
mod tests {
    use super::HandleKey;

    #[test]
    fn handle_key_round_trips() {
        for v in [0u64, 1, u32::MAX as u64, u64::MAX, 1u64 << 32, 0x1234_5678_9abc_def0] {
            assert_eq!(HandleKey::from_u64(v).to_u64(), v);
        }
    }
}
🤖 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/sdks/typescript/bridge_typescript/src/handle.rs` around lines
47 - 58, Add a Rust unit-test module near HandleKey that directly exercises
HandleKey::from_u64 and HandleKey::to_u64. Define a handle_key_round_trips test
covering zero, boundary values, u64::MAX, a 32-bit shift, and a representative
mixed-bit value, asserting each value round-trips unchanged without requiring a
napi or JavaScript runtime.

Source: Coding guidelines

baml_language/sdks/typescript/bridge_typescript/src/media.rs (1)

49-76: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Confusing error message field name in create_media.

c_string(value, context) (Line 56) passes the operation name ("fromUrl", "fromFile", "fromBase64") as the field argument, so a NUL byte in the value produces "fromUrl cannot contain NUL" instead of naming the actual offending value (url/file/base64 string). Consider passing a value-specific field label distinct from the context used for status_to_napi.

💡 Proposed fix
 fn create_media(
     constructor: MediaConstructor,
     media_kind: MediaTypeEnum,
     value: String,
     mime_type: Option<String>,
     context: &str,
 ) -> napi::Result<(u64, i32)> {
-    let value = c_string(value, context)?;
+    let value = c_string(value, "value")?;
     let mime_type = mime_type.map(|s| c_string(s, "mimeType")).transpose()?;
🤖 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/sdks/typescript/bridge_typescript/src/media.rs` around lines 49
- 76, Update create_media so the value passed to c_string uses a value-specific
field label (such as url, file, or base64) rather than context, while preserving
context for status_to_napi error reporting. Ensure NUL-byte errors identify the
offending media value field instead of the operation name.
baml_language/sdks/typescript/bridge_typescript/tests/host_callable.test.ts (1)

161-176: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test doesn't exercise real concurrency for the collision check.

caughtFirst fully resolves before caughtSecond starts, so the two registry entries are never live simultaneously — this doesn't actually stress the collision scenario the test name implies. Consider awaiting both concurrently.

♻️ Proposed fix for genuine concurrency
-        const caughtFirst = await callFunction(rt, 'CallCb', {
-            callback: (_x: number): string => { throw raisedFirst; },
-            x: 1,
-        }).catch(e => e);
-        const caughtSecond = await callFunction(rt, 'CallCb', {
-            callback: (_x: number): string => { throw raisedSecond; },
-            x: 2,
-        }).catch(e => e);
+        const [caughtFirst, caughtSecond] = await Promise.all([
+            callFunction(rt, 'CallCb', {
+                callback: (_x: number): string => { throw raisedFirst; },
+                x: 1,
+            }).catch(e => e),
+            callFunction(rt, 'CallCb', {
+                callback: (_x: number): string => { throw raisedSecond; },
+                x: 2,
+            }).catch(e => e),
+        ]);
🤖 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/sdks/typescript/bridge_typescript/tests/host_callable.test.ts`
around lines 161 - 176, Update the test around callFunction so both CallCb
invocations are started before awaiting either result, using concurrent promise
handling while preserving the separate raisedFirst and raisedSecond callbacks
and identity assertions. Ensure both registry entries remain active
simultaneously to validate that rapid concurrent errors do not collide.
baml_language/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts (2)

53-69: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider preserving the original function's parameter types.

The current generic signature (...args: unknown[]) => T discards the parameter types of the original function fn, which might result in a loss of type safety or IDE autocompletion for the wrapped function. You can preserve the exact signature by making the entire function type generic.

💡 Proposed refactor
-    traceFn<T>(name: string, fn: (...args: unknown[]) => T): (...args: unknown[]) => T {
+    traceFn<F extends (...args: any[]) => any>(name: string, fn: F): (...args: Parameters<F>) => ReturnType<F> {
         const self = this;
-        return function (this: unknown, ...args: unknown[]): T {
+        return function (this: unknown, ...args: Parameters<F>): ReturnType<F> {
             const mgr = self.cloneContext();
🤖 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/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts`
around lines 53 - 69, Update the traceFn method to be generic over the entire
function type, preserving fn’s parameter tuple and return type in the wrapped
function signature. Keep the existing context tracing, invocation, and
error-handling behavior unchanged while replacing the unknown[] parameter typing
with inferred function parameters.

71-87: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider preserving the original async function's parameter types.

Similar to traceFn, the generic signature here drops the original parameter types of the function being wrapped. Using Parameters<F> will retain type safety.

💡 Proposed refactor
-    traceFnAsync<T>(name: string, fn: (...args: unknown[]) => Promise<T>): (...args: unknown[]) => Promise<T> {
+    traceFnAsync<F extends (...args: any[]) => Promise<any>>(name: string, fn: F): (...args: Parameters<F>) => ReturnType<F> {
         const self = this;
-        return async function (this: unknown, ...args: unknown[]): Promise<T> {
+        return async function (this: unknown, ...args: Parameters<F>): ReturnType<F> {
             const mgr = self.cloneContext();
🤖 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/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts`
around lines 71 - 87, Update traceFnAsync to be generic over the wrapped
function type and derive its arguments from Parameters<F>, while preserving the
Promise return type and this binding behavior. Ensure the returned wrapper
accepts the original function’s parameter types instead of (...args: unknown[]),
matching the type-safety approach used by traceFn.
🤖 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/sdk_tests/crates/typescript/function_calls/customizable/cancellation.node.test.ts`:
- Around line 137-158: Update the reused-call-context test “surfaces a reused
call context as AbortError with BAML reason” to capture a start timestamp before
invoking callFunction and call expectFastCancellation(start) after verifying the
cancellation reason. Preserve the existing abort and rejection assertions.

In `@baml_language/sdks/typescript/bridge_typescript/src/host_value.rs`:
- Around line 129-140: Update register_host_callable to handle
REGISTRY.table.lock() poisoning explicitly instead of calling unwrap. Match the
lock result consistently with drop_registry_entry and host_dispatch_callback,
log the warning through the file’s existing mechanism, and return an appropriate
napi::Result error without panicking across the FFI boundary.

In
`@baml_language/sdks/typescript/bridge_typescript/typescript_src/define_function.ts`:
- Around line 234-239: Update typeArgsFor and the corresponding non-generic
handling near the later type-argument path to call resolveTypesOption even when
isGeneric is false. Reject any supplied $types value with the same strict
validation/error behavior as the generic path, while continuing to return no
type arguments when $types is absent.

In `@baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts`:
- Around line 81-84: Update wrapNativeError to inspect the native error’s
message and code, then return the corresponding typed subclass such as
BamlInvalidArgumentError or BamlClientError instead of always constructing
BamlError. Preserve the existing String(err) fallback for non-Error values and
ensure unmapped errors continue returning the generic BamlError.

In `@baml_language/sdks/typescript/bridge_typescript/typescript_src/wire_ty.ts`:
- Around line 141-167: Update outboundTyToBamlType to preserve wire-encoded
never and union types emitted by lowerTypeToWireTy instead of falling through to
undefined. Decode each representation into the corresponding BamlType token or
binding, while retaining the existing handling for primitive, collection,
optional, and class types.

---

Nitpick comments:
In `@baml_language/sdks/typescript/bridge_typescript/src/baml_call_context.rs`:
- Around line 29-33: Update the active call ID extraction in the relevant abort
flow to use std::mem::take on the locked active_call_ids vector instead of
cloning it. Ensure the vector is cleared while its contents are returned,
preserving the existing default behavior if the mutex is poisoned and preventing
repeated abort calls from re-canceling IDs.

In `@baml_language/sdks/typescript/bridge_typescript/src/handle.rs`:
- Around line 47-58: Add a Rust unit-test module near HandleKey that directly
exercises HandleKey::from_u64 and HandleKey::to_u64. Define a
handle_key_round_trips test covering zero, boundary values, u64::MAX, a 32-bit
shift, and a representative mixed-bit value, asserting each value round-trips
unchanged without requiring a napi or JavaScript runtime.

In `@baml_language/sdks/typescript/bridge_typescript/src/media.rs`:
- Around line 49-76: Update create_media so the value passed to c_string uses a
value-specific field label (such as url, file, or base64) rather than context,
while preserving context for status_to_napi error reporting. Ensure NUL-byte
errors identify the offending media value field instead of the operation name.

In `@baml_language/sdks/typescript/bridge_typescript/src/runtime.rs`:
- Around line 152-173: Add Rust unit tests targeting the private decode_args
function, covering rejection of a zero call_id, successful type_args
translation, kwargs conversion, and malformed protobuf input. Construct
representative CallFunctionArgs protobuf payloads, invoke decode_args directly,
and assert both returned DecodedCallArgs fields and the expected errors while
keeping existing behavior unchanged.

In `@baml_language/sdks/typescript/bridge_typescript/tests/host_callable.test.ts`:
- Around line 161-176: Update the test around callFunction so both CallCb
invocations are started before awaiting either result, using concurrent promise
handling while preserving the separate raisedFirst and raisedSecond callbacks
and identity assertions. Ensure both registry entries remain active
simultaneously to validate that rapid concurrent errors do not collide.

In
`@baml_language/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts`:
- Around line 53-69: Update the traceFn method to be generic over the entire
function type, preserving fn’s parameter tuple and return type in the wrapped
function signature. Keep the existing context tracing, invocation, and
error-handling behavior unchanged while replacing the unknown[] parameter typing
with inferred function parameters.
- Around line 71-87: Update traceFnAsync to be generic over the wrapped function
type and derive its arguments from Parameters<F>, while preserving the Promise
return type and this binding behavior. Ensure the returned wrapper accepts the
original function’s parameter types instead of (...args: unknown[]), matching
the type-safety approach used by traceFn.
🪄 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

Run ID: 8ca825c2-1b2c-4c54-b61f-8a91878f0720

📥 Commits

Reviewing files that changed from the base of the PR and between 708799d and 4313734.

⛔ Files ignored due to path filters (47)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/ctx_manager.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/define_function.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/errors.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/exit_hook.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/host_value_registry.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/index.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/index.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/native.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/native.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/proto/baml_cffi.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/proto/baml_cffi.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/stream.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/typemap.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.d.ts is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.d.ts.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.js is excluded by !**/dist/**
  • baml_language/sdks/typescript/bridge_typescript/dist/wire_ty.js.map is excluded by !**/dist/**, !**/*.map
  • baml_language/sdks/typescript/bridge_typescript/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (135)
  • .github/workflows/build2-nodejs-sdk.reusable.yaml
  • .github/workflows/cargo-tests.reusable.yaml
  • .github/workflows/ci.yaml
  • .github/workflows/publish2-nodejs-sdk.yaml
  • .gitignore
  • baml_language/.config/nextest.toml
  • baml_language/Cargo.toml
  • baml_language/crates/baml_cli/Cargo.toml
  • baml_language/crates/baml_cli/src/generate.rs
  • baml_language/crates/baml_codegen_types/src/generator_fields.rs
  • baml_language/crates/bex_engine/src/lib.rs
  • baml_language/crates/bex_engine/tests/host_value_callable.rs
  • baml_language/crates/bridge_ctypes/README.md
  • baml_language/sdk_tests/DEVELOPMENT.md
  • baml_language/sdk_tests/README.md
  • baml_language/sdk_tests/crates/python_pydantic2/function_calls/customizable/test_methods_on_classes.py
  • baml_language/sdk_tests/crates/typescript/Cargo.toml
  • baml_language/sdk_tests/crates/typescript/build.rs
  • baml_language/sdk_tests/crates/typescript/docstrings_etc/customizable/main.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/cancellation.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/host_callables.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/methods_on_classes.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/optional_args.static.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/optional_args.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/runtime.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/stdlib_entrypoints.node.test.ts
  • baml_language/sdk_tests/crates/typescript/function_calls/customizable/union_throws.test.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/replay_harness.node.ts
  • baml_language/sdk_tests/crates/typescript/llm_functions/customizable/streaming_e2e.node.test.ts
  • baml_language/sdk_tests/crates/typescript/setup.ps1
  • baml_language/sdk_tests/crates/typescript/setup.sh
  • baml_language/sdk_tests/crates/typescript/src/lib.rs
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/main.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_aliases.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_class_refs.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_complex_models.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_enums.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_forward_refs.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_generics.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_handles.node.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_lists.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_literals.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_maps.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_media.node.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_optional.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_primitives.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_recursion.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_routing.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_streams.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_symbol_collisions.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_unions.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/roundtrip_void.test.ts
  • baml_language/sdk_tests/crates/typescript/type_shapes/customizable/test_generic.test.ts
  • baml_language/sdk_tests/crates/typescript_node/build.rs
  • baml_language/sdk_tests/fixtures/function_calls/baml_src/main.baml
  • baml_language/sdk_tests/fixtures/function_calls/baml_src/ns_generic_tests/types.baml
  • baml_language/sdk_tests/harness_runner/Cargo.toml
  • baml_language/sdk_tests/harness_runner/src/lib.rs
  • baml_language/sdk_tests/harness_setup/Cargo.toml
  • baml_language/sdk_tests/harness_setup/src/lib.rs
  • baml_language/sdk_tests/harness_setup/src/templates/package.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig_web.json
  • baml_language/sdk_tests/harness_setup/src/templates/tsconfig_workers.json
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_node.config.ts
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_web.config.ts
  • baml_language/sdk_tests/harness_setup/src/templates/vitest_workers.config.ts
  • baml_language/sdk_tests/harness_setup/src/typescript.rs
  • baml_language/sdk_tests/harness_setup/src/typescript_node.rs
  • baml_language/sdks/go/bridge_go/pkg/tests/host_callable_test.go
  • baml_language/sdks/nodejs/bridge_nodejs/typescript_src/generated-header.txt
  • baml_language/sdks/python/rust/bridge_python/src/host_value.rs
  • baml_language/sdks/typescript/bridge_typescript/.gitignore
  • baml_language/sdks/typescript/bridge_typescript/Cargo.toml
  • baml_language/sdks/typescript/bridge_typescript/build.rs
  • baml_language/sdks/typescript/bridge_typescript/package.json
  • baml_language/sdks/typescript/bridge_typescript/src/baml_call_context.rs
  • baml_language/sdks/typescript/bridge_typescript/src/errors.rs
  • baml_language/sdks/typescript/bridge_typescript/src/handle.rs
  • baml_language/sdks/typescript/bridge_typescript/src/host_value.rs
  • baml_language/sdks/typescript/bridge_typescript/src/lib.rs
  • baml_language/sdks/typescript/bridge_typescript/src/media.rs
  • baml_language/sdks/typescript/bridge_typescript/src/runtime.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/collector.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/host_span_manager.rs
  • baml_language/sdks/typescript/bridge_typescript/src/types/mod.rs
  • baml_language/sdks/typescript/bridge_typescript/tests/call_function.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/host_callable.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/run_vitest.rs
  • baml_language/sdks/typescript/bridge_typescript/tests/test_decode_call_result.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_decode_handle.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_engine.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_media.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_stream.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tests/test_typemap.test.ts
  • baml_language/sdks/typescript/bridge_typescript/tsconfig.json
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/clean-dist.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/copy-native-dts.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/copy-proto.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/ctx_manager.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/define_function.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/exit_hook.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/generated-header.txt
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/host_value_registry.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/index.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/native.d.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto/baml_cffi.d.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/proto/baml_cffi.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/stream.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/tag-generated-files.js
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/typemap.ts
  • baml_language/sdks/typescript/bridge_typescript/typescript_src/wire_ty.ts
  • baml_language/sdks/typescript/bridge_typescript/vitest.config.ts
  • baml_language/sdks/typescript/sdkgen_typescript_shared/Cargo.toml
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/class.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/enum_.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/function.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/method.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/mod.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/type_alias.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/emit/typemap_file.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/leaf.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/lib.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/routing.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/sdkgen_typescript.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/sdkgen_typescript_web.rs
  • baml_language/sdks/typescript/sdkgen_typescript_shared/src/translate_ty.rs
  • baml_language/stow.toml
  • pnpm-workspace.yaml
  • scripts/baml-language-version
  • tools/build
💤 Files with no reviewable changes (3)
  • baml_language/sdks/nodejs/bridge_nodejs/typescript_src/generated-header.txt
  • baml_language/sdk_tests/crates/typescript_node/build.rs
  • baml_language/sdk_tests/harness_setup/src/typescript_node.rs
🛑 Comments failed to post (5)
baml_language/sdk_tests/crates/typescript/function_calls/customizable/cancellation.node.test.ts (1)

137-158: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Missing fast-cancellation timing assertion in the last test.

Every other test in this suite captures start and ends with expectFastCancellation(start); this test (reused call context) omits both, so it won't catch a regression where cancellation on a reused context becomes slow.

🕐 Proposed fix to add the timing check
   it("surfaces a reused call context as AbortError with BAML reason", async () => {
+    const start = performance.now();
     const ctx = new BamlCallContext();
     const pending = callFunction(
       getRuntime(),
       SLEEP_FQN,
       { ms: 2000 },
       undefined,
       undefined,
       ctx,
     );

     await new Promise((resolve) => setTimeout(resolve, 50));
     ctx.abort();

     try {
       await pending;
       throw new Error("expected callFunction to reject");
     } catch (error) {
       expectBamlCancelledReason(error);
     }
+
+    expectFastCancellation(start);
   });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  it("surfaces a reused call context as AbortError with BAML reason", async () => {
    const start = performance.now();
    const ctx = new BamlCallContext();
    const pending = callFunction(
      getRuntime(),
      SLEEP_FQN,
      { ms: 2000 },
      undefined,
      undefined,
      ctx,
    );

    await new Promise((resolve) => setTimeout(resolve, 50));
    ctx.abort();

    try {
      await pending;
      throw new Error("expected callFunction to reject");
    } catch (error) {
      expectBamlCancelledReason(error);
    }

    expectFastCancellation(start);
  });
});
🤖 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/sdk_tests/crates/typescript/function_calls/customizable/cancellation.node.test.ts`
around lines 137 - 158, Update the reused-call-context test “surfaces a reused
call context as AbortError with BAML reason” to capture a start timestamp before
invoking callFunction and call expectFastCancellation(start) after verifying the
cancellation reason. Preserve the existing abort and rejection assertions.
baml_language/sdks/typescript/bridge_typescript/src/host_value.rs (1)

129-140: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Inconsistent mutex-poisoning handling vs. rest of the file.

Every other lock site in this file (drop_registry_entry, host_dispatch_callback) explicitly matches Err on .lock() and degrades gracefully with a logged warning. Here, .unwrap() (Line 138) would panic on a poisoned mutex instead of returning a clear napi::Result error, which is inconsistent with the file's stated design intent of never panicking across this FFI boundary.

🛡️ Suggested fix
-    let key = next_key();
-    REGISTRY.table.lock().unwrap().insert(key, Arc::new(tsfn));
-    Ok(HandleKey::from_u64(key))
+    let key = next_key();
+    match REGISTRY.table.lock() {
+        Ok(mut t) => {
+            t.insert(key, Arc::new(tsfn));
+            Ok(HandleKey::from_u64(key))
+        }
+        Err(e) => Err(napi::Error::new(
+            napi::Status::GenericFailure,
+            format!("host-callable registry mutex poisoned during registration: {e}"),
+        )),
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

pub fn register_host_callable(callable: Function<'_, DispatchArgs, ()>) -> napi::Result<HandleKey> {
    let tsfn: DispatchTsfn = callable
        .build_threadsafe_function()
        .callee_handled::<false>()
        .weak::<false>()
        // Bound the queue (napi's default is unbounded); see DISPATCH_QUEUE_SIZE.
        .max_queue_size::<DISPATCH_QUEUE_SIZE>()
        .build()?;
    let key = next_key();
    match REGISTRY.table.lock() {
        Ok(mut t) => {
            t.insert(key, Arc::new(tsfn));
            Ok(HandleKey::from_u64(key))
        }
        Err(e) => Err(napi::Error::new(
            napi::Status::GenericFailure,
            format!("host-callable registry mutex poisoned during registration: {e}"),
        )),
    }
}
🤖 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/sdks/typescript/bridge_typescript/src/host_value.rs` around
lines 129 - 140, Update register_host_callable to handle REGISTRY.table.lock()
poisoning explicitly instead of calling unwrap. Match the lock result
consistently with drop_registry_entry and host_dispatch_callback, log the
warning through the file’s existing mechanism, and return an appropriate
napi::Result error without panicking across the FFI boundary.
baml_language/sdks/typescript/bridge_typescript/typescript_src/define_function.ts (1)

234-239: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject $types instead of silently ignoring it on non-generic calls.

Both isGeneric branches return [] without invoking resolveTypesOption, so $types is accepted and discarded despite the strict contract documented at Line 236.

Proposed fix
-    const isGeneric = typeParams.length > 0;
     const typeArgsFor = (built: BuiltArgs): WireTypeArg[] =>
-        isGeneric ? buildTypeArgs(undefined, built.types, typeParams, []) : [];
+        buildTypeArgs(undefined, built.types, typeParams, []);

-    const isGeneric = typeParams.length > 0 || classTypeParams.length > 0;
-
     const makeArgs = (self: unknown, args: unknown[]): BuiltArgs => {
...
             const typeArgsFor = (built: BuiltArgs): WireTypeArg[] =>
-                isGeneric ? buildTypeArgs(self, built.types, typeParams, classTypeParams) : [];
+                buildTypeArgs(self, built.types, typeParams, classTypeParams);

Also applies to: 298-311

🤖 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/sdks/typescript/bridge_typescript/typescript_src/define_function.ts`
around lines 234 - 239, Update typeArgsFor and the corresponding non-generic
handling near the later type-argument path to call resolveTypesOption even when
isGeneric is false. Reject any supplied $types value with the same strict
validation/error behavior as the generic path, while continuing to return no
type arguments when $types is absent.
baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts (1)

81-84: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== errors.ts ==\n'
ast-grep outline baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts --view expanded || true
printf '\n== index.ts ==\n'
ast-grep outline baml_language/sdks/typescript/bridge_typescript/typescript_src/index.ts --view expanded || true
printf '\n== search typed errors / wrapNativeError ==\n'
rg -n "wrapNativeError|BamlInvalidArgumentError|BamlClientError|BamlCancelledError|BamlPanic|BamlAbortError|napi::Error|typed Baml" baml_language/sdks/typescript/bridge_typescript/typescript_src -S
printf '\n== relevant slices ==\n'
sed -n '1,220p' baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts
printf '\n--- index.ts slice ---\n'
sed -n '1,260p' baml_language/sdks/typescript/bridge_typescript/typescript_src/index.ts
printf '\n--- handle.rs search ---\n'
rg -n "status_to_napi|GenericFailure|InvalidArgument|Client|Cancelled|Abort" baml_language -S

Repository: BoundaryML/baml

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# If the previous outline was too broad, grab narrower line-numbered slices.
sed -n '1,220p' baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts | cat -n
printf '\n---\n'
sed -n '1,320p' baml_language/sdks/typescript/bridge_typescript/typescript_src/index.ts | cat -n

Repository: BoundaryML/baml

Length of output: 12928


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Minimal evidence gathering: show exact lines around the wrapper and its call sites.
for f in \
  baml_language/sdks/typescript/bridge_typescript/typescript_src/errors.ts \
  baml_language/sdks/typescript/bridge_typescript/typescript_src/index.ts
do
  echo "===== $f ====="
  nl -ba "$f" | sed -n '1,260p'
done

echo "===== usages ====="
rg -n "wrapNativeError|BamlInvalidArgumentError|BamlClientError|BamlCancelledError|BamlPanic|BamlAbortError" baml_language/sdks/typescript/bridge_typescript/typescript_src -S

Repository: BoundaryML/baml

Length of output: 279


Parse native errors into typed subclasses
wrapNativeError always returns BamlError, so native napi::Error failures can never surface as BamlInvalidArgumentError or BamlClientError. Map the native message/code to the right subclass here before rethrowing.

🤖 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/sdks/typescript/bridge_typescript/typescript_src/errors.ts`
around lines 81 - 84, Update wrapNativeError to inspect the native error’s
message and code, then return the corresponding typed subclass such as
BamlInvalidArgumentError or BamlClientError instead of always constructing
BamlError. Preserve the existing String(err) fallback for non-Error values and
ensure unmapped errors continue returning the generic BamlError.
baml_language/sdks/typescript/bridge_typescript/typescript_src/wire_ty.ts (1)

141-167: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve never and union bindings during wire decoding.

These types are valid BamlType tokens and are emitted by lowerTypeToWireTy, but the inverse path currently converts them to undefined. Returned generic instances therefore lose their concrete type bindings.

Proposed fix
     if (!ty) return undefined;
+    if (ty.never) return Never;
     if (ty.primitive) {
         return TY_PRIMITIVE_TOKEN[ty.primitive.kind ?? -1] ?? undefined;
     }
...
     if (ty.optional) return { optional: outboundTyToBamlType(ty.optional.inner) };
+    if (ty.union) {
+        return {
+            union: (ty.union.options ?? []).map((option) =>
+                outboundTyToBamlType(option)
+            ),
+        };
+    }
     if (ty.classTy) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export function outboundTyToBamlType(
    ty: baml_bridge.cffi.v1.IBamlTy | null | undefined,
): BamlType {
    if (!ty) return undefined;
    if (ty.never) return Never;
    if (ty.primitive) {
        return TY_PRIMITIVE_TOKEN[ty.primitive.kind ?? -1] ?? undefined;
    }
    if (ty.list) return { list: outboundTyToBamlType(ty.list.item) };
    if (ty.map) {
        return { map: [outboundTyToBamlType(ty.map.key), outboundTyToBamlType(ty.map.value)] };
    }
    if (ty.optional) return { optional: outboundTyToBamlType(ty.optional.inner) };
    if (ty.union) {
        return {
            union: (ty.union.options ?? []).map((option) =>
                outboundTyToBamlType(option)
            ),
        };
    }
    if (ty.classTy) {
        const fqn = ty.classTy.name ?? '';
        const args = (ty.classTy.typeArgs ?? []).map((a) => outboundTyToBamlType(a));
        let ctor: BamlClassCtor | undefined;
        try {
            ctor = getTypeMap().getClass(fqn) as BamlClassCtor;
        } catch {
            ctor = undefined; // unmapped FQN — leave unbound
        }
        if (!ctor) return undefined;
        return args.length ? { class: ctor, args } : ctor;
    }
    // union / enum / literal / media / type_var / unknown / any other →
    // unbound wildcard (a structural union is unbound for `class<args>`).
    return undefined;
}
🤖 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/sdks/typescript/bridge_typescript/typescript_src/wire_ty.ts`
around lines 141 - 167, Update outboundTyToBamlType to preserve wire-encoded
never and union types emitted by lowerTypeToWireTy instead of falling through to
undefined. Decode each representation into the corresponding BamlType token or
binding, while retaining the existing handling for primitive, collection,
optional, and class types.

This branch was previously deployed

3 inactive deployments
Preview – promptfiddle — 43137347 Deployed Jul 16, 2026 by vercel[bot]
Preview – promptfiddle2 — 43137347 Deployed Jul 16, 2026 by vercel[bot]
Preview – beps — 43137347 Deployed Jul 16, 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