@codemation/core-nodes 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/dist/index.cjs +3485 -474
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +1763 -685
  5. package/dist/index.d.ts +1763 -685
  6. package/dist/index.js +3452 -479
  7. package/dist/index.js.map +1 -1
  8. package/package.json +8 -5
  9. package/src/authoring/defineRestNode.types.ts +204 -0
  10. package/src/chatModels/OpenAIChatModelFactory.ts +17 -8
  11. package/src/chatModels/OpenAiStrictJsonSchemaFactory.ts +123 -0
  12. package/src/credentials/ApiKeyCredentialType.ts +60 -0
  13. package/src/credentials/BasicAuthCredentialType.ts +51 -0
  14. package/src/credentials/BearerTokenCredentialType.ts +40 -0
  15. package/src/credentials/OAuth2ClientCredentialsTypeFactory.ts +117 -0
  16. package/src/credentials/OAuth2TokenExchangeFactory.ts +52 -0
  17. package/src/credentials/index.ts +4 -0
  18. package/src/http/HttpBodyBuilder.ts +90 -0
  19. package/src/http/HttpRequestExecutor.ts +150 -0
  20. package/src/http/HttpUrlBuilder.ts +22 -0
  21. package/src/http/httpRequest.types.ts +69 -0
  22. package/src/index.ts +10 -1
  23. package/src/nodes/AIAgentExecutionHelpersFactory.ts +45 -59
  24. package/src/nodes/AIAgentNode.ts +391 -288
  25. package/src/nodes/AgentMessageFactory.ts +57 -49
  26. package/src/nodes/AgentStructuredOutputRunner.ts +65 -71
  27. package/src/nodes/AgentToolExecutionCoordinator.ts +31 -16
  28. package/src/nodes/AssertionNode.ts +42 -0
  29. package/src/nodes/CronTriggerFactory.ts +45 -0
  30. package/src/nodes/CronTriggerNode.ts +40 -0
  31. package/src/nodes/HttpRequestNodeFactory.ts +99 -23
  32. package/src/nodes/IsTestRunNode.ts +25 -0
  33. package/src/nodes/NodeBackedToolRuntime.ts +40 -4
  34. package/src/nodes/TestTriggerNode.ts +33 -0
  35. package/src/nodes/WebhookTriggerFactory.ts +1 -1
  36. package/src/nodes/aggregate.ts +1 -1
  37. package/src/nodes/aiAgentSupport.types.ts +22 -2
  38. package/src/nodes/assertion.ts +42 -0
  39. package/src/nodes/collections/collectionDeleteNode.types.ts +23 -0
  40. package/src/nodes/collections/collectionFindOneNode.types.ts +26 -0
  41. package/src/nodes/collections/collectionGetNode.types.ts +26 -0
  42. package/src/nodes/collections/collectionInsertNode.types.ts +22 -0
  43. package/src/nodes/collections/collectionListNode.types.ts +30 -0
  44. package/src/nodes/collections/collectionUpdateNode.types.ts +23 -0
  45. package/src/nodes/collections/index.ts +6 -0
  46. package/src/nodes/httpRequest.ts +62 -1
  47. package/src/nodes/if.ts +1 -1
  48. package/src/nodes/isTestRun.ts +24 -0
  49. package/src/nodes/mapData.ts +1 -0
  50. package/src/nodes/merge.ts +1 -1
  51. package/src/nodes/noOp.ts +1 -0
  52. package/src/nodes/split.ts +1 -1
  53. package/src/nodes/testTrigger.ts +72 -0
  54. package/src/nodes/wait.ts +1 -0
  55. package/src/chatModels/OpenAIStructuredOutputMethodFactory.ts +0 -46
package/dist/index.js CHANGED
@@ -1,184 +1,555 @@
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";
1
+ import { AgentConfigInspector, AgentConnectionNodeCollector, AgentGuardrailDefaults, AgentMessageConfigNormalizer, CallableToolConfig, ChildExecutionScopeFactory, CodemationTelemetryAttributeNames, CodemationTelemetryMetricNames, ConnectionInvocationIdFactory, ConnectionNodeIdFactory, CoreTokens, DefinedNodeRegistry, GenAiTelemetryAttributeNames, ItemExprResolver, ItemsInputNormalizer, NodeBackedToolConfig, NodeOutputNormalizer, RetryPolicy, RunnableOutputBehaviorResolver, WorkflowBuilder, chatModel, defineCredential, defineNode, emitPorts, getOriginIndexFromItem, inject, injectable, isPortsEmission, node } from "@codemation/core";
2
+ import { createOpenAI } from "@ai-sdk/openai";
7
3
  import { CredentialResolverFactory } from "@codemation/core/bootstrap";
4
+ import { Output, generateText, jsonSchema } from "ai";
5
+ import { Cron } from "croner";
8
6
 
9
- //#region \0@oxc-project+runtime@0.95.0/helpers/decorate.js
10
- function __decorate(decorators, target, key, desc) {
11
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
12
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
13
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
- return c > 3 && r && Object.defineProperty(target, key, r), r;
15
- }
7
+ //#region src/credentials/ApiKeyCredentialType.ts
8
+ /**
9
+ * API key credential that injects a key either as an HTTP header or a query parameter.
10
+ */
11
+ const apiKeyCredentialType = defineCredential({
12
+ key: "core-nodes.api-key",
13
+ label: "API Key",
14
+ description: "Authenticates requests by injecting an API key into a header or query parameter.",
15
+ public: {
16
+ placement: {
17
+ label: "Placement",
18
+ type: "string",
19
+ helpText: "Where to send the key: \"header\" (default) or \"query\".",
20
+ placeholder: "header"
21
+ },
22
+ name: {
23
+ label: "Parameter name",
24
+ type: "string",
25
+ helpText: "Header or query param name. Defaults to \"X-API-Key\" for headers, \"api_key\" for query.",
26
+ placeholder: "X-API-Key"
27
+ }
28
+ },
29
+ secret: { apiKey: {
30
+ label: "API Key",
31
+ type: "password",
32
+ required: true,
33
+ helpText: "The secret API key value."
34
+ } },
35
+ async createSession(args) {
36
+ const apiKey = String(args.material.apiKey ?? "");
37
+ if (!apiKey) throw new Error("API key credential material is incomplete: apiKey is required.");
38
+ const isQuery = String(args.publicConfig.placement ?? "header").toLowerCase() === "query";
39
+ const defaultName = isQuery ? "api_key" : "X-API-Key";
40
+ const paramName = String(args.publicConfig.name ?? "").trim() || defaultName;
41
+ return { applyToRequest: (_spec) => {
42
+ if (isQuery) return { query: { [paramName]: apiKey } };
43
+ return { headers: { [paramName]: apiKey } };
44
+ } };
45
+ },
46
+ async test(args) {
47
+ const apiKey = String(args.material.apiKey ?? "");
48
+ return {
49
+ status: apiKey.length > 0 ? "healthy" : "failing",
50
+ message: apiKey.length > 0 ? "API key is configured." : "API key is missing.",
51
+ testedAt: (/* @__PURE__ */ new Date()).toISOString()
52
+ };
53
+ }
54
+ });
16
55
 
17
56
  //#endregion
