@limo-labs/deity 0.3.0-alpha.0 → 0.3.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ZodSchema, z } from 'zod';
2
- import { V as Validator, T as ToolSpec, A as AgentNode, P as PromptNode, E as ExecutionContext$1, S as SystemNode, U as UserNode, L as LLMLoopResult, O as ObserveNode, R as ResultNode, a as ValidationRules, b as ValidateNode, c as RetryNode, d as ToolDefNode, e as ToolsNode, f as ToolRefNode, W as WorkflowChildNode, g as WorkflowSequenceNode, h as WorkflowParallelNode, i as WorkflowConditionalNode, j as WorkflowLoopNode, k as WorkflowForEachNode, l as WorkflowNode, m as AgentComponent, n as WorkflowConfig, o as ExecutionNode, p as ASTNode, M as Message, q as ValidationResult$1, r as LLMAdapter$1, G as GenerationConfig$1, s as StateStore$1, t as TraceLogger, u as TraceEntry, v as ExecutionStats, C as ConversationManager, w as LimoMemoryManager, x as UIUpdateBridge, y as SessionStore, z as ConversationConfig, B as MemoryConfig, D as SessionConfig } from './jsx-dev-runtime-BQMsrQII.cjs';
3
- export { J as JSXComponent, F as JSXElementType, H as JSXProps, I as LLMLoopState, K as LLMResponse, N as MessageRole, Q as TemplatePart, X as ToolCall, Y as ToolResult, Z as ValidationRule, _ as isAgentNode, $ as isObserveNode, a0 as isPromptNode, a1 as isResultNode, a2 as isRetryNode, a3 as isSystemNode, a4 as isToolDefNode, a5 as isToolRefNode, a6 as isToolsNode, a7 as isUserNode, a8 as isValidateNode, a9 as isWorkflowConditionalNode, aa as isWorkflowForEachNode, ab as isWorkflowLoopNode, ac as isWorkflowNode, ad as isWorkflowParallelNode, ae as isWorkflowSequenceNode } from './jsx-dev-runtime-BQMsrQII.cjs';
2
+ import { V as Validator, T as ToolSpec, A as AgentNode, P as PromptNode, E as ExecutionContext$1, S as SystemNode, U as UserNode, L as LLMLoopResult, O as ObserveNode, R as ResultNode, a as ValidationRules, b as ValidateNode, c as RetryNode, d as ToolDefNode, e as ToolsNode, f as ToolRefNode, W as WorkflowChildNode, g as WorkflowSequenceNode, h as WorkflowParallelNode, i as WorkflowConditionalNode, j as WorkflowLoopNode, k as WorkflowForEachNode, l as WorkflowNode, m as AgentComponent, n as WorkflowConfig, o as ExecutionNode, p as ASTNode, M as Message, q as ValidationResult$1, r as LLMAdapter$1, G as GenerationConfig$1, s as StateStore$1, t as TraceLogger, u as TraceEntry, v as ExecutionStats, C as ConversationManager, w as LimoMemoryManager, x as UIUpdateBridge, y as SessionStore, z as ConversationConfig, B as MemoryConfig, D as SessionConfig } from './jsx-dev-runtime-CCicXopP.cjs';
3
+ export { J as JSXComponent, F as JSXElementType, H as JSXProps, I as LLMLoopState, K as LLMResponse, N as MessageRole, Q as TemplatePart, X as ToolCall, Y as ToolResult, Z as ValidationRule, _ as isAgentNode, $ as isObserveNode, a0 as isPromptNode, a1 as isResultNode, a2 as isRetryNode, a3 as isSystemNode, a4 as isToolDefNode, a5 as isToolRefNode, a6 as isToolsNode, a7 as isUserNode, a8 as isValidateNode, a9 as isWorkflowConditionalNode, aa as isWorkflowForEachNode, ab as isWorkflowLoopNode, ac as isWorkflowNode, ad as isWorkflowParallelNode, ae as isWorkflowSequenceNode } from './jsx-dev-runtime-CCicXopP.cjs';
4
4
 
5
5
  /**
6
6
  * Deity TSX - Agent Component
@@ -27,6 +27,8 @@ interface AgentProps<I = unknown, O = unknown> {
27
27
  input: ZodSchema<I>;
28
28
  /** Output schema (Zod) */
