@codemation/core-nodes 0.4.3 → 1.0.1

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/dist/index.js CHANGED
@@ -1,10 +1,7 @@
1
1
  import { AgentConfigInspector, AgentConnectionNodeCollector, AgentGuardrailDefaults, AgentMessageConfigNormalizer, CallableToolConfig, CodemationTelemetryAttributeNames, CodemationTelemetryMetricNames, ConnectionInvocationIdFactory, ConnectionNodeIdFactory, CoreTokens, DefinedNodeRegistry, GenAiTelemetryAttributeNames, ItemExprResolver, ItemsInputNormalizer, NodeBackedToolConfig, NodeOutputNormalizer, RetryPolicy, RunnableOutputBehaviorResolver, WorkflowBuilder, chatModel, emitPorts, getOriginIndexFromItem, inject, injectable, isPortsEmission, node } from "@codemation/core";
2
- import { ChatOpenAI } from "@langchain/openai";
3
- import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
4
- import { isInteropZodSchema } from "@langchain/core/utils/types";
5
- import { toJsonSchema } from "@langchain/core/utils/json_schema";
6
- import { DynamicStructuredTool } from "@langchain/core/tools";
2
+ import { createOpenAI } from "@ai-sdk/openai";
7
3
  import { CredentialResolverFactory } from "@codemation/core/bootstrap";
4
+ import { Output, generateText, jsonSchema } from "ai";
8
5
 
9
6
  //#region \0@oxc-project+runtime@0.95.0/helpers/decorate.js
