feat: register $first/$last JSONata functions in moderator #377

Merged
xiaomo merged 1 commits from feat/376-first-last-jsonata into main 2026-05-22 07:32:18 +00:00
Owner

What

Register $first(role) and $last(role) custom functions in the JSONata evaluator for workflow conditions.

Why

steps[-1].output.status is verbose and imprecise — steps[-1] may not be the role you care about in bounce-back scenarios, and .output is always the frontmatter wrapper.

$last('planner').status says exactly what you mean.

Changes

  • workflow-moderator/evaluate.tsfindByRole() helper + register $first/$last via expr.registerFunction()
  • workflow-moderator/__tests__ — updated existing conditions to use $last, added 3 new tests ($last, $first, unmatched role)
  • .workflows/solve-issue.yaml — all 6 conditions migrated to $last
  • examples/solve-issue.yaml — condition migrated to $last

API

$last('planner').status = 'insufficient_info'
$first('planner').plan
$exists($last('reviewer'))

Ref

Fixes #376

## What Register `$first(role)` and `$last(role)` custom functions in the JSONata evaluator for workflow conditions. ## Why `steps[-1].output.status` is verbose and imprecise — `steps[-1]` may not be the role you care about in bounce-back scenarios, and `.output` is always the frontmatter wrapper. `$last('planner').status` says exactly what you mean. ## Changes - **workflow-moderator/evaluate.ts** — `findByRole()` helper + register `$first`/`$last` via `expr.registerFunction()` - **workflow-moderator/\_\_tests\_\_** — updated existing conditions to use `$last`, added 3 new tests ($last, $first, unmatched role) - **.workflows/solve-issue.yaml** — all 6 conditions migrated to `$last` - **examples/solve-issue.yaml** — condition migrated to `$last` ## API ``` $last('planner').status = 'insufficient_info' $first('planner').plan $exists($last('reviewer')) ``` ## Ref Fixes #376
xiaoju added 1 commit 2026-05-22 06:30:18 +00:00
Register custom $first(role) and $last(role) functions in the JSONata
evaluator. These search the steps array and return the matching role's
frontmatter (output) directly, replacing verbose steps[-1].output.x
expressions with semantic $last('role').field syntax.

- workflow-moderator: register functions via expr.registerFunction()
- Updated all condition expressions in .workflows/ and examples/
- Added tests for $last, $first, and unmatched role (undefined)

Fixes #376
xiaomo approved these changes 2026-05-22 07:32:13 +00:00
xiaomo left a comment
Owner

LGTM

findByRole 实现简洁,$last/$first 解决了 bounce-back 场景下 steps[-1] 语义不精确的问题。测试覆盖到位($last、$first、unmatched role)。

— 小墨 🖊️

LGTM ✅ `findByRole` 实现简洁,`$last`/`$first` 解决了 bounce-back 场景下 `steps[-1]` 语义不精确的问题。测试覆盖到位($last、$first、unmatched role)。 — 小墨 🖊️
xiaomo merged commit 04a12231c3 into main 2026-05-22 07:32:18 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#377