Skip to content

feat: introduce Null and Any types#73

Merged
nikku merged 16 commits intomainfrom
cover-null-variable-type
Feb 26, 2026
Merged

feat: introduce Null and Any types#73
nikku merged 16 commits intomainfrom
cover-null-variable-type

Conversation

@barinali
Copy link
Contributor

@barinali barinali commented Feb 18, 2026

Proposed Changes

This pull request aims to introduce types for various scenarios;

  • Variable defined with no values as Null
  • Variable defined with null literal value as Null
  • Unresolved variables as Any
  • Various bugs fixed

Screenshots

With changes in this PR, we can display variables as can be seen in the screenshot:

image

Try it out

Try out via Camunda Modeler variable-int-up branch.

Checklist

Ensure you provide everything we need to review your contribution:

  • Contribution meets our definition of done
  • Pull request establishes context
    • Link to related issue(s), i.e. Closes {LINK_TO_ISSUE} or Related to {LINK_TO_ISSUE}
    • Brief textual description of the changes
    • Screenshots or short videos showing UI/UX changes
    • Steps to try out, i.e. using the @bpmn-io/sr tool

Pulled #77 out of the scope of this PR.

@bpmn-io-tasks bpmn-io-tasks bot added the in progress Currently worked on label Feb 18, 2026
nikku

This comment was marked as outdated.

@nikku

This comment was marked as outdated.

@barinali

This comment was marked as outdated.

@nikku

This comment was marked as outdated.

@nikku

This comment was marked as outdated.

@nikku nikku force-pushed the cover-null-variable-type branch from 7151eb2 to 47cb19d Compare February 18, 2026 13:13
@nikku

This comment was marked as outdated.

@nikku

This comment was marked as outdated.

@nikku

This comment was marked as outdated.

@barinali barinali marked this pull request as ready for review February 19, 2026 00:17
Copilot AI review requested due to automatic review settings February 19, 2026 00:17
@bpmn-io-tasks bpmn-io-tasks bot added needs review Review pending and removed in progress Currently worked on labels Feb 19, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces explicit variable typing for null / empty mappings (Null) and unknown/unresolved values (Any) in the Zeebe variable resolution pipeline, with accompanying fixtures and tests to validate type inference and propagation.

Changes:

  • Extend FEEL-based type inference to return Null for null and Any for unknown/unresolved values, including union-type merging across multiple origins.
  • Add/adjust tests and BPMN fixtures to cover literal outputs, path resolution, passthrough, unresolved variables, and mapping/merging behavior.
  • Refactor test assertion helpers to support both exact equality (variableEqual) and subset assertions (variableInclude).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
