Skip to content

Virtual field accesses - #4278

Merged
2kai2kai2 merged 7 commits into
canaryfrom
kai/virtual-fields
Jul 30, 2026
Merged

2kai2kai2 merged 7 commits into
canaryfrom
kai/virtual-fields

Conversation

@2kai2kai2

@2kai2kai2 2kai2kai2 commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Previously we emitted a type tag-based switch when accessing interface fields on a non-concrete type. This was unsound and produced unnecessary overhead, so similar to the already-implemented virtual function calls, this PR adds virtual field load/stores.

Additionally:

  • Field declarations that are missing a type will get TypeExprKind::Error and emit a diagnostic in the AST, instead of being optional (since downstream consumers handled the None in different ways)
  • Virtual calls now use TyTemplateInterface where possible as the representation for the interface position (this still doesn't work on the stack but it does everywhere else)

Summary by CodeRabbit

  • New Features

    • Interface-typed values now support runtime field reads and writes, including through generic and existential values.
    • Interface field dispatch now uses declaration-order indexing and correctly links interface fields to concrete class slots.
  • Bug Fixes

    • Missing or invalid field types are now recovered consistently, producing stable diagnostics (instead of falling back to “unknown”).
    • Virtual field access resolution is safer, with clearer handling when a receiver’s interface field cannot be resolved.
  • Tests

    • Added new compiler/runtime integration coverage for interface field index and virtual-field link-table behavior.

And some other fixes:
- A field declaration (both class and interface) without a type in AST
  should emit a diagnostic and get `TypeExpr::Error` instead of being
  optional. This ensures a unified failure path instead of every
  downstream consumer having a different way of handling, erasing, or
  ignoring the problem.
@vercel

vercel Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview Jul 30, 2026 12:19am
promptfiddle Ready Ready Preview Jul 30, 2026 12:19am
promptfiddle2 Ready Ready Preview Jul 30, 2026 12:19am

Request Review

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

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

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

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

@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 272921c5-759c-4bed-842a-8bfd01416a77

📥 Commits

Reviewing files that changed from the base of the PR and between 4cb4662 and 037673b.

📒 Files selected for processing (2)
  • baml_language/crates/baml_compiler2_mir/src/lower.rs
  • baml_language/crates/baml_compiler2_mir/src/optimize.rs

📝 Walkthrough

Walkthrough

This PR makes field type expressions and references non-optional, replaces implementor enumeration with open-world interface field dispatch, emits positional interface-to-class field links, and adds virtual field bytecode operations with VM-side slot resolution.

Changes

Interface field dispatch

Layer / File(s) Summary
Required field type recovery
baml_language/crates/baml_compiler2_ast/..., baml_language/crates/baml_compiler2_hir/..., baml_language/crates/baml_compiler2_ppir/..., baml_language/crates/baml_compiler2_tir/..., baml_language/crates/baml_lsp2_actions/...
Missing field types are recovered as error expressions, and downstream compiler, codegen, cache, and tooling paths consume required type references directly.
MIR virtual field lowering
baml_language/crates/baml_compiler2_mir/..., baml_language/crates/baml_compiler2_emit/...
Interface field reads and writes lower through VirtualFieldAccess and VirtualFieldStore; MIR analysis, optimization, stack handling, and emission support the new operations.
Interface field link tables
baml_language/crates/baml_compiler2_emit/src/lib.rs, baml_language/crates/bex_vm_types/src/types/*, baml_language/crates/bex_vm_types/src/{package.rs,unit.rs,link.rs}, baml_language/crates/bex_vm/src/package_load.rs
Interface fields retain declaration order, and implementation rules carry positional mappings from interface fields to concrete class slots through package serialization and loading.
Virtual field bytecode and VM execution
baml_language/crates/bex_vm_types/src/bytecode.rs, baml_language/crates/bex_vm/src/vm.rs, baml_language/crates/bex_vm/src/debug.rs
Virtual load/store instructions are encoded, decoded, displayed, relinked, and executed with runtime implementation-rule resolution and write barriers.
Dispatch validation and regression coverage
baml_language/crates/baml_tests/..., baml_language/tools/speedtest/workloads/interfaces/field-access-100k.md
Tests cover generic interface views, existential reads and writes, positional type arguments, field ordering, field-link defaults, and the virtual field access workload.

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

Possibly related PRs

Suggested reviewers: sxlijin, codeshaunted

Poem

I’m a rabbit with fields in a row,
Through virtual burrows they go.
Slots link left to right,
Loads hop into sight,
And stores leave a bytecode 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 is concise and accurately reflects the PR’s main change: adding virtual field access 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 kai/virtual-fields

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 29, 2026 22:59 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 29, 2026 23:13 Inactive
@github-actions

github-actions Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Binary size checks passed

✅ 7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
✅ baml-cli Linux 🔒 27.4 MB 11.7 MB file 27.3 MB +118.2 KB (+0.4%) OK
✅ packed-program Linux 🔒 17.7 MB 7.3 MB file 17.7 MB +18.8 KB (+0.1%) OK
✅ baml-cli macOS 🔒 21.3 MB 10.2 MB file 21.2 MB +99.3 KB (+0.5%) OK
✅ packed-program macOS 🔒 13.9 MB 6.4 MB file 13.9 MB +32 B (+0.0%) OK
✅ baml-cli Windows 🔒 23.0 MB 10.4 MB file 22.9 MB +113.7 KB (+0.5%) OK
✅ packed-program Windows 🔒 14.8 MB 6.5 MB file 14.8 MB +839 B (+0.0%) OK
✅ bridge_wasm WASM 16.8 MB 🔒 4.6 MB gzip 4.5 MB +46.0 KB (+1.0%) 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: 5

🧹 Nitpick comments (2)
baml_language/crates/bex_vm/src/vm.rs (1)

3412-3435: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

New helper duplicates existing inline logic at VirtualCall/MakeVirtualBoundMethod.

pop_interface_operand is a clean extraction, but the identical "pop Type, match RealizedTy::Interface, unreachable! otherwise" block is still inlined separately in the (unchanged) OpCode::VirtualCall and OpCode::MakeVirtualBoundMethod handlers further down this file. Now that the helper exists, those two call sites could route through it to remove the duplication.

♻️ Example consolidation at the `VirtualCall` site
-                    let (iface_qtn, iface_args) = {
-                        let iface_ptr = self.as_object_ptr(iface_value, ObjectType::Type)?;
-                        match self.get_object(iface_ptr) {
-                            Object::Type(ty) => match ty.as_ref() {
-                                baml_type::RealizedTy::Interface(qtn, args, _assoc, _attr) => {
-                                    (qtn.clone(), args.clone())
-                                }
-                                other => unreachable!(
-                                    "VirtualCall interface operand must be an Interface type, found {other:?}"
-                                ),
-                            },
-                            other => unreachable!(
-                                "as_object_ptr(Type) guarantees a Type object, found {:?}",
-                                ObjectType::of(other)
-                            ),
-                        }
-                    };
+                    let (iface_qtn, iface_args) = self.pop_interface_operand(iface_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 `@baml_language/crates/bex_vm/src/vm.rs` around lines 3412 - 3435, Replace the
duplicated interface-operand extraction logic in the OpCode::VirtualCall and
OpCode::MakeVirtualBoundMethod handlers with calls to pop_interface_operand.
Preserve the existing interface name and argument handling, including the
current unreachable behavior for non-interface types.
baml_language/crates/baml_compiler2_ast/src/lib.rs (1)

1144-1147: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a test for the new Error recovery sentinel.

The invariant introduced in lower_cst.rs (a typeless field now yields TypeExprKind::Error rather than None) has no test in this module. A small case parsing class C { f } and asserting field.type_expr.kind is Error would pin the new contract, since every other assertion here only exercises the well-typed path.

🤖 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/baml_compiler2_ast/src/lib.rs` around lines 1144 - 1147,
Add a focused test alongside the existing AST parsing tests that parses `class C
{ f }`, retrieves the field through the relevant class/field symbols, and
asserts its `field.type_expr.kind` is `TypeExprKind::Error`. Keep the existing
well-typed assertions unchanged.
🤖 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_compiler2_mir/src/ir.rs`:
- Around line 324-337: Update baml_compiler2_mir::optimize to handle
VirtualFieldStore in every statement traversal: count its receiver/value
operands in count_in_statement, include it in scan_statement and count_defs,
preserve it during dead-assignment removal and assignee finding, and rewrite
both operands through apply_subst_to_statement and rewrite_locals_in_statement.
Keep its field metadata unchanged while applying existing operand
substitution/local-rewrite behavior.

In `@baml_language/crates/baml_compiler2_mir/src/lower.rs`:
- Around line 10277-10365: Update virtual_field_assign_target to resolve and
return the declaring interface view and field index via
interface_view_declaring_field, returning None before lowering the receiver or
value when resolution fails. Adjust try_lower_virtual_field_assign and
try_lower_virtual_field_assign_op to consume that resolved data and pass it to
the interface access/store helpers, preventing side effects before a possible
fall-through.

In `@baml_language/crates/baml_compiler2_mir/src/optimize.rs`:
- Around line 1600-1601: Update verify_mir’s statement match to add an explicit
VirtualFieldStore arm, validating both its receiver and value operands instead
of relying on the wildcard branch. Keep the existing VirtualFieldAccess receiver
validation unchanged.
- Around line 696-701: Update collect_place_index_locals in
baml_language/crates/baml_compiler2_mir/src/optimize.rs:696-701 to scan both
receiver and value for VirtualFieldStore, and update the debug verification
visitor at baml_language/crates/baml_compiler2_mir/src/optimize.rs:1600-1601 to
explicitly verify both operands rather than relying on the wildcard arm.

In `@baml_language/crates/baml_compiler2_tir/src/builder.rs`:
- Around line 12453-12507: Update qualified_interface_field_for_construction so
both lower_type_ref ScopeCtx branches provide the same rigid Self type variable
bounded by the current interface, matching interface_member_lowering_env in
interface_resolution.rs, instead of passing self_ty: None. Add a regression test
covering an interface field typed with Self.Assoc through the
construction-qualification path, verifying it resolves as a type variable or
associated-type projection without cascading recovery errors.

---

Nitpick comments:
In `@baml_language/crates/baml_compiler2_ast/src/lib.rs`:
- Around line 1144-1147: Add a focused test alongside the existing AST parsing
tests that parses `class C { f }`, retrieves the field through the relevant
class/field symbols, and asserts its `field.type_expr.kind` is
`TypeExprKind::Error`. Keep the existing well-typed assertions unchanged.

In `@baml_language/crates/bex_vm/src/vm.rs`:
- Around line 3412-3435: Replace the duplicated interface-operand extraction
logic in the OpCode::VirtualCall and OpCode::MakeVirtualBoundMethod handlers
with calls to pop_interface_operand. Preserve the existing interface name and
argument handling, including the current unreachable behavior for non-interface
types.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 62035413-6cc6-4376-b45f-f72513042102

📥 Commits

Reviewing files that changed from the base of the PR and between fc9cf16 and 4cb4662.

⛔ Files ignored due to path filters (41)
  • baml_language/crates/baml_tests/snapshots/baml_src/array_rest_binding.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/comparable_sort.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/csv.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/defer.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/for_loops.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/interfaces.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/interfaces_associated_types.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/interfaces_class_generics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/iter.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/iter_closure_elements.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/lambdas.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/lexical_scoping.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/null_handling.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/patterns_new_runtime.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/promptast_accessors.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/streaming_parsing.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/string_regressions.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/typed_inputs.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__testing_std__/baml_tests__compiles____testing_std____04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__testing_std__/baml_tests__compiles____testing_std____06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/anyfunction_reflect/baml_tests__compiles__anyfunction_reflect__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/anyfunction_reflect/baml_tests__compiles__anyfunction_reflect__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/backtick_dedent/baml_tests__compiles__backtick_dedent__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/backtick_dedent/baml_tests__compiles__backtick_dedent__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/backtick_strings/baml_tests__compiles__backtick_strings__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/backtick_strings/baml_tests__compiles__backtick_strings__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/closure_loop_variable/baml_tests__compiles__closure_loop_variable__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/closure_loop_variable/baml_tests__compiles__closure_loop_variable__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lexical_scoping/baml_tests__compiles__lexical_scoping__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lexical_scoping/baml_tests__compiles__lexical_scoping__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/testset_dynamic/baml_tests__compiles__testset_dynamic__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/testset_vibes_nested/baml_tests__compiles__testset_vibes_nested__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_textual.snap is excluded by !**/*.snap
📒 Files selected for processing (48)
  • baml_language/crates/baml_builtins2_codegen/src/extract.rs
  • baml_language/crates/baml_cli/src/bytecode_cache.rs
  • baml_language/crates/baml_cli/src/file_signature.rs
  • baml_language/crates/baml_compiler2_ast/src/ast.rs
  • baml_language/crates/baml_compiler2_ast/src/disambiguate.rs
  • baml_language/crates/baml_compiler2_ast/src/lib.rs
  • baml_language/crates/baml_compiler2_ast/src/lower_cst.rs
  • baml_language/crates/baml_compiler2_emit/src/analysis.rs
  • baml_language/crates/baml_compiler2_emit/src/emit.rs
  • baml_language/crates/baml_compiler2_emit/src/lib.rs
  • baml_language/crates/baml_compiler2_emit/src/pull_semantics.rs
  • baml_language/crates/baml_compiler2_emit/src/stack_carry.rs
  • baml_language/crates/baml_compiler2_hir/src/builder.rs
  • baml_language/crates/baml_compiler2_hir/src/item_tree/classes.rs
  • baml_language/crates/baml_compiler2_mir/src/builder.rs
  • baml_language/crates/baml_compiler2_mir/src/ir.rs
  • baml_language/crates/baml_compiler2_mir/src/lower.rs
  • baml_language/crates/baml_compiler2_mir/src/optimize.rs
  • baml_language/crates/baml_compiler2_mir/src/pretty.rs
  • baml_language/crates/baml_compiler2_ppir/src/item_data/classes.rs
  • baml_language/crates/baml_compiler2_ppir/src/item_data/common.rs
  • baml_language/crates/baml_compiler2_ppir/src/item_data/interfaces.rs
  • baml_language/crates/baml_compiler2_ppir/src/lib.rs
  • baml_language/crates/baml_compiler2_tir/src/builder.rs
  • baml_language/crates/baml_compiler2_tir/src/builder/interface_resolution.rs
  • baml_language/crates/baml_compiler2_tir/src/inference.rs
  • baml_language/crates/baml_compiler2_tir/src/interfaces/impl_rules.rs
  • baml_language/crates/baml_compiler2_tir/src/package_interface.rs
  • baml_language/crates/baml_lsp2_actions/src/check.rs
  • baml_language/crates/baml_lsp2_actions/src/definition.rs
  • baml_language/crates/baml_lsp2_actions/src/describe.rs
  • baml_language/crates/baml_lsp2_actions/src/type_info.rs
  • baml_language/crates/baml_project/src/client_codegen.rs
  • baml_language/crates/baml_tests/baml_src/ns_interfaces/interfaces.baml
  • baml_language/crates/baml_tests/src/compiler2_emit/mod.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/mod.rs
  • baml_language/crates/baml_type/src/template.rs
  • baml_language/crates/bex_vm/src/debug.rs
  • baml_language/crates/bex_vm/src/package_load.rs
  • baml_language/crates/bex_vm/src/vm.rs
  • baml_language/crates/bex_vm_types/src/bytecode.rs
  • baml_language/crates/bex_vm_types/src/errors.rs
  • baml_language/crates/bex_vm_types/src/link.rs
  • baml_language/crates/bex_vm_types/src/relink.rs
  • baml_language/crates/bex_vm_types/src/types/interface.rs
  • baml_language/crates/bex_vm_types/src/types/package.rs
  • baml_language/crates/bex_vm_types/src/unit.rs
  • baml_language/tools/speedtest/workloads/interfaces/field-access-100k.md

- Fix missing `match` arms and make exhaustive
- Fix emit ordering to avoid producing incomplete MIR if lowering fails
@2kai2kai2
2kai2kai2 enabled auto-merge July 29, 2026 23:57
@vercel
vercel Bot temporarily deployed to Preview – beps July 29, 2026 23:58 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 30, 2026 00:06 Inactive
@2kai2kai2
2kai2kai2 added this pull request to the merge queue Jul 30, 2026
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 30, 2026 00:19 Inactive
Merged via the queue into canary with commit 69f2cf0 Jul 30, 2026
82 checks passed
@2kai2kai2
2kai2kai2 deleted the kai/virtual-fields branch July 30, 2026 00:20

This branch was previously deployed

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