@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.cjs CHANGED
@@ -64,8 +64,8 @@ var init_compile_observe = __esm({
64
64
 
65
65
  // src/components/Agent.tsx
66
66
  function Agent(props) {
67
- const { id, input, output, description, tags, loopValidator, loopConfig, tools: propsTools, mode, children } = props;
68
- const resolvedMode = mode ?? "llm";
67
+ const { id, input, output, mode, description, tags, loopValidator, loopConfig, tools: propsTools, children } = props;
68
+ const isPure = mode === "pure";
69
69
  if (!id) {
70
70
  throw new Error("Agent: id is required");
71
71
  }
@@ -76,8 +76,8 @@ function Agent(props) {
76
76
  throw new Error("Agent: output schema is required");
77
77
  }
78
78
  if (!children || children.length === 0) {
79
- if (resolvedMode === "pure") {
80
- throw new Error("Agent: pure mode must have at least a Result child");
79
+ if (isPure) {
80
+ throw new Error("Agent: pure mode agent must have at least a Result child");
81
81
  }
82
82
  throw new Error("Agent: must have at least Prompt and Result children");
83
83
  }
@@ -85,10 +85,10 @@ function Agent(props) {
85
85
  const nonToolsChildren = children.filter((child) => child?.type !== "Tools");
86
86
  let prompt;
87
87
  let rest;
88
- if (resolvedMode === "pure") {
89
- const firstNonTools = nonToolsChildren[0];
90
- if (firstNonTools?.type === "Prompt") {
91
- prompt = firstNonTools;
88
+ if (isPure) {
89
+ const firstChild = nonToolsChildren[0];
90
+ if (firstChild?.type === "Prompt") {
91
+ prompt = firstChild;
92
92
  rest = nonToolsChildren.slice(1);
93
93
  } else {
94
94
  prompt = void 0;
@@ -123,12 +123,12 @@ function Agent(props) {
123
123
  id,
124
124
  input,
125
125
  output,
126
+ mode,
126
127
  description,
127
128
  tags,
128
129
  loopValidator,
129
130
  loopConfig,
130
- tools: mergedTools,
131
- mode: resolvedMode
131
+ tools: mergedTools
132
132
  },
133
133
  children: orderedChildren
134
134
  };
@@ -1093,13 +1093,13 @@ function compileAgent(ast) {
1093
1093
  if (!children || children.length === 0) {
1094
1094
  throw new Error("Agent must have children");
1095
1095
  }
1096
+ const isPure = ast.props.mode === "pure";
1096
1097
  const promptNode = children.find((n) => n?.type === "Prompt");
1097
1098
  const observeNode = children.find((n) => n?.type === "Observe");
1098
1099
  const resultNode = children.find((n) => n?.type === "Result");
1099
1100
  const validateNode = children.find((n) => n?.type === "Validate");
1100
1101
  const retryNode = children.find((n) => n?.type === "Retry");
1101
- const mode = ast.props.mode ?? "llm";
1102
- if (mode !== "pure" && !promptNode) {
1102
+ if (!isPure && !promptNode) {
1103
1103
  throw new Error("Agent must have a Prompt node");
1104
1104
  }
1105
1105
  if (!resultNode) {
@@ -1112,14 +1112,12 @@ function compileAgent(ast) {
1112
1112
  const retry = retryNode ? compileRetry(retryNode) : void 0;
1113
1113
  const component = {
1114
1114
  id: ast.props.id,
1115
+ mode: ast.props.mode,
1115
1116
  inputSchema: ast.props.input,
1116
1117
  outputSchema: ast.props.output,
1117
1118
  buildPrompt,
1118
1119
  extractOutput
1119
1120
  };
1120
- if (mode === "pure") {
1121
- component.mode = "pure";
1122
- }
1123
1121
  if (validateOutput) {
1124
1122
  component.validateOutput = validateOutput;
1125
1123
  }
@@ -1245,6 +1243,9 @@ function createLazyAgentComponent(astNode) {
1245
1243
  get id() {
1246
1244
  return astNode.props.id;
1247
1245
  },
1246
+ get mode() {
1247
+ return astNode.props.mode;
1248
+ },
1248
1249
  get inputSchema() {
1249
1250
  return astNode.props.input;
1250
1251
  },
@@ -1260,9 +1261,6 @@ function createLazyAgentComponent(astNode) {
1260
1261
  get loopConfig() {
1261
1262
  return astNode.props.loopConfig;
1262
1263
  },
1263
- get mode() {
1264
- return astNode.props.mode;
1265
- },
1266
1264
  // Lazy methods - compile on first call
1267
1265
  buildPrompt(ctx) {
1268
1266
  return ensureCompiled().buildPrompt(ctx);
@@ -2622,6 +2620,18 @@ var PreflightChecker = class {
2622
2620
  * Check agent structure
2623
2621
  */
2624
2622
  checkAgentStructure(agent, errors) {
2623
+ const isPure = agent.props.mode === "pure";
2624
+ if (isPure) {
2625
+ const resultNode2 = agent.children.find((n) => n?.type === "Result");
2626
+ if (!resultNode2) {
2627
+ errors.push({
2628
+ type: "invalid_structure",
2629
+ message: "Pure mode Agent must have a Result node",
2630
+ nodeType: "Agent"
2631
+ });
2632
+ }
2633
+ return;
2634
+ }
2625
2635
  const [promptNode, ...rest] = agent.children;
2626
2636
  if (!promptNode || promptNode.type !== "Prompt") {
2627
2637
  errors.push({
@@ -2721,6 +2731,13 @@ async function preflight(agent, options) {
2721
2731
  }
2722
2732
 
2723
2733
  // src/testing/test-utils.ts
2734
+ var EMPTY_LLM_RESULT = {
2735
+ response: { content: "", toolCalls: void 0 },
2736
+ messages: [],
2737
+ rounds: 0,
2738
+ toolCallsExecuted: 0,
2739
+ errors: []
2740
+ };
2724
2741
  async function runObserve(agent, options) {
2725
2742
  const observeNode = agent.children.find((n) => n?.type === "Observe");
2726
2743
  if (!observeNode) {
@@ -3382,13 +3399,6 @@ function parseComponentOutput(content, schema) {
3382
3399
  }
3383
3400
 
3384
3401
  // src/engine/executor.ts
3385
- var EMPTY_LLM_RESULT = {
3386
- response: { content: "" },
3387
- messages: [],
3388
- rounds: 0,
3389
- toolCallsExecuted: 0,
3390
- errors: []
3391
- };
3392
3402
  async function executeComponent(component, ctx, adapter, config) {
3393
3403
  const startTime = Date.now();
3394
3404
  const llmResults = [];
@@ -3398,6 +3408,73 @@ async function executeComponent(component, ctx, adapter, config) {
3398
3408
  stageId: component.id,
3399
3409
  timestamp: /* @__PURE__ */ new Date()
3400
3410
  });
3411
+ if (component.mode === "pure") {
3412
+ try {
3413
+ ctx.ui?.stepProgress(component.id, 50, "Executing pure agent...");
3414
+ const syntheticLLMResult = {
3415
+ response: { content: "", toolCalls: void 0 },
3416
+ messages: [],
3417
+ rounds: 0,
3418
+ toolCallsExecuted: 0,
3419
+ errors: []
3420
+ };
3421
+ let output;
3422
+ if (component.extractOutput) {
3423
+ const extracted = await Promise.resolve(component.extractOutput(ctx, syntheticLLMResult));
3424
+ const validation = component.outputSchema.safeParse(extracted);
3425
+ if (!validation.success) {
3426
+ const errors = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
3427
+ throw new Error(`Output validation failed: ${errors}`);
3428
+ }
3429
+ output = validation.data;
3430
+ } else {
3431
+ throw new Error("Pure mode agent must have an extractOutput (Result) function");
3432
+ }
3433
+ if (component.validateOutput) {
3434
+ const validationResult = await Promise.resolve(component.validateOutput(output, ctx));
3435
+ if (!validationResult.valid) {
3436
+ const errorMessages = validationResult.errors?.join("; ") ?? validationResult.feedback ?? "Validation failed";
3437
+ throw new Error(errorMessages);
3438
+ }
3439
+ }
3440
+ const duration2 = Date.now() - startTime;
3441
+ await ctx.trace.log({
3442
+ type: "stage_complete",
3443
+ output,
3444
+ timestamp: /* @__PURE__ */ new Date()
3445
+ });
3446
+ ctx.ui?.completeStep(
3447
+ component.id,
3448
+ `Completed (pure) in ${Math.round(duration2 / 1e3)}s`
3449
+ );
3450
+ return {
3451
+ output,
3452
+ success: true,
3453
+ attempts: 1,
3454
+ llmResults: [syntheticLLMResult],
3455
+ retryResult: {
3456
+ success: true,
3457
+ output,
3458
+ attempts: 1,
3459
+ errors: [],
3460
+ validationHistory: [],
3461
+ outputHistory: [output]
3462
+ },
3463
+ duration: duration2
3464
+ };
3465
+ } catch (error) {
3466
+ const errorMessage = error instanceof Error ? error.message : String(error);
3467
+ await ctx.trace.log({
3468
+ type: "stage_failed",
3469
+ error: errorMessage,
3470
+ timestamp: /* @__PURE__ */ new Date()
3471
+ });
3472
+ ctx.ui?.failStep(component.id, errorMessage);
3473
+ throw new Error(
3474
+ `Component ${component.id} (pure mode) failed: ${errorMessage}`
3475
+ );
3476
+ }
3477
+ }
3401
3478
  const retryResult = await executeWithRetry(
3402
3479
  component,
3403
3480
  ctx,
@@ -5089,13 +5166,14 @@ async function executeStepNode(node, ctx, adapter, config) {
5089
5166
  if (!node.component) {
5090
5167
  throw new Error("Step node missing component");
5091
5168
  }
5092
- if (node.component.mode === "pure") {
5093
- return executePureComponent(node.component, ctx);
5094
- }
5095
5169
  if (!adapter) {
5096
5170
  if (node.component.model?.adapter) {
5097
5171
  adapter = node.component.model.adapter;
5098
5172
  config = node.component.model.config;
5173
+ } else if (node.component.mode === "pure") {
5174
+ adapter = {
5175
+ generate: async () => ({ content: "", toolCalls: void 0 })
5176
+ };
5099
5177
  } else {
5100
5178
  throw new Error("No LLM adapter provided");
5101
5179
  }
@@ -5279,56 +5357,6 @@ function createIterationContext(baseCtx, currentItem, index, totalItems, itemMod
5279
5357
  isLastIteration: index === totalItems - 1
5280
5358
  };
5281
5359
  }
5282
- async function executePureComponent(component, ctx) {
5283
- ctx.ui?.startStep(component.id, component.id);
5284
- await ctx.trace.log({
5285
- type: "stage_start",
5286
- stageId: component.id,
5287
- timestamp: /* @__PURE__ */ new Date()
5288
- });
5289
- try {
5290
- if (!component.extractOutput) {
5291
- throw new Error(`Pure component '${component.id}' must have extractOutput defined`);
5292
- }
5293
- const output = await Promise.resolve(
5294
- component.extractOutput(ctx, EMPTY_LLM_RESULT)
5295
- );
5296
- const schemaResult = component.outputSchema.safeParse(output);
5297
- if (!schemaResult.success) {
5298
- const errors = schemaResult.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
5299
- throw new Error(`Pure component '${component.id}' output validation failed: ${errors}`);
5300
- }
5301
- const validatedOutput = schemaResult.data;
5302
- if (component.validateOutput) {
5303
- const validationResult = await Promise.resolve(
5304
- component.validateOutput(validatedOutput, ctx)
5305
- );
5306
- if (!validationResult.valid) {
5307
- const feedback = validationResult.feedback || validationResult.errors?.join("; ") || "Validation failed";
5308
- throw new Error(`Pure component '${component.id}' validateOutput failed: ${feedback}`);
5309
- }
5310
- }
5311
- if (ctx instanceof ExecutionContext) {
5312
- ctx.previousOutputs[component.id] = validatedOutput;
5313
- }
5314
- await ctx.trace.log({
5315
- type: "stage_complete",
5316
- output: validatedOutput,
5317
- timestamp: /* @__PURE__ */ new Date()
5318
- });
5319
- ctx.ui?.completeStep(component.id, "Pure execution complete");
5320
- return validatedOutput;
5321
- } catch (error) {
5322
- const errorMessage = error instanceof Error ? error.message : String(error);
5323
- await ctx.trace.log({
5324
- type: "stage_failed",
5325
- error: errorMessage,
5326
- timestamp: /* @__PURE__ */ new Date()
5327
- });
5328
- ctx.ui?.failStep(component.id, errorMessage);
5329
- throw error;
5330
- }
5331
- }
5332
5360
  function createStepNode(component) {
5333
5361
  return {
5334
5362
  type: "step",