Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/accumulator-output-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remoraflow/core": patch
---

The validator now types a `for-each` or `while` accumulator from its loop body's output, so an accumulator that builds the wrong shape is reported as an error. It warns separately when the initial value, which the loop outputs if the body never runs, does not match the body's output. Type inference also flattens lists of arrays correctly, types empty literal arrays as arrays with no items, checks each member of a union and each tuple item against the target schema, and treats different JSON Schema types as disjoint. The `for-each` and `while` step descriptions now explain how to collect outputs without an accumulator and how to append to an array accumulator.
5 changes: 5 additions & 0 deletions .changeset/faster-workflow-definition-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remoraflow/core": patch
---

The workflow definition schema is about twice as fast to build, because the union of step types is now built in one call instead of a chain of `.or()` and `.exclude()` calls.
5 changes: 5 additions & 0 deletions .changeset/switch-case-forwards-branch-output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remoraflow/core": minor
---

A `switch-case` step's output is now the value returned by its selected branch, instead of `null`. The validator types it as the union of the branch outputs. Field access on a union type no longer warns when every member of the union has the field.
6 changes: 6 additions & 0 deletions .changeset/validate-jmespath-function-names.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@remoraflow/core": patch
"@remoraflow/ui": patch
---

The validator now reports calls to JMESPath functions that do not exist, such as `append()`, instead of letting them fail at runtime. The list of JMESPath functions is exported as `JMESPATH_FUNCTION_NAMES`, and the UI's syntax highlighting uses it.
5 changes: 5 additions & 0 deletions .changeset/workflow-editor-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remoraflow/core": minor
---

Workflow generation now edits a draft workflow in place instead of resubmitting the full definition on every attempt. The agent uses `write-workflow`, `read-workflow` (JMESPath), `edit-workflow` (JSON Patch), and `submit-workflow`. Write and edit return validation diagnostics without failing the tool call, edits also return the changed workflow, and both accept `submitIfValid` to submit a workflow that has no errors or warnings without a separate call. An edit that uses `replace` on a field that does not exist adds the field. When a required output schema is given and the workflow declares no `outputSchema`, the required schema is used. Tool calls whose top-level object or array arguments were sent as JSON strings are repaired. The generation instructions are marked as an Anthropic prompt-cache breakpoint. `step-end` diagnostic events now include each step's tool calls, with the input and error of failed calls.
255 changes: 232 additions & 23 deletions bun.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"arktype": "^2.1.29",
"capture-console": "^1.0.2",
"dedent": "^1.7.2",
"fast-json-patch": "^3.1.1",
"jmespath": "^0.16.0",
"tokenx": "^1.3.0",
"zod": "^4.4.3"
Expand All @@ -61,8 +62,10 @@
}
},
"devDependencies": {
"@ai-sdk/openai": "^4.0.43",
"@ai-sdk/amazon-bedrock": "5.0.58",
"@ai-sdk/openai-compatible": "3.0.31",
"@ai-sdk/provider-utils": "5.0.27",
"@aws-sdk/credential-providers": "^3.1139.0",
"@aws/durable-execution-sdk-js": "^1.1.0",
"@aws/durable-execution-sdk-js-testing": "^1.1.1",
"@temporalio/client": "^1.23.0",
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/execution/step-executors/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,15 @@ describe("step executors", () => {
expect(result.scope?.fallback).toBe("D");
});

test("outputs the selected branch's return value", async () => {
const result = await runStep(
switchStep,
{ x: "a" },
{ workflowDefinition: workflow(switchStep, matched, fallback) },
);
expect(result.scope?.sc).toBe("A");
});

test("errors with UNRECOGNIZED_CASE when nothing matches", async () => {
const noDefault = step("sc", {
type: "switch-case",
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/execution/step-executors/switch-case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ export const switchCaseExecutor: StepExecutor<"switch-case"> = {
}
const branchScope = lastUpdate?.scope ?? scope;
yield {
scope: { ...scope, ...branchScope },
scope: {
...scope,
...branchScope,
[step.id]: lastUpdate?.output ?? null,
},
output: null,
error: null,
...(step.nextStepId
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/execution/step-output-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,13 @@ const CONTRACT_CASES: Record<WorkflowStep["type"], ContractCase> = {
],
},
}),
step("body", { type: "start" }),
step("body", {
type: "end",
params: { output: { type: "literal", value: "picked" } },
}),
],
// `switch-case` merges the branch scope but binds nothing under its own id.
expectedOutput: undefined,
conformance: "verified",
expectedOutput: "picked",
conformance: "unconstrained",
},
"wait-for-condition": {
steps: [
Expand Down
Loading
Loading