18
- //#region src/chatModels/OpenAIChatModelFactory.ts
19
- let OpenAIChatModelFactory = class OpenAIChatModelFactory$1 {
57
+ //#region src/credentials/BasicAuthCredentialType.ts
58
+ /**
59
+ * HTTP Basic authentication credential.
60
+ * Session sets `Authorization: Basic <base64(username:password)>`.
61
+ */
62
+ const basicAuthCredentialType = defineCredential({
63
+ key: "core-nodes.basic-auth",
64
+ label: "Basic Auth",
65
+ description: "Authenticates requests using HTTP Basic Authentication (username + password).",
66
+ public: { username: {
67
+ label: "Username",
68
+ type: "string",
69
+ required: true,
70
+ helpText: "The username for HTTP Basic Authentication."
71
+ } },
72
+ secret: { password: {
73
+ label: "Password",
74
+ type: "password",
75
+ required: true,
76
+ helpText: "The password for HTTP Basic Authentication."
77
+ } },
78
+ async createSession(args) {
79
+ const username = String(args.publicConfig.username ?? "");
80
+ const password = String(args.material.password ?? "");
81
+ if (!username) throw new Error("Basic Auth credential is incomplete: username is required.");
82
+ const encoded = Buffer.from(`${username}:${password}`).toString("base64");
83
+ return { applyToRequest: (_spec) => ({ headers: { authorization: `Basic ${encoded}` } }) };
84
+ },
85
+ async test(args) {
86
+ const username = String(args.publicConfig.username ?? "");
87
+ const password = String(args.material.password ?? "");
88
+ const ok = username.length > 0 && password.length > 0;
89
+ return {
90
+ status: ok ? "healthy" : "failing",
91
+ message: ok ? "Basic Auth credentials are configured." : "Username or password is missing.",
92
+ testedAt: (/* @__PURE__ */ new Date()).toISOString()
93
+ };
94
+ }
95
+ });
96
+
97
+ //#endregion
98
+ //#region src/credentials/BearerTokenCredentialType.ts
99
+ /**
100
+ * Simple Bearer token credential.
101
+ * Session sets `Authorization: Bearer <token>` on every request.
102
+ */
103
+ const bearerTokenCredentialType = defineCredential({
104
+ key: "core-nodes.bearer-token",
105
+ label: "Bearer Token",
106
+ description: "Authenticates requests using a static Bearer token in the Authorization header.",
107
+ public: {},
108
+ secret: { token: {
109
+ label: "Token",
110
+ type: "password",
111
+ required: true,
112
+ helpText: "The Bearer token to include in the Authorization header."
113
+ } },
114
+ async createSession(args) {
115
+ const token = String(args.material.token ?? "");
116
+ if (!token) throw new Error("Bearer token credential material is incomplete: token is required.");
117
+ return { applyToRequest: (_spec) => ({ headers: { authorization: `Bearer ${token}` } }) };
118
+ },
119
+ async test(args) {
120
+ const token = String(args.material.token ?? "");
121
+ return {
122
+ status: token.length > 0 ? "healthy" : "failing",
123
+ message: token.length > 0 ? "Bearer token is configured." : "Token is missing.",
124
+ testedAt: (/* @__PURE__ */ new Date()).toISOString()
125
+ };
126
+ }
127
+ });
128
+
129
+ //#endregion
130
+ //#region src/credentials/OAuth2TokenExchangeFactory.ts
131
+ var OAuth2TokenExchangeFactory = class {
20
132
  async create(args) {
21
- 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
133
+ const body = new URLSearchParams({
134
+ grant_type: "client_credentials",
135
+ client_id: args.clientId
28
136
  });
137
+ if (args.scopes) body.set("scope", args.scopes);
138
+ if (args.audience) body.set("audience", args.audience);
139
+ const encoded = Buffer.from(`${args.clientId}:${args.clientSecret}`).toString("base64");
140
+ const response = await globalThis.fetch(args.tokenUrl, {
141
+ method: "POST",
142
+ headers: {
143
+ "content-type": "application/x-www-form-urlencoded",
144
+ authorization: `Basic ${encoded}`
145
+ },
146
+ body: body.toString()
147
+ });
148
+ if (!response.ok) {
149
+ const text = await response.text().catch(() => "");
150
+ throw new Error(`Token exchange failed (${response.status} ${response.statusText}): ${text}`);
151
+ }
152
+ const json = await response.json();
153
+ const token = String(json["access_token"] ?? "");
154
+ if (!token) throw new Error("Token exchange response did not include an access_token.");
155
+ return token;
29
156
  }
30
157
  };
31
- OpenAIChatModelFactory = __decorate([chatModel({ packageName: "@codemation/core-nodes" })], OpenAIChatModelFactory);
32
158
 
33
159
  //#endregion
34
- //#region src/chatModels/OpenAIStructuredOutputMethodFactory.ts
35
- var _OpenAIStructuredOutputMethodFactory;
36
- let OpenAIStructuredOutputMethodFactory = class OpenAIStructuredOutputMethodFactory$1 {
37
- static {
38
- _OpenAIStructuredOutputMethodFactory = this;
160
+ //#region src/credentials/OAuth2ClientCredentialsTypeFactory.ts
161
+ /**
162
+ * OAuth2 client-credentials flow credential.
163
+ *
164
+ * This is a machine-to-machine flow: no user redirect occurs. The session
165
+ * POSTs to the configured `tokenUrl` with `client_credentials` grant, caches
166
+ * the resulting access token for the duration of the session, and injects it
167
+ * as `Authorization: Bearer <token>` on each request.
168
+ *
169
+ * Token caching is per-session only (one createSession call = one token fetch
170
+ * at most). Cross-session caching would require host-level state and is out of
171
+ * scope here. Because the engine creates a fresh session per execution, a new
172
+ * token is fetched once per node activation.
173
+ *
174
+ * NOTE: `auth` is intentionally omitted from the definition. The OAuth2
175
+ * `auth: { kind: "oauth2" }` shape signals an authorization-code / user-redirect
176
+ * flow; using it here would cause the host UI to render an OAuth consent button
177
+ * that goes nowhere. Client-credentials is a purely server-side flow.
178
+ */
179
+ const oauth2ClientCredentialsType = defineCredential({
180
+ key: "core-nodes.oauth2-client-credentials",
181
+ label: "OAuth2 Client Credentials",
182
+ description: "Machine-to-machine OAuth2 using the client_credentials grant. Exchanges client ID and secret for a bearer token before each workflow execution.",
183
+ public: {
184
+ tokenUrl: {
185
+ label: "Token URL",
186
+ type: "string",
187
+ required: true,
188
+ helpText: "The token endpoint URL, e.g. https://auth.example.com/oauth/token."
189
+ },
190
+ scopes: {
191
+ label: "Scopes",
192
+ type: "string",
193
+ helpText: "Space-separated list of OAuth2 scopes to request (optional)."
194
+ },
195
+ audience: {
196
+ label: "Audience",
197
+ type: "string",
198
+ helpText: "Optional audience parameter sent to the token endpoint.",
199
+ visibility: "advanced"
200
+ }
201
+ },
202
+ secret: {
203
+ clientId: {
204
+ label: "Client ID",
205
+ type: "string",
206
+ required: true
207
+ },
208
+ clientSecret: {
209
+ label: "Client Secret",
210
+ type: "password",
211
+ required: true
212
+ }
213
+ },
214
+ async createSession(args) {
215
+ const tokenUrl = String(args.publicConfig.tokenUrl ?? "");
216
+ const clientId = String(args.material.clientId ?? "");
217
+ const clientSecret = String(args.material.clientSecret ?? "");
218
+ if (!tokenUrl || !clientId || !clientSecret) throw new Error("OAuth2 client credentials are incomplete: tokenUrl, clientId, and clientSecret are required.");
219
+ const accessToken = await new OAuth2TokenExchangeFactory().create({
220
+ tokenUrl,
221
+ clientId,
222
+ clientSecret,
223
+ scopes: String(args.publicConfig.scopes ?? ""),
224
+ audience: String(args.publicConfig.audience ?? "")
225
+ });
226
+ return { applyToRequest: (_spec) => ({ headers: { authorization: `Bearer ${accessToken}` } }) };
227
+ },
228
+ async test(args) {
229
+ const tokenUrl = String(args.publicConfig.tokenUrl ?? "");
230
+ const clientId = String(args.material.clientId ?? "");
231
+ const clientSecret = String(args.material.clientSecret ?? "");
232
+ if (!tokenUrl || !clientId || !clientSecret) return {
233
+ status: "failing",
234
+ message: "tokenUrl, clientId, and clientSecret are all required.",
235
+ testedAt: (/* @__PURE__ */ new Date()).toISOString()
236
+ };
237
+ try {
238
+ await new OAuth2TokenExchangeFactory().create({
239
+ tokenUrl,
240
+ clientId,
241
+ clientSecret,
242
+ scopes: String(args.publicConfig.scopes ?? ""),
243
+ audience: String(args.publicConfig.audience ?? "")
244
+ });
245
+ return {
246
+ status: "healthy",
247
+ message: "Token exchange succeeded.",
248
+ testedAt: (/* @__PURE__ */ new Date()).toISOString()
249
+ };
250
+ } catch (error) {
251
+ return {
252
+ status: "failing",
253
+ message: error instanceof Error ? error.message : String(error),
254
+ testedAt: (/* @__PURE__ */ new Date()).toISOString()
255
+ };
256
+ }
39
257
  }
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
258
+ });
259
+
260
+ //#endregion
261
+ //#region src/http/HttpRequestExecutor.ts
262
+ /**
263
+ * Executes a single HTTP request described by {@link HttpRequestSpec}.
264
+ *
265
+ * - Credential sessions provide header/query deltas via `applyToRequest`.
266
+ * - Body encoding is delegated to {@link HttpBodyBuilder}.
267
+ * - URL query merging is delegated to {@link HttpUrlBuilder}.
268
+ * - Binary response bodies: when `download.mode` triggers binary attach, the
269
+ * `bodyBinaryName` field is set in the result but the body is NOT read here.
270
+ * Callers that need binary attachment should use `buildRequest` to get the
271
+ * resolved URL + init and make the fetch + binary attach themselves.
272
+ *
273
+ * Collaborators (`fetch`, body builder, url builder) are injected so callers
274
+ * own construction at composition roots and tests can supply deterministic stubs.
275
+ */
276
+ var HttpRequestExecutor = class {
277
+ constructor(fetchFn, bodyBuilder, urlBuilder) {
278
+ this.fetchFn = fetchFn;
279
+ this.bodyBuilder = bodyBuilder;
280
+ this.urlBuilder = urlBuilder;
281
+ }
282
+ /**
283
+ * Builds the fetch init (headers, query, body) from the spec + credential delta,
284
+ * returning both the resolved URL and the RequestInit so callers can make the
285
+ * actual fetch call themselves (useful for streaming / binary attach).
286
+ */
287
+ async buildRequest(spec, item) {
288
+ const credentialDelta = spec.credential?.applyToRequest(spec) ?? {};
289
+ const mergedHeaders = {
290
+ ...spec.headers ?? {},
291
+ ...credentialDelta.headers ?? {}
292
+ };
293
+ const mergedQuery = {
294
+ ...spec.query ?? {},
295
+ ...credentialDelta.query ?? {}
47
296
  };
297
+ const encodedBody = await this.bodyBuilder.build(spec.body, item, spec.ctx);
298
+ if (encodedBody && encodedBody.contentType) mergedHeaders["content-type"] = encodedBody.contentType;
299
+ return {
300
+ url: this.urlBuilder.build(spec.url, mergedQuery),
301
+ init: {
302
+ method: spec.method,
303
+ headers: mergedHeaders,
304
+ ...encodedBody ? { body: encodedBody.body } : {}
305
+ }
306
+ };
307
+ }
308
+ /**
309
+ * Executes an HTTP request and returns parsed result.
310
+ * For binary downloads (when `shouldAttachBody` is true), the body is NOT consumed
311
+ * and callers must call `ctx.binary.attach` directly using the resolved URL + init
312
+ * (available via `buildRequest`).
313
+ */
314
+ async execute(spec, item) {
315
+ const { url: resolvedUrl, init } = await this.buildRequest(spec, item);
316
+ const response = await this.fetchFn(resolvedUrl, init);
317
+ const responseHeaders = this.readHeaders(response.headers);
318
+ const mimeType = this.resolveMimeType(responseHeaders);
319
+ const downloadMode = spec.download?.mode ?? "auto";
320
+ const binaryName = spec.download?.binaryName ?? "body";
321
+ const shouldDownload = this.shouldAttachBody(downloadMode, mimeType);
322
+ const isJson = this.isJsonMimeType(mimeType);
323
+ let json;
324
+ let text;
325
+ let bodyBinaryName;
326
+ if (shouldDownload) bodyBinaryName = binaryName;
327
+ else if (isJson) try {
328
+ json = await response.json();
329
+ } catch {
330
+ text = await response.text();
331
+ }
332
+ else text = await response.text();
48
333
  return {
49
- method: this.supportsJsonSchema(model) ? "jsonSchema" : "functionCalling",
50
- strict: true
334
+ url: resolvedUrl,
335
+ method: spec.method.toUpperCase(),
336
+ status: response.status,
337
+ ok: response.ok,
338
+ statusText: response.statusText,
339
+ mimeType,
340
+ headers: responseHeaders,
341
+ ...json !== void 0 ? { json } : {},
342
+ ...text !== void 0 ? { text } : {},
343
+ ...bodyBinaryName !== void 0 ? { bodyBinaryName } : {}
51
344
  };
52
345
  }
53
- readModelName(chatModelConfig) {
54
- const candidate = chatModelConfig;
55
- return typeof candidate.model === "string" ? candidate.model : void 0;
346
+ readHeaders(headers) {
347
+ const values = {};
348
+ headers.forEach((value, key) => {
349
+ values[key] = value;
350
+ });
351
+ return values;
352
+ }
353
+ resolveMimeType(headers) {
354
+ const contentType = headers["content-type"];
355
+ if (!contentType) return "application/octet-stream";
356
+ return contentType.split(";")[0]?.trim() || "application/octet-stream";
56
357
  }
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");
358
+ isJsonMimeType(mimeType) {
359
+ return mimeType === "application/json" || mimeType.endsWith("+json");
60
360
  }
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;
361
+ shouldAttachBody(mode, mimeType) {
362
+ if (mode === "always") return true;
363
+ if (mode === "never") return false;
364
+ return mimeType.startsWith("image/") || mimeType.startsWith("audio/") || mimeType.startsWith("video/") || mimeType === "application/pdf";
65
365
  }
66
366
  };
67
- OpenAIStructuredOutputMethodFactory = _OpenAIStructuredOutputMethodFactory = __decorate([injectable()], OpenAIStructuredOutputMethodFactory);
68
367
 
69
368
  //#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
369
+ //#region src/http/HttpBodyBuilder.ts
370
+ /**
371
+ * Builds a fetch-compatible `BodyInit` + Content-Type pair from an {@link HttpBodySpec}.
372
+ * Multipart binaries are read from `item.binary` via `ctx.binary.openReadStream`.
373
+ */
374
+ var HttpBodyBuilder = class {
375
+ async build(spec, item, ctx) {
376
+ if (!spec || spec.kind === "none") return;
377
+ if (spec.kind === "json") return {
378
+ body: JSON.stringify(spec.data),
379
+ contentType: "application/json"
85
380
  };
86
- }
87
- getCredentialRequirements() {
88
- return [{
89
- slotKey: this.credentialSlotKey,
90
- label: "OpenAI API key",
91
- acceptedTypes: ["openai.apiKey"]
92
- }];
381
+ if (spec.kind === "form") {
382
+ const params = new URLSearchParams();
383
+ for (const [key, value] of Object.entries(spec.data)) params.append(key, value);
384
+ return {
385
+ body: params.toString(),
386
+ contentType: "application/x-www-form-urlencoded"
387
+ };
388
+ }
389
+ if (spec.kind === "multipart") {
390
+ const formData = new FormData();
391
+ for (const [key, value] of Object.entries(spec.fields)) formData.append(key, value);
392
+ if (spec.binaries) for (const [fieldName, binaryRef] of Object.entries(spec.binaries)) {
393
+ const attachment = item.binary?.[binaryRef];
394
+ if (attachment) {
395
+ const readResult = await ctx.binary.openReadStream(attachment);
396
+ if (readResult) {
397
+ const reader = readResult.body.getReader();
398
+ const chunks = [];
399
+ let done = false;
400
+ while (!done) {
401
+ const result = await reader.read();
402
+ done = result.done;
403
+ if (result.value) chunks.push(result.value);
404
+ }
405
+ const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
406
+ const merged = new Uint8Array(totalLength);
407
+ let offset = 0;
408
+ for (const chunk of chunks) {
409
+ merged.set(chunk, offset);
410
+ offset += chunk.length;
411
+ }
412
+ const blob = new Blob([merged], { type: attachment.mimeType });
413
+ formData.append(fieldName, blob, attachment.filename ?? binaryRef);
414
+ }
415
+ }
416
+ }
417
+ return {
418
+ body: formData,
419
+ contentType: ""
420
+ };
421
+ }
93
422
  }
94
423
  };
95
424
 
96
425
  //#endregion
97
- //#region src/chatModels/OpenAiChatModelPresetsFactory.ts
426
+ //#region src/http/HttpUrlBuilder.ts
98
427
  /**
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.
428
+ * Merges query parameters into a base URL.
429
+ * Handles both scalar and array values, and preserves any existing params.
102
430
  */
103
- var OpenAiChatModelPresets = class {
104
- demoGpt4oMini = new OpenAIChatModelConfig("OpenAI", "gpt-4o-mini");
105
- demoGpt41 = new OpenAIChatModelConfig("OpenAI", "gpt-4.1");
431
+ var HttpUrlBuilder = class {
432
+ build(baseUrl, query) {
433
+ if (!query || Object.keys(query).length === 0) return baseUrl;
434
+ const parsed = new URL(baseUrl);
435
+ for (const [key, value] of Object.entries(query)) if (Array.isArray(value)) for (const entry of value) parsed.searchParams.append(key, entry);
436
+ else parsed.searchParams.append(key, value);
437
+ return parsed.toString();
438
+ }
106
439
  };
107
- const openAiChatModelPresets = new OpenAiChatModelPresets();
108
440
 
109
441
  //#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
- };
442
+ //#region src/authoring/defineRestNode.types.ts
443
+ /**
444
+ * Substitutes `{name}` placeholders in a path template using values from `params`.
445
+ */
446
+ function substitutePath(template, params) {
447
+ return template.replace(/\{([^}]+)}/g, (_match, key) => {
448
+ const value = params[key];
449
+ return value !== void 0 ? String(value) : `{${key}}`;
450
+ });
451
+ }
452
+ /**
453
+ * Declarative helper for creating thin API-wrapper nodes.
454
+ *
455
+ * Usage:
456
+ * ```ts
457
+ * export const postMessage = defineRestNode({
458
+ * key: "slack.post-message",
459
+ * title: "Send Slack message",
460
+ * icon: "si:slack",
461
+ * api: { baseUrl: "https://slack.com/api", path: "/chat.postMessage", method: "POST" },
462
+ * credentials: { auth: bearerTokenCredentialType },
463
+ * inputSchema: z.object({ channel: z.string(), text: z.string() }),
464
+ * request: ({ input }) => ({
465
+ * body: { kind: "json", data: { channel: input.channel, text: input.text } },
466
+ * }),
467
+ * response: ({ json }) => ({ messageTs: (json as any).ts }),
468
+ * });
469
+ * ```
470
+ *
471
+ * - `defineRestNode` is a thin wrapper over `defineNode`; it does not introduce a new runtime kind.
472
+ * - Credential sessions are resolved via the `credentials` binding map (same as `defineNode`).
473
+ * - Path `{placeholder}` substitution is applied from `input` keys before the request is made.
474
+ * - Non-2xx responses throw an `Error` by default (`errorPolicy: "throw"`).
475
+ */
476
+ function defineRestNode(options) {
477
+ const errorPolicy = options.errorPolicy ?? "throw";
478
+ return defineNode({
479
+ key: options.key,
480
+ title: options.title,
481
+ description: options.description,
482
+ icon: options.icon,
483
+ credentials: options.credentials,
484
+ inputSchema: options.inputSchema,
485
+ async execute({ input, item, ctx }, { credentials }) {
486
+ const credentialSlot = options.credentials ? Object.keys(options.credentials)[0] : void 0;
487
+ const credential = credentialSlot ? await credentials[credentialSlot]?.() : void 0;
488
+ const inputRecord = input ?? {};
489
+ const requestShape = options.request ? await options.request({ input }) : {};
490
+ const pathParams = {
491
+ ...inputRecord,
492
+ ...requestShape.pathParams ?? {}
493
+ };
494
+ const resolvedPath = substitutePath(options.api.path, pathParams);
495
+ const resolvedUrl = `${options.api.baseUrl}${resolvedPath}`;
496
+ const result = await new HttpRequestExecutor(globalThis.fetch, new HttpBodyBuilder(), new HttpUrlBuilder()).execute({
497
+ url: resolvedUrl,
498
+ method: (options.api.method ?? "GET").toUpperCase(),
499
+ headers: requestShape.headers,
500
+ query: requestShape.query,
501
+ body: requestShape.body,
502
+ credential,
503
+ ctx
504
+ }, item);
505
+ if (errorPolicy === "throw" && !result.ok) throw new Error(`HTTP ${result.status} ${result.statusText} for ${result.method} ${result.url}`);
506
+ const responseCtx = {
507
+ status: result.status,
508
+ ok: result.ok,
509
+ statusText: result.statusText,
510
+ mimeType: result.mimeType,
511
+ headers: result.headers,
512
+ ...result.json !== void 0 ? { json: result.json } : {},
513
+ ...result.text !== void 0 ? { text: result.text } : {}
514
+ };
515
+ if (options.response) return await options.response({
516
+ ...responseCtx,
517
+ input
518
+ });
519
+ return { json: responseCtx };
520
+ }
521
+ });
522
+ }
161
523
 
162
524
  //#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) {
525
+ //#region \0@oxc-project+runtime@0.95.0/helpers/decorate.js
526
+ function __decorate(decorators, target, key, desc) {
527
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
528
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
529
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
530
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
531
+ }
532
+
533
+ //#endregion
534
+ //#region src/chatModels/OpenAIChatModelFactory.ts
535
+ let OpenAIChatModelFactory = class OpenAIChatModelFactory$1 {
536
+ async create(args) {
537
+ const session = await args.ctx.getCredential(args.config.credentialSlotKey);
169
538
  return {
170
- ...item,
171
- json: value
539
+ languageModel: createOpenAI({
540
+ apiKey: session.apiKey,
541
+ baseURL: session.baseUrl
542
+ }).chat(args.config.model),
543
+ modelName: args.config.model,
544
+ provider: "openai",
545
+ defaultCallOptions: {
546
+ maxOutputTokens: args.config.options?.maxTokens,
547
+ temperature: args.config.options?.temperature
548
+ }
172
549
  };
173
550
  }
174
- static fromAgentContent(content) {
175
- try {
176
- return JSON.parse(content);
177
- } catch {
178
- return { output: content };
179
- }
180
- }
181
551
  };
552
+ OpenAIChatModelFactory = __decorate([chatModel({ packageName: "@codemation/core-nodes" })], OpenAIChatModelFactory);
182
553
 
183
554
  //#endregion
184
555
  //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.js
@@ -269,10 +640,21 @@ function cleanRegex(source) {
269
640
  const end = source.endsWith("$") ? source.length - 1 : source.length;
270
641
  return source.slice(start, end);
271
642
  }
643
+ function floatSafeRemainder(val, step) {
644
+ const valDecCount = (val.toString().split(".")[1] || "").length;
645
+ const stepString = step.toString();
646
+ let stepDecCount = (stepString.split(".")[1] || "").length;
647
+ if (stepDecCount === 0 && /\d?e-\d?/.test(stepString)) {
648
+ const match = stepString.match(/\d?e-(\d?)/);
649
+ if (match?.[1]) stepDecCount = Number.parseInt(match[1]);
650
+ }
651
+ const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
652
+ return Number.parseInt(val.toFixed(decCount).replace(".", "")) % Number.parseInt(step.toFixed(decCount).replace(".", "")) / 10 ** decCount;
653
+ }
272
654
  const EVALUATING = Symbol("evaluating");
273
- function defineLazy(object, key, getter) {
655
+ function defineLazy(object$1, key, getter) {
274
656
  let value = void 0;
275
- Object.defineProperty(object, key, {
657
+ Object.defineProperty(object$1, key, {
276
658
  get() {
277
659
  if (value === EVALUATING) return;
278
660
  if (value === void 0) {
@@ -282,11 +664,19 @@ function defineLazy(object, key, getter) {
282
664
  return value;
283
665
  },
284
666
  set(v) {
285
- Object.defineProperty(object, key, { value: v });
667
+ Object.defineProperty(object$1, key, { value: v });
286
668
  },
287
669
  configurable: true
288
670
  });
289
671
  }
672
+ function assignProp(target, prop, value) {
673
+ Object.defineProperty(target, prop, {
674
+ value,
675
+ writable: true,
676
+ enumerable: true,
677
+ configurable: true
678
+ });
679
+ }
290
680
  function mergeDefs(...defs) {
291
681
  const mergedDescriptors = {};
292
682
  for (const def of defs) {
@@ -295,6 +685,12 @@ function mergeDefs(...defs) {
295
685
  }
296
686
  return Object.defineProperties({}, mergedDescriptors);
297
687
  }
688
+ function esc(str) {
689
+ return JSON.stringify(str);
690
+ }
691
+ function slugify(input) {
692
+ return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
693
+ }
298
694
  const captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
299
695
  function isObject(data) {
300
696
  return typeof data === "object" && data !== null && !Array.isArray(data);
@@ -323,6 +719,14 @@ function shallowClone(o) {
323
719
  if (Array.isArray(o)) return [...o];
324
720
  return o;
325
721
  }
722
+ const propertyKeyTypes = new Set([
723
+ "string",
724
+ "number",
725
+ "symbol"
726
+ ]);
727
+ function escapeRegex(str) {
728
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
729
+ }
326
730
  function clone(inst, def, params) {
327
731
  const cl = new inst._zod.constr(def ?? inst._zod.def);
328
732
  if (!def || params?.parent) cl._zod.parent = inst;
@@ -343,6 +747,11 @@ function normalizeParams(_params) {
343
747
  };
344
748
  return params;
345
749
  }
750
+ function optionalKeys(shape) {
751
+ return Object.keys(shape).filter((k) => {
752
+ return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
753
+ });
754
+ }
346
755
  const NUMBER_FORMAT_RANGES = {
347
756
  safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
348
757
  int32: [-2147483648, 2147483647],
@@ -350,6 +759,130 @@ const NUMBER_FORMAT_RANGES = {
350
759
  float32: [-34028234663852886e22, 34028234663852886e22],
351
760
  float64: [-Number.MAX_VALUE, Number.MAX_VALUE]
352
761
  };
762
+ function pick(schema, mask) {
763
+ const currDef = schema._zod.def;
764
+ const checks = currDef.checks;
765
+ if (checks && checks.length > 0) throw new Error(".pick() cannot be used on object schemas containing refinements");
766
+ return clone(schema, mergeDefs(schema._zod.def, {
767
+ get shape() {
768
+ const newShape = {};
769
+ for (const key in mask) {
770
+ if (!(key in currDef.shape)) throw new Error(`Unrecognized key: "${key}"`);
771
+ if (!mask[key]) continue;
772
+ newShape[key] = currDef.shape[key];
773
+ }
774
+ assignProp(this, "shape", newShape);
775
+ return newShape;
776
+ },
777
+ checks: []
778
+ }));
779
+ }
780
+ function omit(schema, mask) {
781
+ const currDef = schema._zod.def;
782
+ const checks = currDef.checks;
783
+ if (checks && checks.length > 0) throw new Error(".omit() cannot be used on object schemas containing refinements");
784
+ return clone(schema, mergeDefs(schema._zod.def, {
785
+ get shape() {
786
+ const newShape = { ...schema._zod.def.shape };
787
+ for (const key in mask) {
788
+ if (!(key in currDef.shape)) throw new Error(`Unrecognized key: "${key}"`);
789
+ if (!mask[key]) continue;
790
+ delete newShape[key];
791
+ }
792
+ assignProp(this, "shape", newShape);
793
+ return newShape;
794
+ },
795
+ checks: []
796
+ }));
797
+ }
798
+ function extend(schema, shape) {
799
+ if (!isPlainObject(shape)) throw new Error("Invalid input to extend: expected a plain object");
800
+ const checks = schema._zod.def.checks;
801
+ if (checks && checks.length > 0) {
802
+ const existingShape = schema._zod.def.shape;
803
+ for (const key in shape) if (Object.getOwnPropertyDescriptor(existingShape, key) !== void 0) throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.");
804
+ }
805
+ return clone(schema, mergeDefs(schema._zod.def, { get shape() {
806
+ const _shape = {
807
+ ...schema._zod.def.shape,
808
+ ...shape
809
+ };
810
+ assignProp(this, "shape", _shape);
811
+ return _shape;
812
+ } }));
813
+ }
814
+ function safeExtend(schema, shape) {
815
+ if (!isPlainObject(shape)) throw new Error("Invalid input to safeExtend: expected a plain object");
816
+ return clone(schema, mergeDefs(schema._zod.def, { get shape() {
817
+ const _shape = {
818
+ ...schema._zod.def.shape,
819
+ ...shape
820
+ };
821
+ assignProp(this, "shape", _shape);
822
+ return _shape;
823
+ } }));
824
+ }
825
+ function merge(a, b) {
826
+ return clone(a, mergeDefs(a._zod.def, {
827
+ get shape() {
828
+ const _shape = {
829
+ ...a._zod.def.shape,
830
+ ...b._zod.def.shape
831
+ };
832
+ assignProp(this, "shape", _shape);
833
+ return _shape;
834
+ },
835
+ get catchall() {
836
+ return b._zod.def.catchall;
837
+ },
838
+ checks: []
839
+ }));
840
+ }
841
+ function partial(Class, schema, mask) {
842
+ const checks = schema._zod.def.checks;
843
+ if (checks && checks.length > 0) throw new Error(".partial() cannot be used on object schemas containing refinements");
844
+ return clone(schema, mergeDefs(schema._zod.def, {
845
+ get shape() {
846
+ const oldShape = schema._zod.def.shape;
847
+ const shape = { ...oldShape };
848
+ if (mask) for (const key in mask) {
849
+ if (!(key in oldShape)) throw new Error(`Unrecognized key: "${key}"`);
850
+ if (!mask[key]) continue;
851
+ shape[key] = Class ? new Class({
852
+ type: "optional",
853
+ innerType: oldShape[key]
854
+ }) : oldShape[key];
855
+ }
856
+ else for (const key in oldShape) shape[key] = Class ? new Class({
857
+ type: "optional",
858
+ innerType: oldShape[key]
859
+ }) : oldShape[key];
860
+ assignProp(this, "shape", shape);
861
+ return shape;
862
+ },
863
+ checks: []
864
+ }));
865
+ }
866
+ function required(Class, schema, mask) {
867
+ return clone(schema, mergeDefs(schema._zod.def, { get shape() {
868
+ const oldShape = schema._zod.def.shape;
869
+ const shape = { ...oldShape };
870
+ if (mask) for (const key in mask) {
871
+ if (!(key in shape)) throw new Error(`Unrecognized key: "${key}"`);
872
+ if (!mask[key]) continue;
873
+ shape[key] = new Class({
874
+ type: "nonoptional",
875
+ innerType: oldShape[key]
876
+ });
877
+ }
878
+ else for (const key in oldShape) shape[key] = new Class({
879
+ type: "nonoptional",
880
+ innerType: oldShape[key]
881
+ });
882
+ assignProp(this, "shape", shape);
883
+ return shape;
884
+ } }));
885
+ }
353
886
  function aborted(x, startIndex = 0) {
354
887
  if (x.aborted === true) return true;
355
888
  for (let i = startIndex; i < x.issues.length; i++) if (x.issues[i]?.continue !== true) return true;
@@ -555,6 +1088,64 @@ const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
555
1088
  };
556
1089
  const safeDecodeAsync$1 = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
557
1090
 
1091
+ //#endregion
1092
+ //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/regexes.js
1093
+ const cuid = /^[cC][^\s-]{8,}$/;
1094
+ const cuid2 = /^[0-9a-z]+$/;
1095
+ const ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;
1096
+ const xid = /^[0-9a-vA-V]{20}$/;
1097
+ const ksuid = /^[A-Za-z0-9]{27}$/;
1098
+ const nanoid = /^[a-zA-Z0-9_-]{21}$/;
1099
+ /** ISO 8601-1 duration regex. Does not support the 8601-2 extensions like negative durations or fractional/negative components. */
1100
+ const duration$1 = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
1101
+ /** A regex for any UUID-like identifier: 8-4-4-4-12 hex pattern */
1102
+ const guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
1103
+ /** Returns a regex for validating an RFC 9562/4122 UUID.
1104
+ *
1105
+ * @param version Optionally specify a version 1-8. If no version is specified, all versions are supported. */
1106
+ const uuid = (version$1) => {
1107
+ if (!version$1) return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
1108
+ return /* @__PURE__ */ new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version$1}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
1109
+ };
1110
+ /** Practical email validation */
1111
+ const email = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;
1112
+ const _emoji$1 = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
1113
+ function emoji() {
1114
+ return new RegExp(_emoji$1, "u");
1115
+ }
1116
+ const ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
1117
+ const ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
1118
+ const cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
1119
+ const cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
1120
+ const base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
1121
+ const base64url = /^[A-Za-z0-9_-]*$/;
1122
+ const e164 = /^\+[1-9]\d{6,14}$/;
1123
+ const dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
1124
+ const date$1 = /* @__PURE__ */ new RegExp(`^${dateSource}$`);
1125
+ function timeSource(args) {
1126
+ const hhmm = `(?:[01]\\d|2[0-3]):[0-5]\\d`;
1127
+ return typeof args.precision === "number" ? args.precision === -1 ? `${hhmm}` : args.precision === 0 ? `${hhmm}:[0-5]\\d` : `${hhmm}:[0-5]\\d\\.\\d{${args.precision}}` : `${hhmm}(?::[0-5]\\d(?:\\.\\d+)?)?`;
1128
+ }
1129
+ function time$1(args) {
1130
+ return /* @__PURE__ */ new RegExp(`^${timeSource(args)}$`);
1131
+ }
1132
+ function datetime$1(args) {
1133
+ const time$2 = timeSource({ precision: args.precision });
1134
+ const opts = ["Z"];
1135
+ if (args.local) opts.push("");
1136
+ if (args.offset) opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);
1137
+ const timeRegex = `${time$2}(?:${opts.join("|")})`;
1138
+ return /* @__PURE__ */ new RegExp(`^${dateSource}T(?:${timeRegex})$`);
1139
+ }
1140
+ const string$1 = (params) => {
1141
+ const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
1142
+ return /* @__PURE__ */ new RegExp(`^${regex}$`);
1143
+ };
1144
+ const integer = /^-?\d+$/;
1145
+ const number$1 = /^-?\d+(?:\.\d+)?$/;
1146
+ const lowercase = /^[^A-Z]*$/;
1147
+ const uppercase = /^[^a-z]*$/;
1148
+
558
1149
  //#endregion
559
1150
  //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/checks.js
560
1151
  const $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
@@ -563,33 +1154,172 @@ const $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
563
1154
  inst._zod.def = def;
564
1155
  (_a$1 = inst._zod).onattach ?? (_a$1.onattach = []);
565
1156
  });
566
- const $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (inst, def) => {
567
- var _a$1;
1157
+ const numericOriginMap = {
1158
+ number: "number",
1159
+ bigint: "bigint",
1160
+ object: "date"
1161
+ };
1162
+ const $ZodCheckLessThan = /* @__PURE__ */ $constructor("$ZodCheckLessThan", (inst, def) => {
568
1163
  $ZodCheck.init(inst, def);
569
- (_a$1 = inst._zod.def).when ?? (_a$1.when = (payload) => {
570
- const val = payload.value;
571
- return !nullish(val) && val.length !== void 0;
572
- });
1164
+ const origin = numericOriginMap[typeof def.value];
573
1165
  inst._zod.onattach.push((inst$1) => {
574
- const curr = inst$1._zod.bag.maximum ?? Number.POSITIVE_INFINITY;
575
- if (def.maximum < curr) inst$1._zod.bag.maximum = def.maximum;
1166
+ const bag = inst$1._zod.bag;
1167
+ const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY;
1168
+ if (def.value < curr) if (def.inclusive) bag.maximum = def.value;
1169
+ else bag.exclusiveMaximum = def.value;
576
1170
  });
577
1171
  inst._zod.check = (payload) => {
578
- const input = payload.value;
579
- if (input.length <= def.maximum) return;
580
- const origin = getLengthableOrigin(input);
1172
+ if (def.inclusive ? payload.value <= def.value : payload.value < def.value) return;
581
1173
  payload.issues.push({
582
1174
  origin,
583
1175
  code: "too_big",
584
- maximum: def.maximum,
585
- inclusive: true,
586
- input,
1176
+ maximum: typeof def.value === "object" ? def.value.getTime() : def.value,
1177
+ input: payload.value,
1178
+ inclusive: def.inclusive,
587
1179
  inst,
588
1180
  continue: !def.abort
589
1181
  });
590
1182
  };
591
1183
  });
592
- const $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (inst, def) => {
1184
+ const $ZodCheckGreaterThan = /* @__PURE__ */ $constructor("$ZodCheckGreaterThan", (inst, def) => {
1185
+ $ZodCheck.init(inst, def);
1186
+ const origin = numericOriginMap[typeof def.value];
1187
+ inst._zod.onattach.push((inst$1) => {
1188
+ const bag = inst$1._zod.bag;
1189
+ const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY;
1190
+ if (def.value > curr) if (def.inclusive) bag.minimum = def.value;
1191
+ else bag.exclusiveMinimum = def.value;
1192
+ });
1193
+ inst._zod.check = (payload) => {
1194
+ if (def.inclusive ? payload.value >= def.value : payload.value > def.value) return;
1195
+ payload.issues.push({
1196
+ origin,
1197
+ code: "too_small",
1198
+ minimum: typeof def.value === "object" ? def.value.getTime() : def.value,
1199
+ input: payload.value,
1200
+ inclusive: def.inclusive,
1201
+ inst,
1202
+ continue: !def.abort
1203
+ });
1204
+ };
1205
+ });
1206
+ const $ZodCheckMultipleOf = /* @__PURE__ */ $constructor("$ZodCheckMultipleOf", (inst, def) => {
1207
+ $ZodCheck.init(inst, def);
1208
+ inst._zod.onattach.push((inst$1) => {
1209
+ var _a$1;
1210
+ (_a$1 = inst$1._zod.bag).multipleOf ?? (_a$1.multipleOf = def.value);
1211
+ });
1212
+ inst._zod.check = (payload) => {
1213
+ if (typeof payload.value !== typeof def.value) throw new Error("Cannot mix number and bigint in multiple_of check.");
1214
+ if (typeof payload.value === "bigint" ? payload.value % def.value === BigInt(0) : floatSafeRemainder(payload.value, def.value) === 0) return;
1215
+ payload.issues.push({
1216
+ origin: typeof payload.value,
1217
+ code: "not_multiple_of",
1218
+ divisor: def.value,
1219
+ input: payload.value,
1220
+ inst,
1221
+ continue: !def.abort
1222
+ });
1223
+ };
1224
+ });
1225
+ const $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat", (inst, def) => {
1226
+ $ZodCheck.init(inst, def);
1227
+ def.format = def.format || "float64";
1228
+ const isInt = def.format?.includes("int");
1229
+ const origin = isInt ? "int" : "number";
1230
+ const [minimum, maximum] = NUMBER_FORMAT_RANGES[def.format];
1231
+ inst._zod.onattach.push((inst$1) => {
1232
+ const bag = inst$1._zod.bag;
1233
+ bag.format = def.format;
1234
+ bag.minimum = minimum;
1235
+ bag.maximum = maximum;
1236
+ if (isInt) bag.pattern = integer;
1237
+ });
1238
+ inst._zod.check = (payload) => {
1239
+ const input = payload.value;
1240
+ if (isInt) {
1241
+ if (!Number.isInteger(input)) {
1242
+ payload.issues.push({
1243
+ expected: origin,
1244
+ format: def.format,
1245
+ code: "invalid_type",
1246
+ continue: false,
1247
+ input,
1248
+ inst
1249
+ });
1250
+ return;
1251
+ }
1252
+ if (!Number.isSafeInteger(input)) {
1253
+ if (input > 0) payload.issues.push({
1254
+ input,
1255
+ code: "too_big",
1256
+ maximum: Number.MAX_SAFE_INTEGER,
1257
+ note: "Integers must be within the safe integer range.",
1258
+ inst,
1259
+ origin,
1260
+ inclusive: true,
1261
+ continue: !def.abort
1262
+ });
1263
+ else payload.issues.push({
1264
+ input,
1265
+ code: "too_small",
1266
+ minimum: Number.MIN_SAFE_INTEGER,
1267
+ note: "Integers must be within the safe integer range.",
1268
+ inst,
1269
+ origin,
1270
+ inclusive: true,
1271
+ continue: !def.abort
1272
+ });
1273
+ return;
1274
+ }
1275
+ }
1276
+ if (input < minimum) payload.issues.push({
1277
+ origin: "number",
1278
+ input,
1279
+ code: "too_small",
1280
+ minimum,
1281
+ inclusive: true,
1282
+ inst,
1283
+ continue: !def.abort
1284
+ });
1285
+ if (input > maximum) payload.issues.push({
1286
+ origin: "number",
1287
+ input,
1288
+ code: "too_big",
1289
+ maximum,
1290
+ inclusive: true,
1291
+ inst,
1292
+ continue: !def.abort
1293
+ });
1294
+ };
1295
+ });
1296
+ const $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (inst, def) => {
1297
+ var _a$1;
1298
+ $ZodCheck.init(inst, def);
1299
+ (_a$1 = inst._zod.def).when ?? (_a$1.when = (payload) => {
1300
+ const val = payload.value;
1301
+ return !nullish(val) && val.length !== void 0;
1302
+ });
1303
+ inst._zod.onattach.push((inst$1) => {
1304
+ const curr = inst$1._zod.bag.maximum ?? Number.POSITIVE_INFINITY;
1305
+ if (def.maximum < curr) inst$1._zod.bag.maximum = def.maximum;
1306
+ });
1307
+ inst._zod.check = (payload) => {
1308
+ const input = payload.value;
1309
+ if (input.length <= def.maximum) return;
1310
+ const origin = getLengthableOrigin(input);
1311
+ payload.issues.push({
1312
+ origin,
1313
+ code: "too_big",
1314
+ maximum: def.maximum,
1315
+ inclusive: true,
1316
+ input,
1317
+ inst,
1318
+ continue: !def.abort
1319
+ });
1320
+ };
1321
+ });
1322
+ const $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (inst, def) => {
593
1323
  var _a$1;
594
1324
  $ZodCheck.init(inst, def);
595
1325
  (_a$1 = inst._zod.def).when ?? (_a$1.when = (payload) => {
@@ -651,6 +1381,123 @@ const $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEqual
651
1381
  });
652
1382
  };
653
1383
  });
1384
+ const $ZodCheckStringFormat = /* @__PURE__ */ $constructor("$ZodCheckStringFormat", (inst, def) => {
1385
+ var _a$1, _b;
1386
+ $ZodCheck.init(inst, def);
1387
+ inst._zod.onattach.push((inst$1) => {
1388
+ const bag = inst$1._zod.bag;
1389
+ bag.format = def.format;
1390
+ if (def.pattern) {
1391
+ bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
1392
+ bag.patterns.add(def.pattern);
1393
+ }
1394
+ });
1395
+ if (def.pattern) (_a$1 = inst._zod).check ?? (_a$1.check = (payload) => {
1396
+ def.pattern.lastIndex = 0;
1397
+ if (def.pattern.test(payload.value)) return;
1398
+ payload.issues.push({
1399
+ origin: "string",
1400
+ code: "invalid_format",
1401
+ format: def.format,
1402
+ input: payload.value,
1403
+ ...def.pattern ? { pattern: def.pattern.toString() } : {},
1404
+ inst,
1405
+ continue: !def.abort
1406
+ });
1407
+ });
1408
+ else (_b = inst._zod).check ?? (_b.check = () => {});
1409
+ });
1410
+ const $ZodCheckRegex = /* @__PURE__ */ $constructor("$ZodCheckRegex", (inst, def) => {
1411
+ $ZodCheckStringFormat.init(inst, def);
1412
+ inst._zod.check = (payload) => {
1413
+ def.pattern.lastIndex = 0;
1414
+ if (def.pattern.test(payload.value)) return;
1415
+ payload.issues.push({
1416
+ origin: "string",
1417
+ code: "invalid_format",
1418
+ format: "regex",
1419
+ input: payload.value,
1420
+ pattern: def.pattern.toString(),
1421
+ inst,
1422
+ continue: !def.abort
1423
+ });
1424
+ };
1425
+ });
1426
+ const $ZodCheckLowerCase = /* @__PURE__ */ $constructor("$ZodCheckLowerCase", (inst, def) => {
1427
+ def.pattern ?? (def.pattern = lowercase);
1428
+ $ZodCheckStringFormat.init(inst, def);
1429
+ });
1430
+ const $ZodCheckUpperCase = /* @__PURE__ */ $constructor("$ZodCheckUpperCase", (inst, def) => {
1431
+ def.pattern ?? (def.pattern = uppercase);
1432
+ $ZodCheckStringFormat.init(inst, def);
1433
+ });
1434
+ const $ZodCheckIncludes = /* @__PURE__ */ $constructor("$ZodCheckIncludes", (inst, def) => {
1435
+ $ZodCheck.init(inst, def);
1436
+ const escapedRegex = escapeRegex(def.includes);
1437
+ const pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);
1438
+ def.pattern = pattern;
1439
+ inst._zod.onattach.push((inst$1) => {
1440
+ const bag = inst$1._zod.bag;
1441
+ bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
1442
+ bag.patterns.add(pattern);
1443
+ });
1444
+ inst._zod.check = (payload) => {
1445
+ if (payload.value.includes(def.includes, def.position)) return;
1446
+ payload.issues.push({
1447
+ origin: "string",
1448
+ code: "invalid_format",
1449
+ format: "includes",
1450
+ includes: def.includes,
1451
+ input: payload.value,
1452
+ inst,
1453
+ continue: !def.abort
1454
+ });
1455
+ };
1456
+ });
1457
+ const $ZodCheckStartsWith = /* @__PURE__ */ $constructor("$ZodCheckStartsWith", (inst, def) => {
1458
+ $ZodCheck.init(inst, def);
1459
+ const pattern = /* @__PURE__ */ new RegExp(`^${escapeRegex(def.prefix)}.*`);
1460
+ def.pattern ?? (def.pattern = pattern);
1461
+ inst._zod.onattach.push((inst$1) => {
1462
+ const bag = inst$1._zod.bag;
1463
+ bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
1464
+ bag.patterns.add(pattern);
1465
+ });
1466
+ inst._zod.check = (payload) => {
1467
+ if (payload.value.startsWith(def.prefix)) return;
1468
+ payload.issues.push({
1469
+ origin: "string",
1470
+ code: "invalid_format",
1471
+ format: "starts_with",
1472
+ prefix: def.prefix,
1473
+ input: payload.value,
1474
+ inst,
1475
+ continue: !def.abort
1476
+ });
1477
+ };
1478
+ });
1479
+ const $ZodCheckEndsWith = /* @__PURE__ */ $constructor("$ZodCheckEndsWith", (inst, def) => {
1480
+ $ZodCheck.init(inst, def);
1481
+ const pattern = /* @__PURE__ */ new RegExp(`.*${escapeRegex(def.suffix)}$`);
1482
+ def.pattern ?? (def.pattern = pattern);
1483
+ inst._zod.onattach.push((inst$1) => {
1484
+ const bag = inst$1._zod.bag;
1485
+ bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
1486
+ bag.patterns.add(pattern);
1487
+ });
1488
+ inst._zod.check = (payload) => {
1489
+ if (payload.value.endsWith(def.suffix)) return;
1490
+ payload.issues.push({
1491
+ origin: "string",
1492
+ code: "invalid_format",
1493
+ format: "ends_with",
1494
+ suffix: def.suffix,
1495
+ input: payload.value,
1496
+ inst,
1497
+ continue: !def.abort
1498
+ });
1499
+ };
1500
+ });
654
1501
  const $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (inst, def) => {
655
1502
  $ZodCheck.init(inst, def);
656
1503
  inst._zod.check = (payload) => {
@@ -658,6 +1505,38 @@ const $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (i
658
1505
  };
659
1506
  });
660
1507
 
1508
+ //#endregion
1509
+ //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/doc.js
1510
+ var Doc = class {
1511
+ constructor(args = []) {
1512
+ this.content = [];
1513
+ this.indent = 0;
1514
+ if (this) this.args = args;
1515
+ }
1516
+ indented(fn) {
1517
+ this.indent += 1;
1518
+ fn(this);
1519
+ this.indent -= 1;
1520
+ }
1521
+ write(arg) {
1522
+ if (typeof arg === "function") {
1523
+ arg(this, { execution: "sync" });
1524
+ arg(this, { execution: "async" });
1525
+ return;
1526
+ }
1527
+ const lines = arg.split("\n").filter((x) => x);
1528
+ const minIndent = Math.min(...lines.map((x) => x.length - x.trimStart().length));
1529
+ const dedented = lines.map((x) => x.slice(minIndent)).map((x) => " ".repeat(this.indent * 2) + x);
1530
+ for (const line of dedented) this.content.push(line);
1531
+ }
1532
+ compile() {
1533
+ const F = Function;
1534
+ const args = this?.args;
1535
+ const lines = [...(this?.content ?? [``]).map((x) => ` ${x}`)];
1536
+ return new F(...args, lines.join("\n"));
1537
+ }
1538
+ };
1539
+
661
1540
  //#endregion
662
1541
  //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/versions.js
663
1542
  const version = {
@@ -756,10 +1635,308 @@ const $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
756
1635
  version: 1
757
1636
  }));
758
1637
  });
