@oomol-lab/open-flow 0.1.0-beta.74 → 0.1.0-beta.76

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 (139) hide show
  1. package/README.md +3 -1
  2. package/dist/browser/{ContentIcon-CUQHjQIw.js → ContentIcon-Cm1hbVzW.js} +4 -3
  3. package/dist/browser/{FlowCanvas-Dtf8_cQp.js → FlowCanvas-NzKtla_c.js} +62 -62
  4. package/dist/browser/{createResourceDialog-DI9pL-Yr.js → createResourceDialog-BgdedQqu.js} +3 -3
  5. package/dist/browser/{dialog-BYJGvItc.js → dialog-aSElFFw2.js} +322 -26
  6. package/dist/browser/{exportSvg-BOoy7-Db.js → exportSvg-Dcz4HTo_.js} +2 -2
  7. package/dist/browser/{flowChanges-RL-H4CjD.js → flowChanges-NZyS7HSp.js} +490 -438
  8. package/dist/browser/{flowWorkspace-BkDsETj0.js → flowWorkspace-Bl0SDehy.js} +499 -61
  9. package/dist/browser/preview.css +696 -825
  10. package/dist/browser/preview.js +1399 -717
  11. package/dist/browser/theme.css +114 -262
  12. package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-3XMK9jkr.js} +1 -1
  13. package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-C9sBGOKZ.js} +1 -1
  14. package/dist/browser/ui.css +354 -460
  15. package/dist/browser/ui.js +1 -1
  16. package/dist/browser/workbench.css +696 -825
  17. package/dist/browser/workbench.js +13 -7
  18. package/dist/browser/{workbenchSelect-BcWPWGzw.js → workbenchSelect-DBGP7Y4Z.js} +2 -2
  19. package/dist/command/index.js +41 -43
  20. package/dist/common/authoring.d.ts +5 -5
  21. package/dist/common/authoringExamples.d.ts +3 -2
  22. package/dist/common/authoringSchema.d.ts +70 -4
  23. package/dist/common/connector-proxy.d.ts +1 -1
  24. package/dist/common/control-api-conformance.js +250 -138
  25. package/dist/common/control-api.d.ts +3 -2
  26. package/dist/common/control-api.js +246 -134
  27. package/dist/common/control-requests.d.ts +3 -3
  28. package/dist/common/control-requests.js +353 -79
  29. package/dist/common/cron-trigger.d.ts +2 -1
  30. package/dist/common/decision.d.ts +4 -4
  31. package/dist/common/decision.js +5 -2
  32. package/dist/common/engine-contract.d.ts +6 -1
  33. package/dist/common/event-source-definition.d.ts +1 -1
  34. package/dist/common/event-source-view.d.ts +22 -0
  35. package/dist/common/event-source.d.ts +1 -1
  36. package/dist/common/event-source.js +24 -65
  37. package/dist/common/event-sources.d.ts +0 -21
  38. package/dist/common/flow-authoring.js +90 -19
  39. package/dist/common/flow-change-schema.d.ts +9 -1
  40. package/dist/common/flow-change.d.ts +7 -201
  41. package/dist/common/flow-change.js +96 -23
  42. package/dist/common/flow-encoding.js +89 -21
  43. package/dist/common/flow-graph.d.ts +2 -1
  44. package/dist/common/flow-input-value.d.ts +1 -1
  45. package/dist/common/flow-model.d.ts +121 -0
  46. package/dist/common/flow-notifications.d.ts +1 -1
  47. package/dist/common/flow-retry.d.ts +3 -5
  48. package/dist/common/flow-semantics.js +816 -586
  49. package/dist/common/flow-workflowReferences.d.ts +8 -0
  50. package/dist/common/flowInspection.d.ts +1 -1
  51. package/dist/common/http-hosts.d.ts +6 -0
  52. package/dist/common/http-request.d.ts +164 -0
  53. package/dist/common/http-request.js +5272 -0
  54. package/dist/common/integration-trigger.d.ts +2 -1
  55. package/dist/common/mcp.d.ts +3 -3
  56. package/dist/common/mcp.js +248 -136
  57. package/dist/common/openapi.d.ts +4 -4
  58. package/dist/common/openapi.js +4 -1
  59. package/dist/common/poll-trigger.d.ts +2 -1
  60. package/dist/common/run-events.js +11 -9
  61. package/dist/common/runtime-contract.d.ts +23 -1
  62. package/dist/common/runtime-contract.js +607 -72
  63. package/dist/common/runtime-nodejs-compat.d.ts +44 -0
  64. package/dist/common/runtime-nodejs-compat.js +5870 -0
  65. package/dist/common/scheduler-checkpoint.d.ts +1 -1
  66. package/dist/common/scheduler-node-execution.d.ts +1 -1
  67. package/dist/common/scheduler.d.ts +2 -2
  68. package/dist/common/scheduler.js +95 -25
  69. package/dist/common/trigger-catalog.d.ts +1 -7
  70. package/dist/common/trigger-config-options.d.ts +1 -1
  71. package/dist/common/trigger-config.d.ts +1 -1
  72. package/dist/common/trigger-contract.d.ts +2 -1
  73. package/dist/common/trigger-localization.d.ts +8 -2
  74. package/dist/common/trigger-model.d.ts +101 -0
  75. package/dist/common/webhook-response.d.ts +1 -3
  76. package/dist/common/webhook-trigger.d.ts +3 -1
  77. package/dist/common/webhook-trigger.js +12 -11
  78. package/dist/common/workflow.d.ts +3 -12
  79. package/dist/common/workflow.js +25 -23
  80. package/dist/index.d.ts +41 -14
  81. package/package.json +9 -1
  82. package/skills/open-flow/references/flow-authoring.md +1 -0
  83. package/skills/open-flow/references/flow-n8n-conversion.md +19 -15
  84. package/src/base/common/json.ts +1 -1
  85. package/src/connector/common/proxy.ts +1 -1
  86. package/src/control/common/api.ts +7 -5
  87. package/src/control/common/authoring.ts +14 -3
  88. package/src/control/common/authoringExamples.ts +8 -0
  89. package/src/control/common/authoringSchema.ts +38 -25
  90. package/src/control/common/authoringTools.ts +1 -1
  91. package/src/control/common/conformance.ts +1 -1
  92. package/src/control/common/connectorDecoders.ts +1 -1
  93. package/src/control/common/eventSources.ts +2 -29
  94. package/src/control/common/triggerCatalog.ts +1 -8
  95. package/src/decision/common/decision.ts +15 -7
  96. package/src/event-source/common/definition.ts +1 -1
  97. package/src/event-source/common/index.ts +1 -1
  98. package/src/event-source/common/view.ts +20 -0
  99. package/src/execution/common/checkpoint.ts +1 -1
  100. package/src/execution/common/events.ts +3 -0
  101. package/src/execution/common/node-execution.ts +5 -3
  102. package/src/execution/common/scheduler.ts +2 -1
  103. package/src/flow/common/change.ts +59 -192
  104. package/src/flow/common/changeSchema.ts +39 -5
  105. package/src/flow/common/connectionUsage.ts +1 -1
  106. package/src/flow/common/graph.ts +10 -4
  107. package/src/flow/common/inputValue.ts +1 -1
  108. package/src/flow/common/model.ts +130 -0
  109. package/src/flow/common/modules.ts +1 -1
  110. package/src/flow/common/portChanges.ts +1 -1
  111. package/src/flow/common/retry.ts +3 -5
  112. package/src/flow/common/semantics.ts +71 -7
  113. package/src/flow/common/webhookResponse.ts +4 -8
  114. package/src/flow/common/workflowReferences.ts +31 -0
  115. package/src/http/common/authBindings.ts +9 -0
  116. package/src/http/common/headers.ts +5 -0
  117. package/src/http/common/hosts.ts +13 -0
  118. package/src/http/common/httpRequest.ts +266 -0
  119. package/src/openapi/common/openapi.ts +9 -5
  120. package/src/{execution → runtime}/common/engineContract.ts +24 -15
  121. package/src/runtime/common/nodejsCompat.ts +275 -0
  122. package/src/runtime/common/nodejsGuest.generated.json +47 -0
  123. package/src/runtime/common/runtime.ts +1138 -0
  124. package/src/trigger/common/config.ts +1 -1
  125. package/src/trigger/common/configOptions.ts +1 -1
  126. package/src/trigger/common/contract.ts +2 -1
  127. package/src/trigger/common/cron.ts +2 -1
  128. package/src/trigger/common/integration.ts +2 -1
  129. package/src/trigger/common/model.ts +87 -0
  130. package/src/trigger/common/poll.ts +2 -1
  131. package/src/trigger/common/webhook.ts +7 -4
  132. package/src/trigger/providers/fieldDescriptions.ts +1 -1
  133. package/src/trigger/providers/localization.ts +9 -2
  134. package/src/trigger/providers/remote.ts +1 -1
  135. package/src/types/index.ts +44 -15
  136. package/src/workflow/common/workflow.ts +3 -44
  137. package/src/execution/common/runtime.ts +0 -563
  138. package/src/openapi/common/authBindings.ts +0 -12
  139. /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'
