@oomol-lab/open-flow 0.1.0-beta.75 → 0.1.0-beta.77

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.
Files changed (146) hide show
  1. package/README.md +3 -1
  2. package/dist/browser/{ContentIcon-FCpKiwjp.js → ContentIcon-VZQO8VZU.js} +9 -6
  3. package/dist/browser/{FlowCanvas-dzRBnlUT.js → FlowCanvas-BNGDMaWr.js} +75 -63
  4. package/dist/browser/{createResourceDialog-BeYDdUl-.js → createResourceDialog-BmtakfVg.js} +63 -57
  5. package/dist/browser/{dialog-ZtpsFbl4.js → dialog-BcFBfRB1.js} +126 -32
  6. package/dist/browser/{exportSvg-DqXw1yf-.js → exportSvg-CG8hEUNk.js} +2 -2
  7. package/dist/browser/{flowChanges-b_5UobFj.js → flowChanges-BGo_4Ypo.js} +6063 -11285
  8. package/dist/browser/{flowWorkspace-ItojZbO4.js → flowWorkspace-BFHGev7s.js} +1065 -2570
  9. package/dist/browser/preview.css +626 -653
  10. package/dist/browser/preview.js +1907 -9663
  11. package/dist/browser/theme.css +117 -263
  12. package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-BAWSUexx.js} +2 -2
  13. package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-CRoezJPN.js} +1 -1
  14. package/dist/browser/ui.css +464 -463
  15. package/dist/browser/ui.js +4 -3
  16. package/dist/browser/workbench.css +9891 -9897
  17. package/dist/browser/workbench.d.ts +6 -2
  18. package/dist/browser/workbench.js +838 -499
  19. package/dist/browser/{workbenchSelect-M441Lz0d.js → workbenchSelect-CjK-xdm3.js} +2 -2
  20. package/dist/command/index.js +48 -50
  21. package/dist/common/authoring.d.ts +5 -5
  22. package/dist/common/authoringExamples.d.ts +3 -2
  23. package/dist/common/authoringSchema.d.ts +26 -4
  24. package/dist/common/connector-proxy.d.ts +1 -1
  25. package/dist/common/control-api-conformance.js +352 -144
  26. package/dist/common/control-api-errors.d.ts +12 -0
  27. package/dist/common/control-api.d.ts +38 -4
  28. package/dist/common/control-api.js +373 -162
  29. package/dist/common/control-requests.d.ts +22 -3
  30. package/dist/common/control-requests.js +268 -28
  31. package/dist/common/cron-trigger.d.ts +2 -1
  32. package/dist/common/decision.d.ts +4 -4
  33. package/dist/common/decision.js +5 -2
  34. package/dist/common/engine-contract.d.ts +6 -1
  35. package/dist/common/event-source-definition.d.ts +1 -1
  36. package/dist/common/event-source-view.d.ts +22 -0
  37. package/dist/common/event-source.d.ts +1 -1
  38. package/dist/common/event-source.js +24 -65
  39. package/dist/common/event-sources.d.ts +0 -21
  40. package/dist/common/flow-authoring.js +90 -20
  41. package/dist/common/flow-change-schema.d.ts +9 -1
  42. package/dist/common/flow-change.d.ts +8 -202
  43. package/dist/common/flow-change.js +96 -24
  44. package/dist/common/flow-encoding.js +89 -21
  45. package/dist/common/flow-input-value.d.ts +1 -1
  46. package/dist/common/flow-model.d.ts +121 -0
  47. package/dist/common/flow-notifications.d.ts +1 -1
  48. package/dist/common/flow-retry.d.ts +2 -4
  49. package/dist/common/flow-semantics.js +161 -80
  50. package/dist/common/flow-state.d.ts +123 -0
  51. package/dist/common/flow-state.js +5852 -0
  52. package/dist/common/flow-workflowReferences.d.ts +8 -0
  53. package/dist/common/flowInspection.d.ts +1 -1
  54. package/dist/common/http-hosts.d.ts +6 -0
  55. package/dist/common/http-request.d.ts +13 -5
  56. package/dist/common/http-request.js +23 -5
  57. package/dist/common/integration-trigger.d.ts +2 -1
  58. package/dist/common/mcp.d.ts +96 -3
  59. package/dist/common/mcp.js +355 -142
  60. package/dist/common/openapi.d.ts +4 -4
  61. package/dist/common/openapi.js +4 -1
  62. package/dist/common/poll-trigger.d.ts +2 -1
  63. package/dist/common/run-events.js +1 -0
  64. package/dist/common/runtime-contract.d.ts +37 -1
  65. package/dist/common/runtime-contract.js +717 -72
  66. package/dist/common/runtime-nodejs-compat.d.ts +44 -0
  67. package/dist/common/runtime-nodejs-compat.js +5870 -0
  68. package/dist/common/scheduler-checkpoint.d.ts +1 -1
  69. package/dist/common/scheduler-node-execution.d.ts +2 -1
  70. package/dist/common/scheduler.d.ts +2 -2
  71. package/dist/common/scheduler.js +76 -6
  72. package/dist/common/state-conformance.d.ts +16 -0
  73. package/dist/common/tags.d.ts +4 -0
  74. package/dist/common/trigger-catalog.d.ts +1 -7
  75. package/dist/common/trigger-config-options.d.ts +1 -1
  76. package/dist/common/trigger-config.d.ts +1 -1
  77. package/dist/common/trigger-contract.d.ts +2 -1
  78. package/dist/common/trigger-localization.d.ts +8 -2
  79. package/dist/common/trigger-model.d.ts +101 -0
  80. package/dist/common/webhook-response.d.ts +1 -1
  81. package/dist/common/webhook-trigger.d.ts +3 -1
  82. package/dist/common/workflow.d.ts +3 -12
  83. package/dist/common/workflow.js +25 -23
  84. package/dist/index.d.ts +52 -14
  85. package/package.json +9 -1
  86. package/src/base/common/json.ts +1 -1
  87. package/src/connector/common/proxy.ts +1 -1
  88. package/src/control/common/api.ts +90 -16
  89. package/src/control/common/authoring.ts +6 -1
  90. package/src/control/common/authoringExamples.ts +8 -0
  91. package/src/control/common/authoringSchema.ts +26 -13
  92. package/src/control/common/authoringTools.ts +1 -1
  93. package/src/control/common/conformance.ts +1 -1
  94. package/src/control/common/connectorDecoders.ts +1 -1
  95. package/src/control/common/errors.ts +6 -0
  96. package/src/control/common/eventSources.ts +2 -29
  97. package/src/control/common/flowDecoders.ts +1 -0
  98. package/src/control/common/mcp.ts +16 -0
  99. package/src/control/common/requests.ts +10 -2
  100. package/src/control/common/tags.ts +20 -0
  101. package/src/control/common/triggerCatalog.ts +1 -8
  102. package/src/decision/common/decision.ts +15 -7
  103. package/src/event-source/common/definition.ts +1 -1
  104. package/src/event-source/common/index.ts +1 -1
  105. package/src/event-source/common/view.ts +20 -0
  106. package/src/execution/common/checkpoint.ts +1 -1
  107. package/src/execution/common/events.ts +3 -0
  108. package/src/execution/common/node-execution.ts +4 -1
  109. package/src/execution/common/scheduler.ts +3 -1
  110. package/src/flow/common/change.ts +60 -193
  111. package/src/flow/common/changeSchema.ts +39 -4
  112. package/src/flow/common/connectionUsage.ts +1 -1
  113. package/src/flow/common/errorHandling.ts +1 -1
  114. package/src/flow/common/inputValue.ts +1 -1
  115. package/src/flow/common/model.ts +130 -0
  116. package/src/flow/common/modules.ts +1 -1
  117. package/src/flow/common/portChanges.ts +1 -1
  118. package/src/flow/common/retry.ts +2 -4
  119. package/src/flow/common/semantics.ts +31 -4
  120. package/src/flow/common/webhookResponse.ts +1 -1
  121. package/src/flow/common/workflowReferences.ts +31 -0
  122. package/src/http/common/authBindings.ts +6 -9
  123. package/src/http/common/hosts.ts +13 -0
  124. package/src/http/common/httpRequest.ts +30 -15
  125. package/src/openapi/common/openapi.ts +9 -5
  126. package/src/{execution → runtime}/common/engineContract.ts +23 -15
  127. package/src/runtime/common/nodejsCompat.ts +275 -0
  128. package/src/runtime/common/nodejsGuest.generated.json +47 -0
  129. package/src/runtime/common/runtime.ts +1254 -0
  130. package/src/state/common/conformance.ts +86 -0
  131. package/src/state/common/state.ts +169 -0
  132. package/src/trigger/common/config.ts +1 -1
  133. package/src/trigger/common/configOptions.ts +1 -1
  134. package/src/trigger/common/contract.ts +2 -1
  135. package/src/trigger/common/cron.ts +2 -1
  136. package/src/trigger/common/integration.ts +2 -1
  137. package/src/trigger/common/model.ts +87 -0
  138. package/src/trigger/common/poll.ts +2 -1
  139. package/src/trigger/common/webhook.ts +3 -1
  140. package/src/trigger/providers/fieldDescriptions.ts +1 -1
  141. package/src/trigger/providers/localization.ts +9 -2
  142. package/src/trigger/providers/remote.ts +1 -1
  143. package/src/types/index.ts +55 -15
  144. package/src/workflow/common/workflow.ts +3 -44
  145. package/src/execution/common/runtime.ts +0 -563
  146. /package/src/{control → connector}/common/providerIconSprite.ts +0 -0
