@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.
- package/README.md +3 -1
- package/dist/browser/{ContentIcon-CUQHjQIw.js → ContentIcon-Cm1hbVzW.js} +4 -3
- package/dist/browser/{FlowCanvas-Dtf8_cQp.js → FlowCanvas-NzKtla_c.js} +62 -62
- package/dist/browser/{createResourceDialog-DI9pL-Yr.js → createResourceDialog-BgdedQqu.js} +3 -3
- package/dist/browser/{dialog-BYJGvItc.js → dialog-aSElFFw2.js} +322 -26
- package/dist/browser/{exportSvg-BOoy7-Db.js → exportSvg-Dcz4HTo_.js} +2 -2
- package/dist/browser/{flowChanges-RL-H4CjD.js → flowChanges-NZyS7HSp.js} +490 -438
- package/dist/browser/{flowWorkspace-BkDsETj0.js → flowWorkspace-Bl0SDehy.js} +499 -61
- package/dist/browser/preview.css +696 -825
- package/dist/browser/preview.js +1399 -717
- package/dist/browser/theme.css +114 -262
- package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-3XMK9jkr.js} +1 -1
- package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-C9sBGOKZ.js} +1 -1
- package/dist/browser/ui.css +354 -460
- package/dist/browser/ui.js +1 -1
- package/dist/browser/workbench.css +696 -825
- package/dist/browser/workbench.js +13 -7
- package/dist/browser/{workbenchSelect-BcWPWGzw.js → workbenchSelect-DBGP7Y4Z.js} +2 -2
- package/dist/command/index.js +41 -43
- package/dist/common/authoring.d.ts +5 -5
- package/dist/common/authoringExamples.d.ts +3 -2
- package/dist/common/authoringSchema.d.ts +70 -4
- package/dist/common/connector-proxy.d.ts +1 -1
- package/dist/common/control-api-conformance.js +250 -138
- package/dist/common/control-api.d.ts +3 -2
- package/dist/common/control-api.js +246 -134
- package/dist/common/control-requests.d.ts +3 -3
- package/dist/common/control-requests.js +353 -79
- package/dist/common/cron-trigger.d.ts +2 -1
- package/dist/common/decision.d.ts +4 -4
- package/dist/common/decision.js +5 -2
- package/dist/common/engine-contract.d.ts +6 -1
- package/dist/common/event-source-definition.d.ts +1 -1
- package/dist/common/event-source-view.d.ts +22 -0
- package/dist/common/event-source.d.ts +1 -1
- package/dist/common/event-source.js +24 -65
- package/dist/common/event-sources.d.ts +0 -21
- package/dist/common/flow-authoring.js +90 -19
- package/dist/common/flow-change-schema.d.ts +9 -1
- package/dist/common/flow-change.d.ts +7 -201
- package/dist/common/flow-change.js +96 -23
- package/dist/common/flow-encoding.js +89 -21
- package/dist/common/flow-graph.d.ts +2 -1
- package/dist/common/flow-input-value.d.ts +1 -1
- package/dist/common/flow-model.d.ts +121 -0
- package/dist/common/flow-notifications.d.ts +1 -1
- package/dist/common/flow-retry.d.ts +3 -5
- package/dist/common/flow-semantics.js +816 -586
- package/dist/common/flow-workflowReferences.d.ts +8 -0
- package/dist/common/flowInspection.d.ts +1 -1
- package/dist/common/http-hosts.d.ts +6 -0
- package/dist/common/http-request.d.ts +164 -0
- package/dist/common/http-request.js +5272 -0
- package/dist/common/integration-trigger.d.ts +2 -1
- package/dist/common/mcp.d.ts +3 -3
- package/dist/common/mcp.js +248 -136
- package/dist/common/openapi.d.ts +4 -4
- package/dist/common/openapi.js +4 -1
- package/dist/common/poll-trigger.d.ts +2 -1
- package/dist/common/run-events.js +11 -9
- package/dist/common/runtime-contract.d.ts +23 -1
- package/dist/common/runtime-contract.js +607 -72
- package/dist/common/runtime-nodejs-compat.d.ts +44 -0
- package/dist/common/runtime-nodejs-compat.js +5870 -0
- package/dist/common/scheduler-checkpoint.d.ts +1 -1
- package/dist/common/scheduler-node-execution.d.ts +1 -1
- package/dist/common/scheduler.d.ts +2 -2
- package/dist/common/scheduler.js +95 -25
- package/dist/common/trigger-catalog.d.ts +1 -7
- package/dist/common/trigger-config-options.d.ts +1 -1
- package/dist/common/trigger-config.d.ts +1 -1
- package/dist/common/trigger-contract.d.ts +2 -1
- package/dist/common/trigger-localization.d.ts +8 -2
- package/dist/common/trigger-model.d.ts +101 -0
- package/dist/common/webhook-response.d.ts +1 -3
- package/dist/common/webhook-trigger.d.ts +3 -1
- package/dist/common/webhook-trigger.js +12 -11
- package/dist/common/workflow.d.ts +3 -12
- package/dist/common/workflow.js +25 -23
- package/dist/index.d.ts +41 -14
- package/package.json +9 -1
- package/skills/open-flow/references/flow-authoring.md +1 -0
- package/skills/open-flow/references/flow-n8n-conversion.md +19 -15
- package/src/base/common/json.ts +1 -1
- package/src/connector/common/proxy.ts +1 -1
- package/src/control/common/api.ts +7 -5
- package/src/control/common/authoring.ts +14 -3
- package/src/control/common/authoringExamples.ts +8 -0
- package/src/control/common/authoringSchema.ts +38 -25
- package/src/control/common/authoringTools.ts +1 -1
- package/src/control/common/conformance.ts +1 -1
- package/src/control/common/connectorDecoders.ts +1 -1
- package/src/control/common/eventSources.ts +2 -29
- package/src/control/common/triggerCatalog.ts +1 -8
- package/src/decision/common/decision.ts +15 -7
- package/src/event-source/common/definition.ts +1 -1
- package/src/event-source/common/index.ts +1 -1
- package/src/event-source/common/view.ts +20 -0
- package/src/execution/common/checkpoint.ts +1 -1
- package/src/execution/common/events.ts +3 -0
- package/src/execution/common/node-execution.ts +5 -3
- package/src/execution/common/scheduler.ts +2 -1
- package/src/flow/common/change.ts +59 -192
- package/src/flow/common/changeSchema.ts +39 -5
- package/src/flow/common/connectionUsage.ts +1 -1
- package/src/flow/common/graph.ts +10 -4
- package/src/flow/common/inputValue.ts +1 -1
- package/src/flow/common/model.ts +130 -0
- package/src/flow/common/modules.ts +1 -1
- package/src/flow/common/portChanges.ts +1 -1
- package/src/flow/common/retry.ts +3 -5
- package/src/flow/common/semantics.ts +71 -7
- package/src/flow/common/webhookResponse.ts +4 -8
- package/src/flow/common/workflowReferences.ts +31 -0
- package/src/http/common/authBindings.ts +9 -0
- package/src/http/common/headers.ts +5 -0
- package/src/http/common/hosts.ts +13 -0
- package/src/http/common/httpRequest.ts +266 -0
- package/src/openapi/common/openapi.ts +9 -5
- package/src/{execution → runtime}/common/engineContract.ts +24 -15
- package/src/runtime/common/nodejsCompat.ts +275 -0
- package/src/runtime/common/nodejsGuest.generated.json +47 -0
- package/src/runtime/common/runtime.ts +1138 -0
- package/src/trigger/common/config.ts +1 -1
- package/src/trigger/common/configOptions.ts +1 -1
- package/src/trigger/common/contract.ts +2 -1
- package/src/trigger/common/cron.ts +2 -1
- package/src/trigger/common/integration.ts +2 -1
- package/src/trigger/common/model.ts +87 -0
- package/src/trigger/common/poll.ts +2 -1
- package/src/trigger/common/webhook.ts +7 -4
- package/src/trigger/providers/fieldDescriptions.ts +1 -1
- package/src/trigger/providers/localization.ts +9 -2
- package/src/trigger/providers/remote.ts +1 -1
- package/src/types/index.ts +44 -15
- package/src/workflow/common/workflow.ts +3 -44
- package/src/execution/common/runtime.ts +0 -563
- package/src/openapi/common/authBindings.ts +0 -12
- /package/src/{control → connector}/common/providerIconSprite.ts +0 -0
|
@@ -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
|
|
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
|
|
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 {
|
|
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 {
|
|
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('../../
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/src/flow/common/graph.ts
CHANGED
|
@@ -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 (
|
|
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(
|
|
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 './
|
|
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 {
|