1638
+ const $ZodString = /* @__PURE__ */ $constructor("$ZodString", (inst, def) => {
1639
+ $ZodType.init(inst, def);
1640
+ inst._zod.pattern = [...inst?._zod.bag?.patterns ?? []].pop() ?? string$1(inst._zod.bag);
1641
+ inst._zod.parse = (payload, _) => {
1642
+ if (def.coerce) try {
1643
+ payload.value = String(payload.value);
1644
+ } catch (_$1) {}
1645
+ if (typeof payload.value === "string") return payload;
1646
+ payload.issues.push({
1647
+ expected: "string",
1648
+ code: "invalid_type",
1649
+ input: payload.value,
1650
+ inst
1651
+ });
1652
+ return payload;
1653
+ };
1654
+ });
1655
+ const $ZodStringFormat = /* @__PURE__ */ $constructor("$ZodStringFormat", (inst, def) => {
1656
+ $ZodCheckStringFormat.init(inst, def);
1657
+ $ZodString.init(inst, def);
1658
+ });
1659
+ const $ZodGUID = /* @__PURE__ */ $constructor("$ZodGUID", (inst, def) => {
1660
+ def.pattern ?? (def.pattern = guid);
1661
+ $ZodStringFormat.init(inst, def);
1662
+ });
1663
+ const $ZodUUID = /* @__PURE__ */ $constructor("$ZodUUID", (inst, def) => {
1664
+ if (def.version) {
1665
+ const v = {
1666
+ v1: 1,
1667
+ v2: 2,
1668
+ v3: 3,
1669
+ v4: 4,
1670
+ v5: 5,
1671
+ v6: 6,
1672
+ v7: 7,
1673
+ v8: 8
1674
+ }[def.version];
1675
+ if (v === void 0) throw new Error(`Invalid UUID version: "${def.version}"`);
1676
+ def.pattern ?? (def.pattern = uuid(v));
1677
+ } else def.pattern ?? (def.pattern = uuid());
1678
+ $ZodStringFormat.init(inst, def);
1679
+ });
1680
+ const $ZodEmail = /* @__PURE__ */ $constructor("$ZodEmail", (inst, def) => {
1681
+ def.pattern ?? (def.pattern = email);
1682
+ $ZodStringFormat.init(inst, def);
1683
+ });
1684
+ const $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
1685
+ $ZodStringFormat.init(inst, def);
1686
+ inst._zod.check = (payload) => {
1687
+ try {
1688
+ const trimmed = payload.value.trim();
1689
+ const url = new URL(trimmed);
1690
+ if (def.hostname) {
1691
+ def.hostname.lastIndex = 0;
1692
+ if (!def.hostname.test(url.hostname)) payload.issues.push({
1693
+ code: "invalid_format",
1694
+ format: "url",
1695
+ note: "Invalid hostname",
1696
+ pattern: def.hostname.source,
1697
+ input: payload.value,
1698
+ inst,
1699
+ continue: !def.abort
1700
+ });
1701
+ }
1702
+ if (def.protocol) {
1703
+ def.protocol.lastIndex = 0;
1704
+ if (!def.protocol.test(url.protocol.endsWith(":") ? url.protocol.slice(0, -1) : url.protocol)) payload.issues.push({
1705
+ code: "invalid_format",
1706
+ format: "url",
1707
+ note: "Invalid protocol",
1708
+ pattern: def.protocol.source,
1709
+ input: payload.value,
1710
+ inst,
1711
+ continue: !def.abort
1712
+ });
1713
+ }
1714
+ if (def.normalize) payload.value = url.href;
1715
+ else payload.value = trimmed;
1716
+ return;
1717
+ } catch (_) {
1718
+ payload.issues.push({
1719
+ code: "invalid_format",
1720
+ format: "url",
1721
+ input: payload.value,
1722
+ inst,
1723
+ continue: !def.abort
1724
+ });
1725
+ }
1726
+ };
1727
+ });
1728
+ const $ZodEmoji = /* @__PURE__ */ $constructor("$ZodEmoji", (inst, def) => {
1729
+ def.pattern ?? (def.pattern = emoji());
1730
+ $ZodStringFormat.init(inst, def);
1731
+ });
1732
+ const $ZodNanoID = /* @__PURE__ */ $constructor("$ZodNanoID", (inst, def) => {
1733
+ def.pattern ?? (def.pattern = nanoid);
1734
+ $ZodStringFormat.init(inst, def);
1735
+ });
1736
+ const $ZodCUID = /* @__PURE__ */ $constructor("$ZodCUID", (inst, def) => {
1737
+ def.pattern ?? (def.pattern = cuid);
1738
+ $ZodStringFormat.init(inst, def);
1739
+ });
1740
+ const $ZodCUID2 = /* @__PURE__ */ $constructor("$ZodCUID2", (inst, def) => {
1741
+ def.pattern ?? (def.pattern = cuid2);
1742
+ $ZodStringFormat.init(inst, def);
1743
+ });
1744
+ const $ZodULID = /* @__PURE__ */ $constructor("$ZodULID", (inst, def) => {
1745
+ def.pattern ?? (def.pattern = ulid);
1746
+ $ZodStringFormat.init(inst, def);
1747
+ });
1748
+ const $ZodXID = /* @__PURE__ */ $constructor("$ZodXID", (inst, def) => {
1749
+ def.pattern ?? (def.pattern = xid);
1750
+ $ZodStringFormat.init(inst, def);
1751
+ });
1752
+ const $ZodKSUID = /* @__PURE__ */ $constructor("$ZodKSUID", (inst, def) => {
1753
+ def.pattern ?? (def.pattern = ksuid);
1754
+ $ZodStringFormat.init(inst, def);
1755
+ });
1756
+ const $ZodISODateTime = /* @__PURE__ */ $constructor("$ZodISODateTime", (inst, def) => {
1757
+ def.pattern ?? (def.pattern = datetime$1(def));
1758
+ $ZodStringFormat.init(inst, def);
1759
+ });
1760
+ const $ZodISODate = /* @__PURE__ */ $constructor("$ZodISODate", (inst, def) => {
1761
+ def.pattern ?? (def.pattern = date$1);
1762
+ $ZodStringFormat.init(inst, def);
1763
+ });
1764
+ const $ZodISOTime = /* @__PURE__ */ $constructor("$ZodISOTime", (inst, def) => {
1765
+ def.pattern ?? (def.pattern = time$1(def));
1766
+ $ZodStringFormat.init(inst, def);
1767
+ });
1768
+ const $ZodISODuration = /* @__PURE__ */ $constructor("$ZodISODuration", (inst, def) => {
1769
+ def.pattern ?? (def.pattern = duration$1);
1770
+ $ZodStringFormat.init(inst, def);
1771
+ });
1772
+ const $ZodIPv4 = /* @__PURE__ */ $constructor("$ZodIPv4", (inst, def) => {
1773
+ def.pattern ?? (def.pattern = ipv4);
1774
+ $ZodStringFormat.init(inst, def);
1775
+ inst._zod.bag.format = `ipv4`;
1776
+ });
1777
+ const $ZodIPv6 = /* @__PURE__ */ $constructor("$ZodIPv6", (inst, def) => {
1778
+ def.pattern ?? (def.pattern = ipv6);
1779
+ $ZodStringFormat.init(inst, def);
1780
+ inst._zod.bag.format = `ipv6`;
1781
+ inst._zod.check = (payload) => {
1782
+ try {
1783
+ new URL(`http://[${payload.value}]`);
1784
+ } catch {
1785
+ payload.issues.push({
1786
+ code: "invalid_format",
1787
+ format: "ipv6",
1788
+ input: payload.value,
1789
+ inst,
1790
+ continue: !def.abort
1791
+ });
1792
+ }
1793
+ };
1794
+ });
1795
+ const $ZodCIDRv4 = /* @__PURE__ */ $constructor("$ZodCIDRv4", (inst, def) => {
1796
+ def.pattern ?? (def.pattern = cidrv4);
1797
+ $ZodStringFormat.init(inst, def);
1798
+ });
1799
+ const $ZodCIDRv6 = /* @__PURE__ */ $constructor("$ZodCIDRv6", (inst, def) => {
1800
+ def.pattern ?? (def.pattern = cidrv6);
1801
+ $ZodStringFormat.init(inst, def);
1802
+ inst._zod.check = (payload) => {
1803
+ const parts = payload.value.split("/");
1804
+ try {
1805
+ if (parts.length !== 2) throw new Error();
1806
+ const [address, prefix] = parts;
1807
+ if (!prefix) throw new Error();
1808
+ const prefixNum = Number(prefix);
1809
+ if (`${prefixNum}` !== prefix) throw new Error();
1810
+ if (prefixNum < 0 || prefixNum > 128) throw new Error();
1811
+ new URL(`http://[${address}]`);
1812
+ } catch {
1813
+ payload.issues.push({
1814
+ code: "invalid_format",
1815
+ format: "cidrv6",
1816
+ input: payload.value,
1817
+ inst,
1818
+ continue: !def.abort
1819
+ });
1820
+ }
1821
+ };
1822
+ });
1823
+ function isValidBase64(data) {
1824
+ if (data === "") return true;
1825
+ if (data.length % 4 !== 0) return false;
1826
+ try {
1827
+ atob(data);
1828
+ return true;
1829
+ } catch {
1830
+ return false;
1831
+ }
1832
+ }
1833
+ const $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
1834
+ def.pattern ?? (def.pattern = base64);
1835
+ $ZodStringFormat.init(inst, def);
1836
+ inst._zod.bag.contentEncoding = "base64";
1837
+ inst._zod.check = (payload) => {
1838
+ if (isValidBase64(payload.value)) return;
1839
+ payload.issues.push({
1840
+ code: "invalid_format",
1841
+ format: "base64",
1842
+ input: payload.value,
1843
+ inst,
1844
+ continue: !def.abort
1845
+ });
1846
+ };
1847
+ });
1848
+ function isValidBase64URL(data) {
1849
+ if (!base64url.test(data)) return false;
1850
+ const base64$1 = data.replace(/[-_]/g, (c) => c === "-" ? "+" : "/");
1851
+ return isValidBase64(base64$1.padEnd(Math.ceil(base64$1.length / 4) * 4, "="));
1852
+ }
1853
+ const $ZodBase64URL = /* @__PURE__ */ $constructor("$ZodBase64URL", (inst, def) => {
1854
+ def.pattern ?? (def.pattern = base64url);
1855
+ $ZodStringFormat.init(inst, def);
1856
+ inst._zod.bag.contentEncoding = "base64url";
1857
+ inst._zod.check = (payload) => {
1858
+ if (isValidBase64URL(payload.value)) return;
1859
+ payload.issues.push({
1860
+ code: "invalid_format",
1861
+ format: "base64url",
1862
+ input: payload.value,
1863
+ inst,
1864
+ continue: !def.abort
1865
+ });
1866
+ };
1867
+ });
1868
+ const $ZodE164 = /* @__PURE__ */ $constructor("$ZodE164", (inst, def) => {
1869
+ def.pattern ?? (def.pattern = e164);
1870
+ $ZodStringFormat.init(inst, def);
1871
+ });
1872
+ function isValidJWT(token, algorithm = null) {
1873
+ try {
1874
+ const tokensParts = token.split(".");
1875
+ if (tokensParts.length !== 3) return false;
1876
+ const [header] = tokensParts;
1877
+ if (!header) return false;
1878
+ const parsedHeader = JSON.parse(atob(header));
1879
+ if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT") return false;
1880
+ if (!parsedHeader.alg) return false;
1881
+ if (algorithm && (!("alg" in parsedHeader) || parsedHeader.alg !== algorithm)) return false;
1882
+ return true;
1883
+ } catch {
1884
+ return false;
1885
+ }
1886
+ }
1887
+ const $ZodJWT = /* @__PURE__ */ $constructor("$ZodJWT", (inst, def) => {
1888
+ $ZodStringFormat.init(inst, def);
1889
+ inst._zod.check = (payload) => {
1890
+ if (isValidJWT(payload.value, def.alg)) return;
1891
+ payload.issues.push({
1892
+ code: "invalid_format",
1893
+ format: "jwt",
1894
+ input: payload.value,
1895
+ inst,
1896
+ continue: !def.abort
1897
+ });
1898
+ };
1899
+ });
1900
+ const $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
1901
+ $ZodType.init(inst, def);
1902
+ inst._zod.pattern = inst._zod.bag.pattern ?? number$1;
1903
+ inst._zod.parse = (payload, _ctx) => {
1904
+ if (def.coerce) try {
1905
+ payload.value = Number(payload.value);
1906
+ } catch (_) {}
1907
+ const input = payload.value;
1908
+ if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) return payload;
1909
+ const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0;
1910
+ payload.issues.push({
1911
+ expected: "number",
1912
+ code: "invalid_type",
1913
+ input,
1914
+ inst,
1915
+ ...received ? { received } : {}
1916
+ });
1917
+ return payload;
1918
+ };
1919
+ });
1920
+ const $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumberFormat", (inst, def) => {
1921
+ $ZodCheckNumberFormat.init(inst, def);
1922
+ $ZodNumber.init(inst, def);
1923
+ });
759
1924
  const $ZodUnknown = /* @__PURE__ */ $constructor("$ZodUnknown", (inst, def) => {
760
1925
  $ZodType.init(inst, def);
761
1926
  inst._zod.parse = (payload) => payload;
762
1927
  });
