@codemation/core-nodes 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/index.cjs +34 -433
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +95 -1312
  5. package/dist/index.d.ts +95 -1312
  6. package/dist/index.js +35 -435
  7. package/dist/index.js.map +1 -1
  8. package/dist/metadata.json +1 -1
  9. package/package.json +2 -2
  10. package/src/authoring/defineRestNode.types.ts +0 -84
  11. package/src/canvasIconName.ts +0 -7
  12. package/src/chatModels/CodemationChatModelConfig.ts +0 -10
  13. package/src/chatModels/CodemationChatModelFactory.ts +0 -7
  14. package/src/chatModels/ManagedHmacSignerFactory.types.ts +0 -35
  15. package/src/chatModels/OpenAIChatModelFactory.ts +0 -2
  16. package/src/chatModels/OpenAiChatModelPresetsFactory.ts +0 -5
  17. package/src/chatModels/OpenAiCredentialSession.ts +0 -1
  18. package/src/chatModels/OpenAiStrictJsonSchemaFactory.ts +0 -21
  19. package/src/credentials/ApiKeyCredentialType.ts +0 -3
  20. package/src/credentials/BasicAuthCredentialType.ts +0 -4
  21. package/src/credentials/BearerTokenCredentialType.ts +0 -4
  22. package/src/credentials/OAuth2ClientCredentialsTypeFactory.ts +0 -19
  23. package/src/credentials/OAuth2TokenExchangeFactory.ts +0 -7
  24. package/src/http/HttpBodyBuilder.ts +0 -16
  25. package/src/http/HttpRequestExecutor.ts +0 -35
  26. package/src/http/HttpUrlBuilder.ts +0 -4
  27. package/src/http/SSRFBlockedError.ts +0 -4
  28. package/src/http/SsrfGuard.ts +10 -50
  29. package/src/http/httpRequest.types.ts +0 -49
  30. package/src/index.ts +1 -0
  31. package/src/nodes/AIAgentConfig.ts +0 -44
  32. package/src/nodes/AIAgentExecutionHelpersFactory.ts +0 -37
  33. package/src/nodes/AIAgentNode.ts +0 -132
  34. package/src/nodes/AgentBinaryContentFactory.ts +0 -12
  35. package/src/nodes/AgentLoopCheckpoint.types.ts +0 -13
  36. package/src/nodes/AgentMessageFactory.ts +0 -18
  37. package/src/nodes/AgentStructuredOutputRunner.ts +0 -17
  38. package/src/nodes/AgentToolExecutionCoordinator.ts +0 -12
  39. package/src/nodes/AgentToolResultContentFactory.ts +0 -29
  40. package/src/nodes/AssertionNode.ts +0 -14
  41. package/src/nodes/BM25Index.ts +0 -14
  42. package/src/nodes/ConnectionCredentialExecutionContextFactory.ts +0 -5
  43. package/src/nodes/ConnectionCredentialNode.ts +0 -4
  44. package/src/nodes/CronTriggerFactory.ts +0 -9
  45. package/src/nodes/DeferredMetaToolStrategy.ts +0 -18
  46. package/src/nodes/DeferredMetaToolStrategyFactory.ts +0 -5
  47. package/src/nodes/HttpRequestNodeFactory.ts +0 -14
  48. package/src/nodes/InboxApprovalNode.types.ts +0 -16
  49. package/src/nodes/IsTestRunNode.ts +0 -8
  50. package/src/nodes/ManualTriggerFactory.ts +0 -3
  51. package/src/nodes/ManualTriggerNode.ts +0 -4
  52. package/src/nodes/MergeNode.ts +0 -1
  53. package/src/nodes/NodeBackedToolRuntime.ts +0 -14
  54. package/src/nodes/SubWorkflowNode.ts +0 -3
  55. package/src/nodes/SwitchNode.ts +0 -3
  56. package/src/nodes/TestTriggerNode.ts +0 -9
  57. package/src/nodes/aiAgentSupport.types.ts +0 -16
  58. package/src/nodes/assertion.ts +0 -10
  59. package/src/nodes/codemationDocumentScannerNode.ts +0 -18
  60. package/src/nodes/collections/collectionListNode.types.ts +0 -1
  61. package/src/nodes/httpRequest.ts +0 -68
  62. package/src/nodes/isTestRun.ts +0 -4
  63. package/src/nodes/mapData.ts +0 -1
  64. package/src/nodes/merge.ts +0 -4
  65. package/src/nodes/mergeExecutionUtils.types.ts +0 -3
  66. package/src/nodes/nodeOptions.types.ts +0 -8
  67. package/src/nodes/schedulePollingTrigger.ts +37 -0
  68. package/src/nodes/split.ts +0 -4
  69. package/src/nodes/testTrigger.ts +0 -21
  70. package/src/nodes/wait.ts +0 -1
  71. package/src/nodes/webhookTriggerNode.ts +0 -5
  72. package/src/register.types.ts +0 -10
  73. package/src/workflows/AIAgentConnectionWorkflowExpander.ts +0 -3
package/dist/index.js CHANGED
@@ -1,13 +1,10 @@
1
- import { AgentConfigInspector, AgentConnectionNodeCollector, AgentGuardrailDefaults, AgentMessageConfigNormalizer, CallableToolConfig, ChildExecutionScopeFactory, CodemationTelemetryAttributeNames, CodemationTelemetryMetricNames, ConnectionInvocationIdFactory, ConnectionNodeIdFactory, CoreTokens, DefinedNodeRegistry, GenAiTelemetryAttributeNames, InboxChannelResolverToken, ItemExprResolver, ItemsInputNormalizer, NodeBackedToolConfig, NodeOutputNormalizer, RetryPolicy, RunnableOutputBehaviorResolver, SuspensionRequest, WorkflowBuilder, chatModel, defineCredential, defineHumanApprovalNode, defineNode, emitPorts, getOriginIndexFromItem, inject, injectable, isPortsEmission, node } from "@codemation/core";
1
+ import { AgentConfigInspector, AgentConnectionNodeCollector, AgentGuardrailDefaults, AgentMessageConfigNormalizer, CallableToolConfig, ChildExecutionScopeFactory, CodemationTelemetryAttributeNames, CodemationTelemetryMetricNames, ConnectionInvocationIdFactory, ConnectionNodeIdFactory, CoreTokens, DefinedNodeRegistry, GenAiTelemetryAttributeNames, InboxChannelResolverToken, ItemExprResolver, ItemsInputNormalizer, NodeBackedToolConfig, NodeOutputNormalizer, RetryPolicy, RunnableOutputBehaviorResolver, SuspensionRequest, WorkflowBuilder, chatModel, defineCredential, defineHumanApprovalNode, defineNode, definePollingTrigger, emitPorts, getOriginIndexFromItem, inject, injectable, isPortsEmission, node } from "@codemation/core";
2
2
  import dns from "node:dns/promises";
3
3
  import { CredentialResolverFactory } from "@codemation/core/bootstrap";
4
4
  import { createHash, createHmac, randomBytes } from "node:crypto";
5
5
  import { Cron } from "croner";
6
6
 
7
7
  //#region src/credentials/ApiKeyCredentialType.ts