lib/zeebe/util/feelUtility.js Implements Null/Any typing, unresolved-path handling, and union-type merging/backfilling during reference resolution.
lib/base/VariableResolver.js Updates type/info list merging logic for merged variables.
test/globals.js Refactors chai assertions and adds variableInclude.
test/spec/zeebe/ZeebeVariableResolver.spec.js Updates agentic fixture expectations and adds type-resolution coverage.
test/spec/zeebe/Mappings.spec.js Updates expectations for Null/Any and adds new merge/mapping propagation tests.
test/fixtures/zeebe/type-resolution.bpmn New fixture covering literal, path, passthrough, and unresolved type resolution.
test/fixtures/zeebe/mappings/merging.bpmn Extends merging fixture to cover Null/Any propagation scenarios.
test/fixtures/zeebe/ad-hoc-sub-process.agentic.bpmn Updates agentic fixture (provider config + additional tool tasks), impacting variable origins/types.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 268 to 270
if (mapping.source.startsWith('=')) {
return mapping.source.substring(1);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@barinali cf my change https://github.com/bpmn-io/variable-resolver/pull/74/changes#diff-36d9bcfb588ee3a00382ee039fdd5b6fcf85f9ef67e7230a547281444a1be0b9R260

@Buckwich I have updated this piece in a way it returns with the FEEL expression actually so that in the user interface I can display the unresolved FEEL expression as in the screenshot.

Check out data.userPrompt.prompt as reference in the screenshot;

Image

Copy link
Member

Choose a reason for hiding this comment

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

Out of scope for this PR, cf. #77

@barinali barinali requested a review from barmac February 19, 2026 14:56
@barinali barinali changed the title feat: introduce Null type for null variables feat: introduce Null and Any types with value resolution Feb 19, 2026
@barinali barinali requested a review from nikku February 19, 2026 15:02
@nikku nikku changed the base branch from input-output to main February 19, 2026 19:32
@nikku

This comment was marked as outdated.

@Buckwich
Copy link
Member

parse with camunda dialect

if we do parse with camunda dialect do we also need to support protectedNameBuiltins? or why do we need to parse with the dialect.

In general i would prever this lib to not do any parsing and move those parts over to feel-analyzer

Null and Any types and how we designed them

im not really a fan of Unresolved variables as Any

and we should come up with a common way to detect feel expressions. i think most open PRs do it slightly different (eg #83 (comment))

@nikku
Copy link
Member

nikku commented Feb 26, 2026

if we do parse with camunda dialect do we also need to support protectedNameBuiltins? or why do we need to parse with the dialect.

We need it to parse multi-line strings, cf. 1bf7ad3.

if we do parse with camunda dialect do we also need to support protectedNameBuiltins?

Yes, we'd need that, but it can also be a bug we're aware of, today, until we 🔽

In general i would prever this lib to not do any parsing and move those parts over to feel-analyzer

Yes. We're not there yet, though.

Base automatically changed from static-values to main February 26, 2026 14:09
@barinali
Copy link
Contributor Author

@barinali @Buckwich I need a 👍 on this PR from your end, and a confirmation that what we have inside is what we want to ship (as part of our API) to power our future experience:

  • ✔️ hierarchical resolution
  • ✔️ partial resolution toolCallResult.email
  • ✔️ input without source
  • Null and Any types and how we designed them
  • ❓ (correctly) joining types
  • ✔️ alphabetic sorting - does not hurt
  • ✔️ parse with camunda dialect

Compared to the initial intention of this pull request, what we want to ship has been changed in a reducing manner. So, we currently need (compared to what we already have in the main branch);

  • hierarchical resolution (presuming this means context variable values being resolved, like data and provider variables in AI Agent ad-hoc sub process.
  • partial resolution toolCallResult.email
  • Null type or properly returning null for a variable with a value of literal null. Besides this, we do not need to introduce Any/Unknown type right now as the variable-outline would not benefit from it for the time being.

In the current main branch, what we can visualize is as below;

image

We'd like to show these variables as follows with a single exception of agent variable. Instead of showing - for agent, we would like to show its FEEL expression as =agent.

image image

@nikku
Copy link
Member

nikku commented Feb 26, 2026

Thanks both!

@nikku nikku force-pushed the cover-null-variable-type branch from 2eb6bd4 to a5fd87a Compare February 26, 2026 20:58
@nikku
Copy link
Member

nikku commented Feb 26, 2026

We'd like to show these variables as follows with a single exception of agent variable. Instead of showing - for agent, we would like to #77 as =agent.We'd like to show these variables as follows with a single exception of agent variable. Instead of showing - for agent, we would like to #77 as =agent.

@barinali for this we need the Any type, distinguishing unknown from Null

@nikku nikku force-pushed the cover-null-variable-type branch 2 times, most recently from 3f90a03 to f53631c Compare February 26, 2026 21:19
@nikku nikku changed the title feat: introduce Null and Any types with value resolution feat: introduce Null and Any types Feb 26, 2026
@nikku nikku self-assigned this Feb 26, 2026
@nikku nikku merged commit 57fb204 into main Feb 26, 2026
3 checks passed
@bpmn-io-tasks bpmn-io-tasks bot removed the needs review Review pending label Feb 26, 2026
@nikku nikku deleted the cover-null-variable-type branch February 26, 2026 21:21
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.

4 participants