1928
+ const $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
1929
+ $ZodType.init(inst, def);
1930
+ inst._zod.parse = (payload, _ctx) => {
1931
+ payload.issues.push({
1932
+ expected: "never",
1933
+ code: "invalid_type",
1934
+ input: payload.value,
1935
+ inst
1936
+ });
1937
+ return payload;
1938
+ };
1939
+ });
763
1940
  function handleArrayResult(result, final, index) {
764
1941
  if (result.issues.length) final.issues.push(...prefixIssues(index, result.issues));
765
1942
  final.value[index] = result.value;
@@ -768,28 +1945,229 @@ const $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
768
1945
  $ZodType.init(inst, def);
769
1946
  inst._zod.parse = (payload, ctx) => {
770
1947
  const input = payload.value;
771
- if (!Array.isArray(input)) {
1948
+ if (!Array.isArray(input)) {
1949
+ payload.issues.push({
1950
+ expected: "array",
1951
+ code: "invalid_type",
1952
+ input,
1953
+ inst
1954
+ });
1955
+ return payload;
1956
+ }
1957
+ payload.value = Array(input.length);
1958
+ const proms = [];
1959
+ for (let i = 0; i < input.length; i++) {
1960
+ const item = input[i];
1961
+ const result = def.element._zod.run({
1962
+ value: item,
1963
+ issues: []
1964
+ }, ctx);
1965
+ if (result instanceof Promise) proms.push(result.then((result$1) => handleArrayResult(result$1, payload, i)));
1966
+ else handleArrayResult(result, payload, i);
1967
+ }
1968
+ if (proms.length) return Promise.all(proms).then(() => payload);
1969
+ return payload;
1970
+ };
1971
+ });
1972
+ function handlePropertyResult(result, final, key, input, isOptionalOut) {
1973
+ if (result.issues.length) {
1974
+ if (isOptionalOut && !(key in input)) return;
1975
+ final.issues.push(...prefixIssues(key, result.issues));
1976
+ }
1977
+ if (result.value === void 0) {
1978
+ if (key in input) final.value[key] = void 0;
1979
+ } else final.value[key] = result.value;
1980
+ }
1981
+ function normalizeDef(def) {
1982
+ const keys = Object.keys(def.shape);
1983
+ for (const k of keys) if (!def.shape?.[k]?._zod?.traits?.has("$ZodType")) throw new Error(`Invalid element at key "${k}": expected a Zod schema`);
1984
+ const okeys = optionalKeys(def.shape);
1985
+ return {
1986
+ ...def,
1987
+ keys,
1988
+ keySet: new Set(keys),
1989
+ numKeys: keys.length,
1990
+ optionalKeys: new Set(okeys)
1991
+ };
1992
+ }
1993
+ function handleCatchall(proms, input, payload, ctx, def, inst) {
1994
+ const unrecognized = [];
1995
+ const keySet = def.keySet;
1996
+ const _catchall = def.catchall._zod;
1997
+ const t = _catchall.def.type;
1998
+ const isOptionalOut = _catchall.optout === "optional";
1999
+ for (const key in input) {
2000
+ if (keySet.has(key)) continue;
2001
+ if (t === "never") {
2002
+ unrecognized.push(key);
2003
+ continue;
2004
+ }
2005
+ const r = _catchall.run({
2006
+ value: input[key],
2007
+ issues: []
2008
+ }, ctx);
2009
+ if (r instanceof Promise) proms.push(r.then((r$1) => handlePropertyResult(r$1, payload, key, input, isOptionalOut)));
2010
+ else handlePropertyResult(r, payload, key, input, isOptionalOut);
2011
+ }
2012
+ if (unrecognized.length) payload.issues.push({
2013
+ code: "unrecognized_keys",
2014
+ keys: unrecognized,
2015
+ input,
2016
+ inst
2017
+ });
2018
+ if (!proms.length) return payload;
2019
+ return Promise.all(proms).then(() => {
2020
+ return payload;
2021
+ });
2022
+ }
2023
+ const $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
2024
+ $ZodType.init(inst, def);
2025
+ if (!Object.getOwnPropertyDescriptor(def, "shape")?.get) {
2026
+ const sh = def.shape;
2027
+ Object.defineProperty(def, "shape", { get: () => {
2028
+ const newSh = { ...sh };
2029
+ Object.defineProperty(def, "shape", { value: newSh });
2030
+ return newSh;
2031
+ } });
2032
+ }
2033
+ const _normalized = cached(() => normalizeDef(def));
2034
+ defineLazy(inst._zod, "propValues", () => {
2035
+ const shape = def.shape;
2036
+ const propValues = {};
2037
+ for (const key in shape) {
2038
+ const field = shape[key]._zod;
2039
+ if (field.values) {
2040
+ propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
2041
+ for (const v of field.values) propValues[key].add(v);
2042
+ }
2043
+ }
2044
+ return propValues;
2045
+ });
2046
+ const isObject$1 = isObject;
2047
+ const catchall = def.catchall;
2048
+ let value;
2049
+ inst._zod.parse = (payload, ctx) => {
2050
+ value ?? (value = _normalized.value);
2051
+ const input = payload.value;
2052
+ if (!isObject$1(input)) {
2053
+ payload.issues.push({
2054
+ expected: "object",
2055
+ code: "invalid_type",
2056
+ input,
2057
+ inst
2058
+ });
2059
+ return payload;
2060
+ }
2061
+ payload.value = {};
2062
+ const proms = [];
2063
+ const shape = value.shape;
2064
+ for (const key of value.keys) {
2065
+ const el = shape[key];
2066
+ const isOptionalOut = el._zod.optout === "optional";
2067
+ const r = el._zod.run({
2068
+ value: input[key],
2069
+ issues: []
2070
+ }, ctx);
2071
+ if (r instanceof Promise) proms.push(r.then((r$1) => handlePropertyResult(r$1, payload, key, input, isOptionalOut)));
2072
+ else handlePropertyResult(r, payload, key, input, isOptionalOut);
2073
+ }
2074
+ if (!catchall) return proms.length ? Promise.all(proms).then(() => payload) : payload;
2075
+ return handleCatchall(proms, input, payload, ctx, _normalized.value, inst);
2076
+ };
2077
+ });
2078
+ const $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) => {
2079
+ $ZodObject.init(inst, def);
2080
+ const superParse = inst._zod.parse;
2081
+ const _normalized = cached(() => normalizeDef(def));
2082
+ const generateFastpass = (shape) => {
2083
+ const doc = new Doc([
2084
+ "shape",
2085
+ "payload",
2086
+ "ctx"
2087
+ ]);
2088
+ const normalized = _normalized.value;
2089
+ const parseStr = (key) => {
2090
+ const k = esc(key);
2091
+ return `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
2092
+ };
2093
+ doc.write(`const input = payload.value;`);
2094
+ const ids = Object.create(null);
2095
+ let counter = 0;
2096
+ for (const key of normalized.keys) ids[key] = `key_${counter++}`;
2097
+ doc.write(`const newResult = {};`);
2098
+ for (const key of normalized.keys) {
2099
+ const id = ids[key];
2100
+ const k = esc(key);
2101
+ const isOptionalOut = shape[key]?._zod?.optout === "optional";
2102
+ doc.write(`const ${id} = ${parseStr(key)};`);
2103
+ if (isOptionalOut) doc.write(`
2104
+ if (${id}.issues.length) {
2105
+ if (${k} in input) {
2106
+ payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
2107
+ ...iss,
2108
+ path: iss.path ? [${k}, ...iss.path] : [${k}]
2109
+ })));
2110
+ }
2111
+ }
2112
+
2113
+ if (${id}.value === undefined) {
2114
+ if (${k} in input) {
2115
+ newResult[${k}] = undefined;
2116
+ }
2117
+ } else {
2118
+ newResult[${k}] = ${id}.value;
2119
+ }
2120
+
2121
+ `);
2122
+ else doc.write(`
2123
+ if (${id}.issues.length) {
2124
+ payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
2125
+ ...iss,
2126
+ path: iss.path ? [${k}, ...iss.path] : [${k}]
2127
+ })));
2128
+ }
2129
+
2130
+ if (${id}.value === undefined) {
2131
+ if (${k} in input) {
2132
+ newResult[${k}] = undefined;
2133
+ }
2134
+ } else {
2135
+ newResult[${k}] = ${id}.value;
2136
+ }
2137
+
2138
+ `);
2139
+ }
2140
+ doc.write(`payload.value = newResult;`);
2141
+ doc.write(`return payload;`);
2142
+ const fn = doc.compile();
2143
+ return (payload, ctx) => fn(shape, payload, ctx);
2144
+ };
2145
+ let fastpass;
2146
+ const isObject$1 = isObject;
2147
+ const jit = !globalConfig.jitless;
2148
+ const allowsEval$1 = allowsEval;
2149
+ const fastEnabled = jit && allowsEval$1.value;
2150
+ const catchall = def.catchall;
2151
+ let value;
2152
+ inst._zod.parse = (payload, ctx) => {
2153
+ value ?? (value = _normalized.value);
2154
+ const input = payload.value;
2155
+ if (!isObject$1(input)) {
772
2156
  payload.issues.push({
773
- expected: "array",
2157
+ expected: "object",
774
2158
  code: "invalid_type",
775
2159
  input,
776
2160
  inst
777
2161
  });
778
2162
  return payload;
779
2163
  }
780
- payload.value = Array(input.length);
781
- const proms = [];
782
- for (let i = 0; i < input.length; i++) {
783
- const item = input[i];
784
- const result = def.element._zod.run({
785
- value: item,
786
- issues: []
787
- }, ctx);
788
- if (result instanceof Promise) proms.push(result.then((result$1) => handleArrayResult(result$1, payload, i)));
789
- else handleArrayResult(result, payload, i);
2164
+ if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {
2165
+ if (!fastpass) fastpass = generateFastpass(def.shape);
2166
+ payload = fastpass(payload, ctx);
2167
+ if (!catchall) return payload;
2168
+ return handleCatchall([], input, payload, ctx, value, inst);
790
2169
  }
791
- if (proms.length) return Promise.all(proms).then(() => payload);
792
- return payload;
2170
+ return superParse(payload, ctx);
793
2171
  };
794
2172
  });
795
2173
  function handleUnionResults(results, final, inst, ctx) {
@@ -947,6 +2325,115 @@ function handleIntersectionResults(result, left, right) {
947
2325
  result.value = merged.data;
948
2326
  return result;
949
2327
  }
2328
+ const $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
2329
+ $ZodType.init(inst, def);
2330
+ inst._zod.parse = (payload, ctx) => {
2331
+ const input = payload.value;
2332
+ if (!isPlainObject(input)) {
2333
+ payload.issues.push({
2334
+ expected: "record",
2335
+ code: "invalid_type",
2336
+ input,
2337
+ inst
2338
+ });
2339
+ return payload;
2340
+ }
2341
+ const proms = [];
2342
+ const values = def.keyType._zod.values;
2343
+ if (values) {
2344
+ payload.value = {};
2345
+ const recordKeys = /* @__PURE__ */ new Set();
2346
+ for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
2347
+ recordKeys.add(typeof key === "number" ? key.toString() : key);
2348
+ const result = def.valueType._zod.run({
2349
+ value: input[key],
2350
+ issues: []
2351
+ }, ctx);
2352
+ if (result instanceof Promise) proms.push(result.then((result$1) => {
2353
+ if (result$1.issues.length) payload.issues.push(...prefixIssues(key, result$1.issues));
2354
+ payload.value[key] = result$1.value;
2355
+ }));
2356
+ else {
2357
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2358
+ payload.value[key] = result.value;
2359
+ }
2360
+ }
2361
+ let unrecognized;
2362
+ for (const key in input) if (!recordKeys.has(key)) {
2363
+ unrecognized = unrecognized ?? [];
2364
+ unrecognized.push(key);
2365
+ }
2366
+ if (unrecognized && unrecognized.length > 0) payload.issues.push({
2367
+ code: "unrecognized_keys",
2368
+ input,
2369
+ inst,
2370
+ keys: unrecognized
2371
+ });
2372
+ } else {
2373
+ payload.value = {};
2374
+ for (const key of Reflect.ownKeys(input)) {
2375
+ if (key === "__proto__") continue;
2376
+ let keyResult = def.keyType._zod.run({
2377
+ value: key,
2378
+ issues: []
2379
+ }, ctx);
2380
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
2381
+ if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) {
2382
+ const retryResult = def.keyType._zod.run({
2383
+ value: Number(key),
2384
+ issues: []
2385
+ }, ctx);
2386
+ if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
2387
+ if (retryResult.issues.length === 0) keyResult = retryResult;
2388
+ }
2389
+ if (keyResult.issues.length) {
2390
+ if (def.mode === "loose") payload.value[key] = input[key];
2391
+ else payload.issues.push({
2392
+ code: "invalid_key",
2393
+ origin: "record",
2394
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
2395
+ input: key,
2396
+ path: [key],
2397
+ inst
2398
+ });
2399
+ continue;
2400
+ }
2401
+ const result = def.valueType._zod.run({
2402
+ value: input[key],
2403
+ issues: []
2404
+ }, ctx);
2405
+ if (result instanceof Promise) proms.push(result.then((result$1) => {
2406
+ if (result$1.issues.length) payload.issues.push(...prefixIssues(key, result$1.issues));
2407
+ payload.value[keyResult.value] = result$1.value;
2408
+ }));
2409
+ else {
2410
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2411
+ payload.value[keyResult.value] = result.value;
2412
+ }
2413
+ }
2414
+ }
2415
+ if (proms.length) return Promise.all(proms).then(() => payload);
2416
+ return payload;
2417
+ };
2418
+ });
2419
+ const $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
2420
+ $ZodType.init(inst, def);
2421
+ const values = getEnumValues(def.entries);
2422
+ const valuesSet = new Set(values);
2423
+ inst._zod.values = valuesSet;
2424
+ inst._zod.pattern = /* @__PURE__ */ new RegExp(`^(${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})$`);
2425
+ inst._zod.parse = (payload, _ctx) => {
2426
+ const input = payload.value;
2427
+ if (valuesSet.has(input)) return payload;
2428
+ payload.issues.push({
2429
+ code: "invalid_value",
2430
+ values,
2431
+ input,
2432
+ inst
2433
+ });
2434
+ return payload;
2435
+ };
2436
+ });
950
2437
  const $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) => {
951
2438
  $ZodType.init(inst, def);
952
2439
  inst._zod.parse = (payload, ctx) => {
@@ -1216,14 +2703,353 @@ var $ZodRegistry = class {
1216
2703
  function registry() {
1217
2704
  return new $ZodRegistry();
1218
2705
  }
1219
- (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
1220
- const globalRegistry = globalThis.__zod_globalRegistry;
1221
-
1222
- //#endregion
1223
- //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/api.js
2706
+ (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
2707
+ const globalRegistry = globalThis.__zod_globalRegistry;
2708
+
2709
+ //#endregion
2710
+ //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/api.js
2711
+ /* @__NO_SIDE_EFFECTS__ */
2712
+ function _string(Class, params) {
2713
+ return new Class({
2714
+ type: "string",
2715
+ ...normalizeParams(params)
2716
+ });
2717
+ }
2718
+ /* @__NO_SIDE_EFFECTS__ */
2719
+ function _email(Class, params) {
2720
+ return new Class({
2721
+ type: "string",
2722
+ format: "email",
2723
+ check: "string_format",
2724
+ abort: false,
2725
+ ...normalizeParams(params)
2726
+ });
2727
+ }
2728
+ /* @__NO_SIDE_EFFECTS__ */
2729
+ function _guid(Class, params) {
2730
+ return new Class({
2731
+ type: "string",
2732
+ format: "guid",
2733
+ check: "string_format",
2734
+ abort: false,
2735
+ ...normalizeParams(params)
2736
+ });
2737
+ }
2738
+ /* @__NO_SIDE_EFFECTS__ */
2739
+ function _uuid(Class, params) {
2740
+ return new Class({
2741
+ type: "string",
2742
+ format: "uuid",
2743
+ check: "string_format",
2744
+ abort: false,
2745
+ ...normalizeParams(params)
2746
+ });
2747
+ }
2748
+ /* @__NO_SIDE_EFFECTS__ */
2749
+ function _uuidv4(Class, params) {
2750
+ return new Class({
2751
+ type: "string",
2752
+ format: "uuid",
2753
+ check: "string_format",
2754
+ abort: false,
2755
+ version: "v4",
2756
+ ...normalizeParams(params)
2757
+ });
2758
+ }
2759
+ /* @__NO_SIDE_EFFECTS__ */
2760
+ function _uuidv6(Class, params) {
2761
+ return new Class({
2762
+ type: "string",
2763
+ format: "uuid",
2764
+ check: "string_format",
2765
+ abort: false,
2766
+ version: "v6",
2767
+ ...normalizeParams(params)
2768
+ });
2769
+ }
2770
+ /* @__NO_SIDE_EFFECTS__ */
2771
+ function _uuidv7(Class, params) {
2772
+ return new Class({
2773
+ type: "string",
2774
+ format: "uuid",
2775
+ check: "string_format",
2776
+ abort: false,
2777
+ version: "v7",
2778
+ ...normalizeParams(params)
2779
+ });
2780
+ }
2781
+ /* @__NO_SIDE_EFFECTS__ */
2782
+ function _url(Class, params) {
2783
+ return new Class({
2784
+ type: "string",
2785
+ format: "url",
2786
+ check: "string_format",
2787
+ abort: false,
2788
+ ...normalizeParams(params)
2789
+ });
2790
+ }
2791
+ /* @__NO_SIDE_EFFECTS__ */
2792
+ function _emoji(Class, params) {
2793
+ return new Class({
2794
+ type: "string",
2795
+ format: "emoji",
2796
+ check: "string_format",
2797
+ abort: false,
2798
+ ...normalizeParams(params)
2799
+ });
2800
+ }
2801
+ /* @__NO_SIDE_EFFECTS__ */
2802
+ function _nanoid(Class, params) {
2803
+ return new Class({
2804
+ type: "string",
2805
+ format: "nanoid",
2806
+ check: "string_format",
2807
+ abort: false,
2808
+ ...normalizeParams(params)
2809
+ });
2810
+ }
2811
+ /* @__NO_SIDE_EFFECTS__ */
2812
+ function _cuid(Class, params) {
2813
+ return new Class({
2814
+ type: "string",
2815
+ format: "cuid",
2816
+ check: "string_format",
2817
+ abort: false,
2818
+ ...normalizeParams(params)
2819
+ });
2820
+ }
2821
+ /* @__NO_SIDE_EFFECTS__ */
2822
+ function _cuid2(Class, params) {
2823
+ return new Class({
2824
+ type: "string",
2825
+ format: "cuid2",
2826
+ check: "string_format",
2827
+ abort: false,
2828
+ ...normalizeParams(params)
2829
+ });
2830
+ }
2831
+ /* @__NO_SIDE_EFFECTS__ */
2832
+ function _ulid(Class, params) {
2833
+ return new Class({
2834
+ type: "string",
2835
+ format: "ulid",
2836
+ check: "string_format",
2837
+ abort: false,
2838
+ ...normalizeParams(params)
2839
+ });
2840
+ }
2841
+ /* @__NO_SIDE_EFFECTS__ */
2842
+ function _xid(Class, params) {
2843
+ return new Class({
2844
+ type: "string",
2845
+ format: "xid",
2846
+ check: "string_format",
2847
+ abort: false,
2848
+ ...normalizeParams(params)
2849
+ });
2850
+ }
2851
+ /* @__NO_SIDE_EFFECTS__ */
2852
+ function _ksuid(Class, params) {
2853
+ return new Class({
2854
+ type: "string",
2855
+ format: "ksuid",
2856
+ check: "string_format",
2857
+ abort: false,
2858
+ ...normalizeParams(params)
2859
+ });
2860
+ }
2861
+ /* @__NO_SIDE_EFFECTS__ */
2862
+ function _ipv4(Class, params) {
2863
+ return new Class({
2864
+ type: "string",
2865
+ format: "ipv4",
2866
+ check: "string_format",
2867
+ abort: false,
2868
+ ...normalizeParams(params)
2869
+ });
2870
+ }
2871
+ /* @__NO_SIDE_EFFECTS__ */
2872
+ function _ipv6(Class, params) {
2873
+ return new Class({
2874
+ type: "string",
2875
+ format: "ipv6",
2876
+ check: "string_format",
2877
+ abort: false,
2878
+ ...normalizeParams(params)
2879
+ });
2880
+ }
2881
+ /* @__NO_SIDE_EFFECTS__ */
2882
+ function _cidrv4(Class, params) {
2883
+ return new Class({
2884
+ type: "string",
2885
+ format: "cidrv4",
2886
+ check: "string_format",
2887
+ abort: false,
2888
+ ...normalizeParams(params)
2889
+ });
2890
+ }
2891
+ /* @__NO_SIDE_EFFECTS__ */
2892
+ function _cidrv6(Class, params) {
2893
+ return new Class({
2894
+ type: "string",
2895
+ format: "cidrv6",
2896
+ check: "string_format",
2897
+ abort: false,
2898
+ ...normalizeParams(params)
2899
+ });
2900
+ }
2901
+ /* @__NO_SIDE_EFFECTS__ */
2902
+ function _base64(Class, params) {
2903
+ return new Class({
2904
+ type: "string",
2905
+ format: "base64",
2906
+ check: "string_format",
2907
+ abort: false,
2908
+ ...normalizeParams(params)
2909
+ });
2910
+ }
2911
+ /* @__NO_SIDE_EFFECTS__ */
2912
+ function _base64url(Class, params) {
2913
+ return new Class({
2914
+ type: "string",
2915
+ format: "base64url",
2916
+ check: "string_format",
2917
+ abort: false,
2918
+ ...normalizeParams(params)
2919
+ });
2920
+ }
2921
+ /* @__NO_SIDE_EFFECTS__ */
2922
+ function _e164(Class, params) {
2923
+ return new Class({
2924
+ type: "string",
2925
+ format: "e164",
2926
+ check: "string_format",
2927
+ abort: false,
2928
+ ...normalizeParams(params)
2929
+ });
2930
+ }
2931
+ /* @__NO_SIDE_EFFECTS__ */
2932
+ function _jwt(Class, params) {
2933
+ return new Class({
2934
+ type: "string",
2935
+ format: "jwt",
2936
+ check: "string_format",
2937
+ abort: false,
2938
+ ...normalizeParams(params)
2939
+ });
2940
+ }
2941
+ /* @__NO_SIDE_EFFECTS__ */
2942
+ function _isoDateTime(Class, params) {
2943
+ return new Class({
2944
+ type: "string",
2945
+ format: "datetime",
2946
+ check: "string_format",
2947
+ offset: false,
2948
+ local: false,
2949
+ precision: null,
2950
+ ...normalizeParams(params)
2951
+ });
2952
+ }
2953
+ /* @__NO_SIDE_EFFECTS__ */
2954
+ function _isoDate(Class, params) {
2955
+ return new Class({
2956
+ type: "string",
2957
+ format: "date",
2958
+ check: "string_format",
2959
+ ...normalizeParams(params)
2960
+ });
2961
+ }
2962
+ /* @__NO_SIDE_EFFECTS__ */
2963
+ function _isoTime(Class, params) {
2964
+ return new Class({
2965
+ type: "string",
2966
+ format: "time",
2967
+ check: "string_format",
2968
+ precision: null,
2969
+ ...normalizeParams(params)
2970
+ });
2971
+ }
2972
+ /* @__NO_SIDE_EFFECTS__ */
2973
+ function _isoDuration(Class, params) {
2974
+ return new Class({
2975
+ type: "string",
2976
+ format: "duration",
2977
+ check: "string_format",
2978
+ ...normalizeParams(params)
2979
+ });
2980
+ }
2981
+ /* @__NO_SIDE_EFFECTS__ */
2982
+ function _number(Class, params) {
2983
+ return new Class({
2984
+ type: "number",
2985
+ checks: [],
2986
+ ...normalizeParams(params)
2987
+ });
2988
+ }
2989
+ /* @__NO_SIDE_EFFECTS__ */
2990
+ function _int(Class, params) {
2991
+ return new Class({
2992
+ type: "number",
2993
+ check: "number_format",
2994
+ abort: false,
2995
+ format: "safeint",
2996
+ ...normalizeParams(params)
2997
+ });
2998
+ }
2999
+ /* @__NO_SIDE_EFFECTS__ */
3000
+ function _unknown(Class) {
3001
+ return new Class({ type: "unknown" });
3002
+ }
3003
+ /* @__NO_SIDE_EFFECTS__ */
3004
+ function _never(Class, params) {
3005
+ return new Class({
3006
+ type: "never",
3007
+ ...normalizeParams(params)
3008
+ });
3009
+ }
3010
+ /* @__NO_SIDE_EFFECTS__ */
3011
+ function _lt(value, params) {
3012
+ return new $ZodCheckLessThan({
3013
+ check: "less_than",
3014
+ ...normalizeParams(params),
3015
+ value,
3016
+ inclusive: false
3017
+ });
3018
+ }
3019
+ /* @__NO_SIDE_EFFECTS__ */
3020
+ function _lte(value, params) {
3021
+ return new $ZodCheckLessThan({
3022
+ check: "less_than",
3023
+ ...normalizeParams(params),
3024
+ value,
3025
+ inclusive: true
3026
+ });
3027
+ }
3028
+ /* @__NO_SIDE_EFFECTS__ */
3029
+ function _gt(value, params) {
3030
+ return new $ZodCheckGreaterThan({
3031
+ check: "greater_than",
3032
+ ...normalizeParams(params),
3033
+ value,
3034
+ inclusive: false
3035
+ });
3036
+ }
1224
3037
  /* @__NO_SIDE_EFFECTS__ */
1225
- function _unknown(Class) {
1226
- return new Class({ type: "unknown" });
3038
+ function _gte(value, params) {
3039
+ return new $ZodCheckGreaterThan({
3040
+ check: "greater_than",
3041
+ ...normalizeParams(params),
3042
+ value,
3043
+ inclusive: true
3044
+ });
3045
+ }
3046
+ /* @__NO_SIDE_EFFECTS__ */
3047
+ function _multipleOf(value, params) {
3048
+ return new $ZodCheckMultipleOf({
3049
+ check: "multiple_of",
3050
+ ...normalizeParams(params),
3051
+ value
3052
+ });
1227
3053
  }
1228
3054
  /* @__NO_SIDE_EFFECTS__ */
1229
3055
  function _maxLength(maximum, params) {
@@ -1250,6 +3076,58 @@ function _length(length, params) {
1250
3076
  });
1251
3077
  }
1252
3078
  /* @__NO_SIDE_EFFECTS__ */
3079
+ function _regex(pattern, params) {
3080
+ return new $ZodCheckRegex({
3081
+ check: "string_format",
3082
+ format: "regex",
3083
+ ...normalizeParams(params),
3084
+ pattern
3085
+ });
3086
+ }
3087
+ /* @__NO_SIDE_EFFECTS__ */
3088
+ function _lowercase(params) {
3089
+ return new $ZodCheckLowerCase({
3090
+ check: "string_format",
3091
+ format: "lowercase",
3092
+ ...normalizeParams(params)
3093
+ });
3094
+ }
3095
+ /* @__NO_SIDE_EFFECTS__ */
3096
+ function _uppercase(params) {
3097
+ return new $ZodCheckUpperCase({
3098
+ check: "string_format",
3099
+ format: "uppercase",
3100
+ ...normalizeParams(params)
3101
+ });
3102
+ }
3103
+ /* @__NO_SIDE_EFFECTS__ */
3104
+ function _includes(includes, params) {
3105
+ return new $ZodCheckIncludes({
3106
+ check: "string_format",
3107
+ format: "includes",
3108
+ ...normalizeParams(params),
3109
+ includes
3110
+ });
3111
+ }
3112
+ /* @__NO_SIDE_EFFECTS__ */
3113
+ function _startsWith(prefix, params) {
3114
+ return new $ZodCheckStartsWith({
3115
+ check: "string_format",
3116
+ format: "starts_with",
3117
+ ...normalizeParams(params),
3118
+ prefix
3119
+ });
3120
+ }
3121
+ /* @__NO_SIDE_EFFECTS__ */
3122
+ function _endsWith(suffix, params) {
3123
+ return new $ZodCheckEndsWith({
3124
+ check: "string_format",
3125
+ format: "ends_with",
3126
+ ...normalizeParams(params),
3127
+ suffix
3128
+ });
3129
+ }
3130
+ /* @__NO_SIDE_EFFECTS__ */
1253
3131
  function _overwrite(tx) {
1254
3132
  return new $ZodCheckOverwrite({
1255
3133
  check: "overwrite",
@@ -1257,6 +3135,26 @@ function _overwrite(tx) {
1257
3135
  });
1258
3136
  }
1259
3137
  /* @__NO_SIDE_EFFECTS__ */
3138
+ function _normalize(form) {
3139
+ return /* @__PURE__ */ _overwrite((input) => input.normalize(form));
3140
+ }
3141
+ /* @__NO_SIDE_EFFECTS__ */
3142
+ function _trim() {
3143
+ return /* @__PURE__ */ _overwrite((input) => input.trim());
3144
+ }
3145
+ /* @__NO_SIDE_EFFECTS__ */
3146
+ function _toLowerCase() {
3147
+ return /* @__PURE__ */ _overwrite((input) => input.toLowerCase());
3148
+ }
3149
+ /* @__NO_SIDE_EFFECTS__ */
3150
+ function _toUpperCase() {
3151
+ return /* @__PURE__ */ _overwrite((input) => input.toUpperCase());
3152
+ }
3153
+ /* @__NO_SIDE_EFFECTS__ */
3154
+ function _slugify() {
3155
+ return /* @__PURE__ */ _overwrite((input) => slugify(input));
3156
+ }
3157
+ /* @__NO_SIDE_EFFECTS__ */
1260
3158
  function _array(Class, element, params) {
1261
3159
  return new Class({
1262
3160
  type: "array",
@@ -2100,53 +3998,35 @@ let AIAgentExecutionHelpersFactory = class AIAgentExecutionHelpersFactory$1 {
2100
3998
  createConnectionCredentialExecutionContextFactory(credentialSessions) {
2101
3999
  return new ConnectionCredentialExecutionContextFactory(credentialSessions);
2102
4000
  }
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
4001
  /**
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`.
4002
+ * Produces a plain JSON Schema object (`draft-07`) from a Zod schema, as needed by
4003
+ * OpenAI tool-parameter schemas and the structured-output repair prompt.
4004
+ * - Prefers the schema's **instance** `toJSONSchema(...)` method so we stay inside the Zod
4005
+ * instance that created the schema (works across consumer/framework tsx namespaces see
4006
+ * {@link ZodInstanceToJsonSchema}). Falls back to the framework-imported module function.
4007
+ * - Strips root `$schema` (OpenAI ignores it).
4008
+ * - Sanitizes `required` for cfworker json-schema compatibility (must be a string array or absent).
2133
4009
  */
2134
4010
  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)}).`);
4011
+ const { $schema: _draftSchemaOmitted,...rest } = this.convertZodSchemaToJsonSchema(inputSchema, { target: "draft-07" });
4012
+ 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)}).`);
4013
+ 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
4014
  if (options.requireObjectRoot && rest.properties === void 0) rest.properties = {};
2146
4015
  this.sanitizeJsonSchemaRequiredKeywordsForCfworker(rest);
2147
4016
  return rest;
2148
4017
  }
2149
4018
  /**
4019
+ * Runs Zod's `toJSONSchema` via the schema's own instance method when available, so consumer
4020
+ * schemas loaded under a different tsx namespace still convert correctly. If the caller handed us
4021
+ * a payload that lacks that method (e.g. a plain JSON Schema record or a Zod instance whose
4022
+ * prototype was stripped), we fall back to the framework-bundled module function.
4023
+ */
4024
+ convertZodSchemaToJsonSchema(inputSchema, params) {
4025
+ const candidate = inputSchema.toJSONSchema;
4026
+ if (typeof candidate === "function") return candidate.call(inputSchema, params);
4027
+ return toJSONSchema(inputSchema, params);
4028
+ }
4029
+ /**
2150
4030
  * `@cfworker/json-schema` iterates `schema.required` with `for...of`; it must be a string array or absent.
2151
4031
  */
2152
4032
  sanitizeJsonSchemaRequiredKeywordsForCfworker(node$1) {
@@ -2193,6 +4073,214 @@ function __decorateParam(paramIndex, decorator) {
2193
4073
  };
2194
4074
  }
2195
4075
 
