@codemation/core 0.14.0 → 0.15.0
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/CHANGELOG.md +68 -0
- package/dist/{CostCatalogContract-B9aYIqJu.d.cts → CostCatalogContract-Dwo-ZamG.d.cts} +2 -2
- package/dist/EngineRuntimeRegistration.types-BiNasx3G.d.cts +54 -0
- package/dist/EngineRuntimeRegistration.types-Dq4ucrdo.d.ts +21 -0
- package/dist/{InMemoryRunDataFactory-C3rIszrW.d.cts → InMemoryRunDataFactory-D2U9azmZ.d.cts} +2 -20
- package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs} +1 -1
- package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs.map → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs.map} +1 -1
- package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js → InMemoryRunEventBusRegistry-Layt2xgm.js} +1 -1
- package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js.map → InMemoryRunEventBusRegistry-Layt2xgm.js.map} +1 -1
- package/dist/{ItemsInputNormalizer-UCpn7luX.d.cts → ItemsInputNormalizer-A5txcOWX.d.cts} +3 -98
- package/dist/{ItemsInputNormalizer-B9SdLG24.cjs → ItemsInputNormalizer-C1fv3sMW.cjs} +2 -2
- package/dist/ItemsInputNormalizer-C1fv3sMW.cjs.map +1 -0
- package/dist/{ItemsInputNormalizer-DoOawd9R.d.ts → ItemsInputNormalizer-D2vrMrX1.d.ts} +2 -62
- package/dist/{ItemsInputNormalizer-CZEODg94.js → ItemsInputNormalizer-fUYo4GLV.js} +2 -2
- package/dist/ItemsInputNormalizer-fUYo4GLV.js.map +1 -0
- package/dist/{RunIntentService-0f3ICjAz.d.cts → RunIntentService-DKxuHTUz.d.cts} +2 -15
- package/dist/{RunIntentService-Dx_HHxDX.d.ts → RunIntentService-DrpKli2k.d.ts} +2 -22
- package/dist/{agentMcpTypes-B11B3Hd-.d.cts → agentMcpTypes-BHX4RQCC.d.cts} +24 -524
- package/dist/bootstrap/index.cjs +9 -5
- package/dist/bootstrap/index.d.cts +32 -106
- package/dist/bootstrap/index.d.ts +18 -17
- package/dist/bootstrap/index.js +6 -5
- package/dist/{bootstrap-Be0LB0nh.cjs → bootstrap-CTB53rEF.cjs} +9 -60
- package/dist/bootstrap-CTB53rEF.cjs.map +1 -0
- package/dist/{bootstrap-pSQdsMfa.js → bootstrap-DmqKheCI.js} +6 -57
- package/dist/bootstrap-DmqKheCI.js.map +1 -0
- package/dist/browser.cjs +12 -11
- package/dist/browser.d.cts +4 -4
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +3 -2
- package/dist/contracts-7L1wJHdk.cjs +569 -0
- package/dist/contracts-7L1wJHdk.cjs.map +1 -0
- package/dist/contracts-CjJ5CZ7N.js +447 -0
- package/dist/contracts-CjJ5CZ7N.js.map +1 -0
- package/dist/contracts.cjs +9 -2
- package/dist/contracts.d.cts +5 -5
- package/dist/contracts.d.ts +2 -2
- package/dist/contracts.js +3 -2
- package/dist/{executionPersistenceContracts-CX9Ql8N1.d.cts → deploymentManifestTypes-B8CDmZZK.d.cts} +65 -81
- package/dist/di-C6Ubf9o5.cjs +179 -0
- package/dist/di-C6Ubf9o5.cjs.map +1 -0
- package/dist/di-Cjiil7U-.js +114 -0
- package/dist/di-Cjiil7U-.js.map +1 -0
- package/dist/{index-CbJdbIHe.d.ts → index-CRv3_pY3.d.ts} +87 -870
- package/dist/{index-uPnD9EE6.d.ts → index-mnLS0iQl.d.ts} +27 -400
- package/dist/index.cjs +44 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -524
- package/dist/index.d.ts +5 -5
- package/dist/index.js +21 -98
- package/dist/index.js.map +1 -1
- package/dist/{params-Dwl10Ws9.d.cts → params-CrK4iuG1.d.cts} +2 -11
- package/dist/{runtime-CSunvf7A.js → runtime-CBFDpmiz.js} +46 -679
- package/dist/runtime-CBFDpmiz.js.map +1 -0
- package/dist/{runtime-n2tqRwaf.cjs → runtime-Due-FOZ2.cjs} +69 -752
- package/dist/runtime-Due-FOZ2.cjs.map +1 -0
- package/dist/testing.cjs +8 -40
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +3 -32
- package/dist/testing.d.ts +3 -32
- package/dist/testing.js +6 -38
- package/dist/testing.js.map +1 -1
- package/dist/{di-DhwtDRgs.cjs → workflowTypes-BW6Hhee7.cjs} +4 -229
- package/dist/workflowTypes-BW6Hhee7.cjs.map +1 -0
- package/dist/{di-CEV6wTc4.js → workflowTypes-DZtBTmKf.js} +3 -162
- package/dist/workflowTypes-DZtBTmKf.js.map +1 -0
- package/package.json +1 -1
- package/src/ai/AgentConnectionNodeCollector.ts +0 -4
- package/src/ai/AgentMessageConfigNormalizerFactory.ts +0 -4
- package/src/ai/AiHost.ts +0 -38
- package/src/ai/CallableToolConfig.ts +0 -9
- package/src/ai/CallableToolKindToken.ts +0 -4
- package/src/authoring/callableTool.types.ts +0 -3
- package/src/authoring/defineCollection.types.ts +0 -11
- package/src/authoring/defineHumanApprovalNode.types.ts +0 -116
- package/src/authoring/defineNode.types.ts +0 -25
- package/src/authoring/definePollingTrigger.types.ts +18 -152
- package/src/authoring/definePollingTriggerInternals.ts +0 -4
- package/src/authoring/nodeBaseOptions.types.ts +0 -14
- package/src/binaries/boundedReadBinary.types.ts +0 -16
- package/src/bootstrap/index.ts +8 -2
- package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +0 -5
- package/src/bootstrap/runtime/EngineRuntimeRegistration.types.ts +0 -23
- package/src/browser.ts +0 -3
- package/src/contracts/AgentBindError.ts +0 -5
- package/src/contracts/Clock.ts +0 -1
- package/src/contracts/CodemationTelemetryAttributeNames.ts +0 -10
- package/src/contracts/NoOpAgentMcpIntegration.ts +0 -6
- package/src/contracts/NoOpTelemetrySpanScope.ts +0 -7
- package/src/contracts/RetryPolicy.ts +0 -2
- package/src/contracts/agentMcpTypes.ts +0 -34
- package/src/contracts/assertionTypes.ts +0 -33
- package/src/contracts/baseTypes.ts +0 -6
- package/src/contracts/collectionTypes.ts +0 -25
- package/src/contracts/credentialTypes.ts +13 -60
- package/src/contracts/deploymentManifestTypes.ts +158 -0
- package/src/contracts/dispatchTypes.ts +29 -0
- package/src/contracts/executionPersistenceContracts.ts +0 -33
- package/src/contracts/hitlSeamTypes.ts +0 -14
- package/src/contracts/humanTaskStoreTypes.ts +0 -2
- package/src/contracts/inboxChannelTypes.ts +0 -9
- package/src/contracts/index.ts +3 -0
- package/src/contracts/itemExpr.ts +0 -18
- package/src/contracts/itemMeta.ts +0 -3
- package/src/contracts/mcpTypes.ts +0 -16
- package/src/contracts/retryPolicySpec.types.ts +0 -10
- package/src/contracts/runFinishedAtFactory.ts +0 -1
- package/src/contracts/runTypes.ts +0 -74
- package/src/contracts/runtimeTypes.ts +4 -131
- package/src/contracts/telemetryTypes.ts +0 -7
- package/src/contracts/testTriggerTypes.ts +0 -43
- package/src/contracts/triggerInvokerTypes.ts +6 -0
- package/src/contracts/webhookTypes.ts +0 -8
- package/src/contracts/workflowActivationPolicy.ts +0 -5
- package/src/contracts/workflowTypes.ts +4 -86
- package/src/contracts/workspaceFileTypes.ts +0 -72
- package/src/contracts.ts +18 -10
- package/src/credentials/CredentialMaterialProvider.types.ts +0 -28
- package/src/credentials/ManagedCredentialMaterialWriteError.ts +0 -6
- package/src/credentials/ManagedMaterialFetchError.ts +0 -6
- package/src/credentials/OAuthFlowExecutor.types.ts +0 -15
- package/src/di/CoreTokens.ts +2 -6
- package/src/events/ConnectionInvocationEventPublisher.ts +0 -7
- package/src/events/NodeEventPublisher.ts +0 -1
- package/src/events/runEvents.ts +0 -8
- package/src/execution/ActivationEnqueueService.ts +0 -10
- package/src/execution/ChildExecutionScopeFactory.ts +0 -13
- package/src/execution/FanInMergeByOriginMerger.ts +0 -11
- package/src/execution/InProcessRetryRunner.ts +0 -1
- package/src/execution/ItemExprResolver.ts +0 -3
- package/src/execution/NodeActivationRequestComposer.ts +0 -3
- package/src/execution/NodeActivationRequestInputPreparer.ts +0 -5
- package/src/execution/NodeExecutionSnapshotFactory.ts +0 -1
- package/src/execution/NodeExecutor.ts +1 -17
- package/src/execution/NodeSuspensionHandler.ts +1 -39
- package/src/execution/PersistedRunStateTerminalBuilder.ts +0 -5
- package/src/execution/RunSuspendedError.ts +0 -10
- package/src/execution/WorkflowRunExecutionContextFactory.ts +0 -3
- package/src/orchestration/AbortControllerFactory.ts +0 -4
- package/src/orchestration/Engine.ts +0 -9
- package/src/orchestration/NodeExecutionRequestHandlerService.ts +3 -4
- package/src/orchestration/RunContinuationService.ts +7 -39
- package/src/orchestration/RunStartService.ts +0 -7
- package/src/orchestration/TestSuiteOrchestrator.ts +0 -18
- package/src/orchestration/TestSuiteRunIdFactory.ts +0 -4
- package/src/orchestration/TriggerRuntimeService.ts +3 -2
- package/src/planning/CurrentStateFrontierPlanner.ts +0 -1
- package/src/planning/RunQueuePlanner.ts +0 -6
- package/src/policies/executionLimits/EngineExecutionLimitsPolicy.ts +0 -8
- package/src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts +0 -3
- package/src/runStorage/RunSummaryMapper.ts +0 -1
- package/src/runtime/EngineFactory.ts +6 -11
- package/src/runtime/RunIntentService.ts +0 -4
- package/src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts +0 -4
- package/src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts +0 -4
- package/src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts +0 -4
- package/src/runtime-types/PersistedRuntimeTypeNameResolver.ts +0 -1
- package/src/runtime-types/persistedRuntimeTypeModelRegistry.ts +0 -4
- package/src/runtime-types/runtimeTypeDecorators.types.ts +0 -12
- package/src/scheduler/ConfigDrivenOffloadPolicy.ts +0 -1
- package/src/scheduler/DefaultDrivingScheduler.ts +0 -6
- package/src/scheduler/InlineDrivingScheduler.ts +0 -13
- package/src/serialization/ItemsInputNormalizer.ts +0 -5
- package/src/testing/CapturingScheduler.ts +0 -3
- package/src/testing/EngineTestKitRunIdFactory.ts +0 -3
- package/src/testing/ItemHarnessNode.ts +0 -3
- package/src/testing/ItemHarnessNodeConfig.ts +0 -4
- package/src/testing/PrefixedSequentialIdGenerator.ts +0 -3
- package/src/testing/RegistrarEngineTestKit.types.ts +0 -2
- package/src/testing/RejectingCredentialSessionService.ts +0 -4
- package/src/testing/SubWorkflowRunnerTestNode.ts +0 -3
- package/src/testing/WorkflowTestHarnessManualTrigger.ts +0 -3
- package/src/testing/WorkflowTestKitBuilder.ts +0 -4
- package/src/testing/WorkflowTestKitRunNodeWorkflowFactory.ts +0 -3
- package/src/testing.ts +0 -3
- package/src/triggers/polling/PollingTriggerDedupWindow.ts +0 -4
- package/src/triggers/polling/PollingTriggerLogger.ts +0 -5
- package/src/triggers/polling/PollingTriggerRuntime.ts +0 -5
- package/src/types/index.ts +0 -6
- package/src/validation/WorkflowEdgePortValidator.ts +0 -5
- package/src/workflow/definition/ConnectionInvocationIdFactory.ts +0 -7
- package/src/workflow/definition/ConnectionNodeIdFactory.ts +0 -6
- package/src/workflow/definition/NodeIterationIdFactory.ts +0 -13
- package/src/workflow/definition/WorkflowExecutableNodeClassifier.ts +0 -6
- package/src/workflow/dsl/ChainCursorResolver.ts +0 -20
- package/src/workflow/dsl/NodeIdSlugifier.ts +0 -9
- package/src/workflow/dsl/WhenBuilder.ts +0 -17
- package/src/workflow/dsl/WorkflowDefinitionError.ts +0 -9
- package/src/workflow/dsl/workflowBuilderTypes.ts +0 -24
- package/src/workflowSnapshots/MissingRuntimeParityGuard.ts +24 -0
- package/src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts +0 -6
- package/src/workflowSnapshots/WorkflowParityMismatchError.ts +18 -0
- package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +0 -5
- package/src/workflowSnapshots/index.ts +3 -0
- package/dist/EngineRuntimeRegistration.types-BYAmGMdS.d.cts +0 -81
- package/dist/EngineRuntimeRegistration.types-CVLI8DsJ.d.ts +0 -44
- package/dist/ItemsInputNormalizer-B9SdLG24.cjs.map +0 -1
- package/dist/ItemsInputNormalizer-CZEODg94.js.map +0 -1
- package/dist/bootstrap-Be0LB0nh.cjs.map +0 -1
- package/dist/bootstrap-pSQdsMfa.js.map +0 -1
- package/dist/contracts-CK0x6w_G.cjs +0 -74
- package/dist/contracts-CK0x6w_G.cjs.map +0 -1
- package/dist/contracts-DXdfTdpW.js +0 -50
- package/dist/contracts-DXdfTdpW.js.map +0 -1
- package/dist/di-CEV6wTc4.js.map +0 -1
- package/dist/di-DhwtDRgs.cjs.map +0 -1
- package/dist/runtime-CSunvf7A.js.map +0 -1
- package/dist/runtime-n2tqRwaf.cjs.map +0 -1
|
@@ -33,11 +33,6 @@ import { Engine } from "../../orchestration/Engine";
|
|
|
33
33
|
import type { EngineRuntimeRegistrationOptions } from "./EngineRuntimeRegistration.types";
|
|
34
34
|
import type { WebhookTriggerMatcherProvider } from "./EngineRuntimeRegistration.types";
|
|
35
35
|
|
|
36
|
-
/**
|
|
37
|
-
* Container-first entry: call on a host/test container **after** workflow, run, node, and credential
|
|
38
|
-
* ports are registered. The registrar owns the default inline scheduler, engine binding,
|
|
39
|
-
* and intent-surface wiring so hosts only override the seams they actually replace.
|
|
40
|
-
*/
|
|
41
36
|
export class EngineRuntimeRegistrar {
|
|
42
37
|
register(container: DependencyContainer, options?: EngineRuntimeRegistrationOptions): void {
|
|
43
38
|
this.registerSupportFactories(container);
|
|
@@ -5,42 +5,19 @@ import type { TriggerRuntimeDiagnostics } from "../../contracts/runtimeTypes";
|
|
|
5
5
|
import type { WorkflowPolicyRuntimeDefaults } from "../../contracts/workflowTypes";
|
|
6
6
|
import type { EngineExecutionLimitsPolicyConfig } from "../../policies/executionLimits/EngineExecutionLimitsPolicy";
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Creates the webhook route matcher used by {@link import("../api/Engine").Engine}.
|
|
10
|
-
* Hosts may supply logging/diagnostics; tests often use the default factory without diagnostics.
|
|
11
|
-
*/
|
|
12
8
|
export interface WebhookTriggerMatcherProvider {
|
|
13
9
|
createMatcher(container: DependencyContainer): WebhookTriggerMatcher;
|
|
14
10
|
}
|
|
15
11
|
|
|
16
|
-
/**
|
|
17
|
-
* Supplies optional trigger-runtime logging (inactive workflow skips, activation sync).
|
|
18
|
-
*/
|
|
19
12
|
export interface TriggerRuntimeDiagnosticsProvider {
|
|
20
13
|
create(container: DependencyContainer): TriggerRuntimeDiagnostics | undefined;
|
|
21
14
|
}
|
|
22
15
|
|
|
23
16
|
export interface EngineRuntimeRegistrationOptions {
|
|
24
|
-
/**
|
|
25
|
-
* Static limits merged into the factory when the policy token is first resolved.
|
|
26
|
-
* Prefer {@link resolveEngineExecutionLimits} when limits can change after registration (e.g. host `useRuntimeConfig`).
|
|
27
|
-
*/
|
|
28
17
|
engineExecutionLimits?: Partial<EngineExecutionLimitsPolicyConfig>;
|
|
29
|
-
/**
|
|
30
|
-
* Called when the limits policy is first resolved; overrides {@link engineExecutionLimits} when both are set.
|
|
31
|
-
* Use this for host wiring so `runtime.engineExecutionLimits` applied after `registerCoreInfrastructure` is honored.
|
|
32
|
-
*/
|
|
33
18
|
resolveEngineExecutionLimits?: () => Partial<EngineExecutionLimitsPolicyConfig> | undefined;
|
|
34
|
-
/**
|
|
35
|
-
* When {@link webhookTriggerMatcherProvider} is omitted, the registrar builds
|
|
36
|
-
* {@link import("../../runtime/WorkflowRepositoryWebhookTriggerMatcher").WorkflowRepositoryWebhookTriggerMatcher}
|
|
37
|
-
* using this optional routing diagnostics surface.
|
|
38
|
-
*/
|
|
39
19
|
webhookTriggerRoutingDiagnostics?: WebhookTriggerRoutingDiagnostics;
|
|
40
|
-
/** Overrides default webhook matcher construction (e.g. host-injected loggers). */
|
|
41
20
|
webhookTriggerMatcherProvider?: WebhookTriggerMatcherProvider;
|
|
42
|
-
/** Overrides default trigger diagnostics (undefined when omitted). */
|
|
43
21
|
triggerRuntimeDiagnosticsProvider?: TriggerRuntimeDiagnosticsProvider;
|
|
44
|
-
/** Runtime retention/storage defaults used when workflows omit prune/storage policy fields. */
|
|
45
22
|
workflowPolicyRuntimeDefaults?: WorkflowPolicyRuntimeDefaults;
|
|
46
23
|
}
|
package/src/browser.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thrown at agent bind time when mcpServers declarations cannot be resolved.
|
|
3
|
-
* Causes include: unknown server id, missing credential instance, insufficient scopes,
|
|
4
|
-
* and ambiguous shorthand binding (multiple credential instances match).
|
|
5
|
-
*/
|
|
6
1
|
export class AgentBindError extends Error {
|
|
7
2
|
constructor(message: string) {
|
|
8
3
|
super(message);
|
package/src/contracts/Clock.ts
CHANGED
|
@@ -9,24 +9,14 @@ export class CodemationTelemetryAttributeNames {
|
|
|
9
9
|
static readonly connectionInvocationId = "codemation.connection.invocation_id";
|
|
10
10
|
static readonly toolName = "codemation.tool.name";
|
|
11
11
|
static readonly traceParentRunId = "codemation.parent.run.id";
|
|
12
|
-
/** Per-item iteration that emitted this span/metric. Set on spans recorded inside a runnable per-item loop. */
|
|
13
12
|
static readonly iterationId = "codemation.iteration.id";
|
|
14
|
-
/** Item index (0-based) of the iteration. */
|
|
15
13
|
static readonly iterationIndex = "codemation.iteration.index";
|
|
16
|
-
/** Set when this span/metric was recorded under a sub-agent triggered by an outer LLM/tool call. */
|
|
17
14
|
static readonly parentInvocationId = "codemation.parent.invocation_id";
|
|
18
|
-
/** MCP server id on spans created for callTool invocations. */
|
|
19
15
|
static readonly mcpServerId = "mcp.server_id";
|
|
20
|
-
/** MCP tool name on spans created for callTool invocations. */
|
|
21
16
|
static readonly mcpToolName = "mcp.tool_name";
|
|
22
|
-
/** Terminal node-execution status (e.g. `"hitl-approved"`, `"hitl-rejected"`) on HITL outcome spans. */
|
|
23
17
|
static readonly nodeExecutionStatus = "codemation.node.execution_status";
|
|
24
|
-
/** Populated on run-halted spans; discriminates the halt reason (e.g. `"hitl-rejected"`). */
|
|
25
18
|
static readonly runHaltReason = "codemation.run.halt_reason";
|
|
26
|
-
/** Human task ID on `hitl.task.*` span events. */
|
|
27
19
|
static readonly hitlTaskId = "codemation.hitl.task_id";
|
|
28
|
-
/** HITL channel name (e.g. `"inbox"`, `"control-plane-inbox"`) on `hitl.task.*` span events. */
|
|
29
20
|
static readonly hitlChannel = "codemation.hitl.channel";
|
|
30
|
-
/** Decision outcome (e.g. `"approved"`, `"rejected"`) on `hitl.task.decided` span events. */
|
|
31
21
|
static readonly hitlDecisionStatus = "codemation.hitl.decision_status";
|
|
32
22
|
}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { AgentMcpIntegration, AgentMcpToolMap } from "./agentMcpTypes";
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* No-op implementation of AgentMcpIntegration.
|
|
5
|
-
* Registered by the core engine runtime as a fallback when the host does not
|
|
6
|
-
* supply a real implementation (e.g. in unit tests or headless engine setups).
|
|
7
|
-
* Always returns an empty tool map so the agent runs with node-backed tools only.
|
|
8
|
-
*/
|
|
9
3
|
export class NoOpAgentMcpIntegration implements AgentMcpIntegration {
|
|
10
4
|
async prepareMcpTools(): Promise<AgentMcpToolMap> {
|
|
11
5
|
return new Map();
|
|
@@ -11,12 +11,6 @@ import type {
|
|
|
11
11
|
} from "./telemetryTypes";
|
|
12
12
|
import { NoOpTelemetryArtifactReference } from "./NoOpTelemetryArtifactReference";
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* Standalone no-op {@link NodeExecutionTelemetry} value used as the return for `asNodeTelemetry`.
|
|
16
|
-
*
|
|
17
|
-
* Defined here (instead of in `NoOpNodeExecutionTelemetry.ts`) so that {@link NoOpTelemetrySpanScope}
|
|
18
|
-
* can return it without importing the other module — both no-ops share this leaf.
|
|
19
|
-
*/
|
|
20
14
|
const noOpNodeExecutionTelemetry: NodeExecutionTelemetry = {
|
|
21
15
|
traceId: "00000000000000000000000000000000",
|
|
22
16
|
spanId: "0000000000000000",
|
|
@@ -53,6 +47,5 @@ const noOpTelemetrySpanScope: TelemetrySpanScope = {
|
|
|
53
47
|
|
|
54
48
|
export class NoOpTelemetrySpanScope {
|
|
55
49
|
static readonly value: TelemetrySpanScope = noOpTelemetrySpanScope;
|
|
56
|
-
/** Internal: the shared no-op {@link NodeExecutionTelemetry} that {@link NoOpNodeExecutionTelemetry} re-exposes. */
|
|
57
50
|
static readonly nodeExecutionTelemetryValue: NodeExecutionTelemetry = noOpNodeExecutionTelemetry;
|
|
58
51
|
}
|
|
@@ -15,9 +15,7 @@ export class RetryPolicy implements FixedRetryPolicySpec {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
/** Default for HTTP-style transient failures: 3 tries, 1s between attempts. */
|
|
19
18
|
static readonly defaultForHttp: FixedRetryPolicySpec = { kind: "fixed", maxAttempts: 3, delayMs: 1000 };
|
|
20
19
|
|
|
21
|
-
/** Default for LLM / agent calls: 3 tries, 2s fixed backoff. */
|
|
22
20
|
static readonly defaultForAiAgent: FixedRetryPolicySpec = { kind: "fixed", maxAttempts: 3, delayMs: 2000 };
|
|
23
21
|
}
|
|
@@ -3,44 +3,15 @@ import type { ConnectionInvocationAppendArgs, ConnectionInvocationId } from "./r
|
|
|
3
3
|
import type { TelemetrySpanEventRecord } from "./telemetryTypes";
|
|
4
4
|
import type { NodeActivationId, NodeIterationId } from "./workflowTypes";
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Emitted as a span event when a credential is missing required scopes
|
|
8
|
-
* (bind-time) or when callTool returns a permission error (runtime).
|
|
9
|
-
* The credential type id can be looked up from the credential instance when needed.
|
|
10
|
-
*/
|
|
11
6
|
export interface NeedsReconsentEvent {
|
|
12
7
|
readonly serverId: string;
|
|
13
8
|
readonly credentialInstanceId: string;
|
|
14
9
|
readonly missingScopesHint?: readonly string[];
|
|
15
10
|
}
|
|
16
11
|
|
|
17
|
-
/**
|
|
18
|
-
* An opaque MCP tool map: keyed by serverId → (toolName → tool definition).
|
|
19
|
-
* Typed as unknown so core does not depend on the AI SDK's ToolSet type.
|
|
20
|
-
* AIAgentNode (in core-nodes, which does depend on ai) casts this to
|
|
21
|
-
* ReadonlyMap<string, ToolSet> before passing to DeferredMetaToolStrategyFactory.
|
|
22
|
-
*/
|
|
23
12
|
export type AgentMcpToolMap = ReadonlyMap<string, Readonly<Record<string, unknown>>>;
|
|
24
13
|
|
|
25
|
-
/**
|
|
26
|
-
* Contract implemented by the host. Resolves MCP server bindings for an agent run
|
|
27
|
-
* via the standard credential-binding table (one slot per declared server, keyed
|
|
28
|
-
* by `(workflowId, mcpConnectionNodeId, "credential")`), and returns a ready-to-use
|
|
29
|
-
* tool map with wrapped execute callbacks for telemetry and 403 detection.
|
|
30
|
-
* Core-nodes imports this interface so AIAgentNode can inject it without
|
|
31
|
-
* depending on the host.
|
|
32
|
-
*/
|
|
33
14
|
export interface AgentMcpIntegration {
|
|
34
|
-
/**
|
|
35
|
-
* Look up the credential binding per server, validate scopes, open pool
|
|
36
|
-
* connections, and return a tool map keyed by serverId. Each tool's
|
|
37
|
-
* execute callback includes:
|
|
38
|
-
* - Telemetry child span (mcp.server_id, mcp.tool_name attributes)
|
|
39
|
-
* - 403/permission error detection → emits a NeedsReconsentEvent span event
|
|
40
|
-
*
|
|
41
|
-
* Throws `AgentBindError` on validation failures (missing server, unbound
|
|
42
|
-
* credential slot, missing credential instance, insufficient scopes).
|
|
43
|
-
*/
|
|
44
15
|
prepareMcpTools(args: {
|
|
45
16
|
readonly workflowId: WorkflowId;
|
|
46
17
|
readonly agentNodeId: NodeId;
|
|
@@ -50,15 +21,10 @@ export interface AgentMcpIntegration {
|
|
|
50
21
|
readonly startChildSpan: (args: { readonly name: string; readonly attributes?: Record<string, string> }) => {
|
|
51
22
|
readonly end: (args?: { status?: "ok" | "error"; statusMessage?: string }) => void;
|
|
52
23
|
};
|
|
53
|
-
/** Per-MCP-tool-call invocation appender. Optional; when omitted the wrapper emits only telemetry spans. */
|
|
54
24
|
readonly appendMcpInvocation?: (args: ConnectionInvocationAppendArgs) => Promise<void>;
|
|
55
|
-
/** Agent activation id to attach to each invocation record (used by canvas + inspector grouping). */
|
|
56
25
|
readonly parentAgentActivationId?: NodeActivationId;
|
|
57
|
-
/** Per-item iteration id when the agent runs inside a per-item loop. */
|
|
58
26
|
readonly iterationId?: NodeIterationId;
|
|
59
|
-
/** Item index (0-based) of the iteration that owns these tool calls. */
|
|
60
27
|
readonly itemIndex?: number;
|
|
61
|
-
/** Parent invocation id when this agent is itself executing as a sub-agent. */
|
|
62
28
|
readonly parentInvocationId?: ConnectionInvocationId;
|
|
63
29
|
}): Promise<AgentMcpToolMap>;
|
|
64
30
|
}
|
|
@@ -1,45 +1,18 @@
|
|
|
1
1
|
import type { JsonValue, NodeId } from "./workflowTypes";
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* One assertion emitted by an assertion-emitting node (a node whose config sets
|
|
5
|
-
* `emitsAssertions: true`). Each emitted item on `main` carries one of these as `item.json`.
|
|
6
|
-
*
|
|
7
|
-
* Pass/fail is derived from `score >= (passThreshold ?? 0.5)` — see {@link deriveAssertionPassed}.
|
|
8
|
-
* The `errored` marker is for cases where the assertion code itself threw (distinct from
|
|
9
|
-
* "the assertion was evaluated and the score was low") and is treated as a hard fail in rollups
|
|
10
|
-
* regardless of `score`.
|
|
11
|
-
*/
|
|
12
3
|
export interface AssertionResult {
|
|
13
4
|
readonly name: string;
|
|
14
|
-
/** 0..1 score. Source of truth for pass/fail (compared against `passThreshold`). */
|
|
15
5
|
readonly score: number;
|
|
16
|
-
/** 0..1 threshold for "passed". When omitted, consumers default to 0.5. */
|
|
17
6
|
readonly passThreshold?: number;
|
|
18
|
-
/** True when evaluating the assertion threw — treated as fail regardless of `score`. */
|
|
19
7
|
readonly errored?: true;
|
|
20
|
-
/** What the assertion expected. Free-form JSON; UIs render with a JSON viewer. */
|
|
21
8
|
readonly expected?: JsonValue;
|
|
22
|
-
/** What the workflow actually produced. */
|
|
23
9
|
readonly actual?: JsonValue;
|
|
24
|
-
/** Short human-readable explanation, especially for fails / errors. */
|
|
25
10
|
readonly message?: string;
|
|
26
|
-
/** Bag of supplemental fields (e.g. judge prompt, judge raw response, comparison method). */
|
|
27
11
|
readonly details?: Readonly<Record<string, JsonValue>>;
|
|
28
12
|
}
|
|
29
13
|
|
|
30
|
-
/**
|
|
31
|
-
* Default {@link AssertionResult.passThreshold} when authors omit it. Boolean-style assertions
|
|
32
|
-
* (assertEqual / contains / etc.) emit `score: 1` or `score: 0` so this default works for them;
|
|
33
|
-
* AI-judge assertions are expected to set their own threshold.
|
|
34
|
-
*/
|
|
35
14
|
export const DEFAULT_ASSERTION_PASS_THRESHOLD = 0.5;
|
|
36
15
|
|
|
37
|
-
/**
|
|
38
|
-
* Derive whether an assertion result is considered "passing" using the score-based contract:
|
|
39
|
-
* `errored` always fails, otherwise `score >= (passThreshold ?? 0.5)`. This is the canonical
|
|
40
|
-
* derivation — UI and rollup code should call it rather than inlining the comparison so future
|
|
41
|
-
* tweaks (e.g. NaN handling) land in one place.
|
|
42
|
-
*/
|
|
43
16
|
export function deriveAssertionPassed(result: {
|
|
44
17
|
readonly score: number;
|
|
45
18
|
readonly passThreshold?: number;
|
|
@@ -50,14 +23,8 @@ export function deriveAssertionPassed(result: {
|
|
|
50
23
|
return result.score >= threshold;
|
|
51
24
|
}
|
|
52
25
|
|
|
53
|
-
/**
|
|
54
|
-
* Provenance for a persisted {@link AssertionResult}: which node produced it and where in the
|
|
55
|
-
* per-item iteration tree it landed. Filled in by the host-side persister, not the node itself.
|
|
56
|
-
*/
|
|
57
26
|
export interface AssertionResultProvenance {
|
|
58
27
|
readonly nodeId: NodeId;
|
|
59
|
-
/** Per-item iteration id when the emitting node ran inside a per-item loop. */
|
|
60
28
|
readonly iterationId?: string;
|
|
61
|
-
/** Item index (0-based) within the activation that produced this assertion. */
|
|
62
29
|
readonly itemIndex?: number;
|
|
63
30
|
}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal base types that have no dependencies on other contracts.
|
|
3
|
-
* Used by credentialTypes, workflowTypes, and other contract layers
|
|
4
|
-
* to avoid circular dependencies.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
export type WorkflowId = string;
|
|
8
2
|
export type NodeId = string;
|
|
9
3
|
export type OutputPortKey = string;
|
|
@@ -1,44 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents a typed store for a single collection.
|
|
3
|
-
* All rows include auto-managed id, created_at, and updated_at fields.
|
|
4
|
-
*/
|
|
5
1
|
export interface CollectionStore<TRow extends Record<string, unknown> = Record<string, unknown>> {
|
|
6
|
-
/**
|
|
7
|
-
* Insert a new row. id, created_at, and updated_at are auto-populated.
|
|
8
|
-
*/
|
|
9
2
|
insert(row: TRow): Promise<TRow & { id: string; created_at: Date; updated_at: Date }>;
|
|
10
3
|
|
|
11
|
-
/**
|
|
12
|
-
* Get a single row by id.
|
|
13
|
-
*/
|
|
14
4
|
get(id: string): Promise<(TRow & { id: string; created_at: Date; updated_at: Date }) | null>;
|
|
15
5
|
|
|
16
|
-
/**
|
|
17
|
-
* Find a single row matching the provided filter.
|
|
18
|
-
*/
|
|
19
6
|
findOne(filter: Partial<TRow>): Promise<(TRow & { id: string; created_at: Date; updated_at: Date }) | null>;
|
|
20
7
|
|
|
21
|
-
/**
|
|
22
|
-
* List rows with optional pagination and filtering.
|
|
23
|
-
*/
|
|
24
8
|
list(opts?: {
|
|
25
9
|
limit?: number;
|
|
26
10
|
offset?: number;
|
|
27
11
|
where?: Partial<TRow>;
|
|
28
12
|
}): Promise<{ rows: ReadonlyArray<TRow & { id: string; created_at: Date; updated_at: Date }>; total: number }>;
|
|
29
13
|
|
|
30
|
-
/**
|
|
31
|
-
* Update a row by id with partial data.
|
|
32
|
-
*/
|
|
33
14
|
update(id: string, patch: Partial<TRow>): Promise<TRow & { id: string; created_at: Date; updated_at: Date }>;
|
|
34
15
|
|
|
35
|
-
/**
|
|
36
|
-
* Delete a row by id. Hard delete only (no soft delete).
|
|
37
|
-
*/
|
|
38
16
|
delete(id: string): Promise<{ deleted: boolean }>;
|
|
39
17
|
}
|
|
40
18
|
|
|
41
|
-
/**
|
|
42
|
-
* Runtime collections context: keyed by collection name.
|
|
43
|
-
*/
|
|
44
19
|
export type CollectionsContext = Readonly<Record<string, CollectionStore>>;
|
|
@@ -13,22 +13,11 @@ export type CredentialFieldSchema = Readonly<{
|
|
|
13
13
|
type: "string" | "password" | "textarea" | "json" | "boolean";
|
|
14
14
|
required?: true;
|
|
15
15
|
order?: number;
|
|
16
|
-
/**
|
|
17
|
-
* Where this field appears in the credential dialog. Use `"advanced"` for optional or
|
|
18
|
-
* power-user fields; they render inside a collapsible section (see `CredentialTypeDefinition.advancedSection`).
|
|
19
|
-
* Defaults to `"default"` when omitted.
|
|
20
|
-
*/
|
|
21
16
|
visibility?: "default" | "advanced";
|
|
22
17
|
placeholder?: string;
|
|
23
18
|
helpText?: string;
|
|
24
|
-
/** When set, host resolves this field from process.env at runtime; env wins over stored values. */
|
|
25
19
|
envVarName?: string;
|
|
26
|
-
/**
|
|
27
|
-
* When set, the dialog shows a copy action for this exact string (e.g. a static OAuth redirect URI
|
|
28
|
-
* pattern or documentation URL). Do not use for secret values.
|
|
29
|
-
*/
|
|
30
20
|
copyValue?: string;
|
|
31
|
-
/** Accessible label for the copy control (default: Copy). */
|
|
32
21
|
copyButtonLabel?: string;
|
|
33
22
|
}>;
|
|
34
23
|
|
|
@@ -93,20 +82,9 @@ export type CredentialOAuth2AuthDefinition = Readonly<
|
|
|
93
82
|
}
|
|
94
83
|
| {
|
|
95
84
|
kind: "oauth2";
|
|
96
|
-
/**
|
|
97
|
-
* Free-form provider identifier for telemetry, DB rows, and Better Auth provider naming.
|
|
98
|
-
* Not used for any registry lookup — URLs come from {@link authorizeUrl} / {@link tokenUrl}.
|
|
99
|
-
*/
|
|
100
85
|
providerId: string;
|
|
101
|
-
/**
|
|
102
|
-
* Authorization endpoint. May contain `{publicFieldKey}` placeholders that the runtime
|
|
103
|
-
* substitutes from the credential's resolved public config (URL-encoded).
|
|
104
|
-
* Example: `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize`
|
|
105
|
-
*/
|
|
106
86
|
authorizeUrl: string;
|
|
107
|
-
/** Token endpoint. Same templating rules as {@link authorizeUrl}. */
|
|
108
87
|
tokenUrl: string;
|
|
109
|
-
/** Optional userinfo endpoint. Same templating rules as {@link authorizeUrl}. */
|
|
110
88
|
userInfoUrl?: string;
|
|
111
89
|
scopes: ReadonlyArray<string>;
|
|
112
90
|
scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
|
|
@@ -118,11 +96,8 @@ export type CredentialOAuth2AuthDefinition = Readonly<
|
|
|
118
96
|
export type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;
|
|
119
97
|
|
|
120
98
|
export type CredentialAdvancedSectionPresentation = Readonly<{
|
|
121
|
-
/** Collapsible section title (default: "Advanced"). */
|
|
122
99
|
title?: string;
|
|
123
|
-
/** Optional short helper text shown inside the section (above the fields). */
|
|
124
100
|
description?: string;
|
|
125
|
-
/** When true, the advanced section starts expanded. Default: false (collapsed). */
|
|
126
101
|
defaultOpen?: boolean;
|
|
127
102
|
}>;
|
|
128
103
|
|
|
@@ -132,25 +107,13 @@ export type CredentialTypeDefinition = Readonly<{
|
|
|
132
107
|
description?: string;
|
|
133
108
|
publicFields?: ReadonlyArray<CredentialFieldSchema>;
|
|
134
109
|
secretFields?: ReadonlyArray<CredentialFieldSchema>;
|
|
135
|
-
/**
|
|
136
|
-
* Optional labels for the collapsible block that contains every field with `visibility: "advanced"`.
|
|
137
|
-
* If omitted, the UI still shows that block with defaults (title "Advanced", collapsed).
|
|
138
|
-
*/
|
|
139
110
|
advancedSection?: CredentialAdvancedSectionPresentation;
|
|
140
111
|
supportedSourceKinds?: ReadonlyArray<CredentialMaterialSourceKind>;
|
|
141
112
|
auth?: CredentialAuthDefinition;
|
|
142
113
|
}>;
|
|
143
114
|
|
|
144
|
-
/**
|
|
145
|
-
* JSON-shaped credential field bag (public config, resolved secret material, etc.).
|
|
146
|
-
*/
|
|
147
115
|
export type CredentialJsonRecord = Readonly<Record<string, unknown>>;
|
|
148
116
|
|
|
149
|
-
/**
|
|
150
|
-
* Persisted credential instance with typed `publicConfig`.
|
|
151
|
-
* Hosts may specialize `secretRef` with a stricter union while remaining
|
|
152
|
-
* assignable here for session/test callbacks.
|
|
153
|
-
*/
|
|
154
117
|
export type CredentialInstanceRecord<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord> = Readonly<{
|
|
155
118
|
instanceId: CredentialInstanceId;
|
|
156
119
|
typeId: CredentialTypeId;
|
|
@@ -162,23 +125,9 @@ export type CredentialInstanceRecord<TPublicConfig extends CredentialJsonRecord
|
|
|
162
125
|
setupStatus: CredentialSetupStatus;
|
|
163
126
|
createdAt: string;
|
|
164
127
|
updatedAt: string;
|
|
165
|
-
/**
|
|
166
|
-
* Pointer to where the credential material bytes live. For OSS / standalone
|
|
167
|
-
* rows this is `{source: "local", ref: instanceId}` and the bytes co-locate
|
|
168
|
-
* with the row in the workspace DB. For managed-mode rows this is
|
|
169
|
-
* `{source: "control-plane", ref: <cp_id>}` and the bytes live at CP.
|
|
170
|
-
*
|
|
171
|
-
* The seam is read through `CredentialMaterialProvider`. See
|
|
172
|
-
* `docs/design/credentials-oauth-unification.md` ("Material provider seam").
|
|
173
|
-
*/
|
|
174
128
|
material: Readonly<{ source: "local" | "control-plane"; ref: string }>;
|
|
175
129
|
}>;
|
|
176
130
|
|
|
177
|
-
/**
|
|
178
|
-
* Arguments passed to `CredentialType.createSession` and `CredentialType.test`.
|
|
179
|
-
* Declare `TPublicConfig` / `TMaterial` on `CredentialType` so implementations are checked
|
|
180
|
-
* against your credential shapes (similar to `NodeExecutionContext.config` for nodes).
|
|
181
|
-
*/
|
|
182
131
|
export type CredentialSessionFactoryArgs<
|
|
183
132
|
TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,
|
|
184
133
|
TMaterial extends CredentialJsonRecord = CredentialJsonRecord,
|
|
@@ -194,15 +143,23 @@ export type CredentialSessionFactory<
|
|
|
194
143
|
TSession = unknown,
|
|
195
144
|
> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<TSession>;
|
|
196
145
|
|
|
146
|
+
export type CredentialAccessTokenSessionArgs<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord> =
|
|
147
|
+
Readonly<{
|
|
148
|
+
accessToken: string;
|
|
149
|
+
grantedScopes: ReadonlyArray<string>;
|
|
150
|
+
publicConfig: TPublicConfig;
|
|
151
|
+
}>;
|
|
152
|
+
|
|
153
|
+
export type CredentialAccessTokenSessionFactory<
|
|
154
|
+
TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,
|
|
155
|
+
TSession = unknown,
|
|
156
|
+
> = (args: CredentialAccessTokenSessionArgs<TPublicConfig>) => Promise<TSession>;
|
|
157
|
+
|
|
197
158
|
export type CredentialHealthTester<
|
|
198
159
|
TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,
|
|
199
160
|
TMaterial extends CredentialJsonRecord = CredentialJsonRecord,
|
|
200
161
|
> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<CredentialHealth>;
|
|
201
162
|
|
|
202
|
-
/**
|
|
203
|
-
* Full credential type implementation: `definition` (UI/schema), `createSession`, and `test`.
|
|
204
|
-
* Use this at registration and config boundaries; `CredentialTypeDefinition` is only the schema slice.
|
|
205
|
-
*/
|
|
206
163
|
export type CredentialType<
|
|
207
164
|
TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,
|
|
208
165
|
TMaterial extends CredentialJsonRecord = CredentialJsonRecord,
|
|
@@ -210,14 +167,10 @@ export type CredentialType<
|
|
|
210
167
|
> = Readonly<{
|
|
211
168
|
definition: CredentialTypeDefinition;
|
|
212
169
|
createSession: CredentialSessionFactory<TPublicConfig, TMaterial, TSession>;
|
|
170
|
+
createSessionFromAccessToken?: CredentialAccessTokenSessionFactory<TPublicConfig, TSession>;
|
|
213
171
|
test: CredentialHealthTester<TPublicConfig, TMaterial>;
|
|
214
172
|
}>;
|
|
215
173
|
|
|
216
|
-
/**
|
|
217
|
-
* Credential type with unspecified generics — used for `CodemationConfig.credentialTypes`, the host registry,
|
|
218
|
-
* and anywhere a concrete `CredentialType<YourPublic, YourMaterial, YourSession>` is placed in a heterogeneous list.
|
|
219
|
-
* Using `any` here avoids unsafe `as` casts while keeping typed `satisfies CredentialType<…>` definitions.
|
|
220
|
-
*/
|
|
221
174
|
export type AnyCredentialType = CredentialType<any, any, unknown>;
|
|
222
175
|
|
|
223
176
|
export interface CredentialSessionService {
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import type { NodeId, WorkflowId } from "./baseTypes";
|
|
4
|
+
import type { CredentialRequirement } from "./credentialTypes";
|
|
5
|
+
import type { PersistedWorkflowSnapshot } from "./runTypes";
|
|
6
|
+
import type { JsonObject, NodeDefinition, PollingTriggerConfig } from "./workflowTypes";
|
|
7
|
+
import type { WorkflowDefinition } from "../types";
|
|
8
|
+
import { AgentConfigInspector } from "../ai/AgentConfigInspectorFactory";
|
|
9
|
+
import { PersistedWorkflowTokenRegistry } from "../workflowSnapshots/PersistedWorkflowTokenRegistry";
|
|
10
|
+
import { WorkflowSnapshotCodec } from "../workflowSnapshots/WorkflowSnapshotCodec";
|
|
11
|
+
|
|
12
|
+
export const DEPLOYMENT_MANIFEST_SCHEMA_VERSION = 2 as const;
|
|
13
|
+
|
|
14
|
+
export type DeploymentManifestSchemaVersion = typeof DEPLOYMENT_MANIFEST_SCHEMA_VERSION;
|
|
15
|
+
|
|
16
|
+
export type ManifestTriggerConfig = Readonly<{
|
|
17
|
+
nodeId: NodeId;
|
|
18
|
+
triggerKind: "live" | "test";
|
|
19
|
+
config: JsonObject;
|
|
20
|
+
pollIntervalMs?: number;
|
|
21
|
+
nodeTypeId?: string;
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
export type ManifestNodeCredentialShape = Readonly<{
|
|
25
|
+
nodeId: NodeId;
|
|
26
|
+
requirements: ReadonlyArray<CredentialRequirement>;
|
|
27
|
+
}>;
|
|
28
|
+
|
|
29
|
+
export type WorkflowDeploymentManifest<TCanvas = JsonObject> = Readonly<{
|
|
30
|
+
manifestId: string;
|
|
31
|
+
schemaVersion: DeploymentManifestSchemaVersion;
|
|
32
|
+
workflowId: WorkflowId;
|
|
33
|
+
canvas: TCanvas;
|
|
34
|
+
snapshot: PersistedWorkflowSnapshot;
|
|
35
|
+
triggers: ReadonlyArray<ManifestTriggerConfig>;
|
|
36
|
+
credentialShapes: ReadonlyArray<ManifestNodeCredentialShape>;
|
|
37
|
+
}>;
|
|
38
|
+
|
|
39
|
+
export function serializeManifest<TCanvas>(manifest: WorkflowDeploymentManifest<TCanvas>): string {
|
|
40
|
+
return JSON.stringify(manifest);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function deserializeManifest<TCanvas = JsonObject>(raw: string): WorkflowDeploymentManifest<TCanvas> {
|
|
44
|
+
return JSON.parse(raw) as WorkflowDeploymentManifest<TCanvas>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type ManifestCanvasNode = Readonly<{
|
|
48
|
+
id: NodeId;
|
|
49
|
+
kind: string;
|
|
50
|
+
name: string | undefined;
|
|
51
|
+
type?: string;
|
|
52
|
+
role?: string;
|
|
53
|
+
triggerKind?: "live" | "test";
|
|
54
|
+
declaredOutputPorts?: ReadonlyArray<string>;
|
|
55
|
+
declaredInputPorts?: ReadonlyArray<string>;
|
|
56
|
+
}>;
|
|
57
|
+
|
|
58
|
+
export type ManifestCanvas = Readonly<{
|
|
59
|
+
id: WorkflowId;
|
|
60
|
+
name: string;
|
|
61
|
+
nodes: ReadonlyArray<ManifestCanvasNode>;
|
|
62
|
+
edges: WorkflowDefinition["edges"];
|
|
63
|
+
}>;
|
|
64
|
+
|
|
65
|
+
type TriggerNodeConfigShape = Readonly<{ triggerKind?: "live" | "test" }>;
|
|
66
|
+
|
|
67
|
+
function isPollingTriggerConfig(config: unknown): config is PollingTriggerConfig {
|
|
68
|
+
return typeof (config as PollingTriggerConfig).getTriggerPollConfig === "function";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function resolveNodeTypeName(node: NodeDefinition): string {
|
|
72
|
+
const configToken = node.config?.type as Readonly<{ name?: unknown }> | undefined;
|
|
73
|
+
if (typeof configToken?.name === "string" && configToken.name) {
|
|
74
|
+
return configToken.name;
|
|
75
|
+
}
|
|
76
|
+
const nodeToken = node.type as Readonly<{ name?: unknown }> | undefined;
|
|
77
|
+
if (typeof nodeToken?.name === "string" && nodeToken.name) {
|
|
78
|
+
return nodeToken.name;
|
|
79
|
+
}
|
|
80
|
+
return "Node";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function resolveCanvasNode(node: NodeDefinition): ManifestCanvasNode {
|
|
84
|
+
const config = node.config;
|
|
85
|
+
const type = resolveNodeTypeName(node);
|
|
86
|
+
const role = AgentConfigInspector.isAgentNodeConfig(config) ? "agent" : "workflowNode";
|
|
87
|
+
const triggerKind = node.kind === "trigger" ? ((config as TriggerNodeConfigShape).triggerKind ?? "live") : undefined;
|
|
88
|
+
const c = config as {
|
|
89
|
+
declaredOutputPorts?: readonly string[];
|
|
90
|
+
declaredInputPorts?: readonly string[];
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
id: node.id,
|
|
94
|
+
kind: node.kind,
|
|
95
|
+
name: node.name ?? config?.name,
|
|
96
|
+
type,
|
|
97
|
+
role,
|
|
98
|
+
...(triggerKind !== undefined && { triggerKind }),
|
|
99
|
+
...(c.declaredOutputPorts !== undefined && { declaredOutputPorts: c.declaredOutputPorts }),
|
|
100
|
+
...(c.declaredInputPorts !== undefined && { declaredInputPorts: c.declaredInputPorts }),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function emitWorkflowManifest(workflow: WorkflowDefinition): WorkflowDeploymentManifest<ManifestCanvas> {
|
|
105
|
+
const registry = new PersistedWorkflowTokenRegistry();
|
|
106
|
+
registry.registerFromWorkflows([workflow]);
|
|
107
|
+
const codec = new WorkflowSnapshotCodec(registry);
|
|
108
|
+
const snapshot = codec.create(workflow);
|
|
109
|
+
|
|
110
|
+
const canvas = {
|
|
111
|
+
id: workflow.id,
|
|
112
|
+
name: workflow.name,
|
|
113
|
+
nodes: workflow.nodes.map(resolveCanvasNode),
|
|
114
|
+
edges: workflow.edges,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const triggers: ManifestTriggerConfig[] = workflow.nodes
|
|
118
|
+
.filter((n) => n.kind === "trigger")
|
|
119
|
+
.map((n) => {
|
|
120
|
+
const config = n.config;
|
|
121
|
+
const cfg = config as unknown as Record<string, unknown>;
|
|
122
|
+
const triggerKind = (config as TriggerNodeConfigShape).triggerKind ?? "live";
|
|
123
|
+
const pollCfg = isPollingTriggerConfig(config) ? config.getTriggerPollConfig() : undefined;
|
|
124
|
+
const endpointKey = typeof cfg["endpointKey"] === "string" ? cfg["endpointKey"] : undefined;
|
|
125
|
+
const methods = Array.isArray(cfg["methods"]) ? (cfg["methods"] as string[]) : undefined;
|
|
126
|
+
const webhookFields: JsonObject =
|
|
127
|
+
endpointKey !== undefined && methods !== undefined ? { endpointKey, methods } : {};
|
|
128
|
+
const nodeTypeId = registry.getTokenId(config.type) ?? undefined;
|
|
129
|
+
const entry: ManifestTriggerConfig = {
|
|
130
|
+
nodeId: n.id,
|
|
131
|
+
triggerKind,
|
|
132
|
+
config: pollCfg !== undefined ? pollCfg.config : webhookFields,
|
|
133
|
+
nodeTypeId,
|
|
134
|
+
};
|
|
135
|
+
if (pollCfg?.pollIntervalMs !== undefined) {
|
|
136
|
+
return { ...entry, pollIntervalMs: pollCfg.pollIntervalMs };
|
|
137
|
+
}
|
|
138
|
+
return entry;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const credentialShapes: ManifestNodeCredentialShape[] = workflow.nodes
|
|
142
|
+
.map((n) => {
|
|
143
|
+
const requirements = n.config.getCredentialRequirements?.();
|
|
144
|
+
if (!requirements || requirements.length === 0) return null;
|
|
145
|
+
return { nodeId: n.id, requirements } satisfies ManifestNodeCredentialShape;
|
|
146
|
+
})
|
|
147
|
+
.filter((s): s is ManifestNodeCredentialShape => s !== null);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
manifestId: randomUUID(),
|
|
151
|
+
schemaVersion: DEPLOYMENT_MANIFEST_SCHEMA_VERSION,
|
|
152
|
+
workflowId: workflow.id,
|
|
153
|
+
canvas,
|
|
154
|
+
snapshot,
|
|
155
|
+
triggers,
|
|
156
|
+
credentialShapes,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { BinaryAttachment, JsonValue, RunId, WorkflowId } from "./workflowTypes";
|
|
2
|
+
import type { NodeId } from "./baseTypes";
|
|
3
|
+
|
|
4
|
+
export type WorkspaceId = string;
|
|
5
|
+
|
|
6
|
+
export type DispatchBinaryRef = BinaryAttachment;
|
|
7
|
+
|
|
8
|
+
export interface DispatchItemMeta {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly json?: JsonValue;
|
|
11
|
+
readonly binary?: Readonly<Record<string, DispatchBinaryRef>>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface WorkflowDispatch {
|
|
15
|
+
readonly runId: RunId;
|
|
16
|
+
readonly workspaceId: WorkspaceId;
|
|
17
|
+
readonly workflowId: WorkflowId;
|
|
18
|
+
readonly triggerNodeId: NodeId;
|
|
19
|
+
readonly items: ReadonlyArray<DispatchItemMeta>;
|
|
20
|
+
readonly triggerContext: JsonValue;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function serializeDispatch(dispatch: WorkflowDispatch): string {
|
|
24
|
+
return JSON.stringify(dispatch);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function deserializeDispatch(raw: string): WorkflowDispatch {
|
|
28
|
+
return JSON.parse(raw) as WorkflowDispatch;
|
|
29
|
+
}
|