@solidxai/core 0.1.12-beta.2 → 0.1.12-beta.4
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/.claude/settings.local.json +16 -0
- package/CLAUDE.md +26 -0
- package/dist/commands/seed.command.d.ts.map +1 -1
- package/dist/commands/seed.command.js +15 -2
- package/dist/commands/seed.command.js.map +1 -1
- package/dist/constants/media-file-types.d.ts +5 -0
- package/dist/constants/media-file-types.d.ts.map +1 -0
- package/dist/constants/media-file-types.js +27 -0
- package/dist/constants/media-file-types.js.map +1 -0
- package/dist/controllers/media.controller.d.ts +14 -11
- package/dist/controllers/media.controller.d.ts.map +1 -1
- package/dist/controllers/media.controller.js +72 -33
- package/dist/controllers/media.controller.js.map +1 -1
- package/dist/dtos/create-media.dto.d.ts +1 -0
- package/dist/dtos/create-media.dto.d.ts.map +1 -1
- package/dist/dtos/create-media.dto.js +7 -1
- package/dist/dtos/create-media.dto.js.map +1 -1
- package/dist/dtos/create-role-metadata.dto.d.ts +2 -0
- package/dist/dtos/create-role-metadata.dto.d.ts.map +1 -1
- package/dist/dtos/create-role-metadata.dto.js +3 -1
- package/dist/dtos/create-role-metadata.dto.js.map +1 -1
- package/dist/dtos/update-media.dto.d.ts +1 -0
- package/dist/dtos/update-media.dto.d.ts.map +1 -1
- package/dist/dtos/update-media.dto.js +7 -1
- package/dist/dtos/update-media.dto.js.map +1 -1
- package/dist/entities/media.entity.d.ts +1 -0
- package/dist/entities/media.entity.d.ts.map +1 -1
- package/dist/entities/media.entity.js +9 -1
- package/dist/entities/media.entity.js.map +1 -1
- package/dist/enums/auth-type.enum.d.ts +2 -1
- package/dist/enums/auth-type.enum.d.ts.map +1 -1
- package/dist/enums/auth-type.enum.js +1 -0
- package/dist/enums/auth-type.enum.js.map +1 -1
- package/dist/guards/authentication.guard.d.ts +3 -1
- package/dist/guards/authentication.guard.d.ts.map +1 -1
- package/dist/guards/authentication.guard.js +5 -1
- package/dist/guards/authentication.guard.js.map +1 -1
- package/dist/guards/media-signed-url.guard.d.ts +9 -0
- package/dist/guards/media-signed-url.guard.d.ts.map +1 -0
- package/dist/guards/media-signed-url.guard.js +49 -0
- package/dist/guards/media-signed-url.guard.js.map +1 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +10 -13
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
- package/dist/interfaces.d.ts +19 -1
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js +2 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/repository/media.repository.d.ts.map +1 -1
- package/dist/repository/media.repository.js +2 -0
- package/dist/repository/media.repository.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts +7 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +87 -3
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/permission-metadata-seeder.service.d.ts +1 -0
- package/dist/seeders/permission-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/permission-metadata-seeder.service.js +6 -1
- package/dist/seeders/permission-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +114 -13
- package/dist/services/authentication.service.d.ts +1 -0
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +19 -1
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/media-download-url.service.d.ts +21 -0
- package/dist/services/media-download-url.service.d.ts.map +1 -0
- package/dist/services/media-download-url.service.js +67 -0
- package/dist/services/media-download-url.service.js.map +1 -0
- package/dist/services/media-storage.utils.d.ts +27 -0
- package/dist/services/media-storage.utils.d.ts.map +1 -0
- package/dist/services/media-storage.utils.js +82 -0
- package/dist/services/media-storage.utils.js.map +1 -0
- package/dist/services/media.service.d.ts +20 -4
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +157 -55
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts +4 -4
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +37 -63
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.d.ts +5 -5
- package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.js +37 -38
- package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
- package/dist/services/role-metadata.service.d.ts +1 -0
- package/dist/services/role-metadata.service.d.ts.map +1 -1
- package/dist/services/role-metadata.service.js +8 -5
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +11 -1
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.js +1 -1
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/seed.command.ts +17 -3
- package/src/constants/media-file-types.ts +44 -0
- package/src/controllers/media.controller.ts +44 -24
- package/src/dtos/create-media.dto.ts +8 -3
- package/src/dtos/create-role-metadata.dto.ts +2 -0
- package/src/dtos/update-media.dto.ts +8 -3
- package/src/entities/media.entity.ts +4 -1
- package/src/enums/auth-type.enum.ts +1 -0
- package/src/guards/authentication.guard.ts +3 -0
- package/src/guards/media-signed-url.guard.ts +41 -0
- package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +12 -24
- package/src/interfaces.ts +20 -0
- package/src/repository/media.repository.ts +2 -0
- package/src/seeders/module-metadata-seeder.service.ts +109 -3
- package/src/seeders/permission-metadata-seeder.service.ts +6 -1
- package/src/seeders/seed-data/solid-core-metadata.json +114 -13
- package/src/services/1.js +6 -0
- package/src/services/authentication.service.ts +24 -1
- package/src/services/media-download-url.service.ts +67 -0
- package/src/services/media-storage.utils.ts +79 -0
- package/src/services/media.service.ts +189 -59
- package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +52 -76
- package/src/services/mediaStorageProviders/file-storage-provider.ts +44 -48
- package/src/services/role-metadata.service.ts +17 -5
- package/src/solid-core.module.ts +21 -2
- package/src/subscribers/audit.subscriber.ts +1 -1
- package/dist-tests/api/authenticate.spec.js +0 -119
- package/dist-tests/api/authenticate.spec.js.map +0 -1
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
- package/dist-tests/api/ping.spec.js +0 -21
- package/dist-tests/api/ping.spec.js.map +0 -1
- package/dist-tests/helpers/auth.js +0 -41
- package/dist-tests/helpers/auth.js.map +0 -1
- package/dist-tests/helpers/env.js +0 -11
- package/dist-tests/helpers/env.js.map +0 -1
- package/docs/agent-builder/notebook-lm-prompt-for-agent-builder.md +0 -136
- package/docs/agent-builder/team-ready-note-agent-builder.md +0 -305
- package/docs/agent-hub-grooming.md +0 -301
- package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +0 -438
- package/docs/dashboards/dashboard-curl-smoke-tests.txt +0 -146
- package/docs/dashboards/delete-legacy-dashboard-metadata.sql +0 -172
- package/docs/datasource-introspection-ddl-analysis.md +0 -326
- package/docs/datasource-introspection-implementation-plan.md +0 -306
- package/docs/grouping-enhancements.md +0 -89
- package/docs/java-spring/README.md +0 -3
- package/docs/java-spring/solid-core-module-deep-dive-report.md +0 -1317
- package/docs/module-package-import-handoff.md +0 -691
- package/docs/seed-changes.md +0 -65
- package/docs/test-data-workflow.md +0 -200
- package/docs/type-declaration-import-issue.md +0 -24
- package/docs/workflow/business-automation-example-notes.md +0 -309
- package/docs/workflow/data-engineering-pipeline-example-notes.md +0 -330
- package/docs/workflow/foreach-example-notes.md +0 -187
- package/docs/workflow/hello-world-example-notes.md +0 -271
- package/docs/workflow/kestra-concepts-plugins-blueprints.md +0 -315
- package/docs/workflow/loop-until-example-notes.md +0 -198
- package/docs/workflow/microservices-and-apis-example-notes.md +0 -264
- package/docs/workflow/samples.md +0 -25
- package/docs/workflow/what-is-kestra.md +0 -79
- package/docs/workflow/workflow-core-module-handoff-summary.md +0 -191
- package/docs/workflow/workflow-module-brd.md +0 -185
- package/docs/workflow/workflow-module-domain-model.md +0 -252
- package/docs/workflow/workflow-module-metadata-dsl.md +0 -302
- package/docs/workflow/workflow-module-technical-spec.md +0 -293
- package/docs/workflow/workflow-node-type-contracts.md +0 -635
- package/docs/workflow/workflow-node-ui-metadata-contract.md +0 -1262
- package/docs/workflow/workflow-solidx-model-field-spec.md +0 -284
|
@@ -1,1262 +0,0 @@
|
|
|
1
|
-
# Workflow Node UI Metadata Contract
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
|
|
5
|
-
This document explains the newly added workflow node metadata interfaces in:
|
|
6
|
-
|
|
7
|
-
- `solid-core-module/src/types/workflow-dsl.types.ts`
|
|
8
|
-
- `solid-core-ui/src/types/extension-registry.ts`
|
|
9
|
-
|
|
10
|
-
The goal is to support a workflow editor that is:
|
|
11
|
-
|
|
12
|
-
- schema-driven by default
|
|
13
|
-
- dynamically documented
|
|
14
|
-
- extensible through optional UI overrides
|
|
15
|
-
- safe for both `solid-core-ui` and consuming `solid-ui` projects
|
|
16
|
-
|
|
17
|
-
The core principle remains:
|
|
18
|
-
|
|
19
|
-
- backend metadata is the source of truth
|
|
20
|
-
- custom React components are optional escape hatches
|
|
21
|
-
- UI modules resolve component keys, the backend does not import React directly
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Design Summary
|
|
26
|
-
|
|
27
|
-
The new contract separates concerns into four layers:
|
|
28
|
-
|
|
29
|
-
1. `runtime`
|
|
30
|
-
What the node does when executed.
|
|
31
|
-
2. `authoring`
|
|
32
|
-
How the node is configured in schema-driven forms.
|
|
33
|
-
3. `documentation`
|
|
34
|
-
What the Docs panel can render.
|
|
35
|
-
4. `ui`
|
|
36
|
-
Optional extension keys for richer editors and docs renderers.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Object Graph
|
|
41
|
-
|
|
42
|
-
The following diagram shows how the newly added types relate to each other.
|
|
43
|
-
|
|
44
|
-
```mermaid
|
|
45
|
-
graph TD
|
|
46
|
-
A["WorkflowNodeProviderMetadata"] --> B["authoring: WorkflowNodeAuthoringMetadata"]
|
|
47
|
-
A --> C["runtime: WorkflowNodeRuntimeMetadata"]
|
|
48
|
-
A --> D["documentation: WorkflowNodeDocumentationMetadata"]
|
|
49
|
-
A --> E["ui: WorkflowNodeUiMetadata"]
|
|
50
|
-
A --> F["examples: WorkflowNodeExampleDefinition[]"]
|
|
51
|
-
A --> G["metrics: WorkflowNodeMetricDefinition[]"]
|
|
52
|
-
A --> H["definitions: WorkflowNodeReferenceDefinition[]"]
|
|
53
|
-
A --> I["configSchema / uiSchema / outputSchema"]
|
|
54
|
-
|
|
55
|
-
B --> B1["defaultConfiguration"]
|
|
56
|
-
B --> B2["configurationFields: WorkflowNodeConfigurationFieldDefinition[]"]
|
|
57
|
-
B --> B3["childSlots: WorkflowNodeChildSlotDefinition[]"]
|
|
58
|
-
B --> B4["outputs: WorkflowNodeOutputDefinition[]"]
|
|
59
|
-
B --> B5["supportsExpressions / retry / timeout / onError / etc."]
|
|
60
|
-
|
|
61
|
-
B2 --> B2a["valueType: WorkflowNodeConfigurationValueType"]
|
|
62
|
-
B2 --> B2b["extensionComponentKey?"]
|
|
63
|
-
B2 --> B2c["schema / uiSchema"]
|
|
64
|
-
|
|
65
|
-
B3 --> B3a["sequence"]
|
|
66
|
-
B3 --> B3b["branch-collection"]
|
|
67
|
-
|
|
68
|
-
D --> D1["summary"]
|
|
69
|
-
D --> D2["sections: WorkflowNodeDocumentationSection[]"]
|
|
70
|
-
D --> D3["examples: WorkflowNodeExampleDefinition[]"]
|
|
71
|
-
D --> D4["outputs: WorkflowNodeOutputDefinition[]"]
|
|
72
|
-
D --> D5["metrics: WorkflowNodeMetricDefinition[]"]
|
|
73
|
-
D --> D6["definitions: WorkflowNodeReferenceDefinition[]"]
|
|
74
|
-
|
|
75
|
-
E --> E1["editorComponentKey"]
|
|
76
|
-
E --> E2["docsComponentKey"]
|
|
77
|
-
E --> E3["paletteComponentKey"]
|
|
78
|
-
E --> E4["fieldComponentKeys"]
|
|
79
|
-
E --> E5["layoutHints"]
|
|
80
|
-
|
|
81
|
-
J["WorkflowNodeMetadataResponse"] --> A
|
|
82
|
-
|
|
83
|
-
K["solid-core-ui ExtensionComponentTypes"] --> K1["workflowNodeEditor"]
|
|
84
|
-
K --> K2["workflowNodeDocs"]
|
|
85
|
-
K --> K3["workflowNodeFieldEditor"]
|
|
86
|
-
K --> K4["workflowNodePaletteCard"]
|
|
87
|
-
|
|
88
|
-
E1 -.resolved by.-> K1
|
|
89
|
-
E2 -.resolved by.-> K2
|
|
90
|
-
B2b -.resolved by.-> K3
|
|
91
|
-
E3 -.resolved by.-> K4
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Hierarchy in words
|
|
95
|
-
|
|
96
|
-
At the top level:
|
|
97
|
-
|
|
98
|
-
- `WorkflowNodeProviderMetadata` is the main backend contract for one node type
|
|
99
|
-
- `WorkflowNodeMetadataResponse` is the client-facing shape that can expose that metadata to the UI
|
|
100
|
-
|
|
101
|
-
Inside node metadata:
|
|
102
|
-
|
|
103
|
-
- `authoring` drives schema-based form editing
|
|
104
|
-
- `runtime` describes execution behavior hints
|
|
105
|
-
- `documentation` drives the Docs panel
|
|
106
|
-
- `ui` provides optional extension keys and layout hints
|
|
107
|
-
|
|
108
|
-
Inside authoring:
|
|
109
|
-
|
|
110
|
-
- `configurationFields` define editable properties
|
|
111
|
-
- each property can use `WorkflowNodeConfigurationValueType`
|
|
112
|
-
- each property can optionally point to a field-level extension component
|
|
113
|
-
- `childSlots` define control-node nesting structure
|
|
114
|
-
- `outputs` define what downstream nodes can reference
|
|
115
|
-
|
|
116
|
-
Inside documentation:
|
|
117
|
-
|
|
118
|
-
- sections, examples, outputs, metrics, and definitions can all be rendered dynamically
|
|
119
|
-
|
|
120
|
-
On the frontend:
|
|
121
|
-
|
|
122
|
-
- `workflowNodeEditor` is the full-node editor escape hatch
|
|
123
|
-
- `workflowNodeDocs` is the custom docs renderer escape hatch
|
|
124
|
-
- `workflowNodeFieldEditor` is the preferred field-level override
|
|
125
|
-
- `workflowNodePaletteCard` customizes node selection/palette cards
|
|
126
|
-
|
|
127
|
-
### Runtime execution graph
|
|
128
|
-
|
|
129
|
-
The following smaller diagram shows how the runtime-side workflow types fit together during actual execution.
|
|
130
|
-
|
|
131
|
-
```mermaid
|
|
132
|
-
graph TD
|
|
133
|
-
A["WorkflowDefinitionDsl"] --> B["WorkflowNodeDefinition[]"]
|
|
134
|
-
B --> C["WorkflowRuntimeContext"]
|
|
135
|
-
C --> D["WorkflowNodeExecutionContext"]
|
|
136
|
-
|
|
137
|
-
D --> E["WorkflowNodeHandler.execute(...)"]
|
|
138
|
-
E --> F["WorkflowNodeHandlerResult"]
|
|
139
|
-
|
|
140
|
-
C --> G["input"]
|
|
141
|
-
C --> H["variables"]
|
|
142
|
-
C --> I["outputs"]
|
|
143
|
-
C --> J["execution: WorkflowExecution"]
|
|
144
|
-
C --> K["stepExecution: WorkflowStepExecution?"]
|
|
145
|
-
C --> L["item / index / parentNodeId"]
|
|
146
|
-
|
|
147
|
-
D --> M["expression resolver"]
|
|
148
|
-
D --> N["runNodes(...)"]
|
|
149
|
-
D --> O["emitLog(...)"]
|
|
150
|
-
D --> P["emitArtifact(...)"]
|
|
151
|
-
|
|
152
|
-
F --> Q["output"]
|
|
153
|
-
F --> R["artifacts"]
|
|
154
|
-
F --> S["status"]
|
|
155
|
-
|
|
156
|
-
O --> T["WorkflowExecutionLog"]
|
|
157
|
-
P --> U["WorkflowExecutionArtifact"]
|
|
158
|
-
Q --> I
|
|
159
|
-
S --> K
|
|
160
|
-
|
|
161
|
-
V["Future: WorkflowExecutionMetric"] -.pending.-> W["metric persistence / telemetry"]
|
|
162
|
-
E -.may emit.-> V
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Runtime hierarchy in words
|
|
166
|
-
|
|
167
|
-
At execution time:
|
|
168
|
-
|
|
169
|
-
- `WorkflowDefinitionDsl` is parsed from `definitionYaml` and contains the ordered `WorkflowNodeDefinition[]`
|
|
170
|
-
- the runtime builds a `WorkflowRuntimeContext`
|
|
171
|
-
- when a node is about to run, that becomes a `WorkflowNodeExecutionContext`
|
|
172
|
-
- the node handler executes against that context
|
|
173
|
-
- the result can update:
|
|
174
|
-
- `outputs`
|
|
175
|
-
- `WorkflowStepExecution` status
|
|
176
|
-
- `WorkflowExecutionLog`
|
|
177
|
-
- `WorkflowExecutionArtifact`
|
|
178
|
-
|
|
179
|
-
Important separation:
|
|
180
|
-
|
|
181
|
-
- `WorkflowNodeDefinition` is design-time configuration
|
|
182
|
-
- `WorkflowRuntimeContext` is in-memory execution state
|
|
183
|
-
- `WorkflowExecution`, `WorkflowStepExecution`, logs, and artifacts are persisted runtime records
|
|
184
|
-
- `metrics` are still pending a persistence or telemetry strategy
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## New Backend Types
|
|
189
|
-
|
|
190
|
-
### `WorkflowNodeConfigurationValueType`
|
|
191
|
-
|
|
192
|
-
This is the common vocabulary for describing field value shapes across authoring, outputs, and docs.
|
|
193
|
-
|
|
194
|
-
```ts
|
|
195
|
-
type WorkflowNodeConfigurationValueType =
|
|
196
|
-
| "string"
|
|
197
|
-
| "number"
|
|
198
|
-
| "integer"
|
|
199
|
-
| "boolean"
|
|
200
|
-
| "object"
|
|
201
|
-
| "array"
|
|
202
|
-
| "json"
|
|
203
|
-
| "secret"
|
|
204
|
-
| "expression"
|
|
205
|
-
| "relation"
|
|
206
|
-
| "uri"
|
|
207
|
-
| "any";
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
Example:
|
|
211
|
-
|
|
212
|
-
```ts
|
|
213
|
-
const queryFieldType: WorkflowNodeConfigurationValueType = "string";
|
|
214
|
-
const providerFieldType: WorkflowNodeConfigurationValueType = "object";
|
|
215
|
-
const secretFieldType: WorkflowNodeConfigurationValueType = "secret";
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
Why it matters:
|
|
219
|
-
|
|
220
|
-
- keeps backend and frontend aligned on data type meaning
|
|
221
|
-
- supports form generation
|
|
222
|
-
- supports docs badges such as `String`, `Object`, `URI`, `Secret`
|
|
223
|
-
|
|
224
|
-
---
|
|
225
|
-
|
|
226
|
-
### `WorkflowNodeProviderMetadata`
|
|
227
|
-
|
|
228
|
-
This is now the canonical metadata contract for one node type.
|
|
229
|
-
|
|
230
|
-
Example:
|
|
231
|
-
|
|
232
|
-
```ts
|
|
233
|
-
const httpRequestNodeMetadata: WorkflowNodeProviderMetadata = {
|
|
234
|
-
type: "http.request",
|
|
235
|
-
kind: "task",
|
|
236
|
-
version: "1.0.0",
|
|
237
|
-
category: "integration",
|
|
238
|
-
subcategory: "http",
|
|
239
|
-
label: "HTTP Request",
|
|
240
|
-
description: "Execute an outbound HTTP request and expose the response.",
|
|
241
|
-
icon: "globe",
|
|
242
|
-
tags: ["http", "api", "integration"],
|
|
243
|
-
aliases: ["http.fetch"],
|
|
244
|
-
configSchema: {
|
|
245
|
-
type: "object",
|
|
246
|
-
required: ["uri"],
|
|
247
|
-
properties: {
|
|
248
|
-
method: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE"] },
|
|
249
|
-
uri: { type: "string" },
|
|
250
|
-
headers: { type: "object" },
|
|
251
|
-
body: {},
|
|
252
|
-
timeoutMs: { type: "number" }
|
|
253
|
-
}
|
|
254
|
-
},
|
|
255
|
-
uiSchema: {
|
|
256
|
-
"ui:order": ["method", "uri", "headers", "body", "timeoutMs"]
|
|
257
|
-
},
|
|
258
|
-
outputSchema: {
|
|
259
|
-
type: "object",
|
|
260
|
-
properties: {
|
|
261
|
-
ok: { type: "boolean" },
|
|
262
|
-
status: { type: "number" },
|
|
263
|
-
headers: { type: "object" },
|
|
264
|
-
body: {}
|
|
265
|
-
}
|
|
266
|
-
},
|
|
267
|
-
examples: [
|
|
268
|
-
{
|
|
269
|
-
key: "simple-get",
|
|
270
|
-
label: "Simple GET request",
|
|
271
|
-
language: "json",
|
|
272
|
-
snippet: "{\"method\":\"GET\",\"uri\":\"{{ inputs.endpoint }}\"}",
|
|
273
|
-
configurationOnly: true
|
|
274
|
-
}
|
|
275
|
-
],
|
|
276
|
-
metrics: [
|
|
277
|
-
{
|
|
278
|
-
key: "http.request.duration",
|
|
279
|
-
label: "Request duration",
|
|
280
|
-
type: "timer",
|
|
281
|
-
unit: "ms"
|
|
282
|
-
}
|
|
283
|
-
],
|
|
284
|
-
definitions: [
|
|
285
|
-
{
|
|
286
|
-
key: "success-status-behavior",
|
|
287
|
-
label: "Success status behavior",
|
|
288
|
-
content: "When configured, the node treats only the given status codes as successful."
|
|
289
|
-
}
|
|
290
|
-
],
|
|
291
|
-
authoring: {
|
|
292
|
-
supportsExpressions: true,
|
|
293
|
-
supportsRetryPolicy: true,
|
|
294
|
-
supportsTimeoutMs: true,
|
|
295
|
-
supportsOnError: true,
|
|
296
|
-
supportsDisableToggle: true,
|
|
297
|
-
supportsName: true,
|
|
298
|
-
supportsDescription: true
|
|
299
|
-
},
|
|
300
|
-
runtime: {
|
|
301
|
-
emitsLogs: true,
|
|
302
|
-
emitsArtifacts: false,
|
|
303
|
-
deterministicOutputs: false,
|
|
304
|
-
executionMode: "task",
|
|
305
|
-
successStatuses: ["success"]
|
|
306
|
-
},
|
|
307
|
-
documentation: {
|
|
308
|
-
summary: "Call an API, capture the response, and expose it to downstream nodes."
|
|
309
|
-
},
|
|
310
|
-
ui: {
|
|
311
|
-
defaultEditorMode: "schema",
|
|
312
|
-
editorComponentKey: "workflow.node.httpRequest.editor",
|
|
313
|
-
docsComponentKey: "workflow.node.httpRequest.docs",
|
|
314
|
-
paletteComponentKey: "workflow.node.httpRequest.palette",
|
|
315
|
-
modalSize: "xl"
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
Why it matters:
|
|
321
|
-
|
|
322
|
-
- one object can power Code, Flow, and Docs
|
|
323
|
-
- allows core tasks and consuming-project tasks to look uniform
|
|
324
|
-
- enables future API endpoints such as `GET /workflow-node-types`
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
### `WorkflowNodeChildSlotDefinition`
|
|
329
|
-
|
|
330
|
-
Describes how a control node owns nested node collections.
|
|
331
|
-
|
|
332
|
-
Example for an `if` node:
|
|
333
|
-
|
|
334
|
-
```ts
|
|
335
|
-
const ifChildSlots: WorkflowNodeChildSlotDefinition[] = [
|
|
336
|
-
{
|
|
337
|
-
key: "then",
|
|
338
|
-
label: "Then branch",
|
|
339
|
-
description: "Runs when the condition evaluates to true.",
|
|
340
|
-
kind: "sequence",
|
|
341
|
-
required: true,
|
|
342
|
-
minItems: 1
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
key: "else",
|
|
346
|
-
label: "Else branch",
|
|
347
|
-
description: "Runs when the condition evaluates to false.",
|
|
348
|
-
kind: "sequence",
|
|
349
|
-
required: false
|
|
350
|
-
}
|
|
351
|
-
];
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
Example for a `parallel` node:
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
const parallelChildSlots: WorkflowNodeChildSlotDefinition[] = [
|
|
358
|
-
{
|
|
359
|
-
key: "branches",
|
|
360
|
-
label: "Parallel branches",
|
|
361
|
-
description: "Each branch runs concurrently and contains its own ordered node list.",
|
|
362
|
-
kind: "branch-collection",
|
|
363
|
-
required: true,
|
|
364
|
-
minItems: 1
|
|
365
|
-
}
|
|
366
|
-
];
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
Why it matters:
|
|
370
|
-
|
|
371
|
-
- tells the Flow editor which nested containers to render
|
|
372
|
-
- keeps control-node authoring declarative
|
|
373
|
-
- avoids hardcoding `then`, `else`, `children`, `branches` everywhere
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
### `WorkflowNodeConfigurationFieldDefinition`
|
|
378
|
-
|
|
379
|
-
Describes one configurable field for schema-driven authoring.
|
|
380
|
-
|
|
381
|
-
Example:
|
|
382
|
-
|
|
383
|
-
```ts
|
|
384
|
-
const uriField: WorkflowNodeConfigurationFieldDefinition = {
|
|
385
|
-
key: "uri",
|
|
386
|
-
label: "Request URI",
|
|
387
|
-
description: "The target endpoint for the request.",
|
|
388
|
-
valueType: "uri",
|
|
389
|
-
required: true,
|
|
390
|
-
path: "uri",
|
|
391
|
-
expressionAllowed: true,
|
|
392
|
-
secretAllowed: false,
|
|
393
|
-
examples: ["https://example.com", "{{ inputs.endpoint }}"],
|
|
394
|
-
group: "Request",
|
|
395
|
-
widgetHint: "text",
|
|
396
|
-
schema: {
|
|
397
|
-
type: "string"
|
|
398
|
-
},
|
|
399
|
-
uiSchema: {
|
|
400
|
-
"ui:placeholder": "https://api.example.com/orders"
|
|
401
|
-
}
|
|
402
|
-
};
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
Example with an escape-hatch field renderer:
|
|
406
|
-
|
|
407
|
-
```ts
|
|
408
|
-
const headersField: WorkflowNodeConfigurationFieldDefinition = {
|
|
409
|
-
key: "headers",
|
|
410
|
-
label: "Headers",
|
|
411
|
-
description: "Optional request headers.",
|
|
412
|
-
valueType: "object",
|
|
413
|
-
path: "headers",
|
|
414
|
-
expressionAllowed: true,
|
|
415
|
-
group: "Request",
|
|
416
|
-
widgetHint: "key-value-editor",
|
|
417
|
-
extensionComponentKey: "workflow.node.field.headersEditor"
|
|
418
|
-
};
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
Why it matters:
|
|
422
|
-
|
|
423
|
-
- default form generation happens from these definitions
|
|
424
|
-
- special UX can still be plugged in at the field level
|
|
425
|
-
- supports property tables in the Docs panel
|
|
426
|
-
|
|
427
|
-
---
|
|
428
|
-
|
|
429
|
-
### `WorkflowNodeOutputDefinition`
|
|
430
|
-
|
|
431
|
-
Describes one named output exposed by a node.
|
|
432
|
-
|
|
433
|
-
Example:
|
|
434
|
-
|
|
435
|
-
```ts
|
|
436
|
-
const httpOutputs: WorkflowNodeOutputDefinition[] = [
|
|
437
|
-
{
|
|
438
|
-
key: "status",
|
|
439
|
-
label: "HTTP status",
|
|
440
|
-
description: "Status code returned by the remote server.",
|
|
441
|
-
valueType: "integer",
|
|
442
|
-
path: "status",
|
|
443
|
-
required: true
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
key: "body",
|
|
447
|
-
label: "Response body",
|
|
448
|
-
description: "Parsed response body.",
|
|
449
|
-
valueType: "any",
|
|
450
|
-
path: "body"
|
|
451
|
-
}
|
|
452
|
-
];
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
Why it matters:
|
|
456
|
-
|
|
457
|
-
- powers downstream autocomplete such as `{{ outputs.makeRequest.status }}`
|
|
458
|
-
- powers output docs
|
|
459
|
-
- keeps output semantics explicit instead of implied only by runtime code
|
|
460
|
-
|
|
461
|
-
---
|
|
462
|
-
|
|
463
|
-
### `WorkflowNodeMetricDefinition`
|
|
464
|
-
|
|
465
|
-
Describes metrics that a node may emit or contribute to.
|
|
466
|
-
|
|
467
|
-
Example:
|
|
468
|
-
|
|
469
|
-
```ts
|
|
470
|
-
const httpMetrics: WorkflowNodeMetricDefinition[] = [
|
|
471
|
-
{
|
|
472
|
-
key: "http.request.duration",
|
|
473
|
-
label: "Request duration",
|
|
474
|
-
description: "Measures the end-to-end request duration.",
|
|
475
|
-
type: "timer",
|
|
476
|
-
unit: "ms",
|
|
477
|
-
tags: ["http", "latency"]
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
key: "http.request.error.count",
|
|
481
|
-
label: "Request errors",
|
|
482
|
-
description: "Counts request failures.",
|
|
483
|
-
type: "counter",
|
|
484
|
-
tags: ["http", "errors"]
|
|
485
|
-
}
|
|
486
|
-
];
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
Why it matters:
|
|
490
|
-
|
|
491
|
-
- lets the Docs panel show observability affordances
|
|
492
|
-
- helps future execution dashboards stay aligned with task metadata
|
|
493
|
-
|
|
494
|
-
---
|
|
495
|
-
|
|
496
|
-
### `WorkflowNodeExampleDefinition`
|
|
497
|
-
|
|
498
|
-
Represents a runnable or illustrative example.
|
|
499
|
-
|
|
500
|
-
Example:
|
|
501
|
-
|
|
502
|
-
```ts
|
|
503
|
-
const simpleExample: WorkflowNodeExampleDefinition = {
|
|
504
|
-
key: "simple-log",
|
|
505
|
-
label: "Simple log statement",
|
|
506
|
-
description: "Minimal log task example.",
|
|
507
|
-
language: "json",
|
|
508
|
-
snippet: "{\"message\":\"Hello {{ inputs.name }}\"}",
|
|
509
|
-
configurationOnly: true
|
|
510
|
-
};
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
Flow-level example:
|
|
514
|
-
|
|
515
|
-
```ts
|
|
516
|
-
const fullFlowExample: WorkflowNodeExampleDefinition = {
|
|
517
|
-
key: "health-check-flow",
|
|
518
|
-
label: "Health check flow",
|
|
519
|
-
description: "Make a request and log the status code.",
|
|
520
|
-
language: "json",
|
|
521
|
-
snippet: "{\n \"nodes\": [\n {\n \"id\": \"makeRequest\",\n \"kind\": \"task\",\n \"type\": \"http.request\",\n \"configuration\": {\n \"uri\": \"{{ inputs.uri }}\"\n }\n }\n ]\n}"
|
|
522
|
-
};
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
Why it matters:
|
|
526
|
-
|
|
527
|
-
- docs become immediately practical
|
|
528
|
-
- examples can later power “insert sample configuration” actions
|
|
529
|
-
|
|
530
|
-
---
|
|
531
|
-
|
|
532
|
-
### `WorkflowNodeReferenceDefinition`
|
|
533
|
-
|
|
534
|
-
Represents richer supporting definitions, reference cards, or embedded sub-docs.
|
|
535
|
-
|
|
536
|
-
Example:
|
|
537
|
-
|
|
538
|
-
```ts
|
|
539
|
-
const pgVectorDefinition: WorkflowNodeReferenceDefinition = {
|
|
540
|
-
key: "pgvector-connection",
|
|
541
|
-
label: "PGVector connection definition",
|
|
542
|
-
description: "Fields required when using the PGVector embedding store.",
|
|
543
|
-
content: "The PGVector provider needs host, port, user, password, database, and table.",
|
|
544
|
-
schema: {
|
|
545
|
-
type: "object",
|
|
546
|
-
required: ["host", "port", "database", "table"]
|
|
547
|
-
},
|
|
548
|
-
examples: [
|
|
549
|
-
{
|
|
550
|
-
key: "pgvector-sample",
|
|
551
|
-
label: "PGVector sample",
|
|
552
|
-
language: "json",
|
|
553
|
-
snippet: "{\"host\":\"localhost\",\"port\":5432,\"database\":\"postgres\",\"table\":\"embeddings\"}",
|
|
554
|
-
configurationOnly: true
|
|
555
|
-
}
|
|
556
|
-
]
|
|
557
|
-
};
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
Why it matters:
|
|
561
|
-
|
|
562
|
-
- supports the richer Kestra-style docs experience
|
|
563
|
-
- lets one task document nested definition families cleanly
|
|
564
|
-
|
|
565
|
-
---
|
|
566
|
-
|
|
567
|
-
### `WorkflowNodeDocumentationSection`
|
|
568
|
-
|
|
569
|
-
Represents one named section in the Docs panel.
|
|
570
|
-
|
|
571
|
-
Example:
|
|
572
|
-
|
|
573
|
-
```ts
|
|
574
|
-
const docsSections: WorkflowNodeDocumentationSection[] = [
|
|
575
|
-
{
|
|
576
|
-
key: "summary",
|
|
577
|
-
label: "Summary",
|
|
578
|
-
markdown: "Calls an HTTP endpoint and exposes the response to downstream nodes.",
|
|
579
|
-
initiallyExpanded: true
|
|
580
|
-
},
|
|
581
|
-
{
|
|
582
|
-
key: "error-behavior",
|
|
583
|
-
label: "Error behavior",
|
|
584
|
-
markdown: "Network failures and timeout failures cause the node to fail."
|
|
585
|
-
}
|
|
586
|
-
];
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
Why it matters:
|
|
590
|
-
|
|
591
|
-
- keeps docs structured instead of one long markdown blob
|
|
592
|
-
- supports stable tabs, accordions, and search anchors later
|
|
593
|
-
|
|
594
|
-
---
|
|
595
|
-
|
|
596
|
-
### `WorkflowNodeAuthoringMetadata`
|
|
597
|
-
|
|
598
|
-
Defines the schema-driven authoring experience.
|
|
599
|
-
|
|
600
|
-
Example:
|
|
601
|
-
|
|
602
|
-
```ts
|
|
603
|
-
const httpAuthoring: WorkflowNodeAuthoringMetadata = {
|
|
604
|
-
defaultConfiguration: {
|
|
605
|
-
method: "GET",
|
|
606
|
-
headers: {},
|
|
607
|
-
timeoutMs: 30000
|
|
608
|
-
},
|
|
609
|
-
configurationFields: [
|
|
610
|
-
{
|
|
611
|
-
key: "method",
|
|
612
|
-
label: "Method",
|
|
613
|
-
valueType: "string",
|
|
614
|
-
required: false,
|
|
615
|
-
enumValues: ["GET", "POST", "PUT", "PATCH", "DELETE"],
|
|
616
|
-
defaultValue: "GET",
|
|
617
|
-
group: "Request"
|
|
618
|
-
},
|
|
619
|
-
{
|
|
620
|
-
key: "uri",
|
|
621
|
-
label: "URI",
|
|
622
|
-
valueType: "uri",
|
|
623
|
-
required: true,
|
|
624
|
-
expressionAllowed: true,
|
|
625
|
-
group: "Request"
|
|
626
|
-
}
|
|
627
|
-
],
|
|
628
|
-
outputs: [
|
|
629
|
-
{
|
|
630
|
-
key: "status",
|
|
631
|
-
label: "Status",
|
|
632
|
-
valueType: "integer",
|
|
633
|
-
required: true
|
|
634
|
-
}
|
|
635
|
-
],
|
|
636
|
-
supportsExpressions: true,
|
|
637
|
-
supportsRetryPolicy: true,
|
|
638
|
-
supportsTimeoutMs: true,
|
|
639
|
-
supportsOnError: true,
|
|
640
|
-
supportsDisableToggle: true,
|
|
641
|
-
supportsName: true,
|
|
642
|
-
supportsDescription: true,
|
|
643
|
-
searchableText: ["http", "api", "request", "rest"]
|
|
644
|
-
};
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
Why it matters:
|
|
648
|
-
|
|
649
|
-
- this is the default engine for modal-form node editing
|
|
650
|
-
- lets the editor stay metadata-driven for most nodes
|
|
651
|
-
|
|
652
|
-
---
|
|
653
|
-
|
|
654
|
-
### `WorkflowNodeRuntimeMetadata`
|
|
655
|
-
|
|
656
|
-
Describes runtime behavior hints.
|
|
657
|
-
|
|
658
|
-
Example:
|
|
659
|
-
|
|
660
|
-
```ts
|
|
661
|
-
const forEachRuntime: WorkflowNodeRuntimeMetadata = {
|
|
662
|
-
emitsLogs: false,
|
|
663
|
-
emitsArtifacts: false,
|
|
664
|
-
deterministicOutputs: false,
|
|
665
|
-
executionMode: "engine-controlled",
|
|
666
|
-
successStatuses: ["success", "skipped"]
|
|
667
|
-
};
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
Why it matters:
|
|
671
|
-
|
|
672
|
-
- separates runtime semantics from docs and authoring concerns
|
|
673
|
-
- especially useful for control nodes where the engine owns traversal
|
|
674
|
-
|
|
675
|
-
---
|
|
676
|
-
|
|
677
|
-
### `WorkflowNodeDocumentationMetadata`
|
|
678
|
-
|
|
679
|
-
Bundles the content needed for the Docs panel.
|
|
680
|
-
|
|
681
|
-
Example:
|
|
682
|
-
|
|
683
|
-
```ts
|
|
684
|
-
const searchNodeDocs: WorkflowNodeDocumentationMetadata = {
|
|
685
|
-
summary: "Search an embedding store and return ranked matches.",
|
|
686
|
-
sections: [
|
|
687
|
-
{
|
|
688
|
-
key: "behavior",
|
|
689
|
-
label: "Behavior",
|
|
690
|
-
markdown: "The node computes embeddings using the configured provider and queries the selected store."
|
|
691
|
-
}
|
|
692
|
-
],
|
|
693
|
-
examples: [
|
|
694
|
-
{
|
|
695
|
-
key: "search-example",
|
|
696
|
-
label: "Search embeddings",
|
|
697
|
-
language: "json",
|
|
698
|
-
snippet: "{\"query\":\"workflow builder\",\"maxResults\":5}",
|
|
699
|
-
configurationOnly: true
|
|
700
|
-
}
|
|
701
|
-
],
|
|
702
|
-
outputs: [
|
|
703
|
-
{
|
|
704
|
-
key: "results",
|
|
705
|
-
label: "Results",
|
|
706
|
-
valueType: "array"
|
|
707
|
-
}
|
|
708
|
-
],
|
|
709
|
-
metrics: [
|
|
710
|
-
{
|
|
711
|
-
key: "ai.provider.calls",
|
|
712
|
-
label: "Provider calls",
|
|
713
|
-
type: "counter"
|
|
714
|
-
}
|
|
715
|
-
],
|
|
716
|
-
definitions: [
|
|
717
|
-
{
|
|
718
|
-
key: "embedding-store-definitions",
|
|
719
|
-
label: "Embedding store definitions",
|
|
720
|
-
content: "Available stores may define different required connection properties."
|
|
721
|
-
}
|
|
722
|
-
]
|
|
723
|
-
};
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
Why it matters:
|
|
727
|
-
|
|
728
|
-
- gives the Docs panel a stable API
|
|
729
|
-
- aligns closely with the examples shown in the Kestra screenshots
|
|
730
|
-
|
|
731
|
-
---
|
|
732
|
-
|
|
733
|
-
### `WorkflowNodeUiMetadata`
|
|
734
|
-
|
|
735
|
-
Defines optional UI extension keys and layout hints.
|
|
736
|
-
|
|
737
|
-
Example:
|
|
738
|
-
|
|
739
|
-
```ts
|
|
740
|
-
const httpUi: WorkflowNodeUiMetadata = {
|
|
741
|
-
editorComponentKey: "workflow.node.httpRequest.editor",
|
|
742
|
-
docsComponentKey: "workflow.node.httpRequest.docs",
|
|
743
|
-
paletteComponentKey: "workflow.node.httpRequest.palette",
|
|
744
|
-
defaultEditorMode: "schema",
|
|
745
|
-
fieldComponentKeys: {
|
|
746
|
-
headers: "workflow.node.field.headersEditor",
|
|
747
|
-
body: "workflow.node.field.bodyEditor"
|
|
748
|
-
},
|
|
749
|
-
modalSize: "xl",
|
|
750
|
-
layoutHints: {
|
|
751
|
-
preferredPanel: "flow",
|
|
752
|
-
groupOrder: ["Request", "Authentication", "Advanced"],
|
|
753
|
-
stickySummary: true
|
|
754
|
-
}
|
|
755
|
-
};
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
Meaning of the fields:
|
|
759
|
-
|
|
760
|
-
- `editorComponentKey`
|
|
761
|
-
Optional full-node editor override.
|
|
762
|
-
- `docsComponentKey`
|
|
763
|
-
Optional docs renderer override.
|
|
764
|
-
- `paletteComponentKey`
|
|
765
|
-
Optional custom card for the node picker/palette.
|
|
766
|
-
- `defaultEditorMode`
|
|
767
|
-
Tells the UI whether the preferred experience is still schema-first or custom-first.
|
|
768
|
-
- `fieldComponentKeys`
|
|
769
|
-
Field-specific escape hatches without replacing the entire node editor.
|
|
770
|
-
- `modalSize`
|
|
771
|
-
Good for large configuration surfaces.
|
|
772
|
-
- `layoutHints`
|
|
773
|
-
Helps the UI arrange content without hardcoding per-node behavior.
|
|
774
|
-
|
|
775
|
-
Why it matters:
|
|
776
|
-
|
|
777
|
-
- keeps the backend decoupled from React
|
|
778
|
-
- gives the UI enough information to resolve optional enhancements
|
|
779
|
-
|
|
780
|
-
---
|
|
781
|
-
|
|
782
|
-
### `WorkflowNodeMetadataResponse`
|
|
783
|
-
|
|
784
|
-
Represents the shape the backend can safely expose to clients.
|
|
785
|
-
|
|
786
|
-
Example:
|
|
787
|
-
|
|
788
|
-
```ts
|
|
789
|
-
const metadataResponse: WorkflowNodeMetadataResponse = {
|
|
790
|
-
type: "http.request",
|
|
791
|
-
kind: "task",
|
|
792
|
-
version: "1.0.0",
|
|
793
|
-
category: "integration",
|
|
794
|
-
subcategory: "http",
|
|
795
|
-
label: "HTTP Request",
|
|
796
|
-
description: "Execute an outbound HTTP request.",
|
|
797
|
-
icon: "globe",
|
|
798
|
-
tags: ["http", "api"],
|
|
799
|
-
configSchema: {
|
|
800
|
-
type: "object",
|
|
801
|
-
required: ["uri"]
|
|
802
|
-
},
|
|
803
|
-
uiSchema: {
|
|
804
|
-
"ui:order": ["method", "uri", "headers", "body"]
|
|
805
|
-
},
|
|
806
|
-
outputSchema: {
|
|
807
|
-
type: "object",
|
|
808
|
-
properties: {
|
|
809
|
-
status: { type: "number" }
|
|
810
|
-
}
|
|
811
|
-
},
|
|
812
|
-
examples: [
|
|
813
|
-
{
|
|
814
|
-
key: "basic",
|
|
815
|
-
label: "Basic request",
|
|
816
|
-
language: "json",
|
|
817
|
-
snippet: "{\"uri\":\"{{ inputs.url }}\"}",
|
|
818
|
-
configurationOnly: true
|
|
819
|
-
}
|
|
820
|
-
],
|
|
821
|
-
metrics: [
|
|
822
|
-
{
|
|
823
|
-
key: "http.request.duration",
|
|
824
|
-
label: "Request duration",
|
|
825
|
-
type: "timer"
|
|
826
|
-
}
|
|
827
|
-
],
|
|
828
|
-
definitions: [
|
|
829
|
-
{
|
|
830
|
-
key: "status-definition",
|
|
831
|
-
label: "Status definition",
|
|
832
|
-
content: "HTTP status code returned by the response."
|
|
833
|
-
}
|
|
834
|
-
],
|
|
835
|
-
authoring: httpAuthoring,
|
|
836
|
-
runtime: {
|
|
837
|
-
emitsLogs: true,
|
|
838
|
-
executionMode: "task"
|
|
839
|
-
},
|
|
840
|
-
documentation: searchNodeDocs,
|
|
841
|
-
ui: httpUi
|
|
842
|
-
};
|
|
843
|
-
```
|
|
844
|
-
|
|
845
|
-
Why it matters:
|
|
846
|
-
|
|
847
|
-
- good DTO/API shape for the future editor
|
|
848
|
-
- allows UI clients to stay ignorant of server implementation details
|
|
849
|
-
|
|
850
|
-
---
|
|
851
|
-
|
|
852
|
-
## Example: Full Core Node Metadata
|
|
853
|
-
|
|
854
|
-
Below is a compact end-to-end example for a core `log.write` node:
|
|
855
|
-
|
|
856
|
-
```ts
|
|
857
|
-
const logWriteNode: WorkflowNodeProviderMetadata = {
|
|
858
|
-
type: "log.write",
|
|
859
|
-
kind: "task",
|
|
860
|
-
version: "1.0.0",
|
|
861
|
-
category: "core",
|
|
862
|
-
label: "Write Log",
|
|
863
|
-
description: "Write a log line into the workflow execution log.",
|
|
864
|
-
icon: "file-text",
|
|
865
|
-
tags: ["log", "observability"],
|
|
866
|
-
configSchema: {
|
|
867
|
-
type: "object",
|
|
868
|
-
required: ["message"],
|
|
869
|
-
properties: {
|
|
870
|
-
level: { type: "string", enum: ["debug", "info", "warn", "error"] },
|
|
871
|
-
message: { type: "string" },
|
|
872
|
-
metadata: { type: "object" }
|
|
873
|
-
}
|
|
874
|
-
},
|
|
875
|
-
authoring: {
|
|
876
|
-
defaultConfiguration: {
|
|
877
|
-
level: "info"
|
|
878
|
-
},
|
|
879
|
-
configurationFields: [
|
|
880
|
-
{
|
|
881
|
-
key: "level",
|
|
882
|
-
label: "Level",
|
|
883
|
-
valueType: "string",
|
|
884
|
-
enumValues: ["debug", "info", "warn", "error"],
|
|
885
|
-
defaultValue: "info",
|
|
886
|
-
group: "Message"
|
|
887
|
-
},
|
|
888
|
-
{
|
|
889
|
-
key: "message",
|
|
890
|
-
label: "Message",
|
|
891
|
-
valueType: "string",
|
|
892
|
-
required: true,
|
|
893
|
-
expressionAllowed: true,
|
|
894
|
-
group: "Message"
|
|
895
|
-
},
|
|
896
|
-
{
|
|
897
|
-
key: "metadata",
|
|
898
|
-
label: "Metadata",
|
|
899
|
-
valueType: "object",
|
|
900
|
-
expressionAllowed: true,
|
|
901
|
-
group: "Advanced"
|
|
902
|
-
}
|
|
903
|
-
],
|
|
904
|
-
outputs: [
|
|
905
|
-
{
|
|
906
|
-
key: "message",
|
|
907
|
-
label: "Rendered message",
|
|
908
|
-
valueType: "string"
|
|
909
|
-
},
|
|
910
|
-
{
|
|
911
|
-
key: "level",
|
|
912
|
-
label: "Rendered level",
|
|
913
|
-
valueType: "string"
|
|
914
|
-
}
|
|
915
|
-
],
|
|
916
|
-
supportsExpressions: true,
|
|
917
|
-
supportsDisableToggle: true,
|
|
918
|
-
supportsName: true,
|
|
919
|
-
supportsDescription: true
|
|
920
|
-
},
|
|
921
|
-
runtime: {
|
|
922
|
-
emitsLogs: true,
|
|
923
|
-
emitsArtifacts: false,
|
|
924
|
-
deterministicOutputs: true,
|
|
925
|
-
executionMode: "task",
|
|
926
|
-
successStatuses: ["success"]
|
|
927
|
-
},
|
|
928
|
-
documentation: {
|
|
929
|
-
summary: "A lightweight task for debug messages, audit breadcrumbs, and quick verification.",
|
|
930
|
-
sections: [
|
|
931
|
-
{
|
|
932
|
-
key: "usage",
|
|
933
|
-
label: "Usage",
|
|
934
|
-
markdown: "Use this task to inspect expressions and execution values during development."
|
|
935
|
-
}
|
|
936
|
-
],
|
|
937
|
-
examples: [
|
|
938
|
-
{
|
|
939
|
-
key: "simple-message",
|
|
940
|
-
label: "Simple message",
|
|
941
|
-
language: "json",
|
|
942
|
-
snippet: "{\"message\":\"Hello {{ inputs.name }}\"}",
|
|
943
|
-
configurationOnly: true
|
|
944
|
-
}
|
|
945
|
-
],
|
|
946
|
-
outputs: [
|
|
947
|
-
{
|
|
948
|
-
key: "message",
|
|
949
|
-
label: "Message",
|
|
950
|
-
valueType: "string"
|
|
951
|
-
}
|
|
952
|
-
]
|
|
953
|
-
},
|
|
954
|
-
ui: {
|
|
955
|
-
defaultEditorMode: "schema",
|
|
956
|
-
modalSize: "lg",
|
|
957
|
-
layoutHints: {
|
|
958
|
-
preferredPanel: "flow",
|
|
959
|
-
groupOrder: ["Message", "Advanced"]
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
};
|
|
963
|
-
```
|
|
964
|
-
|
|
965
|
-
---
|
|
966
|
-
|
|
967
|
-
## New Frontend Extension Component Types
|
|
968
|
-
|
|
969
|
-
The following lines were added to:
|
|
970
|
-
|
|
971
|
-
- `solid-core-ui/src/types/extension-registry.ts`
|
|
972
|
-
|
|
973
|
-
```ts
|
|
974
|
-
workflowNodeEditor: "workflowNodeEditor",
|
|
975
|
-
workflowNodeDocs: "workflowNodeDocs",
|
|
976
|
-
workflowNodeFieldEditor: "workflowNodeFieldEditor",
|
|
977
|
-
workflowNodePaletteCard: "workflowNodePaletteCard",
|
|
978
|
-
```
|
|
979
|
-
|
|
980
|
-
Each one is documented below.
|
|
981
|
-
|
|
982
|
-
---
|
|
983
|
-
|
|
984
|
-
### `workflowNodeEditor`
|
|
985
|
-
|
|
986
|
-
Line:
|
|
987
|
-
|
|
988
|
-
```ts
|
|
989
|
-
workflowNodeEditor: "workflowNodeEditor"
|
|
990
|
-
```
|
|
991
|
-
|
|
992
|
-
Meaning:
|
|
993
|
-
|
|
994
|
-
- registers a full custom node editor experience
|
|
995
|
-
- used only when schema-driven editing is insufficient
|
|
996
|
-
- should be rare
|
|
997
|
-
|
|
998
|
-
When to use:
|
|
999
|
-
|
|
1000
|
-
- deeply nested configurations
|
|
1001
|
-
- highly visual domain-specific editors
|
|
1002
|
-
- tasks that need a specialized multi-step setup flow
|
|
1003
|
-
|
|
1004
|
-
Example registration:
|
|
1005
|
-
|
|
1006
|
-
```ts
|
|
1007
|
-
{
|
|
1008
|
-
name: "workflow.node.httpRequest.editor",
|
|
1009
|
-
type: ExtensionComponentTypes.workflowNodeEditor,
|
|
1010
|
-
component: HttpRequestNodeEditor
|
|
1011
|
-
}
|
|
1012
|
-
```
|
|
1013
|
-
|
|
1014
|
-
Expected usage:
|
|
1015
|
-
|
|
1016
|
-
- backend metadata sets `ui.editorComponentKey = "workflow.node.httpRequest.editor"`
|
|
1017
|
-
- the workflow editor resolves that key through the extension registry
|
|
1018
|
-
|
|
1019
|
-
---
|
|
1020
|
-
|
|
1021
|
-
### `workflowNodeDocs`
|
|
1022
|
-
|
|
1023
|
-
Line:
|
|
1024
|
-
|
|
1025
|
-
```ts
|
|
1026
|
-
workflowNodeDocs: "workflowNodeDocs"
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
Meaning:
|
|
1030
|
-
|
|
1031
|
-
- registers a custom docs renderer for one node type
|
|
1032
|
-
- default docs should still come from metadata
|
|
1033
|
-
|
|
1034
|
-
When to use:
|
|
1035
|
-
|
|
1036
|
-
- interactive docs
|
|
1037
|
-
- searchable nested definitions
|
|
1038
|
-
- complex examples needing special rendering
|
|
1039
|
-
|
|
1040
|
-
Example registration:
|
|
1041
|
-
|
|
1042
|
-
```ts
|
|
1043
|
-
{
|
|
1044
|
-
name: "workflow.node.search.docs",
|
|
1045
|
-
type: ExtensionComponentTypes.workflowNodeDocs,
|
|
1046
|
-
component: SearchNodeDocsPanel
|
|
1047
|
-
}
|
|
1048
|
-
```
|
|
1049
|
-
|
|
1050
|
-
Expected usage:
|
|
1051
|
-
|
|
1052
|
-
- backend metadata sets `ui.docsComponentKey = "workflow.node.search.docs"`
|
|
1053
|
-
- otherwise the generic Docs renderer uses `documentation`, `examples`, `outputs`, `metrics`, and `definitions`
|
|
1054
|
-
|
|
1055
|
-
---
|
|
1056
|
-
|
|
1057
|
-
### `workflowNodeFieldEditor`
|
|
1058
|
-
|
|
1059
|
-
Line:
|
|
1060
|
-
|
|
1061
|
-
```ts
|
|
1062
|
-
workflowNodeFieldEditor: "workflowNodeFieldEditor"
|
|
1063
|
-
```
|
|
1064
|
-
|
|
1065
|
-
Meaning:
|
|
1066
|
-
|
|
1067
|
-
- registers a field-level override for one configuration field
|
|
1068
|
-
- this is the preferred escape hatch before replacing the whole node editor
|
|
1069
|
-
|
|
1070
|
-
When to use:
|
|
1071
|
-
|
|
1072
|
-
- key/value header editors
|
|
1073
|
-
- auth setup widgets
|
|
1074
|
-
- provider pickers
|
|
1075
|
-
- nested object builders
|
|
1076
|
-
|
|
1077
|
-
Example registration:
|
|
1078
|
-
|
|
1079
|
-
```ts
|
|
1080
|
-
{
|
|
1081
|
-
name: "workflow.node.field.headersEditor",
|
|
1082
|
-
type: ExtensionComponentTypes.workflowNodeFieldEditor,
|
|
1083
|
-
component: HeadersKeyValueEditor
|
|
1084
|
-
}
|
|
1085
|
-
```
|
|
1086
|
-
|
|
1087
|
-
Expected usage:
|
|
1088
|
-
|
|
1089
|
-
- backend metadata sets either:
|
|
1090
|
-
- `WorkflowNodeConfigurationFieldDefinition.extensionComponentKey`
|
|
1091
|
-
- or `WorkflowNodeUiMetadata.fieldComponentKeys["headers"]`
|
|
1092
|
-
|
|
1093
|
-
This is the main UI override pattern we want to encourage.
|
|
1094
|
-
|
|
1095
|
-
---
|
|
1096
|
-
|
|
1097
|
-
### `workflowNodePaletteCard`
|
|
1098
|
-
|
|
1099
|
-
Line:
|
|
1100
|
-
|
|
1101
|
-
```ts
|
|
1102
|
-
workflowNodePaletteCard: "workflowNodePaletteCard"
|
|
1103
|
-
```
|
|
1104
|
-
|
|
1105
|
-
Meaning:
|
|
1106
|
-
|
|
1107
|
-
- registers a custom visual representation for the node picker / palette / insert dialog
|
|
1108
|
-
|
|
1109
|
-
When to use:
|
|
1110
|
-
|
|
1111
|
-
- rich node cards with icons, tags, quick examples, or usage hints
|
|
1112
|
-
- domain-specific palettes where discoverability matters
|
|
1113
|
-
|
|
1114
|
-
Example registration:
|
|
1115
|
-
|
|
1116
|
-
```ts
|
|
1117
|
-
{
|
|
1118
|
-
name: "workflow.node.httpRequest.palette",
|
|
1119
|
-
type: ExtensionComponentTypes.workflowNodePaletteCard,
|
|
1120
|
-
component: HttpRequestPaletteCard
|
|
1121
|
-
}
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
Expected usage:
|
|
1125
|
-
|
|
1126
|
-
- backend metadata sets `ui.paletteComponentKey = "workflow.node.httpRequest.palette"`
|
|
1127
|
-
- otherwise the default palette card can be rendered from `label`, `description`, `category`, `icon`, and `tags`
|
|
1128
|
-
|
|
1129
|
-
---
|
|
1130
|
-
|
|
1131
|
-
## Recommended Precedence Rules
|
|
1132
|
-
|
|
1133
|
-
To keep behavior predictable, the workflow UI should use this order:
|
|
1134
|
-
|
|
1135
|
-
1. render from backend metadata only
|
|
1136
|
-
2. if a field-level override exists, use `workflowNodeFieldEditor`
|
|
1137
|
-
3. if a full-node editor override exists, use `workflowNodeEditor`
|
|
1138
|
-
4. if a docs override exists, use `workflowNodeDocs`
|
|
1139
|
-
5. if a palette override exists, use `workflowNodePaletteCard`
|
|
1140
|
-
|
|
1141
|
-
This preserves the intended design:
|
|
1142
|
-
|
|
1143
|
-
- schema-driven first
|
|
1144
|
-
- extension-driven only when needed
|
|
1145
|
-
|
|
1146
|
-
---
|
|
1147
|
-
|
|
1148
|
-
## Recommended First Implementations
|
|
1149
|
-
|
|
1150
|
-
The first core nodes to enrich with this metadata should likely be:
|
|
1151
|
-
|
|
1152
|
-
1. `log.write`
|
|
1153
|
-
2. `http.request`
|
|
1154
|
-
3. `if`
|
|
1155
|
-
4. `forEach`
|
|
1156
|
-
5. `parallel`
|
|
1157
|
-
|
|
1158
|
-
Suggested rollout:
|
|
1159
|
-
|
|
1160
|
-
1. enrich backend metadata for `log.write`
|
|
1161
|
-
2. build a generic schema-driven modal editor
|
|
1162
|
-
3. build a generic docs panel
|
|
1163
|
-
4. add one field-level override example
|
|
1164
|
-
5. only after that introduce full custom node editors if still necessary
|
|
1165
|
-
|
|
1166
|
-
---
|
|
1167
|
-
|
|
1168
|
-
## Pending Features And Open Decisions
|
|
1169
|
-
|
|
1170
|
-
These items are intentionally not fully implemented yet and should be treated as pending design or delivery work.
|
|
1171
|
-
|
|
1172
|
-
### Metrics persistence and observability
|
|
1173
|
-
|
|
1174
|
-
The current `metrics` metadata is useful as a node capability declaration, but it does not become operationally valuable until we choose how metrics are emitted and stored.
|
|
1175
|
-
|
|
1176
|
-
Current status:
|
|
1177
|
-
|
|
1178
|
-
- `WorkflowNodeMetricDefinition` documents what a node may measure
|
|
1179
|
-
- the runtime does not yet persist metrics into a dedicated table
|
|
1180
|
-
- the runtime does not yet publish metrics to a monitoring backend
|
|
1181
|
-
- the execution UI does not yet visualize metrics
|
|
1182
|
-
|
|
1183
|
-
Practical implication:
|
|
1184
|
-
|
|
1185
|
-
- today, `metrics` is mainly design metadata for docs and future observability
|
|
1186
|
-
- for production value, we need one or both of the following:
|
|
1187
|
-
- persist metrics in a workflow runtime table for querying and dashboards
|
|
1188
|
-
- emit metrics to an external observability system
|
|
1189
|
-
|
|
1190
|
-
Suggested next-step options:
|
|
1191
|
-
|
|
1192
|
-
1. Add a dedicated workflow execution metric table, for example `workflowExecutionMetric`
|
|
1193
|
-
2. Extend execution logs with metric-shaped entries as a simpler interim step
|
|
1194
|
-
3. Emit metrics to an external telemetry backend while keeping only summaries in SolidX
|
|
1195
|
-
|
|
1196
|
-
Recommended direction:
|
|
1197
|
-
|
|
1198
|
-
- keep `metrics` in the node contract now
|
|
1199
|
-
- treat runtime metric storage as a separate pending feature
|
|
1200
|
-
- avoid overbuilding the metrics UI before persistence/emission strategy is agreed
|
|
1201
|
-
|
|
1202
|
-
### Node metadata API
|
|
1203
|
-
|
|
1204
|
-
Pending:
|
|
1205
|
-
|
|
1206
|
-
- dedicated API endpoint for listing workflow node metadata for the editor
|
|
1207
|
-
- stable DTO mapping from provider metadata to client-safe response payloads
|
|
1208
|
-
|
|
1209
|
-
### Expression-aware autocomplete
|
|
1210
|
-
|
|
1211
|
-
Pending:
|
|
1212
|
-
|
|
1213
|
-
- Monaco autocomplete based on workflow DSL plus node metadata
|
|
1214
|
-
- expression suggestions for `inputs`, `outputs`, `execution`, `trigger`, and loop context
|
|
1215
|
-
|
|
1216
|
-
### Generic workflow docs renderer
|
|
1217
|
-
|
|
1218
|
-
Pending:
|
|
1219
|
-
|
|
1220
|
-
- reusable renderer for `summary`, `sections`, `examples`, `outputs`, `metrics`, and `definitions`
|
|
1221
|
-
- search/filter experience inside the Docs panel
|
|
1222
|
-
|
|
1223
|
-
### Flow editor integration
|
|
1224
|
-
|
|
1225
|
-
Pending:
|
|
1226
|
-
|
|
1227
|
-
- mapping `childSlots` metadata into React Flow containers and insertion affordances
|
|
1228
|
-
- node modal editor using schema-driven forms by default
|
|
1229
|
-
|
|
1230
|
-
### Blueprints
|
|
1231
|
-
|
|
1232
|
-
Pending:
|
|
1233
|
-
|
|
1234
|
-
- reintroduce `WorkflowBlueprint` as a first-class concept after the core definition/execution editor is stable
|
|
1235
|
-
- define blueprint metadata shape for starter workflows, tags, categories, and descriptions
|
|
1236
|
-
- decide whether blueprints live as:
|
|
1237
|
-
- dedicated persisted records
|
|
1238
|
-
- metadata-backed JSON assets only
|
|
1239
|
-
- or both
|
|
1240
|
-
- support blueprint browsing in the workflow editor
|
|
1241
|
-
- support “create from blueprint” flows
|
|
1242
|
-
- support core-provided and consuming-project-provided blueprint packs
|
|
1243
|
-
|
|
1244
|
-
Recommended direction:
|
|
1245
|
-
|
|
1246
|
-
- treat blueprints as curated starter workflows, not a separate execution concept
|
|
1247
|
-
- keep them aligned with the same workflow DSL as normal definitions
|
|
1248
|
-
- design the Blueprints panel after the node metadata API and generic docs renderer are in place
|
|
1249
|
-
- defer full blueprint management UX until the definition editor foundation is stable
|
|
1250
|
-
|
|
1251
|
-
---
|
|
1252
|
-
|
|
1253
|
-
## Final Guidance
|
|
1254
|
-
|
|
1255
|
-
This contract is intentionally designed so that:
|
|
1256
|
-
|
|
1257
|
-
- the backend describes node behavior and metadata
|
|
1258
|
-
- the frontend can render most nodes dynamically
|
|
1259
|
-
- `solid-core-ui` can ship polished defaults
|
|
1260
|
-
- consuming `solid-ui` projects can override only the pieces they need
|
|
1261
|
-
|
|
1262
|
-
That keeps the workflow system extensible without making every task implementation expensive.
|