4076
+ //#endregion
4077
+ //#region src/chatModels/OpenAiStrictJsonSchemaFactory.ts
4078
+ var _ref$5;
4079
+ let OpenAiStrictJsonSchemaFactory = class OpenAiStrictJsonSchemaFactory$1 {
4080
+ constructor(executionHelpers) {
4081
+ this.executionHelpers = executionHelpers;
4082
+ }
4083
+ createStructuredOutputRecord(schema, options) {
4084
+ const record$1 = this.executionHelpers.createJsonSchemaRecord(schema, {
4085
+ schemaName: options.schemaName,
4086
+ requireObjectRoot: false
4087
+ });
4088
+ this.strictifyRecursive(record$1);
4089
+ if (options.title !== void 0) record$1.title = options.title;
4090
+ return record$1;
4091
+ }
4092
+ strictifyRecursive(node$1) {
4093
+ if (!node$1 || typeof node$1 !== "object" || Array.isArray(node$1)) return;
4094
+ const o = node$1;
4095
+ this.stripOpenAiRejectedKeywords(o);
4096
+ if (this.isObjectNode(o)) {
4097
+ const props = this.readPropertiesObject(o);
4098
+ o.properties = props;
4099
+ o.additionalProperties = false;
4100
+ o.required = Object.keys(props);
4101
+ for (const value of Object.values(props)) this.strictifyRecursive(value);
4102
+ }
4103
+ this.recurseIntoComposites(o);
4104
+ }
4105
+ stripOpenAiRejectedKeywords(o) {
4106
+ delete o["$schema"];
4107
+ delete o["unevaluatedProperties"];
4108
+ delete o["default"];
4109
+ }
4110
+ isObjectNode(o) {
4111
+ const typeIsObject = o.type === "object" || Array.isArray(o.type) && o.type.includes("object");
4112
+ const hasObjectProperties = o.properties !== void 0 && typeof o.properties === "object" && !Array.isArray(o.properties);
4113
+ return typeIsObject || hasObjectProperties;
4114
+ }
4115
+ readPropertiesObject(o) {
4116
+ if (o.properties && typeof o.properties === "object" && !Array.isArray(o.properties)) return o.properties;
4117
+ return {};
4118
+ }
4119
+ recurseIntoComposites(o) {
4120
+ for (const key of [
4121
+ "allOf",
4122
+ "anyOf",
4123
+ "oneOf",
4124
+ "prefixItems"
4125
+ ]) {
4126
+ const branch = o[key];
4127
+ if (Array.isArray(branch)) for (const sub of branch) this.strictifyRecursive(sub);
4128
+ }
4129
+ if (o.not) this.strictifyRecursive(o.not);
4130
+ if (o.items) if (Array.isArray(o.items)) for (const sub of o.items) this.strictifyRecursive(sub);
4131
+ else this.strictifyRecursive(o.items);
4132
+ for (const key of [
4133
+ "if",
4134
+ "then",
4135
+ "else"
4136
+ ]) if (o[key]) this.strictifyRecursive(o[key]);
4137
+ for (const key of ["$defs", "definitions"]) {
4138
+ const defs = o[key];
4139
+ if (defs && typeof defs === "object" && !Array.isArray(defs)) for (const sub of Object.values(defs)) this.strictifyRecursive(sub);
4140
+ }
4141
+ }
4142
+ };
4143
+ OpenAiStrictJsonSchemaFactory = __decorate([
4144
+ injectable(),
4145
+ __decorateParam(0, inject(AIAgentExecutionHelpersFactory)),
4146
+ __decorateMetadata("design:paramtypes", [typeof (_ref$5 = typeof AIAgentExecutionHelpersFactory !== "undefined" && AIAgentExecutionHelpersFactory) === "function" ? _ref$5 : Object])
4147
+ ], OpenAiStrictJsonSchemaFactory);
4148
+
4149
+ //#endregion
4150
+ //#region src/chatModels/openAiChatModelConfig.ts
4151
+ var OpenAIChatModelConfig = class {
4152
+ type = OpenAIChatModelFactory;
4153
+ presentation;
4154
+ provider = "openai";
4155
+ modelName;
4156
+ constructor(name, model, credentialSlotKey = "openai", presentationIn, options) {
4157
+ this.name = name;
4158
+ this.model = model;
4159
+ this.credentialSlotKey = credentialSlotKey;
4160
+ this.options = options;
4161
+ this.modelName = model;
4162
+ this.presentation = presentationIn ?? {
4163
+ icon: "builtin:openai",
4164
+ label: name
4165
+ };
4166
+ }
4167
+ getCredentialRequirements() {
4168
+ return [{
4169
+ slotKey: this.credentialSlotKey,
4170
+ label: "OpenAI API key",
4171
+ acceptedTypes: ["openai.apiKey"]
4172
+ }];
4173
+ }
4174
+ };
4175
+
4176
+ //#endregion
4177
+ //#region src/chatModels/OpenAiChatModelPresetsFactory.ts
4178
+ /**
4179
+ * Default OpenAI chat model configs for scaffolds and demos (icon + label match {@link OpenAIChatModelConfig} defaults).
4180
+ * Prefer importing {@link openAiChatModelPresets} from here or from the consumer template re-export
4181
+ * instead of repeating {@link OpenAIChatModelConfig} construction in app workflows.
4182
+ */
4183
+ var OpenAiChatModelPresets = class {
4184
+ demoGpt4oMini = new OpenAIChatModelConfig("OpenAI", "gpt-4o-mini");
4185
+ demoGpt41 = new OpenAIChatModelConfig("OpenAI", "gpt-4.1");
4186
+ };
4187
+ const openAiChatModelPresets = new OpenAiChatModelPresets();
4188
+
4189
+ //#endregion
4190
+ //#region src/nodes/AgentMessageFactory.ts
4191
+ /**
4192
+ * AI-SDK-shaped message construction for the AIAgent stack. Emits plain `ModelMessage[]`
4193
+ * ( `{ role: 'system' | 'user' | 'assistant' | 'tool', content: ... }` ) as consumed by
4194
+ * `generateText({ messages })` from the `ai` package.
4195
+ */
4196
+ var AgentMessageFactory = class AgentMessageFactory {
4197
+ static createPromptMessages(messages) {
4198
+ return messages.map((message) => this.createPromptMessage(message));
4199
+ }
4200
+ /**
4201
+ * Builds the assistant message that contains optional text plus one or more tool-call parts,
4202
+ * matching the shape AI SDK emits between steps.
4203
+ */
4204
+ static createAssistantWithToolCalls(text, toolCalls) {
4205
+ const content = [];
4206
+ if (text && text.length > 0) content.push({
4207
+ type: "text",
4208
+ text
4209
+ });
4210
+ for (const toolCall of toolCalls) content.push({
4211
+ type: "tool-call",
4212
+ toolCallId: toolCall.id ?? toolCall.name,
4213
+ toolName: toolCall.name,
4214
+ input: toolCall.input ?? {}
4215
+ });
4216
+ return {
4217
+ role: "assistant",
4218
+ content
4219
+ };
4220
+ }
4221
+ /**
4222
+ * Builds the `{ role: "tool", content: [{ type: "tool-result", ... }, ...] }` message returned
4223
+ * to the model after each tool round.
4224
+ */
4225
+ static createToolResultsMessage(executedToolCalls) {
4226
+ return {
4227
+ role: "tool",
4228
+ content: executedToolCalls.map((executed) => ({
4229
+ type: "tool-result",
4230
+ toolCallId: executed.toolCallId,
4231
+ toolName: executed.toolName,
4232
+ output: {
4233
+ type: "json",
4234
+ value: AgentMessageFactory.toToolResultJson(executed.result)
4235
+ }
4236
+ }))
4237
+ };
4238
+ }
4239
+ static toToolResultJson(value) {
4240
+ if (value === void 0) return null;
4241
+ try {
4242
+ return JSON.parse(JSON.stringify(value));
4243
+ } catch {
4244
+ return String(value);
4245
+ }
4246
+ }
4247
+ static createPromptMessage(message) {
4248
+ if (message.role === "system") return {
4249
+ role: "system",
4250
+ content: message.content
4251
+ };
4252
+ if (message.role === "assistant") return {
4253
+ role: "assistant",
4254
+ content: message.content
4255
+ };
4256
+ return {
4257
+ role: "user",
4258
+ content: message.content
4259
+ };
4260
+ }
4261
+ };
4262
+
4263
+ //#endregion
4264
+ //#region src/nodes/AgentOutputFactory.ts
4265
+ var AgentOutputFactory = class {
4266
+ static fromUnknown(value) {
4267
+ return { main: [{ json: value }] };
4268
+ }
4269
+ static replaceJson(item, value) {
4270
+ return {
4271
+ ...item,
4272
+ json: value
4273
+ };
4274
+ }
4275
+ static fromAgentContent(content) {
4276
+ try {
4277
+ return JSON.parse(content);
4278
+ } catch {
4279
+ return { output: content };
4280
+ }
4281
+ }
4282
+ };
4283
+
2196
4284
  //#endregion
2197
4285
  //#region src/nodes/AgentStructuredOutputRepairPromptFactory.ts
2198
4286
  var _ref$4, _AgentStructuredOutputRepairPromptFactory;
@@ -2233,6 +4321,37 @@ AgentStructuredOutputRepairPromptFactory = _AgentStructuredOutputRepairPromptFac
2233
4321
  __decorateMetadata("design:paramtypes", [typeof (_ref$4 = typeof AIAgentExecutionHelpersFactory !== "undefined" && AIAgentExecutionHelpersFactory) === "function" ? _ref$4 : Object])
2234
4322
  ], AgentStructuredOutputRepairPromptFactory);
2235
4323
 
4324
+ //#endregion
4325
+ //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/iso.js
4326
+ const ZodISODateTime = /* @__PURE__ */ $constructor("ZodISODateTime", (inst, def) => {
4327
+ $ZodISODateTime.init(inst, def);
4328
+ ZodStringFormat.init(inst, def);
4329
+ });
4330
+ function datetime(params) {
4331
+ return _isoDateTime(ZodISODateTime, params);
4332
+ }
4333
+ const ZodISODate = /* @__PURE__ */ $constructor("ZodISODate", (inst, def) => {
4334
+ $ZodISODate.init(inst, def);
4335
+ ZodStringFormat.init(inst, def);
4336
+ });
4337
+ function date(params) {
4338
+ return _isoDate(ZodISODate, params);
4339
+ }
4340
+ const ZodISOTime = /* @__PURE__ */ $constructor("ZodISOTime", (inst, def) => {
4341
+ $ZodISOTime.init(inst, def);
4342
+ ZodStringFormat.init(inst, def);
4343
+ });
4344
+ function time(params) {
4345
+ return _isoTime(ZodISOTime, params);
4346
+ }
4347
+ const ZodISODuration = /* @__PURE__ */ $constructor("ZodISODuration", (inst, def) => {
4348
+ $ZodISODuration.init(inst, def);
4349
+ ZodStringFormat.init(inst, def);
4350
+ });
4351
+ function duration(params) {
4352
+ return _isoDuration(ZodISODuration, params);
4353
+ }
4354
+
2236
4355
  //#endregion
2237
4356
  //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/errors.js
2238
4357
  const initializer = (inst, issues) => {
@@ -2350,6 +4469,181 @@ const ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
2350
4469
  inst.apply = (fn) => fn(inst);
2351
4470
  return inst;
2352
4471
  });
4472
+ /** @internal */
4473
+ const _ZodString = /* @__PURE__ */ $constructor("_ZodString", (inst, def) => {
4474
+ $ZodString.init(inst, def);
4475
+ ZodType.init(inst, def);
4476
+ inst._zod.processJSONSchema = (ctx, json, params) => stringProcessor(inst, ctx, json, params);
4477
+ const bag = inst._zod.bag;
4478
+ inst.format = bag.format ?? null;
4479
+ inst.minLength = bag.minimum ?? null;
4480
+ inst.maxLength = bag.maximum ?? null;
4481
+ inst.regex = (...args) => inst.check(_regex(...args));
4482
+ inst.includes = (...args) => inst.check(_includes(...args));
4483
+ inst.startsWith = (...args) => inst.check(_startsWith(...args));
4484
+ inst.endsWith = (...args) => inst.check(_endsWith(...args));
4485
+ inst.min = (...args) => inst.check(_minLength(...args));
4486
+ inst.max = (...args) => inst.check(_maxLength(...args));
4487
+ inst.length = (...args) => inst.check(_length(...args));
4488
+ inst.nonempty = (...args) => inst.check(_minLength(1, ...args));
4489
+ inst.lowercase = (params) => inst.check(_lowercase(params));
4490
+ inst.uppercase = (params) => inst.check(_uppercase(params));
4491
+ inst.trim = () => inst.check(_trim());
4492
+ inst.normalize = (...args) => inst.check(_normalize(...args));
4493
+ inst.toLowerCase = () => inst.check(_toLowerCase());
4494
+ inst.toUpperCase = () => inst.check(_toUpperCase());
4495
+ inst.slugify = () => inst.check(_slugify());
4496
+ });
4497
+ const ZodString = /* @__PURE__ */ $constructor("ZodString", (inst, def) => {
4498
+ $ZodString.init(inst, def);
4499
+ _ZodString.init(inst, def);
4500
+ inst.email = (params) => inst.check(_email(ZodEmail, params));
4501
+ inst.url = (params) => inst.check(_url(ZodURL, params));
4502
+ inst.jwt = (params) => inst.check(_jwt(ZodJWT, params));
4503
+ inst.emoji = (params) => inst.check(_emoji(ZodEmoji, params));
4504
+ inst.guid = (params) => inst.check(_guid(ZodGUID, params));
4505
+ inst.uuid = (params) => inst.check(_uuid(ZodUUID, params));
4506
+ inst.uuidv4 = (params) => inst.check(_uuidv4(ZodUUID, params));
4507
+ inst.uuidv6 = (params) => inst.check(_uuidv6(ZodUUID, params));
4508
+ inst.uuidv7 = (params) => inst.check(_uuidv7(ZodUUID, params));
4509
+ inst.nanoid = (params) => inst.check(_nanoid(ZodNanoID, params));
4510
+ inst.guid = (params) => inst.check(_guid(ZodGUID, params));
4511
+ inst.cuid = (params) => inst.check(_cuid(ZodCUID, params));
4512
+ inst.cuid2 = (params) => inst.check(_cuid2(ZodCUID2, params));
4513
+ inst.ulid = (params) => inst.check(_ulid(ZodULID, params));
4514
+ inst.base64 = (params) => inst.check(_base64(ZodBase64, params));
4515
+ inst.base64url = (params) => inst.check(_base64url(ZodBase64URL, params));
4516
+ inst.xid = (params) => inst.check(_xid(ZodXID, params));
4517
+ inst.ksuid = (params) => inst.check(_ksuid(ZodKSUID, params));
4518
+ inst.ipv4 = (params) => inst.check(_ipv4(ZodIPv4, params));
4519
+ inst.ipv6 = (params) => inst.check(_ipv6(ZodIPv6, params));
4520
+ inst.cidrv4 = (params) => inst.check(_cidrv4(ZodCIDRv4, params));
4521
+ inst.cidrv6 = (params) => inst.check(_cidrv6(ZodCIDRv6, params));
4522
+ inst.e164 = (params) => inst.check(_e164(ZodE164, params));
4523
+ inst.datetime = (params) => inst.check(datetime(params));
4524
+ inst.date = (params) => inst.check(date(params));
4525
+ inst.time = (params) => inst.check(time(params));
4526
+ inst.duration = (params) => inst.check(duration(params));
4527
+ });
4528
+ function string(params) {
4529
+ return _string(ZodString, params);
4530
+ }
4531
+ const ZodStringFormat = /* @__PURE__ */ $constructor("ZodStringFormat", (inst, def) => {
4532
+ $ZodStringFormat.init(inst, def);
4533
+ _ZodString.init(inst, def);
4534
+ });
4535
+ const ZodEmail = /* @__PURE__ */ $constructor("ZodEmail", (inst, def) => {
4536
+ $ZodEmail.init(inst, def);
4537
+ ZodStringFormat.init(inst, def);
4538
+ });
4539
+ const ZodGUID = /* @__PURE__ */ $constructor("ZodGUID", (inst, def) => {
4540
+ $ZodGUID.init(inst, def);
4541
+ ZodStringFormat.init(inst, def);
4542
+ });
4543
+ const ZodUUID = /* @__PURE__ */ $constructor("ZodUUID", (inst, def) => {
4544
+ $ZodUUID.init(inst, def);
4545
+ ZodStringFormat.init(inst, def);
4546
+ });
4547
+ const ZodURL = /* @__PURE__ */ $constructor("ZodURL", (inst, def) => {
4548
+ $ZodURL.init(inst, def);
4549
+ ZodStringFormat.init(inst, def);
4550
+ });
4551
+ const ZodEmoji = /* @__PURE__ */ $constructor("ZodEmoji", (inst, def) => {
4552
+ $ZodEmoji.init(inst, def);
4553
+ ZodStringFormat.init(inst, def);
4554
+ });
4555
+ const ZodNanoID = /* @__PURE__ */ $constructor("ZodNanoID", (inst, def) => {
4556
+ $ZodNanoID.init(inst, def);
4557
+ ZodStringFormat.init(inst, def);
4558
+ });
4559
+ const ZodCUID = /* @__PURE__ */ $constructor("ZodCUID", (inst, def) => {
4560
+ $ZodCUID.init(inst, def);
4561
+ ZodStringFormat.init(inst, def);
4562
+ });
4563
+ const ZodCUID2 = /* @__PURE__ */ $constructor("ZodCUID2", (inst, def) => {
4564
+ $ZodCUID2.init(inst, def);
4565
+ ZodStringFormat.init(inst, def);
4566
+ });
4567
+ const ZodULID = /* @__PURE__ */ $constructor("ZodULID", (inst, def) => {
4568
+ $ZodULID.init(inst, def);
4569
+ ZodStringFormat.init(inst, def);
4570
+ });
4571
+ const ZodXID = /* @__PURE__ */ $constructor("ZodXID", (inst, def) => {
4572
+ $ZodXID.init(inst, def);
4573
+ ZodStringFormat.init(inst, def);
4574
+ });
4575
+ const ZodKSUID = /* @__PURE__ */ $constructor("ZodKSUID", (inst, def) => {
4576
+ $ZodKSUID.init(inst, def);
4577
+ ZodStringFormat.init(inst, def);
4578
+ });
4579
+ const ZodIPv4 = /* @__PURE__ */ $constructor("ZodIPv4", (inst, def) => {
4580
+ $ZodIPv4.init(inst, def);
4581
+ ZodStringFormat.init(inst, def);
4582
+ });
4583
+ const ZodIPv6 = /* @__PURE__ */ $constructor("ZodIPv6", (inst, def) => {
4584
+ $ZodIPv6.init(inst, def);
4585
+ ZodStringFormat.init(inst, def);
4586
+ });
4587
+ const ZodCIDRv4 = /* @__PURE__ */ $constructor("ZodCIDRv4", (inst, def) => {
4588
+ $ZodCIDRv4.init(inst, def);
4589
+ ZodStringFormat.init(inst, def);
4590
+ });
4591
+ const ZodCIDRv6 = /* @__PURE__ */ $constructor("ZodCIDRv6", (inst, def) => {
4592
+ $ZodCIDRv6.init(inst, def);
4593
+ ZodStringFormat.init(inst, def);
4594
+ });
4595
+ const ZodBase64 = /* @__PURE__ */ $constructor("ZodBase64", (inst, def) => {
4596
+ $ZodBase64.init(inst, def);
4597
+ ZodStringFormat.init(inst, def);
4598
+ });
4599
+ const ZodBase64URL = /* @__PURE__ */ $constructor("ZodBase64URL", (inst, def) => {
4600
+ $ZodBase64URL.init(inst, def);
4601
+ ZodStringFormat.init(inst, def);
4602
+ });
4603
+ const ZodE164 = /* @__PURE__ */ $constructor("ZodE164", (inst, def) => {
4604
+ $ZodE164.init(inst, def);
4605
+ ZodStringFormat.init(inst, def);
4606
+ });
4607
+ const ZodJWT = /* @__PURE__ */ $constructor("ZodJWT", (inst, def) => {
4608
+ $ZodJWT.init(inst, def);
4609
+ ZodStringFormat.init(inst, def);
4610
+ });
4611
+ const ZodNumber = /* @__PURE__ */ $constructor("ZodNumber", (inst, def) => {
4612
+ $ZodNumber.init(inst, def);
4613
+ ZodType.init(inst, def);
4614
+ inst._zod.processJSONSchema = (ctx, json, params) => numberProcessor(inst, ctx, json, params);
4615
+ inst.gt = (value, params) => inst.check(_gt(value, params));
4616
+ inst.gte = (value, params) => inst.check(_gte(value, params));
4617
+ inst.min = (value, params) => inst.check(_gte(value, params));
4618
+ inst.lt = (value, params) => inst.check(_lt(value, params));
4619
+ inst.lte = (value, params) => inst.check(_lte(value, params));
4620
+ inst.max = (value, params) => inst.check(_lte(value, params));
4621
+ inst.int = (params) => inst.check(int(params));
4622
+ inst.safe = (params) => inst.check(int(params));
4623
+ inst.positive = (params) => inst.check(_gt(0, params));
4624
+ inst.nonnegative = (params) => inst.check(_gte(0, params));
4625
+ inst.negative = (params) => inst.check(_lt(0, params));
4626
+ inst.nonpositive = (params) => inst.check(_lte(0, params));
4627
+ inst.multipleOf = (value, params) => inst.check(_multipleOf(value, params));
4628
+ inst.step = (value, params) => inst.check(_multipleOf(value, params));
4629
+ inst.finite = () => inst;
4630
+ const bag = inst._zod.bag;
4631
+ inst.minValue = Math.max(bag.minimum ?? Number.NEGATIVE_INFINITY, bag.exclusiveMinimum ?? Number.NEGATIVE_INFINITY) ?? null;
4632
+ inst.maxValue = Math.min(bag.maximum ?? Number.POSITIVE_INFINITY, bag.exclusiveMaximum ?? Number.POSITIVE_INFINITY) ?? null;
4633
+ inst.isInt = (bag.format ?? "").includes("int") || Number.isSafeInteger(bag.multipleOf ?? .5);
4634
+ inst.isFinite = true;
4635
+ inst.format = bag.format ?? null;
4636
+ });
4637
+ function number(params) {
4638
+ return _number(ZodNumber, params);
4639
+ }
4640
+ const ZodNumberFormat = /* @__PURE__ */ $constructor("ZodNumberFormat", (inst, def) => {
4641
+ $ZodNumberFormat.init(inst, def);
4642
+ ZodNumber.init(inst, def);
4643
+ });
4644
+ function int(params) {
4645
+ return _int(ZodNumberFormat, params);
4646
+ }
2353
4647
  const ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
2354
4648
  $ZodUnknown.init(inst, def);
2355
4649
  ZodType.init(inst, def);
@@ -2358,6 +4652,14 @@ const ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
2358
4652
  function unknown() {
2359
4653
  return _unknown(ZodUnknown);
2360
4654
  }
4655
+ const ZodNever = /* @__PURE__ */ $constructor("ZodNever", (inst, def) => {
4656
+ $ZodNever.init(inst, def);
4657
+ ZodType.init(inst, def);
4658
+ inst._zod.processJSONSchema = (ctx, json, params) => neverProcessor(inst, ctx, json, params);
4659
+ });
4660
+ function never(params) {
4661
+ return _never(ZodNever, params);
4662
+ }
2361
4663
  const ZodArray = /* @__PURE__ */ $constructor("ZodArray", (inst, def) => {
2362
4664
  $ZodArray.init(inst, def);
2363
4665
  ZodType.init(inst, def);
@@ -2372,6 +4674,53 @@ const ZodArray = /* @__PURE__ */ $constructor("ZodArray", (inst, def) => {
2372
4674
  function array(element, params) {
2373
4675
  return _array(ZodArray, element, params);
2374
4676
  }
4677
+ const ZodObject = /* @__PURE__ */ $constructor("ZodObject", (inst, def) => {
4678
+ $ZodObjectJIT.init(inst, def);
4679
+ ZodType.init(inst, def);
4680
+ inst._zod.processJSONSchema = (ctx, json, params) => objectProcessor(inst, ctx, json, params);
4681
+ defineLazy(inst, "shape", () => {
4682
+ return def.shape;
4683
+ });
4684
+ inst.keyof = () => _enum(Object.keys(inst._zod.def.shape));
4685
+ inst.catchall = (catchall) => inst.clone({
4686
+ ...inst._zod.def,
4687
+ catchall
4688
+ });
4689
+ inst.passthrough = () => inst.clone({
4690
+ ...inst._zod.def,
4691
+ catchall: unknown()
4692
+ });
4693
+ inst.loose = () => inst.clone({
4694
+ ...inst._zod.def,
4695
+ catchall: unknown()
4696
+ });
4697
+ inst.strict = () => inst.clone({
4698
+ ...inst._zod.def,
4699
+ catchall: never()
4700
+ });
4701
+ inst.strip = () => inst.clone({
4702
+ ...inst._zod.def,
4703
+ catchall: void 0
4704
+ });
4705
+ inst.extend = (incoming) => {
4706
+ return extend(inst, incoming);
4707
+ };
4708
+ inst.safeExtend = (incoming) => {
4709
+ return safeExtend(inst, incoming);
4710
+ };
4711
+ inst.merge = (other) => merge(inst, other);
4712
+ inst.pick = (mask) => pick(inst, mask);
4713
+ inst.omit = (mask) => omit(inst, mask);
4714
+ inst.partial = (...args) => partial(ZodOptional, inst, args[0]);
4715
+ inst.required = (...args) => required(ZodNonOptional, inst, args[0]);
4716
+ });
4717
+ function object(shape, params) {
4718
+ return new ZodObject({
4719
+ type: "object",
4720
+ shape: shape ?? {},
4721
+ ...normalizeParams(params)
4722
+ });
4723
+ }
2375
4724
  const ZodUnion = /* @__PURE__ */ $constructor("ZodUnion", (inst, def) => {
2376
4725
  $ZodUnion.init(inst, def);
2377
4726
  ZodType.init(inst, def);
@@ -2390,11 +4739,63 @@ const ZodIntersection = /* @__PURE__ */ $constructor("ZodIntersection", (inst, d
2390
4739
  ZodType.init(inst, def);
2391
4740
  inst._zod.processJSONSchema = (ctx, json, params) => intersectionProcessor(inst, ctx, json, params);
2392
4741
  });
2393
- function intersection(left, right) {
2394
- return new ZodIntersection({
2395
- type: "intersection",
2396
- left,
2397
- right
4742
+ function intersection(left, right) {
4743
+ return new ZodIntersection({
4744
+ type: "intersection",
4745
+ left,
4746
+ right
4747
+ });
4748
+ }
4749
+ const ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
4750
+ $ZodRecord.init(inst, def);
4751
+ ZodType.init(inst, def);
4752
+ inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
4753
+ inst.keyType = def.keyType;
4754
+ inst.valueType = def.valueType;
4755
+ });
4756
+ function record(keyType, valueType, params) {
4757
+ return new ZodRecord({
4758
+ type: "record",
4759
+ keyType,
4760
+ valueType,
4761
+ ...normalizeParams(params)
4762
+ });
4763
+ }
4764
+ const ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
4765
+ $ZodEnum.init(inst, def);
4766
+ ZodType.init(inst, def);
4767
+ inst._zod.processJSONSchema = (ctx, json, params) => enumProcessor(inst, ctx, json, params);
4768
+ inst.enum = def.entries;
4769
+ inst.options = Object.values(def.entries);
4770
+ const keys = new Set(Object.keys(def.entries));
4771
+ inst.extract = (values, params) => {
4772
+ const newEntries = {};
4773
+ for (const value of values) if (keys.has(value)) newEntries[value] = def.entries[value];
4774
+ else throw new Error(`Key ${value} not found in enum`);
4775
+ return new ZodEnum({
4776
+ ...def,
4777
+ checks: [],
4778
+ ...normalizeParams(params),
4779
+ entries: newEntries
4780
+ });
4781
+ };
4782
+ inst.exclude = (values, params) => {
4783
+ const newEntries = { ...def.entries };
4784
+ for (const value of values) if (keys.has(value)) delete newEntries[value];
4785
+ else throw new Error(`Key ${value} not found in enum`);
4786
+ return new ZodEnum({
4787
+ ...def,
4788
+ checks: [],
4789
+ ...normalizeParams(params),
4790
+ entries: newEntries
4791
+ });
4792
+ };
4793
+ });
4794
+ function _enum(values, params) {
4795
+ return new ZodEnum({
4796
+ type: "enum",
4797
+ entries: Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values,
4798
+ ...normalizeParams(params)
2398
4799
  });
2399
4800
  }
2400
4801
  const ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
@@ -2571,31 +4972,26 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2571
4972
  _AgentStructuredOutputRunner = this;
2572
4973
  }
2573
4974
  static repairAttemptCount = 2;
2574
- constructor(repairPromptFactory, openAiStructuredOutputMethodFactory) {
4975
+ static structuredOutputSchemaName = "agent_output";
4976
+ constructor(repairPromptFactory, openAiStrictJsonSchemaFactory) {
2575
4977
  this.repairPromptFactory = repairPromptFactory;
2576
- this.openAiStructuredOutputMethodFactory = openAiStructuredOutputMethodFactory;
4978
+ this.openAiStrictJsonSchemaFactory = openAiStrictJsonSchemaFactory;
2577
4979
  }
2578
4980
  async resolve(args) {
2579
4981
  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);
4982
+ if (args.rawFinalText !== void 0) {
4983
+ const directResult = this.tryParseAndValidate(args.rawFinalText, args.schema);
2587
4984
  if (directResult.ok) return directResult.value;
2588
4985
  lastFailure = directResult;
2589
4986
  }
2590
4987
  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
- }
4988
+ const structuredOptions = this.resolveStructuredOutputOptions(args.chatModelConfig);
4989
+ const schemaForModel = this.resolveOutputSchemaForModel(args.schema, structuredOptions);
4990
+ const nativeResult = this.tryValidateStructuredValue(await args.invokeStructuredModel(schemaForModel, args.conversation, structuredOptions), args.schema);
4991
+ if (nativeResult.ok) return nativeResult.value;
4992
+ lastFailure = nativeResult;
2597
4993
  } catch (error) {
2598
- lastFailure = {
4994
+ lastFailure = lastFailure ?? {
2599
4995
  ok: false,
2600
4996
  invalidContent: "",
2601
4997
  validationError: `Native structured output failed: ${this.summarizeError(error)}`
@@ -2619,22 +5015,26 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2619
5015
  validationError: failure.validationError
2620
5016
  }))];
2621
5017
  const repairResponse = await args.invokeTextModel(repairMessages);
2622
- const repairResult = this.tryParseAndValidate(AgentMessageFactory.extractContent(repairResponse), args.schema);
5018
+ const repairResult = this.tryParseAndValidate(repairResponse.text, args.schema);
2623
5019
  if (repairResult.ok) return repairResult.value;
2624
5020
  failure = repairResult;
2625
5021
  }
2626
5022
  throw new Error(`Structured output required for AIAgent "${args.agentName}" (${args.nodeId}) but validation still failed after ${_AgentStructuredOutputRunner.repairAttemptCount} repair attempts: ${failure.validationError}`);
2627
5023
  }
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 };
5024
+ /**
5025
+ * Chooses strict mode for OpenAI chat-model configs, off otherwise. Extendable in future for
5026
+ * other providers that adopt the same "supply a JSON Schema record directly" contract.
5027
+ */
5028
+ resolveStructuredOutputOptions(chatModelConfig) {
5029
+ if (chatModelConfig.type !== OpenAIChatModelFactory) return;
5030
+ return {
5031
+ strict: true,
5032
+ schemaName: _AgentStructuredOutputRunner.structuredOutputSchemaName
5033
+ };
2635
5034
  }
