Skip to content

feat(playground): schema-driven dynamic args form for the Run tab#3935

Merged
rossirpaulo merged 12 commits into
canaryfrom
paulo/playground-dynamic-form-generator
Jul 8, 2026
Merged

feat(playground): schema-driven dynamic args form for the Run tab#3935
rossirpaulo merged 12 commits into
canaryfrom
paulo/playground-dynamic-form-generator

Conversation

@rossirpaulo

@rossirpaulo rossirpaulo commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the raw-JSON args input in the playground Run tab with a schema-driven form: selecting a function now renders one typed widget per parameter (primitives, enums, classes with nested fields, optionals, lists, maps, unions), while serializing into the existing argsJson pipeline so the run path, prompt/cURL previews, per-function memory, and run history are unchanged. A raw-JSON toggle and per-field raw fallbacks remain for anything the form can't render.

How it works

Schema extraction (Rust). New baml_project::param_schema builds a self-contained ParamSchema/FieldSchema tree per function from the Salsa-cached package_interface: class fields and enum variants are expanded inline (cycle-guarded — recursive types cut to a raw-JSON node), T | null folds into Optional, aliases resolve before dispatch, dependency-package (stdlib) types resolve through their own interface, and everything non-data (generics, interfaces, TIR sentinels while mid-edit) degrades to Unsupported instead of erroring.

Transport. The schema rides as params?: ParamSchema[] on FunctionInfo in the updateProject notification, on both transports (WebSocket serializes the source struct directly; the WASM worker path gets tsify twins + From mapping). undefined means no schema (UI degrades to raw-only, old binaries keep working); [] means nullary — the distinction is load-bearing.

Names are canonical dotted FQNs. Class/enum names in schemas (and the $baml markers the form emits) use exactly the form the engine registers: user.shapes.Foo, baml.time.PlainDate. This round-trips verbatim through the encoder and resolves in the engine registry without fallbacks, and makes nested class values decode as real instances — something raw-JSON users couldn't express ergonomically before.

New enum wire marker. serializeValue now honors { "$baml": { "enum": "user.Color", "value": "Red" } }InboundEnumValue. Nothing on the args path coerces plain strings into enum variants, so expr functions previously received strings and param == Color.Red was silently false; the form now produces real VM variants.

