@limo-labs/deity 0.2.0-alpha.0 → 0.2.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,7 +64,7 @@ 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, children } = props;
67
+ const { id, input, output, description, tags, loopValidator, loopConfig, tools: propsTools, children } = props;
68
68
  if (!id) {
69
69
  throw new Error("Agent: id is required");
70
70
  }
@@ -77,9 +77,11 @@ function Agent(props) {
77
77
  if (!children || children.length === 0) {
78
78
  throw new Error("Agent: must have at least Prompt and Result children");
79
79
  }
80
- const [prompt, ...rest] = children;
80
+ const toolsNode = children.find((child) => child?.type === "Tools");
81
+ const nonToolsChildren = children.filter((child) => child?.type !== "Tools");
82
+ const [prompt, ...rest] = nonToolsChildren;
81
83
  if (!prompt || prompt.type !== "Prompt") {
82
- throw new Error("Agent: first child must be a Prompt component");
84
+ throw new Error("Agent: first non-Tools child must be a Prompt component");
83
85
  }
84
86
  const result = rest.find((child) => child?.type === "Result");
85
87
  if (!result) {
@@ -88,6 +90,7 @@ function Agent(props) {
88
90
  const observe = rest.find((child) => child?.type === "Observe");
89
91
  const validate = rest.find((child) => child?.type === "Validate");
90
92
  const retry = rest.find((child) => child?.type === "Retry");
93
+ const mergedTools = mergeTools(propsTools, toolsNode);
91
94
  const orderedChildren = [
92
95
  prompt
93
96
  ];
@@ -95,6 +98,7 @@ function Agent(props) {
95
98
  orderedChildren.push(result);
96
99
  if (validate) orderedChildren.push(validate);
97
100
  if (retry) orderedChildren.push(retry);
101
+ if (toolsNode) orderedChildren.push(toolsNode);
98
102
  return {
99
103
  type: "Agent",
100
104
  props: {
@@ -105,11 +109,24 @@ function Agent(props) {
105
109
  tags,
106
110
  loopValidator,
107
111
  loopConfig,
108
- tools
112
+ tools: mergedTools
109
113
  },
110
114
  children: orderedChildren
111
115
  };
112
116
  }
117
+ function mergeTools(propsTools, toolsNode) {
118
+ if (!propsTools && !toolsNode) {
119
+ return void 0;
120
+ }
121
+ const staticToolsFromNode = toolsNode ? (toolsNode.children || []).filter((child) => child?.type === "Tools:Def" && child.props?.tool).map((child) => child.props.tool) : [];
122
+ if (!toolsNode) {
123
+ return propsTools;
124
+ }
125
+ if (!propsTools) {
126
+ return staticToolsFromNode.length > 0 ? staticToolsFromNode : void 0;
127
+ }
128
+ return [...propsTools, ...staticToolsFromNode];
129
+ }
113
130
 
114
131
  // src/components/Prompt.tsx
115
132
  function Prompt(props) {
@@ -157,6 +174,40 @@ function System(props) {
157
174
  if (children.length === 0) {
158
175
  throw new Error("System: children array is empty");
159
176
  }
177
+ const hasToolRef = children.some(
178
+ (child) => typeof child === "object" && child !== null && "type" in child && child.type === "ToolRef"
179
+ );
180
+ if (hasToolRef) {
181
+ const parts = [];
182
+ for (const child of children) {
183
+ if (typeof child === "object" && child !== null && "type" in child) {
184
+ const node = child;
185
+ if (node.type === "Text" && node.props?.content) {
186
+ parts.push({ kind: "text", value: node.props.content });
187
+ } else if (node.type === "ComputedText" && node.props?.compute) {
188
+ parts.push({ kind: "computed", compute: node.props.compute });
189
+ } else if (node.type === "ToolRef" && node.props?.toolName) {
190
+ parts.push({ kind: "toolref", toolName: node.props.toolName });
191
+ } else {
192
+ throw new Error(`System: invalid child type in template mode: ${node.type}`);
193
+ }
194
+ } else if (typeof child === "string") {
195
+ parts.push({ kind: "text", value: child });
196
+ } else if (typeof child === "function") {
197
+ parts.push({ kind: "computed", compute: child });
198
+ } else {
199
+ throw new Error("System: invalid child in template mode");
200
+ }
201
+ }
202
+ return {
203
+ type: "System",
204
+ props: {
205
+ source,
206
+ required,
207
+ templateParts: parts
208
+ }
209
+ };
210
+ }
160
211
  if (children.length > 1) {
161
212
  throw new Error("System: can only have one child");
162
213
  }
@@ -213,6 +264,38 @@ function User(props) {
213
264
  if (children.length === 0) {
214
265
  throw new Error("User: children array is empty");
215
266
  }
267
+ const hasToolRef = children.some(
268
+ (child) => typeof child === "object" && child !== null && "type" in child && child.type === "ToolRef"
269
+ );
270
+ if (hasToolRef) {
271
+ const parts = [];
272
+ for (const child of children) {
273
+ if (typeof child === "object" && child !== null && "type" in child) {
274
+ const node = child;
275
+ if (node.type === "Text" && node.props?.content) {
276
+ parts.push({ kind: "text", value: node.props.content });
277
+ } else if (node.type === "ComputedText" && node.props?.compute) {
278
+ parts.push({ kind: "computed", compute: node.props.compute });
279
+ } else if (node.type === "ToolRef" && node.props?.toolName) {
280
+ parts.push({ kind: "toolref", toolName: node.props.toolName });
281
+ } else {
282
+ throw new Error(`User: invalid child type in template mode: ${node.type}`);
283
+ }
284
+ } else if (typeof child === "string") {
285
+ parts.push({ kind: "text", value: child });
286
+ } else if (typeof child === "function") {
287
+ parts.push({ kind: "computed", compute: child });
288
+ } else {
289
+ throw new Error("User: invalid child in template mode");
290
+ }
291
+ }
292
+ return {
293
+ type: "User",
294
+ props: {
295
+ templateParts: parts
296
+ }
297
+ };
298
+ }
216
299
  if (children.length > 1) {
217
300
  throw new Error("User: can only have one child");
218
301
  }
@@ -396,6 +479,239 @@ function Retry(props = {}) {
396
479
  }
397
480
  };
398
481
  }
482
+
483
+ // src/components/Tools.tsx
484
+ function Tools(props) {
485
+ const { children } = props;
486
+ const toolDefs = (children || []).filter(
487
+ (child) => child?.type === "Tools:Def"
488
+ );
489
+ return {
490
+ type: "Tools",
491
+ props: {},
492
+ children: toolDefs
493
+ };
494
+ }
495
+ function ToolDef(props) {
496
+ return {
497
+ type: "Tools:Def",
498
+ props: { tool: props.tool }
499
+ };
500
+ }
501
+ function Tool(props) {
502
+ const { name, description, input, execute, children } = props;
503
+ if (!name) {
504
+ throw new Error("Tool: name is required");
505
+ }
506
+ if (!description) {
507
+ throw new Error("Tool: description is required");
508
+ }
509
+ if (!input) {
510
+ throw new Error("Tool: input schema is required");
511
+ }
512
+ let executeFn;
513
+ const hasChildren = children && Array.isArray(children) && children.length > 0;
514
+ if (hasChildren) {
515
+ if (execute) {
516
+ throw new Error("Tool: cannot use both children and execute prop");
517
+ }
518
+ let actualChild = children;
519
+ if (Array.isArray(children)) {
520
+ if (children.length > 1) {
521
+ throw new Error("Tool: can only have one child (the execute function)");
522
+ }
523
+ actualChild = children[0];
524
+ }
525
+ if (typeof actualChild === "object" && actualChild !== null && "type" in actualChild) {
526
+ const node = actualChild;
527
+ if (node.type === "ComputedText" && node.props?.compute) {
528
+ executeFn = node.props.compute;
529
+ } else {
530
+ throw new Error("Tool: invalid child node type (expected ComputedText with execute function)");
531
+ }
532
+ } else if (typeof actualChild === "function") {
533
+ executeFn = actualChild;
534
+ } else {
535
+ throw new Error("Tool: children must be a function");
536
+ }
537
+ } else if (execute) {
538
+ executeFn = execute;
539
+ } else {
540
+ throw new Error("Tool: must provide children (execute function) or execute prop");
541
+ }
542
+ const toolSpec = {
543
+ name,
544
+ description,
545
+ inputSchema: input,
546
+ execute: executeFn
547
+ };
548
+ return {
549
+ type: "Tools:Def",
550
+ props: { tool: toolSpec }
551
+ };
552
+ }
553
+
554
+ // src/components/ToolRef.tsx
555
+ function ToolRef(props) {
556
+ const { tool } = props;
557
+ let toolName;
558
+ if (tool === null || tool === void 0) {
559
+ throw new Error(
560
+ "ToolRef: `tool` prop must be a tool component with .toolName, a ToolSpec with .name, or a string tool ID"
561
+ );
562
+ }
563
+ if (typeof tool === "string") {
564
+ toolName = tool;
565
+ } else if (typeof tool === "function" && "toolName" in tool && typeof tool.toolName === "string") {
566
+ toolName = tool.toolName;
567
+ } else if (typeof tool === "object" && "toolName" in tool && typeof tool.toolName === "string") {
568
+ toolName = tool.toolName;
569
+ } else if (typeof tool === "object" && "name" in tool && typeof tool.name === "string") {
570
+ toolName = tool.name;
571
+ } else {
572
+ throw new Error(
573
+ "ToolRef: `tool` prop must be a tool component with .toolName, a ToolSpec with .name, or a string tool ID"
574
+ );
575
+ }
576
+ return {
577
+ type: "ToolRef",
578
+ props: { toolName }
579
+ };
580
+ }
581
+
582
+ // src/components/Sequence.tsx
583
+ function Sequence(props) {
584
+ const { children } = props;
585
+ if (!children || children.length === 0) {
586
+ throw new Error("Sequence: must have at least one child");
587
+ }
588
+ return {
589
+ type: "WorkflowSequence",
590
+ children
591
+ };
592
+ }
593
+
594
+ // src/components/Parallel.tsx
595
+ function Parallel(props) {
596
+ const { children } = props;
597
+ if (!children || children.length === 0) {
598
+ throw new Error("Parallel: must have at least one child");
599
+ }
600
+ return {
601
+ type: "WorkflowParallel",
602
+ children
603
+ };
604
+ }
605
+
606
+ // src/components/Conditional.tsx
607
+ function Conditional(props) {
608
+ const { condition, children } = props;
609
+ if (!condition) {
610
+ throw new Error("Conditional: condition prop is required");
611
+ }
612
+ if (!children) {
613
+ throw new Error("Conditional: must have at least one child (true branch)");
614
+ }
615
+ if (children.length < 1 || children.length > 2) {
616
+ throw new Error("Conditional: must have 1-2 children (true branch required, false branch optional)");
617
+ }
618
+ return {
619
+ type: "WorkflowConditional",
620
+ props: {
621
+ condition
622
+ },
623
+ children
624
+ };
625
+ }
626
+
627
+ // src/components/Loop.tsx
628
+ function Loop(props) {
629
+ const { iterations, children } = props;
630
+ if (!iterations || iterations < 1) {
631
+ throw new Error("Loop: iterations must be >= 1");
632
+ }
633
+ if (!children) {
634
+ throw new Error("Loop: must have exactly one child");
635
+ }
636
+ const childArray = Array.isArray(children) ? children : [children];
637
+ if (childArray.length !== 1) {
638
+ throw new Error("Loop: must have exactly one child");
639
+ }
640
+ return {
641
+ type: "WorkflowLoop",
642
+ props: {
643
+ iterations
644
+ },
645
+ children: [childArray[0]]
646
+ };
647
+ }
648
+
649
+ // src/components/ForEach.tsx
650
+ function ForEach(props) {
651
+ const {
652
+ items,
653
+ itemMode = "property",
654
+ itemKey = "currentItem",
655
+ errorMode = "stop",
656
+ collectResults = true,
657
+ children
658
+ } = props;
659
+ if (!items) {
660
+ throw new Error("ForEach: items prop is required");
661
+ }
662
+ if (!children) {
663
+ throw new Error("ForEach: must have exactly one child");
664
+ }
665
+ const childArray = Array.isArray(children) ? children : [children];
666
+ if (childArray.length !== 1) {
667
+ throw new Error("ForEach: must have exactly one child");
668
+ }
669
+ const validModes = ["merge", "replace", "property"];
670
+ if (!validModes.includes(itemMode)) {
671
+ throw new Error(`ForEach: itemMode must be one of: ${validModes.join(", ")}`);
672
+ }
673
+ const validErrorModes = ["stop", "continue", "skip"];
674
+ if (!validErrorModes.includes(errorMode)) {
675
+ throw new Error(`ForEach: errorMode must be one of: ${validErrorModes.join(", ")}`);
676
+ }
677
+ return {
678
+ type: "WorkflowForEach",
679
+ props: {
680
+ items,
681
+ itemMode,
682
+ itemKey,
683
+ errorMode,
684
+ collectResults
685
+ },
686
+ children: [childArray[0]]
687
+ };
688
+ }
689
+
690
+ // src/components/Workflow.tsx
691
+ function Workflow(props) {
692
+ const { name, description, defaultModel, state, enhancements, children } = props;
693
+ if (!name) {
694
+ throw new Error("Workflow: name is required");
695
+ }
696
+ if (!children) {
697
+ throw new Error("Workflow: must have exactly one child (workflow graph)");
698
+ }
699
+ const childArray = Array.isArray(children) ? children : [children];
700
+ if (childArray.length !== 1) {
701
+ throw new Error("Workflow: must have exactly one child (workflow graph)");
702
+ }
703
+ return {
704
+ type: "Workflow",
705
+ props: {
706
+ name,
707
+ description,
708
+ defaultModel,
709
+ state,
710
+ enhancements
711
+ },
712
+ children: [childArray[0]]
713
+ };
714
+ }
399
715
  var PromptResourceLoader = class {
400
716
  cache = /* @__PURE__ */ new Map();
401
717
  options;
@@ -605,7 +921,25 @@ function compilePrompt(promptNode) {
605
921
  };
606
922
  }
607
923
  async function resolveSystemContent(node, ctx) {
608
- const { source, content, compute, required = false } = node.props;
924
+ const { source, content, compute, required = false, templateParts } = node.props;
925
+ if (templateParts) {
926
+ const resolved = await Promise.all(
927
+ templateParts.map(async (part) => {
928
+ switch (part.kind) {
929
+ case "text":
930
+ return part.value;
931
+ case "computed":
932
+ return await Promise.resolve(part.compute(ctx));
933
+ case "toolref":
934
+ return part.toolName;
935
+ default:
936
+ const _exhaustive = part;
937
+ throw new Error(`Unknown template part kind: ${_exhaustive.kind}`);
938
+ }
939
+ })
940
+ );
941
+ return resolved.join("");
942
+ }
609
943
  if (source) {
610
944
  if (!source.startsWith("file:")) {
611
945
  throw new Error(`Invalid source format: ${source} (must start with "file:")`);
@@ -626,17 +960,35 @@ async function resolveSystemContent(node, ctx) {
626
960
  if (compute) {
627
961
  return await Promise.resolve(compute(ctx));
628
962
  }
629
- throw new Error("System node must have source, content, or compute");
963
+ throw new Error("System node must have source, content, compute, or templateParts");
630
964
  }
631
965
  async function resolveUserContent(node, ctx) {
632
- const { content, compute } = node.props;
966
+ const { content, compute, templateParts } = node.props;
967
+ if (templateParts) {
968
+ const resolved = await Promise.all(
969
+ templateParts.map(async (part) => {
970
+ switch (part.kind) {
971
+ case "text":
972
+ return part.value;
973
+ case "computed":
974
+ return await Promise.resolve(part.compute(ctx));
975
+ case "toolref":
976
+ return part.toolName;
977
+ default:
978
+ const _exhaustive = part;
979
+ throw new Error(`Unknown template part kind: ${_exhaustive.kind}`);
980
+ }
981
+ })
982
+ );
983
+ return resolved.join("");
984
+ }
633
985
  if (content !== void 0) {
634
986
  return content;
635
987
  }
636
988
  if (compute) {
637
989
  return await Promise.resolve(compute(ctx));
638
990
  }
639
- throw new Error("User node must have content or compute");
991
+ throw new Error("User node must have content, compute, or templateParts");
640
992
  }
641
993
 
642
994
  // src/compiler/compile-agent.ts
@@ -766,6 +1118,184 @@ function compileAgent(ast) {
766
1118
  // src/compiler/index.ts
767
1119
  init_compile_observe();
768
1120
 
1121
+ // src/compiler/compile-workflow-node.ts
1122
+ function compileWorkflowNode(node) {
1123
+ switch (node.type) {
1124
+ case "Agent":
1125
+ return compileAgentNode(node);
1126
+ case "WorkflowSequence":
1127
+ return compileSequenceNode(node);
1128
+ case "WorkflowParallel":
1129
+ return compileParallelNode(node);
1130
+ case "WorkflowConditional":
1131
+ return compileConditionalNode(node);
1132
+ case "WorkflowLoop":
1133
+ return compileLoopNode(node);
1134
+ case "WorkflowForEach":
1135
+ return compileForEachNode(node);
1136
+ default:
1137
+ throw new Error(`Unknown workflow node type: ${node.type}`);
1138
+ }
1139
+ }
1140
+ function compileAgentNode(node) {
1141
+ const lazyComponent = createLazyAgentComponent(node);
1142
+ return {
1143
+ type: "step",
1144
+ component: lazyComponent
1145
+ };
1146
+ }
1147
+ function compileSequenceNode(node) {
1148
+ if (!node.children || node.children.length === 0) {
1149
+ throw new Error("Sequence node must have children");
1150
+ }
1151
+ const children = node.children.map((child) => compileWorkflowNode(child));
1152
+ return {
1153
+ type: "sequence",
1154
+ children
1155
+ };
1156
+ }
1157
+ function compileParallelNode(node) {
1158
+ if (!node.children || node.children.length === 0) {
1159
+ throw new Error("Parallel node must have children");
1160
+ }
1161
+ const children = node.children.map((child) => compileWorkflowNode(child));
1162
+ return {
1163
+ type: "parallel",
1164
+ children
1165
+ };
1166
+ }
1167
+ function compileConditionalNode(node) {
1168
+ if (!node.props?.condition) {
1169
+ throw new Error("Conditional node must have a condition function");
1170
+ }
1171
+ if (!node.children || node.children.length < 1 || node.children.length > 2) {
1172
+ throw new Error("Conditional node must have 1-2 children (true branch required, false branch optional)");
1173
+ }
1174
+ const children = node.children.map((child) => compileWorkflowNode(child));
1175
+ return {
1176
+ type: "conditional",
1177
+ condition: node.props.condition,
1178
+ children
1179
+ };
1180
+ }
1181
+ function compileLoopNode(node) {
1182
+ if (!node.props?.iterations || node.props.iterations < 1) {
1183
+ throw new Error("Loop node must have iterations >= 1");
1184
+ }
1185
+ if (!node.children || node.children.length !== 1) {
1186
+ throw new Error("Loop node must have exactly one child");
1187
+ }
1188
+ const child = compileWorkflowNode(node.children[0]);
1189
+ return {
1190
+ type: "loop",
1191
+ maxIterations: node.props.iterations,
1192
+ children: [child]
1193
+ };
1194
+ }
1195
+ function compileForEachNode(node) {
1196
+ if (!node.props?.items) {
1197
+ throw new Error("ForEach node must have items prop");
1198
+ }
1199
+ if (!node.children || node.children.length !== 1) {
1200
+ throw new Error("ForEach node must have exactly one child");
1201
+ }
1202
+ const child = compileWorkflowNode(node.children[0]);
1203
+ return {
1204
+ type: "foreach",
1205
+ itemsAccessor: node.props.items,
1206
+ itemMode: node.props.itemMode,
1207
+ itemKey: node.props.itemKey,
1208
+ errorMode: node.props.errorMode,
1209
+ collectResults: node.props.collectResults,
1210
+ children: [child]
1211
+ };
1212
+ }
1213
+ function createLazyAgentComponent(astNode) {
1214
+ let compiled = null;
1215
+ const ensureCompiled = () => {
1216
+ if (!compiled) {
1217
+ compiled = compileAgent(astNode);
1218
+ }
1219
+ return compiled;
1220
+ };
1221
+ const proxy = {
1222
+ get id() {
1223
+ return astNode.props.id;
1224
+ },
1225
+ get inputSchema() {
1226
+ return astNode.props.input;
1227
+ },
1228
+ get outputSchema() {
1229
+ return astNode.props.output;
1230
+ },
1231
+ get tools() {
1232
+ return astNode.props.tools;
1233
+ },
1234
+ get loopValidator() {
1235
+ return astNode.props.loopValidator;
1236
+ },
1237
+ get loopConfig() {
1238
+ return astNode.props.loopConfig;
1239
+ },
1240
+ // Lazy methods - compile on first call
1241
+ buildPrompt(ctx) {
1242
+ return ensureCompiled().buildPrompt(ctx);
1243
+ },
1244
+ get retry() {
1245
+ return ensureCompiled().retry;
1246
+ },
1247
+ get model() {
1248
+ return ensureCompiled().model;
1249
+ }
1250
+ };
1251
+ const hasResultNode = astNode.children.some((child) => child.type === "Result");
1252
+ if (hasResultNode) {
1253
+ proxy.extractOutput = (ctx, llmResult) => {
1254
+ return ensureCompiled().extractOutput(ctx, llmResult);
1255
+ };
1256
+ }
1257
+ const hasValidateNode = astNode.children.some((child) => child.type === "Validate");
1258
+ if (hasValidateNode) {
1259
+ proxy.validateOutput = (output, ctx) => {
1260
+ const comp = ensureCompiled();
1261
+ return comp.validateOutput(output, ctx);
1262
+ };
1263
+ }
1264
+ return proxy;
1265
+ }
1266
+
1267
+ // src/compiler/compile-workflow.ts
1268
+ function compileWorkflow(ast) {
1269
+ if (ast.type !== "Workflow") {
1270
+ throw new Error(`Expected Workflow node, got ${ast.type}`);
1271
+ }
1272
+ if (!ast.children || ast.children.length !== 1) {
1273
+ throw new Error("Workflow must have exactly one child (workflow graph)");
1274
+ }
1275
+ const { name, description, defaultModel, state, enhancements } = ast.props;
1276
+ if (!name) {
1277
+ throw new Error("Workflow must have a name");
1278
+ }
1279
+ const graph = compileWorkflowNode(ast.children[0]);
1280
+ const config = {
1281
+ name,
1282
+ graph
1283
+ };
1284
+ if (description) {
1285
+ config.description = description;
1286
+ }
1287
+ if (defaultModel) {
1288
+ config.defaultModel = defaultModel;
1289
+ }
1290
+ if (state) {
1291
+ config.state = state;
1292
+ }
1293
+ if (enhancements) {
1294
+ config.enhancements = enhancements;
1295
+ }
1296
+ return config;
1297
+ }
1298
+
769
1299
  // src/ast/types.ts
770
1300
  function isAgentNode(node) {
771
1301
  return node.type === "Agent";
@@ -791,6 +1321,33 @@ function isValidateNode(node) {
791
1321
  function isRetryNode(node) {
792
1322
  return node.type === "Retry";
793
1323
  }
1324
+ function isToolsNode(node) {
1325
+ return node.type === "Tools";
1326
+ }
1327
+ function isToolDefNode(node) {
1328
+ return node.type === "Tools:Def";
1329
+ }
1330
+ function isToolRefNode(node) {
1331
+ return node.type === "ToolRef";
1332
+ }
1333
+ function isWorkflowSequenceNode(node) {
1334
+ return node.type === "WorkflowSequence";
1335
+ }
1336
+ function isWorkflowParallelNode(node) {
1337
+ return node.type === "WorkflowParallel";
1338
+ }
1339
+ function isWorkflowConditionalNode(node) {
1340
+ return node.type === "WorkflowConditional";
1341
+ }
1342
+ function isWorkflowLoopNode(node) {
1343
+ return node.type === "WorkflowLoop";
1344
+ }
1345
+ function isWorkflowForEachNode(node) {
1346
+ return node.type === "WorkflowForEach";
1347
+ }
1348
+ function isWorkflowNode(node) {
1349
+ return node.type === "Workflow";
1350
+ }
794
1351
 
795
1352
  // src/utilities/observe-utils.ts
796
1353
  var ObserveUtils = class {
@@ -1986,6 +2543,20 @@ var RetryUtils = class {
1986
2543
  }
1987
2544
  };
1988
2545
 
2546
+ // src/utilities/jsx-helpers.ts
2547
+ function toWorkflow(element) {
2548
+ if (element.type !== "Workflow") {
2549
+ throw new Error(`Expected Workflow element, got ${element.type}`);
2550
+ }
2551
+ return element;
2552
+ }
2553
+ function toAgent(element) {
2554
+ if (element.type !== "Agent") {
2555
+ throw new Error(`Expected Agent element, got ${element.type}`);
2556
+ }
2557
+ return element;
2558
+ }
2559
+
1989
2560
  // src/utilities/preflight.ts
1990
2561
  var PreflightChecker = class {
1991
2562
  options;
@@ -2413,6 +2984,7 @@ async function executeLLMLoop(adapter, initialMessages, tools, config, ctx, loop
2413
2984
  });
2414
2985
  }
2415
2986
  }
2987
+ const allPreExecuted = response.toolCalls.every((tc) => tc._alreadyExecuted);
2416
2988
  if (validator) {
2417
2989
  const loopState = {
2418
2990
  rounds,
@@ -2432,6 +3004,9 @@ async function executeLLMLoop(adapter, initialMessages, tools, config, ctx, loop
2432
3004
  });
2433
3005
  }
2434
3006
  }
3007
+ if (allPreExecuted) {
3008
+ break;
3009
+ }
2435
3010
  }
2436
3011
  return {
2437
3012
  response,
@@ -2771,10 +3346,11 @@ async function executeComponent(component, ctx, adapter, config) {
2771
3346
  ctx.ui?.stepProgress(component.id, 50, "Executing LLM...");
2772
3347
  const promptMessages = await Promise.resolve(component.buildPrompt(ctx));
2773
3348
  const messages = feedbackMessages ? [...promptMessages, ...feedbackMessages] : promptMessages;
3349
+ const resolvedTools = component.tools;
2774
3350
  const llmResult = await executeLLMLoop(
2775
3351
  adapter,
2776
3352
  messages,
2777
- component.tools,
3353
+ resolvedTools,
2778
3354
  config,
2779
3355
  ctx,
2780
3356
  component.loopConfig,
@@ -2884,6 +3460,8 @@ var ExecutionContext = class _ExecutionContext {
2884
3460
  ui;
2885
3461
  /** Session store (optional) */
2886
3462
  session;
3463
+ /** Application state store (optional, isolated from AI memory) */
3464
+ appState;
2887
3465
  /** Current stage ID (for UI updates) */
2888
3466
  currentStageId;
2889
3467
  // ========== Constructor ==========
@@ -2896,6 +3474,7 @@ var ExecutionContext = class _ExecutionContext {
2896
3474
  this.conversation = params.conversation;
2897
3475
  this.memory = params.memory;
2898
3476
  this.session = params.session;
3477
+ this.appState = params.appState;
2899
3478
  this.ui = params.ui;
2900
3479
  this.currentStageId = params.currentStageId;
2901
3480
  this.iteration = params.iteration;
@@ -2944,6 +3523,7 @@ var ExecutionContext = class _ExecutionContext {
2944
3523
  conversation: this.conversation,
2945
3524
  memory: this.memory,
2946
3525
  session: this.session,
3526
+ appState: this.appState,
2947
3527
  ui: this.ui,
2948
3528
  currentStageId: updates.currentStageId ?? this.currentStageId,
2949
3529
  iteration: updates.iteration ?? this.iteration,
@@ -2972,6 +3552,27 @@ var ExecutionContext = class _ExecutionContext {
2972
3552
  iterationHistory: this.iterationHistory
2973
3553
  });
2974
3554
  }
3555
+ /**
3556
+ * Update inputs (for ForEach iterations)
3557
+ */
3558
+ withInputs(inputs) {
3559
+ return new _ExecutionContext({
3560
+ inputs,
3561
+ previousOutputs: this.previousOutputs,
3562
+ store: this.store,
3563
+ trace: this.trace,
3564
+ stats: this.stats,
3565
+ conversation: this.conversation,
3566
+ memory: this.memory,
3567
+ session: this.session,
3568
+ appState: this.appState,
3569
+ ui: this.ui,
3570
+ currentStageId: this.currentStageId,
3571
+ iteration: this.iteration,
3572
+ maxIterations: this.maxIterations,
3573
+ iterationHistory: this.iterationHistory
3574
+ });
3575
+ }
2975
3576
  /**
2976
3577
  * Add to iteration history
2977
3578
  */
@@ -3005,6 +3606,12 @@ var ExecutionContext = class _ExecutionContext {
3005
3606
  hasUI() {
3006
3607
  return this.ui !== void 0;
3007
3608
  }
3609
+ /**
3610
+ * Check if appState is enabled
3611
+ */
3612
+ hasAppState() {
3613
+ return this.appState !== void 0;
3614
+ }
3008
3615
  /**
3009
3616
  * Get conversation manager (throws if not available)
3010
3617
  */
@@ -3041,6 +3648,15 @@ var ExecutionContext = class _ExecutionContext {
3041
3648
  }
3042
3649
  return this.ui;
3043
3650
  }
3651
+ /**
3652
+ * Get application state store (throws if not available)
3653
+ */
3654
+ requireAppState() {
3655
+ if (!this.appState) {
3656
+ throw new Error("Application state store not available in this context");
3657
+ }
3658
+ return this.appState;
3659
+ }
3044
3660
  // ========== Debugging ==========
3045
3661
  /**
3046
3662
  * Get context summary for debugging
@@ -3055,7 +3671,8 @@ var ExecutionContext = class _ExecutionContext {
3055
3671
  conversation: this.hasConversation(),
3056
3672
  memory: this.hasMemory(),
3057
3673
  session: this.hasSession(),
3058
- ui: this.hasUI()
3674
+ ui: this.hasUI(),
3675
+ appState: this.hasAppState()
3059
3676
  },
3060
3677
  stats: this.stats
3061
3678
  };
@@ -3491,6 +4108,81 @@ var LimoMemoryManager = class {
3491
4108
  getDetailedMemories() {
3492
4109
  return Array.from(this.detailedMemories.values());
3493
4110
  }
4111
+ /**
4112
+ * Get all memory keys (core + detailed)
4113
+ *
4114
+ * @returns Array of all memory keys
4115
+ */
4116
+ getAllKeys() {
4117
+ const keys = /* @__PURE__ */ new Set();
4118
+ for (const key of this.coreMemories.keys()) keys.add(key);
4119
+ for (const key of this.detailedMemories.keys()) keys.add(key);
4120
+ return Array.from(keys);
4121
+ }
4122
+ /**
4123
+ * Get all Memory objects (core + detailed)
4124
+ *
4125
+ * @returns Array of all Memory entries
4126
+ */
4127
+ getAllMemories() {
4128
+ return [
4129
+ ...Array.from(this.coreMemories.values()),
4130
+ ...Array.from(this.detailedMemories.values())
4131
+ ];
4132
+ }
4133
+ /**
4134
+ * Get raw Memory object by key (without triggering access metadata update)
4135
+ *
4136
+ * @param key - Memory key
4137
+ * @returns Memory object or undefined
4138
+ */
4139
+ getMemory(key) {
4140
+ return this.coreMemories.get(key) || this.detailedMemories.get(key);
4141
+ }
4142
+ /**
4143
+ * Update an existing memory entry
4144
+ *
4145
+ * @param key - Memory key to update
4146
+ * @param updates - Partial updates (content, importance, category, tags)
4147
+ * @returns true if updated, false if key not found
4148
+ */
4149
+ async update(key, updates) {
4150
+ const memory = this.coreMemories.get(key) || this.detailedMemories.get(key);
4151
+ if (!memory) return false;
4152
+ if (updates.content !== void 0) memory.content = updates.content;
4153
+ if (updates.importance !== void 0) memory.importance = updates.importance;
4154
+ if (updates.category !== void 0) memory.category = updates.category;
4155
+ if (updates.tags !== void 0) memory.tags = updates.tags;
4156
+ return true;
4157
+ }
4158
+ /**
4159
+ * Promote a memory to core by key
4160
+ *
4161
+ * @param key - Memory key to promote
4162
+ * @returns true if promoted, false if key not found or already in core
4163
+ */
4164
+ promoteToCoreByKey(key) {
4165
+ const memory = this.detailedMemories.get(key);
4166
+ if (!memory) {
4167
+ return this.coreMemories.has(key) ? false : false;
4168
+ }
4169
+ this.promoteToCore(memory);
4170
+ return true;
4171
+ }
4172
+ /**
4173
+ * Demote a memory from core to detailed by key
4174
+ *
4175
+ * @param key - Memory key to demote
4176
+ * @returns true if demoted, false if key not found in core
4177
+ */
4178
+ demoteFromCore(key) {
4179
+ const memory = this.coreMemories.get(key);
4180
+ if (!memory) return false;
4181
+ memory.is_core = false;
4182
+ this.detailedMemories.set(memory.id, memory);
4183
+ this.coreMemories.delete(memory.id);
4184
+ return true;
4185
+ }
3494
4186
  /**
3495
4187
  * Get memory statistics
3496
4188
  */
@@ -3622,8 +4314,6 @@ var LimoMemoryManager = class {
3622
4314
  return diffMs / (1e3 * 60 * 60 * 24);
3623
4315
  }
3624
4316
  };
3625
-
3626
- // src/session/types.ts
3627
4317
  var DEFAULT_SESSION_CONFIG = {
3628
4318
  directory: ".deity/sessions",
3629
4319
  autoSaveInterval: 3e4,
@@ -3632,6 +4322,32 @@ var DEFAULT_SESSION_CONFIG = {
3632
4322
  maxBackups: 5,
3633
4323
  compress: false
3634
4324
  };
4325
+ var PauseReasonSchema = zod.z.enum(["manual", "timeout", "error"]);
4326
+ var ExecutionStatsSchema = zod.z.object({
4327
+ totalToolCalls: zod.z.number().int().min(0),
4328
+ totalRetries: zod.z.number().int().min(0)
4329
+ }).passthrough();
4330
+ var PausedSessionStateSchema = zod.z.object({
4331
+ inputs: zod.z.unknown(),
4332
+ outputs: zod.z.record(zod.z.string(), zod.z.unknown()),
4333
+ conversation: zod.z.string().optional(),
4334
+ memory: zod.z.string().optional(),
4335
+ appState: zod.z.string().optional(),
4336
+ stats: ExecutionStatsSchema
4337
+ });
4338
+ var PausedSessionMetadataSchema = zod.z.object({
4339
+ pauseReason: PauseReasonSchema,
4340
+ resumable: zod.z.boolean(),
4341
+ notes: zod.z.string().optional()
4342
+ });
4343
+ zod.z.object({
4344
+ sessionId: zod.z.string().min(1, "Session ID cannot be empty"),
4345
+ workflowName: zod.z.string().min(1, "Workflow name cannot be empty"),
4346
+ pausedAt: zod.z.string().datetime("Must be ISO 8601 datetime"),
4347
+ version: zod.z.string().regex(/^\d+\.\d+\.\d+$/, "Must be semver format (e.g., 4.0.0)"),
4348
+ state: PausedSessionStateSchema,
4349
+ metadata: PausedSessionMetadataSchema
4350
+ });
3635
4351
 
3636
4352
  // src/session/serializer.ts
3637
4353
  var TYPE_MARKERS = {
@@ -4060,6 +4776,58 @@ var FileSystemSessionStore = class {
4060
4776
  }
4061
4777
  };
4062
4778
 
4779
+ // src/engine/stores.ts
4780
+ var InMemoryStore = class {
4781
+ data = /* @__PURE__ */ new Map();
4782
+ async get(key) {
4783
+ return this.data.get(key);
4784
+ }
4785
+ async set(key, value) {
4786
+ this.data.set(key, value);
4787
+ }
4788
+ async has(key) {
4789
+ return this.data.has(key);
4790
+ }
4791
+ async delete(key) {
4792
+ this.data.delete(key);
4793
+ }
4794
+ async clear() {
4795
+ this.data.clear();
4796
+ }
4797
+ // Extra methods beyond StateStore interface
4798
+ size() {
4799
+ return this.data.size;
4800
+ }
4801
+ keys() {
4802
+ return Array.from(this.data.keys());
4803
+ }
4804
+ entries() {
4805
+ return Array.from(this.data.entries());
4806
+ }
4807
+ values() {
4808
+ return Array.from(this.data.values());
4809
+ }
4810
+ };
4811
+ var InMemoryTrace = class {
4812
+ entries = [];
4813
+ async log(entry) {
4814
+ this.entries.push(entry);
4815
+ }
4816
+ async getEntries() {
4817
+ return [...this.entries];
4818
+ }
4819
+ // Extra methods for testing
4820
+ clear() {
4821
+ this.entries = [];
4822
+ }
4823
+ count() {
4824
+ return this.entries.length;
4825
+ }
4826
+ getEntriesByType(type) {
4827
+ return this.entries.filter((e) => e.type === type);
4828
+ }
4829
+ };
4830
+
4063
4831
  // src/engine/stats.ts
4064
4832
  var StatsManager = class {
4065
4833
  stats;
@@ -4188,6 +4956,14 @@ async function createEnhancedContext(config) {
4188
4956
  session = new FileSystemSessionStore(sessionConfig);
4189
4957
  await session.init();
4190
4958
  }
4959
+ let appState;
4960
+ if (config.enableAppState) {
4961
+ if (typeof config.enableAppState === "boolean") {
4962
+ appState = new InMemoryStore();
4963
+ } else {
4964
+ appState = config.enableAppState;
4965
+ }
4966
+ }
4191
4967
  return new ExecutionContext({
4192
4968
  inputs: config.inputs,
4193
4969
  previousOutputs: config.previousOutputs ?? {},
@@ -4197,6 +4973,7 @@ async function createEnhancedContext(config) {
4197
4973
  conversation,
4198
4974
  memory,
4199
4975
  session,
4976
+ appState,
4200
4977
  ui: config.ui,
4201
4978
  currentStageId: config.currentStageId,
4202
4979
  iteration: config.loop?.iteration,
@@ -4205,52 +4982,6 @@ async function createEnhancedContext(config) {
4205
4982
  });
4206
4983
  }
4207
4984
 
4208
- // src/engine/stores.ts
4209
- var InMemoryStore = class {
4210
- data = /* @__PURE__ */ new Map();
4211
- async get(key) {
4212
- return this.data.get(key);
4213
- }
4214
- async set(key, value) {
4215
- this.data.set(key, value);
4216
- }
4217
- async has(key) {
4218
- return this.data.has(key);
4219
- }
4220
- async delete(key) {
4221
- this.data.delete(key);
4222
- }
4223
- async clear() {
4224
- this.data.clear();
4225
- }
4226
- // Extra methods for testing
4227
- size() {
4228
- return this.data.size;
4229
- }
4230
- keys() {
4231
- return Array.from(this.data.keys());
4232
- }
4233
- };
4234
- var InMemoryTrace = class {
4235
- entries = [];
4236
- async log(entry) {
4237
- this.entries.push(entry);
4238
- }
4239
- async getEntries() {
4240
- return [...this.entries];
4241
- }
4242
- // Extra methods for testing
4243
- clear() {
4244
- this.entries = [];
4245
- }
4246
- count() {
4247
- return this.entries.length;
4248
- }
4249
- getEntriesByType(type) {
4250
- return this.entries.filter((e) => e.type === type);
4251
- }
4252
- };
4253
-
4254
4985
  // src/engine/workflow.ts
4255
4986
  async function runWorkflow(config, inputs) {
4256
4987
  const store = config.state?.store ?? new InMemoryStore();
@@ -4262,6 +4993,7 @@ async function runWorkflow(config, inputs) {
4262
4993
  enableConversation: config.enhancements?.conversation !== void 0,
4263
4994
  enableMemory: config.enhancements?.memory !== void 0,
4264
4995
  enableSession: config.enhancements?.session !== void 0,
4996
+ enableAppState: config.enhancements?.appState,
4265
4997
  ui: config.enhancements?.ui
4266
4998
  });
4267
4999
  const result = await executeNode(
@@ -4272,6 +5004,10 @@ async function runWorkflow(config, inputs) {
4272
5004
  );
4273
5005
  return result;
4274
5006
  }
5007
+ async function runTSXWorkflow(workflowAST, inputs) {
5008
+ const config = compileWorkflow(workflowAST);
5009
+ return runWorkflow(config, inputs);
5010
+ }
4275
5011
  async function executeNode(node, ctx, adapter, config) {
4276
5012
  switch (node.type) {
4277
5013
  case "step":
@@ -4284,6 +5020,8 @@ async function executeNode(node, ctx, adapter, config) {
4284
5020
  return executeConditionalNode(node, ctx, adapter, config);
4285
5021
  case "loop":
4286
5022
  return executeLoopNode(node, ctx, adapter, config);
5023
+ case "foreach":
5024
+ return executeForEachNode(node, ctx, adapter, config);
4287
5025
  default:
4288
5026
  throw new Error(`Unknown node type: ${node.type}`);
4289
5027
  }
@@ -4369,6 +5107,116 @@ async function executeLoopNode(node, ctx, adapter, config) {
4369
5107
  }
4370
5108
  return results;
4371
5109
  }
5110
+ async function executeForEachNode(node, ctx, adapter, config) {
5111
+ if (!node.children || node.children.length === 0) {
5112
+ throw new Error("ForEach node has no children");
5113
+ }
5114
+ if (!node.itemsAccessor) {
5115
+ throw new Error("ForEach node missing itemsAccessor");
5116
+ }
5117
+ let items;
5118
+ if (typeof node.itemsAccessor === "function") {
5119
+ items = await Promise.resolve(node.itemsAccessor(ctx));
5120
+ } else {
5121
+ items = node.itemsAccessor;
5122
+ }
5123
+ if (!Array.isArray(items)) {
5124
+ throw new Error("ForEach items must be an array");
5125
+ }
5126
+ const itemMode = node.itemMode ?? "property";
5127
+ const itemKey = node.itemKey ?? "currentItem";
5128
+ const errorMode = node.errorMode ?? "stop";
5129
+ const collectResults = node.collectResults ?? true;
5130
+ const results = [];
5131
+ const errors = [];
5132
+ let successCount = 0;
5133
+ let failureCount = 0;
5134
+ for (let i = 0; i < items.length; i++) {
5135
+ const item = items[i];
5136
+ try {
5137
+ const iterationCtx = createIterationContext(
5138
+ ctx,
5139
+ item,
5140
+ i,
5141
+ items.length,
5142
+ itemMode,
5143
+ itemKey
5144
+ );
5145
+ const result = await executeNode(node.children[0], iterationCtx, adapter, config);
5146
+ if (collectResults) {
5147
+ results.push(result);
5148
+ }
5149
+ successCount++;
5150
+ } catch (error) {
5151
+ failureCount++;
5152
+ const err = error instanceof Error ? error : new Error(String(error));
5153
+ if (errorMode === "stop") {
5154
+ throw err;
5155
+ } else if (errorMode === "continue") {
5156
+ errors.push({ index: i, item, error: err });
5157
+ } else ;
5158
+ }
5159
+ }
5160
+ if (errorMode === "continue" && (errors.length > 0 || failureCount > 0)) {
5161
+ return {
5162
+ results,
5163
+ errors,
5164
+ totalItems: items.length,
5165
+ successCount,
5166
+ failureCount
5167
+ };
5168
+ }
5169
+ return results;
5170
+ }
5171
+ function createIterationContext(baseCtx, currentItem, index, totalItems, itemMode, itemKey) {
5172
+ let newInputs;
5173
+ if (itemMode === "property") {
5174
+ newInputs = {
5175
+ ...baseCtx.inputs,
5176
+ [itemKey]: currentItem,
5177
+ __forEachIndex: index,
5178
+ __forEachTotal: totalItems,
5179
+ __forEachIsLast: index === totalItems - 1
5180
+ };
5181
+ } else if (itemMode === "merge") {
5182
+ if (typeof currentItem === "object" && currentItem !== null) {
5183
+ newInputs = {
5184
+ ...baseCtx.inputs,
5185
+ ...currentItem,
5186
+ __forEachIndex: index,
5187
+ __forEachTotal: totalItems,
5188
+ __forEachIsLast: index === totalItems - 1
5189
+ };
5190
+ } else {
5191
+ throw new Error(
5192
+ `ForEach itemMode='merge' requires object items, got ${typeof currentItem}`
5193
+ );
5194
+ }
5195
+ } else if (itemMode === "replace") {
5196
+ if (typeof currentItem === "object" && currentItem !== null) {
5197
+ newInputs = {
5198
+ ...currentItem,
5199
+ __forEachIndex: index,
5200
+ __forEachTotal: totalItems,
5201
+ __forEachIsLast: index === totalItems - 1
5202
+ };
5203
+ } else {
5204
+ newInputs = currentItem;
5205
+ }
5206
+ } else {
5207
+ throw new Error(`Unknown itemMode: ${itemMode}`);
5208
+ }
5209
+ if (baseCtx instanceof ExecutionContext) {
5210
+ return baseCtx.withInputs(newInputs).withIteration(index, totalItems);
5211
+ }
5212
+ return {
5213
+ ...baseCtx,
5214
+ inputs: newInputs,
5215
+ iteration: index,
5216
+ maxIterations: totalItems,
5217
+ isLastIteration: index === totalItems - 1
5218
+ };
5219
+ }
4372
5220
  function createStepNode(component) {
4373
5221
  return {
4374
5222
  type: "step",
@@ -4402,257 +5250,17 @@ function createLoopNode(child, maxIterations) {
4402
5250
  };
4403
5251
  }
4404
5252
 
4405
- // src/engine/tool-result-extractor.ts
4406
- function extractLastToolResult(llmResult, toolName, options = {}) {
4407
- const { unwrap = true, required = true } = options;
4408
- if (llmResult.response?.toolCalls && llmResult.response.toolCalls.length > 0) {
4409
- const toolCalls = llmResult.response.toolCalls.filter(
4410
- (tc) => tc.name === toolName
4411
- );
4412
- if (toolCalls.length > 0) {
4413
- const lastCall = toolCalls[toolCalls.length - 1];
4414
- return parseToolCall(lastCall, unwrap);
4415
- }
4416
- }
4417
- const toolMessages = llmResult.messages.filter(
4418
- (msg) => msg.role === "tool" && msg.name === toolName
4419
- );
4420
- if (toolMessages.length === 0) {
4421
- if (required) {
4422
- throw new Error(`Tool '${toolName}' was not called`);
4423
- }
4424
- return null;
4425
- }
4426
- const lastMessage = toolMessages[toolMessages.length - 1];
4427
- return parseToolResult(lastMessage.content, unwrap);
4428
- }
4429
- function extractAllToolResults(llmResult, toolName, options = {}) {
4430
- const { unwrap = true, filterSuccess = false } = options;
4431
- if (llmResult.response?.toolCalls && llmResult.response.toolCalls.length > 0) {
4432
- const toolCalls = llmResult.response.toolCalls.filter(
4433
- (tc) => tc.name === toolName
4434
- );
4435
- if (toolCalls.length > 0) {
4436
- let results2 = toolCalls.map((tc) => {
4437
- try {
4438
- return parseToolCall(tc, unwrap);
4439
- } catch {
4440
- return null;
4441
- }
4442
- }).filter((r) => r !== null);
4443
- if (filterSuccess && unwrap) {
4444
- results2 = results2.filter((result) => {
4445
- if (result && typeof result === "object" && "success" in result) {
4446
- return result.success === true;
4447
- }
4448
- return true;
4449
- });
4450
- }
4451
- return results2;
4452
- }
4453
- }
4454
- const toolMessages = llmResult.messages.filter(
4455
- (msg) => msg.role === "tool" && msg.name === toolName
4456
- );
4457
- let results = toolMessages.map((msg) => {
4458
- try {
4459
- return parseToolResult(msg.content, unwrap);
4460
- } catch {
4461
- return null;
4462
- }
4463
- }).filter((r) => r !== null);
4464
- if (filterSuccess && unwrap) {
4465
- results = results.filter((result) => {
4466
- if (result && typeof result === "object" && "success" in result) {
4467
- return result.success === true;
4468
- }
4469
- return true;
4470
- });
4471
- }
4472
- return results;
4473
- }
4474
- function countToolCalls(llmResult, toolName, filter) {
4475
- if (llmResult.response?.toolCalls && llmResult.response.toolCalls.length > 0) {
4476
- const toolCalls = llmResult.response.toolCalls.filter(
4477
- (tc) => tc.name === toolName
4478
- );
4479
- if (toolCalls.length > 0) {
4480
- if (!filter) {
4481
- return toolCalls.length;
4482
- }
4483
- return toolCalls.filter((tc) => {
4484
- try {
4485
- const parsed = parseToolCall(tc, true);
4486
- return filter(parsed);
4487
- } catch {
4488
- return false;
4489
- }
4490
- }).length;
4491
- }
4492
- }
4493
- const toolMessages = llmResult.messages.filter(
4494
- (msg) => msg.role === "tool" && msg.name === toolName
4495
- );
4496
- if (!filter) {
4497
- return toolMessages.length;
4498
- }
4499
- return toolMessages.filter((msg) => {
4500
- try {
4501
- const result = JSON.parse(msg.content);
4502
- return filter(result);
4503
- } catch {
4504
- return false;
4505
- }
4506
- }).length;
4507
- }
4508
- function parseToolCall(toolCall, unwrap) {
4509
- try {
4510
- if (toolCall._executionResult) {
4511
- const result = JSON.parse(toolCall._executionResult);
4512
- if (unwrap && result && typeof result === "object") {
4513
- if ("success" in result) {
4514
- if (result.success === false && result.error) {
4515
- throw new Error(`Tool execution failed: ${result.error}`);
4516
- }
4517
- return result.data !== void 0 ? result.data : result;
4518
- }
4519
- }
4520
- return result;
4521
- }
4522
- return toolCall.arguments;
4523
- } catch (error) {
4524
- throw new Error(`Failed to parse tool call: ${error.message}`);
4525
- }
4526
- }
4527
- function parseToolResult(content, unwrap) {
4528
- try {
4529
- const parsed = JSON.parse(content);
4530
- if (unwrap && parsed && typeof parsed === "object") {
4531
- if ("success" in parsed) {
4532
- if (parsed.success === false && parsed.error) {
4533
- throw new Error(`Tool execution failed: ${parsed.error}`);
4534
- }
4535
- return parsed.data !== void 0 ? parsed.data : parsed;
4536
- }
4537
- }
4538
- return parsed;
4539
- } catch (error) {
4540
- throw new Error(`Failed to parse tool result: ${error.message}`);
4541
- }
4542
- }
4543
- var MemoryStoreInputSchema = zod.z.object({
4544
- key: zod.z.string().describe("Unique identifier for this memory entry"),
4545
- content: zod.z.string().min(20).describe("Content to store (minimum 20 characters for meaningful data)"),
4546
- importance: zod.z.number().min(0).max(10).optional().default(5).describe("Importance level (0-10, higher = more important, default: 5)"),
4547
- category: zod.z.string().optional().describe('Category for filtering and organization (e.g., "architecture", "planning")'),
4548
- tags: zod.z.array(zod.z.string()).optional().default([]).describe("Tags for relevance matching and retrieval")
4549
- });
4550
- var MemoryRecallInputSchema = zod.z.object({
4551
- query: zod.z.string().describe("Search query or keywords to find relevant memories"),
4552
- category: zod.z.string().optional().describe("Filter results by category"),
4553
- limit: zod.z.number().min(1).max(20).optional().default(5).describe("Maximum number of memories to return (default: 5, max: 20)")
4554
- });
4555
- function createMemoryTools(ctx) {
4556
- if (!ctx.memory) {
4557
- throw new Error(
4558
- "Cannot create memory tools: Memory is not enabled in ExecutionContext. Use createEnhancedContext({ enableMemory: true }) to enable memory."
4559
- );
4560
- }
4561
- const memory = ctx.memory;
4562
- return [
4563
- // ========================================================================
4564
- // memory_store
4565
- // ========================================================================
4566
- {
4567
- name: "memory_store",
4568
- description: "Store important findings, insights, or context for later retrieval. Use this to remember key information that will be useful in subsequent analysis phases.",
4569
- inputSchema: MemoryStoreInputSchema,
4570
- execute: async (params) => {
4571
- try {
4572
- const memoryData = {
4573
- content: params.content,
4574
- importance: params.importance,
4575
- category: params.category,
4576
- tags: params.tags,
4577
- stored_at: (/* @__PURE__ */ new Date()).toISOString()
4578
- };
4579
- await memory.set(params.key, memoryData);
4580
- return {
4581
- success: true,
4582
- key: params.key,
4583
- stored_at: memoryData.stored_at,
4584
- message: `Memory '${params.key}' stored successfully`
4585
- };
4586
- } catch (error) {
4587
- const errorMsg = error instanceof Error ? error.message : String(error);
4588
- return {
4589
- success: false,
4590
- error: `Failed to store memory: ${errorMsg}`
4591
- };
4592
- }
4593
- }
4594
- },
4595
- // ========================================================================
4596
- // memory_recall
4597
- // ========================================================================
4598
- {
4599
- name: "memory_recall",
4600
- description: "Recall previously stored memories by searching with keywords or queries. Returns the most relevant memories based on content similarity, category, tags, and importance.",
4601
- inputSchema: MemoryRecallInputSchema,
4602
- execute: async (params) => {
4603
- try {
4604
- const keywords = params.query.toLowerCase().split(/\s+/).filter((word) => word.length > 3);
4605
- const memories = await memory.loadWorkingMemory({
4606
- currentTask: params.query,
4607
- keywords,
4608
- categories: params.category ? [params.category] : void 0
4609
- });
4610
- const limit = params.limit ?? 5;
4611
- const results = memories.slice(0, limit);
4612
- const formattedMemories = results.map((m) => {
4613
- let content = m.content;
4614
- try {
4615
- const parsed = JSON.parse(m.content);
4616
- content = parsed.content || m.content;
4617
- } catch {
4618
- }
4619
- return {
4620
- key: m.id,
4621
- content,
4622
- importance: m.importance,
4623
- category: m.category,
4624
- tags: m.tags,
4625
- stored_at: m.stored_at,
4626
- access_count: m.access_count
4627
- };
4628
- });
4629
- return {
4630
- success: true,
4631
- count: formattedMemories.length,
4632
- total_available: memories.length,
4633
- memories: formattedMemories,
4634
- message: `Found ${formattedMemories.length} relevant memories`
4635
- };
4636
- } catch (error) {
4637
- const errorMsg = error instanceof Error ? error.message : String(error);
4638
- return {
4639
- success: false,
4640
- error: `Failed to recall memories: ${errorMsg}`,
4641
- memories: []
4642
- };
4643
- }
4644
- }
4645
- }
4646
- ];
4647
- }
4648
-
4649
5253
  exports.Agent = Agent;
5254
+ exports.Conditional = Conditional;
4650
5255
  exports.DEBUG_ENABLED = DEBUG_ENABLED;
4651
5256
  exports.DebugLogger = DebugLogger;
5257
+ exports.ForEach = ForEach;
4652
5258
  exports.InMemoryStore = InMemoryStore;
4653
5259
  exports.InMemoryTrace = InMemoryTrace;
5260
+ exports.Loop = Loop;
4654
5261
  exports.Observe = Observe;
4655
5262
  exports.ObserveUtils = ObserveUtils;
5263
+ exports.Parallel = Parallel;
4656
5264
  exports.PreflightChecker = PreflightChecker;
4657
5265
  exports.Prompt = Prompt;
4658
5266
  exports.PromptResourceLoader = PromptResourceLoader;
@@ -4660,23 +5268,27 @@ exports.Result = Result;
4660
5268
  exports.ResultUtils = ResultUtils;
4661
5269
  exports.Retry = Retry;
4662
5270
  exports.RetryUtils = RetryUtils;
5271
+ exports.Sequence = Sequence;
4663
5272
  exports.System = System;
5273
+ exports.Tool = Tool;
5274
+ exports.ToolDef = ToolDef;
5275
+ exports.ToolRef = ToolRef;
5276
+ exports.Tools = Tools;
4664
5277
  exports.User = User;
4665
5278
  exports.Validate = Validate;
4666
5279
  exports.ValidateUtils = ValidateUtils;
5280
+ exports.Workflow = Workflow;
4667
5281
  exports.compileAgent = compileAgent;
4668
- exports.countToolCalls = countToolCalls;
5282
+ exports.compileWorkflow = compileWorkflow;
5283
+ exports.compileWorkflowNode = compileWorkflowNode;
4669
5284
  exports.createConditionalNode = createConditionalNode;
4670
5285
  exports.createEnhancedContext = createEnhancedContext;
4671
5286
  exports.createLoopNode = createLoopNode;
4672
- exports.createMemoryTools = createMemoryTools;
4673
5287
  exports.createParallelNode = createParallelNode;
4674
5288
  exports.createSequenceNode = createSequenceNode;
4675
5289
  exports.createStepNode = createStepNode;
4676
5290
  exports.executeComponent = executeComponent;
4677
5291
  exports.executeLLMLoop = executeLLMLoop;
4678
- exports.extractAllToolResults = extractAllToolResults;
4679
- exports.extractLastToolResult = extractLastToolResult;
4680
5292
  exports.getResourceLoader = getResourceLoader;
4681
5293
  exports.isAgentNode = isAgentNode;
4682
5294
  exports.isObserveNode = isObserveNode;
@@ -4684,12 +5296,24 @@ exports.isPromptNode = isPromptNode;
4684
5296
  exports.isResultNode = isResultNode;
4685
5297
  exports.isRetryNode = isRetryNode;
4686
5298
  exports.isSystemNode = isSystemNode;
5299
+ exports.isToolDefNode = isToolDefNode;
5300
+ exports.isToolRefNode = isToolRefNode;
5301
+ exports.isToolsNode = isToolsNode;
4687
5302
  exports.isUserNode = isUserNode;
4688
5303
  exports.isValidateNode = isValidateNode;
5304
+ exports.isWorkflowConditionalNode = isWorkflowConditionalNode;
5305
+ exports.isWorkflowForEachNode = isWorkflowForEachNode;
5306
+ exports.isWorkflowLoopNode = isWorkflowLoopNode;
5307
+ exports.isWorkflowNode = isWorkflowNode;
5308
+ exports.isWorkflowParallelNode = isWorkflowParallelNode;
5309
+ exports.isWorkflowSequenceNode = isWorkflowSequenceNode;
4689
5310
  exports.logger = logger;
4690
5311
  exports.preflight = preflight;
5312
+ exports.runTSXWorkflow = runTSXWorkflow;
4691
5313
  exports.runWorkflow = runWorkflow;
4692
5314
  exports.setResourceLoader = setResourceLoader;
4693
5315
  exports.testFullAgent = testFullAgent;
5316
+ exports.toAgent = toAgent;
5317
+ exports.toWorkflow = toWorkflow;
4694
5318
  //# sourceMappingURL=index.cjs.map
4695
5319
  //# sourceMappingURL=index.cjs.map