29
29
  output: ZodSchema<O>;
30
+ /** Agent execution mode: 'llm' (default) calls LLM, 'pure' runs code only */
31
+ mode?: 'llm' | 'pure';
30
32
  /** Optional description */
31
33
  description?: string;
32
34
  /** Optional tags for categorization */
@@ -37,8 +39,6 @@ interface AgentProps<I = unknown, O = unknown> {
37
39
  loopConfig?: LLMLoopConfig$1;
38
40
  /** Optional tool definitions (backward compatible - can also use <Tools> child) */
39
41
  tools?: ToolSpec[];
40
- /** Execution mode: 'llm' (default) requires LLM adapter, 'pure' skips LLM */
41
- mode?: 'llm' | 'pure';
42
42
  /** Child components (Tools, Prompt, Observe, Result, Validate, Retry) */
43
43
  children?: any[];
44
44
  }
@@ -2229,6 +2229,14 @@ declare function setResourceLoader(loader: PromptResourceLoader): void;
2229
2229
  * - Observe Testing: Test observation logic with mock data
2230
2230
  */
2231
2231
 
2232
+ /**
2233
+ * Empty LLM result for testing pure-mode agents.
2234
+ *
2235
+ * Pure-mode agents don't call LLM, but their extractOutput function
2236
+ * still receives an LLMLoopResult. This constant provides a minimal
2237
+ * empty result for use in tests.
2238
+ */
2239
+ declare const EMPTY_LLM_RESULT: LLMLoopResult;
2232
2240
  /**
2233
2241
  * Full Agent Test Options
2234
2242
  */
@@ -2390,10 +2398,6 @@ interface RetryExecutionResult<O> {
2390
2398
  * Orchestrates AgentComponent execution
2391
2399
  */
2392
2400
 
2393
- /**
2394
- * Empty LLM loop result for pure-function agents that skip LLM execution
2395
- */
2396
- declare const EMPTY_LLM_RESULT: LLMLoopResult;
2397
2401
  /**
2398
2402
  * Result from component execution
2399
2403
  */
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ZodSchema, z } from 'zod';
2
- import { V as Validator, T as ToolSpec, A as AgentNode, P as PromptNode, E as ExecutionContext$1, S as SystemNode, U as UserNode, L as LLMLoopResult, O as ObserveNode, R as ResultNode, a as ValidationRules, b as ValidateNode, c as RetryNode, d as ToolDefNode, e as ToolsNode, f as ToolRefNode, W as WorkflowChildNode, g as WorkflowSequenceNode, h as WorkflowParallelNode, i as WorkflowConditionalNode, j as WorkflowLoopNode, k as WorkflowForEachNode, l as WorkflowNode, m as AgentComponent, n as WorkflowConfig, o as ExecutionNode, p as ASTNode, M as Message, q as ValidationResult$1, r as LLMAdapter$1, G as GenerationConfig$1, s as StateStore$1, t as TraceLogger, u as TraceEntry, v as ExecutionStats, C as ConversationManager, w as LimoMemoryManager, x as UIUpdateBridge, y as SessionStore, z as ConversationConfig, B as MemoryConfig, D as SessionConfig } from './jsx-dev-runtime-BQMsrQII.js';
3
- export { J as JSXComponent, F as JSXElementType, H as JSXProps, I as LLMLoopState, K as LLMResponse, N as MessageRole, Q as TemplatePart, X as ToolCall, Y as ToolResult, Z as ValidationRule, _ as isAgentNode, $ as isObserveNode, a0 as isPromptNode, a1 as isResultNode, a2 as isRetryNode, a3 as isSystemNode, a4 as isToolDefNode, a5 as isToolRefNode, a6 as isToolsNode, a7 as isUserNode, a8 as isValidateNode, a9 as isWorkflowConditionalNode, aa as isWorkflowForEachNode, ab as isWorkflowLoopNode, ac as isWorkflowNode, ad as isWorkflowParallelNode, ae as isWorkflowSequenceNode } from './jsx-dev-runtime-BQMsrQII.js';
2
+ import { V as Validator, T as ToolSpec, A as AgentNode, P as PromptNode, E as ExecutionContext$1, S as SystemNode, U as UserNode, L as LLMLoopResult, O as ObserveNode, R as ResultNode, a as ValidationRules, b as ValidateNode, c as RetryNode, d as ToolDefNode, e as ToolsNode, f as ToolRefNode, W as WorkflowChildNode, g as WorkflowSequenceNode, h as WorkflowParallelNode, i as WorkflowConditionalNode, j as WorkflowLoopNode, k as WorkflowForEachNode, l as WorkflowNode, m as AgentComponent, n as WorkflowConfig, o as ExecutionNode, p as ASTNode, M as Message, q as ValidationResult$1, r as LLMAdapter$1, G as GenerationConfig$1, s as StateStore$1, t as TraceLogger, u as TraceEntry, v as ExecutionStats, C as ConversationManager, w as LimoMemoryManager, x as UIUpdateBridge, y as SessionStore, z as ConversationConfig, B as MemoryConfig, D as SessionConfig } from './jsx-dev-runtime-CCicXopP.js';
3
+ export { J as JSXComponent, F as JSXElementType, H as JSXProps, I as LLMLoopState, K as LLMResponse, N as MessageRole, Q as TemplatePart, X as ToolCall, Y as ToolResult, Z as ValidationRule, _ as isAgentNode, $ as isObserveNode, a0 as isPromptNode, a1 as isResultNode, a2 as isRetryNode, a3 as isSystemNode, a4 as isToolDefNode, a5 as isToolRefNode, a6 as isToolsNode, a7 as isUserNode, a8 as isValidateNode, a9 as isWorkflowConditionalNode, aa as isWorkflowForEachNode, ab as isWorkflowLoopNode, ac as isWorkflowNode, ad as isWorkflowParallelNode, ae as isWorkflowSequenceNode } from './jsx-dev-runtime-CCicXopP.js';
4
4
 
