@codemation/core-nodes 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AgentConfigInspector, AgentConnectionNodeCollector, AgentGuardrailDefaults, AgentMessageConfigNormalizer, CallableToolConfig, ConnectionInvocationIdFactory, ConnectionNodeIdFactory, CoreTokens, DefinedNodeRegistry, ItemExprResolver, ItemsInputNormalizer, NodeBackedToolConfig, NodeOutputNormalizer, RetryPolicy, RunnableOutputBehaviorResolver, WorkflowBuilder, chatModel, emitPorts, getOriginIndexFromItem, inject, injectable, isPortsEmission, node } from "@codemation/core";
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
2
  import { ChatOpenAI } from "@langchain/openai";
3
3
  import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
4
4
  import { isInteropZodSchema } from "@langchain/core/utils/types";
@@ -71,11 +71,14 @@ OpenAIStructuredOutputMethodFactory = _OpenAIStructuredOutputMethodFactory = __d
71
71
  var OpenAIChatModelConfig = class {
72
72
  type = OpenAIChatModelFactory;
73
73
  presentation;
74
+ provider = "openai";
75
+ modelName;
74
76
  constructor(name, model, credentialSlotKey = "openai", presentationIn, options) {
75
77
  this.name = name;
76
78
  this.model = model;
77
79
  this.credentialSlotKey = credentialSlotKey;
78
80
  this.options = options;
81
+ this.modelName = model;
79
82
  this.presentation = presentationIn ?? {
80
83
  icon: "builtin:openai",
81
84
  label: name
@@ -2192,7 +2195,7 @@ function __decorateParam(paramIndex, decorator) {
2192
2195
 
2193
2196
  //#endregion
2194
2197
  //#region src/nodes/AgentStructuredOutputRepairPromptFactory.ts
2195
- var _ref$3, _AgentStructuredOutputRepairPromptFactory;
2198
+ var _ref$4, _AgentStructuredOutputRepairPromptFactory;
2196
2199
  let AgentStructuredOutputRepairPromptFactory = class AgentStructuredOutputRepairPromptFactory$1 {
2197
2200
  static {
2198
2201
  _AgentStructuredOutputRepairPromptFactory = this;
@@ -2227,7 +2230,7 @@ let AgentStructuredOutputRepairPromptFactory = class AgentStructuredOutputRepair
2227
2230
  AgentStructuredOutputRepairPromptFactory = _AgentStructuredOutputRepairPromptFactory = __decorate([
2228
2231
  injectable(),
2229
2232
  __decorateParam(0, inject(AIAgentExecutionHelpersFactory)),
2230
- __decorateMetadata("design:paramtypes", [typeof (_ref$3 = typeof AIAgentExecutionHelpersFactory !== "undefined" && AIAgentExecutionHelpersFactory) === "function" ? _ref$3 : Object])
2233
+ __decorateMetadata("design:paramtypes", [typeof (_ref$4 = typeof AIAgentExecutionHelpersFactory !== "undefined" && AIAgentExecutionHelpersFactory) === "function" ? _ref$4 : Object])
2231
2234
  ], AgentStructuredOutputRepairPromptFactory);
2232
2235
 
2233
2236
  //#endregion
@@ -2562,7 +2565,7 @@ const meta = meta$1;
2562
2565
 
2563
2566
  //#endregion
2564
2567
  //#region src/nodes/AgentStructuredOutputRunner.ts
2565
- var _ref$2, _ref2$2, _AgentStructuredOutputRunner;
2568
+ var _ref$3, _ref2$3, _AgentStructuredOutputRunner;
2566
2569
  let AgentStructuredOutputRunner = class AgentStructuredOutputRunner$1 {
2567
2570
  static {
2568
2571
  _AgentStructuredOutputRunner = this;
@@ -2675,7 +2678,7 @@ AgentStructuredOutputRunner = _AgentStructuredOutputRunner = __decorate([
2675
2678
  injectable(),
2676
2679
  __decorateParam(0, inject(AgentStructuredOutputRepairPromptFactory)),
2677
2680
  __decorateParam(1, inject(OpenAIStructuredOutputMethodFactory)),
2678
- __decorateMetadata("design:paramtypes", [typeof (_ref$2 = typeof AgentStructuredOutputRepairPromptFactory !== "undefined" && AgentStructuredOutputRepairPromptFactory) === "function" ? _ref$2 : Object, typeof (_ref2$2 = typeof OpenAIStructuredOutputMethodFactory !== "undefined" && OpenAIStructuredOutputMethodFactory) === "function" ? _ref2$2 : Object])
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])
2679
2682
  ], AgentStructuredOutputRunner);
2680
2683
 
2681
2684
  //#endregion
@@ -2686,6 +2689,390 @@ var AgentToolCallPortMap = class {
2686
2689
  }
2687
2690
  };
2688
2691
 
2692
+ //#endregion
2693
+ //#region src/nodes/AgentToolErrorClassifier.ts
2694
+ let AgentToolErrorClassifier = class AgentToolErrorClassifier$1 {
2695
+ classify(args) {
2696
+ const effectiveError = this.toError(args.error);
2697
+ if (this.isRepairableValidationError(args.error, effectiveError)) return {
2698
+ kind: "repairable_validation_error",
2699
+ effectiveError,
2700
+ issues: this.extractIssues(args.error, effectiveError, args.toolName),
2701
+ requiredSchemaReminder: this.toJsonValue(args.schema)
2702
+ };
2703
+ if (this.isTransientExecutionError(effectiveError)) return {
2704
+ kind: "transient_execution_error",
2705
+ effectiveError
2706
+ };
2707
+ return {
2708
+ kind: "non_repairable_error",
2709
+ effectiveError
2710
+ };
2711
+ }
2712
+ isRepairableValidationError(rawError, effectiveError) {
2713
+ if (rawError instanceof ZodError) return rawError.codemationToolValidationStage !== "output";
2714
+ if (effectiveError.name === "ZodError") return true;
2715
+ return effectiveError.message.includes("Received tool input did not match expected schema");
2716
+ }
2717
+ extractIssues(rawError, effectiveError, toolName) {
2718
+ if (rawError instanceof ZodError) return rawError.issues.map((issue$1) => ({
2719
+ path: issue$1.path.map((segment) => typeof segment === "number" ? segment : String(segment)),
2720
+ code: issue$1.code,
2721
+ message: issue$1.message,
2722
+ expected: this.toOptionalString("expected" in issue$1 ? issue$1.expected : void 0),
2723
+ received: this.toOptionalString("received" in issue$1 ? issue$1.received : void 0)
2724
+ }));
2725
+ if (effectiveError.name !== "ZodError") return;
2726
+ return [{
2727
+ path: [],
2728
+ code: "invalid_tool_input",
2729
+ message: `Tool "${toolName}" input was invalid: ${effectiveError.message}`
2730
+ }];
2731
+ }
2732
+ isTransientExecutionError(error) {
2733
+ const summary = `${error.name} ${error.message}`.toLowerCase();
2734
+ return summary.includes("timeout") || summary.includes("timed out") || summary.includes("rate limit") || summary.includes("too many requests") || summary.includes("temporarily unavailable") || summary.includes("econnreset") || summary.includes("etimedout") || summary.includes("503");
2735
+ }
2736
+ toError(error) {
2737
+ return error instanceof Error ? error : new Error(String(error));
2738
+ }
2739
+ toJsonValue(value) {
2740
+ if (value === void 0) return;
2741
+ return JSON.parse(JSON.stringify(value));
2742
+ }
2743
+ toOptionalString(value) {
2744
+ if (value === void 0) return;
2745
+ return String(value);
2746
+ }
2747
+ };
2748
+ AgentToolErrorClassifier = __decorate([injectable()], AgentToolErrorClassifier);
2749
+
2750
+ //#endregion
2751
+ //#region src/nodes/AgentToolRepairExhaustedError.ts
2752
+ var AgentToolRepairExhaustedError = class extends Error {
2753
+ details;
2754
+ constructor(args) {
2755
+ super(`AIAgent "${args.agentName}" (${args.nodeId}) could not recover from invalid tool calls for "${args.toolName}" after ${args.maxAttempts} repair attempt(s).`);
2756
+ this.name = "AgentToolRepairExhaustedError";
2757
+ const details = {
2758
+ toolName: args.toolName,
2759
+ maxAttempts: args.maxAttempts,
2760
+ recommendation: "Check tool schema, tool description, or inject known values in code instead of asking the model to infer them."
2761
+ };
2762
+ if (args.lastManagedInput !== void 0) details["lastManagedInput"] = args.lastManagedInput;
2763
+ if (args.lastValidationIssues && args.lastValidationIssues.length > 0) details["lastValidationIssues"] = args.lastValidationIssues.map((issue$1) => this.serializeIssue(issue$1));
2764
+ this.details = details;
2765
+ }
2766
+ serializeIssue(issue$1) {
2767
+ const result = {
2768
+ path: [...issue$1.path],
2769
+ code: issue$1.code,
2770
+ message: issue$1.message
2771
+ };
2772
+ if (issue$1.expected !== void 0) result["expected"] = issue$1.expected;
2773
+ if (issue$1.received !== void 0) result["received"] = issue$1.received;
2774
+ return result;
2775
+ }
2776
+ };
2777
+
2778
+ //#endregion
2779
+ //#region src/nodes/AgentToolRepairPolicy.ts
2780
+ var _AgentToolRepairPolicy;
2781
+ let AgentToolRepairPolicy = class AgentToolRepairPolicy$1 {
2782
+ static {
2783
+ _AgentToolRepairPolicy = this;
2784
+ }
2785
+ static maxRepairAttemptsPerTool = 2;
2786
+ createDecision(toolName, attemptsByToolName) {
2787
+ const attempt = (attemptsByToolName.get(toolName) ?? 0) + 1;
2788
+ attemptsByToolName.set(toolName, attempt);
2789
+ return {
2790
+ attempt,
2791
+ maxAttempts: _AgentToolRepairPolicy.maxRepairAttemptsPerTool,
2792
+ nextAction: attempt < _AgentToolRepairPolicy.maxRepairAttemptsPerTool ? "model_retry_with_tool_error_message" : "fail_agent_run"
2793
+ };
2794
+ }
2795
+ };
2796
+ AgentToolRepairPolicy = _AgentToolRepairPolicy = __decorate([injectable()], AgentToolRepairPolicy);
2797
+
2798
+ //#endregion
2799
+ //#region src/nodes/AgentToolExecutionCoordinator.ts
2800
+ var _ref$2, _ref2$2;
2801
+ let AgentToolExecutionCoordinator = class AgentToolExecutionCoordinator$1 {
2802
+ constructor(errorClassifier, repairPolicy) {
2803
+ this.errorClassifier = errorClassifier;
2804
+ this.repairPolicy = repairPolicy;
2805
+ }
2806
+ async execute(args) {
2807
+ const results = await Promise.allSettled(args.plannedToolCalls.map(async (plannedToolCall) => await this.executePlannedToolCall({
2808
+ ...args,
2809
+ plannedToolCall
2810
+ })));
2811
+ const rejected = results.find((result) => result.status === "rejected");
2812
+ if (rejected?.status === "rejected") throw rejected.reason instanceof Error ? rejected.reason : new Error(String(rejected.reason));
2813
+ return results.filter((result) => result.status === "fulfilled").map((result) => result.value);
2814
+ }
2815
+ async executePlannedToolCall(args) {
2816
+ const { plannedToolCall, ctx } = args;
2817
+ const toolCallInputsByPort = AgentToolCallPortMap.fromInput(plannedToolCall.toolCall.input ?? {});
2818
+ const invocationId = ConnectionInvocationIdFactory.create();
2819
+ const startedAt = /* @__PURE__ */ new Date();
2820
+ const span = ctx.telemetry.startChildSpan({
2821
+ name: "agent.tool.call",
2822
+ kind: "client",
2823
+ startedAt,
2824
+ attributes: {
2825
+ [CodemationTelemetryAttributeNames.connectionInvocationId]: invocationId,
2826
+ [CodemationTelemetryAttributeNames.toolName]: plannedToolCall.binding.config.name
2827
+ }
2828
+ });
2829
+ await ctx.nodeState?.markRunning({
2830
+ nodeId: plannedToolCall.nodeId,
2831
+ activationId: ctx.activationId,
2832
+ inputsByPort: toolCallInputsByPort
2833
+ });
2834
+ try {
2835
+ const serialized = await plannedToolCall.binding.langChainTool.invoke(plannedToolCall.toolCall.input ?? {});
2836
+ const result = this.parseToolOutput(serialized);
2837
+ const finishedAt = /* @__PURE__ */ new Date();
2838
+ await ctx.nodeState?.markCompleted({
2839
+ nodeId: plannedToolCall.nodeId,
2840
+ activationId: ctx.activationId,
2841
+ inputsByPort: toolCallInputsByPort,
2842
+ outputs: AgentOutputFactory.fromUnknown(result)
2843
+ });
2844
+ await span.attachArtifact({
2845
+ kind: "tool.input",
2846
+ contentType: "application/json",
2847
+ previewJson: this.toJsonValue(plannedToolCall.toolCall.input)
2848
+ });
2849
+ await span.attachArtifact({
2850
+ kind: "tool.output",
2851
+ contentType: "application/json",
2852
+ previewJson: this.toJsonValue(result)
2853
+ });
2854
+ await span.end({
2855
+ status: "ok",
2856
+ endedAt: finishedAt
2857
+ });
2858
+ await ctx.nodeState?.appendConnectionInvocation({
2859
+ invocationId,
2860
+ connectionNodeId: plannedToolCall.nodeId,
2861
+ parentAgentNodeId: ctx.nodeId,
2862
+ parentAgentActivationId: ctx.activationId,
2863
+ status: "completed",
2864
+ managedInput: this.toJsonValue(plannedToolCall.toolCall.input),
2865
+ managedOutput: this.toJsonValue(result),
2866
+ queuedAt: startedAt.toISOString(),
2867
+ startedAt: startedAt.toISOString(),
2868
+ finishedAt: finishedAt.toISOString()
2869
+ });
2870
+ return {
2871
+ toolName: plannedToolCall.binding.config.name,
2872
+ toolCallId: plannedToolCall.toolCall.id ?? plannedToolCall.binding.config.name,
2873
+ serialized: typeof serialized === "string" ? serialized : JSON.stringify(serialized),
2874
+ result
2875
+ };
2876
+ } catch (error) {
2877
+ const classification = this.errorClassifier.classify({
2878
+ error,
2879
+ toolName: plannedToolCall.binding.config.name,
2880
+ schema: plannedToolCall.binding.langChainTool.schema
2881
+ });
2882
+ if (classification.kind !== "repairable_validation_error") {
2883
+ const effectiveError = classification.effectiveError;
2884
+ await this.recordFailedInvocation({
2885
+ invocationId,
2886
+ plannedToolCall,
2887
+ ctx,
2888
+ startedAt,
2889
+ inputsByPort: toolCallInputsByPort,
2890
+ managedInput: this.toJsonValue(plannedToolCall.toolCall.input),
2891
+ error: effectiveError
2892
+ });
2893
+ await span.attachArtifact({
2894
+ kind: "tool.input",
2895
+ contentType: "application/json",
2896
+ previewJson: this.toJsonValue(plannedToolCall.toolCall.input)
2897
+ });
2898
+ await span.end({
2899
+ status: "error",
2900
+ statusMessage: effectiveError.message,
2901
+ endedAt: /* @__PURE__ */ new Date()
2902
+ });
2903
+ throw effectiveError;
2904
+ }
2905
+ const repairDecision = this.repairPolicy.createDecision(plannedToolCall.binding.config.name, args.repairAttemptsByToolName);
2906
+ if (repairDecision.nextAction === "fail_agent_run") {
2907
+ const exhaustedError = new AgentToolRepairExhaustedError({
2908
+ agentName: args.agentName,
2909
+ nodeId: ctx.nodeId,
2910
+ toolName: plannedToolCall.binding.config.name,
2911
+ maxAttempts: repairDecision.maxAttempts,
2912
+ lastManagedInput: this.toJsonValue(plannedToolCall.toolCall.input),
2913
+ lastValidationIssues: classification.issues
2914
+ });
2915
+ await this.recordFailedInvocation({
2916
+ invocationId,
2917
+ plannedToolCall,
2918
+ ctx,
2919
+ startedAt,
2920
+ inputsByPort: toolCallInputsByPort,
2921
+ managedInput: this.toJsonValue(plannedToolCall.toolCall.input),
2922
+ error: exhaustedError,
2923
+ errorDetails: exhaustedError.details
2924
+ });
2925
+ await span.attachArtifact({
2926
+ kind: "tool.input",
2927
+ contentType: "application/json",
2928
+ previewJson: this.toJsonValue(plannedToolCall.toolCall.input)
2929
+ });
2930
+ await span.attachArtifact({
2931
+ kind: "tool.error",
2932
+ contentType: "application/json",
2933
+ previewJson: exhaustedError.details
2934
+ });
2935
+ await span.end({
2936
+ status: "error",
2937
+ statusMessage: exhaustedError.message,
2938
+ endedAt: /* @__PURE__ */ new Date()
2939
+ });
2940
+ throw exhaustedError;
2941
+ }
2942
+ const repairPayload = this.createRepairPayload({
2943
+ toolName: plannedToolCall.binding.config.name,
2944
+ issues: classification.issues,
2945
+ requiredSchemaReminder: classification.requiredSchemaReminder
2946
+ });
2947
+ const repairDetails = this.createRepairDetails({
2948
+ toolName: plannedToolCall.binding.config.name,
2949
+ issues: classification.issues,
2950
+ requiredSchemaReminder: classification.requiredSchemaReminder,
2951
+ repairDecision
2952
+ });
2953
+ await this.recordFailedInvocation({
2954
+ invocationId,
2955
+ plannedToolCall,
2956
+ ctx,
2957
+ startedAt,
2958
+ inputsByPort: toolCallInputsByPort,
2959
+ managedInput: this.toJsonValue(plannedToolCall.toolCall.input),
2960
+ error: classification.effectiveError,
2961
+ errorDetails: repairDetails
2962
+ });
2963
+ await span.attachArtifact({
2964
+ kind: "tool.input",
2965
+ contentType: "application/json",
2966
+ previewJson: this.toJsonValue(plannedToolCall.toolCall.input)
2967
+ });
2968
+ await span.attachArtifact({
2969
+ kind: "tool.error",
2970
+ contentType: "application/json",
2971
+ previewJson: repairPayload
2972
+ });
2973
+ await span.end({
2974
+ status: "error",
2975
+ statusMessage: classification.effectiveError.message,
2976
+ endedAt: /* @__PURE__ */ new Date()
2977
+ });
2978
+ return {
2979
+ toolName: plannedToolCall.binding.config.name,
2980
+ toolCallId: plannedToolCall.toolCall.id ?? plannedToolCall.binding.config.name,
2981
+ serialized: JSON.stringify(repairPayload),
2982
+ result: repairPayload
2983
+ };
2984
+ }
2985
+ }
2986
+ async recordFailedInvocation(args) {
2987
+ const finishedAt = /* @__PURE__ */ new Date();
2988
+ await args.ctx.nodeState?.markFailed({
2989
+ nodeId: args.plannedToolCall.nodeId,
2990
+ activationId: args.ctx.activationId,
2991
+ inputsByPort: args.inputsByPort,
2992
+ error: args.error
2993
+ });
2994
+ await args.ctx.nodeState?.appendConnectionInvocation({
2995
+ invocationId: args.invocationId,
2996
+ connectionNodeId: args.plannedToolCall.nodeId,
2997
+ parentAgentNodeId: args.ctx.nodeId,
2998
+ parentAgentActivationId: args.ctx.activationId,
2999
+ status: "failed",
3000
+ managedInput: args.managedInput,
3001
+ error: {
3002
+ message: args.error.message,
3003
+ name: args.error.name,
3004
+ stack: args.error.stack,
3005
+ details: args.errorDetails ?? this.extractErrorDetails(args.error)
3006
+ },
3007
+ queuedAt: args.startedAt.toISOString(),
3008
+ startedAt: args.startedAt.toISOString(),
3009
+ finishedAt: finishedAt.toISOString()
3010
+ });
3011
+ }
3012
+ createRepairPayload(args) {
3013
+ const payload = {
3014
+ status: "error",
3015
+ errorType: "validation",
3016
+ toolName: args.toolName,
3017
+ message: this.createValidationMessage(args.toolName, args.issues),
3018
+ instruction: "Call the tool again with all required fields present and correctly typed."
3019
+ };
3020
+ if (args.requiredSchemaReminder !== void 0) payload["requiredSchemaReminder"] = args.requiredSchemaReminder;
3021
+ return payload;
3022
+ }
3023
+ createRepairDetails(args) {
3024
+ const details = {
3025
+ errorType: "validation",
3026
+ toolName: args.toolName,
3027
+ recoveryHint: "Call the same tool again with every required field present and correctly typed.",
3028
+ repair: {
3029
+ attempt: args.repairDecision.attempt,
3030
+ maxAttempts: args.repairDecision.maxAttempts,
3031
+ nextAction: args.repairDecision.nextAction
3032
+ }
3033
+ };
3034
+ if (args.issues && args.issues.length > 0) details["issues"] = args.issues.map((issue$1) => this.serializeIssue(issue$1));
3035
+ if (args.requiredSchemaReminder !== void 0) details["requiredSchemaReminder"] = args.requiredSchemaReminder;
3036
+ return details;
3037
+ }
3038
+ createValidationMessage(toolName, issues) {
3039
+ const firstIssue = issues?.[0];
3040
+ if (!firstIssue) return `Your previous tool call for "${toolName}" was invalid and did not match the expected schema.`;
3041
+ return `Your previous tool call for "${toolName}" was invalid because field "${firstIssue.path.length > 0 ? firstIssue.path.join(".") : "<root>"}" failed validation: ${firstIssue.message}`;
3042
+ }
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
+ toJsonValue(value) {
3052
+ if (value === void 0) return;
3053
+ return JSON.parse(JSON.stringify(value));
3054
+ }
3055
+ extractErrorDetails(error) {
3056
+ return error.details;
3057
+ }
3058
+ serializeIssue(issue$1) {
3059
+ const result = {
3060
+ path: [...issue$1.path],
3061
+ code: issue$1.code,
3062
+ message: issue$1.message
3063
+ };
3064
+ if (issue$1.expected !== void 0) result["expected"] = issue$1.expected;
3065
+ if (issue$1.received !== void 0) result["received"] = issue$1.received;
3066
+ return result;
3067
+ }
3068
+ };
3069
+ AgentToolExecutionCoordinator = __decorate([
3070
+ injectable(),
3071
+ __decorateParam(0, inject(AgentToolErrorClassifier)),
3072
+ __decorateParam(1, inject(AgentToolRepairPolicy)),
3073
+ __decorateMetadata("design:paramtypes", [typeof (_ref$2 = typeof AgentToolErrorClassifier !== "undefined" && AgentToolErrorClassifier) === "function" ? _ref$2 : Object, typeof (_ref2$2 = typeof AgentToolRepairPolicy !== "undefined" && AgentToolRepairPolicy) === "function" ? _ref2$2 : Object])
3074
+ ], AgentToolExecutionCoordinator);
3075
+
2689
3076
  //#endregion
2690
3077
  //#region src/nodes/NodeBackedToolRuntime.ts
2691
3078
  var _ref$1, _ref2$1, _ref3$1;
@@ -2776,7 +3163,7 @@ var AgentItemPortMap = class {
2776
3163
 
2777
3164
  //#endregion
2778
3165
  //#region src/nodes/AIAgentNode.ts
2779
- var _ref, _ref2, _ref3;
3166
+ var _ref, _ref2, _ref3, _ref4;
2780
3167
  let AIAgentNode = class AIAgentNode$1 {
2781
3168
  kind = "node";
2782
3169
  outputPorts = ["main"];
@@ -2789,11 +3176,12 @@ let AIAgentNode = class AIAgentNode$1 {
2789
3176
  connectionCredentialExecutionContextFactory;
2790
3177
  /** One resolved model/tools bundle per activation context (same ctx across items in a batch). */
2791
3178
  preparedByExecutionContext = /* @__PURE__ */ new WeakMap();
2792
- constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner) {
3179
+ constructor(nodeResolver, credentialSessions, nodeBackedToolRuntime, executionHelpers, structuredOutputRunner, toolExecutionCoordinator) {
2793
3180
  this.nodeResolver = nodeResolver;
2794
3181
  this.nodeBackedToolRuntime = nodeBackedToolRuntime;
2795
3182
  this.executionHelpers = executionHelpers;
2796
3183
  this.structuredOutputRunner = structuredOutputRunner;
3184
+ this.toolExecutionCoordinator = toolExecutionCoordinator;
2797
3185
  this.connectionCredentialExecutionContextFactory = this.executionHelpers.createConnectionCredentialExecutionContextFactory(credentialSessions);
2798
3186
  }
2799
3187
  async execute(args) {
@@ -2856,17 +3244,33 @@ let AIAgentNode = class AIAgentNode$1 {
2856
3244
  invokeTextModel: async (messages) => await this.invokeModel(prepared.model, prepared.languageModelConnectionNodeId, messages, ctx, itemInputsByPort, prepared.guardrails.modelInvocationOptions),
2857
3245
  invokeStructuredModel: async (structuredModel, messages) => await this.invokeStructuredModel(structuredModel, prepared.languageModelConnectionNodeId, messages, ctx, itemInputsByPort, prepared.guardrails.modelInvocationOptions)
2858
3246
  });
3247
+ await ctx.telemetry.recordMetric({
3248
+ name: CodemationTelemetryMetricNames.agentTurns,
3249
+ value: 1
3250
+ });
3251
+ await ctx.telemetry.recordMetric({
3252
+ name: CodemationTelemetryMetricNames.agentToolCalls,
3253
+ value: 0
3254
+ });
2859
3255
  return this.buildOutputItem(item, structuredOutput);
2860
3256
  }
2861
3257
  const modelWithTools = this.bindToolsToModel(prepared.model, itemScopedTools);
2862
- const finalResponse = await this.runTurnLoopUntilFinalAnswer({
3258
+ const loopResult = await this.runTurnLoopUntilFinalAnswer({
2863
3259
  prepared,
2864
3260
  itemInputsByPort,
2865
3261
  itemScopedTools,
2866
3262
  conversation,
2867
3263
  modelWithTools
2868
3264
  });
2869
- const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, finalResponse, itemScopedTools.length > 0);
3265
+ await ctx.telemetry.recordMetric({
3266
+ name: CodemationTelemetryMetricNames.agentTurns,
3267
+ value: loopResult.turnCount
3268
+ });
3269
+ await ctx.telemetry.recordMetric({
3270
+ name: CodemationTelemetryMetricNames.agentToolCalls,
3271
+ value: loopResult.toolCallCount
3272
+ });
3273
+ const outputJson = await this.resolveFinalOutputJson(prepared, itemInputsByPort, conversation, loopResult.finalResponse, itemScopedTools.length > 0);
2870
3274
  return this.buildOutputItem(item, outputJson);
2871
3275
  }
2872
3276
  /**
@@ -2876,7 +3280,11 @@ let AIAgentNode = class AIAgentNode$1 {
2876
3280
  const { prepared, itemInputsByPort, itemScopedTools, conversation, modelWithTools } = args;
2877
3281
  const { ctx, guardrails, languageModelConnectionNodeId } = prepared;
2878
3282
  let finalResponse;
3283
+ let toolCallCount = 0;
3284
+ let turnCount = 0;
3285
+ const repairAttemptsByToolName = /* @__PURE__ */ new Map();
2879
3286
  for (let turn = 1; turn <= guardrails.maxTurns; turn++) {
3287
+ turnCount = turn;
2880
3288
  const response = await this.invokeModel(modelWithTools, languageModelConnectionNodeId, conversation, ctx, itemInputsByPort, guardrails.modelInvocationOptions);
2881
3289
  finalResponse = response;
2882
3290
  const toolCalls = AgentMessageFactory.extractToolCalls(response);
@@ -2886,12 +3294,22 @@ let AIAgentNode = class AIAgentNode$1 {
2886
3294
  break;
2887
3295
  }
2888
3296
  const plannedToolCalls = this.planToolCalls(itemScopedTools, toolCalls, ctx.nodeId);
3297
+ toolCallCount += plannedToolCalls.length;
2889
3298
  await this.markQueuedTools(plannedToolCalls, ctx);
2890
- const executedToolCalls = await this.executeToolCalls(plannedToolCalls, ctx);
3299
+ const executedToolCalls = await this.toolExecutionCoordinator.execute({
3300
+ plannedToolCalls,
3301
+ ctx,
3302
+ agentName: this.getAgentDisplayName(ctx),
3303
+ repairAttemptsByToolName
3304
+ });
2891
3305
  this.appendAssistantAndToolMessages(conversation, response, executedToolCalls);
2892
3306
  }
2893
3307
  if (!finalResponse) throw new Error(`AIAgent "${ctx.config.name ?? ctx.nodeId}" did not produce a model response.`);
2894
- return finalResponse;
3308
+ return {
3309
+ finalResponse,
3310
+ turnCount,
3311
+ toolCallCount
3312
+ };
2895
3313
  }
2896
3314
  cannotExecuteAnotherToolRound(turn, guardrails) {
2897
3315
  return turn >= guardrails.maxTurns;
@@ -2950,6 +3368,10 @@ let AIAgentNode = class AIAgentNode$1 {
2950
3368
  });
2951
3369
  }
2952
3370
  async invokeModel(model, nodeId, messages, ctx, inputsByPort, options) {
3371
+ const invocationId = ConnectionInvocationIdFactory.create();
3372
+ const startedAt = /* @__PURE__ */ new Date();
3373
+ const summarizedInput = this.summarizeLlmMessages(messages);
3374
+ const span = this.createModelInvocationSpan(ctx, invocationId, startedAt);
2953
3375
  await ctx.nodeState?.markQueued({
2954
3376
  nodeId,
2955
3377
  activationId: ctx.activationId,
@@ -2962,6 +3384,7 @@ let AIAgentNode = class AIAgentNode$1 {
2962
3384
  });
2963
3385
  try {
2964
3386
  const response = await model.invoke(messages, options);
3387
+ const finishedAt = /* @__PURE__ */ new Date();
2965
3388
  await ctx.nodeState?.markCompleted({
2966
3389
  nodeId,
2967
3390
  activationId: ctx.activationId,
@@ -2969,22 +3392,56 @@ let AIAgentNode = class AIAgentNode$1 {
2969
3392
  outputs: AgentOutputFactory.fromUnknown({ content: AgentMessageFactory.extractContent(response) })
2970
3393
  });
2971
3394
  const content = AgentMessageFactory.extractContent(response);
3395
+ await span.attachArtifact({
3396
+ kind: "ai.messages",
3397
+ contentType: "application/json",
3398
+ previewJson: summarizedInput
3399
+ });
3400
+ await span.attachArtifact({
3401
+ kind: "ai.response",
3402
+ contentType: "application/json",
3403
+ previewJson: content
3404
+ });
3405
+ await this.recordModelUsageMetrics(span, response, ctx);
3406
+ await span.end({
3407
+ status: "ok",
3408
+ endedAt: finishedAt
3409
+ });
2972
3410
  await ctx.nodeState?.appendConnectionInvocation({
2973
- invocationId: ConnectionInvocationIdFactory.create(),
3411
+ invocationId,
2974
3412
  connectionNodeId: nodeId,
2975
3413
  parentAgentNodeId: ctx.nodeId,
2976
3414
  parentAgentActivationId: ctx.activationId,
2977
3415
  status: "completed",
2978
- managedInput: this.summarizeLlmMessages(messages),
3416
+ managedInput: summarizedInput,
2979
3417
  managedOutput: content,
2980
- finishedAt: (/* @__PURE__ */ new Date()).toISOString()
3418
+ queuedAt: startedAt.toISOString(),
3419
+ startedAt: startedAt.toISOString(),
3420
+ finishedAt: finishedAt.toISOString()
2981
3421
  });
2982
3422
  return response;
2983
3423
  } catch (error) {
2984
- throw await this.failTrackedNodeInvocation(error, nodeId, ctx, inputsByPort, this.summarizeLlmMessages(messages));
3424
+ await span.end({
3425
+ status: "error",
3426
+ statusMessage: error instanceof Error ? error.message : String(error),
3427
+ endedAt: /* @__PURE__ */ new Date()
3428
+ });
3429
+ throw await this.failTrackedNodeInvocation({
3430
+ error,
3431
+ invocationId,
3432
+ startedAt,
3433
+ nodeId,
3434
+ ctx,
3435
+ inputsByPort,
3436
+ managedInput: this.summarizeLlmMessages(messages)
3437
+ });
2985
3438
  }
2986
3439
  }
2987
3440
  async invokeStructuredModel(model, nodeId, messages, ctx, inputsByPort, options) {
3441
+ const invocationId = ConnectionInvocationIdFactory.create();
3442
+ const startedAt = /* @__PURE__ */ new Date();
3443
+ const summarizedInput = this.summarizeLlmMessages(messages);
3444
+ const span = this.createModelInvocationSpan(ctx, invocationId, startedAt);
2988
3445
  await ctx.nodeState?.markQueued({
2989
3446
  nodeId,
2990
3447
  activationId: ctx.activationId,
@@ -2997,27 +3454,174 @@ let AIAgentNode = class AIAgentNode$1 {
2997
3454
  });
2998
3455
  try {
2999
3456
  const response = await model.invoke(messages, options);
3457
+ const finishedAt = /* @__PURE__ */ new Date();
3000
3458
  await ctx.nodeState?.markCompleted({
3001
3459
  nodeId,
3002
3460
  activationId: ctx.activationId,
3003
3461
  inputsByPort,
3004
3462
  outputs: AgentOutputFactory.fromUnknown(response)
3005
3463
  });
3464
+ await span.attachArtifact({
3465
+ kind: "ai.messages",
3466
+ contentType: "application/json",
3467
+ previewJson: summarizedInput
3468
+ });
3469
+ await span.attachArtifact({
3470
+ kind: "ai.response.structured",
3471
+ contentType: "application/json",
3472
+ previewJson: this.resultToJsonValue(response)
3473
+ });
3474
+ await this.recordModelUsageMetrics(span, response, ctx);
3475
+ await span.end({
3476
+ status: "ok",
3477
+ endedAt: finishedAt
3478
+ });
3006
3479
  await ctx.nodeState?.appendConnectionInvocation({
3007
- invocationId: ConnectionInvocationIdFactory.create(),
3480
+ invocationId,
3008
3481
  connectionNodeId: nodeId,
3009
3482
  parentAgentNodeId: ctx.nodeId,
3010
3483
  parentAgentActivationId: ctx.activationId,
3011
3484
  status: "completed",
3012
- managedInput: this.summarizeLlmMessages(messages),
3485
+ managedInput: summarizedInput,
3013
3486
  managedOutput: this.resultToJsonValue(response),
3014
- finishedAt: (/* @__PURE__ */ new Date()).toISOString()
3487
+ queuedAt: startedAt.toISOString(),
3488
+ startedAt: startedAt.toISOString(),
3489
+ finishedAt: finishedAt.toISOString()
3015
3490
  });
3016
3491
  return response;
3017
3492
  } catch (error) {
3018
- throw await this.failTrackedNodeInvocation(error, nodeId, ctx, inputsByPort, this.summarizeLlmMessages(messages));
3493
+ await span.end({
3494
+ status: "error",
3495
+ statusMessage: error instanceof Error ? error.message : String(error),
3496
+ endedAt: /* @__PURE__ */ new Date()
3497
+ });
3498
+ throw await this.failTrackedNodeInvocation({
3499
+ error,
3500
+ invocationId,
3501
+ startedAt,
3502
+ nodeId,
3503
+ ctx,
3504
+ inputsByPort,
3505
+ managedInput: this.summarizeLlmMessages(messages)
3506
+ });
3019
3507
  }
3020
3508
  }
3509
+ createModelInvocationSpan(ctx, invocationId, startedAt) {
3510
+ return ctx.telemetry.startChildSpan({
3511
+ name: "gen_ai.chat.completion",
3512
+ kind: "client",
3513
+ startedAt,
3514
+ attributes: {
3515
+ [CodemationTelemetryAttributeNames.connectionInvocationId]: invocationId,
3516
+ [GenAiTelemetryAttributeNames.operationName]: "chat",
3517
+ [GenAiTelemetryAttributeNames.requestModel]: this.resolveChatModelName(ctx.config.chatModel)
3518
+ }
3519
+ });
3520
+ }
3521
+ async recordModelUsageMetrics(span, response, ctx) {
3522
+ const usage = this.extractModelUsageMetrics(response);
3523
+ for (const [name, value] of Object.entries(usage)) {
3524
+ if (value === void 0) continue;
3525
+ await span.recordMetric({
3526
+ name,
3527
+ value
3528
+ });
3529
+ }
3530
+ await this.captureCostTrackingUsage(span, ctx, usage);
3531
+ }
3532
+ async captureCostTrackingUsage(span, ctx, usage) {
3533
+ const costTracking = span.costTracking;
3534
+ if (!costTracking) return;
3535
+ const provider = ctx.config.chatModel.provider;
3536
+ const pricingKey = ctx.config.chatModel.modelName;
3537
+ if (!provider || !pricingKey) return;
3538
+ const inputTokens = usage[GenAiTelemetryAttributeNames.usageInputTokens];
3539
+ const outputTokens = usage[GenAiTelemetryAttributeNames.usageOutputTokens];
3540
+ if (inputTokens !== void 0) await costTracking.captureUsage({
3541
+ component: "chat",
3542
+ provider,
3543
+ operation: "completion.input",
3544
+ pricingKey,
3545
+ usageUnit: "input_tokens",
3546
+ quantity: inputTokens,
3547
+ modelName: pricingKey
3548
+ });
3549
+ if (outputTokens !== void 0) await costTracking.captureUsage({
3550
+ component: "chat",
3551
+ provider,
3552
+ operation: "completion.output",
3553
+ pricingKey,
3554
+ usageUnit: "output_tokens",
3555
+ quantity: outputTokens,
3556
+ modelName: pricingKey
3557
+ });
3558
+ }
3559
+ resolveChatModelName(chatModel$1) {
3560
+ return chatModel$1.modelName ?? chatModel$1.name;
3561
+ }
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
+ }
3021
3625
  async markQueuedTools(plannedToolCalls, ctx) {
3022
3626
  for (const plannedToolCall of plannedToolCalls) await ctx.nodeState?.markQueued({
3023
3627
  nodeId: plannedToolCall.nodeId,
@@ -3025,47 +3629,6 @@ let AIAgentNode = class AIAgentNode$1 {
3025
3629
  inputsByPort: AgentToolCallPortMap.fromInput(plannedToolCall.toolCall.input ?? {})
3026
3630
  });
3027
3631
  }
3028
- async executeToolCalls(plannedToolCalls, ctx) {
3029
- const results = await Promise.allSettled(plannedToolCalls.map(async (plannedToolCall) => {
3030
- const toolCallInputsByPort = AgentToolCallPortMap.fromInput(plannedToolCall.toolCall.input ?? {});
3031
- await ctx.nodeState?.markRunning({
3032
- nodeId: plannedToolCall.nodeId,
3033
- activationId: ctx.activationId,
3034
- inputsByPort: toolCallInputsByPort
3035
- });
3036
- try {
3037
- const serialized = await plannedToolCall.binding.langChainTool.invoke(plannedToolCall.toolCall.input ?? {});
3038
- const result = this.parseToolOutput(serialized);
3039
- await ctx.nodeState?.markCompleted({
3040
- nodeId: plannedToolCall.nodeId,
3041
- activationId: ctx.activationId,
3042
- inputsByPort: toolCallInputsByPort,
3043
- outputs: AgentOutputFactory.fromUnknown(result)
3044
- });
3045
- await ctx.nodeState?.appendConnectionInvocation({
3046
- invocationId: ConnectionInvocationIdFactory.create(),
3047
- connectionNodeId: plannedToolCall.nodeId,
3048
- parentAgentNodeId: ctx.nodeId,
3049
- parentAgentActivationId: ctx.activationId,
3050
- status: "completed",
3051
- managedInput: this.toolCallInputToJson(plannedToolCall.toolCall.input),
3052
- managedOutput: this.resultToJsonValue(result),
3053
- finishedAt: (/* @__PURE__ */ new Date()).toISOString()
3054
- });
3055
- return {
3056
- toolName: plannedToolCall.binding.config.name,
3057
- toolCallId: plannedToolCall.toolCall.id ?? plannedToolCall.binding.config.name,
3058
- serialized,
3059
- result
3060
- };
3061
- } catch (error) {
3062
- throw await this.failTrackedNodeInvocation(error, plannedToolCall.nodeId, ctx, toolCallInputsByPort, this.toolCallInputToJson(plannedToolCall.toolCall.input));
3063
- }
3064
- }));
3065
- const rejected = results.find((result) => result.status === "rejected");
3066
- if (rejected?.status === "rejected") throw rejected.reason instanceof Error ? rejected.reason : new Error(String(rejected.reason));
3067
- return results.filter((result) => result.status === "fulfilled").map((result) => result.value);
3068
- }
3069
3632
  planToolCalls(bindings, toolCalls, parentNodeId) {
3070
3633
  const invocationCountByToolName = /* @__PURE__ */ new Map();
3071
3634
  return toolCalls.map((toolCall) => {
@@ -3081,35 +3644,31 @@ let AIAgentNode = class AIAgentNode$1 {
3081
3644
  };
3082
3645
  });
3083
3646
  }
3084
- parseToolOutput(serialized) {
3085
- if (typeof serialized !== "string") return serialized;
3086
- try {
3087
- return JSON.parse(serialized);
3088
- } catch {
3089
- return serialized;
3090
- }
3091
- }
3092
- async failTrackedNodeInvocation(error, nodeId, ctx, inputsByPort, managedInput) {
3093
- const effectiveError = error instanceof Error ? error : new Error(String(error));
3094
- await ctx.nodeState?.markFailed({
3095
- nodeId,
3096
- activationId: ctx.activationId,
3097
- inputsByPort,
3647
+ async failTrackedNodeInvocation(args) {
3648
+ const effectiveError = args.error instanceof Error ? args.error : new Error(String(args.error));
3649
+ const finishedAt = /* @__PURE__ */ new Date();
3650
+ await args.ctx.nodeState?.markFailed({
3651
+ nodeId: args.nodeId,
3652
+ activationId: args.ctx.activationId,
3653
+ inputsByPort: args.inputsByPort,
3098
3654
  error: effectiveError
3099
3655
  });
3100
- await ctx.nodeState?.appendConnectionInvocation({
3101
- invocationId: ConnectionInvocationIdFactory.create(),
3102
- connectionNodeId: nodeId,
3103
- parentAgentNodeId: ctx.nodeId,
3104
- parentAgentActivationId: ctx.activationId,
3656
+ await args.ctx.nodeState?.appendConnectionInvocation({
3657
+ invocationId: args.invocationId,
3658
+ connectionNodeId: args.nodeId,
3659
+ parentAgentNodeId: args.ctx.nodeId,
3660
+ parentAgentActivationId: args.ctx.activationId,
3105
3661
  status: "failed",
3106
- managedInput,
3662
+ managedInput: args.managedInput,
3107
3663
  error: {
3108
3664
  message: effectiveError.message,
3109
3665
  name: effectiveError.name,
3110
- stack: effectiveError.stack
3666
+ stack: effectiveError.stack,
3667
+ details: this.extractErrorDetails(effectiveError)
3111
3668
  },
3112
- finishedAt: (/* @__PURE__ */ new Date()).toISOString()
3669
+ queuedAt: args.startedAt.toISOString(),
3670
+ startedAt: args.startedAt.toISOString(),
3671
+ finishedAt: finishedAt.toISOString()
3113
3672
  });
3114
3673
  return effectiveError;
3115
3674
  }
@@ -3121,9 +3680,6 @@ let AIAgentNode = class AIAgentNode$1 {
3121
3680
  lastMessagePreview: preview.slice(0, 4e3)
3122
3681
  };
3123
3682
  }
3124
- toolCallInputToJson(input) {
3125
- return this.resultToJsonValue(input);
3126
- }
3127
3683
  resultToJsonValue(value) {
3128
3684
  if (value === void 0) return;
3129
3685
  const json = JSON.stringify(value);
@@ -3193,6 +3749,9 @@ let AIAgentNode = class AIAgentNode$1 {
3193
3749
  getAgentDisplayName(ctx) {
3194
3750
  return ctx.config.name ?? ctx.nodeId;
3195
3751
  }
3752
+ extractErrorDetails(error) {
3753
+ return error.details;
3754
+ }
3196
3755
  };
3197
3756
  AIAgentNode = __decorate([
3198
3757
  node({ packageName: "@codemation/core-nodes" }),
@@ -3201,12 +3760,14 @@ AIAgentNode = __decorate([
3201
3760
  __decorateParam(2, inject(NodeBackedToolRuntime)),
3202
3761
  __decorateParam(3, inject(AIAgentExecutionHelpersFactory)),
3203
3762
  __decorateParam(4, inject(AgentStructuredOutputRunner)),
3763
+ __decorateParam(5, inject(AgentToolExecutionCoordinator)),
3204
3764
  __decorateMetadata("design:paramtypes", [
3205
3765
  Object,
3206
3766
  Object,
3207
3767
  typeof (_ref = typeof NodeBackedToolRuntime !== "undefined" && NodeBackedToolRuntime) === "function" ? _ref : Object,
3208
3768
  typeof (_ref2 = typeof AIAgentExecutionHelpersFactory !== "undefined" && AIAgentExecutionHelpersFactory) === "function" ? _ref2 : Object,
3209
- typeof (_ref3 = typeof AgentStructuredOutputRunner !== "undefined" && AgentStructuredOutputRunner) === "function" ? _ref3 : Object
3769
+ typeof (_ref3 = typeof AgentStructuredOutputRunner !== "undefined" && AgentStructuredOutputRunner) === "function" ? _ref3 : Object,
3770
+ typeof (_ref4 = typeof AgentToolExecutionCoordinator !== "undefined" && AgentToolExecutionCoordinator) === "function" ? _ref4 : Object
3210
3771
  ])
3211
3772
  ], AIAgentNode);
3212
3773
 
@@ -4263,5 +4824,5 @@ var ConnectionCredentialNodeConfigFactory = class {
4263
4824
  };
4264
4825
 
4265
4826
  //#endregion
4266
- export { AIAgent, AIAgentConnectionWorkflowExpander, AIAgentExecutionHelpersFactory, AIAgentNode, AgentItemPortMap, AgentMessageFactory, AgentOutputFactory, AgentStructuredOutputRepairPromptFactory, AgentStructuredOutputRunner, AgentToolCallPortMap, 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 };
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 };
4267
4828
  //# sourceMappingURL=index.js.map