@codemation/core-nodes 0.10.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +125 -0
- package/dist/index.cjs +273 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +212 -71
- package/dist/index.d.ts +213 -72
- package/dist/index.js +273 -105
- 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/http/HttpBodyBuilder.ts +9 -0
- package/src/http/httpRequest.types.ts +10 -1
- package/src/index.ts +1 -1
- package/src/nodes/AIAgentConfig.ts +28 -0
- package/src/nodes/AIAgentNode.ts +84 -17
- package/src/nodes/AgentBinaryContentFactory.ts +74 -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 +7 -2
- 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.cjs
CHANGED
|
@@ -25,14 +25,10 @@ let __codemation_core = require("@codemation/core");
|
|
|
25
25
|
__codemation_core = __toESM(__codemation_core);
|
|
26
26
|
let node_dns_promises = require("node:dns/promises");
|
|
27
27
|
node_dns_promises = __toESM(node_dns_promises);
|
|
28
|
-
let __ai_sdk_openai = require("@ai-sdk/openai");
|
|
29
|
-
__ai_sdk_openai = __toESM(__ai_sdk_openai);
|
|
30
28
|
let __codemation_core_bootstrap = require("@codemation/core/bootstrap");
|
|
31
29
|
__codemation_core_bootstrap = __toESM(__codemation_core_bootstrap);
|
|
32
30
|
let node_crypto = require("node:crypto");
|
|
33
31
|
node_crypto = __toESM(node_crypto);
|
|
34
|
-
let ai = require("ai");
|
|
35
|
-
ai = __toESM(ai);
|
|
36
32
|
let croner = require("croner");
|
|
37
33
|
croner = __toESM(croner);
|
|
38
34
|
|
|
@@ -525,10 +521,13 @@ var HttpRequestExecutor = class {
|
|
|
525
521
|
var HttpBodyBuilder = class {
|
|
526
522
|
async build(spec, item, ctx) {
|
|
527
523
|
if (!spec || spec.kind === "none") return;
|
|
528
|
-
if (spec.kind === "json")
|
|
529
|
-
body: JSON.stringify(
|
|
530
|
-
|
|
531
|
-
|
|
524
|
+
if (spec.kind === "json") {
|
|
525
|
+
if (typeof spec.data === "string") throw new Error("HttpRequest body kind:\"json\" expects a serializable object for \"data\", but received a string. Pass the object directly (e.g. { a: 1 }), not a pre-stringified JSON string (JSON.stringify(...)).");
|
|
526
|
+
return {
|
|
527
|
+
body: JSON.stringify(spec.data),
|
|
528
|
+
contentType: "application/json"
|
|
529
|
+
};
|
|
530
|
+
}
|
|
532
531
|
if (spec.kind === "form") {
|
|
533
532
|
const params = new URLSearchParams();
|
|
534
533
|
for (const [key, value] of Object.entries(spec.data)) params.append(key, value);
|
|
@@ -701,8 +700,9 @@ function __decorate(decorators, target, key, desc) {
|
|
|
701
700
|
let OpenAIChatModelFactory = class OpenAIChatModelFactory$1 {
|
|
702
701
|
async create(args) {
|
|
703
702
|
const session = await args.ctx.getCredential(args.config.credentialSlotKey);
|
|
703
|
+
const { createOpenAI } = await import("@ai-sdk/openai");
|
|
704
704
|
return {
|
|
705
|
-
languageModel:
|
|
705
|
+
languageModel: createOpenAI({
|
|
706
706
|
apiKey: session.apiKey,
|
|
707
707
|
baseURL: session.baseUrl
|
|
708
708
|
}).chat(args.config.model),
|
|
@@ -4445,27 +4445,24 @@ function buildHmacAuthHeader(workspaceId, pairingSecret, method, url, body, over
|
|
|
4445
4445
|
//#endregion
|
|
4446
4446
|
//#region src/chatModels/CodemationChatModelFactory.ts
|
|
4447
4447
|
let CodemationChatModelFactory = class CodemationChatModelFactory$1 {
|
|
4448
|
-
create(args) {
|
|
4448
|
+
async create(args) {
|
|
4449
4449
|
const gatewayUrl = process.env["LLM_GATEWAY_URL"];
|
|
4450
4450
|
if (!gatewayUrl) throw new Error("Codemation managed AI not available in this environment (LLM_GATEWAY_URL is not set).");
|
|
4451
4451
|
const workspaceId = process.env["WORKSPACE_ID"];
|
|
4452
4452
|
const pairingSecret = process.env["WORKSPACE_PAIRING_SECRET"];
|
|
4453
4453
|
if (!workspaceId || !pairingSecret) throw new Error("Codemation managed AI not available in this environment (workspace pairing is not configured).");
|
|
4454
4454
|
const hmacFetch = managedHmacFetchFactory(workspaceId, pairingSecret);
|
|
4455
|
-
const
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
modelName: args.config.
|
|
4455
|
+
const { createAnthropic } = await import("@ai-sdk/anthropic");
|
|
4456
|
+
return {
|
|
4457
|
+
languageModel: createAnthropic({
|
|
4458
|
+
baseURL: `${gatewayUrl}/v1`,
|
|
4459
|
+
apiKey: "codemation-managed",
|
|
4460
|
+
fetch: hmacFetch
|
|
4461
|
+
})(args.config.complexity),
|
|
4462
|
+
modelName: args.config.complexity,
|
|
4463
4463
|
provider: "codemation-managed",
|
|
4464
|
-
defaultCallOptions: {
|
|
4465
|
-
|
|
4466
|
-
temperature: args.config.options?.temperature
|
|
4467
|
-
}
|
|
4468
|
-
});
|
|
4464
|
+
defaultCallOptions: { maxOutputTokens: args.config.options?.maxTokens }
|
|
4465
|
+
};
|
|
4469
4466
|
}
|
|
4470
4467
|
};
|
|
4471
4468
|
CodemationChatModelFactory = __decorate([(0, __codemation_core.chatModel)({ packageName: "@codemation/core-nodes" })], CodemationChatModelFactory);
|
|
@@ -4477,11 +4474,11 @@ var CodemationChatModelConfig = class {
|
|
|
4477
4474
|
presentation;
|
|
4478
4475
|
provider = "codemation-managed";
|
|
4479
4476
|
modelName;
|
|
4480
|
-
constructor(name,
|
|
4477
|
+
constructor(name, complexity, presentationIn, options) {
|
|
4481
4478
|
this.name = name;
|
|
4482
|
-
this.
|
|
4479
|
+
this.complexity = complexity;
|
|
4483
4480
|
this.options = options;
|
|
4484
|
-
this.modelName =
|
|
4481
|
+
this.modelName = complexity;
|
|
4485
4482
|
this.presentation = presentationIn ?? {
|
|
4486
4483
|
icon: "lucide:bot",
|
|
4487
4484
|
label: name
|
|
@@ -4489,28 +4486,6 @@ var CodemationChatModelConfig = class {
|
|
|
4489
4486
|
}
|
|
4490
4487
|
};
|
|
4491
4488
|
|
|
4492
|
-
//#endregion
|
|
4493
|
-
//#region src/chatModels/ManagedModelFetcher.ts
|
|
4494
|
-
/**
|
|
4495
|
-
* Fetches the active platform-managed model allowlist from the CP.
|
|
4496
|
-
* Reads CONTROL_PLANE_URL from the workspace process env.
|
|
4497
|
-
* Returns an empty array if the env var is absent or the fetch fails.
|
|
4498
|
-
* Cache the result per session — the allowlist changes infrequently.
|
|
4499
|
-
*/
|
|
4500
|
-
var ManagedModelFetcher = class {
|
|
4501
|
-
async fetch() {
|
|
4502
|
-
const cpUrl = process.env["CONTROL_PLANE_URL"];
|
|
4503
|
-
if (!cpUrl) return [];
|
|
4504
|
-
try {
|
|
4505
|
-
const res = await globalThis.fetch(`${cpUrl}/api/llm/managed-models`);
|
|
4506
|
-
if (!res.ok) return [];
|
|
4507
|
-
return await res.json();
|
|
4508
|
-
} catch {
|
|
4509
|
-
return [];
|
|
4510
|
-
}
|
|
4511
|
-
}
|
|
4512
|
-
};
|
|
4513
|
-
|
|
4514
4489
|
//#endregion
|
|
4515
4490
|
//#region src/nodes/AgentMessageFactory.ts
|
|
4516
4491
|
/**
|
|
@@ -5879,6 +5854,63 @@ AgentToolExecutionCoordinator = __decorate([
|
|
|
5879
5854
|
__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])
|
|
5880
5855
|
], AgentToolExecutionCoordinator);
|
|
5881
5856
|
|
|
5857
|
+
//#endregion
|
|
5858
|
+
//#region src/nodes/AgentBinaryContentFactory.ts
|
|
5859
|
+
/**
|
|
5860
|
+
* Turns resolved file binaries into native AI SDK multimodal content parts and merges them into the
|
|
5861
|
+
* agent prompt. Images (`image/*`) become {@link ImagePart}s; every other type (PDFs, office docs,
|
|
5862
|
+
* CSV, JSON, …) becomes a {@link FilePart}. The provider maps these to its wire-level `image` /
|
|
5863
|
+
* `document` blocks; an unsupported file type surfaces as a provider error at runtime.
|
|
5864
|
+
*
|
|
5865
|
+
* Parts are appended to the LAST user message so the binary travels alongside the author's prompt
|
|
5866
|
+
* text (preserving any untrusted-source preamble that already wrapped that text). When no user
|
|
5867
|
+
* message exists, a new user message carrying only the binaries is appended.
|
|
5868
|
+
*/
|
|
5869
|
+
var AgentBinaryContentFactory = class AgentBinaryContentFactory {
|
|
5870
|
+
static toContentPart(binary) {
|
|
5871
|
+
if (binary.mediaType.startsWith("image/")) return {
|
|
5872
|
+
type: "image",
|
|
5873
|
+
image: binary.base64,
|
|
5874
|
+
mediaType: binary.mediaType
|
|
5875
|
+
};
|
|
5876
|
+
return {
|
|
5877
|
+
type: "file",
|
|
5878
|
+
data: binary.base64,
|
|
5879
|
+
mediaType: binary.mediaType,
|
|
5880
|
+
...binary.filename ? { filename: binary.filename } : {}
|
|
5881
|
+
};
|
|
5882
|
+
}
|
|
5883
|
+
static withBinaries(messages, binaries) {
|
|
5884
|
+
if (binaries.length === 0) return messages;
|
|
5885
|
+
const parts = binaries.map((binary) => AgentBinaryContentFactory.toContentPart(binary));
|
|
5886
|
+
const lastUserIndex = AgentBinaryContentFactory.lastUserMessageIndex(messages);
|
|
5887
|
+
if (lastUserIndex === -1) {
|
|
5888
|
+
const appended = {
|
|
5889
|
+
role: "user",
|
|
5890
|
+
content: parts
|
|
5891
|
+
};
|
|
5892
|
+
return [...messages, appended];
|
|
5893
|
+
}
|
|
5894
|
+
const next = [...messages];
|
|
5895
|
+
next[lastUserIndex] = AgentBinaryContentFactory.appendPartsToUserMessage(messages[lastUserIndex], parts);
|
|
5896
|
+
return next;
|
|
5897
|
+
}
|
|
5898
|
+
static lastUserMessageIndex(messages) {
|
|
5899
|
+
for (let index = messages.length - 1; index >= 0; index--) if (messages[index]?.role === "user") return index;
|
|
5900
|
+
return -1;
|
|
5901
|
+
}
|
|
5902
|
+
static appendPartsToUserMessage(message, parts) {
|
|
5903
|
+
const existing = typeof message.content === "string" ? message.content.length > 0 ? [{
|
|
5904
|
+
type: "text",
|
|
5905
|
+
text: message.content
|
|
5906
|
+
}] : [] : message.content;
|
|
5907
|
+
return {
|
|
5908
|
+
...message,
|
|
5909
|
+
content: [...existing, ...parts]
|
|
5910
|
+
};
|
|
5911
|
+
}
|
|
5912
|
+
};
|
|
5913
|
+
|
|
5882
5914
|
//#endregion
|
|
5883
5915
|
//#region src/nodes/NodeBackedToolRuntime.ts
|
|
5884
5916
|
var _ref$1, _ref2$1, _ref3$1, _ref4$1;
|
|
@@ -6077,11 +6109,18 @@ var DeferredMetaToolStrategy = class {
|
|
|
6077
6109
|
mcpEntries = [];
|
|
6078
6110
|
toolsByServerId = /* @__PURE__ */ new Map();
|
|
6079
6111
|
foundToolIds = /* @__PURE__ */ new Set();
|
|
6112
|
+
/**
|
|
6113
|
+
* `jsonSchema` from the `ai` SDK, loaded lazily in {@link initialize} so the SDK
|
|
6114
|
+
* (~28MB RSS) stays off the boot path. `initialize` always runs before the sync
|
|
6115
|
+
* `getToolsForTurn` → `buildFindToolsDefinition` path, so this is set before use.
|
|
6116
|
+
*/
|
|
6117
|
+
jsonSchema;
|
|
6080
6118
|
constructor(bm25, warnFn) {
|
|
6081
6119
|
this.bm25 = bm25;
|
|
6082
6120
|
this.warnFn = warnFn;
|
|
6083
6121
|
}
|
|
6084
6122
|
async initialize(input) {
|
|
6123
|
+
this.jsonSchema = (await import("ai")).jsonSchema;
|
|
6085
6124
|
this.nodeBackedTools = { ...input.nodeBackedTools };
|
|
6086
6125
|
const pinnedIds = input.pinnedMcpTools ?? [];
|
|
6087
6126
|
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}.`);
|
|
@@ -6169,25 +6208,26 @@ var DeferredMetaToolStrategy = class {
|
|
|
6169
6208
|
return [...this.foundToolIds];
|
|
6170
6209
|
}
|
|
6171
6210
|
buildFindToolsDefinition() {
|
|
6211
|
+
const inputSchemaRecord = {
|
|
6212
|
+
type: "object",
|
|
6213
|
+
properties: {
|
|
6214
|
+
query: {
|
|
6215
|
+
type: "string",
|
|
6216
|
+
description: "Natural language description of what you want to do."
|
|
6217
|
+
},
|
|
6218
|
+
limit: {
|
|
6219
|
+
type: "integer",
|
|
6220
|
+
minimum: 1,
|
|
6221
|
+
maximum: 10,
|
|
6222
|
+
description: `Maximum number of tools to return (default ${FIND_TOOLS_DEFAULT_LIMIT}).`
|
|
6223
|
+
}
|
|
6224
|
+
},
|
|
6225
|
+
required: ["query"],
|
|
6226
|
+
additionalProperties: false
|
|
6227
|
+
};
|
|
6172
6228
|
return {
|
|
6173
6229
|
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.",
|
|
6174
|
-
inputSchema:
|
|
6175
|
-
type: "object",
|
|
6176
|
-
properties: {
|
|
6177
|
-
query: {
|
|
6178
|
-
type: "string",
|
|
6179
|
-
description: "Natural language description of what you want to do."
|
|
6180
|
-
},
|
|
6181
|
-
limit: {
|
|
6182
|
-
type: "integer",
|
|
6183
|
-
minimum: 1,
|
|
6184
|
-
maximum: 10,
|
|
6185
|
-
description: `Maximum number of tools to return (default ${FIND_TOOLS_DEFAULT_LIMIT}).`
|
|
6186
|
-
}
|
|
6187
|
-
},
|
|
6188
|
-
required: ["query"],
|
|
6189
|
-
additionalProperties: false
|
|
6190
|
-
})
|
|
6230
|
+
inputSchema: this.jsonSchema(inputSchemaRecord)
|
|
6191
6231
|
};
|
|
6192
6232
|
}
|
|
6193
6233
|
};
|
|
@@ -6221,6 +6261,13 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6221
6261
|
inputSchema = unknown();
|
|
6222
6262
|
connectionCredentialExecutionContextFactory;
|
|
6223
6263
|
preparedByExecutionContext = /* @__PURE__ */ new WeakMap();
|
|
6264
|
+
/**
|
|
6265
|
+
* The `ai` SDK, loaded lazily in {@link execute} so the SDK (~28MB RSS) stays
|
|
6266
|
+
* off the boot path — non-AI workflows never load it. Every path runs through
|
|
6267
|
+
* `execute` → `ensureAiSdk` before any sync helper touches `this.aiSdk`.
|
|
6268
|
+
*/
|
|
6269
|
+
aiSdk;
|
|
6270
|
+
aiSdkPromise = null;
|
|
6224
6271
|
constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner, toolExecutionCoordinator, toolLoadingStrategyFactory, agentMcpIntegration) {
|
|
6225
6272
|
this.nodeResolver = nodeResolver;
|
|
6226
6273
|
this.nodeBackedToolRuntime = nodeBackedToolRuntime;
|
|
@@ -6233,6 +6280,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6233
6280
|
}
|
|
6234
6281
|
async execute(args) {
|
|
6235
6282
|
const { ctx } = args;
|
|
6283
|
+
await this.ensureAiSdk();
|
|
6236
6284
|
if (ctx.resumeContext) return this.executeResumed(args, ctx.resumeContext);
|
|
6237
6285
|
const prepared = await this.getOrPrepareExecution(ctx);
|
|
6238
6286
|
const itemWithMappedJson = {
|
|
@@ -6241,6 +6289,10 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6241
6289
|
};
|
|
6242
6290
|
return (await this.runAgentForItem(prepared, itemWithMappedJson, args.itemIndex, args.items)).json;
|
|
6243
6291
|
}
|
|
6292
|
+
/** Load the `ai` SDK once per node instance (cached promise guards concurrent items). */
|
|
6293
|
+
async ensureAiSdk() {
|
|
6294
|
+
this.aiSdk = await (this.aiSdkPromise ??= import("ai"));
|
|
6295
|
+
}
|
|
6244
6296
|
/**
|
|
6245
6297
|
* Resume path: re-enters the agent loop after a HITL suspension.
|
|
6246
6298
|
* Reconstructs the conversation from the checkpoint, injects the human decision
|
|
@@ -6383,7 +6435,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6383
6435
|
const { ctx } = prepared;
|
|
6384
6436
|
const itemInputsByPort = AgentItemPortMap.fromItem(item);
|
|
6385
6437
|
const itemScopedTools = this.createItemScopedTools(prepared.resolvedTools, ctx, item, itemIndex, items);
|
|
6386
|
-
const conversation = [...this.createPromptMessages(item, itemIndex, items, ctx)];
|
|
6438
|
+
const conversation = [...await this.createPromptMessages(item, itemIndex, items, ctx)];
|
|
6387
6439
|
if (ctx.config.outputSchema && itemScopedTools.length === 0) {
|
|
6388
6440
|
const structuredOutput = await this.structuredOutputRunner.resolve({
|
|
6389
6441
|
model: prepared.model,
|
|
@@ -6570,14 +6622,17 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6570
6622
|
});
|
|
6571
6623
|
}
|
|
6572
6624
|
/**
|
|
6573
|
-
*
|
|
6574
|
-
*
|
|
6625
|
+
* Resolves the HITL behavior for a tool binding, or `undefined` when it is not a HITL tool.
|
|
6626
|
+
* A binding is HITL if either the backing node carries a `defineHumanApprovalNode` marker or the
|
|
6627
|
+
* binding sets a per-binding `onRejected` via `asTool(..., { onRejected })`. The per-binding value
|
|
6628
|
+
* wins over the node marker, so two tools backed by the same node can reject differently.
|
|
6575
6629
|
*/
|
|
6576
6630
|
resolveHumanApprovalBehavior(config$1) {
|
|
6577
6631
|
if (!this.isNodeBackedToolConfig(config$1)) return void 0;
|
|
6578
6632
|
const marker = config$1.node.humanApprovalToolBehavior;
|
|
6579
|
-
|
|
6580
|
-
|
|
6633
|
+
const perBinding = config$1.onRejected;
|
|
6634
|
+
if (marker === void 0 && perBinding === void 0) return void 0;
|
|
6635
|
+
return { onRejected: perBinding ?? marker?.onRejected ?? "return" };
|
|
6581
6636
|
}
|
|
6582
6637
|
/**
|
|
6583
6638
|
* Invoke a text turn using the merged tool set from item-scoped tools (coordinator-managed)
|
|
@@ -6624,7 +6679,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6624
6679
|
const description = this.resolveHumanApprovalBehavior(entry.config) !== void 0 ? `${baseDescription} ${HITL_SOLO_CONSTRAINT_SENTENCE}` : baseDescription;
|
|
6625
6680
|
toolSet[entry.config.name] = {
|
|
6626
6681
|
description,
|
|
6627
|
-
inputSchema:
|
|
6682
|
+
inputSchema: this.aiSdk.jsonSchema(schemaRecord)
|
|
6628
6683
|
};
|
|
6629
6684
|
}
|
|
6630
6685
|
return toolSet;
|
|
@@ -6655,7 +6710,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6655
6710
|
const description = entry.humanApproval !== void 0 && baseDescription !== void 0 ? `${baseDescription} ${HITL_SOLO_CONSTRAINT_SENTENCE}` : entry.humanApproval !== void 0 ? HITL_SOLO_CONSTRAINT_SENTENCE : baseDescription;
|
|
6656
6711
|
toolSet[entry.config.name] = {
|
|
6657
6712
|
description,
|
|
6658
|
-
inputSchema:
|
|
6713
|
+
inputSchema: this.aiSdk.jsonSchema(schemaRecord)
|
|
6659
6714
|
};
|
|
6660
6715
|
}
|
|
6661
6716
|
return toolSet;
|
|
@@ -6707,7 +6762,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6707
6762
|
});
|
|
6708
6763
|
try {
|
|
6709
6764
|
const callOptions = this.resolveCallOptions(model, guardrails.modelInvocationOptions);
|
|
6710
|
-
const result = await
|
|
6765
|
+
const result = await this.aiSdk.generateText({
|
|
6711
6766
|
model: model.languageModel,
|
|
6712
6767
|
messages: [...messages],
|
|
6713
6768
|
tools,
|
|
@@ -6826,8 +6881,8 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
6826
6881
|
schemaName: structuredOptions?.schemaName ?? "structured_output",
|
|
6827
6882
|
requireObjectRoot: true
|
|
6828
6883
|
}) : schema;
|
|
6829
|
-
const outputSchema =
|
|
6830
|
-
const result = await
|
|
6884
|
+
const outputSchema = this.aiSdk.Output.object({ schema: this.aiSdk.jsonSchema(schemaRecord) });
|
|
6885
|
+
const result = await this.aiSdk.generateText({
|
|
6831
6886
|
model: model.languageModel,
|
|
6832
6887
|
messages: [...messages],
|
|
6833
6888
|
experimental_output: outputSchema,
|
|
@@ -7098,7 +7153,7 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
7098
7153
|
const json = JSON.stringify(value);
|
|
7099
7154
|
return JSON.parse(json);
|
|
7100
7155
|
}
|
|
7101
|
-
createPromptMessages(item, itemIndex, items, ctx) {
|
|
7156
|
+
async createPromptMessages(item, itemIndex, items, ctx) {
|
|
7102
7157
|
const messages = __codemation_core.AgentMessageConfigNormalizer.resolveFromInputOrConfig(item.json, ctx.config, {
|
|
7103
7158
|
item,
|
|
7104
7159
|
itemIndex,
|
|
@@ -7106,7 +7161,47 @@ let AIAgentNode = class AIAgentNode$1 {
|
|
|
7106
7161
|
ctx
|
|
7107
7162
|
});
|
|
7108
7163
|
const wrapped = this.wrapUntrustedSourceMessages(messages, item, ctx.config);
|
|
7109
|
-
|
|
7164
|
+
const promptMessages = AgentMessageFactory.createPromptMessages(wrapped);
|
|
7165
|
+
if (ctx.config.passBinariesToModel === false) return promptMessages;
|
|
7166
|
+
const attachments = this.selectBinaryAttachments(item, itemIndex, items, ctx);
|
|
7167
|
+
const binaries = await this.resolveInlineBinaries(attachments, ctx);
|
|
7168
|
+
return AgentBinaryContentFactory.withBinaries(promptMessages, binaries);
|
|
7169
|
+
}
|
|
7170
|
+
/**
|
|
7171
|
+
* Picks which attachments feed the passdown. When the author supplies `config.binaries`
|
|
7172
|
+
* (a static array or a per-item function — e.g. to forward binaries from an earlier node),
|
|
7173
|
+
* those replace the current item's attachments; otherwise the current item's `item.binary`
|
|
7174
|
+
* is used.
|
|
7175
|
+
*/
|
|
7176
|
+
selectBinaryAttachments(item, itemIndex, items, ctx) {
|
|
7177
|
+
const manual = ctx.config.binaries;
|
|
7178
|
+
if (manual !== void 0) return typeof manual === "function" ? manual({
|
|
7179
|
+
item,
|
|
7180
|
+
itemIndex,
|
|
7181
|
+
items,
|
|
7182
|
+
ctx
|
|
7183
|
+
}) : manual;
|
|
7184
|
+
return item.binary ? Object.values(item.binary) : [];
|
|
7185
|
+
}
|
|
7186
|
+
/**
|
|
7187
|
+
* Reads every attachment through `ctx.binary` (storage-backed, by reference — never base64 on
|
|
7188
|
+
* `item.json`) and resolves it to inline base64 so the agent can pass it to the chat model as a
|
|
7189
|
+
* native multimodal block. Images become image blocks; every other type (PDF, office docs, CSV,
|
|
7190
|
+
* JSON, …) becomes a file block — we don't filter by media type, so any binary can be fed to the
|
|
7191
|
+
* model. If the provider rejects an unsupported type the error surfaces at runtime, and the
|
|
7192
|
+
* workflow can filter the binary upstream.
|
|
7193
|
+
*/
|
|
7194
|
+
async resolveInlineBinaries(attachments, ctx) {
|
|
7195
|
+
const resolved = [];
|
|
7196
|
+
for (const attachment of attachments) {
|
|
7197
|
+
const bytes = await ctx.binary.getBytes(attachment);
|
|
7198
|
+
resolved.push({
|
|
7199
|
+
mediaType: attachment.mimeType,
|
|
7200
|
+
base64: Buffer.from(bytes).toString("base64"),
|
|
7201
|
+
...attachment.filename ? { filename: attachment.filename } : {}
|
|
7202
|
+
});
|
|
7203
|
+
}
|
|
7204
|
+
return resolved;
|
|
7110
7205
|
}
|
|
7111
7206
|
/**
|
|
7112
7207
|
* When `item.json.__source` matches an entry in `config.untrustedSources`
|
|
@@ -7220,6 +7315,7 @@ var AIAgent = class {
|
|
|
7220
7315
|
chatModel;
|
|
7221
7316
|
tools;
|
|
7222
7317
|
id;
|
|
7318
|
+
description;
|
|
7223
7319
|
retryPolicy;
|
|
7224
7320
|
guardrails;
|
|
7225
7321
|
inputSchema;
|
|
@@ -7227,12 +7323,15 @@ var AIAgent = class {
|
|
|
7227
7323
|
mcpServers;
|
|
7228
7324
|
pinnedMcpTools;
|
|
7229
7325
|
untrustedSources;
|
|
7326
|
+
passBinariesToModel;
|
|
7327
|
+
binaries;
|
|
7230
7328
|
constructor(options) {
|
|
7231
7329
|
this.name = options.name;
|
|
7232
7330
|
this.messages = options.messages;
|
|
7233
7331
|
this.chatModel = options.chatModel;
|
|
7234
7332
|
this.tools = options.tools ?? [];
|
|
7235
7333
|
this.id = options.id;
|
|
7334
|
+
this.description = options.description;
|
|
7236
7335
|
this.retryPolicy = options.retryPolicy ?? __codemation_core.RetryPolicy.defaultForAiAgent;
|
|
7237
7336
|
this.guardrails = options.guardrails;
|
|
7238
7337
|
this.inputSchema = options.inputSchema;
|
|
@@ -7240,6 +7339,8 @@ var AIAgent = class {
|
|
|
7240
7339
|
this.mcpServers = options.mcpServers;
|
|
7241
7340
|
this.pinnedMcpTools = options.pinnedMcpTools;
|
|
7242
7341
|
this.untrustedSources = options.untrustedSources;
|
|
7342
|
+
this.passBinariesToModel = options.passBinariesToModel;
|
|
7343
|
+
this.binaries = options.binaries;
|
|
7243
7344
|
}
|
|
7244
7345
|
inspectorSummary() {
|
|
7245
7346
|
const rows = [];
|
|
@@ -7310,12 +7411,14 @@ var Assertion = class {
|
|
|
7310
7411
|
icon;
|
|
7311
7412
|
name;
|
|
7312
7413
|
id;
|
|
7414
|
+
description;
|
|
7313
7415
|
emitsAssertions = true;
|
|
7314
7416
|
assertions;
|
|
7315
7417
|
constructor(options) {
|
|
7316
7418
|
this.name = options.name ?? "Assertion";
|
|
7317
7419
|
this.id = options.id;
|
|
7318
7420
|
this.icon = options.icon ?? "lucide:check-circle";
|
|
7421
|
+
this.description = options.description;
|
|
7319
7422
|
this.assertions = options.assertions;
|
|
7320
7423
|
}
|
|
7321
7424
|
inspectorSummary() {
|
|
@@ -7367,6 +7470,7 @@ var Callback = class Callback {
|
|
|
7367
7470
|
icon = "lucide:braces";
|
|
7368
7471
|
emptyBatchExecution = "runOnce";
|
|
7369
7472
|
id;
|
|
7473
|
+
description;
|
|
7370
7474
|
retryPolicy;
|
|
7371
7475
|
nodeErrorHandler;
|
|
7372
7476
|
declaredOutputPorts;
|
|
@@ -7378,6 +7482,7 @@ var Callback = class Callback {
|
|
|
7378
7482
|
id: idOrOptions
|
|
7379
7483
|
} : idOrOptions;
|
|
7380
7484
|
this.id = resolvedOptions?.id;
|
|
7485
|
+
this.description = resolvedOptions?.description;
|
|
7381
7486
|
this.retryPolicy = resolvedOptions?.retryPolicy;
|
|
7382
7487
|
this.nodeErrorHandler = resolvedOptions?.nodeErrorHandler;
|
|
7383
7488
|
this.declaredOutputPorts = resolvedOptions?.declaredOutputPorts;
|
|
@@ -7579,10 +7684,12 @@ var HttpRequest = class {
|
|
|
7579
7684
|
type = HttpRequestNode;
|
|
7580
7685
|
execution = { hint: "local" };
|
|
7581
7686
|
icon = "lucide:globe";
|
|
7687
|
+
description;
|
|
7582
7688
|
constructor(name, args = {}, retryPolicy = __codemation_core.RetryPolicy.defaultForHttp) {
|
|
7583
7689
|
this.name = name;
|
|
7584
7690
|
this.args = args;
|
|
7585
7691
|
this.retryPolicy = retryPolicy;
|
|
7692
|
+
this.description = args.description;
|
|
7586
7693
|
}
|
|
7587
7694
|
get id() {
|
|
7588
7695
|
return this.args.id;
|
|
@@ -7677,10 +7784,14 @@ var Aggregate = class {
|
|
|
7677
7784
|
execution = { hint: "local" };
|
|
7678
7785
|
keepBinaries = true;
|
|
7679
7786
|
icon = "builtin:aggregate-rows";
|
|
7680
|
-
|
|
7787
|
+
id;
|
|
7788
|
+
description;
|
|
7789
|
+
constructor(name, aggregate, idOrOptions) {
|
|
7681
7790
|
this.name = name;
|
|
7682
7791
|
this.aggregate = aggregate;
|
|
7683
|
-
|
|
7792
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
7793
|
+
this.id = options?.id;
|
|
7794
|
+
this.description = options?.description;
|
|
7684
7795
|
}
|
|
7685
7796
|
inspectorSummary() {
|
|
7686
7797
|
const fnName = this.aggregate.name;
|
|
@@ -7711,10 +7822,14 @@ var Filter = class {
|
|
|
7711
7822
|
type = FilterNode;
|
|
7712
7823
|
execution = { hint: "local" };
|
|
7713
7824
|
icon = "lucide:filter";
|
|
7714
|
-
|
|
7825
|
+
id;
|
|
7826
|
+
description;
|
|
7827
|
+
constructor(name, predicate, idOrOptions) {
|
|
7715
7828
|
this.name = name;
|
|
7716
7829
|
this.predicate = predicate;
|
|
7717
|
-
|
|
7830
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
7831
|
+
this.id = options?.id;
|
|
7832
|
+
this.description = options?.description;
|
|
7718
7833
|
}
|
|
7719
7834
|
inspectorSummary() {
|
|
7720
7835
|
const fnName = this.predicate.name;
|
|
@@ -7789,10 +7904,14 @@ var If = class {
|
|
|
7789
7904
|
execution = { hint: "local" };
|
|
7790
7905
|
icon = "lucide:split@rot=90";
|
|
7791
7906
|
declaredOutputPorts = ["true", "false"];
|
|
7792
|
-
|
|
7907
|
+
id;
|
|
7908
|
+
description;
|
|
7909
|
+
constructor(name, predicate, idOrOptions) {
|
|
7793
7910
|
this.name = name;
|
|
7794
7911
|
this.predicate = predicate;
|
|
7795
|
-
|
|
7912
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
7913
|
+
this.id = options?.id;
|
|
7914
|
+
this.description = options?.description;
|
|
7796
7915
|
}
|
|
7797
7916
|
inspectorSummary() {
|
|
7798
7917
|
const fnName = this.predicate.name;
|
|
@@ -7832,9 +7951,12 @@ var IsTestRun = class {
|
|
|
7832
7951
|
declaredOutputPorts = ["true", "false"];
|
|
7833
7952
|
name;
|
|
7834
7953
|
id;
|
|
7835
|
-
|
|
7954
|
+
description;
|
|
7955
|
+
constructor(name = "Is test run?", idOrOptions) {
|
|
7836
7956
|
this.name = name;
|
|
7837
|
-
|
|
7957
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
7958
|
+
this.id = options?.id;
|
|
7959
|
+
this.description = options?.description;
|
|
7838
7960
|
}
|
|
7839
7961
|
};
|
|
7840
7962
|
|
|
@@ -7863,11 +7985,15 @@ var Switch = class {
|
|
|
7863
7985
|
execution = { hint: "local" };
|
|
7864
7986
|
icon = "lucide:git-branch-plus";
|
|
7865
7987
|
declaredOutputPorts;
|
|
7866
|
-
|
|
7988
|
+
id;
|
|
7989
|
+
description;
|
|
7990
|
+
constructor(name, cfg, idOrOptions) {
|
|
7867
7991
|
this.name = name;
|
|
7868
7992
|
this.cfg = cfg;
|
|
7869
|
-
this.id = id;
|
|
7870
7993
|
this.declaredOutputPorts = [...new Set([...cfg.cases, cfg.defaultCase])].sort();
|
|
7994
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
7995
|
+
this.id = options?.id;
|
|
7996
|
+
this.description = options?.description;
|
|
7871
7997
|
}
|
|
7872
7998
|
inspectorSummary() {
|
|
7873
7999
|
const rows = [{
|
|
@@ -7906,10 +8032,14 @@ var Split = class {
|
|
|
7906
8032
|
*/
|
|
7907
8033
|
continueWhenEmptyOutput = true;
|
|
7908
8034
|
icon = "builtin:split-rows";
|
|
7909
|
-
|
|
8035
|
+
id;
|
|
8036
|
+
description;
|
|
8037
|
+
constructor(name, getElements, idOrOptions) {
|
|
7910
8038
|
this.name = name;
|
|
7911
8039
|
this.getElements = getElements;
|
|
7912
|
-
|
|
8040
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8041
|
+
this.id = options?.id;
|
|
8042
|
+
this.description = options?.description;
|
|
7913
8043
|
}
|
|
7914
8044
|
inspectorSummary() {
|
|
7915
8045
|
const fnName = this.getElements.name;
|
|
@@ -7967,14 +8097,17 @@ var CronTrigger = class {
|
|
|
7967
8097
|
type = CronTriggerNode;
|
|
7968
8098
|
icon = "lucide:clock";
|
|
7969
8099
|
id;
|
|
7970
|
-
|
|
8100
|
+
description;
|
|
8101
|
+
constructor(name, args, idOrOptions) {
|
|
7971
8102
|
this.name = name;
|
|
7972
8103
|
this.args = args;
|
|
7973
8104
|
new croner.Cron(args.schedule, {
|
|
7974
8105
|
paused: true,
|
|
7975
8106
|
timezone: args.timezone
|
|
7976
8107
|
});
|
|
7977
|
-
|
|
8108
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8109
|
+
this.id = options?.id;
|
|
8110
|
+
this.description = options?.description;
|
|
7978
8111
|
}
|
|
7979
8112
|
get schedule() {
|
|
7980
8113
|
return this.args.schedule;
|
|
@@ -8028,20 +8161,21 @@ var ManualTrigger = class ManualTrigger {
|
|
|
8028
8161
|
icon = "lucide:play";
|
|
8029
8162
|
defaultItems;
|
|
8030
8163
|
id;
|
|
8164
|
+
description;
|
|
8031
8165
|
/** Manual runs often emit an empty batch; still schedule downstream by default. */
|
|
8032
8166
|
continueWhenEmptyOutput = true;
|
|
8033
|
-
constructor(name = "Manual trigger", defaultItemsOrId,
|
|
8167
|
+
constructor(name = "Manual trigger", defaultItemsOrId, idOrOptions) {
|
|
8034
8168
|
this.name = name;
|
|
8035
8169
|
this.defaultItems = ManualTrigger.resolveDefaultItems(defaultItemsOrId);
|
|
8036
|
-
|
|
8170
|
+
const trailing = idOrOptions ?? (typeof defaultItemsOrId === "string" ? defaultItemsOrId : void 0);
|
|
8171
|
+
const options = typeof trailing === "string" ? { id: trailing } : trailing ?? {};
|
|
8172
|
+
this.id = options.id;
|
|
8173
|
+
this.description = options.description;
|
|
8037
8174
|
}
|
|
8038
8175
|
static resolveDefaultItems(value) {
|
|
8039
8176
|
if (typeof value === "string" || value === void 0) return;
|
|
8040
8177
|
return this.itemsInputNormalizer.normalize(value);
|
|
8041
8178
|
}
|
|
8042
|
-
static resolveId(value, id) {
|
|
8043
|
-
return typeof value === "string" ? value : id;
|
|
8044
|
-
}
|
|
8045
8179
|
inspectorSummary() {
|
|
8046
8180
|
const rows = [{
|
|
8047
8181
|
label: "Trigger",
|
|
@@ -8087,11 +8221,13 @@ var MapData = class {
|
|
|
8087
8221
|
continueWhenEmptyOutput = true;
|
|
8088
8222
|
icon = "lucide:square-pen";
|
|
8089
8223
|
keepBinaries;
|
|
8224
|
+
description;
|
|
8090
8225
|
constructor(name, map, options = {}) {
|
|
8091
8226
|
this.name = name;
|
|
8092
8227
|
this.map = map;
|
|
8093
8228
|
this.options = options;
|
|
8094
8229
|
this.keepBinaries = options.keepBinaries ?? true;
|
|
8230
|
+
this.description = options.description;
|
|
8095
8231
|
}
|
|
8096
8232
|
get id() {
|
|
8097
8233
|
return this.options.id;
|
|
@@ -8164,10 +8300,14 @@ var Merge = class {
|
|
|
8164
8300
|
kind = "node";
|
|
8165
8301
|
type = MergeNode;
|
|
8166
8302
|
icon = "lucide:merge@rot=90";
|
|
8167
|
-
|
|
8303
|
+
id;
|
|
8304
|
+
description;
|
|
8305
|
+
constructor(name, cfg = { mode: "passThrough" }, idOrOptions) {
|
|
8168
8306
|
this.name = name;
|
|
8169
8307
|
this.cfg = cfg;
|
|
8170
|
-
|
|
8308
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8309
|
+
this.id = options?.id;
|
|
8310
|
+
this.description = options?.description;
|
|
8171
8311
|
}
|
|
8172
8312
|
inspectorSummary() {
|
|
8173
8313
|
const rows = [{
|
|
@@ -8200,9 +8340,13 @@ var NoOp = class {
|
|
|
8200
8340
|
type = NoOpNode;
|
|
8201
8341
|
execution = { hint: "local" };
|
|
8202
8342
|
icon = "lucide:circle-dashed";
|
|
8203
|
-
|
|
8343
|
+
id;
|
|
8344
|
+
description;
|
|
8345
|
+
constructor(name = "NoOp", idOrOptions) {
|
|
8204
8346
|
this.name = name;
|
|
8205
|
-
|
|
8347
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8348
|
+
this.id = options?.id;
|
|
8349
|
+
this.description = options?.description;
|
|
8206
8350
|
}
|
|
8207
8351
|
};
|
|
8208
8352
|
|
|
@@ -8268,12 +8412,16 @@ var SubWorkflow = class {
|
|
|
8268
8412
|
kind = "node";
|
|
8269
8413
|
type = SubWorkflowNode;
|
|
8270
8414
|
icon = "lucide:workflow";
|
|
8271
|
-
|
|
8415
|
+
id;
|
|
8416
|
+
description;
|
|
8417
|
+
constructor(name, workflowId, upstreamRefs, startAt, idOrOptions) {
|
|
8272
8418
|
this.name = name;
|
|
8273
8419
|
this.workflowId = workflowId;
|
|
8274
8420
|
this.upstreamRefs = upstreamRefs;
|
|
8275
8421
|
this.startAt = startAt;
|
|
8276
|
-
|
|
8422
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8423
|
+
this.id = options?.id;
|
|
8424
|
+
this.description = options?.description;
|
|
8277
8425
|
}
|
|
8278
8426
|
inspectorSummary() {
|
|
8279
8427
|
const rows = [{
|
|
@@ -8383,10 +8531,14 @@ var Wait = class {
|
|
|
8383
8531
|
/** Pass-through empty batches should still advance to downstream nodes. */
|
|
8384
8532
|
continueWhenEmptyOutput = true;
|
|
8385
8533
|
icon = "lucide:hourglass";
|
|
8386
|
-
|
|
8534
|
+
id;
|
|
8535
|
+
description;
|
|
8536
|
+
constructor(name, milliseconds, idOrOptions) {
|
|
8387
8537
|
this.name = name;
|
|
8388
8538
|
this.milliseconds = milliseconds;
|
|
8389
|
-
|
|
8539
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8540
|
+
this.id = options?.id;
|
|
8541
|
+
this.description = options?.description;
|
|
8390
8542
|
}
|
|
8391
8543
|
inspectorSummary() {
|
|
8392
8544
|
const seconds = this.milliseconds / 1e3;
|
|
@@ -8441,11 +8593,15 @@ var WebhookTrigger = class WebhookTrigger {
|
|
|
8441
8593
|
kind = "trigger";
|
|
8442
8594
|
type = WebhookTriggerNode;
|
|
8443
8595
|
icon = "lucide:globe";
|
|
8444
|
-
|
|
8596
|
+
id;
|
|
8597
|
+
description;
|
|
8598
|
+
constructor(name, args, handler = WebhookTrigger.defaultHandler, idOrOptions) {
|
|
8445
8599
|
this.name = name;
|
|
8446
8600
|
this.args = args;
|
|
8447
8601
|
this.handler = handler;
|
|
8448
|
-
|
|
8602
|
+
const options = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
8603
|
+
this.id = options?.id;
|
|
8604
|
+
this.description = options?.description;
|
|
8449
8605
|
}
|
|
8450
8606
|
get endpointKey() {
|
|
8451
8607
|
return this.args.endpointKey;
|
|
@@ -8502,11 +8658,21 @@ function createWorkflowBuilder(meta$2) {
|
|
|
8502
8658
|
|
|
8503
8659
|
//#endregion
|
|
8504
8660
|
//#region src/workflowAuthoring/WorkflowChatModelFactory.types.ts
|
|
8661
|
+
const VALID_COMPLEXITY = new Set([
|
|
8662
|
+
"low",
|
|
8663
|
+
"medium",
|
|
8664
|
+
"high",
|
|
8665
|
+
"xhigh"
|
|
8666
|
+
]);
|
|
8505
8667
|
var WorkflowChatModelFactory = class {
|
|
8506
8668
|
static create(model) {
|
|
8507
8669
|
if (typeof model !== "string") return model;
|
|
8508
8670
|
const [provider, resolvedModel] = model.includes(":") ? model.split(":", 2) : ["openai", model];
|
|
8509
|
-
if (provider === "codemation-managed")
|
|
8671
|
+
if (provider === "codemation-managed") {
|
|
8672
|
+
const complexity = resolvedModel ?? "medium";
|
|
8673
|
+
if (!VALID_COMPLEXITY.has(complexity)) throw new Error(`Invalid managed complexity "${complexity}". Must be one of: low, medium, high, xhigh.`);
|
|
8674
|
+
return new CodemationChatModelConfig("Codemation Managed", complexity);
|
|
8675
|
+
}
|
|
8510
8676
|
if (provider !== "openai") throw new Error(`Unsupported workflow().agent() model provider "${provider}".`);
|
|
8511
8677
|
return new OpenAIChatModelConfig("OpenAI", resolvedModel);
|
|
8512
8678
|
}
|
|
@@ -9274,7 +9440,6 @@ Object.defineProperty(exports, 'IsTestRunNode', {
|
|
|
9274
9440
|
return IsTestRunNode;
|
|
9275
9441
|
}
|
|
9276
9442
|
});
|
|
9277
|
-
exports.ManagedModelFetcher = ManagedModelFetcher;
|
|
9278
9443
|
exports.ManualTrigger = ManualTrigger;
|
|
9279
9444
|
Object.defineProperty(exports, 'ManualTriggerNode', {
|
|
9280
9445
|
enumerable: true,
|