@@ -1,4 +1,4 @@
1
- import type { JsonValue } from '../../flow/common/change.ts'
1
+ import type { JsonValue } from '../../types/index.ts'
2
2
 
3
3
  export interface SourceConfiguration {
4
4
  readonly identity: string
@@ -1,9 +1,9 @@
1
1
  import type { EventSourceDefinition, SourceConfiguration } from './definition.ts'
2
2
 
3
3
  import { z } from 'zod'
4
- import { eventSourceViewSchema } from '../../control/common/eventSources.ts'
5
4
  import catalog from './catalog.generated.json' with { type: 'json' }
6
5
  import { SourceIdentityError } from './definition.ts'
6
+ import { eventSourceViewSchema } from './view.ts'
7
7
 
8
8
  export type {
9
9
  EventSourceDefinition,
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod'
2
+
3
+ const id = z.string().min(1).max(256)
4
+
5
+ /** Public projection of a source that Connector validates and Open Flow exposes unchanged. */
6
+ export const eventSourceViewSchema = z.object({
7
+ appId: id.nullable(),
8
+ workspaceId: id.optional(),
9
+ installationId: id.optional(),
10
+ organizationId: id.optional(),
11
+ projectId: id.optional(),
12
+ projectKey: id.optional(),
13
+ subscriptionStatus: z.enum(['idle', 'pending', 'ready', 'error']).optional(),
14
+ lastError: z.string().optional(),
15
+ signingSecretConfigured: z.boolean().optional(),
16
+ manageSubscriptions: z.boolean().nullable(),
17
+ verificationTokenConfigured: z.boolean().nullable(),
18
+ encryptKeyConfigured: z.boolean().nullable(),
19
+ verifiedAt: z.string().nullable(),
20
+ })
@@ -1,7 +1,7 @@
1
1
  import type { Graph, JsonValue } from '../../flow/common/change.ts'
2
+ import type { AgentCheckpoint } from '../../runtime/common/runtime.ts'
2
3
  import type { DependenciesCheckpoint } from './dependencies.ts'
3
4
  import type { ExecutableNode } from './node-execution.ts'
4
- import type { AgentCheckpoint } from './runtime.ts'
5
5
 
6
6
  import { z } from 'zod'
7
7
  import { isTriggerNode } from '../../flow/common/change.ts'
@@ -23,6 +23,7 @@ const nodeKinds = new Set([
23
23
  'javascript',
24
24
  'openapi',
25
25
  'http-request',
26
+ 'dedupe',
26
27
  'llm',
27
28
  'value',
28
29
  'wait',
@@ -56,6 +57,7 @@ function nodeKind(
56
57
  | 'javascript'
57
58
  | 'openapi'
58
59
  | 'http-request'
60
+ | 'dedupe'
59
61
  | 'llm'
60
62
  | 'value'
61
63
  | 'wait'
@@ -76,6 +78,7 @@ function nodeKind(
76
78
  | 'javascript'
77
79
  | 'openapi'
78
80
  | 'http-request'
81
+ | 'dedupe'
79
82
  | 'llm'
80
83
  | 'value'
81
84
  | 'wait'
@@ -1,9 +1,9 @@
1
1
  import type { AgentConfig } from '../../flow/common/agent.ts'
2
2
  import type { Graph, GraphNode, InputMapping, InputPortDefinition, JsonValue, TriggerNode } from '../../flow/common/change.ts'
3
3
  import type { WebhookResponseSnapshot } from '../../flow/common/webhookResponse.ts'
4
+ import type { AgentCheckpoint, AgentResult } from '../../runtime/common/runtime.ts'
4
5
  import type { FlowRunCheckpoint } from './checkpoint.ts'
5
6
  import type { Dependencies } from './dependencies.ts'
6
- import type { AgentCheckpoint, AgentResult } from './runtime.ts'
7
7
  import type { FlowRunOptions, SchedulerEvent, SchedulerFailure, TaskInvocation } from './scheduler.ts'
8
8
 
9
9
  import * as Effect from 'effect/Effect'
@@ -109,6 +109,7 @@ function nodeKind(
109
109
  | 'javascript'
110
110
  | 'openapi'
111
111
  | 'http-request'
112
+ | 'dedupe'
112
113
  | 'llm'
113
114
  | 'value'
114
115
  | 'wait'
@@ -301,6 +302,7 @@ export function executeNode(
301
302
  readonly node: ExecutableNode
302
303
  readonly jobId: string
303
304
  readonly nodeInputs: Readonly<Record<string, JsonValue>>
305
+ readonly launchInputs?: Readonly<Record<string, JsonValue>>
304
306
  readonly flowId: string
305
307
  readonly runId: string
306
308
  readonly graph: Graph
@@ -368,6 +370,7 @@ export function executeNode(
368
370
  if (additional.has(handle)) return false
369
371
  const task = 'executor' in node.task ? node.task : undefined
370
372
  if (task == null || !['openapi', 'http-request'].includes(task.executor.kind)) return true
373
+ if (Object.hasOwn(input.launchInputs ?? {}, handle)) return true
371
374
  const mapping = node.inputs[handle]
372
375
  return (
373
376
  mapping?.kind != 'unset' &&
@@ -2,10 +2,10 @@ import type { TaskCapability, Graph, JsonValue, WaitAction, WaitAutoContinue } f
2
2
  import type { NodeErrorData } from '../../flow/common/errorHandling.ts'
3
3
  import type { PreparedFlow } from '../../flow/common/semantics.ts'
4
4
  import type { WebhookResponseSnapshot } from '../../flow/common/webhookResponse.ts'
5
+ import type { AgentCheckpoint } from '../../runtime/common/runtime.ts'
5
6
  import type { PreviousNode } from '../../types/index.ts'
6
7
  import type { FlowRunCheckpoint } from './checkpoint.ts'
7
8
  import type { ExecutableNode, NodeResult } from './node-execution.ts'
8
- import type { AgentCheckpoint } from './runtime.ts'
9
9
 
10
10
  import * as Cause from 'effect/Cause'
11
11
  import * as Clock from 'effect/Clock'
@@ -70,6 +70,7 @@ export type SchedulerEvent =
70
70
  | 'javascript'
71
71
  | 'openapi'
72
72
  | 'http-request'
73
+ | 'dedupe'
73
74
  | 'llm'
74
75
  | 'value'
75
76
  | 'wait'
@@ -344,6 +345,7 @@ function runGraph(
344
345
  node,
345
346
  jobId,
346
347
  nodeInputs,
348
+ launchInputs: launch[nodeId],
347
349
  resolution,
348
350
  flowId: target.flowId,
349
351
  runId,
@@ -1,12 +1,27 @@
1
- import type { JsonValue, Port, PortDefinition } from '../../types/index.ts'
1
+ import type { TriggerNode, TriggerSchedule } from '../../trigger/common/model.ts'
2
+ import type {
3
+ CodeModule,
4
+ ConnectorCapability,
5
+ FixedInputValue,
6
+ GraphNodeBase,
7
+ InlineTaskDefinition,
8
+ InputMapping,
9
+ InputPort,
10
+ JsonValue,
11
+ ManagedTaskDefinitionOf,
12
+ RetryConfiguration,
13
+ Port,
14
+ Source,
15
+ TaskCapability,
16
+ WorkflowCapability,
17
+ WorkflowExecutor,
18
+ } from './model.ts'
2
19
 
3
- import { assertHttpAuthBindings } from '../../http/common/authBindings.ts'
4
20
  export { fixedInputValue, inputValue, inputValues } from './inputValue.ts'
5
- import type { RetryConfiguration } from './retry.ts'
6
21
  import type { WebhookMethod } from './webhookMethod.ts'
7
22
 
8
23
  import { dequal } from 'dequal/lite'
9
- import { authoringDefinitionSchemas, currentFlowModelVersion, decodeRevisionContent } from './changeSchema.ts'
24
+ import { assertDocumentHttpAuthBindings, authoringDefinitionSchemas, currentFlowModelVersion, decodeRevisionContent } from './changeSchema.ts'
10
25
  import { nodeInputMappings, setConditionInput } from './condition.ts'
11
26
  import { supportsNodeErrorHandling } from './errorHandling.ts'
12
27
  import { supportsNodeRetry } from './retry.ts'
@@ -18,7 +33,39 @@ export { nodeSystemOutputPorts, supportsNodeErrorHandling, nodeErrorSchema } fro
18
33
  export type { NodeErrorData } from './errorHandling.ts'
19
34
  export type { WebhookMethod }
20
35
 
21
- export type { JsonValue, Port, PortDefinition } from '../../types/index.ts'
36
+ export type {
37
+ BindingSource,
38
+ CodeModule,
39
+ ConnectorAccessCapability,
40
+ ConnectorActionCapability,
41
+ ConnectorCapability,
42
+ ConnectorPermissionCapability,
43
+ FixedInputValue,
44
+ Group,
45
+ InlineTaskDefinition,
46
+ InputMapping,
47
+ InputPort,
48
+ InputPortDefinition,
49
+ InputValues,
50
+ JsonValue,
51
+ NodeSource,
52
+ Port,
53
+ PortDefinition,
54
+ Source,
55
+ TaskCapability,
56
+ WorkflowCapability,
57
+ } from './model.ts'
58
+ export { portsByHandle } from './model.ts'
59
+ export type {
60
+ IntegrationBodyFormat,
61
+ IntegrationEndpointDeclaration,
62
+ IntegrationEndpointMethod,
63
+ TriggerKeySnapshot,
64
+ TriggerNode,
65
+ TriggerSchedule,
66
+ WebhookBodyField,
67
+ WebhookOptions,
68
+ } from '../../trigger/common/model.ts'
22
69
 
23
70
  export { isSchemaKeyword } from './schemaKeywords.ts'
24
71
  export type { SchemaKeyword, SchemaMismatch } from './schemaKeywords.ts'
@@ -42,52 +89,6 @@ export function validVariableName(value: string): boolean {
42
89
  return value.length <= 256 && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value) && value.slice(0, 3).toUpperCase() != 'OO_'
43
90
  }
44
91
 
45
- export interface InputPortDefinition extends PortDefinition {
46
- readonly value?: JsonValue
47
- }
48
-
49
- export interface InputPort extends InputPortDefinition {
50
- readonly handle: string
51
- }
52
-
53
- export interface Group {
54
- readonly collapsed?: boolean
55
- readonly group: string
56
- }
57
-
58
- export function portsByHandle<Value extends Port>(ports: readonly (Value | Group)[]): Readonly<Record<string, Value>> {
59
- return Object.fromEntries(ports.flatMap((port) => ('handle' in port ? [[port.handle, port]] : [])))
60
- }
61
-
62
- export interface NodeSource {
63
- readonly system?: true
64
- readonly field?: string
65
- readonly kind: 'node'
66
- readonly nodeId: string
67
- readonly output: string
68
- }
69
-
70
- export interface BindingSource {
71
- readonly bindingId: string
72
- readonly kind: 'binding'
73
- }
74
-
75
- export type FixedInputValue = { readonly kind: 'unset' } | { readonly kind: 'value'; readonly value: JsonValue }
76
- export type InputValues = Readonly<Record<string, FixedInputValue>>
77
-
78
- export type InputMapping = FixedInputValue | { readonly kind: 'sources'; readonly sources: readonly (BindingSource | NodeSource)[] }
79
-
80
- interface GraphNodeBase {
81
- readonly description?: string
82
- readonly icon?: string
83
- readonly inputs: Readonly<Record<string, InputMapping>>
84
- readonly name?: string
85
- readonly maxExecutions?: number
86
- readonly timeoutMs?: number
87
- readonly retry?: RetryConfiguration
88
- readonly onError?: 'stop' | 'error'
89
- }
90
-
91
92
  export interface ValueNode extends GraphNodeBase {
92
93
  readonly kind: 'value'
93
94
  readonly values: readonly InputPort[]
@@ -138,8 +139,6 @@ export type ConditionOperator =
138
139
  | 'notHasValue'
139
140
  | 'startsWith'
140
141
 
141
- export type Source = BindingSource | NodeSource
142
-
143
142
  export type ConditionOperand =
144
143
  | { readonly kind: 'value'; readonly value?: JsonValue; readonly jsonSchema?: JsonValue }
145
144
  | { readonly kind: 'source'; readonly source: Source }
@@ -168,7 +167,8 @@ export interface ConditionNode extends GraphNodeBase {
168
167
 
169
168
  export type ManagedTaskExecutor =
170
169
  | import('../../http/common/httpRequest.ts').HttpRequestExecutor
171
- | import('../../workflow/common/workflow.ts').WorkflowExecutor
170
+ | import('../../state/common/state.ts').DedupeExecutor
171
+ | WorkflowExecutor
172
172
  | import('../../decision/common/decision.ts').DecisionExecutor
173
173
  | import('../../openapi/common/openapi.ts').OpenApiExecutor
174
174
  | { readonly kind: 'connector'; readonly action: string; readonly connectionId?: string; readonly outputMode?: 'value' }
@@ -205,23 +205,12 @@ export interface AgentConnectorTool extends AgentToolBase {
205
205
  readonly connectionId?: string
206
206
  }
207
207
 
208
- export interface WorkflowCapability {
209
- readonly kind: 'workflow'
210
- readonly name: string
211
- readonly flowId: string
212
- readonly revisionId: string
213
- readonly inputs: readonly Port[]
214
- readonly outputs: readonly Port[] | null
215
- }
216
-
217
208
  export interface AgentWorkflowTool extends AgentToolBase, Omit<WorkflowCapability, 'inputs'> {
218
209
  readonly action?: never
219
210
  readonly connectionId?: never
220
211
  }
221
212
 
222
213
  export type AgentTool = AgentConnectorTool | AgentWorkflowTool
223
- export type TaskCapability = ConnectorCapability | WorkflowCapability
224
-
225
214
  export const workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/
226
215
 
227
216
  export function workflowToolNameIssue(name: string, otherNames: Iterable<string> = []): 'invalid' | 'duplicate' | undefined {
@@ -239,33 +228,13 @@ export function decodeTaskCapabilities(value: unknown): readonly TaskCapability[
239
228
  if (workflowToolNameIssue(item.name, names)) throw new TypeError('Workflow tool names must be unique provider-compatible names.')
240
229
  names.add(item.name)
241
230
  }
231
+ const http = parsed.filter((item) => item.kind == 'http')
232
+ if (http.length > 1 || http.some((item) => new Set(item.hosts).size != item.hosts.length))
233
+ throw new TypeError('Code declares HTTP hosts once, without duplicates.')
242
234
  let connectorIndex = 0
243
235
  return parsed.map((item) => (item.kind == 'connector' ? connectors[connectorIndex++]! : item)) as readonly TaskCapability[]
244
236
  }
245
237
 
246
- export interface ConnectorAccessCapability {
247
- readonly actionHints?: readonly string[]
248
- readonly connectionHints?: readonly {
249
- readonly action: string
250
- readonly connectionId: string
251
- readonly alias?: string
252
- }[]
253
- readonly kind: 'connector'
254
- }
255
-
256
- export interface ConnectorActionCapability {
257
- readonly action: string
258
- readonly connections: readonly { readonly connectionId: string; readonly alias?: string }[]
259
- readonly connectionId?: string
260
- readonly kind: 'connector'
261
- }
262
-
263
- export type ConnectorPermissionCapability =
264
- | { readonly kind: 'connector'; readonly mode: 'shared' }
265
- | { readonly kind: 'connector'; readonly mode: 'independent'; readonly actions: readonly { readonly action: string; readonly connectionId?: string }[] }
266
-
267
- export type ConnectorCapability = ConnectorAccessCapability | ConnectorActionCapability | ConnectorPermissionCapability
268
-
269
238
  export function decodeConnectorCapabilities(value: unknown): readonly ConnectorCapability[] {
270
239
  if (!Array.isArray(value)) throw new TypeError('Connector capabilities must be an array.')
271
240
  if (value.length == 0) return []
@@ -389,20 +358,7 @@ export function decodeConnectorCapabilities(value: unknown): readonly ConnectorC
389
358
  })
390
359
  }
391
360
 
392
- interface TaskDefinitionBase {
393
- readonly inputs: readonly (InputPort | Group)[]
394
- readonly name: string
395
- readonly outputs: readonly (Port | Group)[]
396
- }
397
-
398
- export interface InlineTaskDefinition extends TaskDefinitionBase {
399
- readonly capabilities?: readonly TaskCapability[]
400
- readonly moduleId: string
401
- }
402
-
403
- export interface ManagedTaskDefinition extends TaskDefinitionBase {
404
- readonly executor: ManagedTaskExecutor
405
- }
361
+ export type ManagedTaskDefinition = ManagedTaskDefinitionOf<ManagedTaskExecutor>
406
362
 
407
363
  export type TaskDefinition = InlineTaskDefinition | ManagedTaskDefinition
408
364
 
@@ -417,89 +373,6 @@ export interface Graph {
417
373
  readonly nodes: Readonly<Record<string, GraphNode>>
418
374
  }
419
375
 
420
- export type TriggerSchedule =
421
- | { readonly expression: string; readonly timezone: string; readonly type: 'cron' }
422
- | { readonly type: 'every'; readonly unit: 'day' | 'hour' | 'minute' | 'month' | 'week'; readonly value: number }
423
-
424
- interface TriggerKeySnapshotBase {
425
- readonly configInputs: readonly (InputPort | Group)[]
426
- readonly definitionVersion: number
427
- readonly description: string
428
- readonly displayName: string
429
- readonly key: string
430
- readonly name: string
431
- readonly outputs: readonly Port[]
432
- readonly provider: string
433
- }
434
-
435
- export type IntegrationEndpointMethod = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT'
436
-
437
- export type IntegrationBodyFormat = 'form' | 'json' | 'multipart' | 'text'
438
-
439
- export interface IntegrationEndpointDeclaration {
440
- readonly body: {
441
- readonly allowArray: boolean
442
- readonly allowEmpty: boolean
443
- readonly formats: readonly IntegrationBodyFormat[]
444
- }
445
- readonly methods: readonly IntegrationEndpointMethod[]
446
- readonly successStatus: number
447
- }
448
-
449
- export type TriggerKeySnapshot =
450
- | (TriggerKeySnapshotBase & { readonly type: 'poll' })
451
- | (TriggerKeySnapshotBase & { readonly endpoint: IntegrationEndpointDeclaration; readonly type: 'integration' })
452
-
453
- export interface WebhookBodyField extends InputPort {}
454
-
455
- export interface WebhookOptions {
456
- readonly allowedOrigins?: readonly string[]
457
- readonly responseBody?:
458
- | { readonly kind: 'workflow-outputs'; readonly output?: string; readonly timeoutMs?: number }
459
- | { readonly kind: 'webhook-response'; readonly nodeId?: string; readonly timeoutMs?: number }
460
- readonly responseData?: string
461
- readonly responseHeaders?: Readonly<Record<string, string>>
462
- readonly responseHeadersSource?: {
463
- readonly kind: 'workflow-outputs'
464
- readonly output?: string
465
- }
466
- readonly responseHeaderOutputs?: Readonly<Record<string, string>>
467
- readonly responseStatusCode?: number
468
- readonly responseStatusCodeOutput?: string
469
- }
470
-
471
- interface TriggerNodeBase {
472
- readonly onError?: never
473
- readonly description?: string
474
- readonly icon?: string
475
- readonly name: string
476
- }
477
-
478
- export type TriggerNode =
479
- | (TriggerNodeBase & { readonly kind: 'manual' })
480
- | (TriggerNodeBase & { readonly kind: 'start'; readonly inputDefs: readonly Port[] })
481
- | (TriggerNodeBase & { readonly kind: 'error'; readonly sourceFlowIds?: readonly string[] })
482
- | (TriggerNodeBase & {
483
- readonly bodyFields: readonly WebhookBodyField[]
484
- readonly kind: 'webhook'
485
- readonly method: WebhookMethod
486
- readonly options?: WebhookOptions
487
- })
488
- | (TriggerNodeBase & { readonly cronTimes: readonly TriggerSchedule[]; readonly kind: 'cron' })
489
- | (TriggerNodeBase & {
490
- readonly connectionId?: string
491
- readonly config: InputValues
492
- readonly definition: TriggerKeySnapshot & { readonly type: 'poll' }
493
- readonly kind: 'poll'
494
- readonly pollTimes: readonly TriggerSchedule[]
495
- })
496
- | (TriggerNodeBase & {
497
- readonly connectionId?: string
498
- readonly config: InputValues
499
- readonly definition: TriggerKeySnapshot & { readonly type: 'integration' }
500
- readonly kind: 'integration'
501
- })
502
-
503
376
  export interface OutputsNode extends Omit<GraphNodeBase, 'inputs'> {
504
377
  readonly kind: 'outputs'
505
378
  readonly outputDefs: readonly Port[]
@@ -523,15 +396,9 @@ export interface FlowDocument {
523
396
  readonly graph: Graph
524
397
  }
525
398
 
526
- export interface CodeModule {
527
- readonly imports: readonly string[]
528
- readonly name: string
529
- readonly source: string
530
- }
531
-
532
399
  export interface RevisionContent {
533
400
  readonly document: FlowDocument
534
- readonly modelVersion: 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | typeof currentFlowModelVersion
401
+ readonly modelVersion: 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | typeof currentFlowModelVersion
535
402
  readonly modules: Readonly<Record<string, CodeModule>>
536
403
  }
537
404
 
@@ -1032,6 +899,6 @@ export function applyFlowChanges(content: RevisionContent, operations: readonly
1032
899
  }
1033
900
  }
1034
901
  }
1035
- assertHttpAuthBindings(document)
902
+ assertDocumentHttpAuthBindings(document)
1036
903
  return upgradeDecodedRevisionContent({ document, modelVersion: currentFlowModelVersion, modules })
1037
904
  }
@@ -4,7 +4,9 @@ import { dequal } from 'dequal/lite'
4
4
  import { z } from 'zod'
5
5
  import { limitDecisionTask } from '../../decision/common/decision.ts'
6
6
  import { assertHttpAuthBindings } from '../../http/common/authBindings.ts'
7
+ import { isHttpHost, maxHttpHosts } from '../../http/common/hosts.ts'
7
8
  import { httpRequestExecutorSchema } from '../../http/common/httpRequest.ts'
9
+ import { dedupeExecutorSchema } from '../../state/common/state.ts'
8
10
  import { checkJsonDepth } from './json.ts'
9
11
  import { retryConfigurationSchema } from './retry.ts'
10
12
  import { triggerScheduleSchema } from './triggerScheduleSchema.ts'
@@ -12,7 +14,7 @@ import { waitAutoContinueDraftSchema, waitAutoContinueSchema } from './wait.ts'
12
14
  import { webhookMethods } from './webhookMethod.ts'
13
15
  import { webhookResponseTimeout } from './webhookResponse.ts'
14
16
 
15
- export const currentFlowModelVersion = 11
17
+ export const currentFlowModelVersion = 13
16
18
  const text = z.string()
17
19
  const actionConnection = text.describe(
18
20
  'Account selection: omit while unconfigured; use an account ID to select it; use "" to explicitly defer configuration. Deferred Actions fail if called; deferred Agent tools are excluded from the callable tool set. Not supported by Triggers.',
@@ -57,7 +59,15 @@ export const workflowCapabilitySchema = z.strictObject({
57
59
  inputs: z.array(port),
58
60
  outputs: z.array(port).nullable(),
59
61
  })
60
- const capability = z.union([connectorCapabilitySchema, workflowCapabilitySchema])
62
+ export const httpCapabilitySchema = z.strictObject({
63
+ kind: z.literal('http'),
64
+ hosts: z
65
+ .array(text.refine(isHttpHost, 'Use a lowercase host name or IPv4 address, optionally prefixed by "*." for subdomains.'))
66
+ .min(1)
67
+ .max(maxHttpHosts)
68
+ .describe('Hosts Code may call with context.fetch. "*.example.com" matches subdomains only.'),
69
+ })
70
+ const capability = z.union([connectorCapabilitySchema, workflowCapabilitySchema, httpCapabilitySchema])
61
71
  const inline = z.object({ ...ports, name: text, moduleId: text, capabilities: z.array(capability).optional() })
62
72
  const agentValue = z.union([z.object({ kind: z.literal('value'), value: json }), z.object({ kind: z.literal('input'), input: text })])
63
73
  const agentInput = z.union([agentValue, z.object({ kind: z.literal('model') })])
@@ -120,6 +130,7 @@ const managedFields = z.object({
120
130
  }),
121
131
  z.strictObject({ kind: z.literal('workflow'), flowId: text, revisionId: text }),
122
132
  httpRequestExecutorSchema,
133
+ dedupeExecutorSchema,
123
134
  ]),
124
135
  })
125
136
 
@@ -308,6 +319,8 @@ const revision = z.object({
308
319
  z.literal(8),
309
320
  z.literal(9),
310
321
  z.literal(10),
322
+ z.literal(11),
323
+ z.literal(12),
311
324
  z.literal(currentFlowModelVersion),
312
325
  ]),
313
326
  document,
@@ -593,7 +606,7 @@ export function decodeRevisionContent(value: unknown): RevisionContent {
593
606
  checkJsonDepth(value)
594
607
  const content = revision.parse(value) as RevisionContent
595
608
  checkModelVersion(content)
596
- assertHttpAuthBindings(content.document)
609
+ assertDocumentHttpAuthBindings(content.document)
597
610
  return content
598
611
  }
599
612
 
@@ -603,7 +616,7 @@ export function decodeRevisionEnvelope(value: unknown): RevisionContent {
603
616
  const candidate = revisionSource.modelVersion == 2 ? { ...revisionSource, document: upgradeLegacyDocument(revisionSource.document) } : value
604
617
  const content = envelope.parse(candidate) as RevisionContent
605
618
  checkModelVersion(content)
606
- assertHttpAuthBindings(content.document)
619
+ assertDocumentHttpAuthBindings(content.document)
607
620
  return { modelVersion: content.modelVersion, document: content.document, modules: content.modules }
608
621
  }
609
622
 
@@ -713,6 +726,21 @@ export function changeOperationsSchema(kind?: string): JsonValue {
713
726
  }
714
727
 
715
728
  function checkModelVersion(content: RevisionContent): void {
729
+ if (
730
+ content.modelVersion < 13 &&
731
+ Object.values(content.document.graph.nodes).some(
732
+ (candidateNode) => candidateNode.kind === 'task' && 'executor' in candidateNode.task && candidateNode.task.executor.kind === 'dedupe',
733
+ )
734
+ )
735
+ throw new Error('Deduplication requires Flow model v13.')
736
+ if (
737
+ content.modelVersion < 12 &&
738
+ Object.values(content.document.graph.nodes).some(
739
+ (candidateNode) =>
740
+ candidateNode.kind == 'task' && 'moduleId' in candidateNode.task && candidateNode.task.capabilities?.some((item) => item.kind == 'http'),
741
+ )
742
+ )
743
+ throw new TypeError('Code HTTP access requires Flow model version 12.')
716
744
  if (
717
745
  content.modelVersion < 11 &&
718
746
  Object.values(content.document.graph.nodes).some(
@@ -790,3 +818,10 @@ function checkModelVersion(content: RevisionContent): void {
790
818
  if (content.modelVersion < 5 && Object.values(content.document.graph.nodes).some((itemNode) => itemNode.kind == 'error'))
791
819
  throw new TypeError('Error workflows require Flow model version 5.')
792
820
  }
821
+
822
+ export function assertDocumentHttpAuthBindings(content: FlowDocument): void {
823
+ for (const graphNode of Object.values(content.graph.nodes)) {
824
+ if (graphNode.kind == 'task' && 'executor' in graphNode.task && ['openapi', 'http-request'].includes(graphNode.task.executor.kind))
825
+ assertHttpAuthBindings(graphNode.inputs)
826
+ }
827
+ }
@@ -93,7 +93,7 @@ export function clearNodeConnections(graph: FlowDocument['graph'], connectionId?
93
93
  return [id, node]
94
94
  }
95
95
  const capabilities = node.task.capabilities?.map((capability) => {
96
- if (capability.kind == 'workflow') return capability
96
+ if (capability.kind == 'workflow' || capability.kind == 'http') return capability
97
97
  if (!('mode' in capability)) {
98
98
  if ('action' in capability) {
99
99
  const { connectionId: selected, ...rest } = capability
@@ -26,7 +26,7 @@ export const nodeErrorSchema = {
26
26
  } as const
27
27
 
28
28
  export function supportsNodeErrorHandling(node: GraphNode): boolean {
29
- return supportsNodeRetry(node)
29
+ return supportsNodeRetry(node) || (node.kind === 'task' && 'executor' in node.task && node.task.executor.kind === 'dedupe')
30
30
  }
31
31
 
32
32
  export function nodeSystemOutputPorts(node: GraphNode): Readonly<Record<string, PortDefinition>> {
@@ -1,4 +1,4 @@
1
- import type { FixedInputValue, InputValues, InputMapping, JsonValue } from './change.ts'
1
+ import type { FixedInputValue, InputValues, InputMapping, JsonValue } from './model.ts'
2
2
 
3
3
  /** An explicit clear suppresses the default; absent mappings still inherit it. */
4
4
  export function inputValue(mapping: InputMapping | undefined, fallback: JsonValue | undefined): JsonValue | undefined {