10
7
  function __decorate(decorators, target, key, desc) {
@@ -19,166 +16,21 @@ function __decorate(decorators, target, key, desc) {
19
16
  let OpenAIChatModelFactory = class OpenAIChatModelFactory$1 {
20
17
  async create(args) {
21
18
  const session = await args.ctx.getCredential(args.config.credentialSlotKey);
22
- return new ChatOpenAI({
23
- apiKey: session.apiKey,
24
- model: args.config.model,
25
- temperature: args.config.options?.temperature,
26
- maxTokens: args.config.options?.maxTokens,
27
- configuration: session.baseUrl ? { baseURL: session.baseUrl } : void 0
28
- });
29
- }
30
- };
31
- OpenAIChatModelFactory = __decorate([chatModel({ packageName: "@codemation/core-nodes" })], OpenAIChatModelFactory);
32
-
33
- //#endregion
34
- //#region src/chatModels/OpenAIStructuredOutputMethodFactory.ts
35
- var _OpenAIStructuredOutputMethodFactory;
36
- let OpenAIStructuredOutputMethodFactory = class OpenAIStructuredOutputMethodFactory$1 {
37
- static {
38
- _OpenAIStructuredOutputMethodFactory = this;
39
- }
40
- static isoDatePattern = /^\d{4}-\d{2}-\d{2}$/;
41
- create(chatModelConfig) {
42
- if (chatModelConfig.type !== OpenAIChatModelFactory) return;
43
- const model = this.readModelName(chatModelConfig);
44
- if (!model) return {
45
- method: "functionCalling",
46
- strict: true
47
- };
48
19
  return {
49
- method: this.supportsJsonSchema(model) ? "jsonSchema" : "functionCalling",
50
- strict: true
51
- };
52
- }
53
- readModelName(chatModelConfig) {
54
- const candidate = chatModelConfig;
55
- return typeof candidate.model === "string" ? candidate.model : void 0;
56
- }
57
- supportsJsonSchema(model) {
58
- if (model === "gpt-4o" || model === "gpt-4o-mini") return true;
59
- return this.supportsSnapshotAtOrAfter(model, "gpt-4o-", "2024-08-06") || this.supportsSnapshotAtOrAfter(model, "gpt-4o-mini-", "2024-07-18");
60
- }
61
- supportsSnapshotAtOrAfter(model, prefix, minimumSnapshotDate) {
62
- if (!model.startsWith(prefix)) return false;
63
- const snapshotDate = model.slice(prefix.length);
64
- return _OpenAIStructuredOutputMethodFactory.isoDatePattern.test(snapshotDate) && snapshotDate >= minimumSnapshotDate;
65
- }
66
- };
67
- OpenAIStructuredOutputMethodFactory = _OpenAIStructuredOutputMethodFactory = __decorate([injectable()], OpenAIStructuredOutputMethodFactory);
68
-
69
- //#endregion
70
- //#region src/chatModels/openAiChatModelConfig.ts
71
- var OpenAIChatModelConfig = class {
72
- type = OpenAIChatModelFactory;
73
- presentation;
74
- provider = "openai";
75
- modelName;
76
- constructor(name, model, credentialSlotKey = "openai", presentationIn, options) {
77
- this.name = name;
78
- this.model = model;
79
- this.credentialSlotKey = credentialSlotKey;
80
- this.options = options;
81
- this.modelName = model;
82
- this.presentation = presentationIn ?? {
83
- icon: "builtin:openai",
84
- label: name
85
- };
86
- }
87
- getCredentialRequirements() {
88
- return [{
89
- slotKey: this.credentialSlotKey,
90
- label: "OpenAI API key",
91
- acceptedTypes: ["openai.apiKey"]
92
- }];
93
- }
94
- };
95
-
96
- //#endregion
97
- //#region src/chatModels/OpenAiChatModelPresetsFactory.ts
98
- /**
99
- * Default OpenAI chat model configs for scaffolds and demos (icon + label match {@link OpenAIChatModelConfig} defaults).
100
- * Prefer importing {@link openAiChatModelPresets} from here or from the consumer template re-export
101
- * instead of repeating {@link OpenAIChatModelConfig} construction in app workflows.
102
- */
103
- var OpenAiChatModelPresets = class {
104
- demoGpt4oMini = new OpenAIChatModelConfig("OpenAI", "gpt-4o-mini");
105
- demoGpt41 = new OpenAIChatModelConfig("OpenAI", "gpt-4.1");
106
- };
107
- const openAiChatModelPresets = new OpenAiChatModelPresets();
108
-
109
- //#endregion
110
- //#region src/nodes/AgentMessageFactory.ts
111
- var AgentMessageFactory = class {
112
- static createPromptMessages(messages) {
113
- return messages.map((message) => this.createPromptMessage(message));
114
- }
115
- static createSystemPrompt(systemMessage) {
116
- return new SystemMessage(systemMessage);
117
- }
118
- static createUserPrompt(prompt) {
119
- return new HumanMessage(prompt);
120
- }
121
- static createAssistantPrompt(prompt) {
122
- return new AIMessage(prompt);
123
- }
124
- static createToolMessage(toolCallId, content) {
125
- return new ToolMessage({
126
- tool_call_id: toolCallId,
127
- content
128
- });
129
- }
130
- static extractContent(message) {
131
- if (typeof message === "string") return message;
132
- if (!this.isRecord(message)) return String(message);
133
- const content = message.content;
134
- if (typeof content === "string") return content;
135
- if (Array.isArray(content)) return content.map((part) => {
136
- if (typeof part === "string") return part;
137
- if (this.isRecord(part) && typeof part.text === "string") return part.text;
138
- return JSON.stringify(part);
139
- }).join("\n");
140
- return JSON.stringify(content);
141
- }
142
- static extractToolCalls(message) {
143
- if (!this.isRecord(message)) return [];
144
- const toolCalls = message.tool_calls;
145
- if (!Array.isArray(toolCalls)) return [];
146
- return toolCalls.filter((toolCall) => this.isRecord(toolCall) && typeof toolCall.name === "string").map((toolCall) => ({
147
- id: typeof toolCall.id === "string" ? toolCall.id : void 0,
148
- name: toolCall.name,
149
- input: this.isRecord(toolCall) && "args" in toolCall ? toolCall.args : void 0
150
- }));
151
- }
152
- static isRecord(value) {
153
- return typeof value === "object" && value !== null;
154
- }
155
- static createPromptMessage(message) {
156
- if (message.role === "system") return this.createSystemPrompt(message.content);
157
- if (message.role === "assistant") return this.createAssistantPrompt(message.content);
158
- return this.createUserPrompt(message.content);
159
- }
160
- };
161
-
162
- //#endregion
163
- //#region src/nodes/AgentOutputFactory.ts
164
- var AgentOutputFactory = class {
165
- static fromUnknown(value) {
166
- return { main: [{ json: value }] };
167
- }
168
- static replaceJson(item, value) {
169
- return {
170
- ...item,
171
- json: value
20
+ languageModel: createOpenAI({
21
+ apiKey: session.apiKey,
22
+ baseURL: session.baseUrl
23
+ }).chat(args.config.model),
24
+ modelName: args.config.model,
25
+ provider: "openai",
26
+ defaultCallOptions: {
27
+ maxOutputTokens: args.config.options?.maxTokens,
28
+ temperature: args.config.options?.temperature
29
+ }
172
30
  };
173
31
  }
174
- static fromAgentContent(content) {
175
- try {
176
- return JSON.parse(content);
177
- } catch {
178
- return { output: content };
179
- }
180
- }
181
32
  };
33
+ OpenAIChatModelFactory = __decorate([chatModel({ packageName: "@codemation/core-nodes" })], OpenAIChatModelFactory);
182
34
 
183
35
  //#endregion
184
36
  //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.js
@@ -2100,53 +1952,35 @@ let AIAgentExecutionHelpersFactory = class AIAgentExecutionHelpersFactory$1 {
2100
1952
  createConnectionCredentialExecutionContextFactory(credentialSessions) {
2101
1953
  return new ConnectionCredentialExecutionContextFactory(credentialSessions);
2102
1954
  }
2103
- createDynamicStructuredTool(entry, toolCredentialContext, item, itemIndex, items) {
2104
- if (entry.runtime.inputSchema == null) throw new Error(`Cannot create LangChain tool "${entry.config.name}": missing inputSchema (broken tool runtime resolution).`);
2105
- const schemaForOpenAi = this.createJsonSchemaRecord(entry.runtime.inputSchema, {
2106
- schemaName: entry.config.name,
2107
- requireObjectRoot: true
2108
- });
2109
- return new DynamicStructuredTool({
2110
- name: entry.config.name,
2111
- description: entry.config.description ?? entry.runtime.defaultDescription,
2112
- schema: schemaForOpenAi,
2113
- func: async (input) => {
2114
- const result = await entry.runtime.execute({
2115
- config: entry.config,
2116
- input,
2117
- ctx: toolCredentialContext,
2118
- item,
2119
- itemIndex,
2120
- items
2121
- });
2122
- return JSON.stringify(result);
2123
- }
2124
- });
2125
- }
2126
1955
  /**
2127
- * Produces a plain JSON Schema object for OpenAI tool parameters and LangChain tool invocation:
2128
- * - **Zod** `toJSONSchema(..., { target: "draft-07" })` so shapes match what `@cfworker/json-schema`
2129
- * expects (`required` must be an array; draft 2020-12 output can break validation).
2130
- * - Otherwise LangChain `toJsonSchema` (Standard Schema + JSON passthrough); if the result is still Zod
2131
- * (duplicate `zod` copies), fall back to Zod `toJSONSchema` with draft-07.
2132
- * - Strip root `$schema` for OpenAI; normalize invalid `required` keywords for cfworker; ensure `properties`.
1956
+ * Produces a plain JSON Schema object (`draft-07`) from a Zod schema, as needed by
1957
+ * OpenAI tool-parameter schemas and the structured-output repair prompt.
1958
+ * - Prefers the schema's **instance** `toJSONSchema(...)` method so we stay inside the Zod
1959
+ * instance that created the schema (works across consumer/framework tsx namespaces see
1960
+ * {@link ZodInstanceToJsonSchema}). Falls back to the framework-imported module function.
1961
+ * - Strips root `$schema` (OpenAI ignores it).
1962
+ * - Sanitizes `required` for cfworker json-schema compatibility (must be a string array or absent).
2133
1963
  */
2134
1964
  createJsonSchemaRecord(inputSchema, options) {
2135
- const draft07Params = { target: "draft-07" };
2136
- let converted;
2137
- if (isInteropZodSchema(inputSchema)) converted = toJSONSchema(inputSchema, draft07Params);
2138
- else {
2139
- converted = toJsonSchema(inputSchema);
2140
- if (isInteropZodSchema(converted)) converted = toJSONSchema(inputSchema, draft07Params);
2141
- }
2142
- const { $schema: _draftSchemaOmitted,...rest } = converted;
2143
- if (options.requireObjectRoot && rest.type !== "object") throw new Error(`Cannot create LangChain tool "${options.schemaName}": tool input schema must be a JSON Schema object type (got type=${String(rest.type)}).`);
2144
- if (options.requireObjectRoot && rest.properties !== void 0 && (typeof rest.properties !== "object" || Array.isArray(rest.properties))) throw new Error(`Cannot create LangChain tool "${options.schemaName}": tool input schema "properties" must be an object (got ${JSON.stringify(rest.properties)}).`);
1965
+ const { $schema: _draftSchemaOmitted,...rest } = this.convertZodSchemaToJsonSchema(inputSchema, { target: "draft-07" });
1966
+ 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)}).`);
1967
+ if (options.requireObjectRoot && rest.properties !== void 0 && (typeof rest.properties !== "object" || Array.isArray(rest.properties))) throw new Error(`Cannot create tool "${options.schemaName}": tool input schema "properties" must be an object (got ${JSON.stringify(rest.properties)}).`);
2145
1968
  if (options.requireObjectRoot && rest.properties === void 0) rest.properties = {};
2146
1969
  this.sanitizeJsonSchemaRequiredKeywordsForCfworker(rest);
2147
1970
  return rest;
2148
1971
  }
2149
1972
  /**
1973
+ * Runs Zod's `toJSONSchema` via the schema's own instance method when available, so consumer
1974
+ * schemas loaded under a different tsx namespace still convert correctly. If the caller handed us
1975
+ * a payload that lacks that method (e.g. a plain JSON Schema record or a Zod instance whose
1976
+ * prototype was stripped), we fall back to the framework-bundled module function.
1977
+ */
1978
+ convertZodSchemaToJsonSchema(inputSchema, params) {
1979
+ const candidate = inputSchema.toJSONSchema;
1980
+ if (typeof candidate === "function") return candidate.call(inputSchema, params);
1981
+ return toJSONSchema(inputSchema, params);
1982
+ }
1983
+ /**
2150
1984
  * `@cfworker/json-schema` iterates `schema.required` with `for...of`; it must be a string array or absent.
2151
1985
  */
2152
1986
  sanitizeJsonSchemaRequiredKeywordsForCfworker(node$1) {
@@ -2193,6 +2027,214 @@ function __decorateParam(paramIndex, decorator) {
2193
2027
  };
2194
2028
  }
2195
2029
 
2030
+ //#endregion
2031
+ //#region src/chatModels/OpenAiStrictJsonSchemaFactory.ts
2032
+ var _ref$5;
2033
+ let OpenAiStrictJsonSchemaFactory = class OpenAiStrictJsonSchemaFactory$1 {
2034
+ constructor(executionHelpers) {
2035
+ this.executionHelpers = executionHelpers;
2036
+ }
2037
+ createStructuredOutputRecord(schema, options) {
2038
+ const record = this.executionHelpers.createJsonSchemaRecord(schema, {
2039
+ schemaName: options.schemaName,
2040
+ requireObjectRoot: false
2041
+ });
2042
+ this.strictifyRecursive(record);
2043
+ if (options.title !== void 0) record.title = options.title;
2044
+ return record;
2045
+ }
2046
+ strictifyRecursive(node$1) {
2047
+ if (!node$1 || typeof node$1 !== "object" || Array.isArray(node$1)) return;
2048
+ const o = node$1;
2049
+ this.stripOpenAiRejectedKeywords(o);
2050
+ if (this.isObjectNode(o)) {
2051
+ const props = this.readPropertiesObject(o);
2052
+ o.properties = props;
2053
+ o.additionalProperties = false;
2054
+ o.required = Object.keys(props);
2055
+ for (const value of Object.values(props)) this.strictifyRecursive(value);
2056
+ }
2057
+ this.recurseIntoComposites(o);
2058
+ }
2059
+ stripOpenAiRejectedKeywords(o) {
2060
+ delete o["$schema"];
2061
+ delete o["unevaluatedProperties"];
2062
+ delete o["default"];
2063
+ }
2064
+ isObjectNode(o) {
2065
+ const typeIsObject = o.type === "object" || Array.isArray(o.type) && o.type.includes("object");
2066
+ const hasObjectProperties = o.properties !== void 0 && typeof o.properties === "object" && !Array.isArray(o.properties);
2067
+ return typeIsObject || hasObjectProperties;
2068
+ }
2069
+ readPropertiesObject(o) {
2070
+ if (o.properties && typeof o.properties === "object" && !Array.isArray(o.properties)) return o.properties;
2071
+ return {};
2072
+ }
2073
+ recurseIntoComposites(o) {
2074
+ for (const key of [
2075
+ "allOf",
2076
+ "anyOf",
2077
+ "oneOf",
2078
+ "prefixItems"
2079
+ ]) {
2080
+ const branch = o[key];
2081
+ if (Array.isArray(branch)) for (const sub of branch) this.strictifyRecursive(sub);
2082
+ }
2083
+ if (o.not) this.strictifyRecursive(o.not);
2084
+ if (o.items) if (Array.isArray(o.items)) for (const sub of o.items) this.strictifyRecursive(sub);
2085
+ else this.strictifyRecursive(o.items);
2086
+ for (const key of [
2087
+ "if",
2088
+ "then",
2089
+ "else"
2090
+ ]) if (o[key]) this.strictifyRecursive(o[key]);
2091
+ for (const key of ["$defs", "definitions"]) {
2092
+ const defs = o[key];
2093
+ if (defs && typeof defs === "object" && !Array.isArray(defs)) for (const sub of Object.values(defs)) this.strictifyRecursive(sub);
2094
+ }
2095
+ }
2096
+ };
2097
+ OpenAiStrictJsonSchemaFactory = __decorate([
2098
+ injectable(),
2099
+ __decorateParam(0, inject(AIAgentExecutionHelpersFactory)),
2100
+ __decorateMetadata("design:paramtypes", [typeof (_ref$5 = typeof AIAgentExecutionHelpersFactory !== "undefined" && AIAgentExecutionHelpersFactory) === "function" ? _ref$5 : Object])
2101
+ ], OpenAiStrictJsonSchemaFactory);
2102
+
2103
+ //#endregion
2104
+ //#region src/chatModels/openAiChatModelConfig.ts
2105
+ var OpenAIChatModelConfig = class {
2106
+ type = OpenAIChatModelFactory;
2107
+ presentation;
2108
+ provider = "openai";
2109
+ modelName;
2110
+ constructor(name, model, credentialSlotKey = "openai", presentationIn, options) {
2111
+ this.name = name;
2112
+ this.model = model;
2113
+ this.credentialSlotKey = credentialSlotKey;
2114
+ this.options = options;
2115
+ this.modelName = model;
2116
+ this.presentation = presentationIn ?? {
2117
+ icon: "builtin:openai",
2118
+ label: name
2119
+ };
2120
+ }
2121
+ getCredentialRequirements() {
2122
+ return [{
2123
+ slotKey: this.credentialSlotKey,
2124
+ label: "OpenAI API key",
2125
+ acceptedTypes: ["openai.apiKey"]
2126
+ }];
2127
+ }
2128
+ };
2129
+
2130
+ //#endregion
2131
+ //#region src/chatModels/OpenAiChatModelPresetsFactory.ts
2132
+ /**
2133
+ * Default OpenAI chat model configs for scaffolds and demos (icon + label match {@link OpenAIChatModelConfig} defaults).
2134
+ * Prefer importing {@link openAiChatModelPresets} from here or from the consumer template re-export
2135
+ * instead of repeating {@link OpenAIChatModelConfig} construction in app workflows.
2136
+ */
2137
+ var OpenAiChatModelPresets = class {
2138
+ demoGpt4oMini = new OpenAIChatModelConfig("OpenAI", "gpt-4o-mini");
2139
+ demoGpt41 = new OpenAIChatModelConfig("OpenAI", "gpt-4.1");
2140
+ };
2141
+ const openAiChatModelPresets = new OpenAiChatModelPresets();
2142
+
2143
+ //#endregion
2144
+ //#region src/nodes/AgentMessageFactory.ts
2145
+ /**
2146
+ * AI-SDK-shaped message construction for the AIAgent stack. Emits plain `ModelMessage[]`
2147
+ * ( `{ role: 'system' | 'user' | 'assistant' | 'tool', content: ... }` ) as consumed by
2148
+ * `generateText({ messages })` from the `ai` package.
2149
+ */
2150
+ var AgentMessageFactory = class AgentMessageFactory {
2151
+ static createPromptMessages(messages) {
2152
+ return messages.map((message) => this.createPromptMessage(message));
2153
+ }
2154
+ /**
2155
+ * Builds the assistant message that contains optional text plus one or more tool-call parts,
2156
+ * matching the shape AI SDK emits between steps.
2157
+ */
2158
+ static createAssistantWithToolCalls(text, toolCalls) {
2159
+ const content = [];
2160
+ if (text && text.length > 0) content.push({
2161
+ type: "text",
2162
+ text
2163
+ });
2164
+ for (const toolCall of toolCalls) content.push({
2165
+ type: "tool-call",
2166
+ toolCallId: toolCall.id ?? toolCall.name,
2167
+ toolName: toolCall.name,
2168
+ input: toolCall.input ?? {}
2169
+ });
2170
+ return {
2171
+ role: "assistant",
2172
+ content
2173
+ };
2174
+ }
2175
+ /**
2176
+ * Builds the `{ role: "tool", content: [{ type: "tool-result", ... }, ...] }` message returned
2177
+ * to the model after each tool round.
2178
+ */
2179
+ static createToolResultsMessage(executedToolCalls) {
2180
+ return {
2181
+ role: "tool",
2182
+ content: executedToolCalls.map((executed) => ({
2183
+ type: "tool-result",
2184
+ toolCallId: executed.toolCallId,
2185
+ toolName: executed.toolName,
2186
+ output: {
2187
+ type: "json",
2188
+ value: AgentMessageFactory.toToolResultJson(executed.result)
2189
+ }
2190
+ }))
2191
+ };
2192
+ }
2193
+ static toToolResultJson(value) {
2194
+ if (value === void 0) return null;
2195
+ try {
2196
+ return JSON.parse(JSON.stringify(value));
2197
+ } catch {
2198
+ return String(value);
2199
+ }
2200
+ }
2201
+ static createPromptMessage(message) {
2202
+ if (message.role === "system") return {
2203
+ role: "system",
2204
+ content: message.content
2205
+ };
2206
+ if (message.role === "assistant") return {
2207
+ role: "assistant",
2208
+ content: message.content
2209
+ };
2210
+ return {
2211
+ role: "user",
2212
+ content: message.content
2213
+ };
2214
+ }
2215
+ };
2216
+
2217
+ //#endregion
2218
+ //#region src/nodes/AgentOutputFactory.ts
2219
+ var AgentOutputFactory = class {
2220
+ static fromUnknown(value) {
2221
+ return { main: [{ json: value }] };
2222
+ }
2223
+ static replaceJson(item, value) {
2224
+ return {
2225
+ ...item,
2226
+ json: value
2227
+ };
2228
+ }
2229
+ static fromAgentContent(content) {
2230
+ try {
2231
+ return JSON.parse(content);
2232
+ } catch {
2233
+ return { output: content };
2234
+ }
2235
+ }
2236
+ };
2237
+
2196
2238
  //#endregion
2197
2239
  //#region src/nodes/AgentStructuredOutputRepairPromptFactory.ts
2198
2240
  var _ref$4, _AgentStructuredOutputRepairPromptFactory;
@@ -2571,31 +2613,26 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2571
2613
  _AgentStructuredOutputRunner = this;
2572
2614
  }
2573
2615
  static repairAttemptCount = 2;
2574
- constructor(repairPromptFactory, openAiStructuredOutputMethodFactory) {
2616
+ static structuredOutputSchemaName = "agent_output";
2617
+ constructor(repairPromptFactory, openAiStrictJsonSchemaFactory) {
2575
2618
  this.repairPromptFactory = repairPromptFactory;
2576
- this.openAiStructuredOutputMethodFactory = openAiStructuredOutputMethodFactory;
2619
+ this.openAiStrictJsonSchemaFactory = openAiStrictJsonSchemaFactory;
2577
2620
  }
2578
2621
  async resolve(args) {
2579
2622
  let lastFailure;
2580
- if (args.rawFinalResponse) {
2581
- const directResult = this.tryParseAndValidate(AgentMessageFactory.extractContent(args.rawFinalResponse), args.schema);
2582
- if (directResult.ok) return directResult.value;
2583
- lastFailure = directResult;
2584
- } else if (!this.supportsNativeStructuredOutput(args.model)) {
2585
- const rawResponse = await args.invokeTextModel(args.conversation);
2586
- const directResult = this.tryParseAndValidate(AgentMessageFactory.extractContent(rawResponse), args.schema);
2623
+ if (args.rawFinalText !== void 0) {
2624
+ const directResult = this.tryParseAndValidate(args.rawFinalText, args.schema);
2587
2625
  if (directResult.ok) return directResult.value;
2588
2626
  lastFailure = directResult;
2589
2627
  }
2590
2628
  try {
2591
- const nativeStructuredModel = this.createStructuredOutputModel(args.model, args.chatModelConfig, args.schema);
2592
- if (nativeStructuredModel) {
2593
- const nativeResult = this.tryValidateStructuredValue(await args.invokeStructuredModel(nativeStructuredModel, args.conversation), args.schema);
2594
- if (nativeResult.ok) return nativeResult.value;
2595
- lastFailure = nativeResult;
2596
- }
2629
+ const structuredOptions = this.resolveStructuredOutputOptions(args.chatModelConfig);
2630
+ const schemaForModel = this.resolveOutputSchemaForModel(args.schema, structuredOptions);
2631
+ const nativeResult = this.tryValidateStructuredValue(await args.invokeStructuredModel(schemaForModel, args.conversation, structuredOptions), args.schema);
2632
+ if (nativeResult.ok) return nativeResult.value;
2633
+ lastFailure = nativeResult;
2597
2634
  } catch (error) {
2598
- lastFailure = {
2635
+ lastFailure = lastFailure ?? {
2599
2636
  ok: false,
2600
2637
  invalidContent: "",
2601
2638
  validationError: `Native structured output failed: ${this.summarizeError(error)}`
@@ -2619,22 +2656,26 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2619
2656
  validationError: failure.validationError
2620
2657
  }))];
2621
2658
  const repairResponse = await args.invokeTextModel(repairMessages);
2622
- const repairResult = this.tryParseAndValidate(AgentMessageFactory.extractContent(repairResponse), args.schema);
2659
+ const repairResult = this.tryParseAndValidate(repairResponse.text, args.schema);
2623
2660
  if (repairResult.ok) return repairResult.value;
2624
2661
  failure = repairResult;
2625
2662
  }
2626
2663
  throw new Error(`Structured output required for AIAgent "${args.agentName}" (${args.nodeId}) but validation still failed after ${_AgentStructuredOutputRunner.repairAttemptCount} repair attempts: ${failure.validationError}`);
2627
2664
  }
2628
- createStructuredOutputModel(model, chatModelConfig, schema) {
2629
- if (!this.supportsNativeStructuredOutput(model)) return;
2630
- const options = this.getStructuredOutputOptions(chatModelConfig);
2631
- return model.withStructuredOutput(schema, options);
2632
- }
2633
- getStructuredOutputOptions(chatModelConfig) {
2634
- return this.openAiStructuredOutputMethodFactory.create(chatModelConfig) ?? { strict: true };
2665
+ /**
2666
+ * Chooses strict mode for OpenAI chat-model configs, off otherwise. Extendable in future for
2667
+ * other providers that adopt the same "supply a JSON Schema record directly" contract.
2668
+ */
2669
+ resolveStructuredOutputOptions(chatModelConfig) {
2670
+ if (chatModelConfig.type !== OpenAIChatModelFactory) return;
2671
+ return {
2672
+ strict: true,
2673
+ schemaName: _AgentStructuredOutputRunner.structuredOutputSchemaName
2674
+ };
2635
2675
  }
2636
- supportsNativeStructuredOutput(model) {
2637
- return typeof model.withStructuredOutput === "function";
2676
+ resolveOutputSchemaForModel(schema, options) {
2677
+ if (!options?.strict) return schema;
2678
+ return this.openAiStrictJsonSchemaFactory.createStructuredOutputRecord(schema, { schemaName: options.schemaName ?? _AgentStructuredOutputRunner.structuredOutputSchemaName });
2638
2679
  }
2639
2680
  tryParseAndValidate(content, schema) {
2640
2681
  try {
@@ -2668,7 +2709,7 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2668
2709
  }
2669
2710
  toJson(value) {
2670
2711
  try {
2671
- return JSON.stringify(value);
2712
+ return JSON.stringify(value) ?? String(value);
2672
2713
  } catch (error) {
2673
2714
  return `<<unserializable: ${this.summarizeError(error)}>>`;
2674
2715
  }
@@ -2677,8 +2718,8 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2677
2718
  AgentStructuredOutputRunner = _AgentStructuredOutputRunner = __decorate([
2678
2719
  injectable(),
2679
2720
  __decorateParam(0, inject(AgentStructuredOutputRepairPromptFactory)),
2680
- __decorateParam(1, inject(OpenAIStructuredOutputMethodFactory)),
2681
- __decorateMetadata("design:paramtypes", [typeof (_ref$3 = typeof AgentStructuredOutputRepairPromptFactory !== "undefined" && AgentStructuredOutputRepairPromptFactory) === "function" ? _ref$3 : Object, typeof (_ref2$3 = typeof OpenAIStructuredOutputMethodFactory !== "undefined" && OpenAIStructuredOutputMethodFactory) === "function" ? _ref2$3 : Object])
2721
+ __decorateParam(1, inject(OpenAiStrictJsonSchemaFactory)),
2722
+ __decorateMetadata("design:paramtypes", [typeof (_ref$3 = typeof AgentStructuredOutputRepairPromptFactory !== "undefined" && AgentStructuredOutputRepairPromptFactory) === "function" ? _ref$3 : Object, typeof (_ref2$3 = typeof OpenAiStrictJsonSchemaFactory !== "undefined" && OpenAiStrictJsonSchemaFactory) === "function" ? _ref2$3 : Object])
2682
2723
  ], AgentStructuredOutputRunner);
2683
2724
 
2684
2725
  //#endregion
@@ -2832,8 +2873,8 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2832
2873
  inputsByPort: toolCallInputsByPort
2833
2874
  });
2834
2875
  try {
2835
- const serialized = await plannedToolCall.binding.langChainTool.invoke(plannedToolCall.toolCall.input ?? {});
2836
- const result = this.parseToolOutput(serialized);
2876
+ const result = await plannedToolCall.binding.execute(plannedToolCall.toolCall.input ?? {});
2877
+ const serialized = typeof result === "string" ? result : JSON.stringify(result);
2837
2878
  const finishedAt = /* @__PURE__ */ new Date();
2838
2879
  await ctx.nodeState?.markCompleted({
2839
2880
  nodeId: plannedToolCall.nodeId,
@@ -2877,7 +2918,7 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2877
2918
  const classification = this.errorClassifier.classify({
2878
2919
  error,
2879
2920
  toolName: plannedToolCall.binding.config.name,
2880
- schema: plannedToolCall.binding.langChainTool.schema
2921
+ schema: plannedToolCall.binding.inputSchema
2881
2922
  });
2882
2923
  if (classification.kind !== "repairable_validation_error") {
2883
2924
  const effectiveError = classification.effectiveError;
@@ -3040,14 +3081,6 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
3040
3081
  if (!firstIssue) return `Your previous tool call for "${toolName}" was invalid and did not match the expected schema.`;
3041
3082
  return `Your previous tool call for "${toolName}" was invalid because field "${firstIssue.path.length > 0 ? firstIssue.path.join(".") : "<root>"}" failed validation: ${firstIssue.message}`;
3042
3083
  }
3043
- parseToolOutput(serialized) {
3044
- if (typeof serialized !== "string") return serialized;
3045
- try {
3046
- return JSON.parse(serialized);
3047
- } catch {
3048
- return serialized;
3049
- }
3050
- }
3051
3084
  toJsonValue(value) {
3052
3085
  if (value === void 0) return;
3053
3086
  return JSON.parse(JSON.stringify(value));
@@ -3167,14 +3200,8 @@ var _ref, _ref2, _ref3, _ref4;
3167
3200
  let AIAgentNode = class AIAgentNode$1 {
3168
3201
  kind = "node";
3169
3202
  outputPorts = ["main"];
3170
- /**
3171
- * Engine validates {@link RunnableNodeConfig.inputSchema} (Zod) on {@code item.json} before enqueue, then resolves
3172
- * per-item **`itemExpr`** leaves on config before {@link #execute}. Prefer modeling prompts as
3173
- * {@code { messages: [{ role, content }, ...] }} (on input or config) so persisted inputs are visible in the UI.
3174
- */
3175
3203
  inputSchema = unknown();
3176
3204
  connectionCredentialExecutionContextFactory;
3177
- /** One resolved model/tools bundle per activation context (same ctx across items in a batch). */
3178
3205
  preparedByExecutionContext = /* @__PURE__ */ new WeakMap();
3179
3206
  constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner, toolExecutionCoordinator) {
3180
3207
  this.nodeResolver = nodeResolver;
@@ -3205,9 +3232,6 @@ let AIAgentNode = class AIAgentNode$1 {
3205
3232
  throw error;
3206
3233
  }
3207
3234
  }
3208
- /**
3209
- * Resolves the chat model and tools once per activation, then reuses for every item in the batch.
3210
- */
3211
3235
  async prepareExecution(ctx) {
3212
3236
  const chatModelFactory = this.nodeResolver.resolve(ctx.config.chatModel.type);
3213
3237
  const languageModelCredentialContext = this.connectionCredentialExecutionContextFactory.forConnectionNode(ctx, {
@@ -3225,9 +3249,6 @@ let AIAgentNode = class AIAgentNode$1 {
3225
3249
  languageModelConnectionNodeId: ConnectionNodeIdFactory.languageModelConnectionNodeId(ctx.nodeId)
3226
3250
  };
3227
3251
  }
3228
- /**
3229
- * One item: build prompts, optionally bind tools, run the multi-turn loop, map the final model message to workflow JSON.
3230
- */
3231
3252
  async runAgentForItem(prepared, item, itemIndex, items) {
3232
3253
  const { ctx } = prepared;
3233
3254
  const itemInputsByPort = AgentItemPortMap.fromItem(item);
@@ -3241,8 +3262,8 @@ let AIAgentNode = class AIAgentNode$1 {
3241
3262
  conversation,
3242
3263
  agentName: this.getAgentDisplayName(ctx),
3243
3264
  nodeId: ctx.nodeId,
3244
- invokeTextModel: async (messages) => await this.invokeModel(prepared.model, prepared.languageModelConnectionNodeId, messages, ctx, itemInputsByPort, prepared.guardrails.modelInvocationOptions),
3245
- invokeStructuredModel: async (structuredModel, messages) => await this.invokeStructuredModel(structuredModel, prepared.languageModelConnectionNodeId, messages, ctx, itemInputsByPort, prepared.guardrails.modelInvocationOptions)
3265
+ invokeTextModel: async (messages) => await this.invokeTextTurn(prepared, itemInputsByPort, messages, []),
3266
+ invokeStructuredModel: async (schema, messages, structuredOptions) => await this.invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions)
3246
3267
  });
3247
3268
  await ctx.telemetry.recordMetric({
3248
3269
  name: CodemationTelemetryMetricNames.agentTurns,
@@ -3254,13 +3275,11 @@ let AIAgentNode = class AIAgentNode$1 {
3254
3275
  });
3255
3276
  return this.buildOutputItem(item, structuredOutput);
3256
3277
  }
3257
- const modelWithTools = this.bindToolsToModel(prepared.model, itemScopedTools);
3258
3278
  const loopResult = await this.runTurnLoopUntilFinalAnswer({
3259
3279
  prepared,
3260
3280
  itemInputsByPort,
3261
3281
  itemScopedTools,
3262
- conversation,
3263
- modelWithTools
3282
+ conversation
3264
3283
  });
3265
3284
  await ctx.telemetry.recordMetric({
3266
3285
  name: CodemationTelemetryMetricNames.agentTurns,
@@ -3270,30 +3289,34 @@ let AIAgentNode = class AIAgentNode$1 {
3270
3289
  name: CodemationTelemetryMetricNames.agentToolCalls,
3271
3290
  value: loopResult.toolCallCount
3272
3291
  });
3273
- const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalResponse, itemScopedTools.length > 0);
3292
+ const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalText, itemScopedTools.length > 0);
3274
3293
  return this.buildOutputItem(item, outputJson);
3275
3294
  }
3276
3295
  /**
3277
- * Repeatedly invokes the model until it returns without tool calls, or guardrails end the loop.
3296
+ * Multi-turn loop:
3297
+ * - Each turn is a single `generateText` call with tools exposed but **not auto-executed**
3298
+ * (we control tool dispatch so that {@link AgentToolExecutionCoordinator} drives repair /
3299
+ * connection-invocation recording / transient-error handling exactly like before).
3300
+ * - When the model returns no tool calls the loop ends with the model's text as the final answer.
3301
+ * - Respects `guardrails.maxTurns` and `guardrails.onTurnLimitReached`.
3278
3302
  */
3279
3303
  async runTurnLoopUntilFinalAnswer(args) {
3280
- const { prepared, itemInputsByPort, itemScopedTools, conversation, modelWithTools } = args;
3281
- const { ctx, guardrails, languageModelConnectionNodeId } = prepared;
3282
- let finalResponse;
3304
+ const { prepared, itemInputsByPort, itemScopedTools, conversation } = args;
3305
+ const { ctx, guardrails } = prepared;
3306
+ let finalText = "";
3283
3307
  let toolCallCount = 0;
3284
3308
  let turnCount = 0;
3285
3309
  const repairAttemptsByToolName = /* @__PURE__ */ new Map();
3286
3310
  for (let turn = 1; turn <= guardrails.maxTurns; turn++) {
3287
3311
  turnCount = turn;
3288
- const response = await this.invokeModel(modelWithTools, languageModelConnectionNodeId, conversation, ctx, itemInputsByPort, guardrails.modelInvocationOptions);
3289
- finalResponse = response;
3290
- const toolCalls = AgentMessageFactory.extractToolCalls(response);
3291
- if (toolCalls.length === 0) break;
3312
+ const result = await this.invokeTextTurn(prepared, itemInputsByPort, conversation, itemScopedTools);
3313
+ finalText = result.text;
3314
+ if (result.toolCalls.length === 0) break;
3292
3315
  if (this.cannotExecuteAnotherToolRound(turn, guardrails)) {
3293
3316
  this.finishOrThrowWhenTurnCapHitWithToolCalls(ctx, guardrails);
3294
3317
  break;
3295
3318
  }
3296
- const plannedToolCalls = this.planToolCalls(itemScopedTools, toolCalls, ctx.nodeId);
3319
+ const plannedToolCalls = this.planToolCalls(itemScopedTools, result.toolCalls, ctx.nodeId);
3297
3320
  toolCallCount += plannedToolCalls.length;
3298
3321
  await this.markQueuedTools(plannedToolCalls, ctx);
3299
3322
  const executedToolCalls = await this.toolExecutionCoordinator.execute({
@@ -3302,11 +3325,10 @@ let AIAgentNode = class AIAgentNode$1 {
3302
3325
  agentName: this.getAgentDisplayName(ctx),
3303
3326
  repairAttemptsByToolName
3304
3327
  });
3305
- this.appendAssistantAndToolMessages(conversation, response, executedToolCalls);
3328
+ this.appendAssistantAndToolMessages(conversation, result.assistantMessage, result.text, result.toolCalls, executedToolCalls);
3306
3329
  }
3307
- if (!finalResponse) throw new Error(`AIAgent "${ctx.config.name ?? ctx.nodeId}" did not produce a model response.`);
3308
3330
  return {
3309
- finalResponse,
3331
+ finalText,
3310
3332
  turnCount,
3311
3333
  toolCallCount
3312
3334
  };
@@ -3318,30 +3340,30 @@ let AIAgentNode = class AIAgentNode$1 {
3318
3340
  if (guardrails.onTurnLimitReached === "respondWithLastMessage") return;
3319
3341
  throw new Error(`AIAgent "${ctx.config.name ?? ctx.nodeId}" reached maxTurns=${guardrails.maxTurns} before producing a final response.`);
3320
3342
  }
3321
- appendAssistantAndToolMessages(conversation, assistantMessage, executedToolCalls) {
3322
- conversation.push(assistantMessage, ...executedToolCalls.map((toolCall) => AgentMessageFactory.createToolMessage(toolCall.toolCallId, toolCall.serialized)));
3343
+ appendAssistantAndToolMessages(conversation, assistantMessage, text, toolCalls, executedToolCalls) {
3344
+ conversation.push(assistantMessage ?? AgentMessageFactory.createAssistantWithToolCalls(text, toolCalls), AgentMessageFactory.createToolResultsMessage(executedToolCalls));
3323
3345
  }
3324
- async resolveFinalOutputJson(prepared, itemInputsByPort, conversation, finalResponse, wasToolEnabledRun) {
3325
- if (!prepared.ctx.config.outputSchema) return AgentOutputFactory.fromAgentContent(AgentMessageFactory.extractContent(finalResponse));
3346
+ async resolveFinalOutputJson(prepared, itemInputsByPort, conversation, finalText, wasToolEnabledRun) {
3347
+ if (!prepared.ctx.config.outputSchema) return AgentOutputFactory.fromAgentContent(finalText);
3348
+ const conversationWithFinal = wasToolEnabledRun ? [...conversation, {
3349
+ role: "assistant",
3350
+ content: finalText
3351
+ }] : conversation;
3326
3352
  return await this.structuredOutputRunner.resolve({
3327
3353
  model: prepared.model,
3328
3354
  chatModelConfig: prepared.ctx.config.chatModel,
3329
3355
  schema: prepared.ctx.config.outputSchema,
3330
- conversation: wasToolEnabledRun ? [...conversation, finalResponse] : conversation,
3331
- rawFinalResponse: finalResponse,
3356
+ conversation: conversationWithFinal,
3357
+ rawFinalText: finalText,
3332
3358
  agentName: this.getAgentDisplayName(prepared.ctx),
3333
3359
  nodeId: prepared.ctx.nodeId,
3334
- invokeTextModel: async (messages) => await this.invokeModel(prepared.model, prepared.languageModelConnectionNodeId, messages, prepared.ctx, itemInputsByPort, prepared.guardrails.modelInvocationOptions),
3335
- invokeStructuredModel: async (structuredModel, messages) => await this.invokeStructuredModel(structuredModel, prepared.languageModelConnectionNodeId, messages, prepared.ctx, itemInputsByPort, prepared.guardrails.modelInvocationOptions)
3360
+ invokeTextModel: async (messages) => await this.invokeTextTurn(prepared, itemInputsByPort, messages, []),
3361
+ invokeStructuredModel: async (schema, messages, structuredOptions) => await this.invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions)
3336
3362
  });
3337
3363
  }
3338
3364
  buildOutputItem(item, outputJson) {
3339
3365
  return AgentOutputFactory.replaceJson(item, outputJson);
3340
3366
  }
3341
- bindToolsToModel(model, itemScopedTools) {
3342
- if (itemScopedTools.length === 0 || !model.bindTools) return model;
3343
- return model.bindTools(itemScopedTools.map((entry) => entry.langChainTool));
3344
- }
3345
3367
  resolveTools(toolConfigs) {
3346
3368
  const resolvedTools = toolConfigs.map((config$1) => ({
3347
3369
  config: config$1,
@@ -3360,38 +3382,93 @@ let AIAgentNode = class AIAgentNode$1 {
3360
3382
  connectionNodeId: ConnectionNodeIdFactory.toolConnectionNodeId(ctx.nodeId, entry.config.name),
3361
3383
  getCredentialRequirements: () => entry.config.getCredentialRequirements?.() ?? []
3362
3384
  });
3363
- const langChainTool = this.executionHelpers.createDynamicStructuredTool(entry, toolCredentialContext, item, itemIndex, items);
3364
3385
  return {
3365
3386
  config: entry.config,
3366
- langChainTool
3387
+ inputSchema: entry.runtime.inputSchema,
3388
+ execute: async (input) => {
3389
+ const validated = entry.runtime.inputSchema.parse(input);
3390
+ return await entry.runtime.execute({
3391
+ config: entry.config,
3392
+ input: validated,
3393
+ ctx: toolCredentialContext,
3394
+ item,
3395
+ itemIndex,
3396
+ items
3397
+ });
3398
+ }
3367
3399
  };
3368
3400
  });
3369
3401
  }
3370
- async invokeModel(model, nodeId, messages, ctx, inputsByPort, options) {
3402
+ /**
3403
+ * Builds an AI SDK {@link ToolSet} where every tool ships a pre-converted JSON Schema (via
3404
+ * {@link jsonSchema}) — not the raw Zod schema — and carries **no** `execute`. Two reasons:
3405
+ *
3406
+ * 1. Codemation owns tool dispatch + the per-tool repair loop (see {@link AgentToolExecutionCoordinator}),
3407
+ * so the AI SDK must surface tool calls back to us instead of auto-running them.
3408
+ * 2. The AI SDK's `asSchema` helper discriminates between Zod v3 / Zod v4 / Standard Schema via
3409
+ * runtime feature-detection (`~standard`, `_zod`, etc.). Handing it a pre-built
3410
+ * {@link jsonSchema} record — which is tagged with `Symbol.for('vercel.ai.schema')` — skips all
3411
+ * of that detection and guarantees the provider receives a draft-07 JSON Schema with
3412
+ * `additionalProperties: false` at every object depth (see {@link OpenAiStrictJsonSchemaFactory}
3413
+ * for the same logic applied to structured-output schemas). Codemation still runs its own Zod
3414
+ * validation on tool inputs before execute — the schema handed to the model is advisory.
3415
+ */
3416
+ buildToolSet(itemScopedTools) {
3417
+ if (itemScopedTools.length === 0) return void 0;
3418
+ const toolSet = {};
3419
+ for (const entry of itemScopedTools) {
3420
+ const schemaRecord = this.executionHelpers.createJsonSchemaRecord(entry.inputSchema, {
3421
+ schemaName: entry.config.name,
3422
+ requireObjectRoot: true
3423
+ });
3424
+ toolSet[entry.config.name] = {
3425
+ description: entry.config.description,
3426
+ inputSchema: jsonSchema(schemaRecord)
3427
+ };
3428
+ }
3429
+ return toolSet;
3430
+ }
3431
+ /**
3432
+ * One `generateText` turn (no auto tool execution) with Codemation-owned child-span telemetry
3433
+ * and connection-invocation state recording.
3434
+ */
3435
+ async invokeTextTurn(prepared, itemInputsByPort, messages, itemScopedTools) {
3371
3436
  const invocationId = ConnectionInvocationIdFactory.create();
3372
3437
  const startedAt = /* @__PURE__ */ new Date();
3373
3438
  const summarizedInput = this.summarizeLlmMessages(messages);
3439
+ const { ctx, model, languageModelConnectionNodeId, guardrails } = prepared;
3374
3440
  const span = this.createModelInvocationSpan(ctx, invocationId, startedAt);
3375
3441
  await ctx.nodeState?.markQueued({
3376
- nodeId,
3442
+ nodeId: languageModelConnectionNodeId,
3377
3443
  activationId: ctx.activationId,
3378
- inputsByPort
3444
+ inputsByPort: itemInputsByPort
3379
3445
  });
3380
3446
  await ctx.nodeState?.markRunning({
3381
- nodeId,
3447
+ nodeId: languageModelConnectionNodeId,
3382
3448
  activationId: ctx.activationId,
3383
- inputsByPort
3449
+ inputsByPort: itemInputsByPort
3384
3450
  });
3385
3451
  try {
3386
- const response = await model.invoke(messages, options);
3452
+ const tools = this.buildToolSet(itemScopedTools);
3453
+ const callOptions = this.resolveCallOptions(model, guardrails.modelInvocationOptions);
3454
+ const result = await generateText({
3455
+ model: model.languageModel,
3456
+ messages: [...messages],
3457
+ tools,
3458
+ toolChoice: tools ? "auto" : void 0,
3459
+ maxOutputTokens: callOptions.maxOutputTokens,
3460
+ temperature: callOptions.temperature,
3461
+ providerOptions: callOptions.providerOptions,
3462
+ maxRetries: 0
3463
+ });
3464
+ const turnResult = this.extractTurnResult(result);
3387
3465
  const finishedAt = /* @__PURE__ */ new Date();
3388
3466
  await ctx.nodeState?.markCompleted({
3389
- nodeId,
3467
+ nodeId: languageModelConnectionNodeId,
3390
3468
  activationId: ctx.activationId,
3391
- inputsByPort,
3392
- outputs: AgentOutputFactory.fromUnknown({ content: AgentMessageFactory.extractContent(response) })
3469
+ inputsByPort: itemInputsByPort,
3470
+ outputs: AgentOutputFactory.fromUnknown({ content: turnResult.text })
3393
3471
  });
3394
- const content = AgentMessageFactory.extractContent(response);
3395
3472
  await span.attachArtifact({
3396
3473
  kind: "ai.messages",
3397
3474
  contentType: "application/json",
@@ -3400,26 +3477,26 @@ let AIAgentNode = class AIAgentNode$1 {
3400
3477
  await span.attachArtifact({
3401
3478
  kind: "ai.response",
3402
3479
  contentType: "application/json",
3403
- previewJson: content
3480
+ previewJson: turnResult.text
3404
3481
  });
3405
- await this.recordModelUsageMetrics(span, response, ctx);
3482
+ await this.recordModelUsageMetrics(span, turnResult.usage, ctx);
3406
3483
  await span.end({
3407
3484
  status: "ok",
3408
3485
  endedAt: finishedAt
3409
3486
  });
3410
3487
  await ctx.nodeState?.appendConnectionInvocation({
3411
3488
  invocationId,
3412
- connectionNodeId: nodeId,
3489
+ connectionNodeId: languageModelConnectionNodeId,
3413
3490
  parentAgentNodeId: ctx.nodeId,
3414
3491
  parentAgentActivationId: ctx.activationId,
3415
3492
  status: "completed",
3416
3493
  managedInput: summarizedInput,
3417
- managedOutput: content,
3494
+ managedOutput: turnResult.text,
3418
3495
  queuedAt: startedAt.toISOString(),
3419
3496
  startedAt: startedAt.toISOString(),
3420
3497
  finishedAt: finishedAt.toISOString()
3421
3498
  });
3422
- return response;
3499
+ return turnResult;
3423
3500
  } catch (error) {
3424
3501
  await span.end({
3425
3502
  status: "error",
@@ -3430,36 +3507,53 @@ let AIAgentNode = class AIAgentNode$1 {
3430
3507
  error,
3431
3508
  invocationId,
3432
3509
  startedAt,
3433
- nodeId,
3510
+ nodeId: languageModelConnectionNodeId,
3434
3511
  ctx,
3435
- inputsByPort,
3436
- managedInput: this.summarizeLlmMessages(messages)
3512
+ inputsByPort: itemInputsByPort,
3513
+ managedInput: summarizedInput
3437
3514
  });
3438
3515
  }
3439
3516
  }
3440
- async invokeStructuredModel(model, nodeId, messages, ctx, inputsByPort, options) {
3517
+ /**
3518
+ * Structured-output turn: runs `generateText({ output: Output.object({ schema }) })` via the
3519
+ * structured-output runner. We keep this as a separate helper because the runner needs the raw
3520
+ * validated value (not just text) back, and must be able to retry on Zod failures.
3521
+ */
3522
+ async invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions) {
3441
3523
  const invocationId = ConnectionInvocationIdFactory.create();
3442
3524
  const startedAt = /* @__PURE__ */ new Date();
3443
3525
  const summarizedInput = this.summarizeLlmMessages(messages);
3526
+ const { ctx, model, languageModelConnectionNodeId, guardrails } = prepared;
3444
3527
  const span = this.createModelInvocationSpan(ctx, invocationId, startedAt);
3445
3528
  await ctx.nodeState?.markQueued({
3446
- nodeId,
3529
+ nodeId: languageModelConnectionNodeId,
3447
3530
  activationId: ctx.activationId,
3448
- inputsByPort
3531
+ inputsByPort: itemInputsByPort
3449
3532
  });
3450
3533
  await ctx.nodeState?.markRunning({
3451
- nodeId,
3534
+ nodeId: languageModelConnectionNodeId,
3452
3535
  activationId: ctx.activationId,
3453
- inputsByPort
3536
+ inputsByPort: itemInputsByPort
3454
3537
  });
3455
3538
  try {
3456
- const response = await model.invoke(messages, options);
3539
+ const callOptions = this.resolveCallOptions(model, guardrails.modelInvocationOptions);
3540
+ const outputSchema = structuredOptions?.strict && !this.isZodSchema(schema) ? Output.object({ schema: jsonSchema(schema) }) : Output.object({ schema });
3541
+ const result = await generateText({
3542
+ model: model.languageModel,
3543
+ messages: [...messages],
3544
+ experimental_output: outputSchema,
3545
+ maxOutputTokens: callOptions.maxOutputTokens,
3546
+ temperature: callOptions.temperature,
3547
+ providerOptions: callOptions.providerOptions,
3548
+ maxRetries: 0
3549
+ });
3550
+ const turnResult = this.extractTurnResult(result);
3457
3551
  const finishedAt = /* @__PURE__ */ new Date();
3458
3552
  await ctx.nodeState?.markCompleted({
3459
- nodeId,
3553
+ nodeId: languageModelConnectionNodeId,
3460
3554
  activationId: ctx.activationId,
3461
- inputsByPort,
3462
- outputs: AgentOutputFactory.fromUnknown(response)
3555
+ inputsByPort: itemInputsByPort,
3556
+ outputs: AgentOutputFactory.fromUnknown(result.experimental_output)
3463
3557
  });
3464
3558
  await span.attachArtifact({
3465
3559
  kind: "ai.messages",
@@ -3469,26 +3563,26 @@ let AIAgentNode = class AIAgentNode$1 {
3469
3563
  await span.attachArtifact({
3470
3564
  kind: "ai.response.structured",
3471
3565
  contentType: "application/json",
3472
- previewJson: this.resultToJsonValue(response)
3566
+ previewJson: this.resultToJsonValue(result.experimental_output)
3473
3567
  });
3474
- await this.recordModelUsageMetrics(span, response, ctx);
3568
+ await this.recordModelUsageMetrics(span, turnResult.usage, ctx);
3475
3569
  await span.end({
3476
3570
  status: "ok",
3477
3571
  endedAt: finishedAt
3478
3572
  });
3479
3573
  await ctx.nodeState?.appendConnectionInvocation({
3480
3574
  invocationId,
3481
- connectionNodeId: nodeId,
3575
+ connectionNodeId: languageModelConnectionNodeId,
3482
3576
  parentAgentNodeId: ctx.nodeId,
3483
3577
  parentAgentActivationId: ctx.activationId,
3484
3578
  status: "completed",
3485
3579
  managedInput: summarizedInput,
3486
- managedOutput: this.resultToJsonValue(response),
3580
+ managedOutput: this.resultToJsonValue(result.experimental_output),
3487
3581
  queuedAt: startedAt.toISOString(),
3488
3582
  startedAt: startedAt.toISOString(),
3489
3583
  finishedAt: finishedAt.toISOString()
3490
3584
  });
3491
- return response;
3585
+ return result.experimental_output;
3492
3586
  } catch (error) {
3493
3587
  await span.end({
3494
3588
  status: "error",
@@ -3499,13 +3593,59 @@ let AIAgentNode = class AIAgentNode$1 {
3499
3593
  error,
3500
3594
  invocationId,
3501
3595
  startedAt,
3502
- nodeId,
3596
+ nodeId: languageModelConnectionNodeId,
3503
3597
  ctx,
3504
- inputsByPort,
3505
- managedInput: this.summarizeLlmMessages(messages)
3598
+ inputsByPort: itemInputsByPort,
3599
+ managedInput: summarizedInput
3506
3600
  });
3507
3601
  }
3508
3602
  }
3603
+ isZodSchema(schema) {
3604
+ return typeof schema.parse === "function";
3605
+ }
3606
+ resolveCallOptions(model, overrides) {
3607
+ const defaults = model.defaultCallOptions ?? {};
3608
+ return {
3609
+ maxOutputTokens: overrides?.maxTokens ?? defaults.maxOutputTokens,
3610
+ temperature: defaults.temperature,
3611
+ providerOptions: overrides?.providerOptions ?? defaults.providerOptions
3612
+ };
3613
+ }
3614
+ extractTurnResult(result) {
3615
+ const usage = this.extractUsageFromResult(result);
3616
+ const text = result.text;
3617
+ const toolCalls = result.toolCalls.map((toolCall) => ({
3618
+ id: toolCall.toolCallId,
3619
+ name: toolCall.toolName,
3620
+ input: toolCall.input
3621
+ }));
3622
+ return {
3623
+ assistantMessage: this.extractAssistantMessage(result),
3624
+ text,
3625
+ toolCalls,
3626
+ usage
3627
+ };
3628
+ }
3629
+ extractAssistantMessage(result) {
3630
+ const assistantMessages = result.response.messages.filter((m) => m.role === "assistant");
3631
+ return assistantMessages[assistantMessages.length - 1];
3632
+ }
3633
+ extractUsageFromResult(result) {
3634
+ const usage = result.usage;
3635
+ const inputTokens = this.toFiniteNumber(usage.inputTokens);
3636
+ const outputTokens = this.toFiniteNumber(usage.outputTokens);
3637
+ return {
3638
+ inputTokens,
3639
+ outputTokens,
3640
+ totalTokens: this.toFiniteNumber(usage.totalTokens) ?? (inputTokens !== void 0 && outputTokens !== void 0 ? inputTokens + outputTokens : void 0),
3641
+ cachedInputTokens: this.toFiniteNumber(usage.cachedInputTokens),
3642
+ reasoningTokens: this.toFiniteNumber(usage.reasoningTokens)
3643
+ };
3644
+ }
3645
+ toFiniteNumber(value) {
3646
+ if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
3647
+ return value;
3648
+ }
3509
3649
  createModelInvocationSpan(ctx, invocationId, startedAt) {
3510
3650
  return ctx.telemetry.startChildSpan({
3511
3651
  name: "gen_ai.chat.completion",
@@ -3518,9 +3658,15 @@ let AIAgentNode = class AIAgentNode$1 {
3518
3658
  }
3519
3659
  });
3520
3660
  }
3521
- async recordModelUsageMetrics(span, response, ctx) {
3522
- const usage = this.extractModelUsageMetrics(response);
3523
- for (const [name, value] of Object.entries(usage)) {
3661
+ async recordModelUsageMetrics(span, usage, ctx) {
3662
+ const entries = [
3663
+ [GenAiTelemetryAttributeNames.usageInputTokens, usage.inputTokens],
3664
+ [GenAiTelemetryAttributeNames.usageOutputTokens, usage.outputTokens],
3665
+ [GenAiTelemetryAttributeNames.usageTotalTokens, usage.totalTokens],
3666
+ [GenAiTelemetryAttributeNames.usageCacheReadInputTokens, usage.cachedInputTokens],
3667
+ [GenAiTelemetryAttributeNames.usageReasoningTokens, usage.reasoningTokens]
3668
+ ];
3669
+ for (const [name, value] of entries) {
3524
3670
  if (value === void 0) continue;
3525
3671
  await span.recordMetric({
3526
3672
  name,
@@ -3535,93 +3681,28 @@ let AIAgentNode = class AIAgentNode$1 {
3535
3681
  const provider = ctx.config.chatModel.provider;
3536
3682
  const pricingKey = ctx.config.chatModel.modelName;
3537
3683
  if (!provider || !pricingKey) return;
3538
- const inputTokens = usage[GenAiTelemetryAttributeNames.usageInputTokens];
3539
- const outputTokens = usage[GenAiTelemetryAttributeNames.usageOutputTokens];
3540
- if (inputTokens !== void 0) await costTracking.captureUsage({
3684
+ if (usage.inputTokens !== void 0) await costTracking.captureUsage({
3541
3685
  component: "chat",
3542
3686
  provider,
3543
3687
  operation: "completion.input",
3544
3688
  pricingKey,
3545
3689
  usageUnit: "input_tokens",
3546
- quantity: inputTokens,
3690
+ quantity: usage.inputTokens,
3547
3691
  modelName: pricingKey
3548
3692
  });
3549
- if (outputTokens !== void 0) await costTracking.captureUsage({
3693
+ if (usage.outputTokens !== void 0) await costTracking.captureUsage({
3550
3694
  component: "chat",
3551
3695
  provider,
3552
3696
  operation: "completion.output",
3553
3697
  pricingKey,
3554
3698
  usageUnit: "output_tokens",
3555
- quantity: outputTokens,
3699
+ quantity: usage.outputTokens,
3556
3700
  modelName: pricingKey
3557
3701
  });
3558
3702
  }
3559
3703
  resolveChatModelName(chatModel$1) {
3560
3704
  return chatModel$1.modelName ?? chatModel$1.name;
3561
3705
  }
3562
- extractModelUsageMetrics(response) {
3563
- const usage = this.extractUsageObject(response);
3564
- const inputTokens = this.readUsageNumber(usage, [
3565
- "input_tokens",
3566
- "inputTokens",
3567
- "prompt_tokens",
3568
- "promptTokens"
3569
- ]);
3570
- const outputTokens = this.readUsageNumber(usage, [
3571
- "output_tokens",
3572
- "outputTokens",
3573
- "completion_tokens",
3574
- "completionTokens"
3575
- ]);
3576
- const totalTokens = this.readUsageNumber(usage, ["total_tokens", "totalTokens"]) ?? (inputTokens !== void 0 && outputTokens !== void 0 ? inputTokens + outputTokens : void 0);
3577
- const cachedInputTokens = this.readUsageNumber(usage, [
3578
- "cache_read_input_tokens",
3579
- "cacheReadInputTokens",
3580
- "input_token_details.cached_tokens"
3581
- ]);
3582
- const reasoningTokens = this.readUsageNumber(usage, [
3583
- "reasoning_tokens",
3584
- "reasoningTokens",
3585
- "output_token_details.reasoning_tokens"
3586
- ]);
3587
- return {
3588
- [GenAiTelemetryAttributeNames.usageInputTokens]: inputTokens,
3589
- [GenAiTelemetryAttributeNames.usageOutputTokens]: outputTokens,
3590
- [GenAiTelemetryAttributeNames.usageTotalTokens]: totalTokens,
3591
- [GenAiTelemetryAttributeNames.usageCacheReadInputTokens]: cachedInputTokens,
3592
- [GenAiTelemetryAttributeNames.usageReasoningTokens]: reasoningTokens
3593
- };
3594
- }
3595
- extractUsageObject(response) {
3596
- if (!this.isRecord(response)) return;
3597
- const usageMetadata = response["usage_metadata"];
3598
- if (this.isRecord(usageMetadata)) return usageMetadata;
3599
- const responseMetadata = response["response_metadata"];
3600
- if (this.isRecord(responseMetadata)) {
3601
- const tokenUsage = responseMetadata["tokenUsage"];
3602
- if (this.isRecord(tokenUsage)) return tokenUsage;
3603
- const usage = responseMetadata["usage"];
3604
- if (this.isRecord(usage)) return usage;
3605
- }
3606
- }
3607
- readUsageNumber(source, keys) {
3608
- for (const key of keys) {
3609
- const value = this.readNestedUsageValue(source, key);
3610
- if (typeof value === "number" && Number.isFinite(value)) return value;
3611
- }
3612
- }
3613
- readNestedUsageValue(source, dottedKey) {
3614
- if (!source) return;
3615
- let current = source;
3616
- for (const segment of dottedKey.split(".")) {
3617
- if (!this.isRecord(current)) return;
3618
- current = current[segment];
3619
- }
3620
- return current;
3621
- }
3622
- isRecord(value) {
3623
- return typeof value === "object" && value !== null;
3624
- }
3625
3706
  async markQueuedTools(plannedToolCalls, ctx) {
3626
3707
  for (const plannedToolCall of plannedToolCalls) await ctx.nodeState?.markQueued({
3627
3708
  nodeId: plannedToolCall.nodeId,
@@ -3681,7 +3762,7 @@ let AIAgentNode = class AIAgentNode$1 {
3681
3762
  };
3682
3763
  }
3683
3764
  resultToJsonValue(value) {
3684
- if (value === void 0) return;
3765
+ if (value === void 0) return void 0;
3685
3766
  const json = JSON.stringify(value);
3686
3767
  return JSON.parse(json);
3687
3768
  }
@@ -3696,7 +3777,7 @@ let AIAgentNode = class AIAgentNode$1 {
3696
3777
  resolveToolRuntime(config$1) {
3697
3778
  if (this.isNodeBackedToolConfig(config$1)) {
3698
3779
  const inputSchema = config$1.getInputSchema();
3699
- if (inputSchema == null) throw new Error(`AIAgent tool "${config$1.name}": node-backed tool is missing inputSchema (cannot build LangChain tool).`);
3780
+ if (inputSchema == null) throw new Error(`AIAgent tool "${config$1.name}": node-backed tool is missing inputSchema (cannot build AI SDK tool).`);
3700
3781
  return {
3701
3782
  defaultDescription: `Run workflow node "${config$1.node.name ?? config$1.name}" as an AI tool.`,
3702
3783
  inputSchema,
@@ -3705,7 +3786,7 @@ let AIAgentNode = class AIAgentNode$1 {
3705
3786
  }
3706
3787
  if (this.isCallableToolConfig(config$1)) {
3707
3788
  const inputSchema = config$1.getInputSchema();
3708
- if (inputSchema == null) throw new Error(`AIAgent tool "${config$1.name}": callable tool is missing inputSchema (cannot build LangChain tool).`);
3789
+ if (inputSchema == null) throw new Error(`AIAgent tool "${config$1.name}": callable tool is missing inputSchema (cannot build AI SDK tool).`);
3709
3790
  return {
3710
3791
  defaultDescription: config$1.description ?? `Callable tool "${config$1.name}".`,
3711
3792
  inputSchema,
@@ -3723,17 +3804,9 @@ let AIAgentNode = class AIAgentNode$1 {
3723
3804
  execute: async (args) => await Promise.resolve(tool.execute(args))
3724
3805
  };
3725
3806
  }
3726
- /**
3727
- * Consumer apps can resolve two copies of `@codemation/core`, breaking `instanceof NodeBackedToolConfig` and
3728
- * sending node-backed tools down the plugin-tool branch with `inputSchema: undefined` (LangChain then crashes in
3729
- * json-schema validation). {@link NodeBackedToolConfig#toolKind} is stable across copies.
3730
- */
3731
3807
  isNodeBackedToolConfig(config$1) {
3732
3808
  return config$1 instanceof NodeBackedToolConfig || typeof config$1 === "object" && config$1 !== null && config$1.toolKind === "nodeBacked";
3733
3809
  }
3734
- /**
3735
- * Callable tools use {@link CallableToolConfig#toolKind} for cross-package / JSON round-trip safety.
3736
- */
3737
3810
  isCallableToolConfig(config$1) {
3738
3811
  return config$1 instanceof CallableToolConfig || typeof config$1 === "object" && config$1 !== null && config$1.toolKind === "callable";
3739
3812
  }
@@ -3949,6 +4022,7 @@ var HttpRequest = class {
3949
4022
  kind = "node";
3950
4023
  type = HttpRequestNode;
3951
4024
  execution = { hint: "local" };
4025
+ icon = "lucide:globe";
3952
4026
  constructor(name, args = {}, retryPolicy = RetryPolicy.defaultForHttp) {
3953
4027
  this.name = name;
3954
4028
  this.args = args;
@@ -3990,7 +4064,7 @@ var Aggregate = class {
3990
4064
  type = AggregateNode;
3991
4065
  execution = { hint: "local" };
3992
4066
  keepBinaries = true;
3993
- icon = "lucide:layers";
4067
+ icon = "builtin:aggregate-rows";
3994
4068
  constructor(name, aggregate, id) {
3995
4069
  this.name = name;
3996
4070
  this.aggregate = aggregate;
@@ -4085,7 +4159,7 @@ var If = class {
4085
4159
  kind = "node";
4086
4160
  type = IfNode;
4087
4161
  execution = { hint: "local" };
4088
- icon = "lucide:split";
4162
+ icon = "lucide:split@rot=90";
4089
4163
  declaredOutputPorts = ["true", "false"];
4090
4164
  constructor(name, predicate, id) {
4091
4165
  this.name = name;
@@ -4150,7 +4224,7 @@ var Split = class {
4150
4224
  * Mirrors {@link MapData}'s empty-output behavior.
4151
4225
  */
4152
4226
  continueWhenEmptyOutput = true;
4153
- icon = "lucide:ungroup";
4227
+ icon = "builtin:split-rows";
4154
4228
  constructor(name, getElements, id) {
4155
4229
  this.name = name;
4156
4230
  this.getElements = getElements;
@@ -4221,6 +4295,7 @@ var MapData = class {
4221
4295
  execution = { hint: "local" };
4222
4296
  /** Zero mapped items should still allow downstream nodes to run. */
4223
4297
  continueWhenEmptyOutput = true;
4298
+ icon = "lucide:square-pen";
4224
4299
  keepBinaries;
4225
4300
  constructor(name, map, options = {}) {
4226
4301
  this.name = name;
@@ -4290,7 +4365,7 @@ MergeNode = __decorate([node({ packageName: "@codemation/core-nodes" })], MergeN
4290
4365
  var Merge = class {
4291
4366
  kind = "node";
4292
4367
  type = MergeNode;
4293
- icon = "lucide:git-merge";
4368
+ icon = "lucide:merge@rot=90";
4294
4369
  constructor(name, cfg = { mode: "passThrough" }, id) {
4295
4370
  this.name = name;
4296
4371
  this.cfg = cfg;
@@ -4315,6 +4390,7 @@ var NoOp = class {
4315
4390
  kind = "node";
4316
4391
  type = NoOpNode;
4317
4392
  execution = { hint: "local" };
4393
+ icon = "lucide:circle-dashed";
4318
4394
  constructor(name = "NoOp", id) {
4319
4395
  this.name = name;
4320
4396
  this.id = id;
@@ -4420,6 +4496,7 @@ var Wait = class {
4420
4496
  execution = { hint: "local" };
4421
4497
  /** Pass-through empty batches should still advance to downstream nodes. */
4422
4498
  continueWhenEmptyOutput = true;
4499
+ icon = "lucide:hourglass";
4423
4500
  constructor(name, milliseconds, id) {
4424
4501
  this.name = name;
4425
4502
  this.milliseconds = milliseconds;
@@ -4470,7 +4547,7 @@ WebhookTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })
4470
4547
  var WebhookTrigger = class WebhookTrigger {
4471
4548
  kind = "trigger";
4472
4549
  type = WebhookTriggerNode;
4473
- icon = "lucide:globe";
4550
+ icon = "lucide:webhook";
4474
4551
  constructor(name, args, handler = WebhookTrigger.defaultHandler, id) {
4475
4552
  this.name = name;
4476
4553
  this.args = args;
@@ -4824,5 +4901,5 @@ var ConnectionCredentialNodeConfigFactory = class {
4824
4901
  };
4825
4902
 
4826
4903
  //#endregion
4827
- export { AIAgent, AIAgentConnectionWorkflowExpander, AIAgentExecutionHelpersFactory, AIAgentNode, AgentItemPortMap, AgentMessageFactory, AgentOutputFactory, AgentStructuredOutputRepairPromptFactory, AgentStructuredOutputRunner, AgentToolCallPortMap, AgentToolErrorClassifier, AgentToolExecutionCoordinator, AgentToolRepairExhaustedError, AgentToolRepairPolicy, Aggregate, AggregateNode, Callback, CallbackNode, CallbackResultNormalizer, ConnectionCredentialExecutionContextFactory, ConnectionCredentialNode, ConnectionCredentialNodeConfig, ConnectionCredentialNodeConfigFactory, Filter, FilterNode, HttpRequest, HttpRequestNode, If, IfNode, ManualTrigger, ManualTriggerNode, MapData, MapDataNode, Merge, MergeNode, NoOp, NoOpNode, OpenAIChatModelConfig, OpenAIChatModelFactory, OpenAIStructuredOutputMethodFactory, OpenAiChatModelPresets, Split, SplitNode, SubWorkflow, SubWorkflowNode, Switch, SwitchNode, Wait, WaitDuration, WaitNode, WebhookRespondNowAndContinueError, WebhookRespondNowError, WebhookTrigger, WebhookTriggerNode, WorkflowAuthoringBuilder, WorkflowBranchBuilder, WorkflowChain, createWorkflowBuilder, openAiChatModelPresets, registerCoreNodes, workflow };
4904
+ export { AIAgent, AIAgentConnectionWorkflowExpander, AIAgentExecutionHelpersFactory, AIAgentNode, AgentItemPortMap, AgentMessageFactory, AgentOutputFactory, AgentStructuredOutputRepairPromptFactory, AgentStructuredOutputRunner, AgentToolCallPortMap, AgentToolErrorClassifier, AgentToolExecutionCoordinator, AgentToolRepairExhaustedError, AgentToolRepairPolicy, Aggregate, AggregateNode, Callback, CallbackNode, CallbackResultNormalizer, ConnectionCredentialExecutionContextFactory, ConnectionCredentialNode, ConnectionCredentialNodeConfig, ConnectionCredentialNodeConfigFactory, Filter, FilterNode, HttpRequest, HttpRequestNode, If, IfNode, ManualTrigger, ManualTriggerNode, MapData, MapDataNode, Merge, MergeNode, NoOp, NoOpNode, OpenAIChatModelConfig, OpenAIChatModelFactory, OpenAiChatModelPresets, OpenAiStrictJsonSchemaFactory, Split, SplitNode, SubWorkflow, SubWorkflowNode, Switch, SwitchNode, Wait, WaitDuration, WaitNode, WebhookRespondNowAndContinueError, WebhookRespondNowError, WebhookTrigger, WebhookTriggerNode, WorkflowAuthoringBuilder, WorkflowBranchBuilder, WorkflowChain, createWorkflowBuilder, openAiChatModelPresets, registerCoreNodes, workflow };
4828
4905
  //# sourceMappingURL=index.js.map