@oomol-lab/open-flow 0.1.0-beta.75 → 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 (125) hide show
  1. package/README.md +2 -1
  2. package/dist/browser/{ContentIcon-FCpKiwjp.js → ContentIcon-Cm1hbVzW.js} +2 -2
  3. package/dist/browser/{FlowCanvas-dzRBnlUT.js → FlowCanvas-NzKtla_c.js} +62 -62
  4. package/dist/browser/{createResourceDialog-BeYDdUl-.js → createResourceDialog-BgdedQqu.js} +3 -3
  5. package/dist/browser/{dialog-ZtpsFbl4.js → dialog-aSElFFw2.js} +49 -24
  6. package/dist/browser/{exportSvg-DqXw1yf-.js → exportSvg-Dcz4HTo_.js} +2 -2
  7. package/dist/browser/{flowChanges-b_5UobFj.js → flowChanges-NZyS7HSp.js} +207 -396
  8. package/dist/browser/{flowWorkspace-ItojZbO4.js → flowWorkspace-Bl0SDehy.js} +90 -13
  9. package/dist/browser/preview.css +515 -649
  10. package/dist/browser/preview.js +454 -545
  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 +515 -649
  17. package/dist/browser/workbench.js +7 -7
  18. package/dist/browser/{workbenchSelect-M441Lz0d.js → workbenchSelect-DBGP7Y4Z.js} +2 -2
  19. package/dist/command/index.js +33 -35
  20. package/dist/common/authoring.d.ts +3 -3
  21. package/dist/common/authoringSchema.d.ts +3 -0
  22. package/dist/common/connector-proxy.d.ts +1 -1
  23. package/dist/common/control-api-conformance.js +197 -136
  24. package/dist/common/control-api.d.ts +3 -2
  25. package/dist/common/control-api.js +192 -131
  26. package/dist/common/control-requests.js +126 -24
  27. package/dist/common/cron-trigger.d.ts +2 -1
  28. package/dist/common/decision.d.ts +4 -4
  29. package/dist/common/decision.js +5 -2
  30. package/dist/common/engine-contract.d.ts +5 -1
  31. package/dist/common/event-source-definition.d.ts +1 -1
  32. package/dist/common/event-source-view.d.ts +22 -0
  33. package/dist/common/event-source.d.ts +1 -1
  34. package/dist/common/event-source.js +24 -65
  35. package/dist/common/event-sources.d.ts +0 -21
  36. package/dist/common/flow-authoring.js +40 -18
  37. package/dist/common/flow-change-schema.d.ts +9 -1
  38. package/dist/common/flow-change.d.ts +7 -201
  39. package/dist/common/flow-change.js +46 -22
  40. package/dist/common/flow-encoding.js +40 -20
  41. package/dist/common/flow-input-value.d.ts +1 -1
  42. package/dist/common/flow-model.d.ts +121 -0
  43. package/dist/common/flow-notifications.d.ts +1 -1
  44. package/dist/common/flow-retry.d.ts +2 -4
  45. package/dist/common/flow-semantics.js +83 -86
  46. package/dist/common/flow-workflowReferences.d.ts +8 -0
  47. package/dist/common/flowInspection.d.ts +1 -1
  48. package/dist/common/http-hosts.d.ts +6 -0
  49. package/dist/common/http-request.d.ts +13 -5
  50. package/dist/common/http-request.js +23 -5
  51. package/dist/common/integration-trigger.d.ts +2 -1
  52. package/dist/common/mcp.js +195 -134
  53. package/dist/common/openapi.d.ts +4 -4
  54. package/dist/common/openapi.js +4 -1
  55. package/dist/common/poll-trigger.d.ts +2 -1
  56. package/dist/common/runtime-contract.d.ts +23 -1
  57. package/dist/common/runtime-contract.js +604 -72
  58. package/dist/common/runtime-nodejs-compat.d.ts +44 -0
  59. package/dist/common/runtime-nodejs-compat.js +5870 -0
  60. package/dist/common/scheduler-checkpoint.d.ts +1 -1
  61. package/dist/common/scheduler-node-execution.d.ts +1 -1
  62. package/dist/common/scheduler.d.ts +1 -1
  63. package/dist/common/scheduler.js +25 -4
  64. package/dist/common/trigger-catalog.d.ts +1 -7
  65. package/dist/common/trigger-config-options.d.ts +1 -1
  66. package/dist/common/trigger-config.d.ts +1 -1
  67. package/dist/common/trigger-contract.d.ts +2 -1
  68. package/dist/common/trigger-localization.d.ts +8 -2
  69. package/dist/common/trigger-model.d.ts +101 -0
  70. package/dist/common/webhook-response.d.ts +1 -1
  71. package/dist/common/webhook-trigger.d.ts +3 -1
  72. package/dist/common/workflow.d.ts +3 -12
  73. package/dist/common/workflow.js +25 -23
  74. package/dist/index.d.ts +41 -14
  75. package/package.json +5 -1
  76. package/src/base/common/json.ts +1 -1
  77. package/src/connector/common/proxy.ts +1 -1
  78. package/src/control/common/api.ts +6 -5
  79. package/src/control/common/authoringSchema.ts +9 -2
  80. package/src/control/common/authoringTools.ts +1 -1
  81. package/src/control/common/conformance.ts +1 -1
  82. package/src/control/common/connectorDecoders.ts +1 -1
  83. package/src/control/common/eventSources.ts +2 -29
  84. package/src/control/common/triggerCatalog.ts +1 -8
  85. package/src/decision/common/decision.ts +15 -7
  86. package/src/event-source/common/definition.ts +1 -1
  87. package/src/event-source/common/index.ts +1 -1
  88. package/src/event-source/common/view.ts +20 -0
  89. package/src/execution/common/checkpoint.ts +1 -1
  90. package/src/execution/common/node-execution.ts +1 -1
  91. package/src/execution/common/scheduler.ts +1 -1
  92. package/src/flow/common/change.ts +58 -192
  93. package/src/flow/common/changeSchema.ts +29 -4
  94. package/src/flow/common/connectionUsage.ts +1 -1
  95. package/src/flow/common/inputValue.ts +1 -1
  96. package/src/flow/common/model.ts +130 -0
  97. package/src/flow/common/modules.ts +1 -1
  98. package/src/flow/common/portChanges.ts +1 -1
  99. package/src/flow/common/retry.ts +2 -4
  100. package/src/flow/common/semantics.ts +11 -4
  101. package/src/flow/common/webhookResponse.ts +1 -1
  102. package/src/flow/common/workflowReferences.ts +31 -0
  103. package/src/http/common/authBindings.ts +6 -9
  104. package/src/http/common/hosts.ts +13 -0
  105. package/src/http/common/httpRequest.ts +30 -15
  106. package/src/openapi/common/openapi.ts +9 -5
  107. package/src/{execution → runtime}/common/engineContract.ts +20 -15
  108. package/src/runtime/common/nodejsCompat.ts +275 -0
  109. package/src/runtime/common/nodejsGuest.generated.json +47 -0
  110. package/src/runtime/common/runtime.ts +1138 -0
  111. package/src/trigger/common/config.ts +1 -1
  112. package/src/trigger/common/configOptions.ts +1 -1
  113. package/src/trigger/common/contract.ts +2 -1
  114. package/src/trigger/common/cron.ts +2 -1
  115. package/src/trigger/common/integration.ts +2 -1
  116. package/src/trigger/common/model.ts +87 -0
  117. package/src/trigger/common/poll.ts +2 -1
  118. package/src/trigger/common/webhook.ts +3 -1
  119. package/src/trigger/providers/fieldDescriptions.ts +1 -1
  120. package/src/trigger/providers/localization.ts +9 -2
  121. package/src/trigger/providers/remote.ts +1 -1
  122. package/src/types/index.ts +44 -15
  123. package/src/workflow/common/workflow.ts +3 -44
  124. package/src/execution/common/runtime.ts +0 -563
  125. /package/src/{control → connector}/common/providerIconSprite.ts +0 -0
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod'
2
+ import { eventSourceViewSchema } from '../../event-source/common/view.ts'
2
3
 