5
5
  /**
6
6
  * Deity TSX - Agent Component
@@ -27,6 +27,8 @@ interface AgentProps<I = unknown, O = unknown> {
27
27
  input: ZodSchema<I>;
28
28
  /** Output schema (Zod) */
29
29
  output: ZodSchema<O>;
30
+ /** Agent execution mode: 'llm' (default) calls LLM, 'pure' runs code only */
31
+ mode?: 'llm' | 'pure';
30
32
  /** Optional description */
31
33
  description?: string;
32
34
  /** Optional tags for categorization */
@@ -37,8 +39,6 @@ interface AgentProps<I = unknown, O = unknown> {
37
39
  loopConfig?: LLMLoopConfig$1;
38
40
  /** Optional tool definitions (backward compatible - can also use <Tools> child) */
39
41
  tools?: ToolSpec[];
40
- /** Execution mode: 'llm' (default) requires LLM adapter, 'pure' skips LLM */
41
- mode?: 'llm' | 'pure';
42
42
  /** Child components (Tools, Prompt, Observe, Result, Validate, Retry) */
43
43
  children?: any[];
44
44
  }
@@ -2229,6 +2229,14 @@ declare function setResourceLoader(loader: PromptResourceLoader): void;
2229
2229
  * - Observe Testing: Test observation logic with mock data
2230
2230
  */
2231
2231
 
2232
+ /**
2233
+ * Empty LLM result for testing pure-mode agents.
2234
+ *
2235
+ * Pure-mode agents don't call LLM, but their extractOutput function
2236
+ * still receives an LLMLoopResult. This constant provides a minimal
2237
+ * empty result for use in tests.
2238
+ */
2239
+ declare const EMPTY_LLM_RESULT: LLMLoopResult;
2232
2240
  /**
2233
2241
  * Full Agent Test Options
2234
2242
  */
