@codemation/core-nodes 0.12.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.
- package/CHANGELOG.md +30 -0
- package/dist/index.cjs +180 -413
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -1303
- package/dist/index.d.ts +99 -1303
- package/dist/index.js +181 -415
- package/dist/index.js.map +1 -1
- package/dist/metadata.json +1 -1
- package/package.json +2 -2
- package/src/authoring/defineRestNode.types.ts +0 -84
- package/src/canvasIconName.ts +0 -7
- package/src/chatModels/CodemationChatModelConfig.ts +0 -10
- package/src/chatModels/CodemationChatModelFactory.ts +0 -7
- package/src/chatModels/ManagedHmacSignerFactory.types.ts +0 -35
- package/src/chatModels/OpenAIChatModelFactory.ts +0 -2
- package/src/chatModels/OpenAiChatModelPresetsFactory.ts +0 -5
- package/src/chatModels/OpenAiCredentialSession.ts +0 -1
- package/src/chatModels/OpenAiStrictJsonSchemaFactory.ts +0 -21
- package/src/credentials/ApiKeyCredentialType.ts +0 -3
- package/src/credentials/BasicAuthCredentialType.ts +0 -4
- package/src/credentials/BearerTokenCredentialType.ts +0 -4
- package/src/credentials/OAuth2ClientCredentialsTypeFactory.ts +0 -19
- package/src/credentials/OAuth2TokenExchangeFactory.ts +0 -7
- package/src/http/HttpBodyBuilder.ts +0 -16
- package/src/http/HttpRequestExecutor.ts +0 -35
- package/src/http/HttpUrlBuilder.ts +0 -4
- package/src/http/SSRFBlockedError.ts +0 -4
- package/src/http/SsrfGuard.ts +10 -50
- package/src/http/httpRequest.types.ts +0 -49
- package/src/index.ts +1 -0
- package/src/nodes/AIAgentConfig.ts +3 -39
- package/src/nodes/AIAgentExecutionHelpersFactory.ts +0 -37
- package/src/nodes/AIAgentNode.ts +4 -134
- package/src/nodes/AgentBinaryContentFactory.ts +0 -12
- package/src/nodes/AgentLoopCheckpoint.types.ts +0 -13
- package/src/nodes/AgentMessageFactory.ts +17 -19
- package/src/nodes/AgentStructuredOutputRunner.ts +0 -17
- package/src/nodes/AgentToolExecutionCoordinator.ts +0 -12
- package/src/nodes/AgentToolResultContentFactory.ts +126 -0
- package/src/nodes/AssertionNode.ts +0 -14
- package/src/nodes/BM25Index.ts +0 -14
- package/src/nodes/ConnectionCredentialExecutionContextFactory.ts +0 -5
- package/src/nodes/ConnectionCredentialNode.ts +0 -4
- package/src/nodes/CronTriggerFactory.ts +0 -9
- package/src/nodes/DeferredMetaToolStrategy.ts +0 -18
- package/src/nodes/DeferredMetaToolStrategyFactory.ts +0 -5
- package/src/nodes/HttpRequestNodeFactory.ts +0 -14
- package/src/nodes/InboxApprovalNode.types.ts +0 -16
- package/src/nodes/IsTestRunNode.ts +0 -8
- package/src/nodes/ManualTriggerFactory.ts +0 -3
- package/src/nodes/ManualTriggerNode.ts +0 -4
- package/src/nodes/MergeNode.ts +0 -1
- package/src/nodes/NodeBackedToolRuntime.ts +0 -14
- package/src/nodes/SubWorkflowNode.ts +0 -3
- package/src/nodes/SwitchNode.ts +0 -3
- package/src/nodes/TestTriggerNode.ts +0 -9
- package/src/nodes/aiAgentSupport.types.ts +0 -16
- package/src/nodes/assertion.ts +0 -10
- package/src/nodes/codemationDocumentScannerNode.ts +0 -18
- package/src/nodes/collections/collectionListNode.types.ts +0 -1
- package/src/nodes/httpRequest.ts +0 -68
- package/src/nodes/isTestRun.ts +0 -4
- package/src/nodes/mapData.ts +0 -1
- package/src/nodes/merge.ts +0 -4
- package/src/nodes/mergeExecutionUtils.types.ts +0 -3
- package/src/nodes/nodeOptions.types.ts +0 -8
- package/src/nodes/schedulePollingTrigger.ts +37 -0
- package/src/nodes/split.ts +0 -4
- package/src/nodes/testTrigger.ts +0 -21
- package/src/nodes/wait.ts +0 -1
- package/src/nodes/webhookTriggerNode.ts +0 -5
- package/src/register.types.ts +0 -10
- 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");
|
|
@@ -4458,21 +4284,137 @@ var CodemationChatModelConfig = class {
|
|
|
4458
4284
|
}
|
|
4459
4285
|
};
|
|
4460
4286
|
|
|
4287
|
+
//#endregion
|
|
4288
|
+
//#region src/nodes/AgentToolResultContentFactory.ts
|
|
4289
|
+
const MAX_INLINE_BYTES = 8 * 1024 * 1024;
|
|
4290
|
+
const KNOWN_MCP_BLOCK_TYPES = new Set([
|
|
4291
|
+
"text",
|
|
4292
|
+
"image",
|
|
4293
|
+
"audio",
|
|
4294
|
+
"resource",
|
|
4295
|
+
"resource_link"
|
|
4296
|
+
]);
|
|
4297
|
+
var AgentToolResultContentFactory = class AgentToolResultContentFactory {
|
|
4298
|
+
static tryMapToContentOutput(result) {
|
|
4299
|
+
const blocks = AgentToolResultContentFactory.contentBlocks(result);
|
|
4300
|
+
if (blocks === void 0) return void 0;
|
|
4301
|
+
const parts = [];
|
|
4302
|
+
let inlinedBytes = 0;
|
|
4303
|
+
for (const block of blocks) {
|
|
4304
|
+
const mapped = AgentToolResultContentFactory.mapBlock(block, inlinedBytes);
|
|
4305
|
+
parts.push(mapped.part);
|
|
4306
|
+
inlinedBytes += mapped.bytes;
|
|
4307
|
+
}
|
|
4308
|
+
return parts;
|
|
4309
|
+
}
|
|
4310
|
+
static contentBlocks(result) {
|
|
4311
|
+
if (result === null || typeof result !== "object") return void 0;
|
|
4312
|
+
const content = result.content;
|
|
4313
|
+
if (!Array.isArray(content) || content.length === 0) return void 0;
|
|
4314
|
+
if (!content.every((block) => block !== null && typeof block === "object" && typeof block.type === "string")) return void 0;
|
|
4315
|
+
return content.some((block) => KNOWN_MCP_BLOCK_TYPES.has(block.type)) ? content : void 0;
|
|
4316
|
+
}
|
|
4317
|
+
static mapBlock(block, inlinedBytesSoFar) {
|
|
4318
|
+
const type = block.type;
|
|
4319
|
+
if (type === "text" && typeof block.text === "string") return {
|
|
4320
|
+
part: {
|
|
4321
|
+
type: "text",
|
|
4322
|
+
text: block.text
|
|
4323
|
+
},
|
|
4324
|
+
bytes: 0
|
|
4325
|
+
};
|
|
4326
|
+
if (type === "image" && typeof block.data === "string" && typeof block.mimeType === "string") return AgentToolResultContentFactory.mapBinary({
|
|
4327
|
+
base64: block.data,
|
|
4328
|
+
mediaType: block.mimeType,
|
|
4329
|
+
inlinedBytesSoFar
|
|
4330
|
+
});
|
|
4331
|
+
if (type === "resource" && block.resource) return AgentToolResultContentFactory.mapEmbeddedResource(block.resource, inlinedBytesSoFar);
|
|
4332
|
+
if (type === "resource_link" && typeof block.uri === "string") {
|
|
4333
|
+
const mime = typeof block.mimeType === "string" ? ` (${block.mimeType})` : "";
|
|
4334
|
+
return {
|
|
4335
|
+
part: {
|
|
4336
|
+
type: "text",
|
|
4337
|
+
text: `[linked resource: ${block.uri}${mime}]`
|
|
4338
|
+
},
|
|
4339
|
+
bytes: 0
|
|
4340
|
+
};
|
|
4341
|
+
}
|
|
4342
|
+
return {
|
|
4343
|
+
part: {
|
|
4344
|
+
type: "text",
|
|
4345
|
+
text: `[unsupported tool content block: ${String(type)}]`
|
|
4346
|
+
},
|
|
4347
|
+
bytes: 0
|
|
4348
|
+
};
|
|
4349
|
+
}
|
|
4350
|
+
static mapEmbeddedResource(resource, inlinedBytesSoFar) {
|
|
4351
|
+
if (typeof resource.text === "string") return {
|
|
4352
|
+
part: {
|
|
4353
|
+
type: "text",
|
|
4354
|
+
text: resource.text
|
|
4355
|
+
},
|
|
4356
|
+
bytes: 0
|
|
4357
|
+
};
|
|
4358
|
+
if (typeof resource.blob === "string" && typeof resource.mimeType === "string") return AgentToolResultContentFactory.mapBinary({
|
|
4359
|
+
base64: resource.blob,
|
|
4360
|
+
mediaType: resource.mimeType,
|
|
4361
|
+
filename: typeof resource.name === "string" ? resource.name : void 0,
|
|
4362
|
+
inlinedBytesSoFar
|
|
4363
|
+
});
|
|
4364
|
+
return {
|
|
4365
|
+
part: {
|
|
4366
|
+
type: "text",
|
|
4367
|
+
text: `[embedded resource: ${typeof resource.uri === "string" ? resource.uri : "unknown"}]`
|
|
4368
|
+
},
|
|
4369
|
+
bytes: 0
|
|
4370
|
+
};
|
|
4371
|
+
}
|
|
4372
|
+
static mapBinary(args) {
|
|
4373
|
+
const rawBytes = Math.floor(args.base64.length * 3 / 4);
|
|
4374
|
+
if (args.inlinedBytesSoFar + rawBytes > MAX_INLINE_BYTES) {
|
|
4375
|
+
const name = args.filename ? ` "${args.filename}"` : "";
|
|
4376
|
+
const kb = Math.round(rawBytes / 1024);
|
|
4377
|
+
return {
|
|
4378
|
+
part: {
|
|
4379
|
+
type: "text",
|
|
4380
|
+
text: `[binary${name} (${args.mediaType}, ~${kb} KB) omitted: exceeds the per-tool-result inline limit]`
|
|
4381
|
+
},
|
|
4382
|
+
bytes: 0
|
|
4383
|
+
};
|
|
4384
|
+
}
|
|
4385
|
+
if (args.mediaType.startsWith("image/")) return {
|
|
4386
|
+
part: {
|
|
4387
|
+
type: "image-data",
|
|
4388
|
+
data: args.base64,
|
|
4389
|
+
mediaType: args.mediaType
|
|
4390
|
+
},
|
|
4391
|
+
bytes: rawBytes
|
|
4392
|
+
};
|
|
4393
|
+
if (args.mediaType === "application/pdf") return {
|
|
4394
|
+
part: {
|
|
4395
|
+
type: "file-data",
|
|
4396
|
+
data: args.base64,
|
|
4397
|
+
mediaType: args.mediaType,
|
|
4398
|
+
...args.filename ? { filename: args.filename } : {}
|
|
4399
|
+
},
|
|
4400
|
+
bytes: rawBytes
|
|
4401
|
+
};
|
|
4402
|
+
return {
|
|
4403
|
+
part: {
|
|
4404
|
+
type: "text",
|
|
4405
|
+
text: `[binary${args.filename ? ` "${args.filename}"` : ""} (${args.mediaType}) not inlined: unsupported by the model]`
|
|
4406
|
+
},
|
|
4407
|
+
bytes: 0
|
|
4408
|
+
};
|
|
4409
|
+
}
|
|
4410
|
+
};
|
|
4411
|
+
|
|
4461
4412
|
//#endregion
|
|
4462
4413
|
//#region src/nodes/AgentMessageFactory.ts
|
|
4463
|
-
/**
|
|
4464
|
-
* AI-SDK-shaped message construction for the AIAgent stack. Emits plain `ModelMessage[]`
|
|
4465
|
-
* ( `{ role: 'system' | 'user' | 'assistant' | 'tool', content: ... }` ) as consumed by
|
|
4466
|
-
* `generateText({ messages })` from the `ai` package.
|
|
4467
|
-
*/
|
|
4468
4414
|
var AgentMessageFactory = class AgentMessageFactory {
|
|
4469
4415
|
static createPromptMessages(messages) {
|
|
4470
4416
|
return messages.map((message) => this.createPromptMessage(message));
|
|
4471
4417
|
}
|
|
4472
|
-
/**
|
|
4473
|
-
* Builds the assistant message that contains optional text plus one or more tool-call parts,
|
|
4474
|
-
* matching the shape AI SDK emits between steps.
|
|
4475
|
-
*/
|
|
4476
4418
|
static createAssistantWithToolCalls(text, toolCalls) {
|
|
4477
4419
|
const content = [];
|
|
4478
4420
|
if (text && text.length > 0) content.push({
|
|
@@ -4490,24 +4432,30 @@ var AgentMessageFactory = class AgentMessageFactory {
|
|
|
4490
4432
|
content
|
|
4491
4433
|
};
|
|
4492
4434
|
}
|
|
4493
|
-
|
|
4494
|
-
* Builds the `{ role: "tool", content: [{ type: "tool-result", ... }, ...] }` message returned
|
|
4495
|
-
* to the model after each tool round.
|
|
4496
|
-
*/
|
|
4497
|
-
static createToolResultsMessage(executedToolCalls) {
|
|
4435
|
+
static createToolResultsMessage(executedToolCalls, passToolBinariesToModel = true) {
|
|
4498
4436
|
return {
|
|
4499
4437
|
role: "tool",
|
|
4500
4438
|
content: executedToolCalls.map((executed) => ({
|
|
4501
4439
|
type: "tool-result",
|
|
4502
4440
|
toolCallId: executed.toolCallId,
|
|
4503
4441
|
toolName: executed.toolName,
|
|
4504
|
-
output:
|
|
4505
|
-
type: "json",
|
|
4506
|
-
value: AgentMessageFactory.toToolResultJson(executed.result)
|
|
4507
|
-
}
|
|
4442
|
+
output: AgentMessageFactory.toToolResultOutput(executed.result, passToolBinariesToModel)
|
|
4508
4443
|
}))
|
|
4509
4444
|
};
|
|
4510
4445
|
}
|
|
4446
|
+
static toToolResultOutput(result, passToolBinariesToModel) {
|
|
4447
|
+
if (passToolBinariesToModel) {
|
|
4448
|
+
const content = AgentToolResultContentFactory.tryMapToContentOutput(result);
|
|
4449
|
+
if (content !== void 0) return {
|
|
4450
|
+
type: "content",
|
|
4451
|
+
value: content
|
|
4452
|
+
};
|
|
4453
|
+
}
|
|
4454
|
+
return {
|
|
4455
|
+
type: "json",
|
|
4456
|
+
value: AgentMessageFactory.toToolResultJson(result)
|
|
4457
|
+
};
|
|
4458
|
+
}
|
|
4511
4459
|
static toToolResultJson(value) {
|
|
4512
4460
|
if (value === void 0) return null;
|
|
4513
4461
|
try {
|
|
@@ -5304,10 +5252,6 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
|
|
|
5304
5252
|
}
|
|
5305
5253
|
throw new Error(`Structured output required for AIAgent "${args.agentName}" (${args.nodeId}) but validation still failed after ${_AgentStructuredOutputRunner.repairAttemptCount} repair attempts: ${failure.validationError}`);
|
|
5306
5254
|
}
|
|
5307
|
-
/**
|
|
5308
|
-
* Chooses strict mode for OpenAI chat-model configs, off otherwise. Extendable in future for
|
|
5309
|
-
* other providers that adopt the same "supply a JSON Schema record directly" contract.
|
|
5310
|
-
*/
|
|
5311
5255
|
resolveStructuredOutputOptions(chatModelConfig) {
|
|
5312
5256
|
if (chatModelConfig.type !== OpenAIChatModelFactory) return;
|
|
5313
5257
|
return {
|
|
@@ -5790,10 +5734,6 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
|
|
|
5790
5734
|
extractErrorDetails(error) {
|
|
5791
5735
|
return error.details;
|
|
5792
5736
|
}
|
|
5793
|
-
/**
|
|
5794
|
-
* Extracts the text content from the last assistant message in the conversation snapshot.
|
|
5795
|
-
* Used to populate `agentReasoning` in the HITL suspension metadata.
|
|
5796
|
-
*/
|
|
5797
5737
|
extractLastAssistantText(conversation) {
|
|
5798
5738
|
for (let i = conversation.length - 1; i >= 0; i--) {
|
|
5799
5739
|
const msg = conversation[i];
|
|
@@ -5828,16 +5768,6 @@ AgentToolExecutionCoordinator = __decorate([
|
|
|
5828
5768
|
|
|
5829
5769
|
//#endregion
|
|
5830
5770
|
//#region src/nodes/AgentBinaryContentFactory.ts
|
|
5831
|
-
/**
|
|
5832
|
-
* Turns resolved file binaries into native AI SDK multimodal content parts and merges them into the
|
|
5833
|
-
* agent prompt. Images (`image/*`) become {@link ImagePart}s; every other type (PDFs, office docs,
|
|
5834
|
-
* CSV, JSON, …) becomes a {@link FilePart}. The provider maps these to its wire-level `image` /
|
|
5835
|
-
* `document` blocks; an unsupported file type surfaces as a provider error at runtime.
|
|
5836
|
-
*
|
|
5837
|
-
* Parts are appended to the LAST user message so the binary travels alongside the author's prompt
|
|
5838
|
-
* text (preserving any untrusted-source preamble that already wrapped that text). When no user
|
|
5839
|
-
* message exists, a new user message carrying only the binaries is appended.
|
|
5840
|
-
*/
|
|
5841
5771
|
var AgentBinaryContentFactory = class AgentBinaryContentFactory {
|
|
5842
5772
|
static toContentPart(binary) {
|
|
5843
5773
|
if (binary.mediaType.startsWith("image/")) return {
|
|
@@ -5916,20 +5846,6 @@ let NodeBackedToolRuntime = class NodeBackedToolRuntime$1 {
|
|
|
5916
5846
|
outputs
|
|
5917
5847
|
});
|
|
5918
5848
|
}
|
|
5919
|
-
/**
|
|
5920
|
-
* Returns a re-rooted child ctx for nested-agent tools (so their LLM/tool connection ids derive
|
|
5921
|
-
* from the tool connection node, telemetry parents under the tool-call span, and connection
|
|
5922
|
-
* invocations carry `parentInvocationId`). Plain runnable tools (non-agent) keep the orchestrator
|
|
5923
|
-
* ctx with only `config` swapped — no nesting concern.
|
|
5924
|
-
*
|
|
5925
|
-
* The caller (`AIAgentNode.createItemScopedTools`) already wraps the orchestrator ctx via
|
|
5926
|
-
* `ConnectionCredentialExecutionContextFactory.forConnectionNode`, so `args.ctx.nodeId` is the
|
|
5927
|
-
* tool's own connection node id (e.g. `AIAgentNode:2__conn__tool__searchInMail`). We pass that
|
|
5928
|
-
* through as the sub-agent's `nodeId`; deriving another `toolConnectionNodeId(args.ctx.nodeId,
|
|
5929
|
-
* config.name)` here would prepend a duplicate `__conn__tool__<name>` segment and exponentially
|
|
5930
|
-
* deepen ids on each invocation, which also breaks credential resolution because user-provided
|
|
5931
|
-
* bindings sit on the single-level connection node id.
|
|
5932
|
-
*/
|
|
5933
5849
|
resolveNodeCtx(config$1, args) {
|
|
5934
5850
|
const isNestedAgent = AgentConfigInspector.isAgentNodeConfig(config$1.node);
|
|
5935
5851
|
const hooks = args.hooks;
|
|
@@ -5994,22 +5910,12 @@ NodeBackedToolRuntime = __decorate([
|
|
|
5994
5910
|
|
|
5995
5911
|
//#endregion
|
|
5996
5912
|
//#region src/nodes/BM25Index.ts
|
|
5997
|
-
/**
|
|
5998
|
-
* Minimal BM25 (Okapi BM25) implementation for indexing MCP tool descriptions.
|
|
5999
|
-
*
|
|
6000
|
-
* Parameters: k1=1.5, b=0.75 (standard defaults).
|
|
6001
|
-
* Tokenisation: lowercase, split on non-alphanumerics, filter empties.
|
|
6002
|
-
*/
|
|
6003
5913
|
var BM25Index = class {
|
|
6004
5914
|
k1 = 1.5;
|
|
6005
5915
|
b = .75;
|
|
6006
5916
|
tf = [];
|
|
6007
5917
|
df = /* @__PURE__ */ new Map();
|
|
6008
5918
|
avgDocLen = 0;
|
|
6009
|
-
/**
|
|
6010
|
-
* Add all documents at once. After calling this, search is available.
|
|
6011
|
-
* Documents are indexed in insertion order; search returns their indices.
|
|
6012
|
-
*/
|
|
6013
5919
|
add(docs) {
|
|
6014
5920
|
const docTerms = docs.map((d) => this.tokenize(d));
|
|
6015
5921
|
let totalLen = 0;
|
|
@@ -6022,10 +5928,6 @@ var BM25Index = class {
|
|
|
6022
5928
|
}
|
|
6023
5929
|
this.avgDocLen = docTerms.length > 0 ? totalLen / docTerms.length : 0;
|
|
6024
5930
|
}
|
|
6025
|
-
/**
|
|
6026
|
-
* Returns up to `limit` document indices ranked by BM25 score (highest first).
|
|
6027
|
-
* Returns an empty array if the index is empty or the query matches nothing.
|
|
6028
|
-
*/
|
|
6029
5931
|
search(query, limit) {
|
|
6030
5932
|
const n = this.tf.length;
|
|
6031
5933
|
if (n === 0) return [];
|
|
@@ -6066,26 +5968,12 @@ const PINNED_TOOLS_SOFT_LIMIT = 8;
|
|
|
6066
5968
|
const PINNED_TOOLS_HARD_LIMIT = 16;
|
|
6067
5969
|
const FIND_TOOLS_NAME = "find_tools";
|
|
6068
5970
|
const FIND_TOOLS_DEFAULT_LIMIT = 5;
|
|
6069
|
-
/**
|
|
6070
|
-
* Default tool-loading strategy: BM25-indexed MCP tool deferral via a `find_tools` meta-tool.
|
|
6071
|
-
*
|
|
6072
|
-
* - Node-backed tools and pinned MCP tools are always included in every turn.
|
|
6073
|
-
* - `find_tools(query, limit?)` is added to the tool set when MCP tools are indexed.
|
|
6074
|
-
* - Tools surfaced by `find_tools` are included in subsequent turns.
|
|
6075
|
-
*
|
|
6076
|
-
* Not DI-managed; instantiated per agent execution by DeferredMetaToolStrategyFactory.
|
|
6077
|
-
*/
|
|
6078
5971
|
var DeferredMetaToolStrategy = class {
|
|
6079
5972
|
nodeBackedTools = {};
|
|
6080
5973
|
pinnedTools = {};
|
|
6081
5974
|
mcpEntries = [];
|
|
6082
5975
|
toolsByServerId = /* @__PURE__ */ new Map();
|
|
6083
5976
|
foundToolIds = /* @__PURE__ */ new Set();
|
|
6084
|
-
/**
|
|
6085
|
-
* `jsonSchema` from the `ai` SDK, loaded lazily in {@link initialize} so the SDK
|
|
6086
|
-
* (~28MB RSS) stays off the boot path. `initialize` always runs before the sync
|
|
6087
|
-
* `getToolsForTurn` → `buildFindToolsDefinition` path, so this is set before use.
|
|
6088
|
-
*/
|
|
6089
5977
|
jsonSchema;
|
|
6090
5978
|
constructor(bm25, warnFn) {
|
|
6091
5979
|
this.bm25 = bm25;
|
|
@@ -6233,11 +6121,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6233
6121
|
inputSchema = unknown();
|
|
6234
6122
|
connectionCredentialExecutionContextFactory;
|
|
6235
6123
|
preparedByExecutionContext = /* @__PURE__ */ new WeakMap();
|
|
6236
|
-
/**
|
|
6237
|
-
* The `ai` SDK, loaded lazily in {@link execute} so the SDK (~28MB RSS) stays
|
|
6238
|
-
* off the boot path — non-AI workflows never load it. Every path runs through
|
|
6239
|
-
* `execute` → `ensureAiSdk` before any sync helper touches `this.aiSdk`.
|
|
6240
|
-
*/
|
|
6241
6124
|
aiSdk;
|
|
6242
6125
|
aiSdkPromise = null;
|
|
6243
6126
|
constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner, toolExecutionCoordinator, toolLoadingStrategyFactory, agentMcpIntegration) {
|
|
@@ -6261,15 +6144,9 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6261
6144
|
};
|
|
6262
6145
|
return (await this.runAgentForItem(prepared, itemWithMappedJson, args.itemIndex, args.items)).json;
|
|
6263
6146
|
}
|
|
6264
|
-
/** Load the `ai` SDK once per node instance (cached promise guards concurrent items). */
|
|
6265
6147
|
async ensureAiSdk() {
|
|
6266
6148
|
this.aiSdk = await (this.aiSdkPromise ??= import("ai"));
|
|
6267
6149
|
}
|
|
6268
|
-
/**
|
|
6269
|
-
* Resume path: re-enters the agent loop after a HITL suspension.
|
|
6270
|
-
* Reconstructs the conversation from the checkpoint, injects the human decision
|
|
6271
|
-
* as a tool_result, and continues the loop from where it suspended.
|
|
6272
|
-
*/
|
|
6273
6150
|
async executeResumed(args, resumeContext) {
|
|
6274
6151
|
const { ctx } = args;
|
|
6275
6152
|
const taskMetadata = resumeContext.task.metadata ?? {};
|
|
@@ -6296,7 +6173,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6296
6173
|
result: decision,
|
|
6297
6174
|
serialized: JSON.stringify(decision)
|
|
6298
6175
|
};
|
|
6299
|
-
const conversation = [...checkpoint.conversation, AgentMessageFactory.createToolResultsMessage([toolResultEntry])];
|
|
6176
|
+
const conversation = [...checkpoint.conversation, AgentMessageFactory.createToolResultsMessage([toolResultEntry], ctx.config.passToolBinariesToModel !== false)];
|
|
6300
6177
|
const loopResult = await this.runTurnLoopUntilFinalAnswer({
|
|
6301
6178
|
prepared,
|
|
6302
6179
|
itemInputsByPort,
|
|
@@ -6316,10 +6193,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6316
6193
|
const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalText, itemScopedTools.length > 0);
|
|
6317
6194
|
return this.buildOutputItem(item, outputJson).json;
|
|
6318
6195
|
}
|
|
6319
|
-
/**
|
|
6320
|
-
* Normalizes a {@link ResumeContext} decision into a flat JSON-serializable shape
|
|
6321
|
-
* suitable for injection as a tool_result content.
|
|
6322
|
-
*/
|
|
6323
6196
|
normalizeDecision(resumeContext) {
|
|
6324
6197
|
const { decision } = resumeContext;
|
|
6325
6198
|
if (decision.kind === "decided") {
|
|
@@ -6446,16 +6319,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6446
6319
|
const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalText, itemScopedTools.length > 0);
|
|
6447
6320
|
return this.buildOutputItem(item, outputJson);
|
|
6448
6321
|
}
|
|
6449
|
-
/**
|
|
6450
|
-
* Multi-turn loop:
|
|
6451
|
-
* - Each turn is a single `generateText` call with tools exposed but **not auto-executed**
|
|
6452
|
-
* (we control tool dispatch so that {@link AgentToolExecutionCoordinator} drives repair /
|
|
6453
|
-
* connection-invocation recording / transient-error handling exactly like before).
|
|
6454
|
-
* - When the model returns no tool calls the loop ends with the model's text as the final answer.
|
|
6455
|
-
* - Respects `guardrails.maxTurns` and `guardrails.onTurnLimitReached`.
|
|
6456
|
-
* - Strategy-owned tool calls (e.g. `find_tools`) are dispatched via the strategy, not the
|
|
6457
|
-
* coordinator; their results are tracked so subsequent turns receive the discovered tools.
|
|
6458
|
-
*/
|
|
6459
6322
|
async runTurnLoopUntilFinalAnswer(args) {
|
|
6460
6323
|
const { prepared, itemInputsByPort, itemScopedTools, conversation } = args;
|
|
6461
6324
|
const { ctx, guardrails, toolLoadingStrategy } = prepared;
|
|
@@ -6463,7 +6326,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6463
6326
|
let toolCallCount = args.resumedToolCallCount ?? 0;
|
|
6464
6327
|
let turnCount = 0;
|
|
6465
6328
|
const repairAttemptsByToolName = /* @__PURE__ */ new Map();
|
|
6466
|
-
/** Tool IDs surfaced by find_tools across all prior turns in this item run. */
|
|
6467
6329
|
let previousFoundToolIds = [];
|
|
6468
6330
|
for (let turn = 1; turn <= guardrails.maxTurns; turn++) {
|
|
6469
6331
|
turnCount = turn;
|
|
@@ -6516,7 +6378,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6516
6378
|
coordinatorExecutedCalls.push(...executed);
|
|
6517
6379
|
}
|
|
6518
6380
|
const allExecutedCalls = [...strategyExecutedCalls, ...coordinatorExecutedCalls];
|
|
6519
|
-
this.appendAssistantAndToolMessages(conversation, result.assistantMessage, result.text, result.toolCalls, allExecutedCalls);
|
|
6381
|
+
this.appendAssistantAndToolMessages(conversation, result.assistantMessage, result.text, result.toolCalls, allExecutedCalls, ctx.config.passToolBinariesToModel !== false);
|
|
6520
6382
|
}
|
|
6521
6383
|
return {
|
|
6522
6384
|
finalText,
|
|
@@ -6531,8 +6393,8 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6531
6393
|
if (guardrails.onTurnLimitReached === "respondWithLastMessage") return;
|
|
6532
6394
|
throw new Error(`AIAgent "${ctx.config.name ?? ctx.nodeId}" reached maxTurns=${guardrails.maxTurns} before producing a final response.`);
|
|
6533
6395
|
}
|
|
6534
|
-
appendAssistantAndToolMessages(conversation, assistantMessage, text, toolCalls, executedToolCalls) {
|
|
6535
|
-
conversation.push(assistantMessage ?? AgentMessageFactory.createAssistantWithToolCalls(text, toolCalls), AgentMessageFactory.createToolResultsMessage(executedToolCalls));
|
|
6396
|
+
appendAssistantAndToolMessages(conversation, assistantMessage, text, toolCalls, executedToolCalls, passToolBinariesToModel) {
|
|
6397
|
+
conversation.push(assistantMessage ?? AgentMessageFactory.createAssistantWithToolCalls(text, toolCalls), AgentMessageFactory.createToolResultsMessage(executedToolCalls, passToolBinariesToModel));
|
|
6536
6398
|
}
|
|
6537
6399
|
async resolveFinalOutputJson(prepared, itemInputsByPort, conversation, finalText, wasToolEnabledRun) {
|
|
6538
6400
|
if (!prepared.ctx.config.outputSchema) return AgentOutputFactory.fromAgentContent(finalText);
|
|
@@ -6593,12 +6455,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6593
6455
|
};
|
|
6594
6456
|
});
|
|
6595
6457
|
}
|
|
6596
|
-
/**
|
|
6597
|
-
* Resolves the HITL behavior for a tool binding, or `undefined` when it is not a HITL tool.
|
|
6598
|
-
* A binding is HITL if either the backing node carries a `defineHumanApprovalNode` marker or the
|
|
6599
|
-
* binding sets a per-binding `onRejected` via `asTool(..., { onRejected })`. The per-binding value
|
|
6600
|
-
* wins over the node marker, so two tools backed by the same node can reject differently.
|
|
6601
|
-
*/
|
|
6602
6458
|
resolveHumanApprovalBehavior(config$1) {
|
|
6603
6459
|
if (!this.isNodeBackedToolConfig(config$1)) return void 0;
|
|
6604
6460
|
const marker = config$1.node.humanApprovalToolBehavior;
|
|
@@ -6606,11 +6462,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6606
6462
|
if (marker === void 0 && perBinding === void 0) return void 0;
|
|
6607
6463
|
return { onRejected: perBinding ?? marker?.onRejected ?? "return" };
|
|
6608
6464
|
}
|
|
6609
|
-
/**
|
|
6610
|
-
* Invoke a text turn using the merged tool set from item-scoped tools (coordinator-managed)
|
|
6611
|
-
* and strategy tools (find_tools + discovered MCP tools).
|
|
6612
|
-
* Strategy tools take precedence for names that overlap.
|
|
6613
|
-
*/
|
|
6614
6465
|
async invokeTextTurnWithStrategyTools(prepared, itemInputsByPort, messages, itemScopedTools, strategyTools) {
|
|
6615
6466
|
const itemToolSet = this.buildToolSet(itemScopedTools);
|
|
6616
6467
|
const strategyHasTools = Object.keys(strategyTools).length > 0;
|
|
@@ -6621,10 +6472,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6621
6472
|
} : void 0;
|
|
6622
6473
|
return this.invokeTextTurnWithToolSet(prepared, itemInputsByPort, messages, mergedTools);
|
|
6623
6474
|
}
|
|
6624
|
-
/**
|
|
6625
|
-
* Removes `execute` properties from ToolSet entries so the AI SDK does not
|
|
6626
|
-
* auto-execute them within `generateText`. Codemation owns all tool dispatch.
|
|
6627
|
-
*/
|
|
6628
6475
|
stripExecuteCallbacks(tools) {
|
|
6629
6476
|
const stripped = {};
|
|
6630
6477
|
for (const [name, def] of Object.entries(tools)) {
|
|
@@ -6633,12 +6480,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6633
6480
|
}
|
|
6634
6481
|
return stripped;
|
|
6635
6482
|
}
|
|
6636
|
-
/**
|
|
6637
|
-
* Builds a ToolSet from resolved tools for strategy initialization.
|
|
6638
|
-
* The strategy uses this for its "always-included" node-backed tool descriptions.
|
|
6639
|
-
* HITL tools (detected via the `humanApprovalToolBehavior` field set by `defineHumanApprovalNode`) get the solo-constraint sentence
|
|
6640
|
-
* appended to their description.
|
|
6641
|
-
*/
|
|
6642
6483
|
buildToolSetFromResolved(resolvedTools) {
|
|
6643
6484
|
if (resolvedTools.length === 0) return {};
|
|
6644
6485
|
const toolSet = {};
|
|
@@ -6656,20 +6497,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6656
6497
|
}
|
|
6657
6498
|
return toolSet;
|
|
6658
6499
|
}
|
|
6659
|
-
/**
|
|
6660
|
-
* Builds an AI SDK {@link ToolSet} where every tool ships a pre-converted JSON Schema (via
|
|
6661
|
-
* {@link jsonSchema}) — not the raw Zod schema — and carries **no** `execute`. Two reasons:
|
|
6662
|
-
*
|
|
6663
|
-
* 1. Codemation owns tool dispatch + the per-tool repair loop (see {@link AgentToolExecutionCoordinator}),
|
|
6664
|
-
* so the AI SDK must surface tool calls back to us instead of auto-running them.
|
|
6665
|
-
* 2. The AI SDK's `asSchema` helper discriminates between Zod v3 / Zod v4 / Standard Schema via
|
|
6666
|
-
* runtime feature-detection (`~standard`, `_zod`, etc.). Handing it a pre-built
|
|
6667
|
-
* {@link jsonSchema} record — which is tagged with `Symbol.for('vercel.ai.schema')` — skips all
|
|
6668
|
-
* of that detection and guarantees the provider receives a draft-07 JSON Schema with
|
|
6669
|
-
* `additionalProperties: false` at every object depth (see {@link OpenAiStrictJsonSchemaFactory}
|
|
6670
|
-
* for the same logic applied to structured-output schemas). Codemation still runs its own Zod
|
|
6671
|
-
* validation on tool inputs before execute — the schema handed to the model is advisory.
|
|
6672
|
-
*/
|
|
6673
6500
|
buildToolSet(itemScopedTools) {
|
|
6674
6501
|
if (itemScopedTools.length === 0) return void 0;
|
|
6675
6502
|
const toolSet = {};
|
|
@@ -6687,10 +6514,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6687
6514
|
}
|
|
6688
6515
|
return toolSet;
|
|
6689
6516
|
}
|
|
6690
|
-
/**
|
|
6691
|
-
* One `generateText` turn (no auto tool execution) with Codemation-owned child-span telemetry
|
|
6692
|
-
* and connection-invocation state recording. Accepts a pre-built ToolSet.
|
|
6693
|
-
*/
|
|
6694
6517
|
async invokeTextTurnWithToolSet(prepared, itemInputsByPort, messages, tools) {
|
|
6695
6518
|
const invocationId = ConnectionInvocationIdFactory.create();
|
|
6696
6519
|
const startedAt = /* @__PURE__ */ new Date();
|
|
@@ -6801,11 +6624,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6801
6624
|
});
|
|
6802
6625
|
}
|
|
6803
6626
|
}
|
|
6804
|
-
/**
|
|
6805
|
-
* Structured-output turn: runs `generateText({ output: Output.object({ schema }) })` via the
|
|
6806
|
-
* structured-output runner. We keep this as a separate helper because the runner needs the raw
|
|
6807
|
-
* validated value (not just text) back, and must be able to retry on Zod failures.
|
|
6808
|
-
*/
|
|
6809
6627
|
async invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions) {
|
|
6810
6628
|
const invocationId = ConnectionInvocationIdFactory.create();
|
|
6811
6629
|
const startedAt = /* @__PURE__ */ new Date();
|
|
@@ -6930,13 +6748,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6930
6748
|
providerOptions: overrides?.providerOptions ?? defaults.providerOptions
|
|
6931
6749
|
};
|
|
6932
6750
|
}
|
|
6933
|
-
/**
|
|
6934
|
-
* Build a no-code-friendly output payload for an LLM round.
|
|
6935
|
-
*
|
|
6936
|
-
* Always includes `content` (matching the canvas snapshot shape used elsewhere) and adds a
|
|
6937
|
-
* `toolCalls` array when the round produced tool calls so the execution inspector surfaces the
|
|
6938
|
-
* planned calls instead of just an empty `""` for tool-only rounds.
|
|
6939
|
-
*/
|
|
6940
6751
|
summarizeTurnOutput(turnResult) {
|
|
6941
6752
|
if (turnResult.toolCalls.length === 0) return { content: turnResult.text };
|
|
6942
6753
|
const toolCalls = turnResult.toolCalls.map((toolCall) => ({
|
|
@@ -7139,12 +6950,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
7139
6950
|
const binaries = await this.resolveInlineBinaries(attachments, ctx);
|
|
7140
6951
|
return AgentBinaryContentFactory.withBinaries(promptMessages, binaries);
|
|
7141
6952
|
}
|
|
7142
|
-
/**
|
|
7143
|
-
* Picks which attachments feed the passdown. When the author supplies `config.binaries`
|
|
7144
|
-
* (a static array or a per-item function — e.g. to forward binaries from an earlier node),
|
|
7145
|
-
* those replace the current item's attachments; otherwise the current item's `item.binary`
|
|
7146
|
-
* is used.
|
|
7147
|
-
*/
|
|
7148
6953
|
selectBinaryAttachments(item, itemIndex, items, ctx) {
|
|
7149
6954
|
const manual = ctx.config.binaries;
|
|
7150
6955
|
if (manual !== void 0) return typeof manual === "function" ? manual({
|
|
@@ -7155,14 +6960,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
7155
6960
|
}) : manual;
|
|
7156
6961
|
return item.binary ? Object.values(item.binary) : [];
|
|
7157
6962
|
}
|
|
7158
|
-
/**
|
|
7159
|
-
* Reads every attachment through `ctx.binary` (storage-backed, by reference — never base64 on
|
|
7160
|
-
* `item.json`) and resolves it to inline base64 so the agent can pass it to the chat model as a
|
|
7161
|
-
* native multimodal block. Images become image blocks; every other type (PDF, office docs, CSV,
|
|
7162
|
-
* JSON, …) becomes a file block — we don't filter by media type, so any binary can be fed to the
|
|
7163
|
-
* model. If the provider rejects an unsupported type the error surfaces at runtime, and the
|
|
7164
|
-
* workflow can filter the binary upstream.
|
|
7165
|
-
*/
|
|
7166
6963
|
async resolveInlineBinaries(attachments, ctx) {
|
|
7167
6964
|
const resolved = [];
|
|
7168
6965
|
for (const attachment of attachments) {
|
|
@@ -7175,12 +6972,6 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
7175
6972
|
}
|
|
7176
6973
|
return resolved;
|
|
7177
6974
|
}
|
|
7178
|
-
/**
|
|
7179
|
-
* When `item.json.__source` matches an entry in `config.untrustedSources`
|
|
7180
|
-
* (default: `["gmail", "ocr", "webhook"]`), wraps every user-role message
|
|
7181
|
-
* content with an untrusted-external-source preamble so the LLM treats the
|
|
7182
|
-
* content as data, not instructions.
|
|
7183
|
-
*/
|
|
7184
6975
|
wrapUntrustedSourceMessages(messages, item, config$1) {
|
|
7185
6976
|
const source = item.json !== null && typeof item.json === "object" ? item.json.__source : void 0;
|
|
7186
6977
|
if (typeof source !== "string") return messages;
|
|
@@ -7273,10 +7064,6 @@ AIAgentNode = __decorate([
|
|
|
7273
7064
|
|
|
7274
7065
|
//#endregion
|
|
7275
7066
|
//#region src/nodes/AIAgentConfig.ts
|
|
7276
|
-
/**
|
|
7277
|
-
* AI agent: credential bindings are keyed to connection-owned LLM/tool node ids (ConnectionNodeIdFactory),
|
|
7278
|
-
* not to the agent workflow node id.
|
|
7279
|
-
*/
|
|
7280
7067
|
var AIAgent = class {
|
|
7281
7068
|
kind = "node";
|
|
7282
7069
|
type = AIAgentNode;
|
|
@@ -7296,6 +7083,7 @@ var AIAgent = class {
|
|
|
7296
7083
|
pinnedMcpTools;
|
|
7297
7084
|
untrustedSources;
|
|
7298
7085
|
passBinariesToModel;
|
|
7086
|
+
passToolBinariesToModel;
|
|
7299
7087
|
binaries;
|
|
7300
7088
|
constructor(options) {
|
|
7301
7089
|
this.name = options.name;
|
|
@@ -7312,6 +7100,7 @@ var AIAgent = class {
|
|
|
7312
7100
|
this.pinnedMcpTools = options.pinnedMcpTools;
|
|
7313
7101
|
this.untrustedSources = options.untrustedSources;
|
|
7314
7102
|
this.passBinariesToModel = options.passBinariesToModel;
|
|
7103
|
+
this.passToolBinariesToModel = options.passToolBinariesToModel;
|
|
7315
7104
|
this.binaries = options.binaries;
|
|
7316
7105
|
}
|
|
7317
7106
|
inspectorSummary() {
|
|
@@ -7372,11 +7161,6 @@ AssertionNode = __decorate([node({ packageName: "@codemation/core-nodes" })], As
|
|
|
7372
7161
|
|
|
7373
7162
|
//#endregion
|
|
7374
7163
|
//#region src/nodes/assertion.ts
|
|
7375
|
-
/**
|
|
7376
|
-
* Generic assertion node — the "callback" form. For declarative shorthands (StringEquals,
|
|
7377
|
-
* JudgeByAgent) compose this with helpers added in later phases. Sets `emitsAssertions: true`
|
|
7378
|
-
* so host-side persisters know to record its outputs as `TestAssertion` rows.
|
|
7379
|
-
*/
|
|
7380
7164
|
var Assertion = class {
|
|
7381
7165
|
kind = "node";
|
|
7382
7166
|
type = AssertionNode;
|
|
@@ -7639,17 +7423,12 @@ HttpRequestNode = __decorate([node({ packageName: "@codemation/core-nodes" })],
|
|
|
7639
7423
|
|
|
7640
7424
|
//#endregion
|
|
7641
7425
|
//#region src/nodes/httpRequest.ts
|
|
7642
|
-
/**
|
|
7643
|
-
* The built-in HTTP request credential type IDs accepted by the `HttpRequest` node.
|
|
7644
|
-
* These match the four generic credential types shipped with `@codemation/core-nodes`.
|
|
7645
|
-
*/
|
|
7646
7426
|
const HTTP_REQUEST_ACCEPTED_CREDENTIAL_TYPES = [
|
|
7647
7427
|
bearerTokenCredentialType.definition.typeId,
|
|
7648
7428
|
apiKeyCredentialType.definition.typeId,
|
|
7649
7429
|
basicAuthCredentialType.definition.typeId,
|
|
7650
7430
|
oauth2ClientCredentialsType.definition.typeId
|
|
7651
7431
|
];
|
|
7652
|
-
/** Default maximum response size for binary mode: 100 MiB. */
|
|
7653
7432
|
const DEFAULT_RESPONSE_SIZE_CAP_BYTES = 100 * 1024 * 1024;
|
|
7654
7433
|
var HttpRequest = class {
|
|
7655
7434
|
kind = "node";
|
|
@@ -7818,9 +7597,6 @@ var Filter = class {
|
|
|
7818
7597
|
function getOriginIndex(item) {
|
|
7819
7598
|
return getOriginIndexFromItem(item);
|
|
7820
7599
|
}
|
|
7821
|
-
/**
|
|
7822
|
-
* Tags items routed to fan-in merge-by-origin (same contract as {@link IfNode} / {@link SwitchNode}).
|
|
7823
|
-
*/
|
|
7824
7600
|
function tagItemForRouterFanIn(args) {
|
|
7825
7601
|
const { item, itemIndex, nodeId, inputPortLabel = "$in" } = args;
|
|
7826
7602
|
const metaBase = item.meta && typeof item.meta === "object" ? item.meta : {};
|
|
@@ -7911,10 +7687,6 @@ IsTestRunNode = __decorate([node({ packageName: "@codemation/core-nodes" })], Is
|
|
|
7911
7687
|
|
|
7912
7688
|
//#endregion
|
|
7913
7689
|
//#region src/nodes/isTestRun.ts
|
|
7914
|
-
/**
|
|
7915
|
-
* Branches per-item on whether the current run is a test run. Output ports: `true`, `false`.
|
|
7916
|
-
* The wire payload is unchanged — this is a router, not a transform.
|
|
7917
|
-
*/
|
|
7918
7690
|
var IsTestRun = class {
|
|
7919
7691
|
kind = "node";
|
|
7920
7692
|
type = IsTestRunNode;
|
|
@@ -7998,10 +7770,6 @@ var Split = class {
|
|
|
7998
7770
|
type = SplitNode;
|
|
7999
7771
|
execution = { hint: "local" };
|
|
8000
7772
|
keepBinaries = true;
|
|
8001
|
-
/**
|
|
8002
|
-
* When splitting yields zero items for a batch, downstream single-input nodes still run once with an empty batch.
|
|
8003
|
-
* Mirrors {@link MapData}'s empty-output behavior.
|
|
8004
|
-
*/
|
|
8005
7773
|
continueWhenEmptyOutput = true;
|
|
8006
7774
|
icon = "builtin:split-rows";
|
|
8007
7775
|
id;
|
|
@@ -8055,15 +7823,6 @@ CronTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })],
|
|
|
8055
7823
|
|
|
8056
7824
|
//#endregion
|
|
8057
7825
|
//#region src/nodes/CronTriggerFactory.ts
|
|
8058
|
-
/**
|
|
8059
|
-
* Schedules a workflow on a standard cron expression.
|
|
8060
|
-
*
|
|
8061
|
-
* Each tick emits one item: `{ firedAt: string, scheduledFor: string }` — both ISO-8601 timestamps.
|
|
8062
|
-
* `firedAt` is the wall-clock moment the callback ran; `scheduledFor` is the cron-computed
|
|
8063
|
-
* firing instant (these differ when the job was delayed).
|
|
8064
|
-
*
|
|
8065
|
-
* Timezone defaults to UTC when omitted — cron without an explicit TZ is a DST footgun.
|
|
8066
|
-
*/
|
|
8067
7826
|
var CronTrigger = class {
|
|
8068
7827
|
kind = "trigger";
|
|
8069
7828
|
type = CronTriggerNode;
|
|
@@ -8134,7 +7893,6 @@ var ManualTrigger = class ManualTrigger {
|
|
|
8134
7893
|
defaultItems;
|
|
8135
7894
|
id;
|
|
8136
7895
|
description;
|
|
8137
|
-
/** Manual runs often emit an empty batch; still schedule downstream by default. */
|
|
8138
7896
|
continueWhenEmptyOutput = true;
|
|
8139
7897
|
constructor(name = "Manual trigger", defaultItemsOrId, idOrOptions) {
|
|
8140
7898
|
this.name = name;
|
|
@@ -8189,7 +7947,6 @@ var MapData = class {
|
|
|
8189
7947
|
kind = "node";
|
|
8190
7948
|
type = MapDataNode;
|
|
8191
7949
|
execution = { hint: "local" };
|
|
8192
|
-
/** Zero mapped items should still allow downstream nodes to run. */
|
|
8193
7950
|
continueWhenEmptyOutput = true;
|
|
8194
7951
|
icon = "lucide:square-pen";
|
|
8195
7952
|
keepBinaries;
|
|
@@ -8422,11 +8179,6 @@ TestTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })],
|
|
|
8422
8179
|
|
|
8423
8180
|
//#endregion
|
|
8424
8181
|
//#region src/nodes/testTrigger.ts
|
|
8425
|
-
/**
|
|
8426
|
-
* Trigger config for a test fixture source. Drop one (or more) of these on the canvas alongside
|
|
8427
|
-
* a workflow's live triggers; clicking "Run tests" on the Tests tab invokes
|
|
8428
|
-
* {@link TestTriggerOptions.generateItems} via the TestSuiteOrchestrator.
|
|
8429
|
-
*/
|
|
8430
8182
|
var TestTrigger = class {
|
|
8431
8183
|
kind = "trigger";
|
|
8432
8184
|
triggerKind = "test";
|
|
@@ -8500,7 +8252,6 @@ var Wait = class {
|
|
|
8500
8252
|
kind = "node";
|
|
8501
8253
|
type = WaitNode;
|
|
8502
8254
|
execution = { hint: "local" };
|
|
8503
|
-
/** Pass-through empty batches should still advance to downstream nodes. */
|
|
8504
8255
|
continueWhenEmptyOutput = true;
|
|
8505
8256
|
icon = "lucide:hourglass";
|
|
8506
8257
|
id;
|
|
@@ -8602,6 +8353,39 @@ var WebhookTrigger = class WebhookTrigger {
|
|
|
8602
8353
|
}
|
|
8603
8354
|
};
|
|
8604
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
|
+
|
|
8605
8389
|
//#endregion
|
|
8606
8390
|
//#region src/nodes/ConnectionCredentialNode.ts
|
|
8607
8391
|
let ConnectionCredentialNode = class ConnectionCredentialNode$1 {
|
|
@@ -8615,11 +8399,6 @@ ConnectionCredentialNode = __decorate([node({ packageName: "@codemation/core-nod
|
|
|
8615
8399
|
|
|
8616
8400
|
//#endregion
|
|
8617
8401
|
//#region src/register.types.ts
|
|
8618
|
-
/**
|
|
8619
|
-
* Registrar for built-in nodes. In a real project, this would use tsyringe's
|
|
8620
|
-
* container.registerSingleton(...). For the skeleton we keep it token-based:
|
|
8621
|
-
* the engine resolves node implementations by class token.
|
|
8622
|
-
*/
|
|
8623
8402
|
function registerCoreNodes(container) {}
|
|
8624
8403
|
|
|
8625
8404
|
//#endregion
|
|
@@ -8848,9 +8627,6 @@ function workflow(id) {
|
|
|
8848
8627
|
|
|
8849
8628
|
//#endregion
|
|
8850
8629
|
//#region src/workflows/AIAgentConnectionWorkflowExpander.ts
|
|
8851
|
-
/**
|
|
8852
|
-
* Materializes connection-owned child nodes and {@link WorkflowDefinition.connections} for AI agent nodes.
|
|
8853
|
-
*/
|
|
8854
8630
|
var AIAgentConnectionWorkflowExpander = class {
|
|
8855
8631
|
constructor(connectionCredentialNodeConfigFactory, mcpServerResolver) {
|
|
8856
8632
|
this.connectionCredentialNodeConfigFactory = connectionCredentialNodeConfigFactory;
|
|
@@ -9118,16 +8894,6 @@ const collectionDeleteNode = defineNode({
|
|
|
9118
8894
|
function resolveSubjectField(field, item) {
|
|
9119
8895
|
return typeof field === "function" ? field({ item }) : field;
|
|
9120
8896
|
}
|
|
9121
|
-
/**
|
|
9122
|
-
* Auto-detecting inbox approval node.
|
|
9123
|
-
*
|
|
9124
|
-
* Uses `ctx.resolve(InboxChannelResolverToken)` to pick the right inbox channel
|
|
9125
|
-
* at runtime:
|
|
9126
|
-
* - In managed mode (PairingConfig present): routes to the control-plane inbox.
|
|
9127
|
-
* - Otherwise: routes to the local inbox.
|
|
9128
|
-
*
|
|
9129
|
-
* Authors use this node directly; no extra wiring needed per deployment mode.
|
|
9130
|
-
*/
|
|
9131
8897
|
const inboxApproval = defineHumanApprovalNode({
|
|
9132
8898
|
key: "inbox.approval",
|
|
9133
8899
|
title: "Inbox Approval",
|
|
@@ -9281,5 +9047,5 @@ const codemationDocumentScannerNode = defineNode({
|
|
|
9281
9047
|
});
|
|
9282
9048
|
|
|
9283
9049
|
//#endregion
|
|
9284
|
-
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 };
|
|
9285
9051
|
//# sourceMappingURL=index.js.map
|