3
4
  const id = z.string().min(1).max(256)
4
5
  const eventType = z.string().regex(/^[a-z][a-z0-9_.:]{0,127}$/)
@@ -10,45 +11,17 @@ const eventSourceSchema = z.object({
10
11
  revision: z.int().positive(),
11
12
  name,
12
13
  provider: z.enum(['feishu', 'feishu_app_bot', 'slackbot', 'intercom', 'sentry', 'zoom', 'fireflies', 'jira']),
13
- appId: id.nullable(),
14
- workspaceId: id.optional(),
15
- installationId: id.optional(),
16
- organizationId: id.optional(),
17
- projectId: id.optional(),
18
- projectKey: id.optional(),
19
- subscriptionStatus: z.enum(['idle', 'pending', 'ready', 'error']).optional(),
20
- lastError: z.string().optional(),
21
- signingSecretConfigured: z.boolean().optional(),
14
+ ...eventSourceViewSchema.shape,
22
15
  connectionId: id,
23
16
  teamId: id.nullable(),
24
17
  enabled: z.boolean(),
25
18
  eventTypes: z.array(eventType),
26
- manageSubscriptions: z.boolean().nullable(),
27
- verificationTokenConfigured: z.boolean().nullable(),
28
- encryptKeyConfigured: z.boolean().nullable(),
29
19
  endpointUrl: z.string().nullable(),
30
- verifiedAt: z.string().nullable(),
31
20
  lastReceivedAt: z.string().nullable(),
32
21
  updatedAt: z.string(),
33
22
  consumers: z.array(z.object({ flowId: id, flowName: z.string(), triggerNodeId: id })),
34
23
  })