@@ -2390,10 +2398,6 @@ interface RetryExecutionResult<O> {
2390
2398
  * Orchestrates AgentComponent execution
2391
2399
  */
2392
2400
 
2393
- /**
2394
- * Empty LLM loop result for pure-function agents that skip LLM execution
2395
- */
2396
- declare const EMPTY_LLM_RESULT: LLMLoopResult;
2397
2401
  /**
2398
2402
  * Result from component execution
2399
2403
  */
package/dist/index.js CHANGED
@@ -42,8 +42,8 @@ var init_compile_observe = __esm({
42
42
 
43
43
  // src/components/Agent.tsx
44
44
  function Agent(props) {
45
- const { id, input, output, description, tags, loopValidator, loopConfig, tools: propsTools, mode, children } = props;
46
- const resolvedMode = mode ?? "llm";
45
+ const { id, input, output, mode, description, tags, loopValidator, loopConfig, tools: propsTools, children } = props;
46
+ const isPure = mode === "pure";
47
47
  if (!id) {
48
48
  throw new Error("Agent: id is required");
49
49
  }
@@ -54,8 +54,8 @@ function Agent(props) {
54
54
  throw new Error("Agent: output schema is required");
55
55
  }
56
56
  if (!children || children.length === 0) {
57
- if (resolvedMode === "pure") {
58
- throw new Error("Agent: pure mode must have at least a Result child");
57
+ if (isPure) {
58
+ throw new Error("Agent: pure mode agent must have at least a Result child");
59
59
  }
60
60
  throw new Error("Agent: must have at least Prompt and Result children");
61
61
  }
@@ -63,10 +63,10 @@ function Agent(props) {
63
63
  const nonToolsChildren = children.filter((child) => child?.type !== "Tools");
64
64
  let prompt;
65
65
  let rest;
66
- if (resolvedMode === "pure") {
67
- const firstNonTools = nonToolsChildren[0];
68
- if (firstNonTools?.type === "Prompt") {
69
- prompt = firstNonTools;
66
+ if (isPure) {
67
+ const firstChild = nonToolsChildren[0];
68
+ if (firstChild?.type === "Prompt") {
69
+ prompt = firstChild;
70
70
  rest = nonToolsChildren.slice(1);
71
71
  } else {
72
72
  prompt = void 0;
@@ -101,12 +101,12 @@ function Agent(props) {
101
101
  id,
102
102
  input,
103
103
  output,
104
+ mode,
104
105
  description,
105
106
  tags,
106
107
  loopValidator,
107
108
  loopConfig,
108
- tools: mergedTools,
109
- mode: resolvedMode
109
+ tools: mergedTools
110
110
  },
111
111
  children: orderedChildren
112
112
  };
@@ -1071,13 +1071,13 @@ function compileAgent(ast) {
1071
1071
  if (!children || children.length === 0) {
1072
1072
  throw new Error("Agent must have children");
1073
1073
  }
1074
+ const isPure = ast.props.mode === "pure";
1074
1075
  const promptNode = children.find((n) => n?.type === "Prompt");
1075
1076
  const observeNode = children.find((n) => n?.type === "Observe");
1076
1077
  const resultNode = children.find((n) => n?.type === "Result");
1077
1078
  const validateNode = children.find((n) => n?.type === "Validate");
1078
1079
  const retryNode = children.find((n) => n?.type === "Retry");
1079
- const mode = ast.props.mode ?? "llm";
1080
- if (mode !== "pure" && !promptNode) {
1080
+ if (!isPure && !promptNode) {
1081
1081
  throw new Error("Agent must have a Prompt node");
1082
1082
  }
1083
1083
  if (!resultNode) {
@@ -1090,14 +1090,12 @@ function compileAgent(ast) {
1090
1090
  const retry = retryNode ? compileRetry(retryNode) : void 0;
1091
1091
  const component = {
1092
1092
  id: ast.props.id,
1093
+ mode: ast.props.mode,
1093
1094
  inputSchema: ast.props.input,
1094
1095
  outputSchema: ast.props.output,
1095
1096
  buildPrompt,
1096
1097
  extractOutput
1097
1098
  };
1098
- if (mode === "pure") {
1099
- component.mode = "pure";
1100
- }
1101
1099
  if (validateOutput) {
1102
1100
  component.validateOutput = validateOutput;
1103
1101
  }
@@ -1223,6 +1221,9 @@ function createLazyAgentComponent(astNode) {
1223
1221
  get id() {
1224
1222
  return astNode.props.id;
1225
1223
  },
1224
+ get mode() {
1225
+ return astNode.props.mode;
1226
+ },
1226
1227
  get inputSchema() {
1227
1228
  return astNode.props.input;
1228
1229
  },
@@ -1238,9 +1239,6 @@ function createLazyAgentComponent(astNode) {
1238
1239
  get loopConfig() {
1239
1240
  return astNode.props.loopConfig;
1240
1241
  },
1241
- get mode() {
1242
- return astNode.props.mode;
1243
- },
1244
1242
  // Lazy methods - compile on first call
1245
1243
  buildPrompt(ctx) {
1246
1244
  return ensureCompiled().buildPrompt(ctx);
@@ -2600,6 +2598,18 @@ var PreflightChecker = class {
2600
2598
  * Check agent structure
2601
2599
  */
2602
2600
  checkAgentStructure(agent, errors) {
2601
+ const isPure = agent.props.mode === "pure";
2602
+ if (isPure) {
2603
+ const resultNode2 = agent.children.find((n) => n?.type === "Result");
2604
+ if (!resultNode2) {
2605
+ errors.push({
2606
+ type: "invalid_structure",
2607
+ message: "Pure mode Agent must have a Result node",
2608
+ nodeType: "Agent"
2609
+ });
2610
+ }
2611
+ return;
2612
+ }
2603
2613
  const [promptNode, ...rest] = agent.children;
2604
2614
  if (!promptNode || promptNode.type !== "Prompt") {
2605
2615
  errors.push({
@@ -2699,6 +2709,13 @@ async function preflight(agent, options) {
2699
2709
  }
2700
2710
 
2701
2711
  // src/testing/test-utils.ts
2712
+ var EMPTY_LLM_RESULT = {
2713
+ response: { content: "", toolCalls: void 0 },
2714
+ messages: [],
2715
+ rounds: 0,
2716
+ toolCallsExecuted: 0,
2717
+ errors: []
2718
+ };
2702
2719
  async function runObserve(agent, options) {
2703
2720
  const observeNode = agent.children.find((n) => n?.type === "Observe");
2704
2721
  if (!observeNode) {
@@ -3360,13 +3377,6 @@ function parseComponentOutput(content, schema) {
3360
3377
  }
3361
3378
 
3362
3379
  // src/engine/executor.ts
3363
- var EMPTY_LLM_RESULT = {
3364
- response: { content: "" },
3365
- messages: [],
3366
- rounds: 0,
3367
- toolCallsExecuted: 0,
3368
- errors: []
3369
- };
3370
3380
  async function executeComponent(component, ctx, adapter, config) {
3371
3381
  const startTime = Date.now();
3372
3382
  const llmResults = [];
@@ -3376,6 +3386,73 @@ async function executeComponent(component, ctx, adapter, config) {
3376
3386
  stageId: component.id,
3377
3387
  timestamp: /* @__PURE__ */ new Date()
3378
3388
  });
3389
+ if (component.mode === "pure") {
3390
+ try {
3391
+ ctx.ui?.stepProgress(component.id, 50, "Executing pure agent...");
3392
+ const syntheticLLMResult = {
3393
+ response: { content: "", toolCalls: void 0 },
3394
+ messages: [],
3395
+ rounds: 0,
3396
+ toolCallsExecuted: 0,
3397
+ errors: []
3398
+ };
3399
+ let output;
3400
+ if (component.extractOutput) {
3401
+ const extracted = await Promise.resolve(component.extractOutput(ctx, syntheticLLMResult));
3402
+ const validation = component.outputSchema.safeParse(extracted);
3403
+ if (!validation.success) {
3404
+ const errors = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
3405
+ throw new Error(`Output validation failed: ${errors}`);
3406
+ }
3407
+ output = validation.data;
3408
+ } else {
3409
+ throw new Error("Pure mode agent must have an extractOutput (Result) function");
3410
+ }
3411
+ if (component.validateOutput) {
3412
+ const validationResult = await Promise.resolve(component.validateOutput(output, ctx));
3413
+ if (!validationResult.valid) {
3414
+ const errorMessages = validationResult.errors?.join("; ") ?? validationResult.feedback ?? "Validation failed";
3415
+ throw new Error(errorMessages);
3416
+ }
3417
+ }
3418
+ const duration2 = Date.now() - startTime;
3419
+ await ctx.trace.log({
3420
+ type: "stage_complete",
3421
+ output,
3422
+ timestamp: /* @__PURE__ */ new Date()
3423
+ });
3424
+ ctx.ui?.completeStep(
3425
+ component.id,
3426
+ `Completed (pure) in ${Math.round(duration2 / 1e3)}s`
3427
+ );
3428
+ return {
3429
+ output,
3430
+ success: true,
3431
+ attempts: 1,
3432
+ llmResults: [syntheticLLMResult],
3433
+ retryResult: {
3434
+ success: true,
3435
+ output,
3436
+ attempts: 1,
3437
+ errors: [],
3438
+ validationHistory: [],
3439
+ outputHistory: [output]
3440
+ },
3441
+ duration: duration2
3442
+ };
3443
+ } catch (error) {
3444
+ const errorMessage = error instanceof Error ? error.message : String(error);
3445
+ await ctx.trace.log({
3446
+ type: "stage_failed",
3447
+ error: errorMessage,
3448
+ timestamp: /* @__PURE__ */ new Date()
3449
+ });
3450
+ ctx.ui?.failStep(component.id, errorMessage);
3451
+ throw new Error(
3452
+ `Component ${component.id} (pure mode) failed: ${errorMessage}`
3453
+ );
3454
+ }
3455
+ }
3379
3456
  const retryResult = await executeWithRetry(
3380
3457
  component,
3381
3458
  ctx,
@@ -5067,13 +5144,14 @@ async function executeStepNode(node, ctx, adapter, config) {
5067
5144
  if (!node.component) {
5068
5145
  throw new Error("Step node missing component");
5069
5146
  }
5070
- if (node.component.mode === "pure") {
5071
- return executePureComponent(node.component, ctx);
5072
- }
5073
5147
  if (!adapter) {
5074
5148
  if (node.component.model?.adapter) {
5075
5149
  adapter = node.component.model.adapter;
5076
5150
  config = node.component.model.config;
5151
+ } else if (node.component.mode === "pure") {
5152
+ adapter = {
5153
+ generate: async () => ({ content: "", toolCalls: void 0 })
5154
+ };
5077
5155
  } else {
5078
5156
  throw new Error("No LLM adapter provided");
5079
5157
  }
@@ -5257,56 +5335,6 @@ function createIterationContext(baseCtx, currentItem, index, totalItems, itemMod
5257
5335
  isLastIteration: index === totalItems - 1
5258
5336
  };
5259
5337
  }
5260
- async function executePureComponent(component, ctx) {
5261
- ctx.ui?.startStep(component.id, component.id);
5262
- await ctx.trace.log({
5263
- type: "stage_start",
5264
- stageId: component.id,
5265
- timestamp: /* @__PURE__ */ new Date()
5266
- });
5267
- try {
5268
- if (!component.extractOutput) {
5269
- throw new Error(`Pure component '${component.id}' must have extractOutput defined`);
5270
- }
5271
- const output = await Promise.resolve(
5272
- component.extractOutput(ctx, EMPTY_LLM_RESULT)
5273
- );
5274
- const schemaResult = component.outputSchema.safeParse(output);
5275
- if (!schemaResult.success) {
5276
- const errors = schemaResult.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
5277
- throw new Error(`Pure component '${component.id}' output validation failed: ${errors}`);
5278
- }
5279
- const validatedOutput = schemaResult.data;
5280
- if (component.validateOutput) {
5281
- const validationResult = await Promise.resolve(
5282
- component.validateOutput(validatedOutput, ctx)
5283
- );
5284
- if (!validationResult.valid) {
5285
- const feedback = validationResult.feedback || validationResult.errors?.join("; ") || "Validation failed";
5286
- throw new Error(`Pure component '${component.id}' validateOutput failed: ${feedback}`);
5287
- }
5288
- }
5289
- if (ctx instanceof ExecutionContext) {
5290
- ctx.previousOutputs[component.id] = validatedOutput;
5291
- }
5292
- await ctx.trace.log({
5293
- type: "stage_complete",
5294
- output: validatedOutput,
5295
- timestamp: /* @__PURE__ */ new Date()
5296
- });
5297
- ctx.ui?.completeStep(component.id, "Pure execution complete");
5298
- return validatedOutput;
5299
- } catch (error) {
5300
- const errorMessage = error instanceof Error ? error.message : String(error);
5301
- await ctx.trace.log({
5302
- type: "stage_failed",
5303
- error: errorMessage,
5304
- timestamp: /* @__PURE__ */ new Date()
5305
- });
5306
- ctx.ui?.failStep(component.id, errorMessage);
5307
- throw error;
5308
- }
5309
- }
5310
5338
  function createStepNode(component) {
5311
5339
  return {
5312
5340
  type: "step",