8
- /**
9
- * API key credential that injects a key either as an HTTP header or a query parameter.
10
- */
11
8
  const apiKeyCredentialType = defineCredential({
12
9
  key: "core-nodes.api-key",
13
10
  label: "API Key",
@@ -55,10 +52,6 @@ const apiKeyCredentialType = defineCredential({
55
52
 
56
53
  //#endregion
57
54
  //#region src/credentials/BasicAuthCredentialType.ts
58
- /**
59
- * HTTP Basic authentication credential.
60
- * Session sets `Authorization: Basic <base64(username:password)>`.
61
- */
62
55
  const basicAuthCredentialType = defineCredential({
63
56
  key: "core-nodes.basic-auth",
64
57
  label: "Basic Auth",
@@ -96,10 +89,6 @@ const basicAuthCredentialType = defineCredential({
96
89
 
97
90
  //#endregion
98
91
  //#region src/credentials/BearerTokenCredentialType.ts
99
- /**
100
- * Simple Bearer token credential.
101
- * Session sets `Authorization: Bearer <token>` on every request.
102
- */
103
92
  const bearerTokenCredentialType = defineCredential({
104
93
  key: "core-nodes.bearer-token",
105
94
  label: "Bearer Token",
@@ -158,24 +147,6 @@ var OAuth2TokenExchangeFactory = class {
158
147
 
159
148
  //#endregion
160
149
  //#region src/credentials/OAuth2ClientCredentialsTypeFactory.ts
161
- /**
162
- * OAuth2 client-credentials flow credential.
163
- *
164
- * This is a machine-to-machine flow: no user redirect occurs. The session
165
- * POSTs to the configured `tokenUrl` with `client_credentials` grant, caches
166
- * the resulting access token for the duration of the session, and injects it
167
- * as `Authorization: Bearer <token>` on each request.
168
- *
169
- * Token caching is per-session only (one createSession call = one token fetch
170
- * at most). Cross-session caching would require host-level state and is out of
171
- * scope here. Because the engine creates a fresh session per execution, a new
172
- * token is fetched once per node activation.
173
- *
174
- * NOTE: `auth` is intentionally omitted from the definition. The OAuth2
175
- * `auth: { kind: "oauth2" }` shape signals an authorization-code / user-redirect
176
- * flow; using it here would cause the host UI to render an OAuth consent button
177
- * that goes nowhere. Client-credentials is a purely server-side flow.
178
- */
179
150
  const oauth2ClientCredentialsType = defineCredential({
180
151
  key: "core-nodes.oauth2-client-credentials",
181
152
  label: "OAuth2 Client Credentials",
@@ -259,10 +230,6 @@ const oauth2ClientCredentialsType = defineCredential({
259
230
 
260
231
  //#endregion
261
232
  //#region src/http/SSRFBlockedError.ts
262
- /**
263
- * Thrown when an HTTP request target resolves to a private, link-local, or
264
- * loopback address and `allowPrivateNetworkTargets` is not set.
265
- */
266
233
  var SSRFBlockedError = class extends Error {
267
234
  resolvedIp;
268
235
  constructor(host, resolvedIp) {
@@ -274,26 +241,7 @@ var SSRFBlockedError = class extends Error {
274
241
 
275
242
  //#endregion
276
243
  //#region src/http/SsrfGuard.ts
277
- /** Emitted once per process when NODE_ENV=production and no allowedOutboundHosts is set. */
278
244
  let _productionNoAllowlistWarned = false;
279
- /**
280
- * Guards HTTP requests against Server-Side Request Forgery (SSRF) by
281
- * DNS-resolving the target host and rejecting private/link-local/loopback
282
- * addresses.
283
- *
284
- * Blocked ranges:
285
- * - RFC-1918: 10/8, 172.16/12, 192.168/16
286
- * - Link-local: 169.254/16
287
- * - Loopback: 127/8, ::1
288
- *
289
- * When `allowedOutboundHosts` is set, every resolved DNS target must match
290
- * at least one entry in the list (exact hostname or `*.example.com` wildcard).
291
- * When unset, existing behaviour applies: private ranges blocked, public allowed.
292
- *
293
- * Call {@link check} before making any outbound HTTP request.
294
- * Pass `allowPrivate: true` to bypass the private-network guard for trusted workflows
295
- * (allowedOutboundHosts allowlist is still applied when set).
296
- */
297
245
  var SsrfGuard = class {
298
246
  constructor(allowedOutboundHosts) {
299
247
  this.allowedOutboundHosts = allowedOutboundHosts;
@@ -302,15 +250,6 @@ var SsrfGuard = class {
302
250
  console.warn("[SsrfGuard] WARNING: NODE_ENV=production but no allowedOutboundHosts is configured for HttpRequest. All public destinations are permitted. Set allowedOutboundHosts to restrict outbound traffic.");
303
251
  }
304
252
  }
305
- /**
306
- * Resolves the host of `url` via DNS and throws {@link SSRFBlockedError}
307
- * if any resolved address falls in a blocked range, or if the host does not
308
- * match the operator-configured allowlist (when set).
309
- *
310
- * @param url - Fully-qualified URL of the intended request target.
311
- * @param allowPrivate - When `true`, the private-network check is skipped.
312
- * The allowedOutboundHosts check is still applied when set.
313
- */
314
253
  async check(url, allowPrivate) {
315
254
  if (allowPrivate && !this.allowedOutboundHosts?.length) return;
316
255
  let host;
@@ -334,10 +273,6 @@ var SsrfGuard = class {
334
273
  }
335
274
  for (const { address } of addresses) if (this.isPrivateAddress(address)) throw new SSRFBlockedError(host, address);
336
275
  }
337
- /**
338
- * Returns true when `host` matches at least one entry in `allowedOutboundHosts`.
339
- * Supports exact hostnames (`api.example.com`) and wildcard prefixes (`*.example.com`).
340
- */
341
276
  isHostAllowed(host) {
342
277
  for (const allowed of this.allowedOutboundHosts ?? []) if (allowed.startsWith("*.")) {
343
278
  const suffix = allowed.slice(1);
@@ -371,21 +306,6 @@ var SsrfGuard = class {
371
306
 
372
307
  //#endregion
373
308
  //#region src/http/HttpRequestExecutor.ts
374
- /**
375
- * Executes a single HTTP request described by {@link HttpRequestSpec}.
376
- *
377
- * - Credential sessions provide header/query deltas via `applyToRequest`.
378
- * - Body encoding is delegated to {@link HttpBodyBuilder}.
379
- * - URL query merging is delegated to {@link HttpUrlBuilder}.
380
- * - SSRF protection is delegated to {@link SsrfGuard} (injected).
381
- * - Binary response bodies: when `download.mode` triggers binary attach, the
382
- * `bodyBinaryName` field is set in the result but the body is NOT read here.
383
- * Callers that need binary attachment should use `buildRequest` to get the
384
- * resolved URL + init and make the fetch + binary attach themselves.
385
- *
386
- * Collaborators (`fetch`, body builder, url builder, ssrfGuard) are injected so
387
- * callers own construction at composition roots and tests can supply deterministic stubs.
388
- */
389
309
  var HttpRequestExecutor = class {
390
310
  constructor(fetchFn, bodyBuilder, urlBuilder, ssrfGuard) {
391
311
  this.fetchFn = fetchFn;
@@ -393,14 +313,6 @@ var HttpRequestExecutor = class {
393
313
  this.urlBuilder = urlBuilder;
394
314
  this.ssrfGuard = ssrfGuard;
395
315
  }
396
- /**
397
- * Builds the fetch init (headers, query, body) from the spec + credential delta,
398
- * returning both the resolved URL and the RequestInit so callers can make the
399
- * actual fetch call themselves (useful for streaming / binary attach).
400
- *
401
- * Also performs SSRF protection via the injected {@link SsrfGuard} before
402
- * returning — throws {@link SSRFBlockedError} if the target is a private address.
403
- */
404
316
  async buildRequest(spec, item) {
405
317
  await this.ssrfGuard.check(spec.url, spec.allowPrivateNetworkTargets ?? false);
406
318
  const credentialDelta = spec.credential?.applyToRequest(spec) ?? {};
@@ -424,12 +336,6 @@ var HttpRequestExecutor = class {
424
336
  }
425
337
  };
426
338
  }
427
- /**
428
- * Executes an HTTP request and returns parsed result.
429
- * For binary downloads (when `shouldAttachBody` is true), the body is NOT consumed
430
- * and callers must call `ctx.binary.attach` directly using the resolved URL + init
431
- * (available via `buildRequest`).
432
- */
433
339
  async execute(spec, item) {
434
340
  const { url: resolvedUrl, init } = await this.buildRequest(spec, item);
435
341
  const response = await this.fetchFn(resolvedUrl, init);
@@ -486,10 +392,6 @@ var HttpRequestExecutor = class {
486
392
 
487
393
  //#endregion
488
394
  //#region src/http/HttpBodyBuilder.ts
489
- /**
490
- * Builds a fetch-compatible `BodyInit` + Content-Type pair from an {@link HttpBodySpec}.
491
- * Multipart binaries are read from `item.binary` via `ctx.binary.openReadStream`.
492
- */
493
395
  var HttpBodyBuilder = class {
494
396
  async build(spec, item, ctx) {
495
397
  if (!spec || spec.kind === "none") return;
@@ -560,10 +462,6 @@ var HttpBodyBuilder = class {
560
462
 
561
463
  //#endregion
562
464
  //#region src/http/HttpUrlBuilder.ts
563
- /**
564
- * Merges query parameters into a base URL.
565
- * Handles both scalar and array values, and preserves any existing params.
566
- */
567
465
  var HttpUrlBuilder = class {
568
466
  build(baseUrl, query) {
569
467
  if (!query || Object.keys(query).length === 0) return baseUrl;
@@ -576,39 +474,12 @@ var HttpUrlBuilder = class {
576
474
 
577
475
  //#endregion
578
476
  //#region src/authoring/defineRestNode.types.ts
579
- /**
580
- * Substitutes `{name}` placeholders in a path template using values from `params`.
581
- */
582
477
  function substitutePath(template, params) {
583
478
  return template.replace(/\{([^}]+)}/g, (_match, key) => {
584
479
  const value = params[key];
585
480
  return value !== void 0 ? String(value) : `{${key}}`;
586
481
  });
587
482
  }
588
- /**
589
- * Declarative helper for creating thin API-wrapper nodes.
590
- *
591
- * Usage:
592
- * ```ts
593
- * export const postMessage = defineRestNode({
594
- * key: "slack.post-message",
595
- * title: "Send Slack message",
596
- * icon: "si:slack",
597
- * api: { baseUrl: "https://slack.com/api", path: "/chat.postMessage", method: "POST" },
598
- * credentials: { auth: bearerTokenCredentialType },
599
- * inputSchema: z.object({ channel: z.string(), text: z.string() }),
600
- * request: ({ input }) => ({
601
- * body: { kind: "json", data: { channel: input.channel, text: input.text } },
602
- * }),
603
- * response: ({ json }) => ({ messageTs: (json as any).ts }),
604
- * });
605
- * ```
606
- *
607
- * - `defineRestNode` is a thin wrapper over `defineNode`; it does not introduce a new runtime kind.
608
- * - Credential sessions are resolved via the `credentials` binding map (same as `defineNode`).
609
- * - Path `{placeholder}` substitution is applied from `input` keys before the request is made.
610
- * - Non-2xx responses throw an `Error` by default (`errorPolicy: "throw"`).
611
- */
612
483
  function defineRestNode(options) {
613
484
  const errorPolicy = options.errorPolicy ?? "throw";
614
485
  return defineNode({
@@ -4146,11 +4017,6 @@ function toJSONSchema(input, params) {
4146
4017
 
4147
4018
  //#endregion
4148
4019
  //#region src/nodes/ConnectionCredentialExecutionContextFactory.ts
4149
- /**
4150
- * Builds a {@link NodeExecutionContext} whose identity for credential binding and `getCredential`
4151
- * is a **connection-owned** workflow node id (`ConnectionNodeIdFactory` in `@codemation/core`),
4152
- * not the executing parent node. Use for LLM slots, tool slots, or any connection-scoped owner.
4153
- */
4154
4020
  var ConnectionCredentialExecutionContextFactory = class {
4155
4021
  credentialResolverFactory;
4156
4022
  constructor(credentialSessions) {
@@ -4173,15 +4039,6 @@ let AIAgentExecutionHelpersFactory = class AIAgentExecutionHelpersFactory$1 {
4173
4039
  createConnectionCredentialExecutionContextFactory(credentialSessions) {
4174
4040
  return new ConnectionCredentialExecutionContextFactory(credentialSessions);
4175
4041
  }
4176
- /**
4177
- * Produces a plain JSON Schema object (`draft-07`) from a Zod schema, as needed by
4178
- * OpenAI tool-parameter schemas and the structured-output repair prompt.
4179
- * - Prefers the schema's **instance** `toJSONSchema(...)` method so we stay inside the Zod
4180
- * instance that created the schema (works across consumer/framework tsx namespaces — see
4181
- * {@link ZodInstanceToJsonSchema}). Falls back to the framework-imported module function.
4182
- * - Strips root `$schema` (OpenAI ignores it).
4183
- * - Sanitizes `required` for cfworker json-schema compatibility (must be a string array or absent).
4184
- */
4185
4042
  createJsonSchemaRecord(inputSchema, options) {
4186
4043
  const { $schema: _draftSchemaOmitted,...rest } = this.convertZodSchemaToJsonSchema(inputSchema, { target: "draft-07" });
4187
4044
  if (options.requireObjectRoot && rest.type !== "object") throw new Error(`Cannot create tool "${options.schemaName}": tool input schema must be a JSON Schema object type (got type=${String(rest.type)}).`);
@@ -4190,20 +4047,11 @@ let AIAgentExecutionHelpersFactory = class AIAgentExecutionHelpersFactory$1 {
4190
4047
  this.sanitizeJsonSchemaRequiredKeywordsForCfworker(rest);
4191
4048
  return rest;
4192
4049
  }
4193
- /**
4194
- * Runs Zod's `toJSONSchema` via the schema's own instance method when available, so consumer
4195
- * schemas loaded under a different tsx namespace still convert correctly. If the caller handed us
4196
- * a payload that lacks that method (e.g. a plain JSON Schema record or a Zod instance whose
4197
- * prototype was stripped), we fall back to the framework-bundled module function.
4198
- */
4199
4050
  convertZodSchemaToJsonSchema(inputSchema, params) {
4200
4051
  const candidate = inputSchema.toJSONSchema;
4201
4052
  if (typeof candidate === "function") return candidate.call(inputSchema, params);
4202
4053
  return toJSONSchema(inputSchema, params);
4203
4054
  }
4204
- /**
4205
- * `@cfworker/json-schema` iterates `schema.required` with `for...of`; it must be a string array or absent.
4206
- */
4207
4055
  sanitizeJsonSchemaRequiredKeywordsForCfworker(node$1) {
4208
4056
  if (!node$1 || typeof node$1 !== "object" || Array.isArray(node$1)) return;
4209
4057
  const o = node$1;
@@ -4350,11 +4198,6 @@ var OpenAIChatModelConfig = class {
4350
4198
 
4351
4199
  //#endregion
4352
4200
  //#region src/chatModels/OpenAiChatModelPresetsFactory.ts
4353
- /**
4354
- * Default OpenAI chat model configs for scaffolds and demos (icon + label match {@link OpenAIChatModelConfig} defaults).
4355
- * Prefer importing {@link openAiChatModelPresets} from here or from the consumer template re-export
4356
- * instead of repeating {@link OpenAIChatModelConfig} construction in app workflows.
4357
- */
4358
4201
  var OpenAiChatModelPresets = class {
4359
4202
  demoGpt4oMini = new OpenAIChatModelConfig("OpenAI", "gpt-4o-mini");
4360
4203
  demoGpt41 = new OpenAIChatModelConfig("OpenAI", "gpt-4.1");
@@ -4363,19 +4206,6 @@ const openAiChatModelPresets = new OpenAiChatModelPresets();
4363
4206
 
4364
4207
  //#endregion
4365
4208
  //#region src/chatModels/ManagedHmacSignerFactory.types.ts
4366
- /**
4367
- * Creates an HMAC-signing fetch wrapper that authenticates requests to
4368
- * Codemation managed services (LLM broker, doc-scanner) with the
4369
- * Codemation-Hmac v=1 scheme.
4370
- *
4371
- * Mirrors HmacRequestSigner from @codemation/host/pairing without importing
4372
- * that package (which would create a circular dependency since @codemation/host
4373
- * depends on @codemation/core-nodes).
4374
- *
4375
- * @param workspaceId - Workspace identifier injected by the CP provisioner.
4376
- * @param pairingSecret - Base64-encoded 32-byte HMAC key injected by the provisioner.
4377
- * @param options - Optional behaviour flags and test seams.
4378
- */
4379
4209
  function managedHmacFetchFactory(workspaceId, pairingSecret, options) {
4380
4210
  const signBody = options?.signBody ?? true;
4381
4211
  return async (input, init) => {
@@ -4394,10 +4224,6 @@ function managedHmacFetchFactory(workspaceId, pairingSecret, options) {
4394
4224
  });
4395
4225
  };
4396
4226
  }
4397
- /**
4398
- * Produces a Codemation-Hmac v=1 Authorization header value.
4399
- * Algorithm must match HmacVerifier.computeSignature() in the control-plane.
4400
- */
4401
4227
  function buildHmacAuthHeader(workspaceId, pairingSecret, method, url, body, overrides) {
4402
4228
  const ts = overrides?.now ? overrides.now() : Math.floor(Date.now() / 1e3);
4403
4229
  const nonce = overrides?.nonce ? overrides.nonce() : randomBytes(16).toString("base64");
@@ -4460,12 +4286,7 @@ var CodemationChatModelConfig = class {
4460
4286
 
4461
4287
  //#endregion
4462
4288
  //#region src/nodes/AgentToolResultContentFactory.ts
4463
- /**
4464
- * Cap on raw (pre-base64) bytes inlined from a single tool result. Base64 inflates ~33% and every
4465
- * inlined byte eats model context, so oversize binaries are replaced with a text placeholder.
4466
- */
4467
4289
  const MAX_INLINE_BYTES = 8 * 1024 * 1024;
4468
- /** MCP content-block discriminators. At least one must appear for a result to be treated as MCP-shaped. */
4469
4290
  const KNOWN_MCP_BLOCK_TYPES = new Set([
4470
4291
  "text",
4471
4292
  "image",
@@ -4473,19 +4294,6 @@ const KNOWN_MCP_BLOCK_TYPES = new Set([
4473
4294
  "resource",
4474
4295
  "resource_link"
4475
4296
  ]);
4476
- /**
4477
- * Maps a tool result that is **content-block-shaped** (an MCP `CallToolResult` with a `content`
4478
- * array) into AI SDK `{ type: "content" }` tool-result output, so binaries reach the chat model as
4479
- * native multimodal tool-result blocks instead of being flattened to inert JSON text.
4480
- *
4481
- * The `@ai-sdk/anthropic` provider maps a `content`-output part as follows:
4482
- * `text` → text block, `image-data` → image block, `file-data` (only `application/pdf`) → document
4483
- * block. Non-PDF `file-data` is dropped by the provider, so this factory emits `image-data` for
4484
- * images, `file-data` only for PDFs, and a text marker for every other binary type.
4485
- *
4486
- * Returns `undefined` when the result is not content-block-shaped — callers keep the existing
4487
- * `{ type: "json" }` path, so plain string/object tool results are unaffected.
4488
- */
4489
4297
  var AgentToolResultContentFactory = class AgentToolResultContentFactory {
4490
4298
  static tryMapToContentOutput(result) {
4491
4299
  const blocks = AgentToolResultContentFactory.contentBlocks(result);
@@ -4499,12 +4307,6 @@ var AgentToolResultContentFactory = class AgentToolResultContentFactory {
4499
4307
  }
4500
4308
  return parts;
4501
4309
  }
4502
- /**
4503
- * Returns the `content` array iff `result` is an object whose `content` is an array of typed
4504
- * blocks AND at least one block carries a known MCP discriminator. A plain JSON result that merely
4505
- * has a `content` key of some other shape (e.g. Notion/Slack rich-text blocks) is rejected,
4506
- * preserving the `{ type: "json" }` path so its payload is never lost.
4507
- */
4508
4310
  static contentBlocks(result) {
4509
4311
  if (result === null || typeof result !== "object") return void 0;
4510
4312
  const content = result.content;
@@ -4609,19 +4411,10 @@ var AgentToolResultContentFactory = class AgentToolResultContentFactory {
4609
4411
 
4610
4412
  //#endregion
4611
4413
  //#region src/nodes/AgentMessageFactory.ts
4612
- /**
4613
- * AI-SDK-shaped message construction for the AIAgent stack. Emits plain `ModelMessage[]`
4614
- * ( `{ role: 'system' | 'user' | 'assistant' | 'tool', content: ... }` ) as consumed by
4615
- * `generateText({ messages })` from the `ai` package.
4616
- */
4617
4414
  var AgentMessageFactory = class AgentMessageFactory {
4618
4415
  static createPromptMessages(messages) {
4619
4416
  return messages.map((message) => this.createPromptMessage(message));
4620
4417
  }
4621
- /**
4622
- * Builds the assistant message that contains optional text plus one or more tool-call parts,
4623
- * matching the shape AI SDK emits between steps.
4624
- */
4625
4418
  static createAssistantWithToolCalls(text, toolCalls) {
4626
4419
  const content = [];
4627
4420
  if (text && text.length > 0) content.push({
@@ -4639,10 +4432,6 @@ var AgentMessageFactory = class AgentMessageFactory {
4639
4432
  content
4640
4433
  };
4641
4434
  }
4642
- /**
4643
- * Builds the `{ role: "tool", content: [{ type: "tool-result", ... }, ...] }` message returned
4644
- * to the model after each tool round.
4645
- */
4646
4435
  static createToolResultsMessage(executedToolCalls, passToolBinariesToModel = true) {
4647
4436
  return {
4648
4437
  role: "tool",
@@ -4654,11 +4443,6 @@ var AgentMessageFactory = class AgentMessageFactory {
4654
4443
  }))
4655
4444
  };
4656
4445
  }
4657
- /**
4658
- * Routes a tool result to a native multimodal `{ type: "content" }` output when it is
4659
- * content-block-shaped (an MCP `CallToolResult`) and binary passdown is enabled; otherwise keeps
4660
- * the inert `{ type: "json" }` path.
4661
- */
4662
4446
  static toToolResultOutput(result, passToolBinariesToModel) {
4663
4447
  if (passToolBinariesToModel) {
4664
4448
  const content = AgentToolResultContentFactory.tryMapToContentOutput(result);
@@ -5468,10 +5252,6 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
5468
5252
  }
5469
5253
  throw new Error(`Structured output required for AIAgent "${args.agentName}" (${args.nodeId}) but validation still failed after ${_AgentStructuredOutputRunner.repairAttemptCount} repair attempts: ${failure.validationError}`);
5470
5254
  }
5471
- /**
5472
- * Chooses strict mode for OpenAI chat-model configs, off otherwise. Extendable in future for
5473
- * other providers that adopt the same "supply a JSON Schema record directly" contract.
5474
- */
5475
5255
  resolveStructuredOutputOptions(chatModelConfig) {
5476
5256
  if (chatModelConfig.type !== OpenAIChatModelFactory) return;
5477
5257
  return {
@@ -5954,10 +5734,6 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
5954
5734
  extractErrorDetails(error) {
5955
5735
  return error.details;
5956
5736
  }
5957
- /**
5958
- * Extracts the text content from the last assistant message in the conversation snapshot.
5959
- * Used to populate `agentReasoning` in the HITL suspension metadata.
5960
- */
5961
5737
  extractLastAssistantText(conversation) {
5962
5738
  for (let i = conversation.length - 1; i >= 0; i--) {
5963
5739
  const msg = conversation[i];
@@ -5992,16 +5768,6 @@ AgentToolExecutionCoordinator = __decorate([
5992
5768
 
5993
5769
  //#endregion
5994
5770
  //#region src/nodes/AgentBinaryContentFactory.ts
5995
- /**
5996
- * Turns resolved file binaries into native AI SDK multimodal content parts and merges them into the
5997
- * agent prompt. Images (`image/*`) become {@link ImagePart}s; every other type (PDFs, office docs,
5998
- * CSV, JSON, …) becomes a {@link FilePart}. The provider maps these to its wire-level `image` /
5999
- * `document` blocks; an unsupported file type surfaces as a provider error at runtime.
6000
- *
6001
- * Parts are appended to the LAST user message so the binary travels alongside the author's prompt
6002
- * text (preserving any untrusted-source preamble that already wrapped that text). When no user
6003
- * message exists, a new user message carrying only the binaries is appended.
6004
- */
6005
5771
  var AgentBinaryContentFactory = class AgentBinaryContentFactory {
6006
5772
  static toContentPart(binary) {
6007
5773
  if (binary.mediaType.startsWith("image/")) return {
@@ -6080,20 +5846,6 @@ let NodeBackedToolRuntime = class NodeBackedToolRuntime$1 {
6080
5846
  outputs
6081
5847
  });
6082
5848
  }
6083
- /**
6084
- * Returns a re-rooted child ctx for nested-agent tools (so their LLM/tool connection ids derive
6085
- * from the tool connection node, telemetry parents under the tool-call span, and connection
6086
- * invocations carry `parentInvocationId`). Plain runnable tools (non-agent) keep the orchestrator
6087
- * ctx with only `config` swapped — no nesting concern.
6088
- *
6089
- * The caller (`AIAgentNode.createItemScopedTools`) already wraps the orchestrator ctx via
6090
- * `ConnectionCredentialExecutionContextFactory.forConnectionNode`, so `args.ctx.nodeId` is the
6091
- * tool's own connection node id (e.g. `AIAgentNode:2__conn__tool__searchInMail`). We pass that
6092
- * through as the sub-agent's `nodeId`; deriving another `toolConnectionNodeId(args.ctx.nodeId,
6093
- * config.name)` here would prepend a duplicate `__conn__tool__<name>` segment and exponentially
6094
- * deepen ids on each invocation, which also breaks credential resolution because user-provided
6095
- * bindings sit on the single-level connection node id.
6096
- */
6097
5849
  resolveNodeCtx(config$1, args) {
6098
5850
  const isNestedAgent = AgentConfigInspector.isAgentNodeConfig(config$1.node);
6099
5851
  const hooks = args.hooks;
@@ -6158,22 +5910,12 @@ NodeBackedToolRuntime = __decorate([
6158
5910
 
6159
5911
  //#endregion
6160
5912
  //#region src/nodes/BM25Index.ts
6161
- /**
6162
- * Minimal BM25 (Okapi BM25) implementation for indexing MCP tool descriptions.
6163
- *
6164
- * Parameters: k1=1.5, b=0.75 (standard defaults).
6165
- * Tokenisation: lowercase, split on non-alphanumerics, filter empties.
6166
- */
6167
5913
  var BM25Index = class {
6168
5914
  k1 = 1.5;
6169
5915
  b = .75;
6170
5916
  tf = [];
6171
5917
  df = /* @__PURE__ */ new Map();
6172
5918
  avgDocLen = 0;
6173
- /**
6174
- * Add all documents at once. After calling this, search is available.
6175
- * Documents are indexed in insertion order; search returns their indices.
6176
- */
6177
5919
  add(docs) {
6178
5920
  const docTerms = docs.map((d) => this.tokenize(d));
6179
5921
  let totalLen = 0;
@@ -6186,10 +5928,6 @@ var BM25Index = class {
6186
5928
  }
6187
5929
  this.avgDocLen = docTerms.length > 0 ? totalLen / docTerms.length : 0;
6188
5930
  }
6189
- /**
6190
- * Returns up to `limit` document indices ranked by BM25 score (highest first).
6191
- * Returns an empty array if the index is empty or the query matches nothing.
6192
- */
6193
5931
  search(query, limit) {
6194
5932
  const n = this.tf.length;
6195
5933
  if (n === 0) return [];
@@ -6230,26 +5968,12 @@ const PINNED_TOOLS_SOFT_LIMIT = 8;
6230
5968
  const PINNED_TOOLS_HARD_LIMIT = 16;
6231
5969
  const FIND_TOOLS_NAME = "find_tools";
6232
5970
  const FIND_TOOLS_DEFAULT_LIMIT = 5;
6233
- /**
6234
- * Default tool-loading strategy: BM25-indexed MCP tool deferral via a `find_tools` meta-tool.
6235
- *
6236
- * - Node-backed tools and pinned MCP tools are always included in every turn.
6237
- * - `find_tools(query, limit?)` is added to the tool set when MCP tools are indexed.
6238
- * - Tools surfaced by `find_tools` are included in subsequent turns.
6239
- *
6240
- * Not DI-managed; instantiated per agent execution by DeferredMetaToolStrategyFactory.
6241
- */
6242
5971
  var DeferredMetaToolStrategy = class {
6243
5972
  nodeBackedTools = {};
6244
5973
  pinnedTools = {};
6245
5974
  mcpEntries = [];
6246
5975
  toolsByServerId = /* @__PURE__ */ new Map();
6247
5976
  foundToolIds = /* @__PURE__ */ new Set();
6248
- /**
6249
- * `jsonSchema` from the `ai` SDK, loaded lazily in {@link initialize} so the SDK
6250
- * (~28MB RSS) stays off the boot path. `initialize` always runs before the sync
6251
- * `getToolsForTurn` → `buildFindToolsDefinition` path, so this is set before use.
6252
- */
6253
5977
  jsonSchema;
6254
5978
  constructor(bm25, warnFn) {
6255
5979
  this.bm25 = bm25;
@@ -6397,11 +6121,6 @@ let AIAgentNode = class AIAgentNode$1 {
6397
6121
  inputSchema = unknown();
6398
6122
  connectionCredentialExecutionContextFactory;
6399
6123
  preparedByExecutionContext = /* @__PURE__ */ new WeakMap();
6400
- /**
6401
- * The `ai` SDK, loaded lazily in {@link execute} so the SDK (~28MB RSS) stays
6402
- * off the boot path — non-AI workflows never load it. Every path runs through
6403
- * `execute` → `ensureAiSdk` before any sync helper touches `this.aiSdk`.
6404
- */
6405
6124
  aiSdk;
6406
6125
  aiSdkPromise = null;
6407
6126
  constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner, toolExecutionCoordinator, toolLoadingStrategyFactory, agentMcpIntegration) {
@@ -6425,15 +6144,9 @@ let AIAgentNode = class AIAgentNode$1 {
6425
6144
  };
6426
6145
  return (await this.runAgentForItem(prepared, itemWithMappedJson, args.itemIndex, args.items)).json;
6427
6146
  }
6428
- /** Load the `ai` SDK once per node instance (cached promise guards concurrent items). */
6429
6147
  async ensureAiSdk() {
6430
6148
  this.aiSdk = await (this.aiSdkPromise ??= import("ai"));
6431
6149
  }
6432
- /**
6433
- * Resume path: re-enters the agent loop after a HITL suspension.
6434
- * Reconstructs the conversation from the checkpoint, injects the human decision
6435
- * as a tool_result, and continues the loop from where it suspended.
6436
- */
6437
6150
  async executeResumed(args, resumeContext) {
6438
6151
  const { ctx } = args;
6439
6152
  const taskMetadata = resumeContext.task.metadata ?? {};
@@ -6480,10 +6193,6 @@ let AIAgentNode = class AIAgentNode$1 {
6480
6193
  const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalText, itemScopedTools.length > 0);
6481
6194
  return this.buildOutputItem(item, outputJson).json;
6482
6195
  }
6483
- /**
6484
- * Normalizes a {@link ResumeContext} decision into a flat JSON-serializable shape
6485
- * suitable for injection as a tool_result content.
6486
- */
6487
6196
  normalizeDecision(resumeContext) {
6488
6197
  const { decision } = resumeContext;
6489
6198
  if (decision.kind === "decided") {
@@ -6610,16 +6319,6 @@ let AIAgentNode = class AIAgentNode$1 {
6610
6319
  const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalText, itemScopedTools.length > 0);
6611
6320
  return this.buildOutputItem(item, outputJson);
6612
6321
  }
6613
- /**
6614
- * Multi-turn loop:
6615
- * - Each turn is a single `generateText` call with tools exposed but **not auto-executed**
6616
- * (we control tool dispatch so that {@link AgentToolExecutionCoordinator} drives repair /
6617
- * connection-invocation recording / transient-error handling exactly like before).
6618
- * - When the model returns no tool calls the loop ends with the model's text as the final answer.
6619
- * - Respects `guardrails.maxTurns` and `guardrails.onTurnLimitReached`.
6620
- * - Strategy-owned tool calls (e.g. `find_tools`) are dispatched via the strategy, not the
6621
- * coordinator; their results are tracked so subsequent turns receive the discovered tools.
6622
- */
6623
6322
  async runTurnLoopUntilFinalAnswer(args) {
6624
6323
  const { prepared, itemInputsByPort, itemScopedTools, conversation } = args;
6625
6324
  const { ctx, guardrails, toolLoadingStrategy } = prepared;
@@ -6627,7 +6326,6 @@ let AIAgentNode = class AIAgentNode$1 {
6627
6326
  let toolCallCount = args.resumedToolCallCount ?? 0;
6628
6327
  let turnCount = 0;
6629
6328
  const repairAttemptsByToolName = /* @__PURE__ */ new Map();
6630
- /** Tool IDs surfaced by find_tools across all prior turns in this item run. */
6631
6329
  let previousFoundToolIds = [];
6632
6330
  for (let turn = 1; turn <= guardrails.maxTurns; turn++) {
6633
6331
  turnCount = turn;
@@ -6757,12 +6455,6 @@ let AIAgentNode = class AIAgentNode$1 {
6757
6455
  };
6758
6456
  });
6759
6457
  }
6760
- /**
6761
- * Resolves the HITL behavior for a tool binding, or `undefined` when it is not a HITL tool.
6762
- * A binding is HITL if either the backing node carries a `defineHumanApprovalNode` marker or the
6763
- * binding sets a per-binding `onRejected` via `asTool(..., { onRejected })`. The per-binding value
6764
- * wins over the node marker, so two tools backed by the same node can reject differently.
6765
- */
6766
6458
  resolveHumanApprovalBehavior(config$1) {
6767
6459
  if (!this.isNodeBackedToolConfig(config$1)) return void 0;
6768
6460
  const marker = config$1.node.humanApprovalToolBehavior;
@@ -6770,11 +6462,6 @@ let AIAgentNode = class AIAgentNode$1 {
6770
6462
  if (marker === void 0 && perBinding === void 0) return void 0;
6771
6463
  return { onRejected: perBinding ?? marker?.onRejected ?? "return" };
6772
6464
  }
6773
- /**
6774
- * Invoke a text turn using the merged tool set from item-scoped tools (coordinator-managed)
6775
- * and strategy tools (find_tools + discovered MCP tools).
6776
- * Strategy tools take precedence for names that overlap.
6777
- */
6778
6465
  async invokeTextTurnWithStrategyTools(prepared, itemInputsByPort, messages, itemScopedTools, strategyTools) {
6779
6466
  const itemToolSet = this.buildToolSet(itemScopedTools);
6780
6467
  const strategyHasTools = Object.keys(strategyTools).length > 0;
@@ -6785,10 +6472,6 @@ let AIAgentNode = class AIAgentNode$1 {
6785
6472
  } : void 0;
6786
6473
  return this.invokeTextTurnWithToolSet(prepared, itemInputsByPort, messages, mergedTools);
6787
6474
  }
6788
- /**
6789
- * Removes `execute` properties from ToolSet entries so the AI SDK does not
6790
- * auto-execute them within `generateText`. Codemation owns all tool dispatch.
6791
- */
6792
6475
  stripExecuteCallbacks(tools) {
6793
6476
  const stripped = {};
6794
6477
  for (const [name, def] of Object.entries(tools)) {
@@ -6797,12 +6480,6 @@ let AIAgentNode = class AIAgentNode$1 {
6797
6480
  }
6798
6481
  return stripped;
6799
6482
  }
6800
- /**
6801
- * Builds a ToolSet from resolved tools for strategy initialization.
6802
- * The strategy uses this for its "always-included" node-backed tool descriptions.
6803
- * HITL tools (detected via the `humanApprovalToolBehavior` field set by `defineHumanApprovalNode`) get the solo-constraint sentence
6804
- * appended to their description.
6805
- */
6806
6483
  buildToolSetFromResolved(resolvedTools) {
6807
6484
  if (resolvedTools.length === 0) return {};
6808
6485
  const toolSet = {};
@@ -6820,20 +6497,6 @@ let AIAgentNode = class AIAgentNode$1 {
6820
6497
  }
6821
6498
  return toolSet;
6822
6499
  }
6823
- /**
6824
- * Builds an AI SDK {@link ToolSet} where every tool ships a pre-converted JSON Schema (via
6825
- * {@link jsonSchema}) — not the raw Zod schema — and carries **no** `execute`. Two reasons:
6826
- *
6827
- * 1. Codemation owns tool dispatch + the per-tool repair loop (see {@link AgentToolExecutionCoordinator}),
6828
- * so the AI SDK must surface tool calls back to us instead of auto-running them.
6829
- * 2. The AI SDK's `asSchema` helper discriminates between Zod v3 / Zod v4 / Standard Schema via
6830
- * runtime feature-detection (`~standard`, `_zod`, etc.). Handing it a pre-built
6831
- * {@link jsonSchema} record — which is tagged with `Symbol.for('vercel.ai.schema')` — skips all
6832
- * of that detection and guarantees the provider receives a draft-07 JSON Schema with
6833
- * `additionalProperties: false` at every object depth (see {@link OpenAiStrictJsonSchemaFactory}
6834
- * for the same logic applied to structured-output schemas). Codemation still runs its own Zod
6835
- * validation on tool inputs before execute — the schema handed to the model is advisory.
6836
- */
6837
6500
  buildToolSet(itemScopedTools) {
6838
6501
  if (itemScopedTools.length === 0) return void 0;
6839
6502
  const toolSet = {};
@@ -6851,10 +6514,6 @@ let AIAgentNode = class AIAgentNode$1 {
6851
6514
  }
6852
6515
  return toolSet;
6853
6516
  }
6854
- /**
6855
- * One `generateText` turn (no auto tool execution) with Codemation-owned child-span telemetry
6856
- * and connection-invocation state recording. Accepts a pre-built ToolSet.
6857
- */
6858
6517
  async invokeTextTurnWithToolSet(prepared, itemInputsByPort, messages, tools) {
6859
6518
  const invocationId = ConnectionInvocationIdFactory.create();
6860
6519
  const startedAt = /* @__PURE__ */ new Date();
@@ -6965,11 +6624,6 @@ let AIAgentNode = class AIAgentNode$1 {
6965
6624
  });
6966
6625
  }
6967
6626
  }
6968
- /**
6969
- * Structured-output turn: runs `generateText({ output: Output.object({ schema }) })` via the
6970
- * structured-output runner. We keep this as a separate helper because the runner needs the raw
6971
- * validated value (not just text) back, and must be able to retry on Zod failures.
6972
- */
6973
6627
  async invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions) {
6974
6628
  const invocationId = ConnectionInvocationIdFactory.create();
6975
6629
  const startedAt = /* @__PURE__ */ new Date();
@@ -7094,13 +6748,6 @@ let AIAgentNode = class AIAgentNode$1 {
7094
6748
  providerOptions: overrides?.providerOptions ?? defaults.providerOptions
7095
6749
  };
7096
6750
  }
7097
- /**
7098
- * Build a no-code-friendly output payload for an LLM round.
7099
- *
7100
- * Always includes `content` (matching the canvas snapshot shape used elsewhere) and adds a
7101
- * `toolCalls` array when the round produced tool calls so the execution inspector surfaces the
7102
- * planned calls instead of just an empty `""` for tool-only rounds.
7103
- */
7104
6751
  summarizeTurnOutput(turnResult) {
7105
6752
  if (turnResult.toolCalls.length === 0) return { content: turnResult.text };
7106
6753
  const toolCalls = turnResult.toolCalls.map((toolCall) => ({
@@ -7303,12 +6950,6 @@ let AIAgentNode = class AIAgentNode$1 {
7303
6950
  const binaries = await this.resolveInlineBinaries(attachments, ctx);
7304
6951
  return AgentBinaryContentFactory.withBinaries(promptMessages, binaries);
7305
6952
  }
7306
- /**
7307
- * Picks which attachments feed the passdown. When the author supplies `config.binaries`
7308
- * (a static array or a per-item function — e.g. to forward binaries from an earlier node),
7309
- * those replace the current item's attachments; otherwise the current item's `item.binary`
7310
- * is used.
7311
- */
7312
6953
  selectBinaryAttachments(item, itemIndex, items, ctx) {
7313
6954
  const manual = ctx.config.binaries;
7314
6955
  if (manual !== void 0) return typeof manual === "function" ? manual({
@@ -7319,14 +6960,6 @@ let AIAgentNode = class AIAgentNode$1 {
7319
6960
  }) : manual;
7320
6961
  return item.binary ? Object.values(item.binary) : [];
7321
6962
  }
7322
- /**
7323
- * Reads every attachment through `ctx.binary` (storage-backed, by reference — never base64 on
7324
- * `item.json`) and resolves it to inline base64 so the agent can pass it to the chat model as a
7325
- * native multimodal block. Images become image blocks; every other type (PDF, office docs, CSV,
7326
- * JSON, …) becomes a file block — we don't filter by media type, so any binary can be fed to the
7327
- * model. If the provider rejects an unsupported type the error surfaces at runtime, and the
7328
- * workflow can filter the binary upstream.
7329
- */
7330
6963
  async resolveInlineBinaries(attachments, ctx) {
7331
6964
  const resolved = [];
7332
6965
  for (const attachment of attachments) {
@@ -7339,12 +6972,6 @@ let AIAgentNode = class AIAgentNode$1 {
7339
6972
  }
7340
6973
  return resolved;
7341
6974
  }
7342
- /**
7343
- * When `item.json.__source` matches an entry in `config.untrustedSources`
7344
- * (default: `["gmail", "ocr", "webhook"]`), wraps every user-role message
7345
- * content with an untrusted-external-source preamble so the LLM treats the
7346
- * content as data, not instructions.
7347
- */
7348
6975
  wrapUntrustedSourceMessages(messages, item, config$1) {
7349
6976
  const source = item.json !== null && typeof item.json === "object" ? item.json.__source : void 0;
7350
6977
  if (typeof source !== "string") return messages;
@@ -7437,10 +7064,6 @@ AIAgentNode = __decorate([
7437
7064
 
7438
7065
  //#endregion
7439
7066
  //#region src/nodes/AIAgentConfig.ts
7440
- /**
7441
- * AI agent: credential bindings are keyed to connection-owned LLM/tool node ids (ConnectionNodeIdFactory),
7442
- * not to the agent workflow node id.
7443
- */
7444
7067
  var AIAgent = class {
7445
7068
  kind = "node";
7446
7069
  type = AIAgentNode;
@@ -7538,11 +7161,6 @@ AssertionNode = __decorate([node({ packageName: "@codemation/core-nodes" })], As
7538
7161
 
7539
7162
  //#endregion
7540
7163
  //#region src/nodes/assertion.ts
7541
- /**
7542
- * Generic assertion node — the "callback" form. For declarative shorthands (StringEquals,
7543
- * JudgeByAgent) compose this with helpers added in later phases. Sets `emitsAssertions: true`
7544
- * so host-side persisters know to record its outputs as `TestAssertion` rows.
7545
- */
7546
7164
  var Assertion = class {
7547
7165
  kind = "node";
7548
7166
  type = AssertionNode;
@@ -7805,17 +7423,12 @@ HttpRequestNode = __decorate([node({ packageName: "@codemation/core-nodes" })],
7805
7423
 
7806
7424
  //#endregion
7807
7425
  //#region src/nodes/httpRequest.ts
7808
- /**
7809
- * The built-in HTTP request credential type IDs accepted by the `HttpRequest` node.
7810
- * These match the four generic credential types shipped with `@codemation/core-nodes`.
7811
- */
7812
7426
  const HTTP_REQUEST_ACCEPTED_CREDENTIAL_TYPES = [
7813
7427
  bearerTokenCredentialType.definition.typeId,
7814
7428
  apiKeyCredentialType.definition.typeId,
7815
7429
  basicAuthCredentialType.definition.typeId,
7816
7430
  oauth2ClientCredentialsType.definition.typeId
7817
7431
  ];
7818
- /** Default maximum response size for binary mode: 100 MiB. */
7819
7432
  const DEFAULT_RESPONSE_SIZE_CAP_BYTES = 100 * 1024 * 1024;
7820
7433
  var HttpRequest = class {
7821
7434
  kind = "node";
@@ -7984,9 +7597,6 @@ var Filter = class {
7984
7597
  function getOriginIndex(item) {
7985
7598
  return getOriginIndexFromItem(item);
7986
7599
  }
7987
- /**
7988
- * Tags items routed to fan-in merge-by-origin (same contract as {@link IfNode} / {@link SwitchNode}).
7989
- */
7990
7600
  function tagItemForRouterFanIn(args) {
7991
7601
  const { item, itemIndex, nodeId, inputPortLabel = "$in" } = args;
7992
7602
  const metaBase = item.meta && typeof item.meta === "object" ? item.meta : {};
@@ -8077,10 +7687,6 @@ IsTestRunNode = __decorate([node({ packageName: "@codemation/core-nodes" })], Is
8077
7687
 
8078
7688
  //#endregion
8079
7689
  //#region src/nodes/isTestRun.ts
8080
- /**
8081
- * Branches per-item on whether the current run is a test run. Output ports: `true`, `false`.
8082
- * The wire payload is unchanged — this is a router, not a transform.
8083
- */
8084
7690
  var IsTestRun = class {
8085
7691
  kind = "node";
8086
7692
  type = IsTestRunNode;
@@ -8164,10 +7770,6 @@ var Split = class {
8164
7770
  type = SplitNode;
8165
7771
  execution = { hint: "local" };
8166
7772
  keepBinaries = true;
8167
- /**
8168
- * When splitting yields zero items for a batch, downstream single-input nodes still run once with an empty batch.
8169
- * Mirrors {@link MapData}'s empty-output behavior.
8170
- */
8171
7773
  continueWhenEmptyOutput = true;
8172
7774
  icon = "builtin:split-rows";
8173
7775
  id;
@@ -8221,15 +7823,6 @@ CronTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })],
8221
7823
 
8222
7824
  //#endregion
8223
7825
  //#region src/nodes/CronTriggerFactory.ts
8224
- /**
8225
- * Schedules a workflow on a standard cron expression.
8226
- *
8227
- * Each tick emits one item: `{ firedAt: string, scheduledFor: string }` — both ISO-8601 timestamps.
8228
- * `firedAt` is the wall-clock moment the callback ran; `scheduledFor` is the cron-computed
8229
- * firing instant (these differ when the job was delayed).
8230
- *
8231
- * Timezone defaults to UTC when omitted — cron without an explicit TZ is a DST footgun.
8232
- */
8233
7826
  var CronTrigger = class {
8234
7827
  kind = "trigger";
8235
7828
  type = CronTriggerNode;
@@ -8300,7 +7893,6 @@ var ManualTrigger = class ManualTrigger {
8300
7893
  defaultItems;
8301
7894
  id;
8302
7895
  description;
8303
- /** Manual runs often emit an empty batch; still schedule downstream by default. */
8304
7896
  continueWhenEmptyOutput = true;
8305
7897
  constructor(name = "Manual trigger", defaultItemsOrId, idOrOptions) {
8306
7898
  this.name = name;
@@ -8355,7 +7947,6 @@ var MapData = class {
8355
7947
  kind = "node";
8356
7948
  type = MapDataNode;
8357
7949
  execution = { hint: "local" };
8358
- /** Zero mapped items should still allow downstream nodes to run. */
8359
7950
  continueWhenEmptyOutput = true;
8360
7951
  icon = "lucide:square-pen";
8361
7952
  keepBinaries;
@@ -8588,11 +8179,6 @@ TestTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })],
8588
8179
 
8589
8180
  //#endregion
8590
8181
  //#region src/nodes/testTrigger.ts
8591
- /**
8592
- * Trigger config for a test fixture source. Drop one (or more) of these on the canvas alongside
8593
- * a workflow's live triggers; clicking "Run tests" on the Tests tab invokes
8594
- * {@link TestTriggerOptions.generateItems} via the TestSuiteOrchestrator.
8595
- */
8596
8182
  var TestTrigger = class {
8597
8183
  kind = "trigger";
8598
8184
  triggerKind = "test";
@@ -8666,7 +8252,6 @@ var Wait = class {
8666
8252
  kind = "node";
8667
8253
  type = WaitNode;
8668
8254
  execution = { hint: "local" };
8669
- /** Pass-through empty batches should still advance to downstream nodes. */
8670
8255
  continueWhenEmptyOutput = true;
8671
8256
  icon = "lucide:hourglass";
8672
8257
  id;
@@ -8768,6 +8353,39 @@ var WebhookTrigger = class WebhookTrigger {
8768
8353
  }
8769
8354
  };
8770
8355
 
8356
+ //#endregion
8357
+ //#region src/nodes/schedulePollingTrigger.ts
8358
+ const schedulePollingTrigger = definePollingTrigger({
8359
+ key: "schedule.interval",
8360
+ packageName: "@codemation/core-nodes",
8361
+ title: "Run on schedule",
8362
+ description: "Emit one tick item on every poll cycle.",
8363
+ icon: "lucide:clock",
8364
+ pollIntervalMs: 6e4,
8365
+ initialState() {
8366
+ return { tick: 0 };
8367
+ },
8368
+ poll({ state }) {
8369
+ const tick = (state ?? { tick: 0 }).tick + 1;
8370
+ return {
8371
+ items: [{ json: {
8372
+ firedAt: (/* @__PURE__ */ new Date()).toISOString(),
8373
+ tick
8374
+ } }],
8375
+ nextState: { tick }
8376
+ };
8377
+ },
8378
+ execute(items) {
8379
+ return { main: items };
8380
+ },
8381
+ testItems() {
8382
+ return [{ json: {
8383
+ firedAt: (/* @__PURE__ */ new Date()).toISOString(),
8384
+ tick: 0
8385
+ } }];
8386
+ }
8387
+ });
8388
+
8771
8389
  //#endregion
8772
8390
  //#region src/nodes/ConnectionCredentialNode.ts
8773
8391
  let ConnectionCredentialNode = class ConnectionCredentialNode$1 {
@@ -8781,11 +8399,6 @@ ConnectionCredentialNode = __decorate([node({ packageName: "@codemation/core-nod
8781
8399
 
8782
8400
  //#endregion
8783
8401
  //#region src/register.types.ts
8784
- /**
8785
- * Registrar for built-in nodes. In a real project, this would use tsyringe's
8786
- * container.registerSingleton(...). For the skeleton we keep it token-based:
8787
- * the engine resolves node implementations by class token.
8788
- */
8789
8402
  function registerCoreNodes(container) {}
8790
8403
 
8791
8404
  //#endregion
@@ -9014,9 +8627,6 @@ function workflow(id) {
9014
8627
 
9015
8628
  //#endregion
9016
8629
  //#region src/workflows/AIAgentConnectionWorkflowExpander.ts
9017
- /**
9018
- * Materializes connection-owned child nodes and {@link WorkflowDefinition.connections} for AI agent nodes.
9019
- */
9020
8630
  var AIAgentConnectionWorkflowExpander = class {
9021
8631
  constructor(connectionCredentialNodeConfigFactory, mcpServerResolver) {
9022
8632
  this.connectionCredentialNodeConfigFactory = connectionCredentialNodeConfigFactory;
@@ -9284,16 +8894,6 @@ const collectionDeleteNode = defineNode({
9284
8894
  function resolveSubjectField(field, item) {
9285
8895
  return typeof field === "function" ? field({ item }) : field;
9286
8896
  }
9287
- /**
9288
- * Auto-detecting inbox approval node.
9289
- *
9290
- * Uses `ctx.resolve(InboxChannelResolverToken)` to pick the right inbox channel
9291
- * at runtime:
9292
- * - In managed mode (PairingConfig present): routes to the control-plane inbox.
9293
- * - Otherwise: routes to the local inbox.
9294
- *
9295
- * Authors use this node directly; no extra wiring needed per deployment mode.
9296
- */
9297
8897
  const inboxApproval = defineHumanApprovalNode({
9298
8898
  key: "inbox.approval",
9299
8899
  title: "Inbox Approval",
@@ -9447,5 +9047,5 @@ const codemationDocumentScannerNode = defineNode({
9447
9047
  });
9448
9048
 
9449
9049
  //#endregion
9450
- export { AIAgent, AIAgentConnectionWorkflowExpander, AIAgentExecutionHelpersFactory, AIAgentNode, AgentItemPortMap, AgentMessageFactory, AgentOutputFactory, AgentStructuredOutputRepairPromptFactory, AgentStructuredOutputRunner, AgentToolCallPortMap, AgentToolErrorClassifier, AgentToolExecutionCoordinator, AgentToolRepairExhaustedError, AgentToolRepairPolicy, Aggregate, AggregateNode, Assertion, AssertionNode, BM25Index, Callback, CallbackNode, CallbackResultNormalizer, CodemationChatModelConfig, CodemationChatModelFactory, ConnectionCredentialExecutionContextFactory, ConnectionCredentialNode, ConnectionCredentialNodeConfig, ConnectionCredentialNodeConfigFactory, CronTrigger, CronTriggerNode, DeferredMetaToolStrategy, DeferredMetaToolStrategyFactory, Filter, FilterNode, HTTP_REQUEST_ACCEPTED_CREDENTIAL_TYPES, HttpRequest, HttpRequestNode, If, IfNode, IsTestRun, IsTestRunNode, ManualTrigger, ManualTriggerNode, MapData, MapDataNode, Merge, MergeNode, NoOp, NoOpNode, OpenAIChatModelConfig, OpenAIChatModelFactory, OpenAiChatModelPresets, OpenAiStrictJsonSchemaFactory, SSRFBlockedError, Split, SplitNode, SsrfGuard, SubWorkflow, SubWorkflowNode, Switch, SwitchNode, TestTrigger, TestTriggerNode, Wait, WaitDuration, WaitNode, WebhookRespondNowAndContinueError, WebhookRespondNowError, WebhookTrigger, WebhookTriggerNode, WorkflowAuthoringBuilder, WorkflowBranchBuilder, WorkflowChain, apiKeyCredentialType, basicAuthCredentialType, bearerTokenCredentialType, codemationDocumentScannerNode, collectionDeleteNode, collectionFindOneNode, collectionGetNode, collectionInsertNode, collectionListNode, collectionUpdateNode, createWorkflowBuilder, defineRestNode, inboxApproval, oauth2ClientCredentialsType, openAiChatModelPresets, registerCoreNodes, workflow };
9050
+ export { AIAgent, AIAgentConnectionWorkflowExpander, AIAgentExecutionHelpersFactory, AIAgentNode, AgentItemPortMap, AgentMessageFactory, AgentOutputFactory, AgentStructuredOutputRepairPromptFactory, AgentStructuredOutputRunner, AgentToolCallPortMap, AgentToolErrorClassifier, AgentToolExecutionCoordinator, AgentToolRepairExhaustedError, AgentToolRepairPolicy, Aggregate, AggregateNode, Assertion, AssertionNode, BM25Index, Callback, CallbackNode, CallbackResultNormalizer, CodemationChatModelConfig, CodemationChatModelFactory, ConnectionCredentialExecutionContextFactory, ConnectionCredentialNode, ConnectionCredentialNodeConfig, ConnectionCredentialNodeConfigFactory, CronTrigger, CronTriggerNode, DeferredMetaToolStrategy, DeferredMetaToolStrategyFactory, Filter, FilterNode, HTTP_REQUEST_ACCEPTED_CREDENTIAL_TYPES, HttpRequest, HttpRequestNode, If, IfNode, IsTestRun, IsTestRunNode, ManualTrigger, ManualTriggerNode, MapData, MapDataNode, Merge, MergeNode, NoOp, NoOpNode, OpenAIChatModelConfig, OpenAIChatModelFactory, OpenAiChatModelPresets, OpenAiStrictJsonSchemaFactory, SSRFBlockedError, Split, SplitNode, SsrfGuard, SubWorkflow, SubWorkflowNode, Switch, SwitchNode, TestTrigger, TestTriggerNode, Wait, WaitDuration, WaitNode, WebhookRespondNowAndContinueError, WebhookRespondNowError, WebhookTrigger, WebhookTriggerNode, WorkflowAuthoringBuilder, WorkflowBranchBuilder, WorkflowChain, apiKeyCredentialType, basicAuthCredentialType, bearerTokenCredentialType, codemationDocumentScannerNode, collectionDeleteNode, collectionFindOneNode, collectionGetNode, collectionInsertNode, collectionListNode, collectionUpdateNode, createWorkflowBuilder, defineRestNode, inboxApproval, oauth2ClientCredentialsType, openAiChatModelPresets, registerCoreNodes, schedulePollingTrigger, workflow };
9451
9051
  //# sourceMappingURL=index.js.map