@limo-labs/deity 0.2.2 → 0.3.0-alpha.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.
package/dist/index.cjs CHANGED
@@ -64,7 +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, children } = props;
67
+ const { id, input, output, description, tags, loopValidator, loopConfig, tools: propsTools, mode, children } = props;
68
+ const resolvedMode = mode ?? "llm";
68
69
  if (!id) {
69
70
  throw new Error("Agent: id is required");
70
71
  }
@@ -75,13 +76,31 @@ function Agent(props) {
75
76
  throw new Error("Agent: output schema is required");
76
77
  }
77
78
  if (!children || children.length === 0) {
79
+ if (resolvedMode === "pure") {
80
+ throw new Error("Agent: pure mode must have at least a Result child");
81
+ }
78
82
  throw new Error("Agent: must have at least Prompt and Result children");
79
83
  }
80
84
  const toolsNode = children.find((child) => child?.type === "Tools");
81
85
  const nonToolsChildren = children.filter((child) => child?.type !== "Tools");
82
- const [prompt, ...rest] = nonToolsChildren;
83
- if (!prompt || prompt.type !== "Prompt") {
84
- throw new Error("Agent: first non-Tools child must be a Prompt component");
86
+ let prompt;
87
+ let rest;
88
+ if (resolvedMode === "pure") {
89
+ const firstNonTools = nonToolsChildren[0];
90
+ if (firstNonTools?.type === "Prompt") {
91
+ prompt = firstNonTools;
92
+ rest = nonToolsChildren.slice(1);
93
+ } else {
94
+ prompt = void 0;
95
+ rest = nonToolsChildren;
96
+ }
97
+ } else {
98
+ const [first, ...remaining] = nonToolsChildren;
99
+ if (!first || first.type !== "Prompt") {
100
+ throw new Error("Agent: first non-Tools child must be a Prompt component");
101
+ }
102
+ prompt = first;
103
+ rest = remaining;
85
104
  }
86
105
  const result = rest.find((child) => child?.type === "Result");
87
106
  if (!result) {
@@ -91,9 +110,8 @@ function Agent(props) {
91
110
  const validate = rest.find((child) => child?.type === "Validate");
92
111
  const retry = rest.find((child) => child?.type === "Retry");
93
112
  const mergedTools = mergeTools(propsTools, toolsNode);
94
- const orderedChildren = [
95
- prompt
96
- ];
113
+ const orderedChildren = [];
114
+ if (prompt) orderedChildren.push(prompt);
97
115
  if (observe) orderedChildren.push(observe);
98
116
  orderedChildren.push(result);
99
117
  if (validate) orderedChildren.push(validate);
@@ -109,7 +127,8 @@ function Agent(props) {
109
127
  tags,
110
128
  loopValidator,
111
129
  loopConfig,
112
- tools: mergedTools
130
+ tools: mergedTools,
131
+ mode: resolvedMode
113
132
  },
114
133
  children: orderedChildren
115
134
  };
@@ -1079,13 +1098,14 @@ function compileAgent(ast) {
1079
1098
  const resultNode = children.find((n) => n?.type === "Result");
1080
1099
  const validateNode = children.find((n) => n?.type === "Validate");
1081
1100
  const retryNode = children.find((n) => n?.type === "Retry");
1082
- if (!promptNode) {
1101
+ const mode = ast.props.mode ?? "llm";
1102
+ if (mode !== "pure" && !promptNode) {
1083
1103
  throw new Error("Agent must have a Prompt node");
1084
1104
  }
1085
1105
  if (!resultNode) {
1086
1106
  throw new Error("Agent must have a Result node");
1087
1107
  }
1088
- const buildPrompt = compilePrompt(promptNode);
1108
+ const buildPrompt = promptNode ? compilePrompt(promptNode) : () => [];
1089
1109
  const observe = observeNode ? compileObserve(observeNode) : void 0;
1090
1110
  const extractOutput = compileResult(resultNode, observe);
1091
1111
  const validateOutput = validateNode ? compileValidate(validateNode) : void 0;
@@ -1097,6 +1117,9 @@ function compileAgent(ast) {
1097
1117
  buildPrompt,
1098
1118
  extractOutput
1099
1119
  };
1120
+ if (mode === "pure") {
1121
+ component.mode = "pure";
1122
+ }
1100
1123
  if (validateOutput) {
1101
1124
  component.validateOutput = validateOutput;
1102
1125
  }
@@ -1237,6 +1260,9 @@ function createLazyAgentComponent(astNode) {
1237
1260
  get loopConfig() {
1238
1261
  return astNode.props.loopConfig;
1239
1262
  },
1263
+ get mode() {
1264
+ return astNode.props.mode;
1265
+ },
1240
1266
  // Lazy methods - compile on first call
1241
1267
  buildPrompt(ctx) {
1242
1268
  return ensureCompiled().buildPrompt(ctx);
@@ -3356,6 +3382,13 @@ function parseComponentOutput(content, schema) {
3356
3382
  }
3357
3383
 
3358
3384
  // src/engine/executor.ts
3385
+ var EMPTY_LLM_RESULT = {
3386
+ response: { content: "" },
3387
+ messages: [],
3388
+ rounds: 0,
3389
+ toolCallsExecuted: 0,
3390
+ errors: []
3391
+ };
3359
3392
  async function executeComponent(component, ctx, adapter, config) {
3360
3393
  const startTime = Date.now();
3361
3394
  const llmResults = [];
@@ -5056,6 +5089,9 @@ async function executeStepNode(node, ctx, adapter, config) {
5056
5089
  if (!node.component) {
5057
5090
  throw new Error("Step node missing component");
5058
5091
  }
5092
+ if (node.component.mode === "pure") {
5093
+ return executePureComponent(node.component, ctx);
5094
+ }
5059
5095
  if (!adapter) {
5060
5096
  if (node.component.model?.adapter) {
5061
5097
  adapter = node.component.model.adapter;
@@ -5243,6 +5279,56 @@ function createIterationContext(baseCtx, currentItem, index, totalItems, itemMod
5243
5279
  isLastIteration: index === totalItems - 1
5244
5280
  };
5245
5281
  }
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
+ }
5246
5332
  function createStepNode(component) {
5247
5333
  return {
5248
5334
  type: "step",
@@ -5281,6 +5367,7 @@ exports.Conditional = Conditional;
5281
5367
  exports.DEADLINE_PROMPT = DEADLINE_PROMPT;
5282
5368
  exports.DEBUG_ENABLED = DEBUG_ENABLED;
5283
5369
  exports.DebugLogger = DebugLogger;
5370
+ exports.EMPTY_LLM_RESULT = EMPTY_LLM_RESULT;
5284
5371
  exports.ForEach = ForEach;
5285
5372
  exports.InMemoryStore = InMemoryStore;
5286
5373
  exports.InMemoryTrace = InMemoryTrace;