From 070afc19a29da1e6f3911df3863f6144e5e123cb Mon Sep 17 00:00:00 2001 From: Kostandin Angjellari Date: Thu, 15 Oct 2026 15:07:50 +0200 Subject: [PATCH 01/12] Add a flow scenario runner that starts runs by definition id Moves the local runner into apps/hash-ai-worker-ts/scripts/flow-scenarios with the Array actions scenario. It writes the scenario's definition as a Flow Definition entity in the user's web, then starts the run by its id like the startFlow resolver. Co-authored-by: Amp --- apps/hash-ai-worker-ts/.gitignore | 1 + apps/hash-ai-worker-ts/package.json | 1 + .../scripts/flow-scenarios/README.md | 50 ++ .../flow-scenarios/run-flow-scenario.ts | 666 ++++++++++++++++++ .../scripts/flow-scenarios/scenario.ts | 36 + .../scenarios/array-actions.scenario.ts | 155 ++++ 6 files changed, 909 insertions(+) create mode 100644 apps/hash-ai-worker-ts/scripts/flow-scenarios/README.md create mode 100644 apps/hash-ai-worker-ts/scripts/flow-scenarios/run-flow-scenario.ts create mode 100644 apps/hash-ai-worker-ts/scripts/flow-scenarios/scenario.ts create mode 100644 apps/hash-ai-worker-ts/scripts/flow-scenarios/scenarios/array-actions.scenario.ts diff --git a/apps/hash-ai-worker-ts/.gitignore b/apps/hash-ai-worker-ts/.gitignore index cab0ae42058..3d71ec97a91 100644 --- a/apps/hash-ai-worker-ts/.gitignore +++ b/apps/hash-ai-worker-ts/.gitignore @@ -1 +1,2 @@ scripts/sanitized-html +scripts/flow-scenarios/runs diff --git a/apps/hash-ai-worker-ts/package.json b/apps/hash-ai-worker-ts/package.json index f681ff2e91d..ca83ac1d4a8 100644 --- a/apps/hash-ai-worker-ts/package.json +++ b/apps/hash-ai-worker-ts/package.json @@ -33,6 +33,7 @@ "generate:chart-config-schema": "yarn exe ./scripts/generate-chart-config-schema.ts", "lint:eslint": "eslint --report-unused-disable-directives .", "lint:tsc": "tsc --noEmit", + "run-flow-scenario": "NODE_ENV=development yarn exe ./scripts/flow-scenarios/run-flow-scenario.ts", "sanitize-html": "NODE_ENV=development yarn exe ./scripts/sanitize-html.ts", "sentry:sourcemaps": "sentry-cli sourcemaps inject --org hashintel --project hash-temporal-worker-ai ./dist && sentry-cli sourcemaps upload --org hashintel --project hash-temporal-worker-ai ./dist", "start": "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=2048 node ./dist/main.js", diff --git a/apps/hash-ai-worker-ts/scripts/flow-scenarios/README.md b/apps/hash-ai-worker-ts/scripts/flow-scenarios/README.md new file mode 100644 index 00000000000..1cef7473f86 --- /dev/null +++ b/apps/hash-ai-worker-ts/scripts/flow-scenarios/README.md @@ -0,0 +1,50 @@ +# Flow scenarios + +A scenario is a flow definition, its inputs and the outputs you expect. `run-flow-scenario` runs it end to end +through Temporal on the local stack, the way the `startFlow` resolver starts a run, checks every expectation and +prints a report you can paste into a PR. + +## Start the stack + +```bash +yarn compose --profile hgres up -d # infrastructure and the graph, in Docker +yarn dev:backend # once, to run migrations and seed the alice and bob01 users +yarn workspace @apps/hash-ai-worker-ts dev # the worker for the `ai` task queue +yarn workspace @apps/hash-integration-worker dev # the worker for the `integration` task queue, if the flow needs it +``` + +The workers import `@local/hash-isomorphic-utils` and `@local/hash-backend-utils` from their builds, so rebuild a +library after changing it (`yarn workspace @local/hash-isomorphic-utils build`). The runner warns when a build is +older than its source, and stops if the worker polling the task queue runs from another checkout. + +## Write a scenario + +Copy [`scenarios/array-actions.scenario.ts`](scenarios/array-actions.scenario.ts) and edit it. A scenario exports +`scenario = defineScenario({ ... })` with: + +- `flow`: built with `defineFlow` from `@local/hash-isomorphic-utils/flows/define-flow`. Give it a + `flowDefinitionId` of its own: the runner stores the definition as a `Flow Definition` entity with that uuid in + the user's web, and updates it when the definition changes, because runs load their definition from the graph. +- `inputs`: a `{ kind, value }` payload for each flow input. +- `expect`: + - `status`: the run's status, `COMPLETED` by default. + - `outputs`: the flow's output values by name, without the `{ kind, value }` wrapper. + - `steps`: by step id, the step's `status` (`COMPLETED`, `FAILED`, `SKIPPED`…), its `outputs`, and + `absentOutputs` it must not produce, such as the branch an If didn't take. +- `user`: the shortname to run as, in their own web. `alice` by default. + +Work out the expected values by hand before running, rather than copying them from a run. Values are compared +exactly. + +## Run it + +```bash +yarn workspace @apps/hash-ai-worker-ts run-flow-scenario scripts/flow-scenarios/scenarios/array-actions.scenario.ts +``` + +The scenario path is relative to `apps/hash-ai-worker-ts`. `--dry-run` only validates the definition, without the +stack. `--timeout ` (300 by default) reports the steps so far if the run hasn't finished by then. + +The report is printed and saved to `runs/