2636
- supportsNativeStructuredOutput(model) {
2637
- return typeof model.withStructuredOutput === "function";
5035
+ resolveOutputSchemaForModel(schema, options) {
5036
+ if (!options?.strict) return schema;
5037
+ return this.openAiStrictJsonSchemaFactory.createStructuredOutputRecord(schema, { schemaName: options.schemaName ?? _AgentStructuredOutputRunner.structuredOutputSchemaName });
2638
5038
  }
2639
5039
  tryParseAndValidate(content, schema) {
2640
5040
  try {
@@ -2668,7 +5068,7 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2668
5068
  }
2669
5069
  toJson(value) {
2670
5070
  try {
2671
- return JSON.stringify(value);
5071
+ return JSON.stringify(value) ?? String(value);
2672
5072
  } catch (error) {
2673
5073
  return `<<unserializable: ${this.summarizeError(error)}>>`;
2674
5074
  }
@@ -2677,8 +5077,8 @@ let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2677
5077
  AgentStructuredOutputRunner = _AgentStructuredOutputRunner = __decorate([
2678
5078
  injectable(),
2679
5079
  __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])
5080
+ __decorateParam(1, inject(OpenAiStrictJsonSchemaFactory)),
5081
+ __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
5082
  ], AgentStructuredOutputRunner);
2683
5083
 
2684
5084
  //#endregion
@@ -2815,7 +5215,7 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2815
5215
  async executePlannedToolCall(args) {
2816
5216
  const { plannedToolCall, ctx } = args;
2817
5217
  const toolCallInputsByPort = AgentToolCallPortMap.fromInput(plannedToolCall.toolCall.input ?? {});
2818
- const invocationId = ConnectionInvocationIdFactory.create();
5218
+ const invocationId = plannedToolCall.invocationId;
2819
5219
  const startedAt = /* @__PURE__ */ new Date();
2820
5220
  const span = ctx.telemetry.startChildSpan({
2821
5221
  name: "agent.tool.call",
@@ -2823,7 +5223,10 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2823
5223
  startedAt,
2824
5224
  attributes: {
2825
5225
  [CodemationTelemetryAttributeNames.connectionInvocationId]: invocationId,
2826
- [CodemationTelemetryAttributeNames.toolName]: plannedToolCall.binding.config.name
5226
+ [CodemationTelemetryAttributeNames.toolName]: plannedToolCall.binding.config.name,
5227
+ ...ctx.iterationId ? { [CodemationTelemetryAttributeNames.iterationId]: ctx.iterationId } : {},
5228
+ ...typeof ctx.itemIndex === "number" ? { [CodemationTelemetryAttributeNames.iterationIndex]: ctx.itemIndex } : {},
5229
+ ...ctx.parentInvocationId ? { [CodemationTelemetryAttributeNames.parentInvocationId]: ctx.parentInvocationId } : {}
2827
5230
  }
2828
5231
  });
2829
5232
  await ctx.nodeState?.markRunning({
@@ -2831,9 +5234,24 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2831
5234
  activationId: ctx.activationId,
2832
5235
  inputsByPort: toolCallInputsByPort
2833
5236
  });
5237
+ await ctx.nodeState?.appendConnectionInvocation({
5238
+ invocationId,
5239
+ connectionNodeId: plannedToolCall.nodeId,
5240
+ parentAgentNodeId: ctx.nodeId,
5241
+ parentAgentActivationId: ctx.activationId,
5242
+ status: "running",
5243
+ managedInput: this.toJsonValue(plannedToolCall.toolCall.input),
5244
+ queuedAt: startedAt.toISOString(),
5245
+ startedAt: startedAt.toISOString(),
5246
+ iterationId: ctx.iterationId,
5247
+ parentInvocationId: ctx.parentInvocationId
5248
+ });
2834
5249
  try {
2835
- const serialized = await plannedToolCall.binding.langChainTool.invoke(plannedToolCall.toolCall.input ?? {});
2836
- const result = this.parseToolOutput(serialized);
5250
+ const result = await plannedToolCall.binding.execute(plannedToolCall.toolCall.input ?? {}, {
5251
+ parentSpan: span,
5252
+ parentInvocationId: invocationId
5253
+ });
5254
+ const serialized = typeof result === "string" ? result : JSON.stringify(result);
2837
5255
  const finishedAt = /* @__PURE__ */ new Date();
2838
5256
  await ctx.nodeState?.markCompleted({
2839
5257
  nodeId: plannedToolCall.nodeId,
@@ -2865,7 +5283,9 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2865
5283
  managedOutput: this.toJsonValue(result),
2866
5284
  queuedAt: startedAt.toISOString(),
2867
5285
  startedAt: startedAt.toISOString(),
2868
- finishedAt: finishedAt.toISOString()
5286
+ finishedAt: finishedAt.toISOString(),
5287
+ iterationId: ctx.iterationId,
5288
+ parentInvocationId: ctx.parentInvocationId
2869
5289
  });
2870
5290
  return {
2871
5291
  toolName: plannedToolCall.binding.config.name,
@@ -2877,7 +5297,7 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2877
5297
  const classification = this.errorClassifier.classify({
2878
5298
  error,
2879
5299
  toolName: plannedToolCall.binding.config.name,
2880
- schema: plannedToolCall.binding.langChainTool.schema
5300
+ schema: plannedToolCall.binding.inputSchema
2881
5301
  });
2882
5302
  if (classification.kind !== "repairable_validation_error") {
2883
5303
  const effectiveError = classification.effectiveError;
@@ -3006,7 +5426,9 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
3006
5426
  },
3007
5427
  queuedAt: args.startedAt.toISOString(),
3008
5428
  startedAt: args.startedAt.toISOString(),
3009
- finishedAt: finishedAt.toISOString()
5429
+ finishedAt: finishedAt.toISOString(),
5430
+ iterationId: args.ctx.iterationId,
5431
+ parentInvocationId: args.ctx.parentInvocationId
3010
5432
  });
3011
5433
  }
3012
5434
  createRepairPayload(args) {
@@ -3040,14 +5462,6 @@ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
3040
5462
  if (!firstIssue) return `Your previous tool call for "${toolName}" was invalid and did not match the expected schema.`;
3041
5463
  return `Your previous tool call for "${toolName}" was invalid because field "${firstIssue.path.length > 0 ? firstIssue.path.join(".") : "<root>"}" failed validation: ${firstIssue.message}`;
3042
5464
  }
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
5465
  toJsonValue(value) {
3052
5466
  if (value === void 0) return;
3053
5467
  return JSON.parse(JSON.stringify(value));
@@ -3075,13 +5489,14 @@ AgentToolExecutionCoordinator = __decorate([
3075
5489
 
3076
5490
  //#endregion
3077
5491
  //#region src/nodes/NodeBackedToolRuntime.ts
3078
- var _ref$1, _ref2$1, _ref3$1;
5492
+ var _ref$1, _ref2$1, _ref3$1, _ref4$1;
3079
5493
  let NodeBackedToolRuntime = class NodeBackedToolRuntime$1 {
3080
- constructor(nodeResolver, itemExprResolver, outputNormalizer, outputBehaviorResolver) {
5494
+ constructor(nodeResolver, itemExprResolver, outputNormalizer, outputBehaviorResolver, childExecutionScopeFactory) {
3081
5495
  this.nodeResolver = nodeResolver;
3082
5496
  this.itemExprResolver = itemExprResolver;
3083
5497
  this.outputNormalizer = outputNormalizer;
3084
5498
  this.outputBehaviorResolver = outputBehaviorResolver;
5499
+ this.childExecutionScopeFactory = childExecutionScopeFactory;
3085
5500
  }
3086
5501
  async execute(config$1, args) {
3087
5502
  const nodeInput = config$1.toNodeItem({
@@ -3092,10 +5507,7 @@ let NodeBackedToolRuntime = class NodeBackedToolRuntime$1 {
3092
5507
  ctx: args.ctx,
3093
5508
  node: config$1.node
3094
5509
  });
3095
- const nodeCtx = {
3096
- ...args.ctx,
3097
- config: config$1.node
3098
- };
5510
+ const nodeCtx = this.resolveNodeCtx(config$1, args);
3099
5511
  const resolvedNode = this.nodeResolver.resolve(config$1.node.type);
3100
5512
  const outputs = await this.executeResolvedNode(resolvedNode, nodeInput, nodeCtx);
3101
5513
  return config$1.toToolOutput({
@@ -3108,6 +5520,35 @@ let NodeBackedToolRuntime = class NodeBackedToolRuntime$1 {
3108
5520
  outputs
3109
5521
  });
3110
5522
  }
5523
+ /**
5524
+ * Returns a re-rooted child ctx for nested-agent tools (so their LLM/tool connection ids derive
5525
+ * from the tool connection node, telemetry parents under the tool-call span, and connection
5526
+ * invocations carry `parentInvocationId`). Plain runnable tools (non-agent) keep the orchestrator
5527
+ * ctx with only `config` swapped — no nesting concern.
5528
+ *
5529
+ * The caller (`AIAgentNode.createItemScopedTools`) already wraps the orchestrator ctx via
5530
+ * `ConnectionCredentialExecutionContextFactory.forConnectionNode`, so `args.ctx.nodeId` is the
5531
+ * tool's own connection node id (e.g. `AIAgentNode:2__conn__tool__searchInMail`). We pass that
5532
+ * through as the sub-agent's `nodeId`; deriving another `toolConnectionNodeId(args.ctx.nodeId,
5533
+ * config.name)` here would prepend a duplicate `__conn__tool__<name>` segment and exponentially
5534
+ * deepen ids on each invocation, which also breaks credential resolution because user-provided
5535
+ * bindings sit on the single-level connection node id.
5536
+ */
5537
+ resolveNodeCtx(config$1, args) {
5538
+ const isNestedAgent = AgentConfigInspector.isAgentNodeConfig(config$1.node);
5539
+ const hooks = args.hooks;
5540
+ if (!isNestedAgent || !hooks?.parentSpan || !hooks.parentInvocationId) return {
5541
+ ...args.ctx,
5542
+ config: config$1.node
5543
+ };
5544
+ return this.childExecutionScopeFactory.forSubAgent({
5545
+ parentCtx: args.ctx,
5546
+ childNodeId: args.ctx.nodeId,
5547
+ childConfig: config$1.node,
5548
+ parentInvocationId: hooks.parentInvocationId,
5549
+ parentSpan: hooks.parentSpan
5550
+ });
5551
+ }
3111
5552
  async executeResolvedNode(resolvedNode, nodeInput, ctx) {
3112
5553
  if (this.isMultiInputNode(resolvedNode)) return await resolvedNode.executeMulti({ in: [nodeInput] }, ctx);
3113
5554
  if (this.isRunnableNode(resolvedNode)) {
@@ -3145,11 +5586,13 @@ NodeBackedToolRuntime = __decorate([
3145
5586
  __decorateParam(1, inject(ItemExprResolver)),
3146
5587
  __decorateParam(2, inject(NodeOutputNormalizer)),
3147
5588
  __decorateParam(3, inject(RunnableOutputBehaviorResolver)),
5589
+ __decorateParam(4, inject(ChildExecutionScopeFactory)),
3148
5590
  __decorateMetadata("design:paramtypes", [
3149
5591
  Object,
3150
5592
  typeof (_ref$1 = typeof ItemExprResolver !== "undefined" && ItemExprResolver) === "function" ? _ref$1 : Object,
3151
5593
  typeof (_ref2$1 = typeof NodeOutputNormalizer !== "undefined" && NodeOutputNormalizer) === "function" ? _ref2$1 : Object,
3152
- typeof (_ref3$1 = typeof RunnableOutputBehaviorResolver !== "undefined" && RunnableOutputBehaviorResolver) === "function" ? _ref3$1 : Object
5594
+ typeof (_ref3$1 = typeof RunnableOutputBehaviorResolver !== "undefined" && RunnableOutputBehaviorResolver) === "function" ? _ref3$1 : Object,
5595
+ typeof (_ref4$1 = typeof ChildExecutionScopeFactory !== "undefined" && ChildExecutionScopeFactory) === "function" ? _ref4$1 : Object
3153
5596
  ])
3154
5597
  ], NodeBackedToolRuntime);
3155
5598
 
@@ -3167,14 +5610,8 @@ var _ref, _ref2, _ref3, _ref4;
3167
5610
  let AIAgentNode = class AIAgentNode$1 {
3168
5611
  kind = "node";
3169
5612
  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
5613
  inputSchema = unknown();
3176
5614
  connectionCredentialExecutionContextFactory;
3177
- /** One resolved model/tools bundle per activation context (same ctx across items in a batch). */
3178
5615
  preparedByExecutionContext = /* @__PURE__ */ new WeakMap();
3179
5616
  constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner, toolExecutionCoordinator) {
3180
5617
  this.nodeResolver = nodeResolver;
@@ -3205,9 +5642,6 @@ let AIAgentNode = class AIAgentNode$1 {
3205
5642
  throw error;
3206
5643
  }
3207
5644
  }
3208
- /**
3209
- * Resolves the chat model and tools once per activation, then reuses for every item in the batch.
3210
- */
3211
5645
  async prepareExecution(ctx) {
3212
5646
  const chatModelFactory = this.nodeResolver.resolve(ctx.config.chatModel.type);
3213
5647
  const languageModelCredentialContext = this.connectionCredentialExecutionContextFactory.forConnectionNode(ctx, {
@@ -3225,9 +5659,6 @@ let AIAgentNode = class AIAgentNode$1 {
3225
5659
  languageModelConnectionNodeId: ConnectionNodeIdFactory.languageModelConnectionNodeId(ctx.nodeId)
3226
5660
  };
3227
5661
  }
3228
- /**
3229
- * One item: build prompts, optionally bind tools, run the multi-turn loop, map the final model message to workflow JSON.
3230
- */
3231
5662
  async runAgentForItem(prepared, item, itemIndex, items) {
3232
5663
  const { ctx } = prepared;
3233
5664
  const itemInputsByPort = AgentItemPortMap.fromItem(item);
@@ -3241,8 +5672,8 @@ let AIAgentNode = class AIAgentNode$1 {
3241
5672
  conversation,
3242
5673
  agentName: this.getAgentDisplayName(ctx),
3243
5674
  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)
5675
+ invokeTextModel: async (messages) => await this.invokeTextTurn(prepared, itemInputsByPort, messages, []),
5676
+ invokeStructuredModel: async (schema, messages, structuredOptions) => await this.invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions)
3246
5677
  });
3247
5678
  await ctx.telemetry.recordMetric({
3248
5679
  name: CodemationTelemetryMetricNames.agentTurns,
@@ -3254,13 +5685,11 @@ let AIAgentNode = class AIAgentNode$1 {
3254
5685
  });
3255
5686
  return this.buildOutputItem(item, structuredOutput);
3256
5687
  }
3257
- const modelWithTools = this.bindToolsToModel(prepared.model, itemScopedTools);
3258
5688
  const loopResult = await this.runTurnLoopUntilFinalAnswer({
3259
5689
  prepared,
3260
5690
  itemInputsByPort,
3261
5691
  itemScopedTools,
3262
- conversation,
3263
- modelWithTools
5692
+ conversation
3264
5693
  });
3265
5694
  await ctx.telemetry.recordMetric({
3266
5695
  name: CodemationTelemetryMetricNames.agentTurns,
@@ -3270,30 +5699,34 @@ let AIAgentNode = class AIAgentNode$1 {
3270
5699
  name: CodemationTelemetryMetricNames.agentToolCalls,
3271
5700
  value: loopResult.toolCallCount
3272
5701
  });
3273
- const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalResponse, itemScopedTools.length > 0);
5702
+ const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalText, itemScopedTools.length > 0);
3274
5703
  return this.buildOutputItem(item, outputJson);
3275
5704
  }
3276
5705
  /**
3277
- * Repeatedly invokes the model until it returns without tool calls, or guardrails end the loop.
5706
+ * Multi-turn loop:
5707
+ * - Each turn is a single `generateText` call with tools exposed but **not auto-executed**
5708
+ * (we control tool dispatch so that {@link AgentToolExecutionCoordinator} drives repair /
5709
+ * connection-invocation recording / transient-error handling exactly like before).
5710
+ * - When the model returns no tool calls the loop ends with the model's text as the final answer.
5711
+ * - Respects `guardrails.maxTurns` and `guardrails.onTurnLimitReached`.
3278
5712
  */
3279
5713
  async runTurnLoopUntilFinalAnswer(args) {
3280
- const { prepared, itemInputsByPort, itemScopedTools, conversation, modelWithTools } = args;
3281
- const { ctx, guardrails, languageModelConnectionNodeId } = prepared;
3282
- let finalResponse;
5714
+ const { prepared, itemInputsByPort, itemScopedTools, conversation } = args;
5715
+ const { ctx, guardrails } = prepared;
5716
+ let finalText = "";
3283
5717
  let toolCallCount = 0;
3284
5718
  let turnCount = 0;
3285
5719
  const repairAttemptsByToolName = /* @__PURE__ */ new Map();
3286
5720
  for (let turn = 1; turn <= guardrails.maxTurns; turn++) {
3287
5721
  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;
5722
+ const result = await this.invokeTextTurn(prepared, itemInputsByPort, conversation, itemScopedTools);
5723
+ finalText = result.text;
5724
+ if (result.toolCalls.length === 0) break;
3292
5725
  if (this.cannotExecuteAnotherToolRound(turn, guardrails)) {
3293
5726
  this.finishOrThrowWhenTurnCapHitWithToolCalls(ctx, guardrails);
3294
5727
  break;
3295
5728
  }
3296
- const plannedToolCalls = this.planToolCalls(itemScopedTools, toolCalls, ctx.nodeId);
5729
+ const plannedToolCalls = this.planToolCalls(itemScopedTools, result.toolCalls, ctx.nodeId);
3297
5730
  toolCallCount += plannedToolCalls.length;
3298
5731
  await this.markQueuedTools(plannedToolCalls, ctx);
3299
5732
  const executedToolCalls = await this.toolExecutionCoordinator.execute({
@@ -3302,11 +5735,10 @@ let AIAgentNode = class AIAgentNode$1 {
3302
5735
  agentName: this.getAgentDisplayName(ctx),
3303
5736
  repairAttemptsByToolName
3304
5737
  });
3305
- this.appendAssistantAndToolMessages(conversation, response, executedToolCalls);
5738
+ this.appendAssistantAndToolMessages(conversation, result.assistantMessage, result.text, result.toolCalls, executedToolCalls);
3306
5739
  }
3307
- if (!finalResponse) throw new Error(`AIAgent "${ctx.config.name ?? ctx.nodeId}" did not produce a model response.`);
3308
5740
  return {
3309
- finalResponse,
5741
+ finalText,
3310
5742
  turnCount,
3311
5743
  toolCallCount
3312
5744
  };
@@ -3318,30 +5750,30 @@ let AIAgentNode = class AIAgentNode$1 {
3318
5750
  if (guardrails.onTurnLimitReached === "respondWithLastMessage") return;
3319
5751
  throw new Error(`AIAgent "${ctx.config.name ?? ctx.nodeId}" reached maxTurns=${guardrails.maxTurns} before producing a final response.`);
3320
5752
  }
3321
- appendAssistantAndToolMessages(conversation, assistantMessage, executedToolCalls) {
3322
- conversation.push(assistantMessage, ...executedToolCalls.map((toolCall) => AgentMessageFactory.createToolMessage(toolCall.toolCallId, toolCall.serialized)));
5753
+ appendAssistantAndToolMessages(conversation, assistantMessage, text, toolCalls, executedToolCalls) {
5754
+ conversation.push(assistantMessage ?? AgentMessageFactory.createAssistantWithToolCalls(text, toolCalls), AgentMessageFactory.createToolResultsMessage(executedToolCalls));
3323
5755
  }
3324
- async resolveFinalOutputJson(prepared, itemInputsByPort, conversation, finalResponse, wasToolEnabledRun) {
3325
- if (!prepared.ctx.config.outputSchema) return AgentOutputFactory.fromAgentContent(AgentMessageFactory.extractContent(finalResponse));
5756
+ async resolveFinalOutputJson(prepared, itemInputsByPort, conversation, finalText, wasToolEnabledRun) {
5757
+ if (!prepared.ctx.config.outputSchema) return AgentOutputFactory.fromAgentContent(finalText);
5758
+ const conversationWithFinal = wasToolEnabledRun ? [...conversation, {
5759
+ role: "assistant",
5760
+ content: finalText
5761
+ }] : conversation;
3326
5762
  return await this.structuredOutputRunner.resolve({
3327
5763
  model: prepared.model,
3328
5764
  chatModelConfig: prepared.ctx.config.chatModel,
3329
5765
  schema: prepared.ctx.config.outputSchema,
3330
- conversation: wasToolEnabledRun ? [...conversation, finalResponse] : conversation,
3331
- rawFinalResponse: finalResponse,
5766
+ conversation: conversationWithFinal,
5767
+ rawFinalText: finalText,
3332
5768
  agentName: this.getAgentDisplayName(prepared.ctx),
3333
5769
  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)
5770
+ invokeTextModel: async (messages) => await this.invokeTextTurn(prepared, itemInputsByPort, messages, []),
5771
+ invokeStructuredModel: async (schema, messages, structuredOptions) => await this.invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions)
3336
5772
  });
3337
5773
  }
3338
5774
  buildOutputItem(item, outputJson) {
3339
5775
  return AgentOutputFactory.replaceJson(item, outputJson);
3340
5776
  }
3341
- bindToolsToModel(model, itemScopedTools) {
3342
- if (itemScopedTools.length === 0 || !model.bindTools) return model;
3343
- return model.bindTools(itemScopedTools.map((entry) => entry.langChainTool));
3344
- }
3345
5777
  resolveTools(toolConfigs) {
3346
5778
  const resolvedTools = toolConfigs.map((config$1) => ({
3347
5779
  config: config$1,
@@ -3360,38 +5792,120 @@ let AIAgentNode = class AIAgentNode$1 {
3360
5792
  connectionNodeId: ConnectionNodeIdFactory.toolConnectionNodeId(ctx.nodeId, entry.config.name),
3361
5793
  getCredentialRequirements: () => entry.config.getCredentialRequirements?.() ?? []
3362
5794
  });
3363
- const langChainTool = this.executionHelpers.createDynamicStructuredTool(entry, toolCredentialContext, item, itemIndex, items);
3364
5795
  return {
3365
5796
  config: entry.config,
3366
- langChainTool
5797
+ inputSchema: entry.runtime.inputSchema,
5798
+ execute: async (input, hooks) => {
5799
+ const validated = entry.runtime.inputSchema.parse(input);
5800
+ return await entry.runtime.execute({
5801
+ config: entry.config,
5802
+ input: validated,
5803
+ ctx: toolCredentialContext,
5804
+ item,
5805
+ itemIndex,
5806
+ items,
5807
+ hooks
5808
+ });
5809
+ }
3367
5810
  };
3368
5811
  });
3369
5812
  }
3370
- async invokeModel(model, nodeId, messages, ctx, inputsByPort, options) {
5813
+ /**
5814
+ * Builds an AI SDK {@link ToolSet} where every tool ships a pre-converted JSON Schema (via
5815
+ * {@link jsonSchema}) — not the raw Zod schema — and carries **no** `execute`. Two reasons:
5816
+ *
5817
+ * 1. Codemation owns tool dispatch + the per-tool repair loop (see {@link AgentToolExecutionCoordinator}),
5818
+ * so the AI SDK must surface tool calls back to us instead of auto-running them.
5819
+ * 2. The AI SDK's `asSchema` helper discriminates between Zod v3 / Zod v4 / Standard Schema via
5820
+ * runtime feature-detection (`~standard`, `_zod`, etc.). Handing it a pre-built
5821
+ * {@link jsonSchema} record — which is tagged with `Symbol.for('vercel.ai.schema')` — skips all
5822
+ * of that detection and guarantees the provider receives a draft-07 JSON Schema with
5823
+ * `additionalProperties: false` at every object depth (see {@link OpenAiStrictJsonSchemaFactory}
5824
+ * for the same logic applied to structured-output schemas). Codemation still runs its own Zod
5825
+ * validation on tool inputs before execute — the schema handed to the model is advisory.
5826
+ */
5827
+ buildToolSet(itemScopedTools) {
5828
+ if (itemScopedTools.length === 0) return void 0;
5829
+ const toolSet = {};
5830
+ for (const entry of itemScopedTools) {
5831
+ const schemaRecord = this.executionHelpers.createJsonSchemaRecord(entry.inputSchema, {
5832
+ schemaName: entry.config.name,
5833
+ requireObjectRoot: true
5834
+ });
5835
+ toolSet[entry.config.name] = {
5836
+ description: entry.config.description,
5837
+ inputSchema: jsonSchema(schemaRecord)
5838
+ };
5839
+ }
5840
+ return toolSet;
5841
+ }
5842
+ /**
5843
+ * One `generateText` turn (no auto tool execution) with Codemation-owned child-span telemetry
5844
+ * and connection-invocation state recording.
5845
+ */
5846
+ async invokeTextTurn(prepared, itemInputsByPort, messages, itemScopedTools) {
3371
5847
  const invocationId = ConnectionInvocationIdFactory.create();
3372
5848
  const startedAt = /* @__PURE__ */ new Date();
3373
5849
  const summarizedInput = this.summarizeLlmMessages(messages);
5850
+ const { ctx, model, languageModelConnectionNodeId, guardrails } = prepared;
3374
5851
  const span = this.createModelInvocationSpan(ctx, invocationId, startedAt);
3375
5852
  await ctx.nodeState?.markQueued({
3376
- nodeId,
5853
+ nodeId: languageModelConnectionNodeId,
3377
5854
  activationId: ctx.activationId,
3378
- inputsByPort
5855
+ inputsByPort: itemInputsByPort
5856
+ });
5857
+ await ctx.nodeState?.appendConnectionInvocation({
5858
+ invocationId,
5859
+ connectionNodeId: languageModelConnectionNodeId,
5860
+ parentAgentNodeId: ctx.nodeId,
5861
+ parentAgentActivationId: ctx.activationId,
5862
+ status: "queued",
5863
+ managedInput: summarizedInput,
5864
+ queuedAt: startedAt.toISOString(),
5865
+ iterationId: ctx.iterationId,
5866
+ itemIndex: ctx.itemIndex,
5867
+ parentInvocationId: ctx.parentInvocationId
3379
5868
  });
3380
5869
  await ctx.nodeState?.markRunning({
3381
- nodeId,
5870
+ nodeId: languageModelConnectionNodeId,
3382
5871
  activationId: ctx.activationId,
3383
- inputsByPort
5872
+ inputsByPort: itemInputsByPort
5873
+ });
5874
+ await ctx.nodeState?.appendConnectionInvocation({
5875
+ invocationId,
5876
+ connectionNodeId: languageModelConnectionNodeId,
5877
+ parentAgentNodeId: ctx.nodeId,
5878
+ parentAgentActivationId: ctx.activationId,
5879
+ status: "running",
5880
+ managedInput: summarizedInput,
5881
+ queuedAt: startedAt.toISOString(),
5882
+ startedAt: startedAt.toISOString(),
5883
+ iterationId: ctx.iterationId,
5884
+ itemIndex: ctx.itemIndex,
5885
+ parentInvocationId: ctx.parentInvocationId
3384
5886
  });
3385
5887
  try {
3386
- const response = await model.invoke(messages, options);
5888
+ const tools = this.buildToolSet(itemScopedTools);
5889
+ const callOptions = this.resolveCallOptions(model, guardrails.modelInvocationOptions);
5890
+ const result = await generateText({
5891
+ model: model.languageModel,
5892
+ messages: [...messages],
5893
+ tools,
5894
+ toolChoice: tools ? "auto" : void 0,
5895
+ maxOutputTokens: callOptions.maxOutputTokens,
5896
+ temperature: callOptions.temperature,
5897
+ providerOptions: callOptions.providerOptions,
5898
+ maxRetries: 0
5899
+ });
5900
+ const turnResult = this.extractTurnResult(result);
3387
5901
  const finishedAt = /* @__PURE__ */ new Date();
5902
+ const managedOutput = this.summarizeTurnOutput(turnResult);
3388
5903
  await ctx.nodeState?.markCompleted({
3389
- nodeId,
5904
+ nodeId: languageModelConnectionNodeId,
3390
5905
  activationId: ctx.activationId,
3391
- inputsByPort,
3392
- outputs: AgentOutputFactory.fromUnknown({ content: AgentMessageFactory.extractContent(response) })
5906
+ inputsByPort: itemInputsByPort,
5907
+ outputs: AgentOutputFactory.fromUnknown(managedOutput)
3393
5908
  });
3394
- const content = AgentMessageFactory.extractContent(response);
3395
5909
  await span.attachArtifact({
3396
5910
  kind: "ai.messages",
3397
5911
  contentType: "application/json",
@@ -3400,26 +5914,29 @@ let AIAgentNode = class AIAgentNode$1 {
3400
5914
  await span.attachArtifact({
3401
5915
  kind: "ai.response",
3402
5916
  contentType: "application/json",
3403
- previewJson: content
5917
+ previewJson: turnResult.text
3404
5918
  });
3405
- await this.recordModelUsageMetrics(span, response, ctx);
5919
+ await this.recordModelUsageMetrics(span, turnResult.usage, ctx);
3406
5920
  await span.end({
3407
5921
  status: "ok",
3408
5922
  endedAt: finishedAt
3409
5923
  });
3410
5924
  await ctx.nodeState?.appendConnectionInvocation({
3411
5925
  invocationId,
3412
- connectionNodeId: nodeId,
5926
+ connectionNodeId: languageModelConnectionNodeId,
3413
5927
  parentAgentNodeId: ctx.nodeId,
3414
5928
  parentAgentActivationId: ctx.activationId,
3415
5929
  status: "completed",
3416
5930
  managedInput: summarizedInput,
3417
- managedOutput: content,
5931
+ managedOutput,
3418
5932
  queuedAt: startedAt.toISOString(),
3419
5933
  startedAt: startedAt.toISOString(),
3420
- finishedAt: finishedAt.toISOString()
5934
+ finishedAt: finishedAt.toISOString(),
5935
+ iterationId: ctx.iterationId,
5936
+ itemIndex: ctx.itemIndex,
5937
+ parentInvocationId: ctx.parentInvocationId
3421
5938
  });
3422
- return response;
5939
+ return turnResult;
3423
5940
  } catch (error) {
3424
5941
  await span.end({
3425
5942
  status: "error",
@@ -3430,36 +5947,78 @@ let AIAgentNode = class AIAgentNode$1 {
3430
5947
  error,
3431
5948
  invocationId,
3432
5949
  startedAt,
3433
- nodeId,
5950
+ nodeId: languageModelConnectionNodeId,
3434
5951
  ctx,
3435
- inputsByPort,
3436
- managedInput: this.summarizeLlmMessages(messages)
5952
+ inputsByPort: itemInputsByPort,
5953
+ managedInput: summarizedInput
3437
5954
  });
3438
5955
  }
3439
5956
  }
3440
- async invokeStructuredModel(model, nodeId, messages, ctx, inputsByPort, options) {
5957
+ /**
5958
+ * Structured-output turn: runs `generateText({ output: Output.object({ schema }) })` via the
5959
+ * structured-output runner. We keep this as a separate helper because the runner needs the raw
5960
+ * validated value (not just text) back, and must be able to retry on Zod failures.
5961
+ */
5962
+ async invokeStructuredTurn(prepared, itemInputsByPort, schema, messages, structuredOptions) {
3441
5963
  const invocationId = ConnectionInvocationIdFactory.create();
3442
5964
  const startedAt = /* @__PURE__ */ new Date();
3443
5965
  const summarizedInput = this.summarizeLlmMessages(messages);
5966
+ const { ctx, model, languageModelConnectionNodeId, guardrails } = prepared;
3444
5967
  const span = this.createModelInvocationSpan(ctx, invocationId, startedAt);
3445
5968
  await ctx.nodeState?.markQueued({
3446
- nodeId,
5969
+ nodeId: languageModelConnectionNodeId,
3447
5970
  activationId: ctx.activationId,
3448
- inputsByPort
5971
+ inputsByPort: itemInputsByPort
5972
+ });
5973
+ await ctx.nodeState?.appendConnectionInvocation({
5974
+ invocationId,
5975
+ connectionNodeId: languageModelConnectionNodeId,
5976
+ parentAgentNodeId: ctx.nodeId,
5977
+ parentAgentActivationId: ctx.activationId,
5978
+ status: "queued",
5979
+ managedInput: summarizedInput,
5980
+ queuedAt: startedAt.toISOString(),
5981
+ iterationId: ctx.iterationId,
5982
+ itemIndex: ctx.itemIndex,
5983
+ parentInvocationId: ctx.parentInvocationId
3449
5984
  });
3450
5985
  await ctx.nodeState?.markRunning({
3451
- nodeId,
5986
+ nodeId: languageModelConnectionNodeId,
3452
5987
  activationId: ctx.activationId,
3453
- inputsByPort
5988
+ inputsByPort: itemInputsByPort
5989
+ });
5990
+ await ctx.nodeState?.appendConnectionInvocation({
5991
+ invocationId,
5992
+ connectionNodeId: languageModelConnectionNodeId,
5993
+ parentAgentNodeId: ctx.nodeId,
5994
+ parentAgentActivationId: ctx.activationId,
5995
+ status: "running",
5996
+ managedInput: summarizedInput,
5997
+ queuedAt: startedAt.toISOString(),
5998
+ startedAt: startedAt.toISOString(),
5999
+ iterationId: ctx.iterationId,
6000
+ itemIndex: ctx.itemIndex,
6001
+ parentInvocationId: ctx.parentInvocationId
3454
6002
  });
3455
6003
  try {
3456
- const response = await model.invoke(messages, options);
6004
+ const callOptions = this.resolveCallOptions(model, guardrails.modelInvocationOptions);
6005
+ const outputSchema = structuredOptions?.strict && !this.isZodSchema(schema) ? Output.object({ schema: jsonSchema(schema) }) : Output.object({ schema });
6006
+ const result = await generateText({
6007
+ model: model.languageModel,
6008
+ messages: [...messages],
6009
+ experimental_output: outputSchema,
6010
+ maxOutputTokens: callOptions.maxOutputTokens,
6011
+ temperature: callOptions.temperature,
6012
+ providerOptions: callOptions.providerOptions,
6013
+ maxRetries: 0
6014
+ });
6015
+ const turnResult = this.extractTurnResult(result);
3457
6016
  const finishedAt = /* @__PURE__ */ new Date();
3458
6017
  await ctx.nodeState?.markCompleted({
3459
- nodeId,
6018
+ nodeId: languageModelConnectionNodeId,
3460
6019
  activationId: ctx.activationId,
3461
- inputsByPort,
3462
- outputs: AgentOutputFactory.fromUnknown(response)
6020
+ inputsByPort: itemInputsByPort,
6021
+ outputs: AgentOutputFactory.fromUnknown(result.experimental_output)
3463
6022
  });
3464
6023
  await span.attachArtifact({
3465
6024
  kind: "ai.messages",
@@ -3469,26 +6028,29 @@ let AIAgentNode = class AIAgentNode$1 {
3469
6028
  await span.attachArtifact({
3470
6029
  kind: "ai.response.structured",
3471
6030
  contentType: "application/json",
3472
- previewJson: this.resultToJsonValue(response)
6031
+ previewJson: this.resultToJsonValue(result.experimental_output)
3473
6032
  });
3474
- await this.recordModelUsageMetrics(span, response, ctx);
6033
+ await this.recordModelUsageMetrics(span, turnResult.usage, ctx);
3475
6034
  await span.end({
3476
6035
  status: "ok",
3477
6036
  endedAt: finishedAt
3478
6037
  });
3479
6038
  await ctx.nodeState?.appendConnectionInvocation({
3480
6039
  invocationId,
3481
- connectionNodeId: nodeId,
6040
+ connectionNodeId: languageModelConnectionNodeId,
3482
6041
  parentAgentNodeId: ctx.nodeId,
3483
6042
  parentAgentActivationId: ctx.activationId,
3484
6043
  status: "completed",
3485
6044
  managedInput: summarizedInput,
3486
- managedOutput: this.resultToJsonValue(response),
6045
+ managedOutput: this.resultToJsonValue(result.experimental_output),
3487
6046
  queuedAt: startedAt.toISOString(),
3488
6047
  startedAt: startedAt.toISOString(),
3489
- finishedAt: finishedAt.toISOString()
6048
+ finishedAt: finishedAt.toISOString(),
6049
+ iterationId: ctx.iterationId,
6050
+ itemIndex: ctx.itemIndex,
6051
+ parentInvocationId: ctx.parentInvocationId
3490
6052
  });
3491
- return response;
6053
+ return result.experimental_output;
3492
6054
  } catch (error) {
3493
6055
  await span.end({
3494
6056
  status: "error",
@@ -3499,13 +6061,77 @@ let AIAgentNode = class AIAgentNode$1 {
3499
6061
  error,
3500
6062
  invocationId,
3501
6063
  startedAt,
3502
- nodeId,
6064
+ nodeId: languageModelConnectionNodeId,
3503
6065
  ctx,
3504
- inputsByPort,
3505
- managedInput: this.summarizeLlmMessages(messages)
6066
+ inputsByPort: itemInputsByPort,
6067
+ managedInput: summarizedInput
3506
6068
  });
3507
6069
  }
3508
6070
  }
6071
+ isZodSchema(schema) {
6072
+ return typeof schema.parse === "function";
6073
+ }
6074
+ resolveCallOptions(model, overrides) {
6075
+ const defaults = model.defaultCallOptions ?? {};
6076
+ return {
6077
+ maxOutputTokens: overrides?.maxTokens ?? defaults.maxOutputTokens,
6078
+ temperature: defaults.temperature,
6079
+ providerOptions: overrides?.providerOptions ?? defaults.providerOptions
6080
+ };
6081
+ }
6082
+ /**
6083
+ * Build a no-code-friendly output payload for an LLM round.
6084
+ *
6085
+ * Always includes `content` (matching the canvas snapshot shape used elsewhere) and adds a
6086
+ * `toolCalls` array when the round produced tool calls so the execution inspector surfaces the
6087
+ * planned calls instead of just an empty `""` for tool-only rounds.
6088
+ */
6089
+ summarizeTurnOutput(turnResult) {
6090
+ if (turnResult.toolCalls.length === 0) return { content: turnResult.text };
6091
+ const toolCalls = turnResult.toolCalls.map((toolCall) => ({
6092
+ name: toolCall.name,
6093
+ args: this.resultToJsonValue(toolCall.input) ?? null
6094
+ }));
6095
+ return {
6096
+ content: turnResult.text,
6097
+ toolCalls
6098
+ };
6099
+ }
6100
+ extractTurnResult(result) {
6101
+ const usage = this.extractUsageFromResult(result);
6102
+ const text = result.text;
6103
+ const toolCalls = result.toolCalls.map((toolCall) => ({
6104
+ id: toolCall.toolCallId,
6105
+ name: toolCall.toolName,
6106
+ input: toolCall.input
6107
+ }));
6108
+ return {
6109
+ assistantMessage: this.extractAssistantMessage(result),
6110
+ text,
6111
+ toolCalls,
6112
+ usage
6113
+ };
6114
+ }
6115
+ extractAssistantMessage(result) {
6116
+ const assistantMessages = result.response.messages.filter((m) => m.role === "assistant");
6117
+ return assistantMessages[assistantMessages.length - 1];
6118
+ }
6119
+ extractUsageFromResult(result) {
6120
+ const usage = result.usage;
6121
+ const inputTokens = this.toFiniteNumber(usage.inputTokens);
6122
+ const outputTokens = this.toFiniteNumber(usage.outputTokens);
6123
+ return {
6124
+ inputTokens,
6125
+ outputTokens,
6126
+ totalTokens: this.toFiniteNumber(usage.totalTokens) ?? (inputTokens !== void 0 && outputTokens !== void 0 ? inputTokens + outputTokens : void 0),
6127
+ cachedInputTokens: this.toFiniteNumber(usage.cachedInputTokens),
6128
+ reasoningTokens: this.toFiniteNumber(usage.reasoningTokens)
6129
+ };
6130
+ }
6131
+ toFiniteNumber(value) {
6132
+ if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
6133
+ return value;
6134
+ }
3509
6135
  createModelInvocationSpan(ctx, invocationId, startedAt) {
3510
6136
  return ctx.telemetry.startChildSpan({
3511
6137
  name: "gen_ai.chat.completion",
@@ -3514,13 +6140,22 @@ let AIAgentNode = class AIAgentNode$1 {
3514
6140
  attributes: {
3515
6141
  [CodemationTelemetryAttributeNames.connectionInvocationId]: invocationId,
3516
6142
  [GenAiTelemetryAttributeNames.operationName]: "chat",
3517
- [GenAiTelemetryAttributeNames.requestModel]: this.resolveChatModelName(ctx.config.chatModel)
6143
+ [GenAiTelemetryAttributeNames.requestModel]: this.resolveChatModelName(ctx.config.chatModel),
6144
+ ...ctx.iterationId ? { [CodemationTelemetryAttributeNames.iterationId]: ctx.iterationId } : {},
6145
+ ...typeof ctx.itemIndex === "number" ? { [CodemationTelemetryAttributeNames.iterationIndex]: ctx.itemIndex } : {},
6146
+ ...ctx.parentInvocationId ? { [CodemationTelemetryAttributeNames.parentInvocationId]: ctx.parentInvocationId } : {}
3518
6147
  }
3519
6148
  });
3520
6149
  }
3521
- async recordModelUsageMetrics(span, response, ctx) {
3522
- const usage = this.extractModelUsageMetrics(response);
3523
- for (const [name, value] of Object.entries(usage)) {
6150
+ async recordModelUsageMetrics(span, usage, ctx) {
6151
+ const entries = [
6152
+ [GenAiTelemetryAttributeNames.usageInputTokens, usage.inputTokens],
6153
+ [GenAiTelemetryAttributeNames.usageOutputTokens, usage.outputTokens],
6154
+ [GenAiTelemetryAttributeNames.usageTotalTokens, usage.totalTokens],
6155
+ [GenAiTelemetryAttributeNames.usageCacheReadInputTokens, usage.cachedInputTokens],
6156
+ [GenAiTelemetryAttributeNames.usageReasoningTokens, usage.reasoningTokens]
6157
+ ];
6158
+ for (const [name, value] of entries) {
3524
6159
  if (value === void 0) continue;
3525
6160
  await span.recordMetric({
3526
6161
  name,
@@ -3535,99 +6170,49 @@ let AIAgentNode = class AIAgentNode$1 {
3535
6170
  const provider = ctx.config.chatModel.provider;
3536
6171
  const pricingKey = ctx.config.chatModel.modelName;
3537
6172
  if (!provider || !pricingKey) return;
3538
- const inputTokens = usage[GenAiTelemetryAttributeNames.usageInputTokens];
3539
- const outputTokens = usage[GenAiTelemetryAttributeNames.usageOutputTokens];
3540
- if (inputTokens !== void 0) await costTracking.captureUsage({
6173
+ if (usage.inputTokens !== void 0) await costTracking.captureUsage({
3541
6174
  component: "chat",
3542
6175
  provider,
3543
6176
  operation: "completion.input",
3544
6177
  pricingKey,
3545
6178
  usageUnit: "input_tokens",
3546
- quantity: inputTokens,
6179
+ quantity: usage.inputTokens,
3547
6180
  modelName: pricingKey
3548
6181
  });
3549
- if (outputTokens !== void 0) await costTracking.captureUsage({
6182
+ if (usage.outputTokens !== void 0) await costTracking.captureUsage({
3550
6183
  component: "chat",
3551
6184
  provider,
3552
6185
  operation: "completion.output",
3553
6186
  pricingKey,
3554
6187
  usageUnit: "output_tokens",
3555
- quantity: outputTokens,
6188
+ quantity: usage.outputTokens,
3556
6189
  modelName: pricingKey
3557
6190
  });
3558
6191
  }
3559
6192
  resolveChatModelName(chatModel$1) {
3560
6193
  return chatModel$1.modelName ?? chatModel$1.name;
3561
6194
  }
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
6195
  async markQueuedTools(plannedToolCalls, ctx) {
3626
- for (const plannedToolCall of plannedToolCalls) await ctx.nodeState?.markQueued({
3627
- nodeId: plannedToolCall.nodeId,
3628
- activationId: ctx.activationId,
3629
- inputsByPort: AgentToolCallPortMap.fromInput(plannedToolCall.toolCall.input ?? {})
3630
- });
6196
+ const queuedAt = (/* @__PURE__ */ new Date()).toISOString();
6197
+ for (const plannedToolCall of plannedToolCalls) {
6198
+ await ctx.nodeState?.markQueued({
6199
+ nodeId: plannedToolCall.nodeId,
6200
+ activationId: ctx.activationId,
6201
+ inputsByPort: AgentToolCallPortMap.fromInput(plannedToolCall.toolCall.input ?? {})
6202
+ });
6203
+ await ctx.nodeState?.appendConnectionInvocation({
6204
+ invocationId: plannedToolCall.invocationId,
6205
+ connectionNodeId: plannedToolCall.nodeId,
6206
+ parentAgentNodeId: ctx.nodeId,
6207
+ parentAgentActivationId: ctx.activationId,
6208
+ status: "queued",
6209
+ managedInput: this.resultToJsonValue(plannedToolCall.toolCall.input),
6210
+ queuedAt,
6211
+ iterationId: ctx.iterationId,
6212
+ itemIndex: ctx.itemIndex,
6213
+ parentInvocationId: ctx.parentInvocationId
6214
+ });
6215
+ }
3631
6216
  }
3632
6217
  planToolCalls(bindings, toolCalls, parentNodeId) {
3633
6218
  const invocationCountByToolName = /* @__PURE__ */ new Map();
@@ -3640,7 +6225,8 @@ let AIAgentNode = class AIAgentNode$1 {
3640
6225
  binding,
3641
6226
  toolCall,
3642
6227
  invocationIndex,
3643
- nodeId: ConnectionNodeIdFactory.toolConnectionNodeId(parentNodeId, binding.config.name)
6228
+ nodeId: ConnectionNodeIdFactory.toolConnectionNodeId(parentNodeId, binding.config.name),
6229
+ invocationId: ConnectionInvocationIdFactory.create()
3644
6230
  };
3645
6231
  });
3646
6232
  }
@@ -3668,7 +6254,10 @@ let AIAgentNode = class AIAgentNode$1 {
3668
6254
  },
3669
6255
  queuedAt: args.startedAt.toISOString(),
3670
6256
  startedAt: args.startedAt.toISOString(),
3671
- finishedAt: finishedAt.toISOString()
6257
+ finishedAt: finishedAt.toISOString(),
6258
+ iterationId: args.ctx.iterationId,
6259
+ itemIndex: args.ctx.itemIndex,
6260
+ parentInvocationId: args.ctx.parentInvocationId
3672
6261
  });
3673
6262
  return effectiveError;
3674
6263
  }
@@ -3681,7 +6270,7 @@ let AIAgentNode = class AIAgentNode$1 {
3681
6270
  };
3682
6271
  }
3683
6272
  resultToJsonValue(value) {
3684
- if (value === void 0) return;
6273
+ if (value === void 0) return void 0;
3685
6274
  const json = JSON.stringify(value);
3686
6275
  return JSON.parse(json);
3687
6276
  }
@@ -3696,7 +6285,7 @@ let AIAgentNode = class AIAgentNode$1 {
3696
6285
  resolveToolRuntime(config$1) {
3697
6286
  if (this.isNodeBackedToolConfig(config$1)) {
3698
6287
  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).`);
6288
+ if (inputSchema == null) throw new Error(`AIAgent tool "${config$1.name}": node-backed tool is missing inputSchema (cannot build AI SDK tool).`);
3700
6289
  return {
3701
6290
  defaultDescription: `Run workflow node "${config$1.node.name ?? config$1.name}" as an AI tool.`,
3702
6291
  inputSchema,
@@ -3705,7 +6294,7 @@ let AIAgentNode = class AIAgentNode$1 {
3705
6294
  }
3706
6295
  if (this.isCallableToolConfig(config$1)) {
3707
6296
  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).`);
6297
+ if (inputSchema == null) throw new Error(`AIAgent tool "${config$1.name}": callable tool is missing inputSchema (cannot build AI SDK tool).`);
3709
6298
  return {
3710
6299
  defaultDescription: config$1.description ?? `Callable tool "${config$1.name}".`,
3711
6300
  inputSchema,
@@ -3723,17 +6312,9 @@ let AIAgentNode = class AIAgentNode$1 {
3723
6312
  execute: async (args) => await Promise.resolve(tool.execute(args))
3724
6313
  };
3725
6314
  }
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
6315
  isNodeBackedToolConfig(config$1) {
3732
6316
  return config$1 instanceof NodeBackedToolConfig || typeof config$1 === "object" && config$1 !== null && config$1.toolKind === "nodeBacked";
3733
6317
  }
3734
- /**
3735
- * Callable tools use {@link CallableToolConfig#toolKind} for cross-package / JSON round-trip safety.
3736
- */
3737
6318
  isCallableToolConfig(config$1) {
3738
6319
  return config$1 instanceof CallableToolConfig || typeof config$1 === "object" && config$1 !== null && config$1.toolKind === "callable";
3739
6320
  }
@@ -3804,6 +6385,52 @@ var AIAgent = class {
3804
6385
  }
3805
6386
  };
3806
6387
 
6388
+ //#endregion
6389
+ //#region src/nodes/AssertionNode.ts
6390
+ let AssertionNode = class AssertionNode$1 {
6391
+ kind = "node";
6392
+ outputPorts = ["main"];
6393
+ async execute(args) {
6394
+ const ctx = args.ctx;
6395
+ const config$1 = ctx.config;
6396
+ try {
6397
+ return [...await config$1.assertions(args.item, ctx)];
6398
+ } catch (err) {
6399
+ const message = err instanceof Error ? err.message : String(err);
6400
+ return [{
6401
+ name: config$1.name ?? "assertion",
6402
+ score: 0,
6403
+ errored: true,
6404
+ message
6405
+ }];
6406
+ }
6407
+ }
6408
+ };
6409
+ AssertionNode = __decorate([node({ packageName: "@codemation/core-nodes" })], AssertionNode);
6410
+
6411
+ //#endregion
6412
+ //#region src/nodes/assertion.ts
6413
+ /**
6414
+ * Generic assertion node — the "callback" form. For declarative shorthands (StringEquals,
6415
+ * JudgeByAgent) compose this with helpers added in later phases. Sets `emitsAssertions: true`
6416
+ * so host-side persisters know to record its outputs as `TestAssertion` rows.
6417
+ */
6418
+ var Assertion = class {
6419
+ kind = "node";
6420
+ type = AssertionNode;
6421
+ icon;
6422
+ name;
6423
+ id;
6424
+ emitsAssertions = true;
6425
+ assertions;
6426
+ constructor(options) {
6427
+ this.name = options.name ?? "Assertion";
6428
+ this.id = options.id;
6429
+ this.icon = options.icon ?? "lucide:check-circle";
6430
+ this.assertions = options.assertions;
6431
+ }
6432
+ };
6433
+
3807
6434
  //#endregion
3808
6435
  //#region src/nodes/CallbackResultNormalizerFactory.ts
3809
6436
  var CallbackResultNormalizer = class {
@@ -3873,32 +6500,79 @@ let HttpRequestNode = class HttpRequestNode$1 {
3873
6500
  }
3874
6501
  async executeItem(item, ctx) {
3875
6502
  const url = this.resolveUrl(item, ctx);
3876
- const response = await fetch(url, { method: ctx.config.method });
6503
+ const credential = await this.resolveCredential(ctx);
6504
+ const spec = {
6505
+ url,
6506
+ method: ctx.config.method,
6507
+ headers: ctx.config.args.headers,
6508
+ query: ctx.config.args.query,
6509
+ body: ctx.config.args.body,
6510
+ credential,
6511
+ download: {
6512
+ mode: ctx.config.downloadMode,
6513
+ binaryName: ctx.config.binaryName
6514
+ },
6515
+ ctx
6516
+ };
6517
+ const { url: resolvedUrl, init } = await new HttpRequestExecutor(globalThis.fetch, new HttpBodyBuilder(), new HttpUrlBuilder()).buildRequest(spec, item);
6518
+ const response = await globalThis.fetch(resolvedUrl, init);
3877
6519
  const headers = this.readHeaders(response.headers);
3878
6520
  const mimeType = this.resolveMimeType(headers);
3879
- const bodyBinaryName = ctx.config.binaryName;
3880
- const shouldAttachBody = this.shouldAttachBody(ctx.config.downloadMode, mimeType);
3881
- let outputItem = { json: {
3882
- url,
6521
+ const binaryName = ctx.config.binaryName;
6522
+ if (this.shouldAttachBody(ctx.config.downloadMode, mimeType)) {
6523
+ const outputJson = {
6524
+ url: resolvedUrl,
6525
+ method: ctx.config.method,
6526
+ ok: response.ok,
6527
+ status: response.status,
6528
+ statusText: response.statusText,
6529
+ mimeType,
6530
+ headers,
6531
+ bodyBinaryName: binaryName
6532
+ };
6533
+ const attachment = await ctx.binary.attach({
6534
+ name: binaryName,
6535
+ body: response.body ? response.body : new Uint8Array(await response.arrayBuffer()),
6536
+ mimeType,
6537
+ filename: this.resolveFilename(resolvedUrl, headers)
6538
+ });
6539
+ let outputItem = { json: outputJson };
6540
+ outputItem = ctx.binary.withAttachment(outputItem, binaryName, attachment);
6541
+ return outputItem;
6542
+ }
6543
+ const isJson = this.isJsonMimeType(mimeType);
6544
+ let json;
6545
+ let text;
6546
+ if (isJson) try {
6547
+ json = await response.json();
6548
+ } catch {
6549
+ text = await response.text();
6550
+ }
6551
+ else text = await response.text();
6552
+ return { json: {
6553
+ url: resolvedUrl,
3883
6554
  method: ctx.config.method,
3884
6555
  ok: response.ok,
3885
6556
  status: response.status,
3886
6557
  statusText: response.statusText,
3887
6558
  mimeType,
3888
6559
  headers,
3889
- ...shouldAttachBody ? { bodyBinaryName } : {}
6560
+ ...json !== void 0 ? { json } : {},
6561
+ ...text !== void 0 ? { text } : {}
3890
6562
  } };
3891
- if (!shouldAttachBody) return outputItem;
3892
- const attachment = await ctx.binary.attach({
3893
- name: bodyBinaryName,
3894
- body: response.body ? response.body : new Uint8Array(await response.arrayBuffer()),
3895
- mimeType,
3896
- filename: this.resolveFilename(url, headers)
3897
- });
3898
- outputItem = ctx.binary.withAttachment(outputItem, bodyBinaryName, attachment);
3899
- return outputItem;
6563
+ }
6564
+ async resolveCredential(ctx) {
6565
+ const slotKey = ctx.config.args.credentialSlot;
6566
+ if (!slotKey) return;
6567
+ try {
6568
+ return await ctx.getCredential(slotKey);
6569
+ } catch {
6570
+ return;
6571
+ }
3900
6572
  }
3901
6573
  resolveUrl(item, ctx) {
6574
+ const literalUrl = ctx.config.args.url;
6575
+ if (literalUrl && literalUrl.trim().length > 0) return literalUrl.trim();
3902
6576
  const candidate = this.asRecord(item.json)[ctx.config.urlField];
3903
6577
  if (typeof candidate !== "string" || candidate.trim() === "") throw new Error(`HttpRequest node expected item.json.${ctx.config.urlField} to contain a URL string.`);
3904
6578
  return candidate;
@@ -3919,6 +6593,9 @@ let HttpRequestNode = class HttpRequestNode$1 {
3919
6593
  if (!contentType) return "application/octet-stream";
3920
6594
  return contentType.split(";")[0]?.trim() || "application/octet-stream";
3921
6595
  }
6596
+ isJsonMimeType(mimeType) {
6597
+ return mimeType === "application/json" || mimeType.endsWith("+json");
6598
+ }
3922
6599
  shouldAttachBody(mode, mimeType) {
3923
6600
  if (mode === "always") return true;
3924
6601
  if (mode === "never") return false;
@@ -3945,10 +6622,21 @@ HttpRequestNode = __decorate([node({ packageName: "@codemation/core-nodes" })],
3945
6622
 
3946
6623
  //#endregion
3947
6624
  //#region src/nodes/httpRequest.ts
6625
+ /**
6626
+ * The built-in HTTP request credential type IDs accepted by the `HttpRequest` node.
6627
+ * These match the four generic credential types shipped with `@codemation/core-nodes`.
6628
+ */
6629
+ const HTTP_REQUEST_ACCEPTED_CREDENTIAL_TYPES = [
6630
+ bearerTokenCredentialType.definition.typeId,
6631
+ apiKeyCredentialType.definition.typeId,
6632
+ basicAuthCredentialType.definition.typeId,
6633
+ oauth2ClientCredentialsType.definition.typeId
6634
+ ];
3948
6635
  var HttpRequest = class {
3949
6636
  kind = "node";
3950
6637
  type = HttpRequestNode;
3951
6638
  execution = { hint: "local" };
6639
+ icon = "lucide:globe";
3952
6640
  constructor(name, args = {}, retryPolicy = RetryPolicy.defaultForHttp) {
3953
6641
  this.name = name;
3954
6642
  this.args = args;
@@ -3969,6 +6657,16 @@ var HttpRequest = class {
3969
6657
  get downloadMode() {
3970
6658
  return this.args.downloadMode ?? "auto";
3971
6659
  }
6660
+ getCredentialRequirements() {
6661
+ if (!this.args.credentialSlot) return [];
6662
+ return [{
6663
+ slotKey: this.args.credentialSlot,
6664
+ label: "Authentication",
6665
+ acceptedTypes: HTTP_REQUEST_ACCEPTED_CREDENTIAL_TYPES,
6666
+ optional: true,
6667
+ helpText: "Optional credential for authenticating the HTTP request."
6668
+ }];
6669
+ }
3972
6670
  };
3973
6671
 
3974
6672
  //#endregion
@@ -3990,7 +6688,7 @@ var Aggregate = class {
3990
6688
  type = AggregateNode;
3991
6689
  execution = { hint: "local" };
3992
6690
  keepBinaries = true;
3993
- icon = "lucide:layers";
6691
+ icon = "builtin:aggregate-rows";
3994
6692
  constructor(name, aggregate, id) {
3995
6693
  this.name = name;
3996
6694
  this.aggregate = aggregate;
@@ -4085,7 +6783,7 @@ var If = class {
4085
6783
  kind = "node";
4086
6784
  type = IfNode;
4087
6785
  execution = { hint: "local" };
4088
- icon = "lucide:split";
6786
+ icon = "lucide:split@rot=90";
4089
6787
  declaredOutputPorts = ["true", "false"];
4090
6788
  constructor(name, predicate, id) {
4091
6789
  this.name = name;
@@ -4094,6 +6792,40 @@ var If = class {
4094
6792
  }
4095
6793
  };
4096
6794
 
6795
+ //#endregion
6796
+ //#region src/nodes/IsTestRunNode.ts
6797
+ let IsTestRunNode = class IsTestRunNode$1 {
6798
+ kind = "node";
6799
+ execute(args) {
6800
+ const isTest = args.ctx.testContext !== void 0;
6801
+ return emitPorts({
6802
+ true: isTest ? [args.item] : [],
6803
+ false: isTest ? [] : [args.item]
6804
+ });
6805
+ }
6806
+ };
6807
+ IsTestRunNode = __decorate([node({ packageName: "@codemation/core-nodes" })], IsTestRunNode);
6808
+
6809
+ //#endregion
6810
+ //#region src/nodes/isTestRun.ts
6811
+ /**
6812
+ * Branches per-item on whether the current run is a test run. Output ports: `true`, `false`.
6813
+ * The wire payload is unchanged — this is a router, not a transform.
6814
+ */
6815
+ var IsTestRun = class {
6816
+ kind = "node";
6817
+ type = IsTestRunNode;
6818
+ execution = { hint: "local" };
6819
+ icon = "lucide:flask-conical";
6820
+ declaredOutputPorts = ["true", "false"];
6821
+ name;
6822
+ id;
6823
+ constructor(name = "Is test run?", id) {
6824
+ this.name = name;
6825
+ this.id = id;
6826
+ }
6827
+ };
6828
+
4097
6829
  //#endregion
4098
6830
  //#region src/nodes/SwitchNode.ts
4099
6831
  let SwitchNode = class SwitchNode$1 {
@@ -4150,7 +6882,7 @@ var Split = class {
4150
6882
  * Mirrors {@link MapData}'s empty-output behavior.
4151
6883
  */
4152
6884
  continueWhenEmptyOutput = true;
4153
- icon = "lucide:ungroup";
6885
+ icon = "builtin:split-rows";
4154
6886
  constructor(name, getElements, id) {
4155
6887
  this.name = name;
4156
6888
  this.getElements = getElements;
@@ -4158,6 +6890,75 @@ var Split = class {
4158
6890
  }
4159
6891
  };
4160
6892
 
6893
+ //#endregion
6894
+ //#region src/nodes/CronTriggerNode.ts
6895
+ let CronTriggerNode = class CronTriggerNode$1 {
6896
+ kind = "trigger";
6897
+ outputPorts = ["main"];
6898
+ async setup(ctx) {
6899
+ const job = ctx.config.createJob(async (self) => {
6900
+ const scheduledFor = self.currentRun()?.toISOString() ?? ctx.now().toISOString();
6901
+ await ctx.emit([{ json: {
6902
+ firedAt: ctx.now().toISOString(),
6903
+ scheduledFor
6904
+ } }]);
6905
+ });
6906
+ ctx.registerCleanup({ stop: () => {
6907
+ job.stop();
6908
+ } });
6909
+ }
6910
+ async execute(items, _ctx) {
6911
+ return { main: items };
6912
+ }
6913
+ async getTestItems(ctx) {
6914
+ const nowIso = ctx.now().toISOString();
6915
+ return [{ json: {
6916
+ firedAt: nowIso,
6917
+ scheduledFor: nowIso
6918
+ } }];
6919
+ }
6920
+ };
6921
+ CronTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })], CronTriggerNode);
6922
+
6923
+ //#endregion
6924
+ //#region src/nodes/CronTriggerFactory.ts
6925
+ /**
6926
+ * Schedules a workflow on a standard cron expression.
6927
+ *
6928
+ * Each tick emits one item: `{ firedAt: string, scheduledFor: string }` — both ISO-8601 timestamps.
6929
+ * `firedAt` is the wall-clock moment the callback ran; `scheduledFor` is the cron-computed
6930
+ * firing instant (these differ when the job was delayed).
6931
+ *
6932
+ * Timezone defaults to UTC when omitted — cron without an explicit TZ is a DST footgun.
6933
+ */
6934
+ var CronTrigger = class {
6935
+ kind = "trigger";
6936
+ type = CronTriggerNode;
6937
+ icon = "lucide:clock";
6938
+ id;
6939
+ constructor(name, args, id) {
6940
+ this.name = name;
6941
+ this.args = args;
6942
+ new Cron(args.schedule, {
6943
+ paused: true,
6944
+ timezone: args.timezone
6945
+ });
6946
+ this.id = id;
6947
+ }
6948
+ get schedule() {
6949
+ return this.args.schedule;
6950
+ }
6951
+ get timezone() {
6952
+ return this.args.timezone;
6953
+ }
6954
+ createJob(callback) {
6955
+ return new Cron(this.args.schedule, {
6956
+ timezone: this.args.timezone,
6957
+ protect: true
6958
+ }, callback);
6959
+ }
6960
+ };
6961
+
4161
6962
  //#endregion
4162
6963
  //#region src/nodes/ManualTriggerNode.ts
4163
6964
  let ManualTriggerNode = class ManualTriggerNode$1 {
@@ -4221,6 +7022,7 @@ var MapData = class {
4221
7022
  execution = { hint: "local" };
4222
7023
  /** Zero mapped items should still allow downstream nodes to run. */
4223
7024
  continueWhenEmptyOutput = true;
7025
+ icon = "lucide:square-pen";
4224
7026
  keepBinaries;
4225
7027
  constructor(name, map, options = {}) {
4226
7028
  this.name = name;
@@ -4290,7 +7092,7 @@ MergeNode = __decorate([node({ packageName: "@codemation/core-nodes" })], MergeN
4290
7092
  var Merge = class {
4291
7093
  kind = "node";
4292
7094
  type = MergeNode;
4293
- icon = "lucide:git-merge";
7095
+ icon = "lucide:merge@rot=90";
4294
7096
  constructor(name, cfg = { mode: "passThrough" }, id) {
4295
7097
  this.name = name;
4296
7098
  this.cfg = cfg;
@@ -4315,6 +7117,7 @@ var NoOp = class {
4315
7117
  kind = "node";
4316
7118
  type = NoOpNode;
4317
7119
  execution = { hint: "local" };
7120
+ icon = "lucide:circle-dashed";
4318
7121
  constructor(name = "NoOp", id) {
4319
7122
  this.name = name;
4320
7123
  this.id = id;
@@ -4387,6 +7190,52 @@ var SubWorkflow = class {
4387
7190
  }
4388
7191
  };
4389
7192
 
7193
+ //#endregion
7194
+ //#region src/nodes/TestTriggerNode.ts
7195
+ let TestTriggerNode = class TestTriggerNode$1 {
7196
+ kind = "trigger";
7197
+ outputPorts = ["main"];
7198
+ async setup(_ctx) {}
7199
+ async execute(items, _ctx) {
7200
+ return { main: items };
7201
+ }
7202
+ };
7203
+ TestTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })], TestTriggerNode);
7204
+
7205
+ //#endregion
7206
+ //#region src/nodes/testTrigger.ts
7207
+ /**
7208
+ * Trigger config for a test fixture source. Drop one (or more) of these on the canvas alongside
7209
+ * a workflow's live triggers; clicking "Run tests" on the Tests tab invokes
7210
+ * {@link TestTriggerOptions.generateItems} via the TestSuiteOrchestrator.
7211
+ */
7212
+ var TestTrigger = class {
7213
+ kind = "trigger";
7214
+ triggerKind = "test";
7215
+ type = TestTriggerNode;
7216
+ icon;
7217
+ name;
7218
+ id;
7219
+ concurrency;
7220
+ description;
7221
+ generateItems;
7222
+ caseLabel;
7223
+ credentialRequirements;
7224
+ constructor(options) {
7225
+ this.name = options.name ?? "Test trigger";
7226
+ this.id = options.id;
7227
+ this.icon = options.icon ?? "lucide:flask-conical";
7228
+ this.concurrency = options.concurrency;
7229
+ this.description = options.description;
7230
+ this.credentialRequirements = options.credentialRequirements ?? [];
7231
+ this.generateItems = options.generateItems;
7232
+ this.caseLabel = options.caseLabel;
7233
+ }
7234
+ getCredentialRequirements() {
7235
+ return this.credentialRequirements;
7236
+ }
7237
+ };
7238
+
4390
7239
  //#endregion
4391
7240
  //#region src/nodes/WaitDurationFactory.ts
4392
7241
  var WaitDuration = class {
@@ -4420,6 +7269,7 @@ var Wait = class {
4420
7269
  execution = { hint: "local" };
4421
7270
  /** Pass-through empty batches should still advance to downstream nodes. */
4422
7271
  continueWhenEmptyOutput = true;
7272
+ icon = "lucide:hourglass";
4423
7273
  constructor(name, milliseconds, id) {
4424
7274
  this.name = name;
4425
7275
  this.milliseconds = milliseconds;
@@ -4470,7 +7320,7 @@ WebhookTriggerNode = __decorate([node({ packageName: "@codemation/core-nodes" })
4470
7320
  var WebhookTrigger = class WebhookTrigger {
4471
7321
  kind = "trigger";
4472
7322
  type = WebhookTriggerNode;
4473
- icon = "lucide:globe";
7323
+ icon = "lucide:webhook";
4474
7324
  constructor(name, args, handler = WebhookTrigger.defaultHandler, id) {
4475
7325
  this.name = name;
4476
7326
  this.args = args;
@@ -4566,10 +7416,10 @@ var WorkflowDefinedNodeResolver = class {
4566
7416
  //#endregion
4567
7417
  //#region src/workflowAuthoring/WorkflowDurationParser.types.ts
4568
7418
  var WorkflowDurationParser = class {
4569
- static parse(duration) {
4570
- if (typeof duration === "number") return Number.isFinite(duration) && duration > 0 ? Math.floor(duration) : 0;
4571
- const match = duration.trim().toLowerCase().match(/^(\d+)(ms|s|m|h)$/);
4572
- if (!match) throw new Error(`Unsupported wait duration "${duration}". Use a number of milliseconds or values like "500ms", "2s", "5m".`);
7419
+ static parse(duration$2) {
7420
+ if (typeof duration$2 === "number") return Number.isFinite(duration$2) && duration$2 > 0 ? Math.floor(duration$2) : 0;
7421
+ const match = duration$2.trim().toLowerCase().match(/^(\d+)(ms|s|m|h)$/);
7422
+ if (!match) throw new Error(`Unsupported wait duration "${duration$2}". Use a number of milliseconds or values like "500ms", "2s", "5m".`);
4573
7423
  const value = Number(match[1]);
4574
7424
  const unit = match[2];
4575
7425
  if (unit === "ms") return value;
@@ -4595,8 +7445,8 @@ var WorkflowBranchBuilder = class WorkflowBranchBuilder {
4595
7445
  }
4596
7446
  wait(nameOrDuration, durationOrUndefined, id) {
4597
7447
  const name = typeof nameOrDuration === "string" && durationOrUndefined !== void 0 ? nameOrDuration : "Wait";
4598
- const duration = durationOrUndefined ?? nameOrDuration;
4599
- return this.then(new Wait(name, WorkflowDurationParser.parse(duration), id));
7448
+ const duration$2 = durationOrUndefined ?? nameOrDuration;
7449
+ return this.then(new Wait(name, WorkflowDurationParser.parse(duration$2), id));
4600
7450
  }
4601
7451
  split(nameOrGetter, getElementsOrUndefined, id) {
4602
7452
  const name = typeof nameOrGetter === "string" ? nameOrGetter : "Split";
@@ -4641,8 +7491,8 @@ var WorkflowChain = class WorkflowChain {
4641
7491
  }
4642
7492
  wait(nameOrDuration, durationOrUndefined, id) {
4643
7493
  const name = typeof nameOrDuration === "string" && durationOrUndefined !== void 0 ? nameOrDuration : "Wait";
4644
- const duration = durationOrUndefined ?? nameOrDuration;
4645
- return this.then(new Wait(name, WorkflowDurationParser.parse(duration), id));
7494
+ const duration$2 = durationOrUndefined ?? nameOrDuration;
7495
+ return this.then(new Wait(name, WorkflowDurationParser.parse(duration$2), id));
4646
7496
  }
4647
7497
  split(nameOrGetter, getElementsOrUndefined, id) {
4648
7498
  const name = typeof nameOrGetter === "string" ? nameOrGetter : "Split";
@@ -4824,5 +7674,128 @@ var ConnectionCredentialNodeConfigFactory = class {
4824
7674
  };
4825
7675
 
4826
7676
  //#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 };
7677
+ //#region src/nodes/collections/collectionInsertNode.types.ts
7678
+ const collectionInsertNode = defineNode({
7679
+ key: "collection-insert",
7680
+ title: "Collection: Insert",
7681
+ description: "Insert a new row into a collection.",
7682
+ icon: "lucide:boxes",
7683
+ configSchema: object({
7684
+ collectionName: string(),
7685
+ data: record(string(), unknown())
7686
+ }),
7687
+ async execute(_args, { config: config$1, execution }) {
7688
+ const store = execution.collections?.[config$1.collectionName];
7689
+ if (!store) throw new Error(`Collection "${config$1.collectionName}" is not registered. Add defineCollection to your codemation config.`);
7690
+ return await store.insert(config$1.data);
7691
+ }
7692
+ });
7693
+
7694
+ //#endregion
7695
+ //#region src/nodes/collections/collectionGetNode.types.ts
7696
+ const collectionGetNode = defineNode({
7697
+ key: "collection-get",
7698
+ title: "Collection: Get",
7699
+ description: "Get a single row by id from a collection.",
7700
+ icon: "lucide:layers",
7701
+ configSchema: object({
7702
+ collectionName: string(),
7703
+ id: string()
7704
+ }),
7705
+ async execute(_args, { config: config$1, execution }) {
7706
+ const store = execution.collections?.[config$1.collectionName];
7707
+ if (!store) throw new Error(`Collection "${config$1.collectionName}" is not registered. Add defineCollection to your codemation config.`);
7708
+ const row = await store.get(config$1.id);
7709
+ if (row === null) return [];
7710
+ return row;
7711
+ }
7712
+ });
7713
+
7714
+ //#endregion
7715
+ //#region src/nodes/collections/collectionFindOneNode.types.ts
7716
+ const collectionFindOneNode = defineNode({
7717
+ key: "collection-find-one",
7718
+ title: "Collection: Find One",
7719
+ description: "Find a single row matching a filter in a collection.",
7720
+ icon: "lucide:filter",
7721
+ configSchema: object({
7722
+ collectionName: string(),
7723
+ where: record(string(), unknown())
7724
+ }),
7725
+ async execute(_args, { config: config$1, execution }) {
7726
+ const store = execution.collections?.[config$1.collectionName];
7727
+ if (!store) throw new Error(`Collection "${config$1.collectionName}" is not registered. Add defineCollection to your codemation config.`);
7728
+ const row = await store.findOne(config$1.where);
7729
+ if (row === null) return [];
7730
+ return row;
7731
+ }
7732
+ });
7733
+
7734
+ //#endregion
7735
+ //#region src/nodes/collections/collectionListNode.types.ts
7736
+ const collectionListNode = defineNode({
7737
+ key: "collection-list",
7738
+ title: "Collection: List",
7739
+ description: "List rows from a collection with optional pagination and filtering.",
7740
+ icon: "lucide:split",
7741
+ configSchema: object({
7742
+ collectionName: string(),
7743
+ limit: number().int().positive().optional(),
7744
+ offset: number().int().nonnegative().optional(),
7745
+ where: record(string(), unknown()).optional()
7746
+ }),
7747
+ async execute(_args, { config: config$1, execution }) {
7748
+ const store = execution.collections?.[config$1.collectionName];
7749
+ if (!store) throw new Error(`Collection "${config$1.collectionName}" is not registered. Add defineCollection to your codemation config.`);
7750
+ const { rows } = await store.list({
7751
+ limit: config$1.limit,
7752
+ offset: config$1.offset,
7753
+ where: config$1.where
7754
+ });
7755
+ return [...rows];
7756
+ }
7757
+ });
7758
+
7759
+ //#endregion
7760
+ //#region src/nodes/collections/collectionUpdateNode.types.ts
7761
+ const collectionUpdateNode = defineNode({
7762
+ key: "collection-update",
7763
+ title: "Collection: Update",
7764
+ description: "Update a row by id in a collection.",
7765
+ icon: "lucide:square-pen",
7766
+ configSchema: object({
7767
+ collectionName: string(),
7768
+ id: string(),
7769
+ patch: record(string(), unknown())
7770
+ }),
7771
+ async execute(_args, { config: config$1, execution }) {
7772
+ const store = execution.collections?.[config$1.collectionName];
7773
+ if (!store) throw new Error(`Collection "${config$1.collectionName}" is not registered. Add defineCollection to your codemation config.`);
7774
+ return await store.update(config$1.id, config$1.patch);
7775
+ }
7776
+ });
7777
+
7778
+ //#endregion
7779
+ //#region src/nodes/collections/collectionDeleteNode.types.ts
7780
+ const collectionDeleteNode = defineNode({
7781
+ key: "collection-delete",
7782
+ title: "Collection: Delete",
7783
+ description: "Delete a row by id from a collection.",
7784
+ icon: "lucide:braces",
7785
+ configSchema: object({
7786
+ collectionName: string(),
7787
+ id: string()
7788
+ }),
7789
+ async execute(_args, { config: config$1, execution }) {
7790
+ const store = execution.collections?.[config$1.collectionName];
7791
+ if (!store) throw new Error(`Collection "${config$1.collectionName}" is not registered. Add defineCollection to your codemation config.`);
7792
+ return {
7793
+ deleted: (await store.delete(config$1.id)).deleted,
7794
+ id: config$1.id
7795
+ };
7796
+ }
7797
+ });
7798
+
7799
+ //#endregion
7800
+ export { AIAgent, AIAgentConnectionWorkflowExpander, AIAgentExecutionHelpersFactory, AIAgentNode, AgentItemPortMap, AgentMessageFactory, AgentOutputFactory, AgentStructuredOutputRepairPromptFactory, AgentStructuredOutputRunner, AgentToolCallPortMap, AgentToolErrorClassifier, AgentToolExecutionCoordinator, AgentToolRepairExhaustedError, AgentToolRepairPolicy, Aggregate, AggregateNode, Assertion, AssertionNode, Callback, CallbackNode, CallbackResultNormalizer, ConnectionCredentialExecutionContextFactory, ConnectionCredentialNode, ConnectionCredentialNodeConfig, ConnectionCredentialNodeConfigFactory, CronTrigger, CronTriggerNode, Filter, FilterNode, HTTP_REQUEST_ACCEPTED_CREDENTIAL_TYPES, HttpRequest, HttpRequestNode, If, IfNode, IsTestRun, IsTestRunNode, ManualTrigger, ManualTriggerNode, MapData, MapDataNode, Merge, MergeNode, NoOp, NoOpNode, OpenAIChatModelConfig, OpenAIChatModelFactory, OpenAiChatModelPresets, OpenAiStrictJsonSchemaFactory, Split, SplitNode, SubWorkflow, SubWorkflowNode, Switch, SwitchNode, TestTrigger, TestTriggerNode, Wait, WaitDuration, WaitNode, WebhookRespondNowAndContinueError, WebhookRespondNowError, WebhookTrigger, WebhookTriggerNode, WorkflowAuthoringBuilder, WorkflowBranchBuilder, WorkflowChain, apiKeyCredentialType, basicAuthCredentialType, bearerTokenCredentialType, collectionDeleteNode, collectionFindOneNode, collectionGetNode, collectionInsertNode, collectionListNode, collectionUpdateNode, createWorkflowBuilder, defineRestNode, oauth2ClientCredentialsType, openAiChatModelPresets, registerCoreNodes, workflow };
4828
7801
  //# sourceMappingURL=index.js.map