UI. ArgsForm dispatches recursively on schema node type (mirroring ValueRenderer's conventions), with pure logic split into a unit-tested args-form-model. Form and raw input write through a single setter so previews and per-function memory never desync; empty args are seeded once per function from schema defaults (injecting required keys and $baml markers automatically); parameters with declared defaults render as omitted with a "set" toggle. New thin UI primitives: Switch (radix) and Select (styled native).

Run ergonomics. The primary Run button (with a platform hint, ⌘↵/Ctrl+↵) is docked in the args strip on the Run tab; other tabs keep a compact play icon in the top bar so re-running while watching the graph stays one click. Cmd/Ctrl+Enter runs from anywhere inside the panel (scoped so it never steals the binding from the host code editor).

Testing

  • baml_project: 12 new unit tests (enum, nested/namespaced/recursive class, recursive alias, unions, maps, unresolved and generic params, stdlib class, defaults, nullary).
  • pkg-proto: enum-marker encoding tests, top-level and nested positions.
  • pkg-playground: 14 model tests; typecheck clean.
  • app-vscode-webview: integration tests for form rendering → argsJson serialization → startRun, the nullary state, the no-schema degradation path, and the keyboard shortcut.
  • Verified end-to-end in promptfiddle against the locally built WASM: enum param on an expr function evaluates c == Color.Greentrue; nested class instance decodes ("Ada from Paris"); namespaced user.shapes.Box resolves (42); omitted defaulted param gets the engine default (15); form edits preserve unknown raw-JSON keys.

Out of scope

Media upload widgets (raw-JSON per-field for now), generic class instances (encoder sends typeArgs: []), test-args editing (tests run engine-side by name), and hydrating the form from a previous run's decoded input.

Summary by CodeRabbit

  • New Features
    • Added schema-driven “args” editing in the playground (typed widgets for primitives, enums, classes, lists/maps, optionals, unions) with a raw/unsupported fallback.
    • Extended function metadata to include parameter schemas and a shared named-type table, surfaced in the LSP and WASM playground updates.
    • Added a Cmd/Ctrl+Enter run shortcut and improved args form/raw switching.
  • Bug Fixes
    • Improved $baml enum-marker encoding/decoding, including nested and malformed marker handling.
  • Tests
    • Added/expanded UI, worker protocol, and golden fixture tests for schema parity and wire-shape consistency.
  • Chores
    • Updated fixture formatting (LF) and TypeScript config to include JSON sources.

ParamSchema/FieldSchema tree for the dynamic args form: inline-expanded
class/enum bodies (cycle-guarded), nullable-union folding, alias
resolution, dependency-package lookup, Unsupported fallback for
non-data types and TIR sentinels. Class/enum names are the canonical
dotted FQN the engine registers (user.shapes.Foo) so $baml markers
round-trip.
…nsports

WebSocket picks the new field up automatically (source struct is
serialized directly); the WASM worker path gets tsify twins plus the
mandatory From mapping. None (omitted) = no schema; [] = nullary.
- pkg-proto: $baml {enum, value} marker encodes InboundEnumValue so expr
  functions receive real variants (no string→enum coercion exists)
- worker-protocol: ParamSchema/FieldSchema mirror, params on
  FunctionInfo, add missing 'autoDerive' origin
- ArgsForm: recursive schema-directed widgets over a controlled value
  record; pure logic split into args-form-model for unit testing
- new ui primitives: Switch (radix), Select (styled native)
Form-by-default with a raw-JSON toggle; both write through one setter
(setArgsJson + typedArgsByFnRef) so prompt/cURL previews, per-function
memory, and run-history snapshots stay in sync. Args that don't parse
to a JSON object keep raw mode with a notice. Empty args are seeded
once per function from schema defaults, injecting $baml class/enum
markers. No schema (params undefined) degrades to the old raw input.
Primary Run (with platform shortcut hint) moves into the args strip on
the Run tab; other tabs get a compact play icon in the top bar so
re-running while watching the graph stays one click. Cmd/Ctrl+Enter
runs from anywhere inside the panel without stealing the binding from
the host code editor. Raw-JSON fallback fields now use the ui kit
Textarea.
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 8, 2026 9:26am
promptfiddle Ready Ready Preview, Comment Jul 8, 2026 9:26am
promptfiddle2 Ready Ready Preview, Comment Jul 8, 2026 9:26am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds parameter schema metadata from Rust into the playground transport, then renders those schemas in the args editor. Enum marker serialization is updated so playground values round-trip through the wire format.

Changes

Backend param schema generation and wiring

Layer / File(s) Summary
ParamSchema data model and conversion logic
baml_language/crates/baml_project/src/param_schema.rs, baml_language/crates/baml_project/src/lib.rs, baml_language/crates/baml_project/Cargo.toml
Defines parameter schema types, converts resolved TIR types into recursive FieldSchema values, adds tests, re-exports the types, and adds serde_json as a dependency.
FunctionSymbol and LSP params wiring
baml_language/crates/baml_project/src/symbols.rs, baml_language/crates/bex_project/src/bex_lsp/mod.rs, baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs, baml_language/crates/bex_project/src/lib.rs
Adds params metadata to function symbol and LSP project update structures and populates it from function_param_schemas.
WASM bridge schema types and conversion
baml_language/crates/bridge_wasm/src/wasm_playground.rs
Adds WASM-facing schema types, conversion from bex_project, and notification wiring for function params.

Playground args form UI and enum marker encoding

Layer / File(s) Summary
Worker protocol schema types
typescript2/pkg-playground/src/worker-protocol.ts
Adds shared schema types for function params and extends FunctionInfo with optional params metadata.
args-form-model helper logic
typescript2/pkg-playground/src/args-form-model.ts, typescript2/pkg-playground/src/args-form-model.test.ts, typescript2/pkg-playground/src/__fixtures__/param-schema-golden.json, typescript2/pkg-playground/tsconfig.json
Adds enum marker helpers, default value generation, schema/value matching, schema labels, raw-JSON fallback rules, and tests/fixture coverage.
Select and Switch UI primitives
typescript2/pkg-playground/src/components/ui/select.tsx, typescript2/pkg-playground/src/components/ui/switch.tsx
Adds the UI controls used by enum, boolean, and form toggles.
ArgsForm component and field editors
typescript2/pkg-playground/src/ArgsForm.tsx
Implements the schema-driven args editor with recursive field rendering for all supported schema kinds.
ExecutionPanel integration and run shortcut
typescript2/pkg-playground/src/ExecutionPanel.tsx, typescript2/app-vscode-webview/src/ExecutionPanel.strict-mode.test.tsx
Switches the panel to form/raw args modes, seeds defaults, adds the run shortcut, and covers the new behavior in StrictMode tests.
Enum marker encoding in pkg-proto
typescript2/pkg-proto/src/encode.ts, typescript2/pkg-proto/src/test/encode-decode.test.ts
Serializes $baml enum markers as enumValue payloads and verifies nested and malformed cases.

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

Sequence Diagram(s)

sequenceDiagram
  participant list_functions_with_metadata
  participant function_param_schemas
  participant build_project_update
  participant PlaygroundNotification
  list_functions_with_metadata->>function_param_schemas: extract ParamSchema + TypeSchema
  function_param_schemas-->>build_project_update: FunctionListing
  build_project_update->>PlaygroundNotification: populate FunctionInfo.params and ProjectUpdate.types
  PlaygroundNotification-->>build_project_update: transport metadata to webview
Loading
sequenceDiagram
  participant ExecutionPanel
  participant ArgsForm
  participant args-form-model
  participant pkg-proto
  ExecutionPanel->>args-form-model: typeLookupFrom(types)
  ExecutionPanel->>ArgsForm: render params + current args
  ArgsForm->>args-form-model: normalizeArgs / valueMatchesSchema
  ExecutionPanel->>pkg-proto: serializeValue($baml.enum)
  pkg-proto-->>ExecutionPanel: enumValue payload
Loading

Possibly related PRs

  • BoundaryML/baml#3393: Shares the same origin/provenance filtering path that determines when parameter schemas are generated.
  • BoundaryML/baml#3476: Adds compiler-side default/omitted-parameter metadata consumed by the new param schema output.
  • BoundaryML/baml#3464: Touches the same media schema/rendering surface used by the new args form schema types.

Poem

I hop through schemas, neat and bright,
With $baml markers tucked just right.
The form says “run,” the types say “go,”
And enums bounce in tidy flow.
A rabbit grin, a JSON glow.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: a schema-driven dynamic args form for the Playground Run tab.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch paulo/playground-dynamic-form-generator

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

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

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

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

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

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Binary size checks passed

7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
baml-cli Linux 🔒 21.9 MB 9.4 MB file 21.5 MB +373.4 KB (+1.7%) OK
packed-program Linux 🔒 15.9 MB 6.7 MB file 15.6 MB +258.2 KB (+1.7%) OK
baml-cli macOS 🔒 16.9 MB 8.2 MB file 16.6 MB +298.3 KB (+1.8%) OK
packed-program macOS 🔒 12.3 MB 5.8 MB file 12.1 MB +198.9 KB (+1.6%) OK
baml-cli Windows 🔒 18.4 MB 8.4 MB file 18.1 MB +312.3 KB (+1.7%) OK
packed-program Windows 🔒 13.2 MB 5.9 MB file 13.0 MB +202.9 KB (+1.6%) OK
bridge_wasm WASM 14.7 MB 🔒 4.2 MB gzip 4.1 MB +105.9 KB (+2.6%) OK

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


Generated by cargo size-gate · workflow run

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (3)
baml_language/crates/bridge_wasm/src/wasm_playground.rs (1)

11-143: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicated wire-format enum across two crates — manual sync risk.

FieldSchema/ParamSchema/FieldSchemaField here are hand-duplicated twins of baml_project::FieldSchema/etc. (acknowledged in the comment at Lines 41-43). Any future variant/field added to the baml_project schema must be remembered here too, with matching serde tags, or the WASM and WebSocket transports will silently diverge. The exhaustive match in the From impl will at least fail to compile on a missing variant, which mitigates most of the risk.

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

In `@baml_language/crates/bridge_wasm/src/wasm_playground.rs` around lines 11 -
143, The wire-format types in wasm_playground.rs are duplicated copies of the
project schema types, so they can drift if new fields or variants are added.
Update the conversion layer centered on the FieldSchema, ParamSchema, and
FieldSchemaField definitions to stay in lockstep with the source bex_project
types, and add a serialization/round-trip test that compares the WASM and
WebSocket shapes. Keep the exhaustive From<bex_project::FieldSchema> match in
sync so any new variant forces a compile-time update.
typescript2/pkg-proto/src/encode.ts (1)

66-86: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Malformed enum marker silently falls through to generic map serialization.

If $baml.enum is set but value is missing/non-string, the object skips this branch and (since type is also absent) falls into the plain-object map path at Line 118-124, which — unlike the type marker branch — doesn't filter out the $baml key. The literal $baml object gets serialized as a map entry, producing a confusing runtime-side error instead of a clear client-side failure.

🛡️ Proposed fix: fail fast on malformed enum markers
     if (
       bamlMarker &&
       typeof bamlMarker === 'object' &&
-      typeof (bamlMarker as Record<string, unknown>).enum === 'string' &&
-      typeof (bamlMarker as Record<string, unknown>).value === 'string'
+      'enum' in (bamlMarker as Record<string, unknown>)
     ) {
+      if (
+        typeof (bamlMarker as Record<string, unknown>).enum !== 'string' ||
+        typeof (bamlMarker as Record<string, unknown>).value !== 'string'
+      ) {
+        throw new Error(
+          `Malformed $baml enum marker: expected { enum: string, value: string }, got ${JSON.stringify(bamlMarker)}`,
+        );
+      }
       const marker = bamlMarker as { enum: string; value: string };
       return {
         value: {
           $case: 'enumValue',
           enumValue: { name: marker.enum, value: marker.value },
         },
       };
     }
🤖 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 `@typescript2/pkg-proto/src/encode.ts` around lines 66 - 86, In `encode.ts`
within the `bamlMarker` handling in `encodeValue`, malformed `$baml.enum`
markers are currently ignored and then serialized as a plain map entry. Update
this branch to fail fast when `$baml.enum` is present but `value` is missing or
not a string, instead of falling through to the generic object/map path. Keep
the existing enum-marker success path intact, and ensure the validation is tied
to the `bamlMarker`/`marker` logic so the `$baml` object is never emitted as a
map entry on invalid enum markers.
typescript2/app-vscode-webview/src/ExecutionPanel.strict-mode.test.tsx (1)

177-258: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding regression coverage for switching away and back to a seeded function.

This test never switches to another function and back after the form auto-seeds defaults. That's the exact path where the setArgsJson/updateArgsJson desync flagged in ExecutionPanel.tsx (seed effect) would surface as lost defaults.

🤖 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 `@typescript2/app-vscode-webview/src/ExecutionPanel.strict-mode.test.tsx`
around lines 177 - 258, Add regression coverage for the seed/reset path in
ExecutionPanel: after selecting a function that auto-seeds defaults, switch to
another function and then back to the original one to verify argsJson stays in
sync. Update the strict-mode test around ExecutionPanel, the Greet selection
flow, and the args form/raw toggle to assert defaults are preserved after the
reselection path. Focus the scenario on the setArgsJson/updateArgsJson behavior
triggered by the seed effect in ExecutionPanel.tsx.
🤖 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 `@typescript2/pkg-playground/src/ArgsForm.tsx`:
- Around line 205-243: The NumberField input currently calls onChange(undefined)
when the draft is emptied, which causes required numeric args to disappear from
argsJson instead of showing a visible error state. Update NumberField to treat
an empty draft as invalid for non-optional/no-default params by keeping
aria-invalid set and/or surfacing an explicit required hint, and avoid emitting
undefined in that case; use the existing NumberField, useDraft, and onChange
flow to preserve the key until the user enters a valid number.
- Around line 269-284: The placeholder option in ArgsForm’s enum Select can be
chosen and currently feeds an empty string into enumValue, creating an invalid
enum marker. Update the Select onChange handling so choosing the “select…”
placeholder does not call onChange with enumValue(schema.name, ''); instead
treat it as no selection (for example by clearing the value or ignoring the
change) while keeping the placeholder rendering based on current being
undefined. Use the existing ArgsForm Select, onChange, and enumValue logic to
make the fix.
- Around line 151-153: The bigint handling in ArgsForm is still routed through
NumberField, which coerces input to Number and loses precision before encoding.
Update the case for bigint in ArgsForm to use a bigint-aware input/parsing path
instead of the integer NumberField branch, and ensure the value passed through
props remains a bigint so encode.ts can emit it without precision loss.

In `@typescript2/pkg-playground/src/components/ui/switch.tsx`:
- Around line 1-8: The Switch component in switch.tsx uses React.ComponentProps
without importing React, so the React namespace is undefined for type-checking.
Add the React import at the top of the file, matching the import pattern used by
the other UI components, and keep the Switch function signature using
React.ComponentProps<typeof SwitchPrimitive.Root>.

In `@typescript2/pkg-playground/src/ExecutionPanel.tsx`:
- Around line 2362-2370: The Cmd/Ctrl+Enter handler in ExecutionPanel bypasses
the same build-error gate used by the Run button because it calls
onRunFunction() directly. Update the shortcut path so it respects hasErrors the
same way the button does, either by adding the guard before invoking
onRunFunction or by centralizing the disabled check inside onRunFunction itself;
make sure the keyboard shortcut cannot run while errors exist, and keep the
behavior aligned with the existing Run button state.
- Around line 2054-2071: The seed initialization in ExecutionPanel’s args
seeding effect is bypassing the single source of truth by calling setArgsJson
directly, which leaves typedArgsByFnRef out of sync and causes seeded defaults
to disappear when the function is reselected. Update this effect to use
updateArgsJson instead of setArgsJson so the seeded JSON is written through the
same path as user edits, and keep the seededFnsRef/typedArgsByFnRef checks
intact to avoid reseeding already-typed functions.

---

Nitpick comments:
In `@baml_language/crates/bridge_wasm/src/wasm_playground.rs`:
- Around line 11-143: The wire-format types in wasm_playground.rs are duplicated
copies of the project schema types, so they can drift if new fields or variants
are added. Update the conversion layer centered on the FieldSchema, ParamSchema,
and FieldSchemaField definitions to stay in lockstep with the source bex_project
types, and add a serialization/round-trip test that compares the WASM and
WebSocket shapes. Keep the exhaustive From<bex_project::FieldSchema> match in
sync so any new variant forces a compile-time update.

In `@typescript2/app-vscode-webview/src/ExecutionPanel.strict-mode.test.tsx`:
- Around line 177-258: Add regression coverage for the seed/reset path in
ExecutionPanel: after selecting a function that auto-seeds defaults, switch to
another function and then back to the original one to verify argsJson stays in
sync. Update the strict-mode test around ExecutionPanel, the Greet selection
flow, and the args form/raw toggle to assert defaults are preserved after the
reselection path. Focus the scenario on the setArgsJson/updateArgsJson behavior
triggered by the seed effect in ExecutionPanel.tsx.

In `@typescript2/pkg-proto/src/encode.ts`:
- Around line 66-86: In `encode.ts` within the `bamlMarker` handling in
`encodeValue`, malformed `$baml.enum` markers are currently ignored and then
serialized as a plain map entry. Update this branch to fail fast when
`$baml.enum` is present but `value` is missing or not a string, instead of
falling through to the generic object/map path. Keep the existing enum-marker
success path intact, and ensure the validation is tied to the
`bamlMarker`/`marker` logic so the `$baml` object is never emitted as a map
entry on invalid enum markers.
🪄 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: 875b74e6-bcd1-4abd-a808-27a133b75218

📥 Commits

Reviewing files that changed from the base of the PR and between 939fbbb and 3b20362.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • baml_language/crates/baml_project/Cargo.toml
  • baml_language/crates/baml_project/src/lib.rs
  • baml_language/crates/baml_project/src/param_schema.rs
  • baml_language/crates/baml_project/src/symbols.rs
  • baml_language/crates/bex_project/src/bex_lsp/mod.rs
  • baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs
  • baml_language/crates/bex_project/src/lib.rs
  • baml_language/crates/bridge_wasm/src/wasm_playground.rs
  • typescript2/app-vscode-webview/src/ExecutionPanel.strict-mode.test.tsx
  • typescript2/pkg-playground/src/ArgsForm.tsx
  • typescript2/pkg-playground/src/ExecutionPanel.tsx
  • typescript2/pkg-playground/src/args-form-model.test.ts
  • typescript2/pkg-playground/src/args-form-model.ts
  • typescript2/pkg-playground/src/components/ui/select.tsx
  • typescript2/pkg-playground/src/components/ui/switch.tsx
  • typescript2/pkg-playground/src/worker-protocol.ts
  • typescript2/pkg-proto/src/encode.ts
  • typescript2/pkg-proto/src/test/encode-decode.test.ts

Comment thread typescript2/pkg-playground/src/ArgsForm.tsx
Comment thread typescript2/pkg-playground/src/ArgsForm.tsx
Comment thread typescript2/pkg-playground/src/ArgsForm.tsx
Comment thread typescript2/pkg-playground/src/components/ui/switch.tsx
Comment thread typescript2/pkg-playground/src/ExecutionPanel.tsx Outdated
Comment thread typescript2/pkg-playground/src/ExecutionPanel.tsx
- NumberField: empty/unparseable drafts are an error state, not a
  deletion — required numeric keys no longer silently drop from argsJson
- enum Select: the placeholder option is inert instead of emitting an
  empty-string variant marker
- Cmd/Ctrl+Enter respects the build-error gate like the Run buttons
- seed defaults write through updateArgsJson so they survive switching
  functions and back (regression test added)
- encode.ts: malformed $baml enum markers fail fast instead of
  serializing as a plain map
- switch.tsx: import React explicitly like the other ui components
- bridge_wasm: round-trip test pinning tsify twins to the bex_project
  serialization
@rossirpaulo
rossirpaulo enabled auto-merge July 7, 2026 23:53
@rossirpaulo
rossirpaulo added this pull request to the merge queue Jul 8, 2026
@rossirpaulo
rossirpaulo removed this pull request from the merge queue due to a manual request Jul 8, 2026
rossirpaulo and others added 3 commits July 8, 2026 01:20
Implements the TASK/REVIEW.md handoff. Named types now serialize once
into a shared per-project table (ProjectUpdate.types, keyed by canonical
dotted FQN) and are referenced by FieldSchema::Ref, so payload is
proportional to distinct types instead of paths through the type graph
(the inline-expansion P0.1 reproducer went from 88 MB to a few KB,
pinned by byte-ceiling regression tests). Aliases are memoized into the
table too — deliberate deviation from the handoff, which kept
non-recursive aliases inline: inlining re-expands the target per
reference site and is exponential on alias DAGs (reproduced 1.9 MB /
4 s on a 16-line file). Recursive types lose the raw-JSON cut-point:
class sections resolve refs lazily on expand, guarded by a ref-visited
set threaded through same-value hops so self-referential alias schemas
(`type A = A | int` compiles clean) degrade to raw JSON instead of
recursing the render.

Also fixes, each with regression tests:
- P0.2: drop the compiler-injected trailing `client: baml.llm.Client`
  param from LLM function schemas.
- P0.3: union chips honor the explicit choice while the value inhabits
  it — `float` is now reachable in `int | float`.
- P1.4a/b: skip extraction for $-companions and non-userDefined
  functions; give capture_cfg_snapshot a schema-free name listing.
- P1.5: hydration normalizes bare enum strings and markerless class
  objects into wire markers, writing through the shared setter.
- P1.6: seeding and normalization resolve the authoritative
  typed ?? argsByFunction ?? initialArgsJson chain (baseArgsFor) instead
  of the one-commit-stale parsedArgs, so host seeds can't be clobbered.
- P1.7: Cmd/Ctrl+Enter no longer starts invisible runs from the
  collection/test-run views.
- P1.8: RawJsonField keeps the last committed value on empty/invalid
  drafts instead of deleting map rows.
- P1.9: unknown schema tags and dangling refs route to the raw-JSON
  path; defaults never return undefined.
- P2.10-16 hygiene, including a wire-shape golden fixture asserted
  byte-identical by the Rust extractor test and validated against the
  worker-protocol.ts mirror.

E2E-verified (13 checks) in promptfiddle over the rebuilt WASM worker:
enum markers evaluate on expr functions, namespaced FQN markers,
one-level seeding, hydration round-trip, recursive and alias params.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conflict resolution: canary #3938 replaced the eager per-compile CFG
snapshot (capture_cfg_snapshot / RetainedCfgSnapshots) with a lazy
per-run RunCfgCache, deleting the function our P1.4b fix had switched
to a schema-free listing. Took canary's side — the lazy rewrite
supersedes P1.4b entirely (no function listing happens on build at
all) — and removed the now-caller-less list_playground_function_names
helper from baml_project.

Verified post-merge: cargo check/test on baml_project, bex_project,
bridge_wasm; pnpm typecheck + tests in pkg-proto (after regenerating
the renamed baml_bridge protos), pkg-playground, app-vscode-webview.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nerator'

The remote branch gained a GitHub-side canary merge (5ad8ca2) with the
same canary content already merged locally in efeef28 — content-wise a
no-op reconciliation of the two merge commits.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@baml_language/crates/baml_project/src/param_schema.rs`:
- Around line 246-300: The named-type expansion in param_schema.rs resets
recursion depth by calling field_schema(field_ty, 0) and field_schema(resolved,
0), which allows long acyclic class/alias chains to recurse one frame per hop
and risk stack overflow. Update the TypeSchema::Class and Ty::TypeAlias
expansion paths in field_schema to thread through the current depth instead of
restarting at 0, or introduce a dedicated recursion limit for named-type
expansion, while preserving the existing memoization behavior in self.table and
lookup_type.
🪄 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: 6f116edb-d737-49f3-aa6b-71f077a3c38b

📥 Commits

Reviewing files that changed from the base of the PR and between 5ad8ca2 and 19192be.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • baml_language/crates/baml_project/src/lib.rs
  • baml_language/crates/baml_project/src/param_schema.rs
  • baml_language/crates/baml_project/src/symbols.rs
  • baml_language/crates/bex_project/src/bex_lsp/mod.rs
  • baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs
  • baml_language/crates/bex_project/src/lib.rs
  • baml_language/crates/bridge_wasm/src/wasm_playground.rs
  • typescript2/app-vscode-webview/src/ExecutionPanel.strict-mode.test.tsx
  • typescript2/pkg-playground/src/ArgsForm.tsx
  • typescript2/pkg-playground/src/ExecutionPanel.tsx
  • typescript2/pkg-playground/src/__fixtures__/param-schema-golden.json
  • typescript2/pkg-playground/src/args-form-model.test.ts
  • typescript2/pkg-playground/src/args-form-model.ts
  • typescript2/pkg-playground/src/components/ui/select.tsx
  • typescript2/pkg-playground/src/param-schema-golden.test.ts
  • typescript2/pkg-playground/src/worker-protocol.ts
  • typescript2/pkg-playground/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (6)
  • baml_language/crates/bex_project/src/lib.rs
  • baml_language/crates/baml_project/src/lib.rs
  • baml_language/crates/bex_project/src/bex_lsp/multi_project/mod.rs
  • typescript2/pkg-playground/src/components/ui/select.tsx
  • typescript2/pkg-playground/src/ArgsForm.tsx
  • typescript2/pkg-playground/src/ExecutionPanel.tsx

Comment thread baml_language/crates/baml_project/src/param_schema.rs
wire_shape_matches_the_ts_golden_fixture byte-compares include_str! of
the fixture against serde_json output; autocrlf on the Windows runner
checked the fixture out with CRLF and failed the assert. Pin the
fixture to LF in .gitattributes (same precedent as *.baml) and
normalize CRLF in the test for stale checkouts that predate the
attribute.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Class/alias bodies expand nested within the referencing frame, so
resetting depth to 0 at each body let long acyclic named-type chains
recurse one native frame per hop with MAX_DEPTH never firing — a
generated chain of thousands of classes could overflow the stack
(the WASM worker's is ~1 MB). Thread the current depth through
class/alias body expansion instead; memoization is unchanged, and a
body first reached past the bound bakes an Unsupported tail into its
table entry (raw-JSON fallback in the UI). Regression test: a
101-class chain extracts bounded with an unsupported tail.

Addresses the PR review comment on param_schema.rs depth resets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@rossirpaulo
rossirpaulo enabled auto-merge July 8, 2026 09:19
@rossirpaulo
rossirpaulo added this pull request to the merge queue Jul 8, 2026
Merged via the queue into canary with commit 5a14843 Jul 8, 2026
55 checks passed
@rossirpaulo
rossirpaulo deleted the paulo/playground-dynamic-form-generator branch July 8, 2026 09:42
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