@codemation/core-nodes 0.10.2 → 0.13.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 +122 -0
- package/dist/index.cjs +427 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +205 -67
- package/dist/index.d.ts +206 -68
- package/dist/index.js +427 -99
- package/dist/index.js.map +1 -1
- package/dist/metadata.json +1 -1
- package/package.json +3 -2
- package/src/chatModels/CodemationChatModelConfig.ts +9 -21
- package/src/chatModels/CodemationChatModelFactory.ts +12 -9
- package/src/chatModels/OpenAIChatModelFactory.ts +3 -2
- package/src/index.ts +1 -1
- package/src/nodes/AIAgentConfig.ts +36 -0
- package/src/nodes/AIAgentNode.ts +81 -15
- package/src/nodes/AgentBinaryContentFactory.ts +74 -0
- package/src/nodes/AgentMessageFactory.ts +22 -6
- package/src/nodes/AgentToolResultContentFactory.ts +155 -0
- package/src/nodes/CallbackNodeFactory.ts +9 -6
- package/src/nodes/CronTriggerFactory.ts +6 -2
- package/src/nodes/DeferredMetaToolStrategy.ts +8 -2
- package/src/nodes/ManualTriggerFactory.ts +15 -11
- package/src/nodes/WebhookTriggerFactory.ts +9 -2
- package/src/nodes/aggregate.ts +9 -2
- package/src/nodes/assertion.ts +3 -0
- package/src/nodes/filter.ts +9 -2
- package/src/nodes/httpRequest.ts +6 -1
- package/src/nodes/if.ts +9 -2
- package/src/nodes/isTestRun.ts +6 -2
- package/src/nodes/mapData.ts +4 -2
- package/src/nodes/merge.ts +9 -2
- package/src/nodes/noOp.ts +9 -2
- package/src/nodes/nodeOptions.types.ts +12 -0
- package/src/nodes/split.ts +9 -2
- package/src/nodes/subWorkflow.ts +9 -2
- package/src/nodes/switch.ts +7 -1
- package/src/nodes/wait.ts +9 -2
- package/src/workflowAuthoring/WorkflowChatModelFactory.types.ts +8 -2
- package/src/chatModels/ManagedModelFetcher.ts +0 -23
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
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";
|
|
2
2
|
import dns from "node:dns/promises";
|
|
3
|
-
import { createOpenAI } from "@ai-sdk/openai";
|
|
4
3
|
import { CredentialResolverFactory } from "@codemation/core/bootstrap";
|
|
5
4
|
import { createHash, createHmac, randomBytes } from "node:crypto";
|
|
6
|
-
import { Output, generateText, jsonSchema } from "ai";
|
|
7
5
|
import { Cron } from "croner";
|
|
8
6
|
|
|
9
7
|
//#region src/credentials/ApiKeyCredentialType.ts
|
|
@@ -674,6 +672,7 @@ function __decorate(decorators, target, key, desc) {
|
|
|
674
672
|
let OpenAIChatModelFactory = class OpenAIChatModelFactory$1 {
|
|
675
673
|
async create(args) {
|
|
676
674
|
const session = await args.ctx.getCredential(args.config.credentialSlotKey);
|
|
675
|
+
const { createOpenAI } = await import("@ai-sdk/openai");
|
|
677
676
|
return {
|
|
678
677
|
languageModel: createOpenAI({
|
|
679
678
|
apiKey: session.apiKey,
|
|
@@ -4418,27 +4417,24 @@ function buildHmacAuthHeader(workspaceId, pairingSecret, method, url, body, over
|
|
|
4418
4417
|
//#endregion
|
|
4419
4418
|
//#region src/chatModels/CodemationChatModelFactory.ts
|
|
4420
4419
|
let CodemationChatModelFactory = class CodemationChatModelFactory$1 {
|
|
4421
|
-
create(args) {
|
|
4420
|
+
async create(args) {
|
|
4422
4421
|
const gatewayUrl = process.env["LLM_GATEWAY_URL"];
|
|
4423
4422
|
if (!gatewayUrl) throw new Error("Codemation managed AI not available in this environment (LLM_GATEWAY_URL is not set).");
|
|
4424
4423
|
const workspaceId = process.env["WORKSPACE_ID"];
|
|
4425
4424
|
const pairingSecret = process.env["WORKSPACE_PAIRING_SECRET"];
|
|
4426
4425
|
if (!workspaceId || !pairingSecret) throw new Error("Codemation managed AI not available in this environment (workspace pairing is not configured).");
|
|
4427
4426
|
const hmacFetch = managedHmacFetchFactory(workspaceId, pairingSecret);
|
|
4428
|
-
const
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
modelName: args.config.
|
|
4427
|
+
const { createAnthropic } = await import("@ai-sdk/anthropic");
|
|
4428
|
+
return {
|
|
4429
|
+
languageModel: createAnthropic({
|
|
4430
|
+
baseURL: `${gatewayUrl}/v1`,
|
|
4431
|
+
apiKey: "codemation-managed",
|
|
4432
|
+
fetch: hmacFetch
|
|
4433
|
+
})(args.config.complexity),
|
|
4434
|
+
modelName: args.config.complexity,
|
|
4436
4435
|
provider: "codemation-managed",
|
|
4437
|
-
defaultCallOptions: {
|
|
4438
|
-
|
|
4439
|
-
temperature: args.config.options?.temperature
|
|
4440
|
-
}
|
|
4441
|
-
});
|
|
4436
|
+
defaultCallOptions: { maxOutputTokens: args.config.options?.maxTokens }
|
|
4437
|
+
};
|
|
4442
4438
|
}
|
|
4443
4439
|
};
|
|
4444
4440
|
CodemationChatModelFactory = __decorate([chatModel({ packageName: "@codemation/core-nodes" })], CodemationChatModelFactory);
|
|
@@ -4450,11 +4446,11 @@ var CodemationChatModelConfig = class {
|
|
|
4450
4446
|
presentation;
|
|
4451
4447
|
provider = "codemation-managed";
|
|
4452
4448
|
modelName;
|
|
4453
|
-
constructor(name,
|
|
4449
|
+
constructor(name, complexity, presentationIn, options) {
|
|
4454
4450
|
this.name = name;
|
|
4455
|
-
this.
|
|
4451
|
+
this.complexity = complexity;
|
|
4456
4452
|
this.options = options;
|
|
4457
|
-
this.modelName =
|
|
4453
|
+
this.modelName = complexity;
|
|
4458
4454
|
this.presentation = presentationIn ?? {
|
|
4459
4455
|
icon: "lucide:bot",
|
|
4460
4456
|
label: name
|
|
@@ -4463,24 +4459,151 @@ var CodemationChatModelConfig = class {
|
|
|
4463
4459
|
};
|
|
4464
4460
|
|
|
4465
4461
|
//#endregion
|
|
4466
|
-
//#region src/
|
|
4462
|
+
//#region src/nodes/AgentToolResultContentFactory.ts
|
|
4467
4463
|
/**
|
|
4468
|
-
*
|
|
4469
|
-
*
|
|
4470
|
-
* Returns an empty array if the env var is absent or the fetch fails.
|
|
4471
|
-
* Cache the result per session — the allowlist changes infrequently.
|
|
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.
|
|
4472
4466
|
*/
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4467
|
+
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
|
+
const KNOWN_MCP_BLOCK_TYPES = new Set([
|
|
4470
|
+
"text",
|
|
4471
|
+
"image",
|
|
4472
|
+
"audio",
|
|
4473
|
+
"resource",
|
|
4474
|
+
"resource_link"
|
|
4475
|
+
]);
|
|
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
|
+
var AgentToolResultContentFactory = class AgentToolResultContentFactory {
|
|
4490
|
+
static tryMapToContentOutput(result) {
|
|
4491
|
+
const blocks = AgentToolResultContentFactory.contentBlocks(result);
|
|
4492
|
+
if (blocks === void 0) return void 0;
|
|
4493
|
+
const parts = [];
|
|
4494
|
+
let inlinedBytes = 0;
|
|
4495
|
+
for (const block of blocks) {
|
|
4496
|
+
const mapped = AgentToolResultContentFactory.mapBlock(block, inlinedBytes);
|
|
4497
|
+
parts.push(mapped.part);
|
|
4498
|
+
inlinedBytes += mapped.bytes;
|
|
4483
4499
|
}
|
|
4500
|
+
return parts;
|
|
4501
|
+
}
|
|
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
|
+
static contentBlocks(result) {
|
|
4509
|
+
if (result === null || typeof result !== "object") return void 0;
|
|
4510
|
+
const content = result.content;
|
|
4511
|
+
if (!Array.isArray(content) || content.length === 0) return void 0;
|
|
4512
|
+
if (!content.every((block) => block !== null && typeof block === "object" && typeof block.type === "string")) return void 0;
|
|
4513
|
+
return content.some((block) => KNOWN_MCP_BLOCK_TYPES.has(block.type)) ? content : void 0;
|
|
4514
|
+
}
|
|
4515
|
+
static mapBlock(block, inlinedBytesSoFar) {
|
|
4516
|
+
const type = block.type;
|
|
4517
|
+
if (type === "text" && typeof block.text === "string") return {
|
|
4518
|
+
part: {
|
|
4519
|
+
type: "text",
|
|
4520
|
+
text: block.text
|
|
4521
|
+
},
|
|
4522
|
+
bytes: 0
|
|
4523
|
+
};
|
|
4524
|
+
if (type === "image" && typeof block.data === "string" && typeof block.mimeType === "string") return AgentToolResultContentFactory.mapBinary({
|
|
4525
|
+
base64: block.data,
|
|
4526
|
+
mediaType: block.mimeType,
|
|
4527
|
+
inlinedBytesSoFar
|
|
4528
|
+
});
|
|
4529
|
+
if (type === "resource" && block.resource) return AgentToolResultContentFactory.mapEmbeddedResource(block.resource, inlinedBytesSoFar);
|
|
4530
|
+
if (type === "resource_link" && typeof block.uri === "string") {
|
|
4531
|
+
const mime = typeof block.mimeType === "string" ? ` (${block.mimeType})` : "";
|
|
4532
|
+
return {
|
|
4533
|
+
part: {
|
|
4534
|
+
type: "text",
|
|
4535
|
+
text: `[linked resource: ${block.uri}${mime}]`
|
|
4536
|
+
},
|
|
4537
|
+
bytes: 0
|
|
4538
|
+
};
|
|
4539
|
+
}
|
|
4540
|
+
return {
|
|
4541
|
+
part: {
|
|
4542
|
+
type: "text",
|
|
4543
|
+
text: `[unsupported tool content block: ${String(type)}]`
|
|
4544
|
+
},
|
|
4545
|
+
bytes: 0
|
|
4546
|
+
};
|
|
4547
|
+
}
|
|
4548
|
+
static mapEmbeddedResource(resource, inlinedBytesSoFar) {
|
|
4549
|
+
if (typeof resource.text === "string") return {
|
|
4550
|
+
part: {
|
|
4551
|
+
type: "text",
|
|
4552
|
+
text: resource.text
|
|
4553
|
+
},
|
|
4554
|
+
bytes: 0
|
|
4555
|
+
};
|
|
4556
|
+
if (typeof resource.blob === "string" && typeof resource.mimeType === "string") return AgentToolResultContentFactory.mapBinary({
|
|
4557
|
+
base64: resource.blob,
|
|
4558
|
+
mediaType: resource.mimeType,
|
|
4559
|
+
filename: typeof resource.name === "string" ? resource.name : void 0,
|
|
4560
|
+
inlinedBytesSoFar
|
|
4561
|
+
});
|
|
4562
|
+
return {
|
|
4563
|
+
part: {
|
|
4564
|
+
type: "text",
|
|
4565
|
+
text: `[embedded resource: ${typeof resource.uri === "string" ? resource.uri : "unknown"}]`
|
|
4566
|
+
},
|
|
4567
|
+
bytes: 0
|
|
4568
|
+
};
|
|
4569
|
+
}
|
|
4570
|
+
static mapBinary(args) {
|
|
4571
|
+
const rawBytes = Math.floor(args.base64.length * 3 / 4);
|
|
4572
|
+
if (args.inlinedBytesSoFar + rawBytes > MAX_INLINE_BYTES) {
|
|
4573
|
+
const name = args.filename ? ` "${args.filename}"` : "";
|
|
4574
|
+
const kb = Math.round(rawBytes / 1024);
|
|
4575
|
+
return {
|
|
4576
|
+
part: {
|
|
4577
|
+
type: "text",
|
|
4578
|
+
text: `[binary${name} (${args.mediaType}, ~${kb} KB) omitted: exceeds the per-tool-result inline limit]`
|
|
4579
|
+
},
|
|
4580
|
+
bytes: 0
|
|
4581
|
+
};
|
|
4582
|
+
}
|
|
4583
|
+
if (args.mediaType.startsWith("image/")) return {
|
|
4584
|
+
part: {
|
|
4585
|
+
type: "image-data",
|
|
4586
|
+
data: args.base64,
|
|
4587
|
+
mediaType: args.mediaType
|
|
4588
|
+
},
|
|
4589
|
+
bytes: rawBytes
|
|
4590
|
+
};
|
|
4591
|
+
if (args.mediaType === "application/pdf") return {
|
|
4592
|
+
part: {
|
|
4593
|
+
type: "file-data",
|
|
4594
|
+
data: args.base64,
|
|
4595
|
+
mediaType: args.mediaType,
|
|
4596
|
+
...args.filename ? { filename: args.filename } : {}
|
|
4597
|
+
},
|
|
4598
|
+
bytes: rawBytes
|
|
4599
|
+
};
|
|
4600
|
+
return {
|
|
4601
|
+
part: {
|
|
4602
|
+
type: "text",
|
|
4603
|
+
text: `[binary${args.filename ? ` "${args.filename}"` : ""} (${args.mediaType}) not inlined: unsupported by the model]`
|
|
4604
|
+
},
|
|
4605
|
+
bytes: 0
|
|
4606
|
+
};
|
|
4484
4607
|
}
|
|
4485
4608
|
};
|
|
4486
4609
|
|
|
@@ -4520,20 +4643,35 @@ var AgentMessageFactory = class AgentMessageFactory {
|
|
|
4520
4643
|
* Builds the `{ role: "tool", content: [{ type: "tool-result", ... }, ...] }` message returned
|
|
4521
4644
|
* to the model after each tool round.
|
|
4522
4645
|
*/
|
|
4523
|
-
static createToolResultsMessage(executedToolCalls) {
|
|
4646
|
+
static createToolResultsMessage(executedToolCalls, passToolBinariesToModel = true) {
|
|
4524
4647
|
return {
|
|
4525
4648
|
role: "tool",
|
|
4526
4649
|
content: executedToolCalls.map((executed) => ({
|
|
4527
4650
|
type: "tool-result",
|
|
4528
4651
|
toolCallId: executed.toolCallId,
|
|
4529
4652
|
toolName: executed.toolName,
|
|
4530
|
-
output:
|
|
4531
|
-
type: "json",
|
|
4532
|
-
value: AgentMessageFactory.toToolResultJson(executed.result)
|
|
4533
|
-
}
|
|
4653
|
+
output: AgentMessageFactory.toToolResultOutput(executed.result, passToolBinariesToModel)
|
|
4534
4654
|
}))
|
|
4535
4655
|
};
|
|
4536
4656
|
}
|
|
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
|
+
static toToolResultOutput(result, passToolBinariesToModel) {
|
|
4663
|
+
if (passToolBinariesToModel) {
|
|
4664
|
+
const content = AgentToolResultContentFactory.tryMapToContentOutput(result);
|
|
4665
|
+
if (content !== void 0) return {
|
|
4666
|
+
type: "content",
|
|
4667
|
+
value: content
|
|
4668
|
+
};
|
|
4669
|
+
}
|
|
4670
|
+
return {
|
|
4671
|
+
type: "json",
|
|
4672
|
+
value: AgentMessageFactory.toToolResultJson(result)
|
|
4673
|
+
};
|
|
4674
|
+
}
|
|
4537
4675
|
static toToolResultJson(value) {
|
|
4538
4676
|
if (value === void 0) return null;
|
|
4539
4677
|
try {
|
|
@@ -5852,6 +5990,63 @@ AgentToolExecutionCoordinator = __decorate([
|
|
|
5852
5990
|
__decorateMetadata("design:paramtypes", [typeof (_ref$2 = typeof AgentToolErrorClassifier !== "undefined" && AgentToolErrorClassifier) === "function" ? _ref$2 : Object, typeof (_ref2$2 = typeof AgentToolRepairPolicy !== "undefined" && AgentToolRepairPolicy) === "function" ? _ref2$2 : Object])
|
|
5853
5991
|
], AgentToolExecutionCoordinator);
|
|
5854
5992
|
|
|
5993
|
+
//#endregion
|
|
5994
|
+
//#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
|
+
var AgentBinaryContentFactory = class AgentBinaryContentFactory {
|
|
6006
|
+
static toContentPart(binary) {
|
|
6007
|
+
if (binary.mediaType.startsWith("image/")) return {
|
|
6008
|
+
type: "image",
|
|
6009
|
+
image: binary.base64,
|
|
6010
|
+
mediaType: binary.mediaType
|
|
6011
|
+
};
|
|
6012
|
+
return {
|
|
6013
|
+
type: "file",
|
|
6014
|
+
data: binary.base64,
|
|
6015
|
+
mediaType: binary.mediaType,
|
|
6016
|
+
...binary.filename ? { filename: binary.filename } : {}
|
|
6017
|
+
};
|
|
6018
|
+
}
|
|
6019
|
+
static withBinaries(messages, binaries) {
|
|
6020
|
+
if (binaries.length === 0) return messages;
|
|
6021
|
+
const parts = binaries.map((binary) => AgentBinaryContentFactory.toContentPart(binary));
|
|
6022
|
+
const lastUserIndex = AgentBinaryContentFactory.lastUserMessageIndex(messages);
|
|
6023
|
+
if (lastUserIndex === -1) {
|
|
6024
|
+
const appended = {
|
|
6025
|
+
role: "user",
|
|
6026
|
+
content: parts
|
|
6027
|
+
};
|
|
6028
|
+
return [...messages, appended];
|
|
6029
|
+
}
|
|
6030
|
+
const next = [...messages];
|
|
6031
|
+
next[lastUserIndex] = AgentBinaryContentFactory.appendPartsToUserMessage(messages[lastUserIndex], parts);
|
|
6032
|
+
return next;
|
|
6033
|
+
}
|
|
6034
|
+
static lastUserMessageIndex(messages) {
|
|
6035
|
+
for (let index = messages.length - 1; index >= 0; index--) if (messages[index]?.role === "user") return index;
|
|
6036
|
+
return -1;
|
|
6037
|
+
}
|
|
6038
|
+
static appendPartsToUserMessage(message, parts) {
|
|
6039
|
+
const existing = typeof message.content === "string" ? message.content.length > 0 ? [{
|
|
6040
|
+
type: "text",
|
|
6041
|
+
text: message.content
|
|
6042
|
+
}] : [] : message.content;
|
|
6043
|
+
return {
|
|
6044
|
+
...message,
|
|
6045
|
+
content: [...existing, ...parts]
|
|
6046
|
+
};
|
|
6047
|
+
}
|
|
6048
|
+
};
|
|
6049
|
+
|
|
5855
6050
|
//#endregion
|
|
5856
6051
|
//#region src/nodes/NodeBackedToolRuntime.ts
|
|
5857
6052
|
var _ref$1, _ref2$1, _ref3$1, _ref4$1;
|
|
@@ -6050,11 +6245,18 @@ var DeferredMetaToolStrategy = class {
|
|
|
6050
6245
|
mcpEntries = [];
|
|
6051
6246
|
toolsByServerId = /* @__PURE__ */ new Map();
|
|
6052
6247
|
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
|
+
jsonSchema;
|
|
6053
6254
|
constructor(bm25, warnFn) {
|
|
6054
6255
|
this.bm25 = bm25;
|
|
6055
6256
|
this.warnFn = warnFn;
|
|
6056
6257
|
}
|
|
6057
6258
|
async initialize(input) {
|
|
6259
|
+
this.jsonSchema = (await import("ai")).jsonSchema;
|
|
6058
6260
|
this.nodeBackedTools = { ...input.nodeBackedTools };
|
|
6059
6261
|
const pinnedIds = input.pinnedMcpTools ?? [];
|
|
6060
6262
|
if (pinnedIds.length > PINNED_TOOLS_HARD_LIMIT) throw new Error(`Agent config error: pinnedMcpTools count (${pinnedIds.length}) exceeds hard limit of ${PINNED_TOOLS_HARD_LIMIT}.`);
|
|
@@ -6142,25 +6344,26 @@ var DeferredMetaToolStrategy = class {
|
|
|
6142
6344
|
return [...this.foundToolIds];
|
|
6143
6345
|
}
|
|
6144
6346
|
buildFindToolsDefinition() {
|
|
6347
|
+
const inputSchemaRecord = {
|
|
6348
|
+
type: "object",
|
|
6349
|
+
properties: {
|
|
6350
|
+
query: {
|
|
6351
|
+
type: "string",
|
|
6352
|
+
description: "Natural language description of what you want to do."
|
|
6353
|
+
},
|
|
6354
|
+
limit: {
|
|
6355
|
+
type: "integer",
|
|
6356
|
+
minimum: 1,
|
|
6357
|
+
maximum: 10,
|
|
6358
|
+
description: `Maximum number of tools to return (default ${FIND_TOOLS_DEFAULT_LIMIT}).`
|
|
6359
|
+
}
|
|
6360
|
+
},
|
|
6361
|
+
required: ["query"],
|
|
6362
|
+
additionalProperties: false
|
|
6363
|
+
};
|
|
6145
6364
|
return {
|
|
6146
6365
|
description: "Search for tools available from connected MCP servers. After this call, the tools listed in the result will be callable on your very next turn. Use this when you need a capability not visible in your current tool list. Do not attempt to call a tool name you have not seen yet — use find_tools to discover it first.",
|
|
6147
|
-
inputSchema: jsonSchema(
|
|
6148
|
-
type: "object",
|
|
6149
|
-
properties: {
|
|
6150
|
-
query: {
|
|
6151
|
-
type: "string",
|
|
6152
|
-
description: "Natural language description of what you want to do."
|
|
6153
|
-
},
|
|
6154
|
-
limit: {
|
|
6155
|
-
type: "integer",
|
|
6156
|
-
minimum: 1,
|
|
6157
|
-
maximum: 10,
|
|
6158
|
-
description: `Maximum number of tools to return (default ${FIND_TOOLS_DEFAULT_LIMIT}).`
|
|
6159
|
-
}
|
|
6160
|
-
},
|
|
6161
|
-
required: ["query"],
|
|
6162
|
-
additionalProperties: false
|
|
6163
|
-
})
|
|
6366
|
+
inputSchema: this.jsonSchema(inputSchemaRecord)
|
|
6164
6367
|
};
|
|
6165
6368
|
}
|
|
6166
6369
|
};
|
|
@@ -6194,6 +6397,13 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6194
6397
|
inputSchema = unknown();
|
|
6195
6398
|
connectionCredentialExecutionContextFactory;
|
|
6196
6399
|
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
|
+
aiSdk;
|
|
6406
|
+
aiSdkPromise = null;
|
|
6197
6407
|
constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner, toolExecutionCoordinator, toolLoadingStrategyFactory, agentMcpIntegration) {
|
|
6198
6408
|
this.nodeResolver = nodeResolver;
|
|
6199
6409
|
this.nodeBackedToolRuntime = nodeBackedToolRuntime;
|
|
@@ -6206,6 +6416,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6206
6416
|
}
|
|
6207
6417
|
async execute(args) {
|
|
6208
6418
|
const { ctx } = args;
|
|
6419
|
+
await this.ensureAiSdk();
|
|
6209
6420
|
if (ctx.resumeContext) return this.executeResumed(args, ctx.resumeContext);
|
|
6210
6421
|
const prepared = await this.getOrPrepareExecution(ctx);
|
|
6211
6422
|
const itemWithMappedJson = {
|
|
@@ -6214,6 +6425,10 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6214
6425
|
};
|
|
6215
6426
|
return (await this.runAgentForItem(prepared, itemWithMappedJson, args.itemIndex, args.items)).json;
|
|
6216
6427
|
}
|
|
6428
|
+
/** Load the `ai` SDK once per node instance (cached promise guards concurrent items). */
|
|
6429
|
+
async ensureAiSdk() {
|
|
6430
|
+
this.aiSdk = await (this.aiSdkPromise ??= import("ai"));
|
|
6431
|
+
}
|
|
6217
6432
|
/**
|
|
6218
6433
|
* Resume path: re-enters the agent loop after a HITL suspension.
|
|
6219
6434
|
* Reconstructs the conversation from the checkpoint, injects the human decision
|
|
@@ -6245,7 +6460,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6245
6460
|
result: decision,
|
|
6246
6461
|
serialized: JSON.stringify(decision)
|
|
6247
6462
|
};
|
|
6248
|
-
const conversation = [...checkpoint.conversation, AgentMessageFactory.createToolResultsMessage([toolResultEntry])];
|
|
6463
|
+
const conversation = [...checkpoint.conversation, AgentMessageFactory.createToolResultsMessage([toolResultEntry], ctx.config.passToolBinariesToModel !== false)];
|
|
6249
6464
|
const loopResult = await this.runTurnLoopUntilFinalAnswer({
|
|
6250
6465
|
prepared,
|
|
6251
6466
|
itemInputsByPort,
|
|
@@ -6356,7 +6571,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6356
6571
|
const { ctx } = prepared;
|
|
6357
6572
|
const itemInputsByPort = AgentItemPortMap.fromItem(item);
|
|
6358
6573
|
const itemScopedTools = this.createItemScopedTools(prepared.resolvedTools, ctx, item, itemIndex, items);
|
|
6359
|
-
const conversation = [...this.createPromptMessages(item, itemIndex, items, ctx)];
|
|
6574
|
+
const conversation = [...await this.createPromptMessages(item, itemIndex, items, ctx)];
|
|
6360
6575
|
if (ctx.config.outputSchema && itemScopedTools.length === 0) {
|
|
6361
6576
|
const structuredOutput = await this.structuredOutputRunner.resolve({
|
|
6362
6577
|
model: prepared.model,
|
|
@@ -6465,7 +6680,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6465
6680
|
coordinatorExecutedCalls.push(...executed);
|
|
6466
6681
|
}
|
|
6467
6682
|
const allExecutedCalls = [...strategyExecutedCalls, ...coordinatorExecutedCalls];
|
|
6468
|
-
this.appendAssistantAndToolMessages(conversation, result.assistantMessage, result.text, result.toolCalls, allExecutedCalls);
|
|
6683
|
+
this.appendAssistantAndToolMessages(conversation, result.assistantMessage, result.text, result.toolCalls, allExecutedCalls, ctx.config.passToolBinariesToModel !== false);
|
|
6469
6684
|
}
|
|
6470
6685
|
return {
|
|
6471
6686
|
finalText,
|
|
@@ -6480,8 +6695,8 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6480
6695
|
if (guardrails.onTurnLimitReached === "respondWithLastMessage") return;
|
|
6481
6696
|
throw new Error(`AIAgent "${ctx.config.name ?? ctx.nodeId}" reached maxTurns=${guardrails.maxTurns} before producing a final response.`);
|
|
6482
6697
|
}
|
|
6483
|
-
appendAssistantAndToolMessages(conversation, assistantMessage, text, toolCalls, executedToolCalls) {
|
|
6484
|
-
conversation.push(assistantMessage ?? AgentMessageFactory.createAssistantWithToolCalls(text, toolCalls), AgentMessageFactory.createToolResultsMessage(executedToolCalls));
|
|
6698
|
+
appendAssistantAndToolMessages(conversation, assistantMessage, text, toolCalls, executedToolCalls, passToolBinariesToModel) {
|
|
6699
|
+
conversation.push(assistantMessage ?? AgentMessageFactory.createAssistantWithToolCalls(text, toolCalls), AgentMessageFactory.createToolResultsMessage(executedToolCalls, passToolBinariesToModel));
|
|
6485
6700
|
}
|
|
6486
6701
|
async resolveFinalOutputJson(prepared, itemInputsByPort, conversation, finalText, wasToolEnabledRun) {
|
|
6487
6702
|
if (!prepared.ctx.config.outputSchema) return AgentOutputFactory.fromAgentContent(finalText);
|
|
@@ -6600,7 +6815,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6600
6815
|
const description = this.resolveHumanApprovalBehavior(entry.config) !== void 0 ? `${baseDescription} ${HITL_SOLO_CONSTRAINT_SENTENCE}` : baseDescription;
|
|
6601
6816
|
toolSet[entry.config.name] = {
|
|
6602
6817
|
description,
|
|
6603
|
-
inputSchema: jsonSchema(schemaRecord)
|
|
6818
|
+
inputSchema: this.aiSdk.jsonSchema(schemaRecord)
|
|
6604
6819
|
};
|
|
6605
6820
|
}
|
|
6606
6821
|
return toolSet;
|
|
@@ -6631,7 +6846,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6631
6846
|
const description = entry.humanApproval !== void 0 && baseDescription !== void 0 ? `${baseDescription} ${HITL_SOLO_CONSTRAINT_SENTENCE}` : entry.humanApproval !== void 0 ? HITL_SOLO_CONSTRAINT_SENTENCE : baseDescription;
|
|
6632
6847
|
toolSet[entry.config.name] = {
|
|
6633
6848
|
description,
|
|
6634
|
-
inputSchema: jsonSchema(schemaRecord)
|
|
6849
|
+
inputSchema: this.aiSdk.jsonSchema(schemaRecord)
|
|
6635
6850
|
};
|
|
6636
6851
|
}
|
|
6637
6852
|
return toolSet;
|
|
@@ -6683,7 +6898,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6683
6898
|
});
|
|
6684
6899
|
try {
|
|
6685
6900
|
const callOptions = this.resolveCallOptions(model, guardrails.modelInvocationOptions);
|
|
6686
|
-
const result = await generateText({
|
|
6901
|
+
const result = await this.aiSdk.generateText({
|
|
6687
6902
|
model: model.languageModel,
|
|
6688
6903
|
messages: [...messages],
|
|
6689
6904
|
tools,
|
|
@@ -6802,8 +7017,8 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6802
7017
|
schemaName: structuredOptions?.schemaName ?? "structured_output",
|
|
6803
7018
|
requireObjectRoot: true
|
|
6804
7019
|
}) : schema;
|
|
6805
|
-
const outputSchema = Output.object({ schema: jsonSchema(schemaRecord) });
|
|
6806
|
-
const result = await generateText({
|
|
7020
|
+
const outputSchema = this.aiSdk.Output.object({ schema: this.aiSdk.jsonSchema(schemaRecord) });
|
|
7021
|
+
const result = await this.aiSdk.generateText({
|
|
6807
7022
|
model: model.languageModel,
|
|
6808
7023
|
messages: [...messages],
|
|
6809
7024
|
experimental_output: outputSchema,
|
|
@@ -7074,7 +7289,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
7074
7289
|
const json = JSON.stringify(value);
|
|
7075
7290
|
return JSON.parse(json);
|
|
7076
7291
|
}
|
|
7077
|
-
createPromptMessages(item, itemIndex, items, ctx) {
|
|
7292
|
+
async createPromptMessages(item, itemIndex, items, ctx) {
|
|
7078
7293
|
const messages = AgentMessageConfigNormalizer.resolveFromInputOrConfig(item.json, ctx.config, {
|
|
7079
7294
|
item,
|
|
7080
7295
|
itemIndex,
|
|
@@ -7082,7 +7297,47 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
7082
7297
|
ctx
|
|
7083
7298
|
});
|
|
7084
7299
|
const wrapped = this.wrapUntrustedSourceMessages(messages, item, ctx.config);
|
|
7085
|
-
|
|
7300
|
+
const promptMessages = AgentMessageFactory.createPromptMessages(wrapped);
|
|
7301
|
+
if (ctx.config.passBinariesToModel === false) return promptMessages;
|
|
7302
|
+
const attachments = this.selectBinaryAttachments(item, itemIndex, items, ctx);
|
|
7303
|
+
const binaries = await this.resolveInlineBinaries(attachments, ctx);
|
|
7304
|
+
return AgentBinaryContentFactory.withBinaries(promptMessages, binaries);
|
|
7305
|
+
}
|
|
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
|
+
selectBinaryAttachments(item, itemIndex, items, ctx) {
|
|
7313
|
+
const manual = ctx.config.binaries;
|
|
7314
|
+
if (manual !== void 0) return typeof manual === "function" ? manual({
|
|
7315
|
+
item,
|
|
7316
|
+
itemIndex,
|
|
7317
|
+
items,
|
|
7318
|
+
ctx
|
|
7319
|
+
}) : manual;
|
|
7320
|
+
return item.binary ? Object.values(item.binary) : [];
|
|
7321
|
+
}
|
|
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
|
+
async resolveInlineBinaries(attachments, ctx) {
|
|
7331
|
+
const resolved = [];
|
|
7332
|
+
for (const attachment of attachments) {
|
|
7333
|
+
const bytes = await ctx.binary.getBytes(attachment);
|
|
7334
|
+
resolved.push({
|
|
7335
|
+
mediaType: attachment.mimeType,
|
|
7336
|
+
base64: Buffer.from(bytes).toString("base64"),
|
|
7337
|
+
...attachment.filename ? { filename: attachment.filename } : {}
|
|
7338
|
+
});
|
|
7339
|
+
}
|
|
7340
|
+
return resolved;
|
|
7086
7341
|
}
|
|
7087
7342
|
/**
|
|
7088
7343
|
* When `item.json.__source` matches an entry in `config.untrustedSources`
|
|
@@ -7196,6 +7451,7 @@ var AIAgent = class {
|
|
|
7196
7451
|
chatModel;
|
|
7197
7452
|
tools;
|
|
7198
7453
|
id;
|
|
7454
|
+
description;
|
|
7199
7455
|
retryPolicy;
|
|
7200
7456
|
guardrails;
|
|
7201
7457
|
inputSchema;
|
|
@@ -7203,12 +7459,16 @@ var AIAgent = class {
|
|
|
7203
7459
|
mcpServers;
|
|
7204
7460
|
pinnedMcpTools;
|
|
7205
7461
|
untrustedSources;
|
|
7462
|
+
passBinariesToModel;
|
|
7463
|
+
passToolBinariesToModel;
|
|
7464
|
+
binaries;
|
|
7206
7465
|
constructor(options) {
|
|
7207
7466
|
this.name = options.name;
|
|
7208
7467
|
this.messages = options.messages;
|
|
7209
7468
|
this.chatModel = options.chatModel;
|
|
7210
7469
|
this.tools = options.tools ?? [];
|
|
7211
7470
|
this.id = options.id;
|
|
7471
|
+
this.description = options.description;
|
|
7212
7472
|
this.retryPolicy = options.retryPolicy ?? RetryPolicy.defaultForAiAgent;
|
|
7213
7473
|
this.guardrails = options.guardrails;
|
|
7214
7474
|
this.inputSchema = options.inputSchema;
|
|
@@ -7216,6 +7476,9 @@ var AIAgent = class {
|
|
|
7216
7476
|
this.mcpServers = options.mcpServers;
|
|
7217
7477
|
this.pinnedMcpTools = options.pinnedMcpTools;
|
|
7218
7478
|
this.untrustedSources = options.untrustedSources;
|
|
7479
|
+
this.passBinariesToModel = options.passBinariesToModel;
|
|
7480
|
+
this.passToolBinariesToModel = options.passToolBinariesToModel;
|
|
7481
|
+
this.binaries = options.binaries;
|
|
7219
7482
|
}
|
|
7220
7483
|
inspectorSummary() {
|
|
7221
7484
|
const rows = [];
|
|
@@ -7286,12 +7549,14 @@ var Assertion = class {
|
|
|
7286
7549
|
icon;
|
|
7287
7550
|
name;
|
|
7288
7551
|
id;
|
|
7552
|
+
description;
|
|
7289
7553
|
emitsAssertions = true;
|
|
7290
7554
|
assertions;
|
|
7291
7555
|
constructor(options) {
|
|
7292
7556
|
this.name = options.name ?? "Assertion";
|
|
7293
7557
|
this.id = options.id;
|
|
7294
7558
|
this.icon = options.icon ?? "lucide:check-circle";
|
|
7559
|
+
this.description = options.description;
|
|
7295
7560
|
this.assertions = options.assertions;
|
|
7296
7561
|
}
|
|
7297
7562
|
inspectorSummary() {
|
|
@@ -7343,6 +7608,7 @@ var Callback = class Callback {
|
|
|
7343
7608
|
icon = "lucide:braces";
|
|
7344
7609
|
emptyBatchExecution = "runOnce";
|
|
7345
7610
|
id;
|
|
7611
|
+
description;
|
|
7346
7612
|
retryPolicy;
|
|
7347
7613
|
nodeErrorHandler;
|
|
7348
7614
|
declaredOutputPorts;
|
|
@@ -7354,6 +7620,7 @@ var Callback = class Callback {
|
|
|
7354
7620
|
id: idOrOptions
|
|
7355
7621
|
} : idOrOptions;
|
|
7356
7622
|
this.id = resolvedOptions?.id;
|
|
7623
|
+
this.description = resolvedOptions?.description;
|
|
7357
7624
|
this.retryPolicy = resolvedOptions?.retryPolicy;
|
|
7358
7625
|
this.nodeErrorHandler = resolvedOptions?.nodeErrorHandler;
|
|
7359
7626
|
this.declaredOutputPorts = resolvedOptions?.declaredOutputPorts;
|
|
@@ -7555,10 +7822,12 @@ var HttpRequest = class {
|
|
|
7555
7822
|
type = HttpRequestNode;
|
|
7556
7823
|
execution = { hint: "local" };
|
|
7557
7824
|
icon = "lucide:globe";
|
|
7825
|
+
description;
|
|
7558
7826
|
constructor(name, args = {}, retryPolicy = RetryPolicy.defaultForHttp) {
|
|
7559
7827
|
this.name = name;
|
|
7560
7828
|
this.args = args;
|
|
7561
7829
|
this.retryPolicy = retryPolicy;
|
|
7830
|
+
this.description = args.description;
|
|
7562
7831
|
}
|
|
7563
7832
|
get id() {
|
|
7564
7833
|
return this.args.id;
|
|
@@ -7653,10 +7922,14 @@ var Aggregate = class {
|
|
|
7653
7922
|
execution = { hint: "local" };
|
|
7654
7923
|
keepBinaries = true;
|
|
7655
7924
|
icon = "builtin:aggregate-rows";
|
|
7656
|
-
|
|
7925
|
+
id;
|
|
7926
|
+
description;
|
|
7927
|
+
constructor(name, aggregate, idOrOptions) {
|
|
7657
7928
|
this.name = name;
|
|
7658
7929
|
this.aggregate = aggregate;
|
|
7659
|
-
|
|
7930
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
7931
|
+
this.id = options?.id;
|
|
7932
|
+
this.description = options?.description;
|
|
7660
7933
|
}
|
|
7661
7934
|
inspectorSummary() {
|
|
7662
7935
|
const fnName = this.aggregate.name;
|
|
@@ -7687,10 +7960,14 @@ var Filter = class {
|
|
|
7687
7960
|
type = FilterNode;
|
|
7688
7961
|
execution = { hint: "local" };
|
|
7689
7962
|
icon = "lucide:filter";
|
|
7690
|
-
|
|
7963
|
+
id;
|
|
7964
|
+
description;
|
|
7965
|
+
constructor(name, predicate, idOrOptions) {
|
|
7691
7966
|
this.name = name;
|
|
7692
7967
|
this.predicate = predicate;
|
|
7693
|
-
|
|
7968
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
7969
|
+
this.id = options?.id;
|
|
7970
|
+
this.description = options?.description;
|
|
7694
7971
|
}
|
|
7695
7972
|
inspectorSummary() {
|
|
7696
7973
|
const fnName = this.predicate.name;
|
|
@@ -7765,10 +8042,14 @@ var If = class {
|
|
|
7765
8042
|
execution = { hint: "local" };
|
|
7766
8043
|
icon = "lucide:split@rot=90";
|
|
7767
8044
|
declaredOutputPorts = ["true", "false"];
|
|
7768
|
-
|
|
8045
|
+
id;
|
|
8046
|
+
description;
|
|
8047
|
+
constructor(name, predicate, idOrOptions) {
|
|
7769
8048
|
this.name = name;
|
|
7770
8049
|
this.predicate = predicate;
|
|
7771
|
-
|
|
8050
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8051
|
+
this.id = options?.id;
|
|
8052
|
+
this.description = options?.description;
|
|
7772
8053
|
}
|
|
7773
8054
|
inspectorSummary() {
|
|
7774
8055
|
const fnName = this.predicate.name;
|
|
@@ -7808,9 +8089,12 @@ var IsTestRun = class {
|
|
|
7808
8089
|
declaredOutputPorts = ["true", "false"];
|
|
7809
8090
|
name;
|
|
7810
8091
|
id;
|
|
7811
|
-
|
|
8092
|
+
description;
|
|
8093
|
+
constructor(name = "Is test run?", idOrOptions) {
|
|
7812
8094
|
this.name = name;
|
|
7813
|
-
|
|
8095
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8096
|
+
this.id = options?.id;
|
|
8097
|
+
this.description = options?.description;
|
|
7814
8098
|
}
|
|
7815
8099
|
};
|
|
7816
8100
|
|
|
@@ -7839,11 +8123,15 @@ var Switch = class {
|
|
|
7839
8123
|
execution = { hint: "local" };
|
|
7840
8124
|
icon = "lucide:git-branch-plus";
|
|
7841
8125
|
declaredOutputPorts;
|
|
7842
|
-
|
|
8126
|
+
id;
|
|
8127
|
+
description;
|
|
8128
|
+
constructor(name, cfg, idOrOptions) {
|
|
7843
8129
|
this.name = name;
|
|
7844
8130
|
this.cfg = cfg;
|
|
7845
|
-
this.id = id;
|
|
7846
8131
|
this.declaredOutputPorts = [...new Set([...cfg.cases, cfg.defaultCase])].sort();
|
|
8132
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8133
|
+
this.id = options?.id;
|
|
8134
|
+
this.description = options?.description;
|
|
7847
8135
|
}
|
|
7848
8136
|
inspectorSummary() {
|
|
7849
8137
|
const rows = [{
|
|
@@ -7882,10 +8170,14 @@ var Split = class {
|
|
|
7882
8170
|
*/
|
|
7883
8171
|
continueWhenEmptyOutput = true;
|
|
7884
8172
|
icon = "builtin:split-rows";
|
|
7885
|
-
|
|
8173
|
+
id;
|
|
8174
|
+
description;
|
|
8175
|
+
constructor(name, getElements, idOrOptions) {
|
|
7886
8176
|
this.name = name;
|
|
7887
8177
|
this.getElements = getElements;
|
|
7888
|
-
|
|
8178
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8179
|
+
this.id = options?.id;
|
|
8180
|
+
this.description = options?.description;
|
|
7889
8181
|
}
|
|
7890
8182
|
inspectorSummary() {
|
|
7891
8183
|
const fnName = this.getElements.name;
|
|
@@ -7943,14 +8235,17 @@ var CronTrigger = class {
|
|
|
7943
8235
|
type = CronTriggerNode;
|
|
7944
8236
|
icon = "lucide:clock";
|
|
7945
8237
|
id;
|
|
7946
|
-
|
|
8238
|
+
description;
|
|
8239
|
+
constructor(name, args, idOrOptions) {
|
|
7947
8240
|
this.name = name;
|
|
7948
8241
|
this.args = args;
|
|
7949
8242
|
new Cron(args.schedule, {
|
|
7950
8243
|
paused: true,
|
|
7951
8244
|
timezone: args.timezone
|
|
7952
8245
|
});
|
|
7953
|
-
|
|
8246
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8247
|
+
this.id = options?.id;
|
|
8248
|
+
this.description = options?.description;
|
|
7954
8249
|
}
|
|
7955
8250
|
get schedule() {
|
|
7956
8251
|
return this.args.schedule;
|
|
@@ -8004,20 +8299,21 @@ var ManualTrigger = class ManualTrigger {
|
|
|
8004
8299
|
icon = "lucide:play";
|
|
8005
8300
|
defaultItems;
|
|
8006
8301
|
id;
|
|
8302
|
+
description;
|
|
8007
8303
|
/** Manual runs often emit an empty batch; still schedule downstream by default. */
|
|
8008
8304
|
continueWhenEmptyOutput = true;
|
|
8009
|
-
constructor(name = "Manual trigger", defaultItemsOrId,
|
|
8305
|
+
constructor(name = "Manual trigger", defaultItemsOrId, idOrOptions) {
|
|
8010
8306
|
this.name = name;
|
|
8011
8307
|
this.defaultItems = ManualTrigger.resolveDefaultItems(defaultItemsOrId);
|
|
8012
|
-
|
|
8308
|
+
const trailing = idOrOptions ?? (typeof defaultItemsOrId === "string" ? defaultItemsOrId : void 0);
|
|
8309
|
+
const options = typeof trailing === "string" ? { id: trailing } : trailing ?? {};
|
|
8310
|
+
this.id = options.id;
|
|
8311
|
+
this.description = options.description;
|
|
8013
8312
|
}
|
|
8014
8313
|
static resolveDefaultItems(value) {
|
|
8015
8314
|
if (typeof value === "string" || value === void 0) return;
|
|
8016
8315
|
return this.itemsInputNormalizer.normalize(value);
|
|
8017
8316
|
}
|
|
8018
|
-
static resolveId(value, id) {
|
|
8019
|
-
return typeof value === "string" ? value : id;
|
|
8020
|
-
}
|
|
8021
8317
|
inspectorSummary() {
|
|
8022
8318
|
const rows = [{
|
|
8023
8319
|
label: "Trigger",
|
|
@@ -8063,11 +8359,13 @@ var MapData = class {
|
|
|
8063
8359
|
continueWhenEmptyOutput = true;
|
|
8064
8360
|
icon = "lucide:square-pen";
|
|
8065
8361
|
keepBinaries;
|
|
8362
|
+
description;
|
|
8066
8363
|
constructor(name, map, options = {}) {
|
|
8067
8364
|
this.name = name;
|
|
8068
8365
|
this.map = map;
|
|
8069
8366
|
this.options = options;
|
|
8070
8367
|
this.keepBinaries = options.keepBinaries ?? true;
|
|
8368
|
+
this.description = options.description;
|
|
8071
8369
|
}
|
|
8072
8370
|
get id() {
|
|
8073
8371
|
return this.options.id;
|
|
@@ -8140,10 +8438,14 @@ var Merge = class {
|
|
|
8140
8438
|
kind = "node";
|
|
8141
8439
|
type = MergeNode;
|
|
8142
8440
|
icon = "lucide:merge@rot=90";
|
|
8143
|
-
|
|
8441
|
+
id;
|
|
8442
|
+
description;
|
|
8443
|
+
constructor(name, cfg = { mode: "passThrough" }, idOrOptions) {
|
|
8144
8444
|
this.name = name;
|
|
8145
8445
|
this.cfg = cfg;
|
|
8146
|
-
|
|
8446
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8447
|
+
this.id = options?.id;
|
|
8448
|
+
this.description = options?.description;
|
|
8147
8449
|
}
|
|
8148
8450
|
inspectorSummary() {
|
|
8149
8451
|
const rows = [{
|
|
@@ -8176,9 +8478,13 @@ var NoOp = class {
|
|
|
8176
8478
|
type = NoOpNode;
|
|
8177
8479
|
execution = { hint: "local" };
|
|
8178
8480
|
icon = "lucide:circle-dashed";
|
|
8179
|
-
|
|
8481
|
+
id;
|
|
8482
|
+
description;
|
|
8483
|
+
constructor(name = "NoOp", idOrOptions) {
|
|
8180
8484
|
this.name = name;
|
|
8181
|
-
|
|
8485
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8486
|
+
this.id = options?.id;
|
|
8487
|
+
this.description = options?.description;
|
|
8182
8488
|
}
|
|
8183
8489
|
};
|
|
8184
8490
|
|
|
@@ -8244,12 +8550,16 @@ var SubWorkflow = class {
|
|
|
8244
8550
|
kind = "node";
|
|
8245
8551
|
type = SubWorkflowNode;
|
|
8246
8552
|
icon = "lucide:workflow";
|
|
8247
|
-
|
|
8553
|
+
id;
|
|
8554
|
+
description;
|
|
8555
|
+
constructor(name, workflowId, upstreamRefs, startAt, idOrOptions) {
|
|
8248
8556
|
this.name = name;
|
|
8249
8557
|
this.workflowId = workflowId;
|
|
8250
8558
|
this.upstreamRefs = upstreamRefs;
|
|
8251
8559
|
this.startAt = startAt;
|
|
8252
|
-
|
|
8560
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8561
|
+
this.id = options?.id;
|
|
8562
|
+
this.description = options?.description;
|
|
8253
8563
|
}
|
|
8254
8564
|
inspectorSummary() {
|
|
8255
8565
|
const rows = [{
|
|
@@ -8359,10 +8669,14 @@ var Wait = class {
|
|
|
8359
8669
|
/** Pass-through empty batches should still advance to downstream nodes. */
|
|
8360
8670
|
continueWhenEmptyOutput = true;
|
|
8361
8671
|
icon = "lucide:hourglass";
|
|
8362
|
-
|
|
8672
|
+
id;
|
|
8673
|
+
description;
|
|
8674
|
+
constructor(name, milliseconds, idOrOptions) {
|
|
8363
8675
|
this.name = name;
|
|
8364
8676
|
this.milliseconds = milliseconds;
|
|
8365
|
-
|
|
8677
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8678
|
+
this.id = options?.id;
|
|
8679
|
+
this.description = options?.description;
|
|
8366
8680
|
}
|
|
8367
8681
|
inspectorSummary() {
|
|
8368
8682
|
const seconds = this.milliseconds / 1e3;
|
|
@@ -8417,11 +8731,15 @@ var WebhookTrigger = class WebhookTrigger {
|
|
|
8417
8731
|
kind = "trigger";
|
|
8418
8732
|
type = WebhookTriggerNode;
|
|
8419
8733
|
icon = "lucide:globe";
|
|
8420
|
-
|
|
8734
|
+
id;
|
|
8735
|
+
description;
|
|
8736
|
+
constructor(name, args, handler = WebhookTrigger.defaultHandler, idOrOptions) {
|
|
8421
8737
|
this.name = name;
|
|
8422
8738
|
this.args = args;
|
|
8423
8739
|
this.handler = handler;
|
|
8424
|
-
|
|
8740
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8741
|
+
this.id = options?.id;
|
|
8742
|
+
this.description = options?.description;
|
|
8425
8743
|
}
|
|
8426
8744
|
get endpointKey() {
|
|
8427
8745
|
return this.args.endpointKey;
|
|
@@ -8478,11 +8796,21 @@ function createWorkflowBuilder(meta$2) {
|
|
|
8478
8796
|
|
|
8479
8797
|
//#endregion
|
|
8480
8798
|
//#region src/workflowAuthoring/WorkflowChatModelFactory.types.ts
|
|
8799
|
+
const VALID_COMPLEXITY = new Set([
|
|
8800
|
+
"low",
|
|
8801
|
+
"medium",
|
|
8802
|
+
"high",
|
|
8803
|
+
"xhigh"
|
|
8804
|
+
]);
|
|
8481
8805
|
var WorkflowChatModelFactory = class {
|
|
8482
8806
|
static create(model) {
|
|
8483
8807
|
if (typeof model !== "string") return model;
|
|
8484
8808
|
const [provider, resolvedModel] = model.includes(":") ? model.split(":", 2) : ["openai", model];
|
|
8485
|
-
if (provider === "codemation-managed")
|
|
8809
|
+
if (provider === "codemation-managed") {
|
|
8810
|
+
const complexity = resolvedModel ?? "medium";
|
|
8811
|
+
if (!VALID_COMPLEXITY.has(complexity)) throw new Error(`Invalid managed complexity "${complexity}". Must be one of: low, medium, high, xhigh.`);
|
|
8812
|
+
return new CodemationChatModelConfig("Codemation Managed", complexity);
|
|
8813
|
+
}
|
|
8486
8814
|
if (provider !== "openai") throw new Error(`Unsupported workflow().agent() model provider "${provider}".`);
|
|
8487
8815
|
return new OpenAIChatModelConfig("OpenAI", resolvedModel);
|
|
8488
8816
|
}
|
|
@@ -9119,5 +9447,5 @@ const codemationDocumentScannerNode = defineNode({
|
|
|
9119
9447
|
});
|
|
9120
9448
|
|
|
9121
9449
|
//#endregion
|
|
9122
|
-
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,
|
|
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 };
|
|
9123
9451
|
//# sourceMappingURL=index.js.map
|