@codemation/core 0.0.19 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/EngineRuntimeRegistration.types-0sgV2XL2.d.ts +42 -0
- package/dist/EngineWorkflowRunnerService-Dx7bJsJR.d.cts +73 -0
- package/dist/InMemoryRunDataFactory-qIYQEar7.d.cts +94 -0
- package/dist/{InMemoryLiveWorkflowRepository-DxoualoC.d.ts → RunIntentService-BCvGdOSY.d.ts} +438 -9
- package/dist/{RunIntentService-C1nu_YwM.js → RunIntentService-BFA48UpH.js} +252 -67
- package/dist/RunIntentService-BFA48UpH.js.map +1 -0
- package/dist/{InMemoryLiveWorkflowRepository-orY1VsWG.d.cts → RunIntentService-CV8izV8t.d.cts} +214 -7
- package/dist/{RunIntentService-ZkjpY7MS.cjs → RunIntentService-DcxXf_AM.cjs} +262 -65
- package/dist/RunIntentService-DcxXf_AM.cjs.map +1 -0
- package/dist/bootstrap/index.cjs +14 -1135
- package/dist/bootstrap/index.d.cts +7 -60
- package/dist/bootstrap/index.d.ts +4 -40
- package/dist/bootstrap/index.js +3 -1122
- package/dist/bootstrap-D67Sf2BF.js +1136 -0
- package/dist/bootstrap-D67Sf2BF.js.map +1 -0
- package/dist/bootstrap-DoQHAEQJ.cjs +1203 -0
- package/dist/bootstrap-DoQHAEQJ.cjs.map +1 -0
- package/dist/{index-BIewO9-9.d.ts → index-BHmrZIHp.d.ts} +32 -260
- package/dist/index.cjs +98 -223
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +196 -6
- package/dist/index.d.ts +3 -3
- package/dist/index.js +92 -218
- package/dist/index.js.map +1 -1
- package/dist/testing.cjs +329 -3
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +181 -4
- package/dist/testing.d.ts +181 -3
- package/dist/testing.js +319 -2
- package/dist/testing.js.map +1 -1
- package/dist/workflowActivationPolicy-B8HzTk3o.js +201 -0
- package/dist/workflowActivationPolicy-B8HzTk3o.js.map +1 -0
- package/dist/workflowActivationPolicy-BzyzXLa_.cjs +231 -0
- package/dist/workflowActivationPolicy-BzyzXLa_.cjs.map +1 -0
- package/package.json +1 -1
- package/src/ai/AgentConnectionNodeCollector.ts +99 -0
- package/src/ai/AgentToolFactory.ts +38 -2
- package/src/ai/AiHost.ts +1 -1
- package/src/browser.ts +11 -0
- package/src/contracts/executionPersistenceContracts.ts +186 -0
- package/src/contracts/index.ts +1 -0
- package/src/contracts/runFinishedAtFactory.ts +5 -2
- package/src/contracts/runTypes.ts +10 -0
- package/src/contracts/runtimeTypes.ts +6 -2
- package/src/contracts/workflowTypes.ts +3 -2
- package/src/events/EventPublishingWorkflowExecutionRepository.ts +5 -0
- package/src/execution/ActivationEnqueueService.ts +8 -8
- package/src/execution/PersistedRunStateTerminalBuilder.ts +3 -0
- package/src/index.ts +6 -0
- package/src/orchestration/NodeExecutionRequestHandlerService.ts +11 -6
- package/src/orchestration/RunContinuationService.ts +94 -24
- package/src/runStorage/InMemoryWorkflowExecutionRepository.ts +14 -1
- package/src/scheduler/DefaultDrivingScheduler.ts +21 -11
- package/src/scheduler/InlineDrivingScheduler.ts +17 -21
- package/src/testing/CapturingScheduler.ts +15 -0
- package/src/testing/EngineTestKitRunIdFactory.ts +24 -0
- package/src/testing/InMemoryTriggerSetupStateRepository.ts +21 -0
- package/src/testing/PrefixedSequentialIdGenerator.ts +17 -0
- package/src/testing/RegistrarEngineTestKit.types.ts +76 -0
- package/src/testing/RegistrarEngineTestKitFactory.ts +154 -0
- package/src/testing/SubWorkflowRunnerTestNode.ts +83 -0
- package/src/testing/WorkflowTestHarnessManualTrigger.ts +39 -0
- package/src/testing/WorkflowTestKit.types.ts +9 -0
- package/src/testing/WorkflowTestKitBuilder.ts +77 -0
- package/src/testing/WorkflowTestKitNodeRegistrationContextFactory.ts +17 -0
- package/src/testing/WorkflowTestKitRunNodeWorkflowFactory.ts +26 -0
- package/src/testing.ts +19 -0
- package/src/types/index.ts +1 -0
- package/src/workflow/definition/ConnectionNodeIdFactory.ts +28 -0
- package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs +0 -151
- package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs.map +0 -1
- package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js +0 -139
- package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js.map +0 -1
- package/dist/RunIntentService-C1nu_YwM.js.map +0 -1
- package/dist/RunIntentService-DjbxzBBP.d.cts +0 -288
- package/dist/RunIntentService-ZkjpY7MS.cjs.map +0 -1
- package/dist/WorkflowSnapshotCodec-DSEzKyt3.d.cts +0 -22
- package/dist/bootstrap/index.cjs.map +0 -1
- package/dist/bootstrap/index.js.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["name: string","config: TConfig","id?: string","definition: DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings>","z","current: z.ZodTypeAny","name: string","node: TNodeConfig","node","node","messages: AgentMessageDto[]","wf: WorkflowBuilder","from: NodeRef","branchPort: OutputPortKey","created: NodeRef[]","prev: NodeRef | null","port: OutputPortKey","wf: WorkflowBuilder","cursor: NodeRef","cursorOutput: OutputPortKey","port: OutputPortKey","prev: NodeRef | null","meta: { id: WorkflowId; name: string }","options?: Readonly<{\n makeMergeNode?: (name: string) => AnyRunnableNodeConfig;\n }>","onClose: () => void","inner: WorkflowExecutionRepository","eventBus: RunEventBus","now: () => Date","ItemsInputNormalizer","maxAttempts: number","delayMs: number","maxAttempts: number","initialDelayMs: number","multiplier: number","maxDelayMs?: number","jitter?: boolean","bindingKey: CredentialBindingKey","acceptedTypes: ReadonlyArray<CredentialTypeId>"],"sources":["../src/contracts/Clock.ts","../src/authoring/DefinedNodeRegistry.ts","../src/authoring/defineNode.types.ts","../src/authoring/defineCredential.types.ts","../src/ai/NodeBackedToolConfig.ts","../src/ai/AgentToolFactory.ts","../src/ai/AgentMessageConfigNormalizerFactory.ts","../src/ai/AgentConfigInspectorFactory.ts","../src/ai/AiHost.ts","../src/workflow/dsl/WhenBuilder.ts","../src/workflow/dsl/ChainCursorResolver.ts","../src/workflow/dsl/WorkflowBuilder.ts","../src/workflow/definition/ConnectionInvocationIdFactory.ts","../src/workflow/graph/ExecutableGraph.ts","../src/workflow/graph/DefaultWorkflowGraphFactory.ts","../src/events/InMemoryRunEventSubscription.ts","../src/events/InMemoryRunEventBusRegistry.ts","../src/events/EventPublishingWorkflowExecutionRepository.ts","../src/serialization/ItemsInputNormalizer.ts","../src/contracts/NoRetryPolicy.ts","../src/contracts/RetryPolicy.ts","../src/contracts/ExpRetryPolicy.ts","../src/contracts/credentialTypes.ts","../src/contracts/workflowTypes.ts","../src/contracts/workflowActivationPolicy.ts"],"sourcesContent":["/** Port for time; inject `SystemClock` in production and a fake/test clock in tests. */\nexport interface Clock {\n now(): Date;\n}\n\nexport class SystemClock implements Clock {\n now(): Date {\n return new Date();\n }\n}\n","import type { DefinedNode } from \"./defineNode.types\";\n\nexport class DefinedNodeRegistry {\n private static readonly definitions = new Map<\n string,\n DefinedNode<string, Record<string, unknown>, unknown, unknown>\n >();\n\n static register(definition: DefinedNode<string, Record<string, unknown>, unknown, unknown>): void {\n this.definitions.set(definition.key, definition);\n }\n\n static resolve(key: string): DefinedNode<string, Record<string, unknown>, unknown, unknown> | undefined {\n return this.definitions.get(key);\n }\n}\n","import type {\n AnyCredentialType,\n CredentialJsonRecord,\n CredentialRequirement,\n CredentialTypeId,\n} from \"../contracts/credentialTypes\";\nimport type { Node, NodeExecutionContext } from \"../contracts/runtimeTypes\";\nimport type { Items, NodeOutputs, RunnableNodeConfig } from \"../contracts/workflowTypes\";\nimport type { TypeToken } from \"../di\";\nimport { node as persistedNode } from \"../runtime-types/runtimeTypeDecorators.types\";\nimport { z } from \"zod\";\nimport { DefinedNodeRegistry } from \"./DefinedNodeRegistry\";\n\ntype MaybePromise<TValue> = TValue | Promise<TValue>;\n\ntype ResolvableCredentialType = AnyCredentialType | CredentialTypeId;\n\ntype SessionForCredentialType<TCredential extends ResolvableCredentialType> = TCredential extends AnyCredentialType\n ? Awaited<ReturnType<TCredential[\"createSession\"]>>\n : unknown;\n\nexport type DefinedNodeCredentialBinding =\n | ResolvableCredentialType\n | Readonly<{\n readonly type: ResolvableCredentialType | ReadonlyArray<ResolvableCredentialType>;\n readonly label?: string;\n readonly optional?: true;\n readonly helpText?: string;\n readonly helpUrl?: string;\n }>;\n\nexport type DefinedNodeCredentialBindings = Readonly<Record<string, DefinedNodeCredentialBinding>>;\n\ntype SessionForBinding<TBinding extends DefinedNodeCredentialBinding> =\n TBinding extends Readonly<{ type: infer TType }>\n ? TType extends ReadonlyArray<infer TEntry>\n ? SessionForCredentialType<TEntry & ResolvableCredentialType>\n : SessionForCredentialType<TType & ResolvableCredentialType>\n : SessionForCredentialType<TBinding & ResolvableCredentialType>;\n\nexport type DefinedNodeCredentialAccessors<TBindings extends DefinedNodeCredentialBindings | undefined> =\n TBindings extends DefinedNodeCredentialBindings\n ? Readonly<{\n [TKey in keyof TBindings]: () => Promise<SessionForBinding<TBindings[TKey]>>;\n }>\n : Readonly<Record<string, never>>;\n\nexport interface DefinedNodeRunContext<\n TConfig extends CredentialJsonRecord,\n TBindings extends DefinedNodeCredentialBindings | undefined,\n> {\n readonly config: TConfig;\n readonly credentials: DefinedNodeCredentialAccessors<TBindings>;\n readonly execution: NodeExecutionContext<RunnableNodeConfig<TConfig, unknown>>;\n}\n\nexport interface DefinedNode<\n TKey extends string,\n TConfig extends CredentialJsonRecord,\n TInputJson,\n TOutputJson,\n _TBindings extends DefinedNodeCredentialBindings | undefined = undefined,\n> {\n readonly kind: \"defined-node\";\n readonly key: TKey;\n readonly title: string;\n readonly description?: string;\n create(config: TConfig, name?: string, id?: string): RunnableNodeConfig<TInputJson, TOutputJson>;\n register(context: { registerNode<TValue>(token: TypeToken<TValue>, implementation?: TypeToken<TValue>): void }): void;\n}\n\nexport interface DefineNodeOptions<\n TKey extends string,\n TConfig extends CredentialJsonRecord,\n TInputJson,\n TOutputJson,\n TBindings extends DefinedNodeCredentialBindings | undefined = undefined,\n> {\n readonly key: TKey;\n readonly title: string;\n readonly description?: string;\n readonly input?: Readonly<Record<keyof TConfig & string, unknown>>;\n readonly configSchema?: z.ZodType<TConfig>;\n readonly credentials?: TBindings;\n run(\n items: ReadonlyArray<TInputJson>,\n context: DefinedNodeRunContext<TConfig, TBindings>,\n ): MaybePromise<ReadonlyArray<TOutputJson>>;\n}\n\nconst definedNodeCredentialRequirementFactory = {\n create(bindings: DefinedNodeCredentialBindings | undefined): ReadonlyArray<CredentialRequirement> {\n if (!bindings) {\n return [];\n }\n return Object.entries(bindings).map(([slotKey, binding]) => {\n if (typeof binding === \"string\" || this.isCredentialType(binding)) {\n return {\n slotKey,\n label: this.humanize(slotKey),\n acceptedTypes: [this.resolveTypeId(binding)],\n };\n }\n\n const types = Array.isArray(binding.type) ? binding.type : [binding.type];\n return {\n slotKey,\n label: binding.label ?? this.humanize(slotKey),\n acceptedTypes: types.map((entry) => this.resolveTypeId(entry)),\n optional: binding.optional,\n helpText: binding.helpText,\n helpUrl: binding.helpUrl,\n };\n });\n },\n\n isCredentialType(value: unknown): value is AnyCredentialType {\n return (\n Boolean(value) &&\n typeof value === \"object\" &&\n \"definition\" in (value as Record<string, unknown>) &&\n typeof (value as AnyCredentialType).definition?.typeId === \"string\"\n );\n },\n\n resolveTypeId(type: ResolvableCredentialType): string {\n return typeof type === \"string\" ? type : type.definition.typeId;\n },\n\n humanize(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[-_.]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/^./, (character) => character.toUpperCase());\n },\n} as const;\n\nconst definedNodeCredentialAccessorFactory = {\n create<TBindings extends DefinedNodeCredentialBindings | undefined>(\n bindings: TBindings,\n ctx: NodeExecutionContext<RunnableNodeConfig<any, any>>,\n ): DefinedNodeCredentialAccessors<TBindings> {\n if (!bindings) {\n return {} as DefinedNodeCredentialAccessors<TBindings>;\n }\n const entries = Object.keys(bindings).map((slotKey) => [slotKey, () => ctx.getCredential(slotKey)] as const);\n return Object.fromEntries(entries) as DefinedNodeCredentialAccessors<TBindings>;\n },\n} as const;\n\nexport function defineNode<\n TKey extends string,\n TConfig extends CredentialJsonRecord,\n TInputJson,\n TOutputJson,\n TBindings extends DefinedNodeCredentialBindings | undefined = undefined,\n>(\n options: DefineNodeOptions<TKey, TConfig, TInputJson, TOutputJson, TBindings>,\n): DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings> {\n const credentialRequirements = definedNodeCredentialRequirementFactory.create(options.credentials);\n type DefinedRunnableNodeConfigShape = RunnableNodeConfig<TInputJson, TOutputJson> & Readonly<{ config: TConfig }>;\n\n const DefinedNodeRuntime = class implements Node<DefinedRunnableNodeConfigShape> {\n readonly kind = \"node\" as const;\n readonly outputPorts = [\"main\"] as const;\n\n async execute(items: Items, ctx: NodeExecutionContext<DefinedRunnableNodeConfigShape>): Promise<NodeOutputs> {\n const outputs = await options.run(\n items.map((item) => item.json as TInputJson),\n {\n config: ctx.config.config,\n credentials: definedNodeCredentialAccessorFactory.create(\n options.credentials,\n ctx,\n ) as DefinedNodeCredentialAccessors<TBindings>,\n execution: ctx as unknown as NodeExecutionContext<RunnableNodeConfig<TConfig, unknown>>,\n },\n );\n\n return {\n main: outputs.map((json, index) => {\n const existing = items[index];\n if (!existing) {\n return { json };\n }\n return { ...existing, json };\n }),\n };\n }\n };\n\n persistedNode({ name: options.key })(DefinedNodeRuntime);\n\n const DefinedRunnableNodeConfig = class implements RunnableNodeConfig<TInputJson, TOutputJson> {\n readonly kind = \"node\" as const;\n readonly type: TypeToken<unknown> = DefinedNodeRuntime;\n\n constructor(\n public readonly name: string,\n public readonly config: TConfig,\n public readonly id?: string,\n ) {}\n\n getCredentialRequirements(): ReadonlyArray<CredentialRequirement> {\n return credentialRequirements;\n }\n };\n\n const definition: DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings> = {\n kind: \"defined-node\",\n key: options.key,\n title: options.title,\n description: options.description,\n create(config, name = options.title, id) {\n return new DefinedRunnableNodeConfig(name, config, id);\n },\n register(context) {\n context.registerNode(DefinedNodeRuntime);\n },\n };\n\n DefinedNodeRegistry.register(definition as DefinedNode<string, Record<string, unknown>, unknown, unknown>);\n\n return definition;\n}\n","import type {\n AnyCredentialType,\n CredentialFieldSchema,\n CredentialHealth,\n CredentialJsonRecord,\n CredentialSessionFactoryArgs,\n CredentialType,\n CredentialTypeDefinition,\n} from \"../contracts/credentialTypes\";\nimport { z } from \"zod\";\n\ntype MaybePromise<TValue> = TValue | Promise<TValue>;\n\ntype CredentialFieldInput = CredentialFieldSchema[\"type\"] | Readonly<Omit<CredentialFieldSchema, \"key\">>;\n\ntype CredentialFieldMap<TConfig extends CredentialJsonRecord> = Readonly<\n Record<keyof TConfig & string, CredentialFieldInput>\n>;\n\ntype ZodObjectSchema<TConfig extends CredentialJsonRecord = CredentialJsonRecord> = z.ZodType<TConfig>;\n\ntype InferCredentialConfig<TSource> =\n TSource extends z.ZodType<infer TConfig, any, any>\n ? Readonly<TConfig> & CredentialJsonRecord\n : TSource extends CredentialFieldMap<infer TConfig>\n ? TConfig\n : CredentialJsonRecord;\n\nexport interface DefineCredentialOptions<\n TPublicSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSecretSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSession,\n> {\n readonly key: string;\n readonly label: string;\n readonly description?: string;\n readonly public: TPublicSource;\n readonly secret: TSecretSource;\n readonly supportedSourceKinds?: CredentialTypeDefinition[\"supportedSourceKinds\"];\n readonly auth?: CredentialTypeDefinition[\"auth\"];\n createSession(\n args: CredentialSessionFactoryArgs<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>>,\n ): MaybePromise<TSession>;\n test(\n args: CredentialSessionFactoryArgs<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>>,\n ): MaybePromise<CredentialHealth>;\n}\n\nexport class CredentialFieldSchemaFactory {\n static create<TConfig extends CredentialJsonRecord>(\n source: CredentialFieldMap<TConfig> | ZodObjectSchema<TConfig>,\n ): ReadonlyArray<CredentialFieldSchema> {\n if (source instanceof z.ZodObject) {\n return this.createFromZodObject(source);\n }\n return this.createFromMap(source as CredentialFieldMap<TConfig>);\n }\n\n private static createFromMap<TConfig extends CredentialJsonRecord>(\n source: CredentialFieldMap<TConfig>,\n ): ReadonlyArray<CredentialFieldSchema> {\n return Object.entries(source).map(([key, input], index) => {\n if (typeof input === \"string\") {\n return {\n key,\n label: this.humanize(key),\n order: index,\n type: input as CredentialFieldSchema[\"type\"],\n };\n }\n return {\n key,\n order: index,\n ...(input as Readonly<Omit<CredentialFieldSchema, \"key\">>),\n };\n });\n }\n\n private static createFromZodObject<_TConfig extends CredentialJsonRecord>(\n source: z.ZodObject,\n ): ReadonlyArray<CredentialFieldSchema> {\n const shape = source.shape;\n return Object.entries(shape).map(([key, schema], index) => {\n const resolved = this.unwrap(schema);\n return {\n key,\n label: this.humanize(key),\n order: index,\n required: this.isRequired(schema) ? true : undefined,\n type: this.resolveType(resolved),\n };\n });\n }\n\n private static isRequired(schema: z.ZodTypeAny): boolean {\n return !(schema instanceof z.ZodOptional || schema instanceof z.ZodDefault);\n }\n\n private static unwrap(schema: z.ZodTypeAny): z.ZodTypeAny {\n let current: z.ZodTypeAny = schema;\n while (current instanceof z.ZodOptional || current instanceof z.ZodDefault) {\n current = current.unwrap() as z.ZodTypeAny;\n }\n return current;\n }\n\n private static resolveType(schema: z.ZodTypeAny): CredentialFieldSchema[\"type\"] {\n if (schema instanceof z.ZodBoolean) {\n return \"boolean\";\n }\n if (schema instanceof z.ZodString) {\n return \"string\";\n }\n return \"json\";\n }\n\n private static humanize(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[-_.]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/^./, (character) => character.toUpperCase());\n }\n}\n\nexport function defineCredential<\n TPublicSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSecretSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSession,\n>(\n options: DefineCredentialOptions<TPublicSource, TSecretSource, TSession>,\n): CredentialType<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>, TSession> & {\n readonly key: string;\n} {\n const definition: CredentialTypeDefinition = {\n typeId: options.key,\n displayName: options.label,\n description: options.description,\n publicFields: CredentialFieldSchemaFactory.create(options.public),\n secretFields: CredentialFieldSchemaFactory.create(options.secret),\n supportedSourceKinds: options.supportedSourceKinds ?? [\"db\", \"env\", \"code\"],\n auth: options.auth,\n };\n\n const credentialType: AnyCredentialType = {\n definition,\n async createSession(args) {\n return await options.createSession(\n args as CredentialSessionFactoryArgs<\n InferCredentialConfig<TPublicSource>,\n InferCredentialConfig<TSecretSource>\n >,\n );\n },\n async test(args) {\n return await options.test(\n args as CredentialSessionFactoryArgs<\n InferCredentialConfig<TPublicSource>,\n InferCredentialConfig<TSecretSource>\n >,\n );\n },\n };\n\n return {\n ...credentialType,\n key: options.key,\n } as CredentialType<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>, TSession> & {\n readonly key: string;\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 { RunnableNodeConfig } from \"../types\";\nimport type { NodeBackedToolConfigOptions, ZodSchemaAny } from \"./AiHost\";\nimport { NodeBackedToolConfig } from \"./NodeBackedToolConfig\";\n\nclass AgentToolFactoryImpl {\n asTool<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TInputSchema extends ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny,\n >(\n node: TNodeConfig,\n options: Readonly<{ name?: string } & NodeBackedToolConfigOptions<TNodeConfig, TInputSchema, TOutputSchema>>,\n ): NodeBackedToolConfig<TNodeConfig, TInputSchema, TOutputSchema> {\n return new NodeBackedToolConfig(options.name ?? node.name ?? \"tool\", node, options);\n }\n}\n\nexport const AgentToolFactory = new AgentToolFactoryImpl();\n","import type {\n AgentMessageBuildArgs,\n AgentMessageConfig,\n AgentMessageDto,\n AgentMessageLine,\n AgentNodeConfig,\n} from \"./AiHost\";\n\nexport class AgentMessageConfigNormalizer {\n static normalize<TInputJson, TOutputJson>(\n config: AgentNodeConfig<TInputJson, TOutputJson>,\n args: AgentMessageBuildArgs<TInputJson>,\n ): ReadonlyArray<AgentMessageDto> {\n const fromMessages = this.normalizeRichMessages(config.messages, args);\n if (fromMessages.length > 0) {\n return fromMessages;\n }\n throw new Error(\n \"AIAgent messages must be a non-empty array, or an object with a non-empty prompt array and/or buildMessages that returns messages.\",\n );\n }\n\n private static normalizeRichMessages<TInputJson>(\n config: AgentMessageConfig<TInputJson>,\n args: AgentMessageBuildArgs<TInputJson>,\n ): ReadonlyArray<AgentMessageDto> {\n if (Array.isArray(config)) {\n return config.map((line) => this.lineToDto(line, args));\n }\n const structured = config as {\n readonly prompt?: ReadonlyArray<AgentMessageLine<TInputJson>>;\n readonly buildMessages?: (a: AgentMessageBuildArgs<TInputJson>) => ReadonlyArray<AgentMessageDto>;\n };\n const messages: AgentMessageDto[] = [];\n for (const line of structured.prompt ?? []) {\n messages.push(this.lineToDto(line, args));\n }\n for (const message of structured.buildMessages?.(args) ?? []) {\n messages.push(message);\n }\n return messages;\n }\n\n private static lineToDto<TInputJson>(\n line: AgentMessageLine<TInputJson>,\n args: AgentMessageBuildArgs<TInputJson>,\n ): AgentMessageDto {\n const content = typeof line.content === \"function\" ? line.content(args) : line.content;\n return { role: line.role, content };\n }\n}\n","import type { NodeConfigBase } from \"../types\";\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 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 { TypeToken } from \"../di\";\n\nimport type { CredentialRequirement } from \"../contracts/credentialTypes\";\n\nimport type {\n Item,\n Items,\n JsonValue,\n NodeExecutionContext,\n NodeOutputs,\n RunnableNodeConfig,\n RunnableNodeInputJson,\n} from \"../types\";\n\nimport type { input as ZodInput, output as ZodOutput, ZodType } from \"zod\";\n\nexport interface AgentCanvasPresentation<TIcon extends string = string> {\n readonly label?: string;\n readonly icon?: TIcon;\n}\n\nexport type ZodSchemaAny = ZodType<any, any, any>;\n\nexport interface ToolConfig {\n readonly type: TypeToken<unknown>;\n readonly name: string;\n readonly description?: string;\n readonly presentation?: AgentCanvasPresentation;\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}\n\nexport type ToolExecuteArgs<TConfig extends ToolConfig = ToolConfig, TInput = unknown> = Readonly<{\n config: TConfig;\n input: TInput;\n ctx: NodeExecutionContext<any>;\n item: Item;\n itemIndex: number;\n items: Items;\n}>;\n\nexport interface Tool<\n TConfig extends ToolConfig = ToolConfig,\n TInputSchema extends ZodSchemaAny = ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny = ZodSchemaAny,\n> {\n readonly defaultDescription: string;\n readonly inputSchema: TInputSchema;\n readonly outputSchema: TOutputSchema;\n execute(\n args: ToolExecuteArgs<TConfig, ZodInput<TInputSchema>>,\n ): Promise<ZodOutput<TOutputSchema>> | ZodOutput<TOutputSchema>;\n}\n\nexport type AgentTool<\n TInputSchema extends ZodSchemaAny = ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny = ZodSchemaAny,\n> = Tool<ToolConfig, TInputSchema, TOutputSchema>;\n\nexport type AgentToolExecuteArgs<TInput = unknown> = ToolExecuteArgs<ToolConfig, TInput>;\n\nexport type AgentToolToken = TypeToken<Tool<ToolConfig, ZodSchemaAny, ZodSchemaAny>>;\n\nexport type AgentMessageRole = \"system\" | \"user\" | \"assistant\";\n\nexport type AgentMessageBuildArgs<TInputJson = unknown> = Readonly<{\n item: Item<TInputJson>;\n itemIndex: number;\n items: Items<TInputJson>;\n ctx: NodeExecutionContext<any>;\n}>;\n\nexport interface AgentMessageDto {\n readonly role: AgentMessageRole;\n readonly content: string;\n}\n\nexport type AgentMessageTemplateContent<TInputJson = unknown> =\n | string\n | ((args: AgentMessageBuildArgs<TInputJson>) => string);\n\nexport interface AgentMessageTemplate<TInputJson = unknown> {\n readonly role: AgentMessageRole;\n readonly content: AgentMessageTemplateContent<TInputJson>;\n}\n\n/** A single prompt line: fixed DTO or template with optional function `content`. */\nexport type AgentMessageLine<TInputJson = unknown> = AgentMessageDto | AgentMessageTemplate<TInputJson>;\n\n/**\n * Message list for an agent. Prefer a **plain array** of `{ role, content }` (optionally with function `content` for templates).\n * Use the object form only when you need `buildMessages` to append messages after optional `prompt` lines.\n */\nexport type AgentMessageConfig<TInputJson = unknown> =\n | ReadonlyArray<AgentMessageLine<TInputJson>>\n | {\n readonly prompt?: ReadonlyArray<AgentMessageLine<TInputJson>>;\n readonly buildMessages?: (args: AgentMessageBuildArgs<TInputJson>) => ReadonlyArray<AgentMessageDto>;\n };\n\nexport type AgentTurnLimitBehavior = \"error\" | \"respondWithLastMessage\";\n\nexport interface AgentModelInvocationOptions {\n readonly maxTokens?: number;\n readonly providerOptions?: Readonly<Record<string, JsonValue>>;\n}\n\nexport interface AgentGuardrailConfig {\n readonly maxTurns?: number;\n readonly onTurnLimitReached?: AgentTurnLimitBehavior;\n readonly modelInvocationOptions?: AgentModelInvocationOptions;\n}\n\n/** Defaults aligned with common tool-agent iteration limits (many products use ~10 max rounds). */\nexport const AgentGuardrailDefaults = {\n maxTurns: 10,\n onTurnLimitReached: \"error\" as AgentTurnLimitBehavior,\n} as const;\n\nexport interface AgentToolDefinition {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: ZodSchemaAny;\n}\n\nexport type AgentToolCall = Readonly<{ id?: string; name: string; input: unknown }>;\n\nexport type AgentToolCallPlanner<_TNodeConfig = unknown> = (\n item: Item,\n index: number,\n items: Items,\n ctx: NodeExecutionContext<any>,\n) => ReadonlyArray<AgentToolCall>;\n\nexport interface ChatModelConfig {\n readonly type: TypeToken<ChatModelFactory<ChatModelConfig>>;\n readonly name: string;\n readonly presentation?: AgentCanvasPresentation;\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}\n\nexport interface LangChainChatModelLike {\n invoke(input: unknown, options?: unknown): Promise<unknown>;\n bindTools?(tools: ReadonlyArray<unknown>): LangChainChatModelLike;\n}\n\nexport interface ChatModelFactory<TConfig extends ChatModelConfig = ChatModelConfig> {\n create(\n args: Readonly<{ config: TConfig; ctx: NodeExecutionContext<any> }>,\n ): Promise<LangChainChatModelLike> | LangChainChatModelLike;\n}\n\nexport type NodeBackedToolInputMapperArgs<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TToolInput = unknown,\n> = Readonly<{\n input: TToolInput;\n item: Item;\n itemIndex: number;\n items: Items;\n ctx: NodeExecutionContext<any>;\n node: TNodeConfig;\n}>;\n\nexport type NodeBackedToolOutputMapperArgs<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TToolInput = unknown,\n> = Readonly<{\n input: TToolInput;\n item: Item;\n itemIndex: number;\n items: Items;\n ctx: NodeExecutionContext<any>;\n node: TNodeConfig;\n outputs: NodeOutputs;\n}>;\n\nexport type NodeBackedToolInputMapper<TNodeConfig extends RunnableNodeConfig<any, any>, TToolInput = unknown> = (\n args: NodeBackedToolInputMapperArgs<TNodeConfig, TToolInput>,\n) => Item<RunnableNodeInputJson<TNodeConfig>> | RunnableNodeInputJson<TNodeConfig>;\n\nexport type NodeBackedToolOutputMapper<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TToolInput = unknown,\n TToolOutput = unknown,\n> = (args: NodeBackedToolOutputMapperArgs<TNodeConfig, TToolInput>) => TToolOutput;\n\nexport type NodeBackedToolConfigOptions<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TInputSchema extends ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny,\n> = Readonly<{\n description?: string;\n presentation?: AgentCanvasPresentation;\n inputSchema: TInputSchema;\n outputSchema: TOutputSchema;\n mapInput?: NodeBackedToolInputMapper<TNodeConfig, ZodInput<TInputSchema>>;\n mapOutput?: NodeBackedToolOutputMapper<TNodeConfig, ZodInput<TInputSchema>, ZodOutput<TOutputSchema>>;\n}>;\n\nexport interface AgentNodeConfig<TInputJson = unknown, TOutputJson = unknown> extends RunnableNodeConfig<\n TInputJson,\n TOutputJson\n> {\n readonly messages: AgentMessageConfig<TInputJson>;\n readonly chatModel: ChatModelConfig;\n readonly tools?: ReadonlyArray<ToolConfig>;\n readonly guardrails?: AgentGuardrailConfig;\n}\n\nexport type AgentAttachmentRole = \"languageModel\" | \"tool\";\n\nexport { NodeBackedToolConfig } from \"./NodeBackedToolConfig\";\nexport { AgentToolFactory } from \"./AgentToolFactory\";\nexport { AgentMessageConfigNormalizer } from \"./AgentMessageConfigNormalizerFactory\";\nexport { AgentConfigInspector } from \"./AgentConfigInspectorFactory\";\n","import type { NodeId, NodeRef, OutputPortKey, UpstreamRefPlaceholder, WorkflowDefinition } from \"../../types\";\n\nimport { WorkflowBuilder } from \"./WorkflowBuilder\";\nimport type { AnyRunnableNodeConfig, BooleanWhenOverloads, ValidStepSequence } from \"./workflowBuilderTypes\";\n\nexport class WhenBuilder<TCurrentJson> {\n constructor(\n private readonly wf: WorkflowBuilder,\n private readonly from: NodeRef,\n private readonly branchPort: OutputPortKey,\n ) {}\n\n addBranch<TSteps extends ReadonlyArray<AnyRunnableNodeConfig>>(\n steps: TSteps & ValidStepSequence<TCurrentJson, TSteps>,\n ): this {\n const created: NodeRef[] = [];\n\n let prev: NodeRef | null = null;\n for (const cfg of steps) {\n const ref = (this.wf as any).add(cfg) as NodeRef;\n created.push(ref);\n if (!prev) (this.wf as any).connect(this.from, ref, this.branchPort, \"in\");\n else (this.wf as any).connect(prev, ref, \"main\", \"in\");\n prev = ref;\n }\n\n for (const cfg of steps) {\n const maybe = cfg as unknown as { upstreamRefs?: Array<{ nodeId: NodeId } | UpstreamRefPlaceholder> };\n if (!Array.isArray(maybe.upstreamRefs) || maybe.upstreamRefs.length === 0) continue;\n\n maybe.upstreamRefs = maybe.upstreamRefs.map((r) => {\n if (typeof r !== \"string\") return r;\n const idx = parseInt(r.slice(1), 10);\n const nodeId = created[idx]?.id;\n return nodeId ? { nodeId } : { nodeId: r };\n });\n }\n\n return this;\n }\n\n readonly when: BooleanWhenOverloads<TCurrentJson, WhenBuilder<TCurrentJson>> = (\n branch: boolean,\n steps: ReadonlyArray<AnyRunnableNodeConfig> | AnyRunnableNodeConfig,\n ...more: AnyRunnableNodeConfig[]\n ): WhenBuilder<TCurrentJson> => {\n const list = Array.isArray(steps) ? steps : [steps, ...more];\n const port: OutputPortKey = branch ? \"true\" : \"false\";\n const b = new WhenBuilder<TCurrentJson>(this.wf, this.from, port);\n b.addBranch(list);\n return b;\n };\n\n build(): WorkflowDefinition {\n return this.wf.build();\n }\n}\n","import type {\n NodeRef,\n OutputPortKey,\n RunnableNodeConfig,\n RunnableNodeOutputJson,\n WorkflowDefinition,\n} from \"../../types\";\n\nimport { WorkflowBuilder } from \"./WorkflowBuilder\";\nimport { WhenBuilder } from \"./WhenBuilder\";\nimport type {\n AnyRunnableNodeConfig,\n BooleanWhenOverloads,\n BranchOutputGuard,\n BranchStepsArg,\n StepSequenceOutput,\n} from \"./workflowBuilderTypes\";\n\ntype ChainCursorWhenOverloads<TCurrentJson> = BooleanWhenOverloads<TCurrentJson, WhenBuilder<TCurrentJson>> & {\n <\n TTrueSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,\n TFalseSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,\n >(\n branches: Readonly<{\n true?: TTrueSteps extends ReadonlyArray<AnyRunnableNodeConfig> ? BranchStepsArg<TCurrentJson, TTrueSteps> : never;\n false?: TFalseSteps extends ReadonlyArray<AnyRunnableNodeConfig>\n ? BranchStepsArg<TCurrentJson, TFalseSteps>\n : never;\n }> &\n BranchOutputGuard<TCurrentJson, TTrueSteps, TFalseSteps>,\n ): ChainCursor<StepSequenceOutput<TCurrentJson, TTrueSteps>>;\n};\n\nexport class ChainCursor<TCurrentJson> {\n constructor(\n private readonly wf: WorkflowBuilder,\n private readonly cursor: NodeRef,\n private readonly cursorOutput: OutputPortKey,\n ) {}\n\n then<TConfig extends RunnableNodeConfig<TCurrentJson, any>>(\n config: TConfig,\n ): ChainCursor<RunnableNodeOutputJson<TConfig>> {\n const next = (this.wf as any).add(config) as NodeRef;\n (this.wf as any).connect(this.cursor, next, this.cursorOutput);\n return new ChainCursor<RunnableNodeOutputJson<TConfig>>(this.wf, next, \"main\");\n }\n\n readonly when: ChainCursorWhenOverloads<TCurrentJson> = ((\n arg1:\n | boolean\n | Readonly<{ true?: ReadonlyArray<AnyRunnableNodeConfig>; false?: ReadonlyArray<AnyRunnableNodeConfig> }>,\n steps?: ReadonlyArray<AnyRunnableNodeConfig> | AnyRunnableNodeConfig,\n ...more: AnyRunnableNodeConfig[]\n ): WhenBuilder<TCurrentJson> | ChainCursor<TCurrentJson> => {\n if (typeof arg1 === \"boolean\") {\n const list = Array.isArray(steps) ? steps : steps ? [steps, ...more] : more;\n const port: OutputPortKey = arg1 ? \"true\" : \"false\";\n const b = new WhenBuilder<TCurrentJson>(this.wf, this.cursor, port);\n b.addBranch(list);\n return b;\n }\n\n const branches = arg1;\n const makeMerge = (this.wf as any).options?.makeMergeNode as ((name: string) => AnyRunnableNodeConfig) | undefined;\n if (!makeMerge) {\n throw new Error(\n 'WorkflowBuilder is missing options.makeMergeNode (required for when({true,false}). Use createWorkflowBuilder from \"@codemation/core-nodes\".',\n );\n }\n\n const wfAny = this.wf as any;\n\n const buildBranch = (\n port: OutputPortKey,\n branchSteps: ReadonlyArray<AnyRunnableNodeConfig> | undefined,\n ): Readonly<{ end: NodeRef; endOutput: OutputPortKey }> => {\n const list = branchSteps ?? [];\n let prev: NodeRef | null = null;\n for (const cfg of list) {\n const ref = wfAny.add(cfg) as NodeRef;\n if (!prev) wfAny.connect(this.cursor, ref, port, \"in\");\n else wfAny.connect(prev, ref, \"main\", \"in\");\n prev = ref;\n }\n if (!prev) return { end: this.cursor, endOutput: port };\n return { end: prev, endOutput: \"main\" };\n };\n\n const t = buildBranch(\"true\", branches.true);\n const f = buildBranch(\"false\", branches.false);\n\n const merge = wfAny.add(makeMerge(\"Merge (auto)\")) as NodeRef;\n wfAny.connect(t.end, merge, t.endOutput, \"true\");\n wfAny.connect(f.end, merge, f.endOutput, \"false\");\n\n return new ChainCursor<TCurrentJson>(this.wf, merge, \"main\");\n }) as ChainCursorWhenOverloads<TCurrentJson>;\n\n build(): WorkflowDefinition {\n return this.wf.build();\n }\n}\n","import type {\n InputPortKey,\n NodeConfigBase,\n NodeDefinition,\n NodeRef,\n OutputPortKey,\n RunnableNodeOutputJson,\n TriggerNodeOutputJson,\n WorkflowDefinition,\n WorkflowId,\n} from \"../../types\";\n\nimport { ChainCursor } from \"./ChainCursorResolver\";\nimport type { AnyRunnableNodeConfig, AnyTriggerNodeConfig } from \"./workflowBuilderTypes\";\n\nexport class WorkflowBuilder {\n private readonly nodes: NodeDefinition[] = [];\n private readonly edges: WorkflowDefinition[\"edges\"] = [];\n private seq = 0;\n\n constructor(\n private readonly meta: { id: WorkflowId; name: string },\n private readonly options?: Readonly<{\n makeMergeNode?: (name: string) => AnyRunnableNodeConfig;\n }>,\n ) {}\n\n private add(config: NodeConfigBase): NodeRef {\n const tokenName = typeof config.type === \"function\" ? config.type.name : String(config.type);\n const id = config.id ?? `${tokenName}:${++this.seq}`;\n this.nodes.push({ id, kind: config.kind, type: config.type, name: config.name, config });\n return { id, kind: config.kind, name: config.name };\n }\n\n private connect(from: NodeRef, to: NodeRef, fromOutput: OutputPortKey = \"main\", toInput: InputPortKey = \"in\"): void {\n this.edges.push({ from: { nodeId: from.id, output: fromOutput }, to: { nodeId: to.id, input: toInput } });\n }\n\n trigger<TConfig extends AnyTriggerNodeConfig>(config: TConfig): ChainCursor<TriggerNodeOutputJson<TConfig>> {\n const ref = this.add(config);\n return new ChainCursor<TriggerNodeOutputJson<TConfig>>(this, ref, \"main\");\n }\n\n start<TConfig extends AnyRunnableNodeConfig>(config: TConfig): ChainCursor<RunnableNodeOutputJson<TConfig>> {\n const ref = this.add(config);\n return new ChainCursor<RunnableNodeOutputJson<TConfig>>(this, ref, \"main\");\n }\n\n build(): WorkflowDefinition {\n return { ...this.meta, nodes: this.nodes, edges: this.edges };\n }\n}\n\nexport { ChainCursor } from \"./ChainCursorResolver\";\nexport { WhenBuilder } from \"./WhenBuilder\";\n","import { randomUUID } from \"node:crypto\";\n\nimport type { NodeId } from \"../../types\";\n\n/**\n * Unique ids for persisted connection invocation history rows (LLM/tool calls under an owning node).\n */\nexport class ConnectionInvocationIdFactory {\n static create(): string {\n return `cinv_${randomUUID()}`;\n }\n\n /** Deterministic id for tests when a stable sequence is needed. */\n static createForTest(runId: string, connectionNodeId: NodeId, sequence: number): string {\n return `cinv_${runId}_${connectionNodeId}_${sequence}`;\n }\n}\n","import type { InputPortKey, NodeId, OutputPortKey, WorkflowDefinition, WorkflowGraph } from \"../../types\";\n\nexport class ExecutableGraph implements WorkflowGraph {\n private readonly outgoingByNodeAndPort = new Map<\n NodeId,\n Map<OutputPortKey, Array<Readonly<{ nodeId: NodeId; input: InputPortKey }>>>\n >();\n\n constructor(def: WorkflowDefinition) {\n for (const e of def.edges) {\n const byPort =\n this.outgoingByNodeAndPort.get(e.from.nodeId) ??\n new Map<OutputPortKey, Array<Readonly<{ nodeId: NodeId; input: InputPortKey }>>>();\n const next = byPort.get(e.from.output) ?? [];\n next.push({ nodeId: e.to.nodeId, input: e.to.input });\n byPort.set(e.from.output, next);\n this.outgoingByNodeAndPort.set(e.from.nodeId, byPort);\n }\n }\n\n next(nodeId: NodeId, output: OutputPortKey): Array<Readonly<{ nodeId: NodeId; input: InputPortKey }>> {\n return this.outgoingByNodeAndPort.get(nodeId)?.get(output) ?? [];\n }\n}\n","import type { WorkflowDefinition, WorkflowGraph, WorkflowGraphFactory } from \"../../types\";\nimport { ExecutableGraph } from \"./ExecutableGraph\";\n\nexport class DefaultWorkflowGraphFactory implements WorkflowGraphFactory {\n create(def: WorkflowDefinition): WorkflowGraph {\n return new ExecutableGraph(def);\n }\n}\n","import type { RunEventSubscription } from \"./runEvents\";\n\nexport class InMemoryRunEventSubscription implements RunEventSubscription {\n constructor(private readonly onClose: () => void) {}\n\n async close(): Promise<void> {\n this.onClose();\n }\n}\n","import type { WorkflowId } from \"../types\";\n\nimport type { RunEvent, RunEventBus, RunEventSubscription } from \"./runEvents\";\n\nimport { InMemoryRunEventSubscription } from \"./InMemoryRunEventSubscription\";\n\nexport class InMemoryRunEventBus implements RunEventBus {\n private readonly globalListeners = new Set<(event: RunEvent) => void>();\n private readonly listenersByWorkflowId = new Map<WorkflowId, Set<(event: RunEvent) => void>>();\n\n async publish(event: RunEvent): Promise<void> {\n for (const listener of this.globalListeners) listener(event);\n for (const listener of this.listenersByWorkflowId.get(event.workflowId) ?? []) listener(event);\n }\n\n async subscribe(onEvent: (event: RunEvent) => void): Promise<RunEventSubscription> {\n this.globalListeners.add(onEvent);\n return new InMemoryRunEventSubscription(() => {\n this.globalListeners.delete(onEvent);\n });\n }\n\n async subscribeToWorkflow(workflowId: WorkflowId, onEvent: (event: RunEvent) => void): Promise<RunEventSubscription> {\n const existing = this.listenersByWorkflowId.get(workflowId) ?? new Set<(event: RunEvent) => void>();\n existing.add(onEvent);\n this.listenersByWorkflowId.set(workflowId, existing);\n\n return new InMemoryRunEventSubscription(() => {\n const listeners = this.listenersByWorkflowId.get(workflowId);\n if (!listeners) return;\n listeners.delete(onEvent);\n if (listeners.size === 0) this.listenersByWorkflowId.delete(workflowId);\n });\n }\n}\n\nexport { InMemoryRunEventSubscription } from \"./InMemoryRunEventSubscription\";\n","import type {\n PersistedRunState,\n RunId,\n RunPruneCandidate,\n RunSummary,\n WorkflowExecutionListingRepository,\n WorkflowExecutionPruneRepository,\n WorkflowExecutionRepository,\n WorkflowId,\n} from \"../types\";\nimport type { RunEventBus } from \"./runEvents\";\n\nexport class EventPublishingWorkflowExecutionRepository\n implements WorkflowExecutionRepository, WorkflowExecutionListingRepository, WorkflowExecutionPruneRepository\n{\n constructor(\n private readonly inner: WorkflowExecutionRepository,\n private readonly eventBus: RunEventBus,\n private readonly now: () => Date = () => new Date(),\n ) {}\n\n async createRun(args: Parameters<WorkflowExecutionRepository[\"createRun\"]>[0]): Promise<void> {\n await this.inner.createRun(args);\n await this.eventBus.publish({\n kind: \"runCreated\",\n runId: args.runId,\n workflowId: args.workflowId,\n parent: args.parent,\n at: this.now().toISOString(),\n });\n }\n\n async load(runId: RunId): Promise<PersistedRunState | undefined> {\n return await this.inner.load(runId);\n }\n\n async save(state: PersistedRunState): Promise<void> {\n await this.inner.save(state);\n await this.eventBus.publish({\n kind: \"runSaved\",\n runId: state.runId,\n workflowId: state.workflowId,\n parent: state.parent,\n at: this.now().toISOString(),\n state,\n });\n }\n\n async deleteRun(runId: RunId): Promise<void> {\n if (!this.inner.deleteRun) return;\n await this.inner.deleteRun(runId);\n }\n\n async listRuns(args?: Readonly<{ workflowId?: WorkflowId; limit?: number }>): Promise<ReadonlyArray<RunSummary>> {\n const listingRepository = this.inner as unknown as Partial<WorkflowExecutionListingRepository>;\n if (!listingRepository.listRuns) return [];\n return await listingRepository.listRuns(args);\n }\n\n async listRunsOlderThan(\n args: Readonly<{ beforeIso: string; limit?: number }>,\n ): Promise<ReadonlyArray<RunPruneCandidate>> {\n const pruneRepository = this.inner as unknown as Partial<WorkflowExecutionPruneRepository>;\n if (!pruneRepository.listRunsOlderThan) return [];\n return await pruneRepository.listRunsOlderThan(args);\n }\n}\n","import type { Item, Items } from \"../contracts/workflowTypes\";\nimport { injectable } from \"../di\";\n\n/**\n * Normalizes external inputs into the engine's canonical `Items` shape.\n * Used at host and builder boundaries where callers may provide either a raw value,\n * a single item-like object, or an array of item-like values.\n */\n@injectable()\nexport class ItemsInputNormalizer {\n normalize(raw: unknown): Items {\n if (raw === undefined || raw === null) {\n return [];\n }\n if (Array.isArray(raw)) {\n return raw.map((value) => this.normalizeItem(value));\n }\n return [this.normalizeItem(raw)];\n }\n\n private normalizeItem(raw: unknown): Item {\n if (!this.isItem(raw)) {\n return { json: raw };\n }\n return {\n json: raw.json,\n ...(raw.binary === undefined ? {} : { binary: raw.binary }),\n ...(raw.meta === undefined ? {} : { meta: raw.meta }),\n ...(raw.paired === undefined ? {} : { paired: raw.paired }),\n };\n }\n\n private isItem(raw: unknown): raw is Item {\n return typeof raw === \"object\" && raw !== null && Object.prototype.hasOwnProperty.call(raw, \"json\");\n }\n}\n","import type { NoneRetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport class NoRetryPolicy implements NoneRetryPolicySpec {\n readonly kind = \"none\" as const;\n}\n","import type { FixedRetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport class RetryPolicy implements FixedRetryPolicySpec {\n readonly kind = \"fixed\" as const;\n\n constructor(\n public readonly maxAttempts: number,\n public readonly delayMs: number,\n ) {\n if (!Number.isFinite(maxAttempts) || maxAttempts < 1 || !Number.isInteger(maxAttempts)) {\n throw new Error(`RetryPolicy.maxAttempts must be a positive integer, got ${maxAttempts}`);\n }\n if (!Number.isFinite(delayMs) || delayMs < 0) {\n throw new Error(`RetryPolicy.delayMs must be a non-negative finite number, got ${delayMs}`);\n }\n }\n\n /** Default for HTTP-style transient failures: 3 tries, 1s between attempts. */\n static readonly defaultForHttp: FixedRetryPolicySpec = { kind: \"fixed\", maxAttempts: 3, delayMs: 1000 };\n\n /** Default for LLM / agent calls: 3 tries, 2s fixed backoff. */\n static readonly defaultForAiAgent: FixedRetryPolicySpec = { kind: \"fixed\", maxAttempts: 3, delayMs: 2000 };\n}\n","import type { ExponentialRetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport class ExpRetryPolicy implements ExponentialRetryPolicySpec {\n readonly kind = \"exponential\" as const;\n\n constructor(\n public readonly maxAttempts: number,\n public readonly initialDelayMs: number,\n public readonly multiplier: number,\n public readonly maxDelayMs?: number,\n public readonly jitter?: boolean,\n ) {\n if (!Number.isFinite(maxAttempts) || maxAttempts < 1 || !Number.isInteger(maxAttempts)) {\n throw new Error(`ExpRetryPolicy.maxAttempts must be a positive integer, got ${maxAttempts}`);\n }\n if (!Number.isFinite(initialDelayMs) || initialDelayMs < 0) {\n throw new Error(`ExpRetryPolicy.initialDelayMs must be a non-negative finite number, got ${initialDelayMs}`);\n }\n if (!Number.isFinite(multiplier) || multiplier < 1) {\n throw new Error(`ExpRetryPolicy.multiplier must be >= 1, got ${multiplier}`);\n }\n }\n}\n","import type { NodeId, WorkflowId } from \"./workflowTypes\";\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 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 CredentialOAuth2AuthDefinition = Readonly<\n | {\n kind: \"oauth2\";\n providerId: string;\n scopes: ReadonlyArray<string>;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n | {\n kind: \"oauth2\";\n providerFromPublicConfig: OAuth2ProviderFromPublicConfig;\n scopes: ReadonlyArray<string>;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n>;\n\nexport type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;\n\nexport type CredentialTypeDefinition = Readonly<{\n typeId: CredentialTypeId;\n displayName: string;\n description?: string;\n publicFields?: ReadonlyArray<CredentialFieldSchema>;\n secretFields?: ReadonlyArray<CredentialFieldSchema>;\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 { TypeToken } from \"../di\";\nimport type { CredentialRequirement } from \"./credentialTypes\";\nimport type { RetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport type WorkflowId = string;\nexport type NodeId = string;\nexport type OutputPortKey = string;\nexport type InputPortKey = string;\nexport type PersistedTokenId = string;\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\nexport interface Edge {\n from: { nodeId: NodeId; output: OutputPortKey };\n to: { nodeId: NodeId; input: InputPortKey };\n}\n\nexport type NodeConnectionName = string;\n\n/**\n * Named connection from an executable parent node to child nodes that exist in {@link WorkflowDefinition.nodes}\n * but are not traversed by the main execution graph.\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 getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}\n\nexport declare const runnableNodeInputType: unique symbol;\nexport declare const runnableNodeOutputType: unique symbol;\nexport declare const triggerNodeOutputType: unique symbol;\n\nexport interface RunnableNodeConfig<TInputJson = unknown, TOutputJson = unknown> extends NodeConfigBase {\n readonly kind: \"node\";\n readonly [runnableNodeInputType]?: TInputJson;\n readonly [runnableNodeOutputType]?: TOutputJson;\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\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 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\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\nexport interface RunDataSnapshot {\n getOutputs(nodeId: NodeId): NodeOutputs | undefined;\n getOutputItems(nodeId: NodeId, output?: OutputPortKey): Items;\n getOutputItem(nodeId: NodeId, itemIndex: number, output?: OutputPortKey): Item | 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}\n\nexport interface PersistedRunPolicySnapshot {\n readonly retentionSeconds?: number;\n readonly binaryRetentionSeconds?: 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 storagePolicy?: WorkflowStoragePolicyMode;\n}\n","import type { WorkflowId } from \"./workflowTypes\";\n\n/**\n * Host-controlled policy: when false, trigger {@link TriggerNode} setup is skipped and webhook routes\n * for that workflow are not registered (see engine trigger runtime + webhook matcher).\n */\nexport interface WorkflowActivationPolicy {\n isActive(workflowId: WorkflowId): boolean;\n}\n\n/** Default for tests and harnesses: every workflow is treated as active (legacy behavior). */\nexport class AllWorkflowsActiveWorkflowActivationPolicy implements WorkflowActivationPolicy {\n isActive(_workflowId: WorkflowId): boolean {\n return true;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["name: string","config: TConfig","id?: string","definition: DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings>","z","current: z.ZodTypeAny","name: string","node: TNodeConfig","node","node","messages: AgentMessageDto[]","AgentConnectionNodeCollector: AgentConnectionNodeCollectorApi","collected: AgentConnectionNodeDescriptor[]","ConnectionNodeIdFactory","tool","inner: WorkflowExecutionRepository","eventBus: RunEventBus","now: () => Date","ItemsInputNormalizer","maxAttempts: number","delayMs: number","maxAttempts: number","initialDelayMs: number","multiplier: number","maxDelayMs?: number","jitter?: boolean","bindingKey: CredentialBindingKey","acceptedTypes: ReadonlyArray<CredentialTypeId>"],"sources":["../src/contracts/Clock.ts","../src/authoring/DefinedNodeRegistry.ts","../src/authoring/defineNode.types.ts","../src/authoring/defineCredential.types.ts","../src/ai/NodeBackedToolConfig.ts","../src/ai/AgentConfigInspectorFactory.ts","../src/ai/AgentToolFactory.ts","../src/ai/AgentMessageConfigNormalizerFactory.ts","../src/ai/AiHost.ts","../src/ai/AgentConnectionNodeCollector.ts","../src/workflow/definition/ConnectionInvocationIdFactory.ts","../src/workflow/graph/ExecutableGraph.ts","../src/workflow/graph/DefaultWorkflowGraphFactory.ts","../src/events/EventPublishingWorkflowExecutionRepository.ts","../src/serialization/ItemsInputNormalizer.ts","../src/contracts/NoRetryPolicy.ts","../src/contracts/RetryPolicy.ts","../src/contracts/ExpRetryPolicy.ts","../src/contracts/credentialTypes.ts","../src/contracts/workflowTypes.ts"],"sourcesContent":["/** Port for time; inject `SystemClock` in production and a fake/test clock in tests. */\nexport interface Clock {\n now(): Date;\n}\n\nexport class SystemClock implements Clock {\n now(): Date {\n return new Date();\n }\n}\n","import type { DefinedNode } from \"./defineNode.types\";\n\nexport class DefinedNodeRegistry {\n private static readonly definitions = new Map<\n string,\n DefinedNode<string, Record<string, unknown>, unknown, unknown>\n >();\n\n static register(definition: DefinedNode<string, Record<string, unknown>, unknown, unknown>): void {\n this.definitions.set(definition.key, definition);\n }\n\n static resolve(key: string): DefinedNode<string, Record<string, unknown>, unknown, unknown> | undefined {\n return this.definitions.get(key);\n }\n}\n","import type {\n AnyCredentialType,\n CredentialJsonRecord,\n CredentialRequirement,\n CredentialTypeId,\n} from \"../contracts/credentialTypes\";\nimport type { Node, NodeExecutionContext } from \"../contracts/runtimeTypes\";\nimport type { Items, NodeOutputs, RunnableNodeConfig } from \"../contracts/workflowTypes\";\nimport type { TypeToken } from \"../di\";\nimport { node as persistedNode } from \"../runtime-types/runtimeTypeDecorators.types\";\nimport { z } from \"zod\";\nimport { DefinedNodeRegistry } from \"./DefinedNodeRegistry\";\n\ntype MaybePromise<TValue> = TValue | Promise<TValue>;\n\ntype ResolvableCredentialType = AnyCredentialType | CredentialTypeId;\n\ntype SessionForCredentialType<TCredential extends ResolvableCredentialType> = TCredential extends AnyCredentialType\n ? Awaited<ReturnType<TCredential[\"createSession\"]>>\n : unknown;\n\nexport type DefinedNodeCredentialBinding =\n | ResolvableCredentialType\n | Readonly<{\n readonly type: ResolvableCredentialType | ReadonlyArray<ResolvableCredentialType>;\n readonly label?: string;\n readonly optional?: true;\n readonly helpText?: string;\n readonly helpUrl?: string;\n }>;\n\nexport type DefinedNodeCredentialBindings = Readonly<Record<string, DefinedNodeCredentialBinding>>;\n\ntype SessionForBinding<TBinding extends DefinedNodeCredentialBinding> =\n TBinding extends Readonly<{ type: infer TType }>\n ? TType extends ReadonlyArray<infer TEntry>\n ? SessionForCredentialType<TEntry & ResolvableCredentialType>\n : SessionForCredentialType<TType & ResolvableCredentialType>\n : SessionForCredentialType<TBinding & ResolvableCredentialType>;\n\nexport type DefinedNodeCredentialAccessors<TBindings extends DefinedNodeCredentialBindings | undefined> =\n TBindings extends DefinedNodeCredentialBindings\n ? Readonly<{\n [TKey in keyof TBindings]: () => Promise<SessionForBinding<TBindings[TKey]>>;\n }>\n : Readonly<Record<string, never>>;\n\nexport interface DefinedNodeRunContext<\n TConfig extends CredentialJsonRecord,\n TBindings extends DefinedNodeCredentialBindings | undefined,\n> {\n readonly config: TConfig;\n readonly credentials: DefinedNodeCredentialAccessors<TBindings>;\n readonly execution: NodeExecutionContext<RunnableNodeConfig<TConfig, unknown>>;\n}\n\nexport interface DefinedNode<\n TKey extends string,\n TConfig extends CredentialJsonRecord,\n TInputJson,\n TOutputJson,\n _TBindings extends DefinedNodeCredentialBindings | undefined = undefined,\n> {\n readonly kind: \"defined-node\";\n readonly key: TKey;\n readonly title: string;\n readonly description?: string;\n create(config: TConfig, name?: string, id?: string): RunnableNodeConfig<TInputJson, TOutputJson>;\n register(context: { registerNode<TValue>(token: TypeToken<TValue>, implementation?: TypeToken<TValue>): void }): void;\n}\n\nexport interface DefineNodeOptions<\n TKey extends string,\n TConfig extends CredentialJsonRecord,\n TInputJson,\n TOutputJson,\n TBindings extends DefinedNodeCredentialBindings | undefined = undefined,\n> {\n readonly key: TKey;\n readonly title: string;\n readonly description?: string;\n readonly input?: Readonly<Record<keyof TConfig & string, unknown>>;\n readonly configSchema?: z.ZodType<TConfig>;\n readonly credentials?: TBindings;\n run(\n items: ReadonlyArray<TInputJson>,\n context: DefinedNodeRunContext<TConfig, TBindings>,\n ): MaybePromise<ReadonlyArray<TOutputJson>>;\n}\n\nconst definedNodeCredentialRequirementFactory = {\n create(bindings: DefinedNodeCredentialBindings | undefined): ReadonlyArray<CredentialRequirement> {\n if (!bindings) {\n return [];\n }\n return Object.entries(bindings).map(([slotKey, binding]) => {\n if (typeof binding === \"string\" || this.isCredentialType(binding)) {\n return {\n slotKey,\n label: this.humanize(slotKey),\n acceptedTypes: [this.resolveTypeId(binding)],\n };\n }\n\n const types = Array.isArray(binding.type) ? binding.type : [binding.type];\n return {\n slotKey,\n label: binding.label ?? this.humanize(slotKey),\n acceptedTypes: types.map((entry) => this.resolveTypeId(entry)),\n optional: binding.optional,\n helpText: binding.helpText,\n helpUrl: binding.helpUrl,\n };\n });\n },\n\n isCredentialType(value: unknown): value is AnyCredentialType {\n return (\n Boolean(value) &&\n typeof value === \"object\" &&\n \"definition\" in (value as Record<string, unknown>) &&\n typeof (value as AnyCredentialType).definition?.typeId === \"string\"\n );\n },\n\n resolveTypeId(type: ResolvableCredentialType): string {\n return typeof type === \"string\" ? type : type.definition.typeId;\n },\n\n humanize(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[-_.]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/^./, (character) => character.toUpperCase());\n },\n} as const;\n\nconst definedNodeCredentialAccessorFactory = {\n create<TBindings extends DefinedNodeCredentialBindings | undefined>(\n bindings: TBindings,\n ctx: NodeExecutionContext<RunnableNodeConfig<any, any>>,\n ): DefinedNodeCredentialAccessors<TBindings> {\n if (!bindings) {\n return {} as DefinedNodeCredentialAccessors<TBindings>;\n }\n const entries = Object.keys(bindings).map((slotKey) => [slotKey, () => ctx.getCredential(slotKey)] as const);\n return Object.fromEntries(entries) as DefinedNodeCredentialAccessors<TBindings>;\n },\n} as const;\n\nexport function defineNode<\n TKey extends string,\n TConfig extends CredentialJsonRecord,\n TInputJson,\n TOutputJson,\n TBindings extends DefinedNodeCredentialBindings | undefined = undefined,\n>(\n options: DefineNodeOptions<TKey, TConfig, TInputJson, TOutputJson, TBindings>,\n): DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings> {\n const credentialRequirements = definedNodeCredentialRequirementFactory.create(options.credentials);\n type DefinedRunnableNodeConfigShape = RunnableNodeConfig<TInputJson, TOutputJson> & Readonly<{ config: TConfig }>;\n\n const DefinedNodeRuntime = class implements Node<DefinedRunnableNodeConfigShape> {\n readonly kind = \"node\" as const;\n readonly outputPorts = [\"main\"] as const;\n\n async execute(items: Items, ctx: NodeExecutionContext<DefinedRunnableNodeConfigShape>): Promise<NodeOutputs> {\n const outputs = await options.run(\n items.map((item) => item.json as TInputJson),\n {\n config: ctx.config.config,\n credentials: definedNodeCredentialAccessorFactory.create(\n options.credentials,\n ctx,\n ) as DefinedNodeCredentialAccessors<TBindings>,\n execution: ctx as unknown as NodeExecutionContext<RunnableNodeConfig<TConfig, unknown>>,\n },\n );\n\n return {\n main: outputs.map((json, index) => {\n const existing = items[index];\n if (!existing) {\n return { json };\n }\n return { ...existing, json };\n }),\n };\n }\n };\n\n persistedNode({ name: options.key })(DefinedNodeRuntime);\n\n const DefinedRunnableNodeConfig = class implements RunnableNodeConfig<TInputJson, TOutputJson> {\n readonly kind = \"node\" as const;\n readonly type: TypeToken<unknown> = DefinedNodeRuntime;\n\n constructor(\n public readonly name: string,\n public readonly config: TConfig,\n public readonly id?: string,\n ) {}\n\n getCredentialRequirements(): ReadonlyArray<CredentialRequirement> {\n return credentialRequirements;\n }\n };\n\n const definition: DefinedNode<TKey, TConfig, TInputJson, TOutputJson, TBindings> = {\n kind: \"defined-node\",\n key: options.key,\n title: options.title,\n description: options.description,\n create(config, name = options.title, id) {\n return new DefinedRunnableNodeConfig(name, config, id);\n },\n register(context) {\n context.registerNode(DefinedNodeRuntime);\n },\n };\n\n DefinedNodeRegistry.register(definition as DefinedNode<string, Record<string, unknown>, unknown, unknown>);\n\n return definition;\n}\n","import type {\n AnyCredentialType,\n CredentialFieldSchema,\n CredentialHealth,\n CredentialJsonRecord,\n CredentialSessionFactoryArgs,\n CredentialType,\n CredentialTypeDefinition,\n} from \"../contracts/credentialTypes\";\nimport { z } from \"zod\";\n\ntype MaybePromise<TValue> = TValue | Promise<TValue>;\n\ntype CredentialFieldInput = CredentialFieldSchema[\"type\"] | Readonly<Omit<CredentialFieldSchema, \"key\">>;\n\ntype CredentialFieldMap<TConfig extends CredentialJsonRecord> = Readonly<\n Record<keyof TConfig & string, CredentialFieldInput>\n>;\n\ntype ZodObjectSchema<TConfig extends CredentialJsonRecord = CredentialJsonRecord> = z.ZodType<TConfig>;\n\ntype InferCredentialConfig<TSource> =\n TSource extends z.ZodType<infer TConfig, any, any>\n ? Readonly<TConfig> & CredentialJsonRecord\n : TSource extends CredentialFieldMap<infer TConfig>\n ? TConfig\n : CredentialJsonRecord;\n\nexport interface DefineCredentialOptions<\n TPublicSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSecretSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSession,\n> {\n readonly key: string;\n readonly label: string;\n readonly description?: string;\n readonly public: TPublicSource;\n readonly secret: TSecretSource;\n readonly supportedSourceKinds?: CredentialTypeDefinition[\"supportedSourceKinds\"];\n readonly auth?: CredentialTypeDefinition[\"auth\"];\n createSession(\n args: CredentialSessionFactoryArgs<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>>,\n ): MaybePromise<TSession>;\n test(\n args: CredentialSessionFactoryArgs<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>>,\n ): MaybePromise<CredentialHealth>;\n}\n\nexport class CredentialFieldSchemaFactory {\n static create<TConfig extends CredentialJsonRecord>(\n source: CredentialFieldMap<TConfig> | ZodObjectSchema<TConfig>,\n ): ReadonlyArray<CredentialFieldSchema> {\n if (source instanceof z.ZodObject) {\n return this.createFromZodObject(source);\n }\n return this.createFromMap(source as CredentialFieldMap<TConfig>);\n }\n\n private static createFromMap<TConfig extends CredentialJsonRecord>(\n source: CredentialFieldMap<TConfig>,\n ): ReadonlyArray<CredentialFieldSchema> {\n return Object.entries(source).map(([key, input], index) => {\n if (typeof input === \"string\") {\n return {\n key,\n label: this.humanize(key),\n order: index,\n type: input as CredentialFieldSchema[\"type\"],\n };\n }\n return {\n key,\n order: index,\n ...(input as Readonly<Omit<CredentialFieldSchema, \"key\">>),\n };\n });\n }\n\n private static createFromZodObject<_TConfig extends CredentialJsonRecord>(\n source: z.ZodObject,\n ): ReadonlyArray<CredentialFieldSchema> {\n const shape = source.shape;\n return Object.entries(shape).map(([key, schema], index) => {\n const resolved = this.unwrap(schema);\n return {\n key,\n label: this.humanize(key),\n order: index,\n required: this.isRequired(schema) ? true : undefined,\n type: this.resolveType(resolved),\n };\n });\n }\n\n private static isRequired(schema: z.ZodTypeAny): boolean {\n return !(schema instanceof z.ZodOptional || schema instanceof z.ZodDefault);\n }\n\n private static unwrap(schema: z.ZodTypeAny): z.ZodTypeAny {\n let current: z.ZodTypeAny = schema;\n while (current instanceof z.ZodOptional || current instanceof z.ZodDefault) {\n current = current.unwrap() as z.ZodTypeAny;\n }\n return current;\n }\n\n private static resolveType(schema: z.ZodTypeAny): CredentialFieldSchema[\"type\"] {\n if (schema instanceof z.ZodBoolean) {\n return \"boolean\";\n }\n if (schema instanceof z.ZodString) {\n return \"string\";\n }\n return \"json\";\n }\n\n private static humanize(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[-_.]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n .replace(/^./, (character) => character.toUpperCase());\n }\n}\n\nexport function defineCredential<\n TPublicSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSecretSource extends CredentialFieldMap<any> | ZodObjectSchema<any>,\n TSession,\n>(\n options: DefineCredentialOptions<TPublicSource, TSecretSource, TSession>,\n): CredentialType<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>, TSession> & {\n readonly key: string;\n} {\n const definition: CredentialTypeDefinition = {\n typeId: options.key,\n displayName: options.label,\n description: options.description,\n publicFields: CredentialFieldSchemaFactory.create(options.public),\n secretFields: CredentialFieldSchemaFactory.create(options.secret),\n supportedSourceKinds: options.supportedSourceKinds ?? [\"db\", \"env\", \"code\"],\n auth: options.auth,\n };\n\n const credentialType: AnyCredentialType = {\n definition,\n async createSession(args) {\n return await options.createSession(\n args as CredentialSessionFactoryArgs<\n InferCredentialConfig<TPublicSource>,\n InferCredentialConfig<TSecretSource>\n >,\n );\n },\n async test(args) {\n return await options.test(\n args as CredentialSessionFactoryArgs<\n InferCredentialConfig<TPublicSource>,\n InferCredentialConfig<TSecretSource>\n >,\n );\n },\n };\n\n return {\n ...credentialType,\n key: options.key,\n } as CredentialType<InferCredentialConfig<TPublicSource>, InferCredentialConfig<TSecretSource>, TSession> & {\n readonly key: string;\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 { NodeConfigBase } from \"../types\";\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 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 { Item, RunnableNodeConfig } from \"../types\";\nimport type { NodeBackedToolConfigOptions, ZodSchemaAny } from \"./AiHost\";\nimport { AgentConfigInspector } from \"./AgentConfigInspectorFactory\";\nimport { NodeBackedToolConfig } from \"./NodeBackedToolConfig\";\n\nclass AgentToolFactoryImpl {\n asTool<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TInputSchema extends ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny,\n >(\n node: TNodeConfig,\n options: Readonly<{ name?: string } & NodeBackedToolConfigOptions<TNodeConfig, TInputSchema, TOutputSchema>>,\n ): NodeBackedToolConfig<TNodeConfig, TInputSchema, TOutputSchema> {\n return new NodeBackedToolConfig(\n options.name ?? node.name ?? \"tool\",\n node,\n this.withDefaultAgentInputMapper(node, options),\n );\n }\n\n private withDefaultAgentInputMapper<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TInputSchema extends ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny,\n >(\n node: TNodeConfig,\n options: Readonly<{ name?: string } & NodeBackedToolConfigOptions<TNodeConfig, TInputSchema, TOutputSchema>>,\n ): Readonly<{ name?: string } & NodeBackedToolConfigOptions<TNodeConfig, TInputSchema, TOutputSchema>> {\n if (options.mapInput || !AgentConfigInspector.isAgentNodeConfig(node)) {\n return options;\n }\n return {\n ...options,\n mapInput: ({ input, item }) => this.mergeAgentToolInputWithCurrentItem(input, item) as never,\n };\n }\n\n private mergeAgentToolInputWithCurrentItem(input: unknown, item: Item): unknown {\n if (!this.isMergeableRecord(input) || !this.isMergeableRecord(item.json)) {\n return input;\n }\n return {\n ...item.json,\n ...input,\n };\n }\n\n private isMergeableRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n }\n}\n\nexport const AgentToolFactory = new AgentToolFactoryImpl();\n","import type {\n AgentMessageBuildArgs,\n AgentMessageConfig,\n AgentMessageDto,\n AgentMessageLine,\n AgentNodeConfig,\n} from \"./AiHost\";\n\nexport class AgentMessageConfigNormalizer {\n static normalize<TInputJson, TOutputJson>(\n config: AgentNodeConfig<TInputJson, TOutputJson>,\n args: AgentMessageBuildArgs<TInputJson>,\n ): ReadonlyArray<AgentMessageDto> {\n const fromMessages = this.normalizeRichMessages(config.messages, args);\n if (fromMessages.length > 0) {\n return fromMessages;\n }\n throw new Error(\n \"AIAgent messages must be a non-empty array, or an object with a non-empty prompt array and/or buildMessages that returns messages.\",\n );\n }\n\n private static normalizeRichMessages<TInputJson>(\n config: AgentMessageConfig<TInputJson>,\n args: AgentMessageBuildArgs<TInputJson>,\n ): ReadonlyArray<AgentMessageDto> {\n if (Array.isArray(config)) {\n return config.map((line) => this.lineToDto(line, args));\n }\n const structured = config as {\n readonly prompt?: ReadonlyArray<AgentMessageLine<TInputJson>>;\n readonly buildMessages?: (a: AgentMessageBuildArgs<TInputJson>) => ReadonlyArray<AgentMessageDto>;\n };\n const messages: AgentMessageDto[] = [];\n for (const line of structured.prompt ?? []) {\n messages.push(this.lineToDto(line, args));\n }\n for (const message of structured.buildMessages?.(args) ?? []) {\n messages.push(message);\n }\n return messages;\n }\n\n private static lineToDto<TInputJson>(\n line: AgentMessageLine<TInputJson>,\n args: AgentMessageBuildArgs<TInputJson>,\n ): AgentMessageDto {\n const content = typeof line.content === \"function\" ? line.content(args) : line.content;\n return { role: line.role, content };\n }\n}\n","import type { TypeToken } from \"../di\";\n\nimport type { CredentialRequirement } from \"../contracts/credentialTypes\";\n\nimport type {\n Item,\n Items,\n JsonValue,\n NodeExecutionContext,\n NodeOutputs,\n RunnableNodeConfig,\n RunnableNodeInputJson,\n} from \"../types\";\n\nimport type { input as ZodInput, output as ZodOutput, ZodType } from \"zod\";\n\nexport interface AgentCanvasPresentation<TIcon extends string = string> {\n readonly label?: string;\n readonly icon?: TIcon;\n}\n\nexport type ZodSchemaAny = ZodType<any, any, any>;\n\nexport interface ToolConfig {\n readonly type: TypeToken<unknown>;\n readonly name: string;\n readonly description?: string;\n readonly presentation?: AgentCanvasPresentation;\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}\n\nexport type ToolExecuteArgs<TConfig extends ToolConfig = ToolConfig, TInput = unknown> = Readonly<{\n config: TConfig;\n input: TInput;\n ctx: NodeExecutionContext<any>;\n item: Item;\n itemIndex: number;\n items: Items;\n}>;\n\nexport interface Tool<\n TConfig extends ToolConfig = ToolConfig,\n TInputSchema extends ZodSchemaAny = ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny = ZodSchemaAny,\n> {\n readonly defaultDescription: string;\n readonly inputSchema: TInputSchema;\n readonly outputSchema: TOutputSchema;\n execute(\n args: ToolExecuteArgs<TConfig, ZodInput<TInputSchema>>,\n ): Promise<ZodOutput<TOutputSchema>> | ZodOutput<TOutputSchema>;\n}\n\nexport type AgentTool<\n TInputSchema extends ZodSchemaAny = ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny = ZodSchemaAny,\n> = Tool<ToolConfig, TInputSchema, TOutputSchema>;\n\nexport type AgentToolExecuteArgs<TInput = unknown> = ToolExecuteArgs<ToolConfig, TInput>;\n\nexport type AgentToolToken = TypeToken<Tool<ToolConfig, ZodSchemaAny, ZodSchemaAny>>;\n\nexport type AgentMessageRole = \"system\" | \"user\" | \"assistant\";\n\nexport type AgentMessageBuildArgs<TInputJson = unknown> = Readonly<{\n item: Item<TInputJson>;\n itemIndex: number;\n items: Items<TInputJson>;\n ctx: NodeExecutionContext<any>;\n}>;\n\nexport interface AgentMessageDto {\n readonly role: AgentMessageRole;\n readonly content: string;\n}\n\nexport type AgentMessageTemplateContent<TInputJson = unknown> =\n | string\n | ((args: AgentMessageBuildArgs<TInputJson>) => string);\n\nexport interface AgentMessageTemplate<TInputJson = unknown> {\n readonly role: AgentMessageRole;\n readonly content: AgentMessageTemplateContent<TInputJson>;\n}\n\n/** A single prompt line: fixed DTO or template with optional function `content`. */\nexport type AgentMessageLine<TInputJson = unknown> = AgentMessageDto | AgentMessageTemplate<TInputJson>;\n\n/**\n * Message list for an agent. Prefer a **plain array** of `{ role, content }` (optionally with function `content` for templates).\n * Use the object form only when you need `buildMessages` to append messages after optional `prompt` lines.\n */\nexport type AgentMessageConfig<TInputJson = unknown> =\n | ReadonlyArray<AgentMessageLine<TInputJson>>\n | {\n readonly prompt?: ReadonlyArray<AgentMessageLine<TInputJson>>;\n readonly buildMessages?: (args: AgentMessageBuildArgs<TInputJson>) => ReadonlyArray<AgentMessageDto>;\n };\n\nexport type AgentTurnLimitBehavior = \"error\" | \"respondWithLastMessage\";\n\nexport interface AgentModelInvocationOptions {\n readonly maxTokens?: number;\n readonly providerOptions?: Readonly<Record<string, JsonValue>>;\n}\n\nexport interface AgentGuardrailConfig {\n readonly maxTurns?: number;\n readonly onTurnLimitReached?: AgentTurnLimitBehavior;\n readonly modelInvocationOptions?: AgentModelInvocationOptions;\n}\n\n/** Defaults aligned with common tool-agent iteration limits (many products use ~10 max rounds). */\nexport const AgentGuardrailDefaults = {\n maxTurns: 10,\n onTurnLimitReached: \"error\" as AgentTurnLimitBehavior,\n} as const;\n\nexport interface AgentToolDefinition {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: ZodSchemaAny;\n}\n\nexport type AgentToolCall = Readonly<{ id?: string; name: string; input: unknown }>;\n\nexport type AgentToolCallPlanner<_TNodeConfig = unknown> = (\n item: Item,\n index: number,\n items: Items,\n ctx: NodeExecutionContext<any>,\n) => ReadonlyArray<AgentToolCall>;\n\nexport interface ChatModelConfig {\n readonly type: TypeToken<ChatModelFactory<ChatModelConfig>>;\n readonly name: string;\n readonly presentation?: AgentCanvasPresentation;\n getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}\n\nexport interface LangChainChatModelLike {\n invoke(input: unknown, options?: unknown): Promise<unknown>;\n bindTools?(tools: ReadonlyArray<unknown>): LangChainChatModelLike;\n}\n\nexport interface ChatModelFactory<TConfig extends ChatModelConfig = ChatModelConfig> {\n create(\n args: Readonly<{ config: TConfig; ctx: NodeExecutionContext<any> }>,\n ): Promise<LangChainChatModelLike> | LangChainChatModelLike;\n}\n\nexport type NodeBackedToolInputMapperArgs<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TToolInput = unknown,\n> = Readonly<{\n input: TToolInput;\n item: Item;\n itemIndex: number;\n items: Items;\n ctx: NodeExecutionContext<any>;\n node: TNodeConfig;\n}>;\n\nexport type NodeBackedToolOutputMapperArgs<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TToolInput = unknown,\n> = Readonly<{\n input: TToolInput;\n item: Item;\n itemIndex: number;\n items: Items;\n ctx: NodeExecutionContext<any>;\n node: TNodeConfig;\n outputs: NodeOutputs;\n}>;\n\nexport type NodeBackedToolInputMapper<TNodeConfig extends RunnableNodeConfig<any, any>, TToolInput = unknown> = (\n args: NodeBackedToolInputMapperArgs<TNodeConfig, TToolInput>,\n) => Item<RunnableNodeInputJson<TNodeConfig>> | RunnableNodeInputJson<TNodeConfig>;\n\nexport type NodeBackedToolOutputMapper<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TToolInput = unknown,\n TToolOutput = unknown,\n> = (args: NodeBackedToolOutputMapperArgs<TNodeConfig, TToolInput>) => TToolOutput;\n\nexport type NodeBackedToolConfigOptions<\n TNodeConfig extends RunnableNodeConfig<any, any>,\n TInputSchema extends ZodSchemaAny,\n TOutputSchema extends ZodSchemaAny,\n> = Readonly<{\n description?: string;\n presentation?: AgentCanvasPresentation;\n inputSchema: TInputSchema;\n outputSchema: TOutputSchema;\n mapInput?: NodeBackedToolInputMapper<TNodeConfig, ZodInput<TInputSchema>>;\n mapOutput?: NodeBackedToolOutputMapper<TNodeConfig, ZodInput<TInputSchema>, ZodOutput<TOutputSchema>>;\n}>;\n\nexport interface AgentNodeConfig<TInputJson = unknown, TOutputJson = unknown> extends RunnableNodeConfig<\n TInputJson,\n TOutputJson\n> {\n readonly messages: AgentMessageConfig<TInputJson>;\n readonly chatModel: ChatModelConfig;\n readonly tools?: ReadonlyArray<ToolConfig>;\n readonly guardrails?: AgentGuardrailConfig;\n}\n\nexport type AgentAttachmentRole = \"languageModel\" | \"tool\" | \"nestedAgent\";\n\nexport { NodeBackedToolConfig } from \"./NodeBackedToolConfig\";\nexport { AgentToolFactory } from \"./AgentToolFactory\";\nexport { AgentMessageConfigNormalizer } from \"./AgentMessageConfigNormalizerFactory\";\nexport { AgentConfigInspector } from \"./AgentConfigInspectorFactory\";\n","import type { CredentialRequirement } from \"../contracts/credentialTypes\";\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\ntype AgentConnectionNodeCollectorApi = Readonly<{\n collect(parentNodeId: NodeId, agentConfig: AgentNodeConfig<any, any>): ReadonlyArray<AgentConnectionNodeDescriptor>;\n}>;\n\nexport const AgentConnectionNodeCollector: AgentConnectionNodeCollectorApi = new (class {\n collect(parentNodeId: NodeId, agentConfig: AgentNodeConfig<any, any>): ReadonlyArray<AgentConnectionNodeDescriptor> {\n const collected: AgentConnectionNodeDescriptor[] = [];\n this.collectInto(parentNodeId, agentConfig, collected);\n return collected;\n }\n\n private collectInto(\n parentNodeId: NodeId,\n agentConfig: AgentNodeConfig<any, any>,\n collected: AgentConnectionNodeDescriptor[],\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);\n }\n }\n\n private collectNestedAgentTools(\n toolNodeId: NodeId,\n tool: ToolConfig,\n collected: AgentConnectionNodeDescriptor[],\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);\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 { randomUUID } from \"node:crypto\";\n\nimport type { NodeId } from \"../../types\";\n\n/**\n * Unique ids for persisted connection invocation history rows (LLM/tool calls under an owning node).\n */\nexport class ConnectionInvocationIdFactory {\n static create(): string {\n return `cinv_${randomUUID()}`;\n }\n\n /** Deterministic id for tests when a stable sequence is needed. */\n static createForTest(runId: string, connectionNodeId: NodeId, sequence: number): string {\n return `cinv_${runId}_${connectionNodeId}_${sequence}`;\n }\n}\n","import type { InputPortKey, NodeId, OutputPortKey, WorkflowDefinition, WorkflowGraph } from \"../../types\";\n\nexport class ExecutableGraph implements WorkflowGraph {\n private readonly outgoingByNodeAndPort = new Map<\n NodeId,\n Map<OutputPortKey, Array<Readonly<{ nodeId: NodeId; input: InputPortKey }>>>\n >();\n\n constructor(def: WorkflowDefinition) {\n for (const e of def.edges) {\n const byPort =\n this.outgoingByNodeAndPort.get(e.from.nodeId) ??\n new Map<OutputPortKey, Array<Readonly<{ nodeId: NodeId; input: InputPortKey }>>>();\n const next = byPort.get(e.from.output) ?? [];\n next.push({ nodeId: e.to.nodeId, input: e.to.input });\n byPort.set(e.from.output, next);\n this.outgoingByNodeAndPort.set(e.from.nodeId, byPort);\n }\n }\n\n next(nodeId: NodeId, output: OutputPortKey): Array<Readonly<{ nodeId: NodeId; input: InputPortKey }>> {\n return this.outgoingByNodeAndPort.get(nodeId)?.get(output) ?? [];\n }\n}\n","import type { WorkflowDefinition, WorkflowGraph, WorkflowGraphFactory } from \"../../types\";\nimport { ExecutableGraph } from \"./ExecutableGraph\";\n\nexport class DefaultWorkflowGraphFactory implements WorkflowGraphFactory {\n create(def: WorkflowDefinition): WorkflowGraph {\n return new ExecutableGraph(def);\n }\n}\n","import type {\n PersistedRunSchedulingState,\n PersistedRunState,\n RunId,\n RunPruneCandidate,\n RunSummary,\n WorkflowExecutionListingRepository,\n WorkflowExecutionPruneRepository,\n WorkflowExecutionRepository,\n WorkflowId,\n} from \"../types\";\nimport type { RunEventBus } from \"./runEvents\";\n\nexport class EventPublishingWorkflowExecutionRepository\n implements WorkflowExecutionRepository, WorkflowExecutionListingRepository, WorkflowExecutionPruneRepository\n{\n constructor(\n private readonly inner: WorkflowExecutionRepository,\n private readonly eventBus: RunEventBus,\n private readonly now: () => Date = () => new Date(),\n ) {}\n\n async createRun(args: Parameters<WorkflowExecutionRepository[\"createRun\"]>[0]): Promise<void> {\n await this.inner.createRun(args);\n await this.eventBus.publish({\n kind: \"runCreated\",\n runId: args.runId,\n workflowId: args.workflowId,\n parent: args.parent,\n at: this.now().toISOString(),\n });\n }\n\n async load(runId: RunId): Promise<PersistedRunState | undefined> {\n return await this.inner.load(runId);\n }\n\n async loadSchedulingState(runId: RunId): Promise<PersistedRunSchedulingState | undefined> {\n return await this.inner.loadSchedulingState(runId);\n }\n\n async save(state: PersistedRunState): Promise<void> {\n await this.inner.save(state);\n await this.eventBus.publish({\n kind: \"runSaved\",\n runId: state.runId,\n workflowId: state.workflowId,\n parent: state.parent,\n at: this.now().toISOString(),\n state,\n });\n }\n\n async deleteRun(runId: RunId): Promise<void> {\n if (!this.inner.deleteRun) return;\n await this.inner.deleteRun(runId);\n }\n\n async listRuns(args?: Readonly<{ workflowId?: WorkflowId; limit?: number }>): Promise<ReadonlyArray<RunSummary>> {\n const listingRepository = this.inner as unknown as Partial<WorkflowExecutionListingRepository>;\n if (!listingRepository.listRuns) return [];\n return await listingRepository.listRuns(args);\n }\n\n async listRunsOlderThan(\n args: Readonly<{ beforeIso: string; limit?: number }>,\n ): Promise<ReadonlyArray<RunPruneCandidate>> {\n const pruneRepository = this.inner as unknown as Partial<WorkflowExecutionPruneRepository>;\n if (!pruneRepository.listRunsOlderThan) return [];\n return await pruneRepository.listRunsOlderThan(args);\n }\n}\n","import type { Item, Items } from \"../contracts/workflowTypes\";\nimport { injectable } from \"../di\";\n\n/**\n * Normalizes external inputs into the engine's canonical `Items` shape.\n * Used at host and builder boundaries where callers may provide either a raw value,\n * a single item-like object, or an array of item-like values.\n */\n@injectable()\nexport class ItemsInputNormalizer {\n normalize(raw: unknown): Items {\n if (raw === undefined || raw === null) {\n return [];\n }\n if (Array.isArray(raw)) {\n return raw.map((value) => this.normalizeItem(value));\n }\n return [this.normalizeItem(raw)];\n }\n\n private normalizeItem(raw: unknown): Item {\n if (!this.isItem(raw)) {\n return { json: raw };\n }\n return {\n json: raw.json,\n ...(raw.binary === undefined ? {} : { binary: raw.binary }),\n ...(raw.meta === undefined ? {} : { meta: raw.meta }),\n ...(raw.paired === undefined ? {} : { paired: raw.paired }),\n };\n }\n\n private isItem(raw: unknown): raw is Item {\n return typeof raw === \"object\" && raw !== null && Object.prototype.hasOwnProperty.call(raw, \"json\");\n }\n}\n","import type { NoneRetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport class NoRetryPolicy implements NoneRetryPolicySpec {\n readonly kind = \"none\" as const;\n}\n","import type { FixedRetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport class RetryPolicy implements FixedRetryPolicySpec {\n readonly kind = \"fixed\" as const;\n\n constructor(\n public readonly maxAttempts: number,\n public readonly delayMs: number,\n ) {\n if (!Number.isFinite(maxAttempts) || maxAttempts < 1 || !Number.isInteger(maxAttempts)) {\n throw new Error(`RetryPolicy.maxAttempts must be a positive integer, got ${maxAttempts}`);\n }\n if (!Number.isFinite(delayMs) || delayMs < 0) {\n throw new Error(`RetryPolicy.delayMs must be a non-negative finite number, got ${delayMs}`);\n }\n }\n\n /** Default for HTTP-style transient failures: 3 tries, 1s between attempts. */\n static readonly defaultForHttp: FixedRetryPolicySpec = { kind: \"fixed\", maxAttempts: 3, delayMs: 1000 };\n\n /** Default for LLM / agent calls: 3 tries, 2s fixed backoff. */\n static readonly defaultForAiAgent: FixedRetryPolicySpec = { kind: \"fixed\", maxAttempts: 3, delayMs: 2000 };\n}\n","import type { ExponentialRetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport class ExpRetryPolicy implements ExponentialRetryPolicySpec {\n readonly kind = \"exponential\" as const;\n\n constructor(\n public readonly maxAttempts: number,\n public readonly initialDelayMs: number,\n public readonly multiplier: number,\n public readonly maxDelayMs?: number,\n public readonly jitter?: boolean,\n ) {\n if (!Number.isFinite(maxAttempts) || maxAttempts < 1 || !Number.isInteger(maxAttempts)) {\n throw new Error(`ExpRetryPolicy.maxAttempts must be a positive integer, got ${maxAttempts}`);\n }\n if (!Number.isFinite(initialDelayMs) || initialDelayMs < 0) {\n throw new Error(`ExpRetryPolicy.initialDelayMs must be a non-negative finite number, got ${initialDelayMs}`);\n }\n if (!Number.isFinite(multiplier) || multiplier < 1) {\n throw new Error(`ExpRetryPolicy.multiplier must be >= 1, got ${multiplier}`);\n }\n }\n}\n","import type { NodeId, WorkflowId } from \"./workflowTypes\";\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 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 CredentialOAuth2AuthDefinition = Readonly<\n | {\n kind: \"oauth2\";\n providerId: string;\n scopes: ReadonlyArray<string>;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n | {\n kind: \"oauth2\";\n providerFromPublicConfig: OAuth2ProviderFromPublicConfig;\n scopes: ReadonlyArray<string>;\n clientIdFieldKey?: string;\n clientSecretFieldKey?: string;\n }\n>;\n\nexport type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;\n\nexport type CredentialTypeDefinition = Readonly<{\n typeId: CredentialTypeId;\n displayName: string;\n description?: string;\n publicFields?: ReadonlyArray<CredentialFieldSchema>;\n secretFields?: ReadonlyArray<CredentialFieldSchema>;\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 { TypeToken } from \"../di\";\nimport type { CredentialRequirement } from \"./credentialTypes\";\nimport type { RetryPolicySpec } from \"./retryPolicySpec.types\";\n\nexport type WorkflowId = string;\nexport type NodeId = string;\nexport type OutputPortKey = string;\nexport type InputPortKey = string;\nexport type PersistedTokenId = string;\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\nexport interface Edge {\n from: { nodeId: NodeId; output: OutputPortKey };\n to: { nodeId: NodeId; input: InputPortKey };\n}\n\nexport type NodeConnectionName = string;\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 getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;\n}\n\nexport declare const runnableNodeInputType: unique symbol;\nexport declare const runnableNodeOutputType: unique symbol;\nexport declare const triggerNodeOutputType: unique symbol;\n\nexport interface RunnableNodeConfig<TInputJson = unknown, TOutputJson = unknown> extends NodeConfigBase {\n readonly kind: \"node\";\n readonly [runnableNodeInputType]?: TInputJson;\n readonly [runnableNodeOutputType]?: TOutputJson;\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\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 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\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\nexport interface RunDataSnapshot {\n getOutputs(nodeId: NodeId): NodeOutputs | undefined;\n getOutputItems(nodeId: NodeId, output?: OutputPortKey): Items;\n getOutputItem(nodeId: NodeId, itemIndex: number, output?: OutputPortKey): Item | 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}\n\nexport interface PersistedRunPolicySnapshot {\n readonly retentionSeconds?: number;\n readonly binaryRetentionSeconds?: 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 storagePolicy?: WorkflowStoragePolicyMode;\n}\n"],"mappings":"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"}
|