35
24
 
36
- export const eventSourceViewSchema = eventSourceSchema.pick({
37
- appId: true,
38
- workspaceId: true,
39
- installationId: true,
40
- organizationId: true,
41
- projectId: true,
42
- projectKey: true,
43
- subscriptionStatus: true,
44
- lastError: true,
45
- signingSecretConfigured: true,
46
- manageSubscriptions: true,
47
- verificationTokenConfigured: true,
48
- encryptKeyConfigured: true,
49
- verifiedAt: true,
50
- })
51
-
52
25
  export interface CreateFeishuEventSource {
53
26
  readonly kind?: 'feishu'
54
27
  readonly version: 1
@@ -1,19 +1,12 @@
1
1
  import type { TriggerKeySnapshot } from '../../flow/common/change.ts'
2
2
  import type { UiLanguage } from '../../localization/common/languages.ts'
3
+ import type { TriggerDisplay } from '../../trigger/providers/localization.ts'
3
4
  import type { TriggerKeySummary } from './api.ts'
4
5
 
5
6
  import { isUiLanguage } from '../../localization/common/languages.ts'
6
7
  import { exact, requiredFields, invalidResponse, record, string } from './decoding.ts'
7
8
  import { triggerKey } from './triggerDecoders.ts'
8
9
 
9
- export interface TriggerDisplay {
10
- readonly configInputs: Readonly<Record<string, string>>
11
- readonly configInputLabels: Readonly<Record<string, string>>
12
- readonly displayName: string
13
- readonly description: string
14
- readonly outputs: Readonly<Record<string, string>>
15
- }
16
-
17
10
  export interface TriggerCatalog {
18
11
  readonly version: 3
19
12
  readonly locale: UiLanguage
@@ -1,4 +1,4 @@
1
- import type { InputPort, JsonValue, ManagedTaskDefinition, Port } from '../../flow/common/change.ts'
1
+ import type { InputPort, JsonValue, ManagedTaskDefinitionOf, Port, TaskExecutor } from '../../flow/common/model.ts'
2
2
 
3
3
  import { dequal } from 'dequal/lite'
4
4
  import { matchesSchema } from '../../flow/common/schema.ts'
@@ -18,6 +18,10 @@ export interface DecisionIssue {
18
18
  readonly message: string
19
19
  }
20
20
 
21
+ function isDecisionExecutor(executor: TaskExecutor): executor is DecisionExecutor {
22
+ return executor.kind === 'decision'
23
+ }
24
+
21
25
  export const decisionModel = 'typesafe/jev'
22
26
  export const decisionLimits = { choice: 255, score: 10 } as const
23
27
 
@@ -34,8 +38,8 @@ export function limitDecisionQuestions(questions: readonly DecisionQuestion[]):
34
38
  }
35
39
 
36
40
  /** Loading an oversized task also updates its previously generated output schemas. */
37
- export function limitDecisionTask(task: ManagedTaskDefinition): ManagedTaskDefinition {
38
- if (task.executor.kind !== 'decision') return task
41
+ export function limitDecisionTask<Task extends ManagedTaskDefinitionOf<TaskExecutor>>(task: Task): Task {
42
+ if (!isDecisionExecutor(task.executor)) return task
39
43
  const original = task.executor.questions
40
44
  const questions = limitDecisionQuestions(original)
41
45
  if (questions === original) return task
@@ -45,7 +49,8 @@ export function limitDecisionTask(task: ManagedTaskDefinition): ManagedTaskDefin
45
49
  if (index < 0 || original[index] === questions[index] || !dequal(port.jsonSchema, answerSchema(original[index]!))) return port
46
50
  return { ...port, jsonSchema: decisionAnswerSchema(questions[index]!) }
47
51
  })
48
- return { ...task, executor: { ...task.executor, questions }, outputs }
52
+ // Only the decision executor and its derived outputs change, so the task keeps its own type.
53
+ return { ...task, executor: { ...task.executor, questions }, outputs } as Task
49
54
  }