@@ -22,6 +22,7 @@ const nodeKinds = new Set([
22
22
  'decision',
23
23
  'javascript',
24
24
  'openapi',
25
+ 'http-request',
25
26
  'llm',
26
27
  'value',
27
28
  'wait',
@@ -54,6 +55,7 @@ function nodeKind(
54
55
  | 'decision'
55
56
  | 'javascript'
56
57
  | 'openapi'
58
+ | 'http-request'
57
59
  | 'llm'
58
60
  | 'value'
59
61
  | 'wait'
@@ -73,6 +75,7 @@ function nodeKind(
73
75
  | 'decision'
74
76
  | 'javascript'
75
77
  | 'openapi'
78
+ | 'http-request'
76
79
  | 'llm'
77
80
  | 'value'
78
81
  | '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'
@@ -108,6 +108,7 @@ function nodeKind(
108
108
  | 'decision'
109
109
  | 'javascript'
110
110
  | 'openapi'
111
+ | 'http-request'
111
112
  | 'llm'
112
113
  | 'value'
113
114
  | 'wait'
@@ -319,7 +320,8 @@ export function executeNode(
319
320
  const title = nodeTitle(node)
320
321
  const projectedInputs = Object.fromEntries(
321
322
  Object.entries(nodeInputs).filter(([handle]) => {
322
- if (node.kind == 'task' && 'executor' in node.task && node.task?.executor.kind == 'openapi' && handle.startsWith('auth.')) return false
323
+ if (node.kind == 'task' && 'executor' in node.task && ['openapi', 'http-request'].includes(node.task.executor.kind) && handle.startsWith('auth.'))
324
+ return false
323
325
  const mapping = nodeInputMappings(node)[handle]
324
326
  return mapping?.kind != 'sources' || mapping.sources.every((source) => source.kind != 'binding')
325
327
  }),
@@ -365,7 +367,7 @@ export function executeNode(
365
367
  Object.entries(nodeInputs).filter(([handle]) => {
366
368
  if (additional.has(handle)) return false
367
369
  const task = 'executor' in node.task ? node.task : undefined
368
- if (task?.executor.kind != 'openapi') return true
370
+ if (task == null || !['openapi', 'http-request'].includes(task.executor.kind)) return true
369
371
  const mapping = node.inputs[handle]
370
372
  return (
371
373
  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'
@@ -69,6 +69,7 @@ export type SchedulerEvent =
69
69
  | 'decision'
70
70
  | 'javascript'
71
71
  | 'openapi'
72
+ | 'http-request'
72
73
  | 'llm'
73
74
  | 'value'
74
75
  | 'wait'
@@ -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 { assertOpenApiAuthBindings } from '../../openapi/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 }
@@ -167,7 +166,8 @@ export interface ConditionNode extends GraphNodeBase {
167
166
  }
168
167
 
169
168
  export type ManagedTaskExecutor =
170
- | import('../../workflow/common/workflow.ts').WorkflowExecutor
169
+ | import('../../http/common/httpRequest.ts').HttpRequestExecutor
170
+ | WorkflowExecutor
171
171
  | import('../../decision/common/decision.ts').DecisionExecutor
172
172
  | import('../../openapi/common/openapi.ts').OpenApiExecutor
173
173
  | { readonly kind: 'connector'; readonly action: string; readonly connectionId?: string; readonly outputMode?: 'value' }
@@ -204,23 +204,12 @@ export interface AgentConnectorTool extends AgentToolBase {
204
204
  readonly connectionId?: string
205
205
  }
206
206
 
207
- export interface WorkflowCapability {
208
- readonly kind: 'workflow'
209
- readonly name: string
210
- readonly flowId: string
211
- readonly revisionId: string
212
- readonly inputs: readonly Port[]
213
- readonly outputs: readonly Port[] | null
214
- }
215
-
216
207
  export interface AgentWorkflowTool extends AgentToolBase, Omit<WorkflowCapability, 'inputs'> {
217
208
  readonly action?: never
218
209
  readonly connectionId?: never
219
210
  }
220
211
 
221
212
  export type AgentTool = AgentConnectorTool | AgentWorkflowTool
222
- export type TaskCapability = ConnectorCapability | WorkflowCapability
223
-
224
213
  export const workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/
225
214
 
226
215
  export function workflowToolNameIssue(name: string, otherNames: Iterable<string> = []): 'invalid' | 'duplicate' | undefined {
@@ -238,33 +227,13 @@ export function decodeTaskCapabilities(value: unknown): readonly TaskCapability[
238
227
  if (workflowToolNameIssue(item.name, names)) throw new TypeError('Workflow tool names must be unique provider-compatible names.')
239
228
  names.add(item.name)
240
229
  }
230
+ const http = parsed.filter((item) => item.kind == 'http')
231
+ if (http.length > 1 || http.some((item) => new Set(item.hosts).size != item.hosts.length))
232
+ throw new TypeError('Code declares HTTP hosts once, without duplicates.')
241
233
  let connectorIndex = 0
242
234
  return parsed.map((item) => (item.kind == 'connector' ? connectors[connectorIndex++]! : item)) as readonly TaskCapability[]
243
235
  }
244
236
 
245
- export interface ConnectorAccessCapability {
246
- readonly actionHints?: readonly string[]
247
- readonly connectionHints?: readonly {
248
- readonly action: string
249
- readonly connectionId: string
250
- readonly alias?: string
251
- }[]
252
- readonly kind: 'connector'
253
- }
254
-
255
- export interface ConnectorActionCapability {
256
- readonly action: string
257
- readonly connections: readonly { readonly connectionId: string; readonly alias?: string }[]
258
- readonly connectionId?: string
259
- readonly kind: 'connector'
260
- }
261
-
262
- export type ConnectorPermissionCapability =
263
- | { readonly kind: 'connector'; readonly mode: 'shared' }
264
- | { readonly kind: 'connector'; readonly mode: 'independent'; readonly actions: readonly { readonly action: string; readonly connectionId?: string }[] }
265
-
266
- export type ConnectorCapability = ConnectorAccessCapability | ConnectorActionCapability | ConnectorPermissionCapability
267
-
268
237
  export function decodeConnectorCapabilities(value: unknown): readonly ConnectorCapability[] {
269
238
  if (!Array.isArray(value)) throw new TypeError('Connector capabilities must be an array.')
270
239
  if (value.length == 0) return []
@@ -388,20 +357,7 @@ export function decodeConnectorCapabilities(value: unknown): readonly ConnectorC
388
357
  })
389
358
  }
390
359
 
391
- interface TaskDefinitionBase {
392
- readonly inputs: readonly (InputPort | Group)[]
393
- readonly name: string
394
- readonly outputs: readonly (Port | Group)[]
395
- }
396
-
397
- export interface InlineTaskDefinition extends TaskDefinitionBase {
398
- readonly capabilities?: readonly TaskCapability[]
399
- readonly moduleId: string
400
- }
401
-
402
- export interface ManagedTaskDefinition extends TaskDefinitionBase {
403
- readonly executor: ManagedTaskExecutor
404
- }
360
+ export type ManagedTaskDefinition = ManagedTaskDefinitionOf<ManagedTaskExecutor>
405
361
 
406
362
  export type TaskDefinition = InlineTaskDefinition | ManagedTaskDefinition
407
363
 
@@ -416,89 +372,6 @@ export interface Graph {
416
372
  readonly nodes: Readonly<Record<string, GraphNode>>
417
373
  }
418
374
 
419
- export type TriggerSchedule =
420
- | { readonly expression: string; readonly timezone: string; readonly type: 'cron' }
421
- | { readonly type: 'every'; readonly unit: 'day' | 'hour' | 'minute' | 'month' | 'week'; readonly value: number }
422
-
423
- interface TriggerKeySnapshotBase {
424
- readonly configInputs: readonly (InputPort | Group)[]
425
- readonly definitionVersion: number
426
- readonly description: string
427
- readonly displayName: string
428
- readonly key: string
429
- readonly name: string
430
- readonly outputs: readonly Port[]
431
- readonly provider: string
432
- }
433
-
434
- export type IntegrationEndpointMethod = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT'
435
-
436
- export type IntegrationBodyFormat = 'form' | 'json' | 'multipart' | 'text'
437
-
438
- export interface IntegrationEndpointDeclaration {
439
- readonly body: {
440
- readonly allowArray: boolean
441
- readonly allowEmpty: boolean
442
- readonly formats: readonly IntegrationBodyFormat[]
443
- }
444
- readonly methods: readonly IntegrationEndpointMethod[]
445
- readonly successStatus: number
446
- }
447
-
448
- export type TriggerKeySnapshot =
449
- | (TriggerKeySnapshotBase & { readonly type: 'poll' })
450
- | (TriggerKeySnapshotBase & { readonly endpoint: IntegrationEndpointDeclaration; readonly type: 'integration' })
451
-
452
- export interface WebhookBodyField extends InputPort {}
453
-
454
- export interface WebhookOptions {
455
- readonly allowedOrigins?: readonly string[]
456
- readonly responseBody?:
457
- | { readonly kind: 'workflow-outputs'; readonly output?: string; readonly timeoutMs?: number }
458
- | { readonly kind: 'webhook-response'; readonly nodeId?: string; readonly timeoutMs?: number }
459
- readonly responseData?: string
460
- readonly responseHeaders?: Readonly<Record<string, string>>
461
- readonly responseHeadersSource?: {
462
- readonly kind: 'workflow-outputs'
463
- readonly output?: string
464
- }
465
- readonly responseHeaderOutputs?: Readonly<Record<string, string>>
466
- readonly responseStatusCode?: number
467
- readonly responseStatusCodeOutput?: string
468
- }
469
-
470
- interface TriggerNodeBase {
471
- readonly onError?: never
472
- readonly description?: string
473
- readonly icon?: string
474
- readonly name: string
475
- }
476
-
477
- export type TriggerNode =
478
- | (TriggerNodeBase & { readonly kind: 'manual' })
479
- | (TriggerNodeBase & { readonly kind: 'start'; readonly inputDefs: readonly Port[] })
480
- | (TriggerNodeBase & { readonly kind: 'error'; readonly sourceFlowIds?: readonly string[] })
481
- | (TriggerNodeBase & {
482
- readonly bodyFields: readonly WebhookBodyField[]
483
- readonly kind: 'webhook'
484
- readonly method: WebhookMethod
485
- readonly options?: WebhookOptions
486
- })
487
- | (TriggerNodeBase & { readonly cronTimes: readonly TriggerSchedule[]; readonly kind: 'cron' })
488
- | (TriggerNodeBase & {
489
- readonly connectionId?: string
490
- readonly config: InputValues
491
- readonly definition: TriggerKeySnapshot & { readonly type: 'poll' }
492
- readonly kind: 'poll'
493
- readonly pollTimes: readonly TriggerSchedule[]
494
- })
495
- | (TriggerNodeBase & {
496
- readonly connectionId?: string
497
- readonly config: InputValues
498
- readonly definition: TriggerKeySnapshot & { readonly type: 'integration' }
499
- readonly kind: 'integration'
500
- })
501
-
502
375
  export interface OutputsNode extends Omit<GraphNodeBase, 'inputs'> {
503
376
  readonly kind: 'outputs'
504
377
  readonly outputDefs: readonly Port[]
@@ -522,12 +395,6 @@ export interface FlowDocument {
522
395
  readonly graph: Graph
523
396
  }
524
397
 
525
- export interface CodeModule {
526
- readonly imports: readonly string[]
527
- readonly name: string
528
- readonly source: string
529
- }
530
-
531
398
  export interface RevisionContent {
532
399
  readonly document: FlowDocument
533
400
  readonly modelVersion: 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | typeof currentFlowModelVersion
@@ -1031,6 +898,6 @@ export function applyFlowChanges(content: RevisionContent, operations: readonly
1031
898
  }
1032
899
  }
1033
900
  }
1034
- assertOpenApiAuthBindings(document)
901
+ assertDocumentHttpAuthBindings(document)
1035
902
  return upgradeDecodedRevisionContent({ document, modelVersion: currentFlowModelVersion, modules })
1036
903
  }
@@ -3,7 +3,9 @@ import type { ChangeOperation, FlowDocument, JsonValue, RevisionContent } from '
3
3
  import { dequal } from 'dequal/lite'
4
4
  import { z } from 'zod'
5
5
  import { limitDecisionTask } from '../../decision/common/decision.ts'
6
- import { assertOpenApiAuthBindings } from '../../openapi/common/authBindings.ts'
6
+ import { assertHttpAuthBindings } from '../../http/common/authBindings.ts'
7
+ import { isHttpHost, maxHttpHosts } from '../../http/common/hosts.ts'
8
+ import { httpRequestExecutorSchema } from '../../http/common/httpRequest.ts'
7
9
  import { checkJsonDepth } from './json.ts'
8
10
  import { retryConfigurationSchema } from './retry.ts'
9
11
  import { triggerScheduleSchema } from './triggerScheduleSchema.ts'
@@ -11,7 +13,7 @@ import { waitAutoContinueDraftSchema, waitAutoContinueSchema } from './wait.ts'
11
13
  import { webhookMethods } from './webhookMethod.ts'
12
14
  import { webhookResponseTimeout } from './webhookResponse.ts'
13
15
 
14
- export const currentFlowModelVersion = 11
16
+ export const currentFlowModelVersion = 12
15
17
  const text = z.string()
16
18
  const actionConnection = text.describe(
17
19
  '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.',
@@ -56,7 +58,15 @@ export const workflowCapabilitySchema = z.strictObject({
56
58
  inputs: z.array(port),
57
59
  outputs: z.array(port).nullable(),
58
60
  })
59
- const capability = z.union([connectorCapabilitySchema, workflowCapabilitySchema])
61
+ export const httpCapabilitySchema = z.strictObject({
62
+ kind: z.literal('http'),
63
+ hosts: z
64
+ .array(text.refine(isHttpHost, 'Use a lowercase host name or IPv4 address, optionally prefixed by "*." for subdomains.'))
65
+ .min(1)
66
+ .max(maxHttpHosts)
67
+ .describe('Hosts Code may call with context.fetch. "*.example.com" matches subdomains only.'),
68
+ })
69
+ const capability = z.union([connectorCapabilitySchema, workflowCapabilitySchema, httpCapabilitySchema])
60
70
  const inline = z.object({ ...ports, name: text, moduleId: text, capabilities: z.array(capability).optional() })
61
71
  const agentValue = z.union([z.object({ kind: z.literal('value'), value: json }), z.object({ kind: z.literal('input'), input: text })])
62
72
  const agentInput = z.union([agentValue, z.object({ kind: z.literal('model') })])
@@ -118,6 +128,7 @@ const managedFields = z.object({
118
128
  .optional(),
119
129
  }),
120
130
  z.strictObject({ kind: z.literal('workflow'), flowId: text, revisionId: text }),
131
+ httpRequestExecutorSchema,
121
132
  ]),
122
133
  })
123
134
 
@@ -306,6 +317,7 @@ const revision = z.object({
306
317
  z.literal(8),
307
318
  z.literal(9),
308
319
  z.literal(10),
320
+ z.literal(11),
309
321
  z.literal(currentFlowModelVersion),
310
322
  ]),
311
323
  document,
@@ -591,7 +603,7 @@ export function decodeRevisionContent(value: unknown): RevisionContent {
591
603
  checkJsonDepth(value)
592
604
  const content = revision.parse(value) as RevisionContent
593
605
  checkModelVersion(content)
594
- assertOpenApiAuthBindings(content.document)
606
+ assertDocumentHttpAuthBindings(content.document)
595
607
  return content
596
608
  }
597
609
 
@@ -601,7 +613,7 @@ export function decodeRevisionEnvelope(value: unknown): RevisionContent {
601
613
  const candidate = revisionSource.modelVersion == 2 ? { ...revisionSource, document: upgradeLegacyDocument(revisionSource.document) } : value
602
614
  const content = envelope.parse(candidate) as RevisionContent
603
615
  checkModelVersion(content)
604
- assertOpenApiAuthBindings(content.document)
616
+ assertDocumentHttpAuthBindings(content.document)
605
617
  return { modelVersion: content.modelVersion, document: content.document, modules: content.modules }
606
618
  }
607
619
 
@@ -711,6 +723,21 @@ export function changeOperationsSchema(kind?: string): JsonValue {
711
723
  }
712
724
 
713
725
  function checkModelVersion(content: RevisionContent): void {
726
+ if (
727
+ content.modelVersion < 12 &&
728
+ Object.values(content.document.graph.nodes).some(
729
+ (candidateNode) =>
730
+ candidateNode.kind == 'task' && 'moduleId' in candidateNode.task && candidateNode.task.capabilities?.some((item) => item.kind == 'http'),
731
+ )
732
+ )
733
+ throw new TypeError('Code HTTP access requires Flow model version 12.')
734
+ if (
735
+ content.modelVersion < 11 &&
736
+ Object.values(content.document.graph.nodes).some(
737
+ (candidateNode) => candidateNode.kind == 'task' && 'executor' in candidateNode.task && candidateNode.task.executor.kind == 'http-request',
738
+ )
739
+ )
740
+ throw new TypeError('HTTP Request requires Flow model version 11.')
714
741
  if (
715
742
  content.modelVersion < 11 &&
716
743
  Object.values(content.document.graph.nodes).some(
@@ -781,3 +808,10 @@ function checkModelVersion(content: RevisionContent): void {
781
808
  if (content.modelVersion < 5 && Object.values(content.document.graph.nodes).some((itemNode) => itemNode.kind == 'error'))
782
809
  throw new TypeError('Error workflows require Flow model version 5.')
783
810
  }
811
+
812
+ export function assertDocumentHttpAuthBindings(content: FlowDocument): void {
813
+ for (const graphNode of Object.values(content.graph.nodes)) {
814
+ if (graphNode.kind == 'task' && 'executor' in graphNode.task && ['openapi', 'http-request'].includes(graphNode.task.executor.kind))
815
+ assertHttpAuthBindings(graphNode.inputs)
816
+ }
817
+ }
@@ -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
@@ -1,3 +1,4 @@
1
+ import type { InputPort } from './change.ts'
1
2
  import type {
2
3
  BindingSource,
3
4
  FlowDocument,
@@ -14,6 +15,7 @@ import type {
14
15
  } from './change.ts'
15
16
  import type { Diagnostic } from './semantics.ts'
16
17
 
18
+ import { httpHeaderNameIssue } from '../../http/common/headers.ts'
17
19
  import { missingTriggerConfig, resolveTriggerConfig } from '../../trigger/common/config.ts'
18
20
  import { triggerOutputDefinitions, triggerOutputPorts, webhookSupportsBody } from '../../trigger/common/contract.ts'
19
21
  import { isTriggerNode, portsByHandle, validVariableName } from './change.ts'
@@ -27,7 +29,6 @@ import {
27
29
  webhookResponseInputs,
28
30
  validWebhookStatus,
29
31
  webhookHeaderValues,
30
- webhookHeaderNameIssue,
31
32
  webhookHeaderValuePort,
32
33
  webhookHeadersPort,
33
34
  webhookResponseAllowsBody,
@@ -92,7 +93,7 @@ export function webhookResponseDiagnostics(graph: Graph, triggerId: string, path
92
93
  ] as const) {
93
94
  const names: string[] = []
94
95
  for (const name of Object.keys(headers ?? {})) {
95
- if (webhookHeaderNameIssue(name, names) != null)
96
+ if (httpHeaderNameIssue(name, names) != null)
96
97
  diagnostics.push(graphDiagnostic('trigger.webhook-response-header-name', 'Use valid, unique HTTP header names.', location))
97
98
  names.push(name)
98
99
  }
@@ -615,9 +616,14 @@ export function checkInputSources(
615
616
  }
616
617
 
617
618
  /** Enumerate structurally available outputs while retaining their compatibility with one input. */
618
- export function inputSourceCandidates(graph: Graph, target: string, handle: string): Readonly<Record<string, readonly InputSourceCandidate[]>> {
619
+ export function inputSourceCandidates(
620
+ graph: Graph,
621
+ target: string,
622
+ handle: string,
623
+ inputPort?: InputPort,
624
+ ): Readonly<Record<string, readonly InputSourceCandidate[]>> {
619
625
  const targetNode = graph.nodes[target]
620
- const input = targetNode == null ? undefined : nodeInputPorts(targetNode)[handle]
626
+ const input = inputPort ?? (targetNode == null ? undefined : nodeInputPorts(targetNode)[handle])
621
627
  if (input == null) return {}
622
628
  const analysis = graphPaths(graph)
623
629
  return Object.fromEntries(
@@ -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 {