@fluidgrids/workflows 0.0.0-stage → 2026.1027.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +208 -2
- package/dist/assemble-CrpUyd_3.d.ts +587 -0
- package/dist/assemble-DEf3znGD.d.cts +587 -0
- package/dist/chunk-3M34AUIY.cjs +27 -0
- package/dist/chunk-5AW745OG.js +25 -0
- package/dist/chunk-5LUIDMF4.js +42 -0
- package/dist/chunk-6AIAC2FP.cjs +185 -0
- package/dist/chunk-6BEW4QD6.js +95 -0
- package/dist/chunk-6U446SKY.js +263 -0
- package/dist/chunk-7YR7DI7B.cjs +274 -0
- package/dist/chunk-CSYBNN3V.cjs +252 -0
- package/dist/chunk-E3APHA6O.cjs +199 -0
- package/dist/chunk-EEAIM35V.js +748 -0
- package/dist/chunk-G4UEPUGO.cjs +46 -0
- package/dist/chunk-IHKXLG6I.js +246 -0
- package/dist/chunk-MBBKGD7K.js +440 -0
- package/dist/chunk-OSPTJCDI.cjs +102 -0
- package/dist/chunk-TQF7MYEN.cjs +771 -0
- package/dist/chunk-TWOYB4Y7.cjs +76 -0
- package/dist/chunk-UB2BHU2M.js +174 -0
- package/dist/chunk-UJNHTS6D.js +181 -0
- package/dist/chunk-UWQWD7BP.cjs +931 -0
- package/dist/chunk-W32BSO3M.js +74 -0
- package/dist/chunk-XBIID5DY.js +893 -0
- package/dist/chunk-Y7NWR3WH.cjs +450 -0
- package/dist/codegen/index.cjs +18 -0
- package/dist/codegen/index.d.cts +15 -0
- package/dist/codegen/index.d.ts +15 -0
- package/dist/codegen/index.js +5 -0
- package/dist/expressions-DhHaqyar.d.cts +62 -0
- package/dist/expressions-DhHaqyar.d.ts +62 -0
- package/dist/hash-CZkTXPCX.d.cts +15 -0
- package/dist/hash-CZkTXPCX.d.ts +15 -0
- package/dist/index.cjs +117 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +4 -0
- package/dist/ir/index.cjs +1246 -0
- package/dist/ir/index.d.cts +838 -0
- package/dist/ir/index.d.ts +838 -0
- package/dist/ir/index.js +1122 -0
- package/dist/lower-CXggJTIo.d.ts +67 -0
- package/dist/lower-DAzvsJCo.d.cts +67 -0
- package/dist/manifest-Bp9ZJlav.d.ts +60 -0
- package/dist/manifest-Duf-gHdO.d.cts +60 -0
- package/dist/node-evaluator-CH3XCJND.cjs +17 -0
- package/dist/node-evaluator-TULXA3WE.js +8 -0
- package/dist/quickjs/index.cjs +46 -0
- package/dist/quickjs/index.d.cts +18 -0
- package/dist/quickjs/index.d.ts +18 -0
- package/dist/quickjs/index.js +44 -0
- package/dist/roundtrip/index.cjs +1448 -0
- package/dist/roundtrip/index.d.cts +290 -0
- package/dist/roundtrip/index.d.ts +290 -0
- package/dist/roundtrip/index.js +1397 -0
- package/dist/types-Dr2Fn1Ax.d.cts +225 -0
- package/dist/types-Dr2Fn1Ax.d.ts +225 -0
- package/package.json +143 -4
- package/schema/ir-v2.schema.json +655 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Copyright (c) 2025 Algoshred Technologies Private Limited.
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software is proprietary and confidential. Unauthorized copying, modification, distribution, or use of this software, via any medium, is strictly prohibited without the express written permission of the copyright holders.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
8
|
+
|
|
9
|
+
For licensing inquiries, please contact: legal@algoshred.com
|
package/README.md
CHANGED
|
@@ -1,3 +1,209 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @fluidgrids/workflows
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Author [FluidGrids](https://fluidgrids.ai) workflows as code. This package is
|
|
4
|
+
Phase A of the code-first workflows spec set (BOFF-9902 / BOFF-9904,
|
|
5
|
+
`fluidgrids-specs/product/specs/code-first/`):
|
|
6
|
+
|
|
7
|
+
- the workflow IR, schema version 2: types, JSON Schema 2020-12, normalisation,
|
|
8
|
+
validation, hashing, diff, interface derivation and the export envelope;
|
|
9
|
+
- the tier-1 graph builder: TypeScript that constructs a canvas workflow;
|
|
10
|
+
- lift (IR to TypeScript or Python) and lower (TypeScript to IR), with a
|
|
11
|
+
fidelity report computed by actually lowering the code;
|
|
12
|
+
- typed node clients generated from a node registry snapshot.
|
|
13
|
+
|
|
14
|
+
Durable (tier-2) workflow functions are Phase B and are not in this package yet.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun add @fluidgrids/workflows
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Entry points
|
|
23
|
+
|
|
24
|
+
| Import | Contents | Runs in |
|
|
25
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
|
26
|
+
| `@fluidgrids/workflows` | `defineWorkflow`, `triggers`, `nodes`, `edge`, `expr`, `and`, `or`, `op`, `trigger`, `toIR` | anywhere; also bundled into workflow code |
|
|
27
|
+
| `@fluidgrids/workflows/ir` | IR v2 types, `IR_V2_SCHEMA`, `normalizeDefinition`, `validate`, `irHash`, `canonicalJson`, `diffDefinitions`, `deriveInterface`, envelope helpers | anywhere, browser included |
|
|
28
|
+
| `@fluidgrids/workflows/roundtrip` | `liftToTypeScript`, `liftToPython`, `lower`, `exportWorkflowCode`, `checkFidelity` | Node or Bun |
|
|
29
|
+
| `@fluidgrids/workflows/codegen` | `generateNodeClients(manifests, 'ts' \| 'py')` | anywhere |
|
|
30
|
+
| `@fluidgrids/workflows/quickjs` | `createQuickJSEvaluator()` for lowering untrusted code | Node or Bun |
|
|
31
|
+
| `@fluidgrids/workflows/schema/ir-v2.schema.json` | the JSON Schema | data |
|
|
32
|
+
|
|
33
|
+
## Tier 1: the graph builder
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { defineWorkflow, expr, triggers } from '@fluidgrids/workflows';
|
|
37
|
+
import { nodes as n } from '../.fluidgrids/nodes';
|
|
38
|
+
|
|
39
|
+
export const leadEnrichment = defineWorkflow(
|
|
40
|
+
{ key: 'lead-enrichment', name: 'Lead enrichment' },
|
|
41
|
+
(wf) => {
|
|
42
|
+
const inbound = wf.trigger(triggers.webhook, { id: 'inbound', args: { path: 'leads' } });
|
|
43
|
+
const enrich = wf.http({
|
|
44
|
+
id: 'enrich',
|
|
45
|
+
after: inbound,
|
|
46
|
+
connection: 'enrichment-api',
|
|
47
|
+
args: {
|
|
48
|
+
method: 'GET',
|
|
49
|
+
url: 'https://person.clearbit.com/v2/combined/find',
|
|
50
|
+
queryParams: { email: wf.json.body.email },
|
|
51
|
+
},
|
|
52
|
+
retry: { maxRetries: 3, retryDelay: 2000 },
|
|
53
|
+
});
|
|
54
|
+
const isEnterprise = wf.if({
|
|
55
|
+
id: 'is-enterprise',
|
|
56
|
+
after: enrich,
|
|
57
|
+
condition: enrich.output.body.company.metrics.employees.gte(500),
|
|
58
|
+
});
|
|
59
|
+
wf.step(n.slack.sendMessage, {
|
|
60
|
+
id: 'notify-sales',
|
|
61
|
+
after: isEnterprise.true,
|
|
62
|
+
connection: 'slack-ops',
|
|
63
|
+
args: {
|
|
64
|
+
channelId: 'C0SALES',
|
|
65
|
+
text: expr`New enterprise lead: ${enrich.output.body.person.name.fullName}`,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The callback runs once and records a graph; `toIR(workflow, { connections, layout })`
|
|
73
|
+
turns the recording into IR v2. Lowering is a pure function of the builder
|
|
74
|
+
calls, so the same source always gives the same IR.
|
|
75
|
+
|
|
76
|
+
- Every node needs an `id` (`defineWorkflow({ autoIds: true })` derives them for quick scripts).
|
|
77
|
+
- References lower to the expression language the workers evaluate:
|
|
78
|
+
`enrich.output.a.b` becomes `{{ $node["enrich"].item.a.b }}`, `wf.json.x`
|
|
79
|
+
becomes `{{ $json.x }}`. Comparisons (`gte`, `eq`, `contains`, `isEmpty`, …,
|
|
80
|
+
`and`, `or`) become the condition tree `internal:if` evaluates.
|
|
81
|
+
- `connection: 'name'` resolves to a connection id when the workflow is pushed.
|
|
82
|
+
- Lowering must not read the clock or a random source while the workflow is
|
|
83
|
+
defined: `Date.now()`, `new Date()` / `Date()` without arguments,
|
|
84
|
+
`Math.random()`, `crypto.getRandomValues()` / `crypto.randomUUID()` and an
|
|
85
|
+
argument-less `Intl.DateTimeFormat` `format()` throw a `DeterminismViolation`
|
|
86
|
+
error in both evaluators. Use `wf.now` and other references for run-time values.
|
|
87
|
+
- Positions come from the layout sidecar `workflows/<key>.layout.json`, or the
|
|
88
|
+
automatic layout the AI draft generator uses.
|
|
89
|
+
- An edge without an explicit `id` gets `e-<source>-<target>[-<sourceHandle>][-<targetHandle>]`.
|
|
90
|
+
Ids may contain `-`, so two edges can share that default; the later ones get
|
|
91
|
+
`-2`, `-3`, … in declaration order. Only a repeated explicit id is an error.
|
|
92
|
+
- `edge(source, { id, type, targetHandle, label, mapping, extra })`,
|
|
93
|
+
`wf.connect`, `wf.edgeOrderIs` and the `extra` option on every node keep any
|
|
94
|
+
stored definition expressible exactly.
|
|
95
|
+
- References into unknown shapes use index signatures, so a project
|
|
96
|
+
`tsconfig.json` should leave `noPropertyAccessFromIndexSignature` and
|
|
97
|
+
`noUncheckedIndexedAccess` off. Declared fields of generated clients are typed
|
|
98
|
+
either way.
|
|
99
|
+
|
|
100
|
+
## Lift, lower and fidelity
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { exportWorkflowCode, lower } from '@fluidgrids/workflows/roundtrip';
|
|
104
|
+
|
|
105
|
+
const exported = await exportWorkflowCode(definition, {
|
|
106
|
+
format: 'TYPESCRIPT', // or 'PYTHON'
|
|
107
|
+
registry, // node manifests, for typed clients
|
|
108
|
+
connectionNames, // connectionId -> name
|
|
109
|
+
});
|
|
110
|
+
exported.files; // workflows/<key>.ts|.py, the layout sidecar, .fluidgrids/nodes.*
|
|
111
|
+
exported.fidelity.level; // 'lossless' when lowering the code reproduces the IR
|
|
112
|
+
|
|
113
|
+
const { buildId, workflows } = await lower(files, { connections });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
- **Lift** normalises the definition, plans builder calls, runs the plan through
|
|
117
|
+
the builder to prove each node and edge lowers back unchanged (falling back to
|
|
118
|
+
an exact `nodes.custom()` + `extra` form where the readable form would not),
|
|
119
|
+
and prints TypeScript with the pinned Prettier or Python that `ruff format`
|
|
120
|
+
leaves unchanged.
|
|
121
|
+
- **Lower** bundles the project with esbuild 0.28.2 (`format: esm`,
|
|
122
|
+
`platform: neutral`, `target: es2023`) from an in-memory file map, serves
|
|
123
|
+
`@fluidgrids/workflows` from the runtime embedded in this package, and
|
|
124
|
+
evaluates the bundle in an isolate. `buildId` is the SHA-256 of the bundle; it
|
|
125
|
+
is identical with `esbuild` and `esbuild-wasm` of the same version, so the CLI
|
|
126
|
+
and the service agree. Workflow code may import project files and
|
|
127
|
+
`@fluidgrids/workflows` only. The sources are limited to `maxSourceBytes`
|
|
128
|
+
(default 1 MiB) before esbuild runs and the bundle to `maxBundleBytes`
|
|
129
|
+
(default 1.5 MiB) before it is evaluated; a `LowerError` with
|
|
130
|
+
`reason: 'too-large'` reports either.
|
|
131
|
+
- **Evaluators**: the default is a fresh Node `vm` context (for the CLI, which
|
|
132
|
+
runs the developer's own code). Services use `createQuickJSEvaluator()` from
|
|
133
|
+
`@fluidgrids/workflows/quickjs` (quickjs-emscripten 0.32.0, the engine the
|
|
134
|
+
workers use), which bounds memory exactly. Both evaluate in a worker thread
|
|
135
|
+
that is terminated at `timeoutMs`, so the budget covers parsing and compiling
|
|
136
|
+
the bundle, promise jobs and anything the code leaves behind, and the calling
|
|
137
|
+
process never runs or inspects a value from the isolate. Failures are
|
|
138
|
+
`LowerError`s with a `reason` (`timeout`, `determinism`, `out-of-memory`, …).
|
|
139
|
+
- **Fidelity** is `lossless` when `irHash(lower(lift(ir))) == irHash(ir)`. Items
|
|
140
|
+
report what is kept as plain strings or exact forms: `expression-verbatim`,
|
|
141
|
+
`legacy-syntax`, `unknown-node`, `connection-id-only`, `connection-ambiguous`
|
|
142
|
+
(a connection name that more than one connection id has, so the id is kept),
|
|
143
|
+
`raw-node`, `key-added`;
|
|
144
|
+
`layout-omitted`, `pinned-data-omitted`, `roundtrip-mismatch` and
|
|
145
|
+
`lowering-failed` make an export lossy.
|
|
146
|
+
|
|
147
|
+
## The IR
|
|
148
|
+
|
|
149
|
+
- `normalizeDefinition` rewrites the builder's legacy mirrors (`data.*`,
|
|
150
|
+
`config` on internal nodes) into the canonical node fields following the
|
|
151
|
+
executor's own reading order, so no executor-visible value changes
|
|
152
|
+
(`executorView` computes what the executor reads, for checking). It is pure
|
|
153
|
+
and idempotent. It keeps the mirrors some executor path reads from the data
|
|
154
|
+
bag only: `data.executionSettings.runOn`, `data.operation_name` (the agent tool
|
|
155
|
+
binding) and an external node's `data.version` (node-state rows). It does not
|
|
156
|
+
promote an external node's `data.state`, which the sub-node paths do not read;
|
|
157
|
+
`validate --strict` reports it. Keys named `__proto__` are ordinary keys
|
|
158
|
+
everywhere (copies, hashes, lift and lower).
|
|
159
|
+
- `irHash` is `sha256:` + the SHA-256 of the RFC 8785 canonical JSON of the
|
|
160
|
+
normalised definition without `authoring`.
|
|
161
|
+
- `validate(definition, { strict, isTaskQueueKnown })` applies the service's
|
|
162
|
+
structural rules and the version-2 rules of spec 01 §9. A stored version-1
|
|
163
|
+
definition that the service accepts never fails it; `strict` adds the
|
|
164
|
+
legacy-mirror, `${…}` and slug-id rules.
|
|
165
|
+
- `buildExportDocument` and `serializeWorkflowDocument` reproduce today's
|
|
166
|
+
export envelope byte for byte for definitions without version-2 fields
|
|
167
|
+
(envelope `schemaVersion: 1`, definition untouched); only definitions that use
|
|
168
|
+
version-2 fields export as `schemaVersion: 2`, normalised.
|
|
169
|
+
|
|
170
|
+
## Node clients
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { generateNodeClients } from '@fluidgrids/workflows/codegen';
|
|
174
|
+
|
|
175
|
+
const { path, content, registrySnapshot } = await generateNodeClients(manifests, 'ts'); // .fluidgrids/nodes.ts
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
One property per node type, one descriptor per operation, typed from the
|
|
179
|
+
manifest's `input_fields` / `output_fields`; trigger operations also appear
|
|
180
|
+
under `triggers`. Internal nodes ship in the package as `nodes.internal.*` and
|
|
181
|
+
`triggers.*`.
|
|
182
|
+
|
|
183
|
+
## Shared fixtures
|
|
184
|
+
|
|
185
|
+
`fixtures/` holds the conformance fixtures shared with the Python SDK: every
|
|
186
|
+
internal node type, the five spec examples, the FG-UC doctor samples and a
|
|
187
|
+
builder-shaped canvas definition, each with the expected TypeScript, Python,
|
|
188
|
+
layout and IR. See `fixtures/README.md`.
|
|
189
|
+
|
|
190
|
+
## Development
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
bun install
|
|
194
|
+
bun run test # vitest
|
|
195
|
+
bun run test:coverage # with the 85% gate
|
|
196
|
+
bun run lint
|
|
197
|
+
bun run typecheck # src, tests and the fixture projects
|
|
198
|
+
bun run check:fixtures # fixtures are current; add --ruff to run ruff format --check
|
|
199
|
+
bun run build # tsup: ESM + CJS + .d.ts
|
|
200
|
+
bun run sanity # everything above
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Releases are CalVer (`YYYY.MDD.PATCH`) through `.github/workflows/release.yml`
|
|
204
|
+
(the shared G60 workflow): push a CalVer tag or run the workflow from the
|
|
205
|
+
Actions tab.
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
Proprietary. Copyright (c) Algoshred Technologies Private Limited. See `LICENSE`.
|