50
55
  export const decisionStateSchema: JsonValue = { type: ['string', 'object', 'array'] }
51
56
  const probability: JsonValue = { type: 'number', minimum: 0, maximum: 1 }
@@ -102,7 +107,10 @@ function answerSchema(question: DecisionQuestion): JsonValue {
102
107
  return { type: 'object', properties, required: Object.keys(properties) }
103
108
  }
104
109
 
105
- export function decisionTask(questions: readonly DecisionQuestion[] = [defaultDecisionQuestion()], name = 'AI Decision'): ManagedTaskDefinition {
110
+ export function decisionTask(
111
+ questions: readonly DecisionQuestion[] = [defaultDecisionQuestion()],
112
+ name = 'AI Decision',
113
+ ): ManagedTaskDefinitionOf<DecisionExecutor> {
106
114
  questions = limitDecisionQuestions(questions)
107
115
  const inputs: InputPort[] = [
108
116
  { handle: 'target', description: 'Text, object, or array to evaluate across all questions.', jsonSchema: decisionStateSchema, nullable: false },
@@ -111,9 +119,9 @@ export function decisionTask(questions: readonly DecisionQuestion[] = [defaultDe
111
119
  return { name, executor: { kind: 'decision', questions }, inputs, outputs }
112
120
  }
113
121
 
114
- export function decisionTaskIssues(task: ManagedTaskDefinition): readonly DecisionIssue[] {
122
+ export function decisionTaskIssues(task: ManagedTaskDefinitionOf<TaskExecutor>): readonly DecisionIssue[] {
115
123
  task = limitDecisionTask(task)
116
- if (task.executor.kind !== 'decision') return []
124
+ if (!isDecisionExecutor(task.executor)) return []
117
125
  const expected = decisionTask(task.executor.questions, task.name)
118
126
  return [
119
127
  ...decisionQuestionIssues(task.executor.questions),
@@ -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'
@@ -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'
@@ -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'
@@ -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,7 @@ 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
+ | WorkflowExecutor
172
171
  | import('../../decision/common/decision.ts').DecisionExecutor
173
172
  | import('../../openapi/common/openapi.ts').OpenApiExecutor
174
173
  | { readonly kind: 'connector'; readonly action: string; readonly connectionId?: string; readonly outputMode?: 'value' }
@@ -205,23 +204,12 @@ export interface AgentConnectorTool extends AgentToolBase {
205
204
  readonly connectionId?: string
206
205
  }
207
206
 
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
207
  export interface AgentWorkflowTool extends AgentToolBase, Omit<WorkflowCapability, 'inputs'> {
218
208
  readonly action?: never
219
209
  readonly connectionId?: never
220
210
  }
221
211
 
222
212
  export type AgentTool = AgentConnectorTool | AgentWorkflowTool
223
- export type TaskCapability = ConnectorCapability | WorkflowCapability
224
-
225
213
  export const workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/
226
214
 
227
215
  export function workflowToolNameIssue(name: string, otherNames: Iterable<string> = []): 'invalid' | 'duplicate' | undefined {
@@ -239,33 +227,13 @@ export function decodeTaskCapabilities(value: unknown): readonly TaskCapability[
239
227
  if (workflowToolNameIssue(item.name, names)) throw new TypeError('Workflow tool names must be unique provider-compatible names.')
240
228
  names.add(item.name)
241
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.')
242
233
  let connectorIndex = 0
243
234
  return parsed.map((item) => (item.kind == 'connector' ? connectors[connectorIndex++]! : item)) as readonly TaskCapability[]
244
235
  }
245
236
 
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
237
  export function decodeConnectorCapabilities(value: unknown): readonly ConnectorCapability[] {
270
238
  if (!Array.isArray(value)) throw new TypeError('Connector capabilities must be an array.')
271
239
  if (value.length == 0) return []
@@ -389,20 +357,7 @@ export function decodeConnectorCapabilities(value: unknown): readonly ConnectorC
389
357
  })
390
358
  }
391
359
 
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
- }
360
+ export type ManagedTaskDefinition = ManagedTaskDefinitionOf<ManagedTaskExecutor>
406
361
 
407
362
  export type TaskDefinition = InlineTaskDefinition | ManagedTaskDefinition
408
363
 
@@ -417,89 +372,6 @@ export interface Graph {
417
372
  readonly nodes: Readonly<Record<string, GraphNode>>
418
373
  }
419
374
 
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
375
  export interface OutputsNode extends Omit<GraphNodeBase, 'inputs'> {
504
376
  readonly kind: 'outputs'
505
377
  readonly outputDefs: readonly Port[]
@@ -523,12 +395,6 @@ export interface FlowDocument {
523
395
  readonly graph: Graph
524
396
  }
525
397
 
526
- export interface CodeModule {
527
- readonly imports: readonly string[]
528
- readonly name: string
529
- readonly source: string
530
- }
531
-
532
398
  export interface RevisionContent {
533
399
  readonly document: FlowDocument
534
400
  readonly modelVersion: 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | typeof currentFlowModelVersion
@@ -1032,6 +898,6 @@ export function applyFlowChanges(content: RevisionContent, operations: readonly
1032
898
  }
1033
899
  }
1034
900
  }
1035
- assertHttpAuthBindings(document)
901
+ assertDocumentHttpAuthBindings(document)
1036
902
  return upgradeDecodedRevisionContent({ document, modelVersion: currentFlowModelVersion, modules })
1037
903
  }
@@ -4,6 +4,7 @@ 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'
8
9
  import { checkJsonDepth } from './json.ts'
9
10
  import { retryConfigurationSchema } from './retry.ts'
@@ -12,7 +13,7 @@ import { waitAutoContinueDraftSchema, waitAutoContinueSchema } from './wait.ts'
12
13
  import { webhookMethods } from './webhookMethod.ts'
13
14
  import { webhookResponseTimeout } from './webhookResponse.ts'
14
15
 
15
- export const currentFlowModelVersion = 11
16
+ export const currentFlowModelVersion = 12
16
17
  const text = z.string()
17
18
  const actionConnection = text.describe(
18
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.',
@@ -57,7 +58,15 @@ export const workflowCapabilitySchema = z.strictObject({
57
58
  inputs: z.array(port),
58
59
  outputs: z.array(port).nullable(),
59
60
  })
60
- 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])
61
70
  const inline = z.object({ ...ports, name: text, moduleId: text, capabilities: z.array(capability).optional() })
62
71
  const agentValue = z.union([z.object({ kind: z.literal('value'), value: json }), z.object({ kind: z.literal('input'), input: text })])
63
72
  const agentInput = z.union([agentValue, z.object({ kind: z.literal('model') })])
@@ -308,6 +317,7 @@ const revision = z.object({
308
317
  z.literal(8),
309
318
  z.literal(9),
310
319
  z.literal(10),
320
+ z.literal(11),
311
321
  z.literal(currentFlowModelVersion),
312
322
  ]),
313
323
  document,
@@ -593,7 +603,7 @@ export function decodeRevisionContent(value: unknown): RevisionContent {
593
603
  checkJsonDepth(value)
594
604
  const content = revision.parse(value) as RevisionContent
595
605
  checkModelVersion(content)
596
- assertHttpAuthBindings(content.document)
606
+ assertDocumentHttpAuthBindings(content.document)
597
607
  return content
598
608
  }
599
609
 
@@ -603,7 +613,7 @@ export function decodeRevisionEnvelope(value: unknown): RevisionContent {
603
613
  const candidate = revisionSource.modelVersion == 2 ? { ...revisionSource, document: upgradeLegacyDocument(revisionSource.document) } : value
604
614
  const content = envelope.parse(candidate) as RevisionContent
605
615
  checkModelVersion(content)
606
- assertHttpAuthBindings(content.document)
616
+ assertDocumentHttpAuthBindings(content.document)
607
617
  return { modelVersion: content.modelVersion, document: content.document, modules: content.modules }
608
618
  }
609
619
 
@@ -713,6 +723,14 @@ export function changeOperationsSchema(kind?: string): JsonValue {
713
723
  }
714
724
 
715
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.')
716
734
  if (
717
735
  content.modelVersion < 11 &&
718
736
  Object.values(content.document.graph.nodes).some(
@@ -790,3 +808,10 @@ function checkModelVersion(content: RevisionContent): void {
790
808
  if (content.modelVersion < 5 && Object.values(content.document.graph.nodes).some((itemNode) => itemNode.kind == 'error'))
791
809
  throw new TypeError('Error workflows require Flow model version 5.')
792
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,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 {