@codemation/core 0.11.1 → 0.12.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/{CostCatalogContract-DZgcUBE4.d.cts → CostCatalogContract-DD7fQ4FF.d.cts} +2 -2
  3. package/dist/{EngineRuntimeRegistration.types-Cggm5GVY.d.cts → EngineRuntimeRegistration.types-DTV5_7Jw.d.cts} +3 -3
  4. package/dist/{EngineRuntimeRegistration.types-BQbS9_gs.d.ts → EngineRuntimeRegistration.types-Dl92Hdoi.d.ts} +2 -2
  5. package/dist/InMemoryRunDataFactory-qMiYjhCK.d.cts +202 -0
  6. package/dist/{ItemsInputNormalizer-D-MH8MBs.js → ItemsInputNormalizer-BhuxvZh5.js} +2 -2
  7. package/dist/{ItemsInputNormalizer-D-MH8MBs.js.map → ItemsInputNormalizer-BhuxvZh5.js.map} +1 -1
  8. package/dist/{ItemsInputNormalizer-_Mfcd3YU.d.ts → ItemsInputNormalizer-C09a7iFP.d.ts} +2 -2
  9. package/dist/{ItemsInputNormalizer-C_dpn76M.d.cts → ItemsInputNormalizer-DLaD6rTl.d.cts} +3 -3
  10. package/dist/{ItemsInputNormalizer-CwdOhSAK.cjs → ItemsInputNormalizer-Div-fb6a.cjs} +2 -2
  11. package/dist/{ItemsInputNormalizer-CwdOhSAK.cjs.map → ItemsInputNormalizer-Div-fb6a.cjs.map} +1 -1
  12. package/dist/{RunIntentService-BVur7x9n.d.ts → RunIntentService-BOSGwmqn.d.ts} +18 -4
  13. package/dist/{RunIntentService-CEF-sFfI.d.cts → RunIntentService-CWMMrAP4.d.cts} +18 -4
  14. package/dist/{agentMcpTypes-ZiNbNsEi.d.cts → agentMcpTypes-DUmniLOY.d.cts} +183 -4
  15. package/dist/bootstrap/index.cjs +3 -3
  16. package/dist/bootstrap/index.d.cts +63 -7
  17. package/dist/bootstrap/index.d.ts +5 -5
  18. package/dist/bootstrap/index.js +3 -3
  19. package/dist/{bootstrap-D_Yyi0wL.js → bootstrap-CKTMMNmL.js} +173 -4
  20. package/dist/bootstrap-CKTMMNmL.js.map +1 -0
  21. package/dist/{bootstrap-BxuTFTLB.cjs → bootstrap-D460dCgS.cjs} +175 -4
  22. package/dist/bootstrap-D460dCgS.cjs.map +1 -0
  23. package/dist/browser.cjs +3 -2
  24. package/dist/browser.d.cts +4 -4
  25. package/dist/browser.d.ts +3 -3
  26. package/dist/browser.js +3 -3
  27. package/dist/contracts.d.cts +5 -5
  28. package/dist/contracts.d.ts +2 -2
  29. package/dist/{di-0Wop7z1y.js → di-DdsgWfVy.js} +31 -2
  30. package/dist/di-DdsgWfVy.js.map +1 -0
  31. package/dist/{di-BlEKdoZS.cjs → di-tO6R7VJV.cjs} +36 -1
  32. package/dist/di-tO6R7VJV.cjs.map +1 -0
  33. package/dist/{executionPersistenceContracts-BgZMRsTa.d.cts → executionPersistenceContracts-DenJJK2T.d.cts} +2 -2
  34. package/dist/{index-62Ba9f7D.d.ts → index-BZDhEQ6W.d.ts} +277 -101
  35. package/dist/{index-zWGtEhrf.d.ts → index-CSKKuK60.d.ts} +441 -5
  36. package/dist/index.cjs +71 -161
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +395 -97
  39. package/dist/index.d.ts +5 -5
  40. package/dist/index.js +56 -159
  41. package/dist/index.js.map +1 -1
  42. package/dist/{params-B5SENSzZ.d.cts → params-DqRvku2h.d.cts} +2 -2
  43. package/dist/{runtime-cxmUkk0l.js → runtime-BPZgnZ9G.js} +611 -16
  44. package/dist/runtime-BPZgnZ9G.js.map +1 -0
  45. package/dist/{runtime-DBzq5YBi.cjs → runtime-CyW9c9XM.cjs} +670 -15
  46. package/dist/runtime-CyW9c9XM.cjs.map +1 -0
  47. package/dist/testing.cjs +3 -3
  48. package/dist/testing.d.cts +3 -3
  49. package/dist/testing.d.ts +3 -3
  50. package/dist/testing.js +3 -3
  51. package/package.json +1 -1
  52. package/src/authoring/defineHumanApprovalNode.types.ts +379 -0
  53. package/src/authoring/index.ts +6 -0
  54. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +29 -0
  55. package/src/contracts/CodemationTelemetryAttributeNames.ts +10 -0
  56. package/src/contracts/credentialTypes.ts +10 -0
  57. package/src/contracts/hitlSeamTypes.ts +34 -0
  58. package/src/contracts/humanTaskStoreTypes.ts +48 -0
  59. package/src/contracts/inboxChannelTypes.ts +58 -0
  60. package/src/contracts/index.ts +3 -0
  61. package/src/contracts/runTypes.ts +61 -3
  62. package/src/contracts/runtimeTypes.ts +112 -0
  63. package/src/credentials/CredentialMaterialProvider.types.ts +61 -0
  64. package/src/credentials/ManagedCredentialMaterialWriteError.ts +14 -0
  65. package/src/credentials/ManagedMaterialFetchError.ts +16 -0
  66. package/src/execution/ActivationEnqueueService.ts +16 -0
  67. package/src/execution/DefaultExecutionContextFactory.ts +11 -0
  68. package/src/execution/NodeExecutionSnapshotFactory.ts +7 -1
  69. package/src/execution/NodeExecutor.ts +60 -1
  70. package/src/execution/NodeExecutorFactory.ts +12 -2
  71. package/src/execution/NodeSuspensionHandler.ts +220 -0
  72. package/src/execution/PersistedRunStateTerminalBuilder.ts +5 -2
  73. package/src/execution/RunStateSemantics.ts +5 -0
  74. package/src/execution/RunSuspendedError.ts +21 -0
  75. package/src/index.ts +40 -0
  76. package/src/orchestration/Engine.ts +12 -2
  77. package/src/orchestration/EngineWaiters.ts +1 -1
  78. package/src/orchestration/NodeExecutionRequestHandlerService.ts +25 -2
  79. package/src/orchestration/RunContinuationService.ts +226 -2
  80. package/src/orchestration/TestSuiteOrchestrator.ts +5 -4
  81. package/src/runtime/RunIntentService.ts +3 -0
  82. package/src/workflow/dsl/ChainCursorResolver.ts +36 -0
  83. package/dist/InMemoryRunDataFactory-C7YItvHG.d.cts +0 -123
  84. package/dist/bootstrap-BxuTFTLB.cjs.map +0 -1
  85. package/dist/bootstrap-D_Yyi0wL.js.map +0 -1
  86. package/dist/di-0Wop7z1y.js.map +0 -1
  87. package/dist/di-BlEKdoZS.cjs.map +0 -1
  88. package/dist/runtime-DBzq5YBi.cjs.map +0 -1
  89. package/dist/runtime-cxmUkk0l.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"bootstrap-D_Yyi0wL.js","names":["out: RunPruneCandidate[]","engine: TestSuiteOrchestratorEngine","testSuiteRunIdFactory: TestSuiteRunIdFactory","credentialResolverFactory: CredentialResolverFactory","abortControllerFactory: AbortControllerFactory","eventBus: RunEventBus | undefined","currentDate: () => Date","setupContext: TestTriggerSetupContext","cases: TestSuiteCaseOutcome[]","waitForSlot: Promise<void> | undefined","releaseSlot: (() => void) | undefined","queue: Array<Promise<void>>","generationError: Error | undefined","status: TestSuiteRunStatus","executionOptions: RunExecutionOptions","terminal: Extract<RunResult, { status: \"completed\" | \"failed\" }>","status: TestCaseRunStatus"],"sources":["../src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts","../src/runStorage/RunSummaryMapper.ts","../src/runStorage/InMemoryWorkflowExecutionRepository.ts","../src/orchestration/AbortControllerFactory.ts","../src/orchestration/TestSuiteOrchestrator.ts","../src/orchestration/TestSuiteRunIdFactory.ts","../src/scheduler/InlineDrivingSchedulerFactory.ts","../src/bootstrap/runtime/EngineRuntimeRegistrar.ts"],"sourcesContent":["import {\n EngineExecutionLimitsPolicy,\n ENGINE_EXECUTION_LIMITS_DEFAULTS,\n type EngineExecutionLimitsPolicyConfig,\n} from \"./EngineExecutionLimitsPolicy\";\n\n/**\n * Builds {@link EngineExecutionLimitsPolicy} by merging {@link ENGINE_EXECUTION_LIMITS_DEFAULTS} with optional `overrides` (e.g. host `runtime.engineExecutionLimits`).\n */\nexport class EngineExecutionLimitsPolicyFactory {\n create(overrides?: Partial<EngineExecutionLimitsPolicyConfig>): EngineExecutionLimitsPolicy {\n return new EngineExecutionLimitsPolicy({ ...ENGINE_EXECUTION_LIMITS_DEFAULTS, ...overrides });\n }\n}\n","import { RunFinishedAtFactory } from \"../contracts/runFinishedAtFactory\";\nimport type { PersistedRunState, RunSummary } from \"../types\";\n\n/** Maps persisted run state to API run summaries for listings. */\nexport class RunSummaryMapper {\n static fromPersistedState(state: PersistedRunState): RunSummary {\n return {\n runId: state.runId,\n workflowId: state.workflowId,\n startedAt: state.startedAt,\n status: state.status,\n finishedAt: RunFinishedAtFactory.resolveIso(state),\n parent: state.parent,\n executionOptions: state.executionOptions,\n };\n }\n}\n","import type {\n EngineRunCounters,\n NodeId,\n NodeOutputs,\n ParentExecutionRef,\n PersistedRunSchedulingState,\n PersistedRunState,\n RunId,\n RunSummary,\n WorkflowExecutionListingRepository,\n WorkflowExecutionPruneRepository,\n WorkflowExecutionRepository,\n RunPruneCandidate,\n WorkflowId,\n} from \"../types\";\nimport { RunFinishedAtFactory } from \"../contracts/runFinishedAtFactory\";\nimport { RunSummaryMapper } from \"./RunSummaryMapper\";\n\nexport class InMemoryWorkflowExecutionRepository\n implements WorkflowExecutionRepository, WorkflowExecutionListingRepository, WorkflowExecutionPruneRepository\n{\n private readonly runs = new Map<RunId, PersistedRunState>();\n\n async createRun(args: {\n runId: RunId;\n workflowId: WorkflowId;\n startedAt: string;\n parent?: ParentExecutionRef;\n executionOptions?: PersistedRunState[\"executionOptions\"];\n control?: PersistedRunState[\"control\"];\n workflowSnapshot?: PersistedRunState[\"workflowSnapshot\"];\n mutableState?: PersistedRunState[\"mutableState\"];\n policySnapshot?: PersistedRunState[\"policySnapshot\"];\n engineCounters?: EngineRunCounters;\n }): Promise<void> {\n this.runs.set(args.runId, {\n runId: args.runId,\n workflowId: args.workflowId,\n startedAt: args.startedAt,\n revision: 0,\n parent: args.parent,\n executionOptions: args.executionOptions,\n control: args.control,\n workflowSnapshot: args.workflowSnapshot,\n mutableState: args.mutableState,\n policySnapshot: args.policySnapshot,\n engineCounters: args.engineCounters,\n status: \"running\",\n queue: [],\n outputsByNode: {} as Record<NodeId, NodeOutputs>,\n nodeSnapshotsByNodeId: {},\n connectionInvocations: [],\n });\n }\n\n async load(runId: RunId): Promise<PersistedRunState | undefined> {\n return this.runs.get(runId);\n }\n\n async loadSchedulingState(runId: RunId): Promise<PersistedRunSchedulingState | undefined> {\n const state = this.runs.get(runId);\n if (!state) {\n return undefined;\n }\n return {\n pending: state.pending ? { ...state.pending } : undefined,\n queue: state.queue.map((entry) => ({ ...entry })),\n };\n }\n\n async save(state: PersistedRunState): Promise<void> {\n this.runs.set(state.runId, { ...state, revision: (state.revision ?? 0) + 1 });\n }\n\n async deleteRun(runId: RunId): Promise<void> {\n this.runs.delete(runId);\n }\n\n async listRuns(args?: Readonly<{ workflowId?: WorkflowId; limit?: number }>): Promise<ReadonlyArray<RunSummary>> {\n const limit = args?.limit ?? 50;\n const summaries = [...this.runs.values()]\n .filter((s) => (args?.workflowId ? s.workflowId === args.workflowId : true))\n .sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n .slice(0, limit)\n .map((s) => RunSummaryMapper.fromPersistedState(s));\n return summaries;\n }\n\n async listRunsOlderThan(\n args: Readonly<{ nowIso: string; defaultRetentionSeconds: number; limit?: number }>,\n ): Promise<ReadonlyArray<RunPruneCandidate>> {\n const limit = args.limit ?? 100;\n const out: RunPruneCandidate[] = [];\n for (const s of this.runs.values()) {\n if (s.status !== \"completed\" && s.status !== \"failed\") continue;\n const finishedAt = RunFinishedAtFactory.resolveIso(s);\n const retentionSeconds = s.policySnapshot?.retentionSeconds ?? args.defaultRetentionSeconds;\n const cutoffIso = new Date(new Date(args.nowIso).getTime() - retentionSeconds * 1000).toISOString();\n if (!finishedAt || finishedAt >= cutoffIso) continue;\n out.push({\n runId: s.runId,\n workflowId: s.workflowId,\n startedAt: s.startedAt,\n finishedAt,\n });\n }\n out.sort((a, b) => a.finishedAt.localeCompare(b.finishedAt));\n return out.slice(0, limit);\n }\n}\n","/**\n * Mints fresh {@link AbortController}s. Injected (rather than direct `new`) to honor the\n * codebase's no-direct-construction rule and to give tests a seam for substituting a fake.\n */\nexport class AbortControllerFactory {\n create(): AbortController {\n return new AbortController();\n }\n}\n","import type { CredentialResolverFactory } from \"../execution/CredentialResolverFactory\";\nimport type { RunEventBus, TestCaseRunStatus, TestSuiteRunStatus } from \"../events/runEvents\";\nimport type {\n Item,\n Items,\n NodeId,\n ParentExecutionRef,\n RunExecutionOptions,\n RunId,\n RunResult,\n TestSuiteRunId,\n TestTriggerNodeConfig,\n TestTriggerSetupContext,\n TriggerNodeConfig,\n WorkflowDefinition,\n WorkflowId,\n} from \"../types\";\n\nimport type { AbortControllerFactory } from \"./AbortControllerFactory\";\nimport { TestSuiteRunIdFactory } from \"./TestSuiteRunIdFactory\";\n\nconst DEFAULT_CONCURRENCY = 4;\n\n/**\n * Engine-facade subset the orchestrator needs. Kept narrow on purpose so unit tests can\n * substitute a fake without depending on the full Engine wiring.\n */\nexport interface TestSuiteOrchestratorEngine {\n runWorkflow(\n wf: WorkflowDefinition,\n startAt: NodeId,\n items: Items,\n parent?: ParentExecutionRef,\n executionOptions?: RunExecutionOptions,\n ): Promise<RunResult>;\n waitForCompletion(runId: RunId): Promise<Extract<RunResult, { status: \"completed\" | \"failed\" }>>;\n}\n\nexport interface TestSuiteCaseOutcome {\n readonly testCaseIndex: number;\n readonly runId: RunId;\n readonly status: TestCaseRunStatus;\n}\n\nexport interface TestSuiteRunResult {\n readonly testSuiteRunId: TestSuiteRunId;\n readonly workflowId: WorkflowId;\n readonly triggerNodeId: NodeId;\n readonly status: TestSuiteRunStatus;\n readonly totalCases: number;\n readonly passedCases: number;\n readonly failedCases: number;\n readonly cases: ReadonlyArray<TestSuiteCaseOutcome>;\n}\n\nexport interface RunTestSuiteArgs {\n readonly workflow: WorkflowDefinition;\n readonly triggerNodeId: NodeId;\n readonly testSuiteRunId?: TestSuiteRunId;\n readonly concurrency?: number;\n readonly signal?: AbortSignal;\n}\n\n/**\n * Drives a {@link TestTriggerNodeConfig.generateItems} iterable into one workflow run per item,\n * with bounded concurrency. Pure engine logic — no persistence, no HTTP, no UI. Hosts adapt by\n * subscribing to {@link RunEventBus} and writing rows on `testSuite*` / `testCase*` / `nodeCompleted`.\n *\n * Cancellation: the supplied `AbortSignal` aborts the source iterable (so credentialed pulls bail)\n * and stops scheduling further cases. In-flight cases are awaited; engine-level cancellation of\n * an already-dispatched run is not yet wired (Phase 2).\n */\nexport class TestSuiteOrchestrator {\n constructor(\n private readonly engine: TestSuiteOrchestratorEngine,\n private readonly testSuiteRunIdFactory: TestSuiteRunIdFactory,\n private readonly credentialResolverFactory: CredentialResolverFactory,\n private readonly abortControllerFactory: AbortControllerFactory,\n private readonly eventBus: RunEventBus | undefined,\n private readonly currentDate: () => Date = () => new Date(),\n ) {}\n\n async runSuite(args: RunTestSuiteArgs): Promise<TestSuiteRunResult> {\n const triggerNodeId = args.triggerNodeId;\n const definition = args.workflow.nodes.find((n) => n.id === triggerNodeId);\n if (!definition) {\n throw new Error(`Unknown trigger nodeId: ${triggerNodeId}`);\n }\n if (definition.kind !== \"trigger\") {\n throw new Error(`Node ${triggerNodeId} is not a trigger`);\n }\n const triggerConfig = definition.config as TriggerNodeConfig;\n if (triggerConfig.triggerKind !== \"test\") {\n throw new Error(\n `Node ${triggerNodeId} is not a test trigger (triggerKind=\"${triggerConfig.triggerKind ?? \"live\"}\")`,\n );\n }\n const testTriggerConfig = triggerConfig as TestTriggerNodeConfig<unknown>;\n if (typeof testTriggerConfig.generateItems !== \"function\") {\n throw new Error(`Test trigger ${triggerNodeId} is missing a generateItems implementation`);\n }\n\n const testSuiteRunId = args.testSuiteRunId ?? this.testSuiteRunIdFactory.makeTestSuiteRunId();\n const concurrency = Math.max(1, args.concurrency ?? testTriggerConfig.concurrency ?? DEFAULT_CONCURRENCY);\n const externalSignal = args.signal;\n const internalAbort = this.abortControllerFactory.create();\n const onExternalAbort = () => internalAbort.abort(externalSignal?.reason);\n if (externalSignal) {\n if (externalSignal.aborted) {\n internalAbort.abort(externalSignal.reason);\n } else {\n externalSignal.addEventListener(\"abort\", onExternalAbort, { once: true });\n }\n }\n\n const triggerNodeName = definition.name ?? testTriggerConfig.name;\n\n await this.publish({\n kind: \"testSuiteStarted\",\n testSuiteRunId,\n workflowId: args.workflow.id,\n triggerNodeId,\n ...(triggerNodeName ? { triggerNodeName } : {}),\n concurrency,\n at: this.now(),\n });\n\n const setupContext: TestTriggerSetupContext = {\n workflowId: args.workflow.id,\n nodeId: triggerNodeId,\n config: testTriggerConfig,\n testSuiteRunId,\n getCredential: this.credentialResolverFactory.create(args.workflow.id, triggerNodeId, testTriggerConfig),\n signal: internalAbort.signal,\n };\n\n const cases: TestSuiteCaseOutcome[] = [];\n let nextIndex = 0;\n let inFlight = 0;\n let waitForSlot: Promise<void> | undefined;\n let releaseSlot: (() => void) | undefined;\n const queue: Array<Promise<void>> = [];\n let generationError: Error | undefined;\n\n const acquireSlot = async (): Promise<void> => {\n while (inFlight >= concurrency) {\n if (!waitForSlot) {\n waitForSlot = new Promise<void>((resolve) => {\n releaseSlot = resolve;\n });\n }\n await waitForSlot;\n }\n inFlight += 1;\n };\n\n const release = (): void => {\n inFlight -= 1;\n if (releaseSlot) {\n const fn = releaseSlot;\n releaseSlot = undefined;\n waitForSlot = undefined;\n fn();\n }\n };\n\n try {\n for await (const item of testTriggerConfig.generateItems(setupContext) as AsyncIterable<Item<unknown>>) {\n if (internalAbort.signal.aborted) {\n break;\n }\n await acquireSlot();\n if (internalAbort.signal.aborted) {\n release();\n break;\n }\n const testCaseIndex = nextIndex++;\n const testCaseLabel = this.resolveCaseLabel(testTriggerConfig, item);\n queue.push(\n this.runOneCase({\n workflow: args.workflow,\n triggerNodeId,\n testSuiteRunId,\n testCaseIndex,\n testCaseLabel,\n item,\n })\n .then((outcome) => {\n cases.push(outcome);\n })\n .finally(release),\n );\n }\n } catch (err) {\n generationError = err instanceof Error ? err : new Error(String(err));\n } finally {\n if (externalSignal) {\n externalSignal.removeEventListener(\"abort\", onExternalAbort);\n }\n }\n\n await Promise.all(queue);\n\n cases.sort((a, b) => a.testCaseIndex - b.testCaseIndex);\n const totalCases = cases.length;\n const passedCases = cases.filter((c) => c.status === \"succeeded\").length;\n const failedCases = cases.filter((c) => c.status === \"failed\").length;\n const status: TestSuiteRunStatus = this.deriveSuiteStatus({\n generationError,\n cancelled: internalAbort.signal.aborted,\n totalCases,\n passedCases,\n failedCases,\n });\n\n await this.publish({\n kind: \"testSuiteFinished\",\n testSuiteRunId,\n workflowId: args.workflow.id,\n status,\n totalCases,\n passedCases,\n failedCases,\n at: this.now(),\n });\n\n if (generationError && status === \"errored\") {\n throw generationError;\n }\n\n return {\n testSuiteRunId,\n workflowId: args.workflow.id,\n triggerNodeId,\n status,\n totalCases,\n passedCases,\n failedCases,\n cases,\n };\n }\n\n private async runOneCase(args: {\n workflow: WorkflowDefinition;\n triggerNodeId: NodeId;\n testSuiteRunId: TestSuiteRunId;\n testCaseIndex: number;\n testCaseLabel: string | undefined;\n item: Item<unknown>;\n }): Promise<TestSuiteCaseOutcome> {\n const executionOptions: RunExecutionOptions = {\n testContext: {\n testSuiteRunId: args.testSuiteRunId,\n testCaseIndex: args.testCaseIndex,\n ...(args.testCaseLabel !== undefined ? { testCaseLabel: args.testCaseLabel } : {}),\n },\n };\n\n const initial = await this.engine.runWorkflow(\n args.workflow,\n args.triggerNodeId,\n [args.item],\n undefined,\n executionOptions,\n );\n\n const runId = initial.runId;\n await this.publish({\n kind: \"testCaseStarted\",\n testSuiteRunId: args.testSuiteRunId,\n testCaseIndex: args.testCaseIndex,\n runId,\n workflowId: args.workflow.id,\n at: this.now(),\n ...(args.testCaseLabel !== undefined ? { testCaseLabel: args.testCaseLabel } : {}),\n });\n\n let terminal: Extract<RunResult, { status: \"completed\" | \"failed\" }>;\n if (initial.status === \"completed\" || initial.status === \"failed\") {\n terminal = initial;\n } else {\n terminal = await this.engine.waitForCompletion(runId);\n }\n\n // RunResult.status from the engine narrows to \"completed\" | \"failed\" here; widening to\n // \"errored\" / \"cancelled\" happens outside this code path (tracker downgrade for assertion\n // failures; outer abort handling for cancelled).\n const status: TestCaseRunStatus = terminal.status === \"completed\" ? \"succeeded\" : \"failed\";\n await this.publish({\n kind: \"testCaseCompleted\",\n testSuiteRunId: args.testSuiteRunId,\n testCaseIndex: args.testCaseIndex,\n runId,\n workflowId: args.workflow.id,\n status,\n at: this.now(),\n });\n return { testCaseIndex: args.testCaseIndex, runId, status };\n }\n\n private deriveSuiteStatus(args: {\n generationError: Error | undefined;\n cancelled: boolean;\n totalCases: number;\n passedCases: number;\n failedCases: number;\n }): TestSuiteRunStatus {\n if (args.generationError && args.totalCases === 0) {\n return \"errored\";\n }\n if (args.cancelled) {\n return \"cancelled\";\n }\n if (args.generationError) {\n return \"errored\";\n }\n if (args.totalCases === 0) {\n return \"succeeded\";\n }\n if (args.failedCases === 0) {\n return \"succeeded\";\n }\n if (args.passedCases === 0) {\n return \"failed\";\n }\n return \"partial\";\n }\n\n private now(): string {\n return this.currentDate().toISOString();\n }\n\n /** Defensive label resolver — author-supplied callbacks throw / return non-strings; we tolerate both. */\n private resolveCaseLabel(config: TestTriggerNodeConfig<unknown>, item: Item<unknown>): string | undefined {\n if (typeof config.caseLabel !== \"function\") return undefined;\n try {\n const result = config.caseLabel(item);\n if (typeof result !== \"string\") return undefined;\n const trimmed = result.trim();\n return trimmed.length === 0 ? undefined : trimmed;\n } catch {\n return undefined;\n }\n }\n\n private async publish(event: Parameters<RunEventBus[\"publish\"]>[0]): Promise<void> {\n if (!this.eventBus) return;\n await this.eventBus.publish(event);\n }\n}\n","import type { TestSuiteRunId } from \"../contracts/testTriggerTypes\";\n\n/**\n * Mints unique TestSuiteRun identifiers. Separated from {@link import(\"../types\").RunIdFactory}\n * so suite ids and per-case workflow run ids never alias.\n */\nexport class TestSuiteRunIdFactory {\n makeTestSuiteRunId(): TestSuiteRunId {\n return `tsr_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n }\n}\n","import { NodeExecutor } from \"../execution/NodeExecutor\";\n\nimport { InlineDrivingScheduler } from \"./InlineDrivingScheduler\";\n\nexport class InlineDrivingSchedulerFactory {\n create(nodeExecutor: NodeExecutor): InlineDrivingScheduler {\n return new InlineDrivingScheduler(nodeExecutor);\n }\n}\n","import { instanceCachingFactory, type DependencyContainer } from \"../../di\";\nimport { CoreTokens } from \"../../di\";\nimport { NoOpAgentMcpIntegration } from \"../../contracts/NoOpAgentMcpIntegration\";\nimport { EngineExecutionLimitsPolicyFactory } from \"../../policies/executionLimits/EngineExecutionLimitsPolicyFactory\";\nimport {\n ChildExecutionScopeFactory,\n DefaultAsyncSleeper,\n InProcessRetryRunnerFactory,\n ItemExprResolver,\n NodeExecutor,\n NodeExecutorFactory,\n NodeInstanceFactoryFactory,\n NodeOutputNormalizer,\n RunnableOutputBehaviorResolver,\n} from \"../../execution\";\nimport {\n EngineFactory,\n EngineWorkflowRunnerServiceFactory,\n RunIntentServiceFactory,\n RunIntentService,\n WorkflowRepositoryWebhookTriggerMatcherFactory,\n} from \"../../runtime\";\nimport { InlineDrivingScheduler } from \"../../scheduler/InlineDrivingScheduler\";\nimport { InlineDrivingSchedulerFactory } from \"../../scheduler/InlineDrivingSchedulerFactory\";\nimport { Engine } from \"../../orchestration/Engine\";\nimport type { EngineRuntimeRegistrationOptions } from \"./EngineRuntimeRegistration.types\";\nimport type { WebhookTriggerMatcherProvider } from \"./EngineRuntimeRegistration.types\";\n\n/**\n * Container-first entry: call on a host/test container **after** workflow, run, node, and credential\n * ports are registered. The registrar owns the default inline scheduler, engine binding,\n * and intent-surface wiring so hosts only override the seams they actually replace.\n */\nexport class EngineRuntimeRegistrar {\n register(container: DependencyContainer, options?: EngineRuntimeRegistrationOptions): void {\n this.registerSupportFactories(container);\n this.registerExecutionLimitsPolicy(container, options);\n this.ensureWorkflowNodeInstanceFactory(container);\n this.ensureNodeExecutor(container);\n this.registerDefaultActivationScheduler(container);\n this.registerEngine(container, options);\n this.registerIntentServices(container);\n this.registerAgentMcpIntegration(container);\n }\n\n private registerAgentMcpIntegration(container: DependencyContainer): void {\n if (container.isRegistered(CoreTokens.AgentMcpIntegration, true)) {\n return;\n }\n container.registerInstance(CoreTokens.AgentMcpIntegration, new NoOpAgentMcpIntegration());\n }\n\n private registerSupportFactories(container: DependencyContainer): void {\n if (!container.isRegistered(ItemExprResolver, true)) {\n container.registerSingleton(ItemExprResolver, ItemExprResolver);\n }\n if (!container.isRegistered(NodeOutputNormalizer, true)) {\n container.registerSingleton(NodeOutputNormalizer, NodeOutputNormalizer);\n }\n if (!container.isRegistered(RunnableOutputBehaviorResolver, true)) {\n container.registerSingleton(RunnableOutputBehaviorResolver, RunnableOutputBehaviorResolver);\n }\n if (!container.isRegistered(ChildExecutionScopeFactory, true)) {\n container.register(ChildExecutionScopeFactory, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n return new ChildExecutionScopeFactory(dependencyContainer.resolve(CoreTokens.ActivationIdFactory));\n }),\n });\n }\n container.registerSingleton(EngineExecutionLimitsPolicyFactory, EngineExecutionLimitsPolicyFactory);\n container.registerSingleton(NodeInstanceFactoryFactory, NodeInstanceFactoryFactory);\n container.registerSingleton(DefaultAsyncSleeper, DefaultAsyncSleeper);\n container.registerSingleton(InProcessRetryRunnerFactory, InProcessRetryRunnerFactory);\n container.registerSingleton(NodeExecutorFactory, NodeExecutorFactory);\n container.registerSingleton(InlineDrivingSchedulerFactory, InlineDrivingSchedulerFactory);\n container.registerSingleton(RunIntentServiceFactory, RunIntentServiceFactory);\n container.registerSingleton(EngineWorkflowRunnerServiceFactory, EngineWorkflowRunnerServiceFactory);\n container.registerSingleton(\n WorkflowRepositoryWebhookTriggerMatcherFactory,\n WorkflowRepositoryWebhookTriggerMatcherFactory,\n );\n }\n\n private registerExecutionLimitsPolicy(\n container: DependencyContainer,\n options: EngineRuntimeRegistrationOptions | undefined,\n ): void {\n if (container.isRegistered(CoreTokens.EngineExecutionLimitsPolicy, true)) {\n return;\n }\n container.register(CoreTokens.EngineExecutionLimitsPolicy, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n const fromResolver = options?.resolveEngineExecutionLimits?.();\n const merged = fromResolver ?? options?.engineExecutionLimits;\n return dependencyContainer.resolve(EngineExecutionLimitsPolicyFactory).create(merged);\n }),\n });\n }\n\n private ensureWorkflowNodeInstanceFactory(container: DependencyContainer): void {\n if (container.isRegistered(CoreTokens.WorkflowNodeInstanceFactory, true)) {\n return;\n }\n container.register(CoreTokens.WorkflowNodeInstanceFactory, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n return dependencyContainer\n .resolve(NodeInstanceFactoryFactory)\n .create(dependencyContainer.resolve(CoreTokens.NodeResolver));\n }),\n });\n }\n\n private ensureNodeExecutor(container: DependencyContainer): void {\n if (container.isRegistered(NodeExecutor, true)) {\n return;\n }\n container.register(NodeExecutor, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n const retryRunner = dependencyContainer\n .resolve(InProcessRetryRunnerFactory)\n .create(dependencyContainer.resolve(DefaultAsyncSleeper));\n return dependencyContainer\n .resolve(NodeExecutorFactory)\n .create(\n dependencyContainer.resolve(CoreTokens.WorkflowNodeInstanceFactory),\n retryRunner,\n dependencyContainer.resolve(RunnableOutputBehaviorResolver),\n );\n }),\n });\n }\n\n private registerDefaultActivationScheduler(container: DependencyContainer): void {\n if (container.isRegistered(CoreTokens.NodeActivationScheduler, true)) {\n return;\n }\n container.register(InlineDrivingScheduler, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n return dependencyContainer\n .resolve(InlineDrivingSchedulerFactory)\n .create(dependencyContainer.resolve(NodeExecutor));\n }),\n });\n container.register(CoreTokens.NodeActivationScheduler, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n return dependencyContainer.resolve(InlineDrivingScheduler);\n }),\n });\n }\n\n private registerEngine(container: DependencyContainer, options: EngineRuntimeRegistrationOptions | undefined): void {\n container.registerSingleton(EngineFactory, EngineFactory);\n const matcherProvider = this.resolveMatcherProvider(options);\n container.register(Engine, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n const liveWorkflowRepository = dependencyContainer.resolve(CoreTokens.LiveWorkflowRepository);\n const nodeResolver = dependencyContainer.resolve(CoreTokens.NodeResolver);\n const tokenRegistryLike = dependencyContainer.resolve(CoreTokens.PersistedWorkflowTokenRegistry);\n const workflowActivationPolicy = dependencyContainer.resolve(CoreTokens.WorkflowActivationPolicy);\n const webhookTriggerMatcher = matcherProvider.createMatcher(dependencyContainer);\n const workflowNodeInstanceFactory = dependencyContainer.resolve(CoreTokens.WorkflowNodeInstanceFactory);\n const triggerRuntimeDiagnostics = options?.triggerRuntimeDiagnosticsProvider?.create(dependencyContainer);\n return dependencyContainer.resolve(EngineFactory).create({\n credentialSessions: dependencyContainer.resolve(CoreTokens.CredentialSessionService),\n liveWorkflowRepository,\n workflowRepository: dependencyContainer.resolve(CoreTokens.WorkflowRepository),\n workflowActivationPolicy,\n nodeResolver,\n triggerSetupStateRepository: dependencyContainer.resolve(CoreTokens.TriggerSetupStateRepository),\n webhookTriggerMatcher,\n runIdFactory: dependencyContainer.resolve(CoreTokens.RunIdFactory),\n activationIdFactory: dependencyContainer.resolve(CoreTokens.ActivationIdFactory),\n workflowExecutionRepository: dependencyContainer.resolve(CoreTokens.WorkflowExecutionRepository),\n activationScheduler: dependencyContainer.resolve(CoreTokens.NodeActivationScheduler),\n runDataFactory: dependencyContainer.resolve(CoreTokens.RunDataFactory),\n executionContextFactory: dependencyContainer.resolve(CoreTokens.ExecutionContextFactory),\n nodeExecutor: dependencyContainer.resolve(NodeExecutor),\n eventBus: dependencyContainer.resolve(CoreTokens.RunEventBus),\n tokenRegistry: tokenRegistryLike,\n workflowNodeInstanceFactory,\n executionLimitsPolicy: dependencyContainer.resolve(CoreTokens.EngineExecutionLimitsPolicy),\n workflowPolicyRuntimeDefaults: options?.workflowPolicyRuntimeDefaults,\n triggerRuntimeDiagnostics,\n });\n }),\n });\n }\n\n private registerIntentServices(container: DependencyContainer): void {\n container.register(RunIntentService, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n return dependencyContainer\n .resolve(RunIntentServiceFactory)\n .create(dependencyContainer.resolve(Engine), dependencyContainer.resolve(CoreTokens.WorkflowRepository));\n }),\n });\n container.register(CoreTokens.WorkflowRunnerService, {\n useFactory: instanceCachingFactory((dependencyContainer) => {\n return dependencyContainer\n .resolve(EngineWorkflowRunnerServiceFactory)\n .create(dependencyContainer.resolve(Engine), dependencyContainer.resolve(CoreTokens.WorkflowRepository));\n }),\n });\n }\n\n private resolveMatcherProvider(options: EngineRuntimeRegistrationOptions | undefined): WebhookTriggerMatcherProvider {\n if (options?.webhookTriggerMatcherProvider) {\n return options.webhookTriggerMatcherProvider;\n }\n return {\n createMatcher: (container) =>\n container\n .resolve(WorkflowRepositoryWebhookTriggerMatcherFactory)\n .create(\n container.resolve(CoreTokens.WorkflowRepository),\n container.resolve(CoreTokens.WorkflowActivationPolicy),\n options?.webhookTriggerRoutingDiagnostics,\n ),\n };\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"di-0Wop7z1y.js","names":["out: unknown[]","out","exprArgs: ItemExprArgs","name: string","node: TNodeConfig","AgentConnectionNodeCollector: AgentConnectionNodeCollectorApi","collected: AgentConnectionNodeDescriptor[]","bindingKey: CredentialBindingKey","acceptedTypes: ReadonlyArray<CredentialTypeId>","max: string | undefined"],"sources":["../src/workflow/definition/ConnectionNodeIdFactory.ts","../src/contracts/itemExpr.ts","../src/ai/AgentConfigInspectorFactory.ts","../src/ai/NodeBackedToolConfig.ts","../src/ai/AgentConnectionNodeCollector.ts","../src/workflow/definition/NodeIterationIdFactory.ts","../src/contracts/credentialTypes.ts","../src/contracts/runFinishedAtFactory.ts","../src/contracts/workflowTypes.ts","../src/di/CoreTokens.ts"],"sourcesContent":["import type { NodeId } from \"../../types\";\n\n/**\n * Deterministic ids for workflow connection-owned child nodes (LLM slot, tools, etc.).\n * These are stable across loads.\n */\nexport class ConnectionNodeIdFactory {\n static readonly connectionSegment = \"__conn__\" as const;\n\n static languageModelConnectionNodeId(parentNodeId: NodeId): NodeId {\n return `${parentNodeId}${this.connectionSegment}llm`;\n }\n\n static toolConnectionNodeId(parentNodeId: NodeId, toolName: string): NodeId {\n const normalized = this.normalizeToolName(toolName);\n return `${parentNodeId}${this.connectionSegment}tool${this.connectionSegment}${normalized}`;\n }\n\n static mcpConnectionNodeId(parentNodeId: NodeId, serverId: string): NodeId {\n return `${parentNodeId}${this.connectionSegment}mcp${this.connectionSegment}${serverId}`;\n }\n\n static isMcpConnectionNodeId(nodeId: NodeId): boolean {\n return nodeId.includes(`${this.connectionSegment}mcp${this.connectionSegment}`);\n }\n\n static parseMcpConnectionNodeId(nodeId: NodeId): Readonly<{ parentNodeId: NodeId; serverId: string }> | undefined {\n if (!this.isMcpConnectionNodeId(nodeId)) {\n return undefined;\n }\n const marker = `${this.connectionSegment}mcp${this.connectionSegment}`;\n const idx = nodeId.lastIndexOf(marker);\n if (idx < 0) {\n return undefined;\n }\n const parentNodeId = nodeId.slice(0, idx);\n const serverId = nodeId.slice(idx + marker.length);\n if (!parentNodeId || !serverId) {\n return undefined;\n }\n return { parentNodeId, serverId };\n }\n\n static isLanguageModelConnectionNodeId(nodeId: NodeId): boolean {\n return nodeId.endsWith(`${this.connectionSegment}llm`);\n }\n\n static isToolConnectionNodeId(nodeId: NodeId): boolean {\n return nodeId.includes(`${this.connectionSegment}tool${this.connectionSegment}`);\n }\n\n static parseLanguageModelConnectionNodeId(nodeId: NodeId): Readonly<{ parentNodeId: NodeId }> | undefined {\n if (!this.isLanguageModelConnectionNodeId(nodeId)) {\n return undefined;\n }\n const suffix = `${this.connectionSegment}llm`;\n const parentNodeId = nodeId.slice(0, -suffix.length);\n return parentNodeId ? { parentNodeId } : undefined;\n }\n\n static parseToolConnectionNodeId(\n nodeId: NodeId,\n ): Readonly<{ parentNodeId: NodeId; normalizedToolName: string }> | undefined {\n if (!this.isToolConnectionNodeId(nodeId)) {\n return undefined;\n }\n const marker = `${this.connectionSegment}tool${this.connectionSegment}`;\n const idx = nodeId.lastIndexOf(marker);\n if (idx < 0) {\n return undefined;\n }\n const parentNodeId = nodeId.slice(0, idx);\n const normalizedToolName = nodeId.slice(idx + marker.length);\n if (!parentNodeId || !normalizedToolName) {\n return undefined;\n }\n return { parentNodeId, normalizedToolName };\n }\n\n /** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */\n static isConnectionOwnedDescendantOf(parentNodeId: NodeId, nodeId: NodeId): boolean {\n return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);\n }\n\n /** Normalizes a tool display name to a stable id segment. */\n static normalizeToolName(toolName: string): string {\n return (\n toolName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\") || \"tool\"\n );\n }\n}\n","import type { NodeExecutionContext } from \"./runtimeTypes\";\nimport type { Item, Items, NodeActivationId, NodeId, RunDataSnapshot, RunId, WorkflowId } from \"./workflowTypes\";\n\nconst ITEM_EXPR_BRAND = Symbol.for(\"codemation.itemExpr\");\n\nexport type ItemExprResolvedContext = Readonly<{\n runId: RunId;\n workflowId: WorkflowId;\n nodeId: NodeId;\n activationId: NodeActivationId;\n data: RunDataSnapshot;\n}>;\n\n/**\n * Context aligned with former {@link ItemInputMapperContext} — use **`data`** to read any completed upstream node.\n */\nexport type ItemExprContext = ItemExprResolvedContext;\n\nexport type ItemExprArgs<TItemJson = unknown> = Readonly<{\n item: Item<TItemJson>;\n itemIndex: number;\n items: Items<TItemJson>;\n ctx: ItemExprContext;\n}>;\n\nexport type ItemExprCallback<T, TItemJson = unknown> = (args: ItemExprArgs<TItemJson>) => T | Promise<T>;\n\nexport type ItemExpr<T, TItemJson = unknown> = Readonly<{\n readonly [ITEM_EXPR_BRAND]: true;\n readonly fn: ItemExprCallback<T, TItemJson>;\n}>;\n\nexport function itemExpr<T, TItemJson = unknown>(fn: ItemExprCallback<T, TItemJson>): ItemExpr<T, TItemJson> {\n return { [ITEM_EXPR_BRAND]: true, fn };\n}\n\nexport function isItemExpr<T, TItemJson = unknown>(value: unknown): value is ItemExpr<T, TItemJson> {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const v = value as Record<PropertyKey, unknown>;\n if (v[ITEM_EXPR_BRAND] === true) {\n return true;\n }\n // Support snapshot-hydrated itemExpr wrappers where the symbol brand was lost but the callback survived.\n // Workflow snapshot hydration currently restores function-valued fields (like `fn`) but may drop symbol-keyed brands.\n // We treat the minimal `{ fn: Function }` shape as an itemExpr wrapper to keep runnable configs working.\n const keys = Object.keys(v);\n if (keys.length === 1 && keys[0] === \"fn\" && typeof (v as { fn?: unknown }).fn === \"function\") {\n return true;\n }\n for (const sym of Object.getOwnPropertySymbols(v)) {\n if (sym.description === \"codemation.itemExpr\" && v[sym] === true) {\n return true;\n }\n }\n return false;\n}\n\nfunction containsItemExprInUnknown(value: unknown, seen: WeakSet<object> = new WeakSet()): boolean {\n if (isItemExpr(value)) {\n return true;\n }\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n if (seen.has(value as object)) {\n return false;\n }\n seen.add(value as object);\n if (Array.isArray(value)) {\n return value.some((entry) => containsItemExprInUnknown(entry, seen));\n }\n for (const entry of Object.values(value as Record<string, unknown>)) {\n if (containsItemExprInUnknown(entry, seen)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Deep-resolves {@link itemExpr} leaves. Returns a new graph (does not mutate the original config object).\n */\nexport async function resolveItemExprsInUnknown(\n value: unknown,\n args: ItemExprArgs,\n seen: WeakSet<object> = new WeakSet(),\n): Promise<unknown> {\n if (isItemExpr(value)) {\n return await Promise.resolve(value.fn(args));\n }\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n if (seen.has(value as object)) {\n return value;\n }\n seen.add(value as object);\n if (Array.isArray(value)) {\n const out: unknown[] = [];\n for (let i = 0; i < value.length; i++) {\n out.push(await resolveItemExprsInUnknown(value[i], args, seen));\n }\n return out;\n }\n const rec = value as Record<string, unknown>;\n const entries = Object.entries(rec);\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null && entries.length === 0) {\n return value;\n }\n const out = Object.create(proto) as Record<string, unknown>;\n for (const [k, v] of entries) {\n out[k] = await resolveItemExprsInUnknown(v, args, seen);\n }\n return out;\n}\n\n/**\n * Clones runnable config (best-effort) so per-item {@link itemExpr} resolution never mutates shared instances.\n */\nexport async function resolveItemExprsForExecution(\n config: unknown,\n nodeCtx: NodeExecutionContext,\n item: Item,\n itemIndex: number,\n items: Items,\n): Promise<unknown | undefined> {\n const exprArgs: ItemExprArgs = {\n item,\n itemIndex,\n items,\n ctx: {\n runId: nodeCtx.runId,\n workflowId: nodeCtx.workflowId,\n nodeId: nodeCtx.nodeId,\n activationId: nodeCtx.activationId,\n data: nodeCtx.data,\n },\n };\n if (!containsItemExprInUnknown(config)) {\n return undefined;\n }\n return await resolveItemExprsInUnknown(config, exprArgs);\n}\n","import type { NodeConfigBase } from \"../types\";\nimport { isItemExpr } from \"../contracts/itemExpr\";\nimport type { AgentNodeConfig } from \"./AiHost\";\n\nexport class AgentConfigInspector {\n static isAgentNodeConfig(config: NodeConfigBase | undefined): config is AgentNodeConfig<any, any> {\n if (!config) return false;\n const candidate = config as Partial<AgentNodeConfig<any, any>>;\n return !!candidate.chatModel && this.hasCompatibleMessageConfiguration(candidate);\n }\n\n private static hasCompatibleMessageConfiguration(candidate: Partial<AgentNodeConfig<any, any>>): boolean {\n const messages = candidate.messages;\n if (messages === undefined || messages === null) {\n return false;\n }\n if (Array.isArray(messages)) {\n return messages.length > 0;\n }\n if (typeof messages === \"object\") {\n if (isItemExpr(messages)) {\n return true;\n }\n const o = messages as { prompt?: unknown; buildMessages?: unknown };\n return (Array.isArray(o.prompt) && o.prompt.length > 0) || typeof o.buildMessages === \"function\";\n }\n return false;\n }\n}\n","import type { CredentialRequirement } from \"../contracts/credentialTypes\";\nimport type { TypeToken } from \"../di\";\nimport type { Item, NodeOutputs, RunnableNodeConfig, RunnableNodeInputJson } from \"../types\";\nimport type { input as ZodInput, output as ZodOutput } from \"zod\";\nimport type {\n AgentCanvasPresentation,\n NodeBackedToolConfigOptions,\n NodeBackedToolInputMapper,\n NodeBackedToolInputMapperArgs,\n NodeBackedToolOutputMapper,\n NodeBackedToolOutputMapperArgs,\n ToolConfig,\n ZodSchemaAny,\n} from \"./AiHost\";\n\nexport class NodeBackedToolConfig<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TInputSchema extends ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny,\n> implements ToolConfig {\n readonly type: TypeToken<unknown>;\n readonly toolKind = \"nodeBacked\" as const;\n readonly description?: string;\n readonly presentation?: AgentCanvasPresentation;\n private readonly inputSchemaValue: TInputSchema;\n private readonly outputSchemaValue: TOutputSchema;\n private readonly mapInputValue?: NodeBackedToolInputMapper<TNodeConfig, ZodInput<TInputSchema>>;\n private readonly mapOutputValue?: NodeBackedToolOutputMapper<\n TNodeConfig,\n ZodInput<TInputSchema>,\n ZodOutput<TOutputSchema>\n >;\n\n constructor(\n public readonly name: string,\n public readonly node: TNodeConfig,\n options: NodeBackedToolConfigOptions<TNodeConfig, TInputSchema, TOutputSchema>,\n ) {\n this.type = node.type;\n this.description = options.description;\n this.presentation = options.presentation;\n this.inputSchemaValue = options.inputSchema;\n this.outputSchemaValue = options.outputSchema;\n this.mapInputValue = options.mapInput;\n this.mapOutputValue = options.mapOutput;\n }\n\n getCredentialRequirements(): ReadonlyArray<CredentialRequirement> {\n return this.node.getCredentialRequirements?.() ?? [];\n }\n\n getInputSchema(): TInputSchema {\n return this.inputSchemaValue;\n }\n\n getOutputSchema(): TOutputSchema {\n return this.outputSchemaValue;\n }\n\n toNodeItem(\n args: NodeBackedToolInputMapperArgs<TNodeConfig, ZodInput<TInputSchema>>,\n ): Item<RunnableNodeInputJson<TNodeConfig>> {\n const mapped = this.mapInputValue?.(args) ?? (args.input as RunnableNodeInputJson<TNodeConfig>);\n if (this.isItem(mapped)) {\n return mapped;\n }\n return { json: mapped };\n }\n\n toToolOutput(args: NodeBackedToolOutputMapperArgs<TNodeConfig, ZodInput<TInputSchema>>): ZodOutput<TOutputSchema> {\n const raw = this.mapOutputValue?.(args) ?? this.readDefaultToolOutput(args.outputs);\n return this.outputSchemaValue.parse(raw) as ZodOutput<TOutputSchema>;\n }\n\n private readDefaultToolOutput(outputs: NodeOutputs): unknown {\n const firstMainItem = outputs.main?.[0];\n if (!firstMainItem) {\n throw new Error(`Node-backed tool \"${this.name}\" did not produce a main output item.`);\n }\n return firstMainItem.json;\n }\n\n private isItem(value: unknown): value is Item {\n return typeof value === \"object\" && value !== null && \"json\" in value;\n }\n}\n","import type { CredentialRequirement } from \"../contracts/credentialTypes\";\nimport type { McpServerDeclaration } from \"../contracts/mcpTypes\";\nimport type { NodeConfigBase, NodeConnectionName, NodeId } from \"../types\";\nimport { ConnectionNodeIdFactory } from \"../workflow/definition/ConnectionNodeIdFactory\";\nimport { AgentConfigInspector } from \"./AgentConfigInspectorFactory\";\nimport type { AgentNodeConfig, ToolConfig } from \"./AiHost\";\nimport { NodeBackedToolConfig } from \"./NodeBackedToolConfig\";\n\nexport type AgentConnectionNodeRole = \"languageModel\" | \"tool\" | \"nestedAgent\";\n\nexport type AgentConnectionCredentialSource = Readonly<{\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}>;\n\nexport type AgentConnectionNodeDescriptor = Readonly<{\n nodeId: NodeId;\n parentNodeId: NodeId;\n connectionName: NodeConnectionName;\n role: AgentConnectionNodeRole;\n name: string;\n typeName: string;\n icon?: string;\n credentialSource: AgentConnectionCredentialSource;\n}>;\n\nexport type McpServerResolver = (id: string) => McpServerDeclaration | undefined;\n\ntype AgentConnectionNodeCollectorApi = Readonly<{\n collect(\n parentNodeId: NodeId,\n agentConfig: AgentNodeConfig<any, any>,\n mcpServerResolver?: McpServerResolver,\n ): ReadonlyArray<AgentConnectionNodeDescriptor>;\n}>;\n\nexport const AgentConnectionNodeCollector: AgentConnectionNodeCollectorApi = new (class {\n collect(\n parentNodeId: NodeId,\n agentConfig: AgentNodeConfig<any, any>,\n mcpServerResolver?: McpServerResolver,\n ): ReadonlyArray<AgentConnectionNodeDescriptor> {\n const collected: AgentConnectionNodeDescriptor[] = [];\n this.collectInto(parentNodeId, agentConfig, collected, mcpServerResolver);\n return collected;\n }\n\n private collectInto(\n parentNodeId: NodeId,\n agentConfig: AgentNodeConfig<any, any>,\n collected: AgentConnectionNodeDescriptor[],\n mcpServerResolver?: McpServerResolver,\n ): void {\n collected.push({\n nodeId: ConnectionNodeIdFactory.languageModelConnectionNodeId(parentNodeId),\n parentNodeId,\n connectionName: \"llm\",\n role: \"languageModel\",\n name: agentConfig.chatModel.presentation?.label ?? agentConfig.chatModel.name,\n typeName: agentConfig.chatModel.name,\n icon: agentConfig.chatModel.presentation?.icon,\n credentialSource: agentConfig.chatModel,\n });\n\n for (const tool of agentConfig.tools ?? []) {\n const toolNodeId = ConnectionNodeIdFactory.toolConnectionNodeId(parentNodeId, tool.name);\n const isNestedAgent = this.isNodeBackedAgentTool(tool);\n collected.push({\n nodeId: toolNodeId,\n parentNodeId,\n connectionName: \"tools\",\n role: isNestedAgent ? \"nestedAgent\" : \"tool\",\n name: tool.presentation?.label ?? tool.name,\n typeName: tool.name,\n icon: tool.presentation?.icon,\n credentialSource: tool,\n });\n this.collectNestedAgentTools(toolNodeId, tool, collected, mcpServerResolver);\n }\n\n if (mcpServerResolver) {\n const mcpServers = (agentConfig as unknown as { mcpServers?: ReadonlyArray<string> }).mcpServers;\n for (const serverId of mcpServers ?? []) {\n const decl = mcpServerResolver(serverId);\n if (!decl) {\n continue;\n }\n const acceptedTypes = decl.acceptedCredentialTypes ?? [];\n collected.push({\n nodeId: ConnectionNodeIdFactory.mcpConnectionNodeId(parentNodeId, serverId),\n parentNodeId,\n connectionName: \"tools\",\n role: \"tool\",\n name: decl.displayName,\n typeName: \"MCP server\",\n icon: \"lucide:plug\",\n credentialSource: {\n getCredentialRequirements: () => [\n {\n slotKey: \"credential\",\n label: decl.displayName,\n acceptedTypes,\n },\n ],\n },\n });\n }\n }\n }\n\n private collectNestedAgentTools(\n toolNodeId: NodeId,\n tool: ToolConfig,\n collected: AgentConnectionNodeDescriptor[],\n mcpServerResolver?: McpServerResolver,\n ): void {\n if (!this.isNodeBackedAgentTool(tool)) {\n return;\n }\n const innerAgent =\n tool instanceof NodeBackedToolConfig ? tool.node : (tool as unknown as { node: AgentNodeConfig<any, any> }).node;\n this.collectInto(toolNodeId, innerAgent, collected, mcpServerResolver);\n }\n\n /**\n * After JSON round-trip (persisted snapshots), tools are plain objects — `instanceof NodeBackedToolConfig` fails.\n * Detect node-backed tools structurally via {@link NodeBackedToolConfig#toolKind}.\n */\n private isNodeBackedAgentTool(tool: ToolConfig): boolean {\n if (tool instanceof NodeBackedToolConfig) {\n return AgentConfigInspector.isAgentNodeConfig(tool.node);\n }\n if (!tool || typeof tool !== \"object\") {\n return false;\n }\n const t = tool as unknown as Record<string, unknown>;\n if (t.toolKind !== \"nodeBacked\") {\n return false;\n }\n return AgentConfigInspector.isAgentNodeConfig(t.node as NodeConfigBase);\n }\n})();\n","import type { NodeId } from \"../../types\";\n\n/**\n * Unique ids for one per-item iteration of a runnable node's execute loop.\n *\n * Activations are per-batch (one scheduled execution of a node, possibly with N items).\n * Iterations refine that to one identifier per item-index inside the batch loop, so per-item\n * connection invocations and telemetry can be grouped without time-window heuristics.\n *\n * Uses Web Crypto's `randomUUID` (Node 19+ and all modern browsers) so this module is safe\n * to include in the browser entry. Importing `node:crypto` here previously leaked into the\n * canvas client bundle through `browser.ts` and OOM'd consumers' Turbopack builds.\n */\nexport class NodeIterationIdFactory {\n static create(): string {\n return `iter_${globalThis.crypto.randomUUID()}`;\n }\n\n /** Deterministic id for tests when a stable sequence is needed. */\n static createForTest(seed: string, sequence: number): string {\n return `iter_${seed}_${sequence}`;\n }\n\n /** Deterministic id derived from a connection node id (for sub-agent / tool-call scopes). */\n static createForConnection(connectionNodeId: NodeId, sequence: number): string {\n return `iter_${connectionNodeId}_${sequence}`;\n }\n}\n","import type { NodeId, WorkflowId } from \"./baseTypes\";\n\nexport type CredentialTypeId = string;\nexport type CredentialInstanceId = string;\n\nexport type CredentialMaterialSourceKind = \"db\" | \"env\" | \"code\";\nexport type CredentialSetupStatus = \"draft\" | \"ready\";\nexport type CredentialHealthStatus = \"unknown\" | \"healthy\" | \"failing\";\n\nexport type CredentialFieldSchema = Readonly<{\n key: string;\n label: string;\n type: \"string\" | \"password\" | \"textarea\" | \"json\" | \"boolean\";\n required?: true;\n order?: number;\n /**\n * Where this field appears in the credential dialog. Use `\"advanced\"` for optional or\n * power-user fields; they render inside a collapsible section (see `CredentialTypeDefinition.advancedSection`).\n * Defaults to `\"default\"` when omitted.\n */\n visibility?: \"default\" | \"advanced\";\n placeholder?: string;\n helpText?: string;\n /** When set, host resolves this field from process.env at runtime; env wins over stored values. */\n envVarName?: string;\n /**\n * When set, the dialog shows a copy action for this exact string (e.g. a static OAuth redirect URI\n * pattern or documentation URL). Do not use for secret values.\n */\n copyValue?: string;\n /** Accessible label for the copy control (default: Copy). */\n copyButtonLabel?: string;\n}>;\n\nexport type CredentialRequirement = Readonly<{\n slotKey: string;\n label: string;\n acceptedTypes: ReadonlyArray<CredentialTypeId>;\n optional?: true;\n helpText?: string;\n helpUrl?: string;\n}>;\n\nexport type CredentialBindingKey = Readonly<{\n workflowId: WorkflowId;\n nodeId: NodeId;\n slotKey: string;\n}>;\n\nexport type CredentialBinding = Readonly<{\n key: CredentialBindingKey;\n instanceId: CredentialInstanceId;\n updatedAt: string;\n}>;\n\nexport type CredentialHealth = Readonly<{\n status: CredentialHealthStatus;\n message?: string;\n testedAt?: string;\n expiresAt?: string;\n details?: Readonly<Record<string, unknown>>;\n}>;\n\nexport type OAuth2ProviderFromPublicConfig = Readonly<{\n authorizeUrlFieldKey: string;\n tokenUrlFieldKey: string;\n userInfoUrlFieldKey?: string;\n}>;\n\nexport type CredentialOAuth2ScopesFromPublicConfig = Readonly<{\n presetFieldKey: string;\n presetScopes: Readonly<Record<string, ReadonlyArray<string>>>;\n customPresetKey?: string;\n customScopesFieldKey?: string;\n}>;\n\nexport type CredentialOAuth2AuthDefinition = Readonly<\n | {\n kind: \"oauth2\";\n providerId: string;\n scopes: ReadonlyArray<string>;\n scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n | {\n kind: \"oauth2\";\n providerFromPublicConfig: OAuth2ProviderFromPublicConfig;\n scopes: ReadonlyArray<string>;\n scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n | {\n kind: \"oauth2\";\n /**\n * Free-form provider identifier for telemetry, DB rows, and Better Auth provider naming.\n * Not used for any registry lookup — URLs come from {@link authorizeUrl} / {@link tokenUrl}.\n */\n providerId: string;\n /**\n * Authorization endpoint. May contain `{publicFieldKey}` placeholders that the runtime\n * substitutes from the credential's resolved public config (URL-encoded).\n * Example: `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize`\n */\n authorizeUrl: string;\n /** Token endpoint. Same templating rules as {@link authorizeUrl}. */\n tokenUrl: string;\n /** Optional userinfo endpoint. Same templating rules as {@link authorizeUrl}. */\n userInfoUrl?: string;\n scopes: ReadonlyArray<string>;\n scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n>;\n\nexport type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;\n\nexport type CredentialAdvancedSectionPresentation = Readonly<{\n /** Collapsible section title (default: \"Advanced\"). */\n title?: string;\n /** Optional short helper text shown inside the section (above the fields). */\n description?: string;\n /** When true, the advanced section starts expanded. Default: false (collapsed). */\n defaultOpen?: boolean;\n}>;\n\nexport type CredentialTypeDefinition = Readonly<{\n typeId: CredentialTypeId;\n displayName: string;\n description?: string;\n publicFields?: ReadonlyArray<CredentialFieldSchema>;\n secretFields?: ReadonlyArray<CredentialFieldSchema>;\n /**\n * Optional labels for the collapsible block that contains every field with `visibility: \"advanced\"`.\n * If omitted, the UI still shows that block with defaults (title \"Advanced\", collapsed).\n */\n advancedSection?: CredentialAdvancedSectionPresentation;\n supportedSourceKinds?: ReadonlyArray<CredentialMaterialSourceKind>;\n auth?: CredentialAuthDefinition;\n}>;\n\n/**\n * JSON-shaped credential field bag (public config, resolved secret material, etc.).\n */\nexport type CredentialJsonRecord = Readonly<Record<string, unknown>>;\n\n/**\n * Persisted credential instance with typed `publicConfig`.\n * Hosts may specialize `secretRef` with a stricter union while remaining\n * assignable here for session/test callbacks.\n */\nexport type CredentialInstanceRecord<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord> = Readonly<{\n instanceId: CredentialInstanceId;\n typeId: CredentialTypeId;\n displayName: string;\n sourceKind: CredentialMaterialSourceKind;\n publicConfig: TPublicConfig;\n secretRef: CredentialJsonRecord;\n tags: ReadonlyArray<string>;\n setupStatus: CredentialSetupStatus;\n createdAt: string;\n updatedAt: string;\n}>;\n\n/**\n * Arguments passed to `CredentialType.createSession` and `CredentialType.test`.\n * Declare `TPublicConfig` / `TMaterial` on `CredentialType` so implementations are checked\n * against your credential shapes (similar to `NodeExecutionContext.config` for nodes).\n */\nexport type CredentialSessionFactoryArgs<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n> = Readonly<{\n instance: CredentialInstanceRecord<TPublicConfig>;\n material: TMaterial;\n publicConfig: TPublicConfig;\n}>;\n\nexport type CredentialSessionFactory<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n TSession = unknown,\n> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<TSession>;\n\nexport type CredentialHealthTester<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<CredentialHealth>;\n\n/**\n * Full credential type implementation: `definition` (UI/schema), `createSession`, and `test`.\n * Use this at registration and config boundaries; `CredentialTypeDefinition` is only the schema slice.\n */\nexport type CredentialType<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n TSession = unknown,\n> = Readonly<{\n definition: CredentialTypeDefinition;\n createSession: CredentialSessionFactory<TPublicConfig, TMaterial, TSession>;\n test: CredentialHealthTester<TPublicConfig, TMaterial>;\n}>;\n\n/**\n * Credential type with unspecified generics — used for `CodemationConfig.credentialTypes`, the host registry,\n * and anywhere a concrete `CredentialType<YourPublic, YourMaterial, YourSession>` is placed in a heterogeneous list.\n * Using `any` here avoids unsafe `as` casts while keeping typed `satisfies CredentialType<…>` definitions.\n */\nexport type AnyCredentialType = CredentialType<any, any, unknown>;\n\nexport interface CredentialSessionService {\n getSession<TSession = unknown>(\n args: Readonly<{\n workflowId: WorkflowId;\n nodeId: NodeId;\n slotKey: string;\n }>,\n ): Promise<TSession>;\n}\n\nexport interface CredentialTypeRegistry {\n listTypes(): ReadonlyArray<CredentialTypeDefinition>;\n getType(typeId: CredentialTypeId): CredentialTypeDefinition | undefined;\n}\n\nexport class CredentialUnboundError extends Error {\n constructor(\n public readonly bindingKey: CredentialBindingKey,\n public readonly acceptedTypes: ReadonlyArray<CredentialTypeId> = [],\n ) {\n super(CredentialUnboundError.createMessage(bindingKey, acceptedTypes));\n this.name = \"CredentialUnboundError\";\n }\n\n private static createMessage(\n bindingKey: CredentialBindingKey,\n acceptedTypes: ReadonlyArray<CredentialTypeId>,\n ): string {\n const acceptedTypesSuffix =\n acceptedTypes.length > 0 ? ` Accepted credential types: ${acceptedTypes.join(\", \")}.` : \"\";\n return `Credential slot \"${bindingKey.slotKey}\" is not bound for workflow ${bindingKey.workflowId} node ${bindingKey.nodeId}.${acceptedTypesSuffix}`;\n }\n}\n","import type { PersistedRunState } from \"./runTypes\";\n\ntype RunFinishedAtSource = Pick<PersistedRunState, \"status\" | \"nodeSnapshotsByNodeId\" | \"finishedAt\">;\n\n/** Derives workflow end time from persisted run root or node snapshots for run listings. */\nexport class RunFinishedAtFactory {\n static resolveIso(state: RunFinishedAtSource): string | undefined {\n if (state.finishedAt && state.status !== \"running\" && state.status !== \"pending\") {\n return state.finishedAt;\n }\n if (state.status === \"running\" || state.status === \"pending\") {\n return undefined;\n }\n let max: string | undefined;\n for (const snap of Object.values(state.nodeSnapshotsByNodeId)) {\n if (snap?.finishedAt && (!max || snap.finishedAt > max)) {\n max = snap.finishedAt;\n }\n }\n return max;\n }\n}\n","import type { ZodType } from \"zod\";\n\nimport type { TypeToken } from \"../di\";\nimport type { CredentialRequirement } from \"./credentialTypes\";\nimport type { RetryPolicySpec } from \"./retryPolicySpec.types\";\nimport type { InputPortKey, NodeConnectionName, NodeId, OutputPortKey, WorkflowId } from \"./baseTypes\";\n\nexport type {\n InputPortKey,\n NodeConnectionName,\n NodeId,\n OutputPortKey,\n PersistedTokenId,\n WorkflowId,\n} from \"./baseTypes\";\n\nexport type NodeIdRef<TJson = unknown> = NodeId & Readonly<{ __codemationNodeJson?: TJson }>;\n\nexport type NodeKind = \"trigger\" | \"node\";\nexport type JsonPrimitive = string | number | boolean | null;\nexport interface JsonObject {\n readonly [key: string]: JsonValue;\n}\nexport type JsonValue = JsonPrimitive | JsonObject | JsonArray;\nexport type JsonArray = ReadonlyArray<JsonValue>;\n/** JSON value that is not a top-level array (nested arrays inside objects are allowed). */\nexport type JsonNonArray = JsonPrimitive | JsonObject;\n\nexport interface Edge {\n from: { nodeId: NodeId; output: OutputPortKey };\n to: { nodeId: NodeId; input: InputPortKey };\n}\n\n/**\n * Named connection from a parent node to child nodes that exist in {@link WorkflowDefinition.nodes}\n * but are not traversed by the main execution graph. Parents are commonly executable nodes, but may\n * also be connection-owned nodes for recursive agent attachments.\n */\nexport interface WorkflowNodeConnection {\n readonly parentNodeId: NodeId;\n readonly connectionName: NodeConnectionName;\n readonly childNodeIds: ReadonlyArray<NodeId>;\n}\n\nexport interface WorkflowDefinition {\n id: WorkflowId;\n name: string;\n nodes: NodeDefinition[];\n edges: Edge[];\n /**\n * Optional metadata: which nodes are connection-owned children (e.g. AI agent `llm` / `tools` slots).\n * When omitted, all nodes in {@link nodes} are treated as executable for topology.\n */\n readonly connections?: ReadonlyArray<WorkflowNodeConnection>;\n /** Directory + file-stem path under a workflow discovery root (for UI grouping only). */\n discoveryPathSegments?: readonly string[];\n /** Retention for run JSON and binaries (seconds). Host/env may supply defaults when omitted. */\n readonly prunePolicy?: WorkflowPrunePolicySpec;\n /** Whether to keep run data after completion. Host/env may supply defaults when omitted. */\n readonly storagePolicy?: WorkflowStoragePolicySpec;\n /** Invoked after a node fails permanently (retries exhausted) and node error handler did not recover. */\n readonly workflowErrorHandler?: WorkflowErrorHandlerSpec;\n}\n\nexport interface WorkflowGraph {\n next(nodeId: NodeId, output: OutputPortKey): ReadonlyArray<Readonly<{ nodeId: NodeId; input: InputPortKey }>>;\n}\n\nexport interface WorkflowGraphFactory {\n create(def: WorkflowDefinition): WorkflowGraph;\n}\n\nexport interface NodeConfigBase {\n readonly kind: NodeKind;\n readonly type: TypeToken<unknown>;\n readonly name?: string;\n readonly id?: NodeId;\n readonly icon?: string;\n readonly execution?: Readonly<{ hint?: \"local\" | \"worker\"; queue?: string }>;\n /** In-process execute retries (runnable nodes). Triggers typically omit this. */\n readonly retryPolicy?: RetryPolicySpec;\n /** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */\n readonly nodeErrorHandler?: NodeErrorHandlerSpec;\n /**\n * When true, edges carrying zero items on an output port still schedule single-input downstream nodes.\n * Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty\n * main batches skip downstream execution and propagate the empty path.\n */\n readonly continueWhenEmptyOutput?: boolean;\n /**\n * Declared I/O port names for canvas authoring (unioned with ports inferred from edges).\n * Use for dynamic routers (Switch) and future error ports.\n */\n readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;\n readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n /**\n * Marker: this node emits {@link import(\"./assertionTypes\").AssertionResult}-shaped items on its\n * `main` port. The TestSuiteOrchestrator (and host-side TestAssertionPersister) listen for\n * `nodeCompleted` events from nodes with this flag set, and persist their output items as\n * TestAssertion records (only when the run carries a `testContext`). Set on assertion node\n * configs (e.g. `AssertionNodeConfig`, `StringEqualsAssertionNodeConfig`).\n */\n readonly emitsAssertions?: true;\n /**\n * Static configuration summary surfaced in the workflow inspector — the design-time\n * \"what does this node do\" panel that renders before any run telemetry exists.\n *\n * Return 2–6 short label/value pairs derived from this config (method + url for an HTTP\n * call, model + tool list for an agent, schedule + timezone for a cron trigger, etc.).\n * Values are truncated by the UI; aim for one line each. Return `undefined` to opt out\n * — the inspector hides the section when no rows are produced.\n *\n * Implement on the config class instance so the function can read sibling config fields.\n * `defineNode({ inspectorSummary })` plumbs through to this.\n */\n inspectorSummary?(): ReadonlyArray<NodeInspectorSummaryRow> | undefined;\n}\n\n/**\n * One row of a node's static configuration summary. See {@link NodeConfigBase.inspectorSummary}.\n */\nexport interface NodeInspectorSummaryRow {\n readonly label: string;\n readonly value: string;\n}\n\nexport declare const runnableNodeInputType: unique symbol;\nexport declare const runnableNodeOutputType: unique symbol;\nexport declare const triggerNodeOutputType: unique symbol;\n\n/**\n * Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).\n * **`TOutputJson`** is emitted `item.json` on outputs.\n */\nexport interface RunnableNodeConfig<TInputJson = unknown, TOutputJson = unknown> extends NodeConfigBase {\n readonly kind: \"node\";\n readonly [runnableNodeInputType]?: TInputJson;\n readonly [runnableNodeOutputType]?: TOutputJson;\n /**\n * Optional Zod input contract for {@link RunnableNode} when not set on the node class.\n * Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.\n */\n readonly inputSchema?: ZodType<TInputJson>;\n /**\n * When an activation receives **zero** input items, the engine normally runs `execute` zero times.\n * Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).\n * Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.\n */\n readonly emptyBatchExecution?: \"skip\" | \"runOnce\";\n}\n\nexport declare const triggerNodeSetupStateType: unique symbol;\n\nexport interface TriggerNodeConfig<\n TOutputJson = unknown,\n TSetupState extends JsonValue | undefined = undefined,\n> extends NodeConfigBase {\n readonly kind: \"trigger\";\n readonly [triggerNodeOutputType]?: TOutputJson;\n readonly [triggerNodeSetupStateType]?: TSetupState;\n /**\n * Distinguishes triggers driven by the live activation policy (webhooks, cron, polling) from\n * triggers driven only by the {@link TestSuiteOrchestrator}. `WorkflowActivation` skips\n * `\"test\"` triggers; the orchestrator skips `\"live\"` triggers. Defaults to `\"live\"` when omitted.\n */\n readonly triggerKind?: \"live\" | \"test\";\n}\n\nexport type RunnableNodeInputJson<TConfig extends RunnableNodeConfig<any, any>> =\n TConfig extends RunnableNodeConfig<infer TInputJson, any> ? TInputJson : never;\n\nexport type RunnableNodeOutputJson<TConfig extends RunnableNodeConfig<any, any>> =\n TConfig extends RunnableNodeConfig<any, infer TOutputJson> ? TOutputJson : never;\n\nexport type TriggerNodeOutputJson<TConfig extends TriggerNodeConfig<any, any>> =\n TConfig extends TriggerNodeConfig<infer TOutputJson, any> ? TOutputJson : never;\n\nexport type TriggerNodeSetupState<TConfig extends TriggerNodeConfig<any, any>> =\n TConfig extends TriggerNodeConfig<any, infer TSetupState> ? TSetupState : never;\n\nexport interface NodeDefinition {\n id: NodeId;\n kind: NodeKind;\n type: TypeToken<unknown>;\n name?: string;\n config: NodeConfigBase;\n}\n\nexport interface NodeRef {\n id: NodeId;\n kind: NodeKind;\n name?: string;\n}\n\nexport function nodeRef<TJson>(nodeId: NodeId): NodeIdRef<TJson> {\n return nodeId as NodeIdRef<TJson>;\n}\n\nexport type PairedItemRef = Readonly<{ nodeId: NodeId; output: OutputPortKey; itemIndex: number }>;\n\nexport type BinaryPreviewKind = \"image\" | \"audio\" | \"video\" | \"download\";\n\nexport type BinaryAttachment = Readonly<{\n id: string;\n storageKey: string;\n mimeType: string;\n size: number;\n storageDriver: string;\n previewKind: BinaryPreviewKind;\n createdAt: string;\n runId: RunId;\n workflowId: WorkflowId;\n nodeId: NodeId;\n activationId: NodeActivationId;\n filename?: string;\n sha256?: string;\n}>;\n\nexport type ItemBinary = Readonly<Record<string, BinaryAttachment>>;\n\nexport type Item<TJson = unknown> = Readonly<{\n json: TJson;\n binary?: ItemBinary;\n meta?: Readonly<Record<string, unknown>>;\n paired?: ReadonlyArray<PairedItemRef>;\n}>;\n\nexport type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;\n\nexport type NodeOutputs = Partial<Record<OutputPortKey, Items>>;\n\nexport type RunId = string;\nexport type NodeActivationId = string;\n/**\n * One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for\n * per-item connection invocations and telemetry. Undefined when the executing node is a batch\n * node or trigger that does not iterate items.\n */\nexport type NodeIterationId = string;\n\nexport interface ParentExecutionRef {\n runId: RunId;\n workflowId: WorkflowId;\n nodeId: NodeId;\n /** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */\n subworkflowDepth?: number;\n /** Effective max node activations from the parent run (propagated to child policy merge). */\n engineMaxNodeActivations?: number;\n /** Effective max subworkflow depth from the parent run (propagated to child policy merge). */\n engineMaxSubworkflowDepth?: number;\n /**\n * Test-suite linkage inherited by the child subworkflow run. Set by whichever node\n * spawns the subworkflow when its own `ctx.testContext` is present, so assertions\n * emitted inside a subworkflow land under the correct parent test case.\n */\n testContext?: import(\"./runTypes\").RunTestContext;\n}\n\nexport interface RunDataSnapshot {\n getOutputs(nodeId: NodeId): NodeOutputs | undefined;\n getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;\n getOutputItem<TJson = unknown>(\n nodeId: NodeId | NodeIdRef<TJson>,\n itemIndex: number,\n output?: OutputPortKey,\n ): Item<TJson> | undefined;\n}\n\nexport interface MutableRunData extends RunDataSnapshot {\n setOutputs(nodeId: NodeId, outputs: NodeOutputs): void;\n dump(): Record<NodeId, NodeOutputs>;\n}\n\nexport interface RunDataFactory {\n create(initial?: Record<NodeId, NodeOutputs>): MutableRunData;\n}\n\nexport interface RunIdFactory {\n makeRunId(): RunId;\n}\n\nexport interface ActivationIdFactory {\n makeActivationId(): NodeActivationId;\n}\n\nexport type UpstreamRefPlaceholder = `$${number}`;\nexport const branchRef = (index: number) => `$${index}` as UpstreamRefPlaceholder;\n\nexport type ExecutionMode = \"local\" | \"worker\";\n\nexport interface NodeSchedulerDecision {\n mode: ExecutionMode;\n queue?: string;\n}\n\nexport interface NodeOffloadPolicy {\n decide(args: { workflowId: WorkflowId; nodeId: NodeId; config: NodeConfigBase }): NodeSchedulerDecision;\n}\n\n/** Whether to persist run execution data after the workflow finishes. */\nexport type WorkflowStoragePolicyMode = \"ALL\" | \"SUCCESS\" | \"ERROR\" | \"NEVER\";\n\nexport type WorkflowStoragePolicySpec = WorkflowStoragePolicyMode | TypeToken<WorkflowStoragePolicyResolver>;\n\nexport interface WorkflowStoragePolicyResolver {\n shouldPersist(args: WorkflowStoragePolicyDecisionArgs): boolean | Promise<boolean>;\n}\n\nexport interface WorkflowStoragePolicyDecisionArgs {\n readonly runId: RunId;\n readonly workflowId: WorkflowId;\n readonly workflow: WorkflowDefinition;\n readonly finalStatus: \"completed\" | \"failed\";\n readonly startedAt: string;\n readonly finishedAt: string;\n}\n\nexport interface WorkflowPrunePolicySpec {\n readonly runDataRetentionSeconds?: number;\n readonly binaryRetentionSeconds?: number;\n readonly telemetrySpanRetentionSeconds?: number;\n readonly telemetryArtifactRetentionSeconds?: number;\n readonly telemetryMetricRetentionSeconds?: number;\n}\n\nexport interface PersistedRunPolicySnapshot {\n readonly retentionSeconds?: number;\n readonly binaryRetentionSeconds?: number;\n readonly telemetrySpanRetentionSeconds?: number;\n readonly telemetryArtifactRetentionSeconds?: number;\n readonly telemetryMetricRetentionSeconds?: number;\n readonly storagePolicy: WorkflowStoragePolicyMode;\n}\n\nexport interface WorkflowErrorHandler {\n onError(ctx: WorkflowErrorContext): void | Promise<void>;\n}\n\nexport interface WorkflowErrorContext {\n readonly runId: RunId;\n readonly workflowId: WorkflowId;\n readonly workflow: WorkflowDefinition;\n readonly failedNodeId: NodeId;\n readonly error: Error;\n readonly startedAt: string;\n readonly finishedAt: string;\n}\n\nexport type WorkflowErrorHandlerSpec = TypeToken<WorkflowErrorHandler> | WorkflowErrorHandler;\n\nexport interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {\n readonly kind: \"single\" | \"multi\";\n readonly items: Items;\n readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;\n readonly ctx: import(\"./runtimeTypes\").NodeExecutionContext<TConfig>;\n readonly error: Error;\n}\n\nexport interface NodeErrorHandler {\n handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;\n}\n\nexport type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;\n\n/** Runtime defaults when workflow omits prune/storage fields (typically from host env). */\nexport interface WorkflowPolicyRuntimeDefaults {\n readonly retentionSeconds?: number;\n readonly binaryRetentionSeconds?: number;\n readonly telemetrySpanRetentionSeconds?: number;\n readonly telemetryArtifactRetentionSeconds?: number;\n readonly telemetryMetricRetentionSeconds?: number;\n readonly storagePolicy?: WorkflowStoragePolicyMode;\n}\n","import type { TypeToken } from \"./index\";\nimport type { RunEventBus } from \"../events/runEvents\";\nimport type { EngineExecutionLimitsPolicy } from \"../policies/executionLimits/EngineExecutionLimitsPolicy\";\nimport type { AgentMcpIntegration } from \"../contracts/agentMcpTypes\";\nimport type {\n ActivationIdFactory,\n BinaryStorage,\n CredentialSessionService,\n CredentialTypeRegistry,\n ExecutionContextFactory,\n LiveWorkflowRepository,\n NodeActivationScheduler,\n NodeResolver,\n PersistedWorkflowTokenRegistryLike,\n RunDataFactory,\n RunIdFactory,\n TriggerSetupStateRepository,\n WorkflowExecutionRepository,\n WorkflowNodeInstanceFactory,\n WorkflowActivationPolicy,\n WorkflowRepository,\n WorkflowRunnerService,\n} from \"../types\";\n\nexport const CoreTokens = {\n PersistedWorkflowTokenRegistry: Symbol.for(\n \"codemation.core.PersistedWorkflowTokenRegistry\",\n ) as TypeToken<PersistedWorkflowTokenRegistryLike>,\n CredentialSessionService: Symbol.for(\n \"codemation.core.CredentialSessionService\",\n ) as TypeToken<CredentialSessionService>,\n CredentialTypeRegistry: Symbol.for(\"codemation.core.CredentialTypeRegistry\") as TypeToken<CredentialTypeRegistry>,\n WorkflowRunnerService: Symbol.for(\"codemation.core.WorkflowRunnerService\") as TypeToken<WorkflowRunnerService>,\n LiveWorkflowRepository: Symbol.for(\"codemation.core.LiveWorkflowRepository\") as TypeToken<LiveWorkflowRepository>,\n WorkflowRepository: Symbol.for(\"codemation.core.WorkflowRepository\") as TypeToken<WorkflowRepository>,\n NodeResolver: Symbol.for(\"codemation.core.NodeResolver\") as TypeToken<NodeResolver>,\n WorkflowNodeInstanceFactory: Symbol.for(\n \"codemation.core.WorkflowNodeInstanceFactory\",\n ) as TypeToken<WorkflowNodeInstanceFactory>,\n RunIdFactory: Symbol.for(\"codemation.core.RunIdFactory\") as TypeToken<RunIdFactory>,\n ActivationIdFactory: Symbol.for(\"codemation.core.ActivationIdFactory\") as TypeToken<ActivationIdFactory>,\n WorkflowExecutionRepository: Symbol.for(\n \"codemation.core.WorkflowExecutionRepository\",\n ) as TypeToken<WorkflowExecutionRepository>,\n TriggerSetupStateRepository: Symbol.for(\n \"codemation.core.TriggerSetupStateRepository\",\n ) as TypeToken<TriggerSetupStateRepository>,\n NodeActivationScheduler: Symbol.for(\"codemation.core.NodeActivationScheduler\") as TypeToken<NodeActivationScheduler>,\n RunDataFactory: Symbol.for(\"codemation.core.RunDataFactory\") as TypeToken<RunDataFactory>,\n ExecutionContextFactory: Symbol.for(\"codemation.core.ExecutionContextFactory\") as TypeToken<ExecutionContextFactory>,\n RunEventBus: Symbol.for(\"codemation.core.RunEventBus\") as TypeToken<RunEventBus>,\n BinaryStorage: Symbol.for(\"codemation.core.BinaryStorage\") as TypeToken<BinaryStorage>,\n WebhookBasePath: Symbol.for(\"codemation.core.WebhookBasePath\") as TypeToken<string>,\n /** Engine execution limits (defaults + optional host overrides). Consumers may bind a custom instance to override. */\n EngineExecutionLimitsPolicy: Symbol.for(\n \"codemation.core.EngineExecutionLimitsPolicy\",\n ) as TypeToken<EngineExecutionLimitsPolicy>,\n WorkflowActivationPolicy: Symbol.for(\n \"codemation.core.WorkflowActivationPolicy\",\n ) as TypeToken<WorkflowActivationPolicy>,\n /**\n * Optional. When registered, AIAgentNode uses it to resolve mcpServers bindings,\n * validate scopes, open pool connections, and prepare the MCP ToolSet map.\n * Not registered in the default core bootstrap — the host provides the implementation.\n */\n AgentMcpIntegration: Symbol.for(\"codemation.core.AgentMcpIntegration\") as TypeToken<AgentMcpIntegration>,\n} as const;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"di-BlEKdoZS.cjs","names":["out: unknown[]","out","exprArgs: ItemExprArgs","name: string","node: TNodeConfig","AgentConnectionNodeCollector: AgentConnectionNodeCollectorApi","collected: AgentConnectionNodeDescriptor[]","bindingKey: CredentialBindingKey","acceptedTypes: ReadonlyArray<CredentialTypeId>","max: string | undefined"],"sources":["../src/workflow/definition/ConnectionNodeIdFactory.ts","../src/contracts/itemExpr.ts","../src/ai/AgentConfigInspectorFactory.ts","../src/ai/NodeBackedToolConfig.ts","../src/ai/AgentConnectionNodeCollector.ts","../src/workflow/definition/NodeIterationIdFactory.ts","../src/contracts/credentialTypes.ts","../src/contracts/runFinishedAtFactory.ts","../src/contracts/workflowTypes.ts","../src/di/CoreTokens.ts"],"sourcesContent":["import type { NodeId } from \"../../types\";\n\n/**\n * Deterministic ids for workflow connection-owned child nodes (LLM slot, tools, etc.).\n * These are stable across loads.\n */\nexport class ConnectionNodeIdFactory {\n static readonly connectionSegment = \"__conn__\" as const;\n\n static languageModelConnectionNodeId(parentNodeId: NodeId): NodeId {\n return `${parentNodeId}${this.connectionSegment}llm`;\n }\n\n static toolConnectionNodeId(parentNodeId: NodeId, toolName: string): NodeId {\n const normalized = this.normalizeToolName(toolName);\n return `${parentNodeId}${this.connectionSegment}tool${this.connectionSegment}${normalized}`;\n }\n\n static mcpConnectionNodeId(parentNodeId: NodeId, serverId: string): NodeId {\n return `${parentNodeId}${this.connectionSegment}mcp${this.connectionSegment}${serverId}`;\n }\n\n static isMcpConnectionNodeId(nodeId: NodeId): boolean {\n return nodeId.includes(`${this.connectionSegment}mcp${this.connectionSegment}`);\n }\n\n static parseMcpConnectionNodeId(nodeId: NodeId): Readonly<{ parentNodeId: NodeId; serverId: string }> | undefined {\n if (!this.isMcpConnectionNodeId(nodeId)) {\n return undefined;\n }\n const marker = `${this.connectionSegment}mcp${this.connectionSegment}`;\n const idx = nodeId.lastIndexOf(marker);\n if (idx < 0) {\n return undefined;\n }\n const parentNodeId = nodeId.slice(0, idx);\n const serverId = nodeId.slice(idx + marker.length);\n if (!parentNodeId || !serverId) {\n return undefined;\n }\n return { parentNodeId, serverId };\n }\n\n static isLanguageModelConnectionNodeId(nodeId: NodeId): boolean {\n return nodeId.endsWith(`${this.connectionSegment}llm`);\n }\n\n static isToolConnectionNodeId(nodeId: NodeId): boolean {\n return nodeId.includes(`${this.connectionSegment}tool${this.connectionSegment}`);\n }\n\n static parseLanguageModelConnectionNodeId(nodeId: NodeId): Readonly<{ parentNodeId: NodeId }> | undefined {\n if (!this.isLanguageModelConnectionNodeId(nodeId)) {\n return undefined;\n }\n const suffix = `${this.connectionSegment}llm`;\n const parentNodeId = nodeId.slice(0, -suffix.length);\n return parentNodeId ? { parentNodeId } : undefined;\n }\n\n static parseToolConnectionNodeId(\n nodeId: NodeId,\n ): Readonly<{ parentNodeId: NodeId; normalizedToolName: string }> | undefined {\n if (!this.isToolConnectionNodeId(nodeId)) {\n return undefined;\n }\n const marker = `${this.connectionSegment}tool${this.connectionSegment}`;\n const idx = nodeId.lastIndexOf(marker);\n if (idx < 0) {\n return undefined;\n }\n const parentNodeId = nodeId.slice(0, idx);\n const normalizedToolName = nodeId.slice(idx + marker.length);\n if (!parentNodeId || !normalizedToolName) {\n return undefined;\n }\n return { parentNodeId, normalizedToolName };\n }\n\n /** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */\n static isConnectionOwnedDescendantOf(parentNodeId: NodeId, nodeId: NodeId): boolean {\n return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);\n }\n\n /** Normalizes a tool display name to a stable id segment. */\n static normalizeToolName(toolName: string): string {\n return (\n toolName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\") || \"tool\"\n );\n }\n}\n","import type { NodeExecutionContext } from \"./runtimeTypes\";\nimport type { Item, Items, NodeActivationId, NodeId, RunDataSnapshot, RunId, WorkflowId } from \"./workflowTypes\";\n\nconst ITEM_EXPR_BRAND = Symbol.for(\"codemation.itemExpr\");\n\nexport type ItemExprResolvedContext = Readonly<{\n runId: RunId;\n workflowId: WorkflowId;\n nodeId: NodeId;\n activationId: NodeActivationId;\n data: RunDataSnapshot;\n}>;\n\n/**\n * Context aligned with former {@link ItemInputMapperContext} — use **`data`** to read any completed upstream node.\n */\nexport type ItemExprContext = ItemExprResolvedContext;\n\nexport type ItemExprArgs<TItemJson = unknown> = Readonly<{\n item: Item<TItemJson>;\n itemIndex: number;\n items: Items<TItemJson>;\n ctx: ItemExprContext;\n}>;\n\nexport type ItemExprCallback<T, TItemJson = unknown> = (args: ItemExprArgs<TItemJson>) => T | Promise<T>;\n\nexport type ItemExpr<T, TItemJson = unknown> = Readonly<{\n readonly [ITEM_EXPR_BRAND]: true;\n readonly fn: ItemExprCallback<T, TItemJson>;\n}>;\n\nexport function itemExpr<T, TItemJson = unknown>(fn: ItemExprCallback<T, TItemJson>): ItemExpr<T, TItemJson> {\n return { [ITEM_EXPR_BRAND]: true, fn };\n}\n\nexport function isItemExpr<T, TItemJson = unknown>(value: unknown): value is ItemExpr<T, TItemJson> {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const v = value as Record<PropertyKey, unknown>;\n if (v[ITEM_EXPR_BRAND] === true) {\n return true;\n }\n // Support snapshot-hydrated itemExpr wrappers where the symbol brand was lost but the callback survived.\n // Workflow snapshot hydration currently restores function-valued fields (like `fn`) but may drop symbol-keyed brands.\n // We treat the minimal `{ fn: Function }` shape as an itemExpr wrapper to keep runnable configs working.\n const keys = Object.keys(v);\n if (keys.length === 1 && keys[0] === \"fn\" && typeof (v as { fn?: unknown }).fn === \"function\") {\n return true;\n }\n for (const sym of Object.getOwnPropertySymbols(v)) {\n if (sym.description === \"codemation.itemExpr\" && v[sym] === true) {\n return true;\n }\n }\n return false;\n}\n\nfunction containsItemExprInUnknown(value: unknown, seen: WeakSet<object> = new WeakSet()): boolean {\n if (isItemExpr(value)) {\n return true;\n }\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n if (seen.has(value as object)) {\n return false;\n }\n seen.add(value as object);\n if (Array.isArray(value)) {\n return value.some((entry) => containsItemExprInUnknown(entry, seen));\n }\n for (const entry of Object.values(value as Record<string, unknown>)) {\n if (containsItemExprInUnknown(entry, seen)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Deep-resolves {@link itemExpr} leaves. Returns a new graph (does not mutate the original config object).\n */\nexport async function resolveItemExprsInUnknown(\n value: unknown,\n args: ItemExprArgs,\n seen: WeakSet<object> = new WeakSet(),\n): Promise<unknown> {\n if (isItemExpr(value)) {\n return await Promise.resolve(value.fn(args));\n }\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n if (seen.has(value as object)) {\n return value;\n }\n seen.add(value as object);\n if (Array.isArray(value)) {\n const out: unknown[] = [];\n for (let i = 0; i < value.length; i++) {\n out.push(await resolveItemExprsInUnknown(value[i], args, seen));\n }\n return out;\n }\n const rec = value as Record<string, unknown>;\n const entries = Object.entries(rec);\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null && entries.length === 0) {\n return value;\n }\n const out = Object.create(proto) as Record<string, unknown>;\n for (const [k, v] of entries) {\n out[k] = await resolveItemExprsInUnknown(v, args, seen);\n }\n return out;\n}\n\n/**\n * Clones runnable config (best-effort) so per-item {@link itemExpr} resolution never mutates shared instances.\n */\nexport async function resolveItemExprsForExecution(\n config: unknown,\n nodeCtx: NodeExecutionContext,\n item: Item,\n itemIndex: number,\n items: Items,\n): Promise<unknown | undefined> {\n const exprArgs: ItemExprArgs = {\n item,\n itemIndex,\n items,\n ctx: {\n runId: nodeCtx.runId,\n workflowId: nodeCtx.workflowId,\n nodeId: nodeCtx.nodeId,\n activationId: nodeCtx.activationId,\n data: nodeCtx.data,\n },\n };\n if (!containsItemExprInUnknown(config)) {\n return undefined;\n }\n return await resolveItemExprsInUnknown(config, exprArgs);\n}\n","import type { NodeConfigBase } from \"../types\";\nimport { isItemExpr } from \"../contracts/itemExpr\";\nimport type { AgentNodeConfig } from \"./AiHost\";\n\nexport class AgentConfigInspector {\n static isAgentNodeConfig(config: NodeConfigBase | undefined): config is AgentNodeConfig<any, any> {\n if (!config) return false;\n const candidate = config as Partial<AgentNodeConfig<any, any>>;\n return !!candidate.chatModel && this.hasCompatibleMessageConfiguration(candidate);\n }\n\n private static hasCompatibleMessageConfiguration(candidate: Partial<AgentNodeConfig<any, any>>): boolean {\n const messages = candidate.messages;\n if (messages === undefined || messages === null) {\n return false;\n }\n if (Array.isArray(messages)) {\n return messages.length > 0;\n }\n if (typeof messages === \"object\") {\n if (isItemExpr(messages)) {\n return true;\n }\n const o = messages as { prompt?: unknown; buildMessages?: unknown };\n return (Array.isArray(o.prompt) && o.prompt.length > 0) || typeof o.buildMessages === \"function\";\n }\n return false;\n }\n}\n","import type { CredentialRequirement } from \"../contracts/credentialTypes\";\nimport type { TypeToken } from \"../di\";\nimport type { Item, NodeOutputs, RunnableNodeConfig, RunnableNodeInputJson } from \"../types\";\nimport type { input as ZodInput, output as ZodOutput } from \"zod\";\nimport type {\n AgentCanvasPresentation,\n NodeBackedToolConfigOptions,\n NodeBackedToolInputMapper,\n NodeBackedToolInputMapperArgs,\n NodeBackedToolOutputMapper,\n NodeBackedToolOutputMapperArgs,\n ToolConfig,\n ZodSchemaAny,\n} from \"./AiHost\";\n\nexport class NodeBackedToolConfig<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TInputSchema extends ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny,\n> implements ToolConfig {\n readonly type: TypeToken<unknown>;\n readonly toolKind = \"nodeBacked\" as const;\n readonly description?: string;\n readonly presentation?: AgentCanvasPresentation;\n private readonly inputSchemaValue: TInputSchema;\n private readonly outputSchemaValue: TOutputSchema;\n private readonly mapInputValue?: NodeBackedToolInputMapper<TNodeConfig, ZodInput<TInputSchema>>;\n private readonly mapOutputValue?: NodeBackedToolOutputMapper<\n TNodeConfig,\n ZodInput<TInputSchema>,\n ZodOutput<TOutputSchema>\n >;\n\n constructor(\n public readonly name: string,\n public readonly node: TNodeConfig,\n options: NodeBackedToolConfigOptions<TNodeConfig, TInputSchema, TOutputSchema>,\n ) {\n this.type = node.type;\n this.description = options.description;\n this.presentation = options.presentation;\n this.inputSchemaValue = options.inputSchema;\n this.outputSchemaValue = options.outputSchema;\n this.mapInputValue = options.mapInput;\n this.mapOutputValue = options.mapOutput;\n }\n\n getCredentialRequirements(): ReadonlyArray<CredentialRequirement> {\n return this.node.getCredentialRequirements?.() ?? [];\n }\n\n getInputSchema(): TInputSchema {\n return this.inputSchemaValue;\n }\n\n getOutputSchema(): TOutputSchema {\n return this.outputSchemaValue;\n }\n\n toNodeItem(\n args: NodeBackedToolInputMapperArgs<TNodeConfig, ZodInput<TInputSchema>>,\n ): Item<RunnableNodeInputJson<TNodeConfig>> {\n const mapped = this.mapInputValue?.(args) ?? (args.input as RunnableNodeInputJson<TNodeConfig>);\n if (this.isItem(mapped)) {\n return mapped;\n }\n return { json: mapped };\n }\n\n toToolOutput(args: NodeBackedToolOutputMapperArgs<TNodeConfig, ZodInput<TInputSchema>>): ZodOutput<TOutputSchema> {\n const raw = this.mapOutputValue?.(args) ?? this.readDefaultToolOutput(args.outputs);\n return this.outputSchemaValue.parse(raw) as ZodOutput<TOutputSchema>;\n }\n\n private readDefaultToolOutput(outputs: NodeOutputs): unknown {\n const firstMainItem = outputs.main?.[0];\n if (!firstMainItem) {\n throw new Error(`Node-backed tool \"${this.name}\" did not produce a main output item.`);\n }\n return firstMainItem.json;\n }\n\n private isItem(value: unknown): value is Item {\n return typeof value === \"object\" && value !== null && \"json\" in value;\n }\n}\n","import type { CredentialRequirement } from \"../contracts/credentialTypes\";\nimport type { McpServerDeclaration } from \"../contracts/mcpTypes\";\nimport type { NodeConfigBase, NodeConnectionName, NodeId } from \"../types\";\nimport { ConnectionNodeIdFactory } from \"../workflow/definition/ConnectionNodeIdFactory\";\nimport { AgentConfigInspector } from \"./AgentConfigInspectorFactory\";\nimport type { AgentNodeConfig, ToolConfig } from \"./AiHost\";\nimport { NodeBackedToolConfig } from \"./NodeBackedToolConfig\";\n\nexport type AgentConnectionNodeRole = \"languageModel\" | \"tool\" | \"nestedAgent\";\n\nexport type AgentConnectionCredentialSource = Readonly<{\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}>;\n\nexport type AgentConnectionNodeDescriptor = Readonly<{\n nodeId: NodeId;\n parentNodeId: NodeId;\n connectionName: NodeConnectionName;\n role: AgentConnectionNodeRole;\n name: string;\n typeName: string;\n icon?: string;\n credentialSource: AgentConnectionCredentialSource;\n}>;\n\nexport type McpServerResolver = (id: string) => McpServerDeclaration | undefined;\n\ntype AgentConnectionNodeCollectorApi = Readonly<{\n collect(\n parentNodeId: NodeId,\n agentConfig: AgentNodeConfig<any, any>,\n mcpServerResolver?: McpServerResolver,\n ): ReadonlyArray<AgentConnectionNodeDescriptor>;\n}>;\n\nexport const AgentConnectionNodeCollector: AgentConnectionNodeCollectorApi = new (class {\n collect(\n parentNodeId: NodeId,\n agentConfig: AgentNodeConfig<any, any>,\n mcpServerResolver?: McpServerResolver,\n ): ReadonlyArray<AgentConnectionNodeDescriptor> {\n const collected: AgentConnectionNodeDescriptor[] = [];\n this.collectInto(parentNodeId, agentConfig, collected, mcpServerResolver);\n return collected;\n }\n\n private collectInto(\n parentNodeId: NodeId,\n agentConfig: AgentNodeConfig<any, any>,\n collected: AgentConnectionNodeDescriptor[],\n mcpServerResolver?: McpServerResolver,\n ): void {\n collected.push({\n nodeId: ConnectionNodeIdFactory.languageModelConnectionNodeId(parentNodeId),\n parentNodeId,\n connectionName: \"llm\",\n role: \"languageModel\",\n name: agentConfig.chatModel.presentation?.label ?? agentConfig.chatModel.name,\n typeName: agentConfig.chatModel.name,\n icon: agentConfig.chatModel.presentation?.icon,\n credentialSource: agentConfig.chatModel,\n });\n\n for (const tool of agentConfig.tools ?? []) {\n const toolNodeId = ConnectionNodeIdFactory.toolConnectionNodeId(parentNodeId, tool.name);\n const isNestedAgent = this.isNodeBackedAgentTool(tool);\n collected.push({\n nodeId: toolNodeId,\n parentNodeId,\n connectionName: \"tools\",\n role: isNestedAgent ? \"nestedAgent\" : \"tool\",\n name: tool.presentation?.label ?? tool.name,\n typeName: tool.name,\n icon: tool.presentation?.icon,\n credentialSource: tool,\n });\n this.collectNestedAgentTools(toolNodeId, tool, collected, mcpServerResolver);\n }\n\n if (mcpServerResolver) {\n const mcpServers = (agentConfig as unknown as { mcpServers?: ReadonlyArray<string> }).mcpServers;\n for (const serverId of mcpServers ?? []) {\n const decl = mcpServerResolver(serverId);\n if (!decl) {\n continue;\n }\n const acceptedTypes = decl.acceptedCredentialTypes ?? [];\n collected.push({\n nodeId: ConnectionNodeIdFactory.mcpConnectionNodeId(parentNodeId, serverId),\n parentNodeId,\n connectionName: \"tools\",\n role: \"tool\",\n name: decl.displayName,\n typeName: \"MCP server\",\n icon: \"lucide:plug\",\n credentialSource: {\n getCredentialRequirements: () => [\n {\n slotKey: \"credential\",\n label: decl.displayName,\n acceptedTypes,\n },\n ],\n },\n });\n }\n }\n }\n\n private collectNestedAgentTools(\n toolNodeId: NodeId,\n tool: ToolConfig,\n collected: AgentConnectionNodeDescriptor[],\n mcpServerResolver?: McpServerResolver,\n ): void {\n if (!this.isNodeBackedAgentTool(tool)) {\n return;\n }\n const innerAgent =\n tool instanceof NodeBackedToolConfig ? tool.node : (tool as unknown as { node: AgentNodeConfig<any, any> }).node;\n this.collectInto(toolNodeId, innerAgent, collected, mcpServerResolver);\n }\n\n /**\n * After JSON round-trip (persisted snapshots), tools are plain objects — `instanceof NodeBackedToolConfig` fails.\n * Detect node-backed tools structurally via {@link NodeBackedToolConfig#toolKind}.\n */\n private isNodeBackedAgentTool(tool: ToolConfig): boolean {\n if (tool instanceof NodeBackedToolConfig) {\n return AgentConfigInspector.isAgentNodeConfig(tool.node);\n }\n if (!tool || typeof tool !== \"object\") {\n return false;\n }\n const t = tool as unknown as Record<string, unknown>;\n if (t.toolKind !== \"nodeBacked\") {\n return false;\n }\n return AgentConfigInspector.isAgentNodeConfig(t.node as NodeConfigBase);\n }\n})();\n","import type { NodeId } from \"../../types\";\n\n/**\n * Unique ids for one per-item iteration of a runnable node's execute loop.\n *\n * Activations are per-batch (one scheduled execution of a node, possibly with N items).\n * Iterations refine that to one identifier per item-index inside the batch loop, so per-item\n * connection invocations and telemetry can be grouped without time-window heuristics.\n *\n * Uses Web Crypto's `randomUUID` (Node 19+ and all modern browsers) so this module is safe\n * to include in the browser entry. Importing `node:crypto` here previously leaked into the\n * canvas client bundle through `browser.ts` and OOM'd consumers' Turbopack builds.\n */\nexport class NodeIterationIdFactory {\n static create(): string {\n return `iter_${globalThis.crypto.randomUUID()}`;\n }\n\n /** Deterministic id for tests when a stable sequence is needed. */\n static createForTest(seed: string, sequence: number): string {\n return `iter_${seed}_${sequence}`;\n }\n\n /** Deterministic id derived from a connection node id (for sub-agent / tool-call scopes). */\n static createForConnection(connectionNodeId: NodeId, sequence: number): string {\n return `iter_${connectionNodeId}_${sequence}`;\n }\n}\n","import type { NodeId, WorkflowId } from \"./baseTypes\";\n\nexport type CredentialTypeId = string;\nexport type CredentialInstanceId = string;\n\nexport type CredentialMaterialSourceKind = \"db\" | \"env\" | \"code\";\nexport type CredentialSetupStatus = \"draft\" | \"ready\";\nexport type CredentialHealthStatus = \"unknown\" | \"healthy\" | \"failing\";\n\nexport type CredentialFieldSchema = Readonly<{\n key: string;\n label: string;\n type: \"string\" | \"password\" | \"textarea\" | \"json\" | \"boolean\";\n required?: true;\n order?: number;\n /**\n * Where this field appears in the credential dialog. Use `\"advanced\"` for optional or\n * power-user fields; they render inside a collapsible section (see `CredentialTypeDefinition.advancedSection`).\n * Defaults to `\"default\"` when omitted.\n */\n visibility?: \"default\" | \"advanced\";\n placeholder?: string;\n helpText?: string;\n /** When set, host resolves this field from process.env at runtime; env wins over stored values. */\n envVarName?: string;\n /**\n * When set, the dialog shows a copy action for this exact string (e.g. a static OAuth redirect URI\n * pattern or documentation URL). Do not use for secret values.\n */\n copyValue?: string;\n /** Accessible label for the copy control (default: Copy). */\n copyButtonLabel?: string;\n}>;\n\nexport type CredentialRequirement = Readonly<{\n slotKey: string;\n label: string;\n acceptedTypes: ReadonlyArray<CredentialTypeId>;\n optional?: true;\n helpText?: string;\n helpUrl?: string;\n}>;\n\nexport type CredentialBindingKey = Readonly<{\n workflowId: WorkflowId;\n nodeId: NodeId;\n slotKey: string;\n}>;\n\nexport type CredentialBinding = Readonly<{\n key: CredentialBindingKey;\n instanceId: CredentialInstanceId;\n updatedAt: string;\n}>;\n\nexport type CredentialHealth = Readonly<{\n status: CredentialHealthStatus;\n message?: string;\n testedAt?: string;\n expiresAt?: string;\n details?: Readonly<Record<string, unknown>>;\n}>;\n\nexport type OAuth2ProviderFromPublicConfig = Readonly<{\n authorizeUrlFieldKey: string;\n tokenUrlFieldKey: string;\n userInfoUrlFieldKey?: string;\n}>;\n\nexport type CredentialOAuth2ScopesFromPublicConfig = Readonly<{\n presetFieldKey: string;\n presetScopes: Readonly<Record<string, ReadonlyArray<string>>>;\n customPresetKey?: string;\n customScopesFieldKey?: string;\n}>;\n\nexport type CredentialOAuth2AuthDefinition = Readonly<\n | {\n kind: \"oauth2\";\n providerId: string;\n scopes: ReadonlyArray<string>;\n scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n | {\n kind: \"oauth2\";\n providerFromPublicConfig: OAuth2ProviderFromPublicConfig;\n scopes: ReadonlyArray<string>;\n scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n | {\n kind: \"oauth2\";\n /**\n * Free-form provider identifier for telemetry, DB rows, and Better Auth provider naming.\n * Not used for any registry lookup — URLs come from {@link authorizeUrl} / {@link tokenUrl}.\n */\n providerId: string;\n /**\n * Authorization endpoint. May contain `{publicFieldKey}` placeholders that the runtime\n * substitutes from the credential's resolved public config (URL-encoded).\n * Example: `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize`\n */\n authorizeUrl: string;\n /** Token endpoint. Same templating rules as {@link authorizeUrl}. */\n tokenUrl: string;\n /** Optional userinfo endpoint. Same templating rules as {@link authorizeUrl}. */\n userInfoUrl?: string;\n scopes: ReadonlyArray<string>;\n scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n>;\n\nexport type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;\n\nexport type CredentialAdvancedSectionPresentation = Readonly<{\n /** Collapsible section title (default: \"Advanced\"). */\n title?: string;\n /** Optional short helper text shown inside the section (above the fields). */\n description?: string;\n /** When true, the advanced section starts expanded. Default: false (collapsed). */\n defaultOpen?: boolean;\n}>;\n\nexport type CredentialTypeDefinition = Readonly<{\n typeId: CredentialTypeId;\n displayName: string;\n description?: string;\n publicFields?: ReadonlyArray<CredentialFieldSchema>;\n secretFields?: ReadonlyArray<CredentialFieldSchema>;\n /**\n * Optional labels for the collapsible block that contains every field with `visibility: \"advanced\"`.\n * If omitted, the UI still shows that block with defaults (title \"Advanced\", collapsed).\n */\n advancedSection?: CredentialAdvancedSectionPresentation;\n supportedSourceKinds?: ReadonlyArray<CredentialMaterialSourceKind>;\n auth?: CredentialAuthDefinition;\n}>;\n\n/**\n * JSON-shaped credential field bag (public config, resolved secret material, etc.).\n */\nexport type CredentialJsonRecord = Readonly<Record<string, unknown>>;\n\n/**\n * Persisted credential instance with typed `publicConfig`.\n * Hosts may specialize `secretRef` with a stricter union while remaining\n * assignable here for session/test callbacks.\n */\nexport type CredentialInstanceRecord<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord> = Readonly<{\n instanceId: CredentialInstanceId;\n typeId: CredentialTypeId;\n displayName: string;\n sourceKind: CredentialMaterialSourceKind;\n publicConfig: TPublicConfig;\n secretRef: CredentialJsonRecord;\n tags: ReadonlyArray<string>;\n setupStatus: CredentialSetupStatus;\n createdAt: string;\n updatedAt: string;\n}>;\n\n/**\n * Arguments passed to `CredentialType.createSession` and `CredentialType.test`.\n * Declare `TPublicConfig` / `TMaterial` on `CredentialType` so implementations are checked\n * against your credential shapes (similar to `NodeExecutionContext.config` for nodes).\n */\nexport type CredentialSessionFactoryArgs<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n> = Readonly<{\n instance: CredentialInstanceRecord<TPublicConfig>;\n material: TMaterial;\n publicConfig: TPublicConfig;\n}>;\n\nexport type CredentialSessionFactory<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n TSession = unknown,\n> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<TSession>;\n\nexport type CredentialHealthTester<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<CredentialHealth>;\n\n/**\n * Full credential type implementation: `definition` (UI/schema), `createSession`, and `test`.\n * Use this at registration and config boundaries; `CredentialTypeDefinition` is only the schema slice.\n */\nexport type CredentialType<\n TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord,\n TMaterial extends CredentialJsonRecord = CredentialJsonRecord,\n TSession = unknown,\n> = Readonly<{\n definition: CredentialTypeDefinition;\n createSession: CredentialSessionFactory<TPublicConfig, TMaterial, TSession>;\n test: CredentialHealthTester<TPublicConfig, TMaterial>;\n}>;\n\n/**\n * Credential type with unspecified generics — used for `CodemationConfig.credentialTypes`, the host registry,\n * and anywhere a concrete `CredentialType<YourPublic, YourMaterial, YourSession>` is placed in a heterogeneous list.\n * Using `any` here avoids unsafe `as` casts while keeping typed `satisfies CredentialType<…>` definitions.\n */\nexport type AnyCredentialType = CredentialType<any, any, unknown>;\n\nexport interface CredentialSessionService {\n getSession<TSession = unknown>(\n args: Readonly<{\n workflowId: WorkflowId;\n nodeId: NodeId;\n slotKey: string;\n }>,\n ): Promise<TSession>;\n}\n\nexport interface CredentialTypeRegistry {\n listTypes(): ReadonlyArray<CredentialTypeDefinition>;\n getType(typeId: CredentialTypeId): CredentialTypeDefinition | undefined;\n}\n\nexport class CredentialUnboundError extends Error {\n constructor(\n public readonly bindingKey: CredentialBindingKey,\n public readonly acceptedTypes: ReadonlyArray<CredentialTypeId> = [],\n ) {\n super(CredentialUnboundError.createMessage(bindingKey, acceptedTypes));\n this.name = \"CredentialUnboundError\";\n }\n\n private static createMessage(\n bindingKey: CredentialBindingKey,\n acceptedTypes: ReadonlyArray<CredentialTypeId>,\n ): string {\n const acceptedTypesSuffix =\n acceptedTypes.length > 0 ? ` Accepted credential types: ${acceptedTypes.join(\", \")}.` : \"\";\n return `Credential slot \"${bindingKey.slotKey}\" is not bound for workflow ${bindingKey.workflowId} node ${bindingKey.nodeId}.${acceptedTypesSuffix}`;\n }\n}\n","import type { PersistedRunState } from \"./runTypes\";\n\ntype RunFinishedAtSource = Pick<PersistedRunState, \"status\" | \"nodeSnapshotsByNodeId\" | \"finishedAt\">;\n\n/** Derives workflow end time from persisted run root or node snapshots for run listings. */\nexport class RunFinishedAtFactory {\n static resolveIso(state: RunFinishedAtSource): string | undefined {\n if (state.finishedAt && state.status !== \"running\" && state.status !== \"pending\") {\n return state.finishedAt;\n }\n if (state.status === \"running\" || state.status === \"pending\") {\n return undefined;\n }\n let max: string | undefined;\n for (const snap of Object.values(state.nodeSnapshotsByNodeId)) {\n if (snap?.finishedAt && (!max || snap.finishedAt > max)) {\n max = snap.finishedAt;\n }\n }\n return max;\n }\n}\n","import type { ZodType } from \"zod\";\n\nimport type { TypeToken } from \"../di\";\nimport type { CredentialRequirement } from \"./credentialTypes\";\nimport type { RetryPolicySpec } from \"./retryPolicySpec.types\";\nimport type { InputPortKey, NodeConnectionName, NodeId, OutputPortKey, WorkflowId } from \"./baseTypes\";\n\nexport type {\n InputPortKey,\n NodeConnectionName,\n NodeId,\n OutputPortKey,\n PersistedTokenId,\n WorkflowId,\n} from \"./baseTypes\";\n\nexport type NodeIdRef<TJson = unknown> = NodeId & Readonly<{ __codemationNodeJson?: TJson }>;\n\nexport type NodeKind = \"trigger\" | \"node\";\nexport type JsonPrimitive = string | number | boolean | null;\nexport interface JsonObject {\n readonly [key: string]: JsonValue;\n}\nexport type JsonValue = JsonPrimitive | JsonObject | JsonArray;\nexport type JsonArray = ReadonlyArray<JsonValue>;\n/** JSON value that is not a top-level array (nested arrays inside objects are allowed). */\nexport type JsonNonArray = JsonPrimitive | JsonObject;\n\nexport interface Edge {\n from: { nodeId: NodeId; output: OutputPortKey };\n to: { nodeId: NodeId; input: InputPortKey };\n}\n\n/**\n * Named connection from a parent node to child nodes that exist in {@link WorkflowDefinition.nodes}\n * but are not traversed by the main execution graph. Parents are commonly executable nodes, but may\n * also be connection-owned nodes for recursive agent attachments.\n */\nexport interface WorkflowNodeConnection {\n readonly parentNodeId: NodeId;\n readonly connectionName: NodeConnectionName;\n readonly childNodeIds: ReadonlyArray<NodeId>;\n}\n\nexport interface WorkflowDefinition {\n id: WorkflowId;\n name: string;\n nodes: NodeDefinition[];\n edges: Edge[];\n /**\n * Optional metadata: which nodes are connection-owned children (e.g. AI agent `llm` / `tools` slots).\n * When omitted, all nodes in {@link nodes} are treated as executable for topology.\n */\n readonly connections?: ReadonlyArray<WorkflowNodeConnection>;\n /** Directory + file-stem path under a workflow discovery root (for UI grouping only). */\n discoveryPathSegments?: readonly string[];\n /** Retention for run JSON and binaries (seconds). Host/env may supply defaults when omitted. */\n readonly prunePolicy?: WorkflowPrunePolicySpec;\n /** Whether to keep run data after completion. Host/env may supply defaults when omitted. */\n readonly storagePolicy?: WorkflowStoragePolicySpec;\n /** Invoked after a node fails permanently (retries exhausted) and node error handler did not recover. */\n readonly workflowErrorHandler?: WorkflowErrorHandlerSpec;\n}\n\nexport interface WorkflowGraph {\n next(nodeId: NodeId, output: OutputPortKey): ReadonlyArray<Readonly<{ nodeId: NodeId; input: InputPortKey }>>;\n}\n\nexport interface WorkflowGraphFactory {\n create(def: WorkflowDefinition): WorkflowGraph;\n}\n\nexport interface NodeConfigBase {\n readonly kind: NodeKind;\n readonly type: TypeToken<unknown>;\n readonly name?: string;\n readonly id?: NodeId;\n readonly icon?: string;\n readonly execution?: Readonly<{ hint?: \"local\" | \"worker\"; queue?: string }>;\n /** In-process execute retries (runnable nodes). Triggers typically omit this. */\n readonly retryPolicy?: RetryPolicySpec;\n /** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */\n readonly nodeErrorHandler?: NodeErrorHandlerSpec;\n /**\n * When true, edges carrying zero items on an output port still schedule single-input downstream nodes.\n * Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty\n * main batches skip downstream execution and propagate the empty path.\n */\n readonly continueWhenEmptyOutput?: boolean;\n /**\n * Declared I/O port names for canvas authoring (unioned with ports inferred from edges).\n * Use for dynamic routers (Switch) and future error ports.\n */\n readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;\n readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n /**\n * Marker: this node emits {@link import(\"./assertionTypes\").AssertionResult}-shaped items on its\n * `main` port. The TestSuiteOrchestrator (and host-side TestAssertionPersister) listen for\n * `nodeCompleted` events from nodes with this flag set, and persist their output items as\n * TestAssertion records (only when the run carries a `testContext`). Set on assertion node\n * configs (e.g. `AssertionNodeConfig`, `StringEqualsAssertionNodeConfig`).\n */\n readonly emitsAssertions?: true;\n /**\n * Static configuration summary surfaced in the workflow inspector — the design-time\n * \"what does this node do\" panel that renders before any run telemetry exists.\n *\n * Return 2–6 short label/value pairs derived from this config (method + url for an HTTP\n * call, model + tool list for an agent, schedule + timezone for a cron trigger, etc.).\n * Values are truncated by the UI; aim for one line each. Return `undefined` to opt out\n * — the inspector hides the section when no rows are produced.\n *\n * Implement on the config class instance so the function can read sibling config fields.\n * `defineNode({ inspectorSummary })` plumbs through to this.\n */\n inspectorSummary?(): ReadonlyArray<NodeInspectorSummaryRow> | undefined;\n}\n\n/**\n * One row of a node's static configuration summary. See {@link NodeConfigBase.inspectorSummary}.\n */\nexport interface NodeInspectorSummaryRow {\n readonly label: string;\n readonly value: string;\n}\n\nexport declare const runnableNodeInputType: unique symbol;\nexport declare const runnableNodeOutputType: unique symbol;\nexport declare const triggerNodeOutputType: unique symbol;\n\n/**\n * Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).\n * **`TOutputJson`** is emitted `item.json` on outputs.\n */\nexport interface RunnableNodeConfig<TInputJson = unknown, TOutputJson = unknown> extends NodeConfigBase {\n readonly kind: \"node\";\n readonly [runnableNodeInputType]?: TInputJson;\n readonly [runnableNodeOutputType]?: TOutputJson;\n /**\n * Optional Zod input contract for {@link RunnableNode} when not set on the node class.\n * Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.\n */\n readonly inputSchema?: ZodType<TInputJson>;\n /**\n * When an activation receives **zero** input items, the engine normally runs `execute` zero times.\n * Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).\n * Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.\n */\n readonly emptyBatchExecution?: \"skip\" | \"runOnce\";\n}\n\nexport declare const triggerNodeSetupStateType: unique symbol;\n\nexport interface TriggerNodeConfig<\n TOutputJson = unknown,\n TSetupState extends JsonValue | undefined = undefined,\n> extends NodeConfigBase {\n readonly kind: \"trigger\";\n readonly [triggerNodeOutputType]?: TOutputJson;\n readonly [triggerNodeSetupStateType]?: TSetupState;\n /**\n * Distinguishes triggers driven by the live activation policy (webhooks, cron, polling) from\n * triggers driven only by the {@link TestSuiteOrchestrator}. `WorkflowActivation` skips\n * `\"test\"` triggers; the orchestrator skips `\"live\"` triggers. Defaults to `\"live\"` when omitted.\n */\n readonly triggerKind?: \"live\" | \"test\";\n}\n\nexport type RunnableNodeInputJson<TConfig extends RunnableNodeConfig<any, any>> =\n TConfig extends RunnableNodeConfig<infer TInputJson, any> ? TInputJson : never;\n\nexport type RunnableNodeOutputJson<TConfig extends RunnableNodeConfig<any, any>> =\n TConfig extends RunnableNodeConfig<any, infer TOutputJson> ? TOutputJson : never;\n\nexport type TriggerNodeOutputJson<TConfig extends TriggerNodeConfig<any, any>> =\n TConfig extends TriggerNodeConfig<infer TOutputJson, any> ? TOutputJson : never;\n\nexport type TriggerNodeSetupState<TConfig extends TriggerNodeConfig<any, any>> =\n TConfig extends TriggerNodeConfig<any, infer TSetupState> ? TSetupState : never;\n\nexport interface NodeDefinition {\n id: NodeId;\n kind: NodeKind;\n type: TypeToken<unknown>;\n name?: string;\n config: NodeConfigBase;\n}\n\nexport interface NodeRef {\n id: NodeId;\n kind: NodeKind;\n name?: string;\n}\n\nexport function nodeRef<TJson>(nodeId: NodeId): NodeIdRef<TJson> {\n return nodeId as NodeIdRef<TJson>;\n}\n\nexport type PairedItemRef = Readonly<{ nodeId: NodeId; output: OutputPortKey; itemIndex: number }>;\n\nexport type BinaryPreviewKind = \"image\" | \"audio\" | \"video\" | \"download\";\n\nexport type BinaryAttachment = Readonly<{\n id: string;\n storageKey: string;\n mimeType: string;\n size: number;\n storageDriver: string;\n previewKind: BinaryPreviewKind;\n createdAt: string;\n runId: RunId;\n workflowId: WorkflowId;\n nodeId: NodeId;\n activationId: NodeActivationId;\n filename?: string;\n sha256?: string;\n}>;\n\nexport type ItemBinary = Readonly<Record<string, BinaryAttachment>>;\n\nexport type Item<TJson = unknown> = Readonly<{\n json: TJson;\n binary?: ItemBinary;\n meta?: Readonly<Record<string, unknown>>;\n paired?: ReadonlyArray<PairedItemRef>;\n}>;\n\nexport type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;\n\nexport type NodeOutputs = Partial<Record<OutputPortKey, Items>>;\n\nexport type RunId = string;\nexport type NodeActivationId = string;\n/**\n * One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for\n * per-item connection invocations and telemetry. Undefined when the executing node is a batch\n * node or trigger that does not iterate items.\n */\nexport type NodeIterationId = string;\n\nexport interface ParentExecutionRef {\n runId: RunId;\n workflowId: WorkflowId;\n nodeId: NodeId;\n /** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */\n subworkflowDepth?: number;\n /** Effective max node activations from the parent run (propagated to child policy merge). */\n engineMaxNodeActivations?: number;\n /** Effective max subworkflow depth from the parent run (propagated to child policy merge). */\n engineMaxSubworkflowDepth?: number;\n /**\n * Test-suite linkage inherited by the child subworkflow run. Set by whichever node\n * spawns the subworkflow when its own `ctx.testContext` is present, so assertions\n * emitted inside a subworkflow land under the correct parent test case.\n */\n testContext?: import(\"./runTypes\").RunTestContext;\n}\n\nexport interface RunDataSnapshot {\n getOutputs(nodeId: NodeId): NodeOutputs | undefined;\n getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;\n getOutputItem<TJson = unknown>(\n nodeId: NodeId | NodeIdRef<TJson>,\n itemIndex: number,\n output?: OutputPortKey,\n ): Item<TJson> | undefined;\n}\n\nexport interface MutableRunData extends RunDataSnapshot {\n setOutputs(nodeId: NodeId, outputs: NodeOutputs): void;\n dump(): Record<NodeId, NodeOutputs>;\n}\n\nexport interface RunDataFactory {\n create(initial?: Record<NodeId, NodeOutputs>): MutableRunData;\n}\n\nexport interface RunIdFactory {\n makeRunId(): RunId;\n}\n\nexport interface ActivationIdFactory {\n makeActivationId(): NodeActivationId;\n}\n\nexport type UpstreamRefPlaceholder = `$${number}`;\nexport const branchRef = (index: number) => `$${index}` as UpstreamRefPlaceholder;\n\nexport type ExecutionMode = \"local\" | \"worker\";\n\nexport interface NodeSchedulerDecision {\n mode: ExecutionMode;\n queue?: string;\n}\n\nexport interface NodeOffloadPolicy {\n decide(args: { workflowId: WorkflowId; nodeId: NodeId; config: NodeConfigBase }): NodeSchedulerDecision;\n}\n\n/** Whether to persist run execution data after the workflow finishes. */\nexport type WorkflowStoragePolicyMode = \"ALL\" | \"SUCCESS\" | \"ERROR\" | \"NEVER\";\n\nexport type WorkflowStoragePolicySpec = WorkflowStoragePolicyMode | TypeToken<WorkflowStoragePolicyResolver>;\n\nexport interface WorkflowStoragePolicyResolver {\n shouldPersist(args: WorkflowStoragePolicyDecisionArgs): boolean | Promise<boolean>;\n}\n\nexport interface WorkflowStoragePolicyDecisionArgs {\n readonly runId: RunId;\n readonly workflowId: WorkflowId;\n readonly workflow: WorkflowDefinition;\n readonly finalStatus: \"completed\" | \"failed\";\n readonly startedAt: string;\n readonly finishedAt: string;\n}\n\nexport interface WorkflowPrunePolicySpec {\n readonly runDataRetentionSeconds?: number;\n readonly binaryRetentionSeconds?: number;\n readonly telemetrySpanRetentionSeconds?: number;\n readonly telemetryArtifactRetentionSeconds?: number;\n readonly telemetryMetricRetentionSeconds?: number;\n}\n\nexport interface PersistedRunPolicySnapshot {\n readonly retentionSeconds?: number;\n readonly binaryRetentionSeconds?: number;\n readonly telemetrySpanRetentionSeconds?: number;\n readonly telemetryArtifactRetentionSeconds?: number;\n readonly telemetryMetricRetentionSeconds?: number;\n readonly storagePolicy: WorkflowStoragePolicyMode;\n}\n\nexport interface WorkflowErrorHandler {\n onError(ctx: WorkflowErrorContext): void | Promise<void>;\n}\n\nexport interface WorkflowErrorContext {\n readonly runId: RunId;\n readonly workflowId: WorkflowId;\n readonly workflow: WorkflowDefinition;\n readonly failedNodeId: NodeId;\n readonly error: Error;\n readonly startedAt: string;\n readonly finishedAt: string;\n}\n\nexport type WorkflowErrorHandlerSpec = TypeToken<WorkflowErrorHandler> | WorkflowErrorHandler;\n\nexport interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {\n readonly kind: \"single\" | \"multi\";\n readonly items: Items;\n readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;\n readonly ctx: import(\"./runtimeTypes\").NodeExecutionContext<TConfig>;\n readonly error: Error;\n}\n\nexport interface NodeErrorHandler {\n handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;\n}\n\nexport type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;\n\n/** Runtime defaults when workflow omits prune/storage fields (typically from host env). */\nexport interface WorkflowPolicyRuntimeDefaults {\n readonly retentionSeconds?: number;\n readonly binaryRetentionSeconds?: number;\n readonly telemetrySpanRetentionSeconds?: number;\n readonly telemetryArtifactRetentionSeconds?: number;\n readonly telemetryMetricRetentionSeconds?: number;\n readonly storagePolicy?: WorkflowStoragePolicyMode;\n}\n","import type { TypeToken } from \"./index\";\nimport type { RunEventBus } from \"../events/runEvents\";\nimport type { EngineExecutionLimitsPolicy } from \"../policies/executionLimits/EngineExecutionLimitsPolicy\";\nimport type { AgentMcpIntegration } from \"../contracts/agentMcpTypes\";\nimport type {\n ActivationIdFactory,\n BinaryStorage,\n CredentialSessionService,\n CredentialTypeRegistry,\n ExecutionContextFactory,\n LiveWorkflowRepository,\n NodeActivationScheduler,\n NodeResolver,\n PersistedWorkflowTokenRegistryLike,\n RunDataFactory,\n RunIdFactory,\n TriggerSetupStateRepository,\n WorkflowExecutionRepository,\n WorkflowNodeInstanceFactory,\n WorkflowActivationPolicy,\n WorkflowRepository,\n WorkflowRunnerService,\n} from \"../types\";\n\nexport const CoreTokens = {\n PersistedWorkflowTokenRegistry: Symbol.for(\n \"codemation.core.PersistedWorkflowTokenRegistry\",\n ) as TypeToken<PersistedWorkflowTokenRegistryLike>,\n CredentialSessionService: Symbol.for(\n \"codemation.core.CredentialSessionService\",\n ) as TypeToken<CredentialSessionService>,\n CredentialTypeRegistry: Symbol.for(\"codemation.core.CredentialTypeRegistry\") as TypeToken<CredentialTypeRegistry>,\n WorkflowRunnerService: Symbol.for(\"codemation.core.WorkflowRunnerService\") as TypeToken<WorkflowRunnerService>,\n LiveWorkflowRepository: Symbol.for(\"codemation.core.LiveWorkflowRepository\") as TypeToken<LiveWorkflowRepository>,\n WorkflowRepository: Symbol.for(\"codemation.core.WorkflowRepository\") as TypeToken<WorkflowRepository>,\n NodeResolver: Symbol.for(\"codemation.core.NodeResolver\") as TypeToken<NodeResolver>,\n WorkflowNodeInstanceFactory: Symbol.for(\n \"codemation.core.WorkflowNodeInstanceFactory\",\n ) as TypeToken<WorkflowNodeInstanceFactory>,\n RunIdFactory: Symbol.for(\"codemation.core.RunIdFactory\") as TypeToken<RunIdFactory>,\n ActivationIdFactory: Symbol.for(\"codemation.core.ActivationIdFactory\") as TypeToken<ActivationIdFactory>,\n WorkflowExecutionRepository: Symbol.for(\n \"codemation.core.WorkflowExecutionRepository\",\n ) as TypeToken<WorkflowExecutionRepository>,\n TriggerSetupStateRepository: Symbol.for(\n \"codemation.core.TriggerSetupStateRepository\",\n ) as TypeToken<TriggerSetupStateRepository>,\n NodeActivationScheduler: Symbol.for(\"codemation.core.NodeActivationScheduler\") as TypeToken<NodeActivationScheduler>,\n RunDataFactory: Symbol.for(\"codemation.core.RunDataFactory\") as TypeToken<RunDataFactory>,\n ExecutionContextFactory: Symbol.for(\"codemation.core.ExecutionContextFactory\") as TypeToken<ExecutionContextFactory>,\n RunEventBus: Symbol.for(\"codemation.core.RunEventBus\") as TypeToken<RunEventBus>,\n BinaryStorage: Symbol.for(\"codemation.core.BinaryStorage\") as TypeToken<BinaryStorage>,\n WebhookBasePath: Symbol.for(\"codemation.core.WebhookBasePath\") as TypeToken<string>,\n /** Engine execution limits (defaults + optional host overrides). Consumers may bind a custom instance to override. */\n EngineExecutionLimitsPolicy: Symbol.for(\n \"codemation.core.EngineExecutionLimitsPolicy\",\n ) as TypeToken<EngineExecutionLimitsPolicy>,\n WorkflowActivationPolicy: Symbol.for(\n \"codemation.core.WorkflowActivationPolicy\",\n ) as TypeToken<WorkflowActivationPolicy>,\n /**\n * Optional. When registered, AIAgentNode uses it to resolve mcpServers bindings,\n * validate scopes, open pool connections, and prepare the MCP ToolSet map.\n * Not registered in the default core bootstrap — the host provides the implementation.\n */\n AgentMcpIntegration: Symbol.for(\"codemation.core.AgentMcpIntegration\") as TypeToken<AgentMcpIntegration>,\n} as const;\n"],"mappings":"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"}