@limo-labs/deity 0.2.0-alpha.0 → 0.2.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,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,241 @@ 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
+ if (children) {
514
+ if (execute) {
515
+ throw new Error("Tool: cannot use both children and execute prop");
516
+ }
517
+ let actualChild = children;
518
+ if (Array.isArray(children)) {
519
+ if (children.length === 0) {
520
+ throw new Error("Tool: children array is empty");
521
+ }
522
+ if (children.length > 1) {
523
+ throw new Error("Tool: can only have one child (the execute function)");
524
+ }
525
+ actualChild = children[0];
526
+ }
527
+ if (typeof actualChild === "object" && actualChild !== null && "type" in actualChild) {
528
+ const node = actualChild;
529
+ if (node.type === "ComputedText" && node.props?.compute) {
530
+ executeFn = node.props.compute;
531
+ } else {
532
+ throw new Error("Tool: invalid child node type (expected ComputedText with execute function)");
533
+ }
534
+ } else if (typeof actualChild === "function") {
535
+ executeFn = actualChild;
536
+ } else {
537
+ throw new Error("Tool: children must be a function");
538
+ }
539
+ } else if (execute) {
540
+ executeFn = execute;
541
+ } else {
542
+ throw new Error("Tool: must provide children (execute function) or execute prop");
543
+ }
544
+ const toolSpec = {
545
+ name,
546
+ description,
547
+ inputSchema: input,
548
+ execute: executeFn
549
+ };
550
+ return {
551
+ type: "Tools:Def",
552
+ props: { tool: toolSpec }
553
+ };
554
+ }
555
+
556
+ // src/components/ToolRef.tsx
557
+ function ToolRef(props) {
558
+ const { tool } = props;
559
+ let toolName;
560
+ if (tool === null || tool === void 0) {
561
+ throw new Error(
562
+ "ToolRef: `tool` prop must be a tool component with .toolName, a ToolSpec with .name, or a string tool ID"
563
+ );
564
+ }
565
+ if (typeof tool === "string") {
566
+ toolName = tool;
567
+ } else if (typeof tool === "function" && "toolName" in tool && typeof tool.toolName === "string") {
568
+ toolName = tool.toolName;
569
+ } else if (typeof tool === "object" && "toolName" in tool && typeof tool.toolName === "string") {
570
+ toolName = tool.toolName;
571
+ } else if (typeof tool === "object" && "name" in tool && typeof tool.name === "string") {
572
+ toolName = tool.name;
573
+ } else {
574
+ throw new Error(
575
+ "ToolRef: `tool` prop must be a tool component with .toolName, a ToolSpec with .name, or a string tool ID"
576
+ );
577
+ }
578
+ return {
579
+ type: "ToolRef",
580
+ props: { toolName }
581
+ };
582
+ }
583
+
584
+ // src/components/Sequence.tsx
585
+ function Sequence(props) {
586
+ const { children } = props;
587
+ if (!children || children.length === 0) {
588
+ throw new Error("Sequence: must have at least one child");
589
+ }
590
+ return {
591
+ type: "WorkflowSequence",
592
+ children
593
+ };
594
+ }
595
+
596
+ // src/components/Parallel.tsx
597
+ function Parallel(props) {
598
+ const { children } = props;
599
+ if (!children || children.length === 0) {
600
+ throw new Error("Parallel: must have at least one child");
601
+ }
602
+ return {
603
+ type: "WorkflowParallel",
604
+ children
605
+ };
606
+ }
607
+
608
+ // src/components/Conditional.tsx
609
+ function Conditional(props) {
610
+ const { condition, children } = props;
611
+ if (!condition) {
612
+ throw new Error("Conditional: condition prop is required");
613
+ }
614
+ if (!children) {
615
+ throw new Error("Conditional: must have at least one child (true branch)");
616
+ }
617
+ if (children.length < 1 || children.length > 2) {
618
+ throw new Error("Conditional: must have 1-2 children (true branch required, false branch optional)");
619
+ }
620
+ return {
621
+ type: "WorkflowConditional",
622
+ props: {
623
+ condition
624
+ },
625
+ children
626
+ };
627
+ }
628
+
629
+ // src/components/Loop.tsx
630
+ function Loop(props) {
631
+ const { iterations, children } = props;
632
+ if (!iterations || iterations < 1) {
633
+ throw new Error("Loop: iterations must be >= 1");
634
+ }
635
+ if (!children) {
636
+ throw new Error("Loop: must have exactly one child");
637
+ }
638
+ const childArray = Array.isArray(children) ? children : [children];
639
+ if (childArray.length !== 1) {
640
+ throw new Error("Loop: must have exactly one child");
641
+ }
642
+ return {
643
+ type: "WorkflowLoop",
644
+ props: {
645
+ iterations
646
+ },
647
+ children: [childArray[0]]
648
+ };
649
+ }
650
+
651
+ // src/components/ForEach.tsx
652
+ function ForEach(props) {
653
+ const {
654
+ items,
655
+ itemMode = "property",
656
+ itemKey = "currentItem",
657
+ errorMode = "stop",
658
+ collectResults = true,
659
+ children
660
+ } = props;
661
+ if (!items) {
662
+ throw new Error("ForEach: items prop is required");
663
+ }
664
+ if (!children) {
665
+ throw new Error("ForEach: must have exactly one child");
666
+ }
667
+ const childArray = Array.isArray(children) ? children : [children];
668
+ if (childArray.length !== 1) {
669
+ throw new Error("ForEach: must have exactly one child");
670
+ }
671
+ const validModes = ["merge", "replace", "property"];
672
+ if (!validModes.includes(itemMode)) {
673
+ throw new Error(`ForEach: itemMode must be one of: ${validModes.join(", ")}`);
674
+ }
675
+ const validErrorModes = ["stop", "continue", "skip"];
676
+ if (!validErrorModes.includes(errorMode)) {
677
+ throw new Error(`ForEach: errorMode must be one of: ${validErrorModes.join(", ")}`);
678
+ }
679
+ return {
680
+ type: "WorkflowForEach",
681
+ props: {
682
+ items,
683
+ itemMode,
684
+ itemKey,
685
+ errorMode,
686
+ collectResults
687
+ },
688
+ children: [childArray[0]]
689
+ };
690
+ }
691
+
692
+ // src/components/Workflow.tsx
693
+ function Workflow(props) {
694
+ const { name, description, defaultModel, state, enhancements, children } = props;
695
+ if (!name) {
696
+ throw new Error("Workflow: name is required");
697
+ }
698
+ if (!children) {
699
+ throw new Error("Workflow: must have exactly one child (workflow graph)");
700
+ }
701
+ const childArray = Array.isArray(children) ? children : [children];
702
+ if (childArray.length !== 1) {
703
+ throw new Error("Workflow: must have exactly one child (workflow graph)");
704
+ }
705
+ return {
706
+ type: "Workflow",
707
+ props: {
708
+ name,
709
+ description,
710
+ defaultModel,
711
+ state,
712
+ enhancements
713
+ },
714
+ children: [childArray[0]]
715
+ };
716
+ }
399
717
  var PromptResourceLoader = class {
400
718
  cache = /* @__PURE__ */ new Map();
401
719
  options;
@@ -605,7 +923,25 @@ function compilePrompt(promptNode) {
605
923
  };
606
924
  }
607
925
  async function resolveSystemContent(node, ctx) {
608
- const { source, content, compute, required = false } = node.props;
926
+ const { source, content, compute, required = false, templateParts } = node.props;
927
+ if (templateParts) {
928
+ const resolved = await Promise.all(
929
+ templateParts.map(async (part) => {
930
+ switch (part.kind) {
931
+ case "text":
932
+ return part.value;
933
+ case "computed":
934
+ return await Promise.resolve(part.compute(ctx));
935
+ case "toolref":
936
+ return part.toolName;
937
+ default:
938
+ const _exhaustive = part;
939
+ throw new Error(`Unknown template part kind: ${_exhaustive.kind}`);
940
+ }
941
+ })
942
+ );
943
+ return resolved.join("");
944
+ }
609
945
  if (source) {
610
946
  if (!source.startsWith("file:")) {
611
947
  throw new Error(`Invalid source format: ${source} (must start with "file:")`);
@@ -626,17 +962,35 @@ async function resolveSystemContent(node, ctx) {
626
962
  if (compute) {
627
963
  return await Promise.resolve(compute(ctx));
628
964
  }
629
- throw new Error("System node must have source, content, or compute");
965
+ throw new Error("System node must have source, content, compute, or templateParts");
630
966
  }
631
967
  async function resolveUserContent(node, ctx) {
632
- const { content, compute } = node.props;
968
+ const { content, compute, templateParts } = node.props;
969
+ if (templateParts) {
970
+ const resolved = await Promise.all(
971
+ templateParts.map(async (part) => {
972
+ switch (part.kind) {
973
+ case "text":
974
+ return part.value;
975
+ case "computed":
976
+ return await Promise.resolve(part.compute(ctx));
977
+ case "toolref":
978
+ return part.toolName;
979
+ default:
980
+ const _exhaustive = part;
981
+ throw new Error(`Unknown template part kind: ${_exhaustive.kind}`);
982
+ }
983
+ })
984
+ );
985
+ return resolved.join("");
986
+ }
633
987
  if (content !== void 0) {
634
988
  return content;
635
989
  }
636
990
  if (compute) {
637
991
  return await Promise.resolve(compute(ctx));
638
992
  }
639
- throw new Error("User node must have content or compute");
993
+ throw new Error("User node must have content, compute, or templateParts");
640
994
  }
641
995
 
642
996
  // src/compiler/compile-agent.ts
@@ -766,6 +1120,184 @@ function compileAgent(ast) {
766
1120
  // src/compiler/index.ts
767
1121
  init_compile_observe();
768
1122
 
1123
+ // src/compiler/compile-workflow-node.ts
1124
+ function compileWorkflowNode(node) {
1125
+ switch (node.type) {
1126
+ case "Agent":
1127
+ return compileAgentNode(node);
1128
+ case "WorkflowSequence":
1129
+ return compileSequenceNode(node);
1130
+ case "WorkflowParallel":
1131
+ return compileParallelNode(node);
1132
+ case "WorkflowConditional":
1133
+ return compileConditionalNode(node);
1134
+ case "WorkflowLoop":
1135
+ return compileLoopNode(node);
1136
+ case "WorkflowForEach":
1137
+ return compileForEachNode(node);
1138
+ default:
1139
+ throw new Error(`Unknown workflow node type: ${node.type}`);
1140
+ }
1141
+ }
1142
+ function compileAgentNode(node) {
1143
+ const lazyComponent = createLazyAgentComponent(node);
1144
+ return {
1145
+ type: "step",
1146
+ component: lazyComponent
1147
+ };
1148
+ }
1149
+ function compileSequenceNode(node) {
1150
+ if (!node.children || node.children.length === 0) {
1151
+ throw new Error("Sequence node must have children");
1152
+ }
1153
+ const children = node.children.map((child) => compileWorkflowNode(child));
1154
+ return {
1155
+ type: "sequence",
1156
+ children
1157
+ };
1158
+ }
1159
+ function compileParallelNode(node) {
1160
+ if (!node.children || node.children.length === 0) {
1161
+ throw new Error("Parallel node must have children");
1162
+ }
1163
+ const children = node.children.map((child) => compileWorkflowNode(child));
1164
+ return {
1165
+ type: "parallel",
1166
+ children
1167
+ };
1168
+ }
1169
+ function compileConditionalNode(node) {
1170
+ if (!node.props?.condition) {
1171
+ throw new Error("Conditional node must have a condition function");
1172
+ }
1173
+ if (!node.children || node.children.length < 1 || node.children.length > 2) {
1174
+ throw new Error("Conditional node must have 1-2 children (true branch required, false branch optional)");
1175
+ }
1176
+ const children = node.children.map((child) => compileWorkflowNode(child));
1177
+ return {
1178
+ type: "conditional",
1179
+ condition: node.props.condition,
1180
+ children
1181
+ };
1182
+ }
1183
+ function compileLoopNode(node) {
1184
+ if (!node.props?.iterations || node.props.iterations < 1) {
1185
+ throw new Error("Loop node must have iterations >= 1");
1186
+ }
1187
+ if (!node.children || node.children.length !== 1) {
1188
+ throw new Error("Loop node must have exactly one child");
1189
+ }
1190
+ const child = compileWorkflowNode(node.children[0]);
1191
+ return {
1192
+ type: "loop",
1193
+ maxIterations: node.props.iterations,
1194
+ children: [child]
1195
+ };
1196
+ }
1197
+ function compileForEachNode(node) {
1198
+ if (!node.props?.items) {
1199
+ throw new Error("ForEach node must have items prop");
1200
+ }
1201
+ if (!node.children || node.children.length !== 1) {
1202
+ throw new Error("ForEach node must have exactly one child");
1203
+ }
1204
+ const child = compileWorkflowNode(node.children[0]);
1205
+ return {
1206
+ type: "foreach",
1207
+ itemsAccessor: node.props.items,
1208
+ itemMode: node.props.itemMode,
1209
+ itemKey: node.props.itemKey,
1210
+ errorMode: node.props.errorMode,
1211
+ collectResults: node.props.collectResults,
1212
+ children: [child]
1213
+ };
1214
+ }
1215
+ function createLazyAgentComponent(astNode) {
1216
+ let compiled = null;
1217
+ const ensureCompiled = () => {
1218
+ if (!compiled) {
1219
+ compiled = compileAgent(astNode);
1220
+ }
1221
+ return compiled;
1222
+ };
1223
+ const proxy = {
1224
+ get id() {
1225
+ return astNode.props.id;
1226
+ },
1227
+ get inputSchema() {
1228
+ return astNode.props.input;
1229
+ },
1230
+ get outputSchema() {
1231
+ return astNode.props.output;
1232
+ },
1233
+ get tools() {
1234
+ return astNode.props.tools;
1235
+ },
1236
+ get loopValidator() {
1237
+ return astNode.props.loopValidator;
1238
+ },
1239
+ get loopConfig() {
1240
+ return astNode.props.loopConfig;
1241
+ },
1242
+ // Lazy methods - compile on first call
1243
+ buildPrompt(ctx) {
1244
+ return ensureCompiled().buildPrompt(ctx);
1245
+ },
1246
+ get retry() {
1247
+ return ensureCompiled().retry;
1248
+ },
1249
+ get model() {
1250
+ return ensureCompiled().model;
1251
+ }
1252
+ };
1253
+ const hasResultNode = astNode.children.some((child) => child.type === "Result");
1254
+ if (hasResultNode) {
1255
+ proxy.extractOutput = (ctx, llmResult) => {
1256
+ return ensureCompiled().extractOutput(ctx, llmResult);
1257
+ };
1258
+ }
1259
+ const hasValidateNode = astNode.children.some((child) => child.type === "Validate");
1260
+ if (hasValidateNode) {
1261
+ proxy.validateOutput = (output, ctx) => {
1262
+ const comp = ensureCompiled();
1263
+ return comp.validateOutput(output, ctx);
1264
+ };
1265
+ }
1266
+ return proxy;
1267
+ }
1268
+
1269
+ // src/compiler/compile-workflow.ts
1270
+ function compileWorkflow(ast) {
1271
+ if (ast.type !== "Workflow") {
1272
+ throw new Error(`Expected Workflow node, got ${ast.type}`);
1273
+ }
1274
+ if (!ast.children || ast.children.length !== 1) {
1275
+ throw new Error("Workflow must have exactly one child (workflow graph)");
1276
+ }
1277
+ const { name, description, defaultModel, state, enhancements } = ast.props;
1278
+ if (!name) {
1279
+ throw new Error("Workflow must have a name");
1280
+ }
1281
+ const graph = compileWorkflowNode(ast.children[0]);
1282
+ const config = {
1283
+ name,
1284
+ graph
1285
+ };
1286
+ if (description) {
1287
+ config.description = description;
1288
+ }
1289
+ if (defaultModel) {
1290
+ config.defaultModel = defaultModel;
1291
+ }
1292
+ if (state) {
1293
+ config.state = state;
1294
+ }
1295
+ if (enhancements) {
1296
+ config.enhancements = enhancements;
1297
+ }
1298
+ return config;
1299
+ }
1300
+
769
1301
  // src/ast/types.ts
770
1302
  function isAgentNode(node) {
771
1303
  return node.type === "Agent";
@@ -791,6 +1323,33 @@ function isValidateNode(node) {
791
1323
  function isRetryNode(node) {
792
1324
  return node.type === "Retry";
793
1325
  }
1326
+ function isToolsNode(node) {
1327
+ return node.type === "Tools";
1328
+ }
1329
+ function isToolDefNode(node) {
1330
+ return node.type === "Tools:Def";
1331
+ }
1332
+ function isToolRefNode(node) {
1333
+ return node.type === "ToolRef";
1334
+ }
1335
+ function isWorkflowSequenceNode(node) {
1336
+ return node.type === "WorkflowSequence";
1337
+ }
1338
+ function isWorkflowParallelNode(node) {
1339
+ return node.type === "WorkflowParallel";
1340
+ }
1341
+ function isWorkflowConditionalNode(node) {
1342
+ return node.type === "WorkflowConditional";
1343
+ }
1344
+ function isWorkflowLoopNode(node) {
1345
+ return node.type === "WorkflowLoop";
1346
+ }
1347
+ function isWorkflowForEachNode(node) {
1348
+ return node.type === "WorkflowForEach";
1349
+ }
1350
+ function isWorkflowNode(node) {
1351
+ return node.type === "Workflow";
1352
+ }
794
1353
 
795
1354
  // src/utilities/observe-utils.ts
796
1355
  var ObserveUtils = class {
@@ -1986,6 +2545,20 @@ var RetryUtils = class {
1986
2545
  }
1987
2546
  };
1988
2547
 
2548
+ // src/utilities/jsx-helpers.ts
2549
+ function toWorkflow(element) {
2550
+ if (element.type !== "Workflow") {
2551
+ throw new Error(`Expected Workflow element, got ${element.type}`);
2552
+ }
2553
+ return element;
2554
+ }
2555
+ function toAgent(element) {
2556
+ if (element.type !== "Agent") {
2557
+ throw new Error(`Expected Agent element, got ${element.type}`);
2558
+ }
2559
+ return element;
2560
+ }
2561
+
1989
2562
  // src/utilities/preflight.ts
1990
2563
  var PreflightChecker = class {
1991
2564
  options;
@@ -2413,6 +2986,7 @@ async function executeLLMLoop(adapter, initialMessages, tools, config, ctx, loop
2413
2986
  });
2414
2987
  }
2415
2988
  }
2989
+ const allPreExecuted = response.toolCalls.every((tc) => tc._alreadyExecuted);
2416
2990
  if (validator) {
2417
2991
  const loopState = {
2418
2992
  rounds,
@@ -2432,6 +3006,9 @@ async function executeLLMLoop(adapter, initialMessages, tools, config, ctx, loop
2432
3006
  });
2433
3007
  }
2434
3008
  }
3009
+ if (allPreExecuted) {
3010
+ break;
3011
+ }
2435
3012
  }
2436
3013
  return {
2437
3014
  response,
@@ -2771,10 +3348,11 @@ async function executeComponent(component, ctx, adapter, config) {
2771
3348
  ctx.ui?.stepProgress(component.id, 50, "Executing LLM...");
2772
3349
  const promptMessages = await Promise.resolve(component.buildPrompt(ctx));
2773
3350
  const messages = feedbackMessages ? [...promptMessages, ...feedbackMessages] : promptMessages;
3351
+ const resolvedTools = component.tools;
2774
3352
  const llmResult = await executeLLMLoop(
2775
3353
  adapter,
2776
3354
  messages,
2777
- component.tools,
3355
+ resolvedTools,
2778
3356
  config,
2779
3357
  ctx,
2780
3358
  component.loopConfig,
@@ -2884,6 +3462,8 @@ var ExecutionContext = class _ExecutionContext {
2884
3462
  ui;
2885
3463
  /** Session store (optional) */
2886
3464
  session;
3465
+ /** Application state store (optional, isolated from AI memory) */
3466
+ appState;
2887
3467
  /** Current stage ID (for UI updates) */
2888
3468
  currentStageId;
2889
3469
  // ========== Constructor ==========
@@ -2896,6 +3476,7 @@ var ExecutionContext = class _ExecutionContext {
2896
3476
  this.conversation = params.conversation;
2897
3477
  this.memory = params.memory;
2898
3478
  this.session = params.session;
3479
+ this.appState = params.appState;
2899
3480
  this.ui = params.ui;
2900
3481
  this.currentStageId = params.currentStageId;
2901
3482
  this.iteration = params.iteration;
@@ -2944,6 +3525,7 @@ var ExecutionContext = class _ExecutionContext {
2944
3525
  conversation: this.conversation,
2945
3526
  memory: this.memory,
2946
3527
  session: this.session,
3528
+ appState: this.appState,
2947
3529
  ui: this.ui,
2948
3530
  currentStageId: updates.currentStageId ?? this.currentStageId,
2949
3531
  iteration: updates.iteration ?? this.iteration,
@@ -2972,6 +3554,27 @@ var ExecutionContext = class _ExecutionContext {
2972
3554
  iterationHistory: this.iterationHistory
2973
3555
  });
2974
3556
  }
3557
+ /**
3558
+ * Update inputs (for ForEach iterations)
3559
+ */
3560
+ withInputs(inputs) {
3561
+ return new _ExecutionContext({
3562
+ inputs,
3563
+ previousOutputs: this.previousOutputs,
3564
+ store: this.store,
3565
+ trace: this.trace,
3566
+ stats: this.stats,
3567
+ conversation: this.conversation,
3568
+ memory: this.memory,
3569
+ session: this.session,
3570
+ appState: this.appState,
3571
+ ui: this.ui,
3572
+ currentStageId: this.currentStageId,
3573
+ iteration: this.iteration,
3574
+ maxIterations: this.maxIterations,
3575
+ iterationHistory: this.iterationHistory
3576
+ });
3577
+ }
2975
3578
  /**
2976
3579
  * Add to iteration history
2977
3580
  */
@@ -3005,6 +3608,12 @@ var ExecutionContext = class _ExecutionContext {
3005
3608
  hasUI() {
3006
3609
  return this.ui !== void 0;
3007
3610
  }
3611
+ /**
3612
+ * Check if appState is enabled
3613
+ */
3614
+ hasAppState() {
3615
+ return this.appState !== void 0;
3616
+ }
3008
3617
  /**
3009
3618
  * Get conversation manager (throws if not available)
3010
3619
  */
@@ -3041,6 +3650,15 @@ var ExecutionContext = class _ExecutionContext {
3041
3650
  }
3042
3651
  return this.ui;
3043
3652
  }
3653
+ /**
3654
+ * Get application state store (throws if not available)
3655
+ */
3656
+ requireAppState() {
3657
+ if (!this.appState) {
3658
+ throw new Error("Application state store not available in this context");
3659
+ }
3660
+ return this.appState;
3661
+ }
3044
3662
  // ========== Debugging ==========
3045
3663
  /**
3046
3664
  * Get context summary for debugging
@@ -3055,7 +3673,8 @@ var ExecutionContext = class _ExecutionContext {
3055
3673
  conversation: this.hasConversation(),
3056
3674
  memory: this.hasMemory(),
3057
3675
  session: this.hasSession(),
3058
- ui: this.hasUI()
3676
+ ui: this.hasUI(),
3677
+ appState: this.hasAppState()
3059
3678
  },
3060
3679
  stats: this.stats
3061
3680
  };
@@ -3491,6 +4110,81 @@ var LimoMemoryManager = class {
3491
4110
  getDetailedMemories() {
3492
4111
  return Array.from(this.detailedMemories.values());
3493
4112
  }
4113
+ /**
4114
+ * Get all memory keys (core + detailed)
4115
+ *
4116
+ * @returns Array of all memory keys
4117
+ */
4118
+ getAllKeys() {
4119
+ const keys = /* @__PURE__ */ new Set();
4120
+ for (const key of this.coreMemories.keys()) keys.add(key);
4121
+ for (const key of this.detailedMemories.keys()) keys.add(key);
4122
+ return Array.from(keys);
4123
+ }
4124
+ /**
4125
+ * Get all Memory objects (core + detailed)
4126
+ *
4127
+ * @returns Array of all Memory entries
4128
+ */
4129
+ getAllMemories() {
4130
+ return [
4131
+ ...Array.from(this.coreMemories.values()),
4132
+ ...Array.from(this.detailedMemories.values())
4133
+ ];
4134
+ }
4135
+ /**
4136
+ * Get raw Memory object by key (without triggering access metadata update)
4137
+ *
4138
+ * @param key - Memory key
4139
+ * @returns Memory object or undefined
4140
+ */
4141
+ getMemory(key) {
4142
+ return this.coreMemories.get(key) || this.detailedMemories.get(key);
4143
+ }
4144
+ /**
4145
+ * Update an existing memory entry
4146
+ *
4147
+ * @param key - Memory key to update
4148
+ * @param updates - Partial updates (content, importance, category, tags)
4149
+ * @returns true if updated, false if key not found
4150
+ */
4151
+ async update(key, updates) {
4152
+ const memory = this.coreMemories.get(key) || this.detailedMemories.get(key);
4153
+ if (!memory) return false;
4154
+ if (updates.content !== void 0) memory.content = updates.content;
4155
+ if (updates.importance !== void 0) memory.importance = updates.importance;
4156
+ if (updates.category !== void 0) memory.category = updates.category;
4157
+ if (updates.tags !== void 0) memory.tags = updates.tags;
4158
+ return true;
4159
+ }
4160
+ /**
4161
+ * Promote a memory to core by key
4162
+ *
4163
+ * @param key - Memory key to promote
4164
+ * @returns true if promoted, false if key not found or already in core
4165
+ */
4166
+ promoteToCoreByKey(key) {
4167
+ const memory = this.detailedMemories.get(key);
4168
+ if (!memory) {
4169
+ return this.coreMemories.has(key) ? false : false;
4170
+ }
4171
+ this.promoteToCore(memory);
4172
+ return true;
4173
+ }
4174
+ /**
4175
+ * Demote a memory from core to detailed by key
4176
+ *
4177
+ * @param key - Memory key to demote
4178
+ * @returns true if demoted, false if key not found in core
4179
+ */
4180
+ demoteFromCore(key) {
4181
+ const memory = this.coreMemories.get(key);
4182
+ if (!memory) return false;
4183
+ memory.is_core = false;
4184
+ this.detailedMemories.set(memory.id, memory);
4185
+ this.coreMemories.delete(memory.id);
4186
+ return true;
4187
+ }
3494
4188
  /**
3495
4189
  * Get memory statistics
3496
4190
  */
@@ -3622,8 +4316,6 @@ var LimoMemoryManager = class {
3622
4316
  return diffMs / (1e3 * 60 * 60 * 24);
3623
4317
  }
3624
4318
  };
3625
-
3626
- // src/session/types.ts
3627
4319
  var DEFAULT_SESSION_CONFIG = {
3628
4320
  directory: ".deity/sessions",
3629
4321
  autoSaveInterval: 3e4,
@@ -3632,6 +4324,32 @@ var DEFAULT_SESSION_CONFIG = {
3632
4324
  maxBackups: 5,
3633
4325
  compress: false
3634
4326
  };
4327
+ var PauseReasonSchema = zod.z.enum(["manual", "timeout", "error"]);
4328
+ var ExecutionStatsSchema = zod.z.object({
4329
+ totalToolCalls: zod.z.number().int().min(0),
4330
+ totalRetries: zod.z.number().int().min(0)
4331
+ }).passthrough();
4332
+ var PausedSessionStateSchema = zod.z.object({
4333
+ inputs: zod.z.unknown(),
4334
+ outputs: zod.z.record(zod.z.string(), zod.z.unknown()),
4335
+ conversation: zod.z.string().optional(),
4336
+ memory: zod.z.string().optional(),
4337
+ appState: zod.z.string().optional(),
4338
+ stats: ExecutionStatsSchema
4339
+ });
4340
+ var PausedSessionMetadataSchema = zod.z.object({
4341
+ pauseReason: PauseReasonSchema,
4342
+ resumable: zod.z.boolean(),
4343
+ notes: zod.z.string().optional()
4344
+ });
4345
+ zod.z.object({
4346
+ sessionId: zod.z.string().min(1, "Session ID cannot be empty"),
4347
+ workflowName: zod.z.string().min(1, "Workflow name cannot be empty"),
4348
+ pausedAt: zod.z.string().datetime("Must be ISO 8601 datetime"),
4349
+ version: zod.z.string().regex(/^\d+\.\d+\.\d+$/, "Must be semver format (e.g., 4.0.0)"),
4350
+ state: PausedSessionStateSchema,
4351
+ metadata: PausedSessionMetadataSchema
4352
+ });
3635
4353
 
3636
4354
  // src/session/serializer.ts
3637
4355
  var TYPE_MARKERS = {
@@ -4060,6 +4778,58 @@ var FileSystemSessionStore = class {
4060
4778
  }
4061
4779
  };
4062
4780
 
4781
+ // src/engine/stores.ts
4782
+ var InMemoryStore = class {
4783
+ data = /* @__PURE__ */ new Map();
4784
+ async get(key) {
4785
+ return this.data.get(key);
4786
+ }
4787
+ async set(key, value) {
4788
+ this.data.set(key, value);
4789
+ }
4790
+ async has(key) {
4791
+ return this.data.has(key);
4792
+ }
4793
+ async delete(key) {
4794
+ this.data.delete(key);
4795
+ }
4796
+ async clear() {
4797
+ this.data.clear();
4798
+ }
4799
+ // Extra methods beyond StateStore interface
4800
+ size() {
4801
+ return this.data.size;
4802
+ }
4803
+ keys() {
4804
+ return Array.from(this.data.keys());
4805
+ }
4806
+ entries() {
4807
+ return Array.from(this.data.entries());
4808
+ }
4809
+ values() {
4810
+ return Array.from(this.data.values());
4811
+ }
4812
+ };
4813
+ var InMemoryTrace = class {
4814
+ entries = [];
4815
+ async log(entry) {
4816
+ this.entries.push(entry);
4817
+ }
4818
+ async getEntries() {
4819
+ return [...this.entries];
4820
+ }
4821
+ // Extra methods for testing
4822
+ clear() {
4823
+ this.entries = [];
4824
+ }
4825
+ count() {
4826
+ return this.entries.length;
4827
+ }
4828
+ getEntriesByType(type) {
4829
+ return this.entries.filter((e) => e.type === type);
4830
+ }
4831
+ };
4832
+
4063
4833
  // src/engine/stats.ts
4064
4834
  var StatsManager = class {
4065
4835
  stats;
@@ -4188,6 +4958,14 @@ async function createEnhancedContext(config) {
4188
4958
  session = new FileSystemSessionStore(sessionConfig);
4189
4959
  await session.init();
4190
4960
  }
4961
+ let appState;
4962
+ if (config.enableAppState) {
4963
+ if (typeof config.enableAppState === "boolean") {
4964
+ appState = new InMemoryStore();
4965
+ } else {
4966
+ appState = config.enableAppState;
4967
+ }
4968
+ }
4191
4969
  return new ExecutionContext({
4192
4970
  inputs: config.inputs,
4193
4971
  previousOutputs: config.previousOutputs ?? {},
@@ -4197,6 +4975,7 @@ async function createEnhancedContext(config) {
4197
4975
  conversation,
4198
4976
  memory,
4199
4977
  session,
4978
+ appState,
4200
4979
  ui: config.ui,
4201
4980
  currentStageId: config.currentStageId,
4202
4981
  iteration: config.loop?.iteration,
@@ -4205,52 +4984,6 @@ async function createEnhancedContext(config) {
4205
4984
  });
4206
4985
  }
4207
4986
 
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
4987
  // src/engine/workflow.ts
4255
4988
  async function runWorkflow(config, inputs) {
4256
4989
  const store = config.state?.store ?? new InMemoryStore();
@@ -4262,6 +4995,7 @@ async function runWorkflow(config, inputs) {
4262
4995
  enableConversation: config.enhancements?.conversation !== void 0,
4263
4996
  enableMemory: config.enhancements?.memory !== void 0,
4264
4997
  enableSession: config.enhancements?.session !== void 0,
4998
+ enableAppState: config.enhancements?.appState,
4265
4999
  ui: config.enhancements?.ui
4266
5000
  });
4267
5001
  const result = await executeNode(
@@ -4272,6 +5006,10 @@ async function runWorkflow(config, inputs) {
4272
5006
  );
4273
5007
  return result;
4274
5008
  }
5009
+ async function runTSXWorkflow(workflowAST, inputs) {
5010
+ const config = compileWorkflow(workflowAST);
5011
+ return runWorkflow(config, inputs);
5012
+ }
4275
5013
  async function executeNode(node, ctx, adapter, config) {
4276
5014
  switch (node.type) {
4277
5015
  case "step":
@@ -4284,6 +5022,8 @@ async function executeNode(node, ctx, adapter, config) {
4284
5022
  return executeConditionalNode(node, ctx, adapter, config);
4285
5023
  case "loop":
4286
5024
  return executeLoopNode(node, ctx, adapter, config);
5025
+ case "foreach":
5026
+ return executeForEachNode(node, ctx, adapter, config);
4287
5027
  default:
4288
5028
  throw new Error(`Unknown node type: ${node.type}`);
4289
5029
  }
@@ -4369,6 +5109,116 @@ async function executeLoopNode(node, ctx, adapter, config) {
4369
5109
  }
4370
5110
  return results;
4371
5111
  }
5112
+ async function executeForEachNode(node, ctx, adapter, config) {
5113
+ if (!node.children || node.children.length === 0) {
5114
+ throw new Error("ForEach node has no children");
5115
+ }
5116
+ if (!node.itemsAccessor) {
5117
+ throw new Error("ForEach node missing itemsAccessor");
5118
+ }
5119
+ let items;
5120
+ if (typeof node.itemsAccessor === "function") {
5121
+ items = await Promise.resolve(node.itemsAccessor(ctx));
5122
+ } else {
5123
+ items = node.itemsAccessor;
5124
+ }
5125
+ if (!Array.isArray(items)) {
5126
+ throw new Error("ForEach items must be an array");
5127
+ }
5128
+ const itemMode = node.itemMode ?? "property";
5129
+ const itemKey = node.itemKey ?? "currentItem";
5130
+ const errorMode = node.errorMode ?? "stop";
5131
+ const collectResults = node.collectResults ?? true;
5132
+ const results = [];
5133
+ const errors = [];
5134
+ let successCount = 0;
5135
+ let failureCount = 0;
5136
+ for (let i = 0; i < items.length; i++) {
5137
+ const item = items[i];
5138
+ try {
5139
+ const iterationCtx = createIterationContext(
5140
+ ctx,
5141
+ item,
5142
+ i,
5143
+ items.length,
5144
+ itemMode,
5145
+ itemKey
5146
+ );
5147
+ const result = await executeNode(node.children[0], iterationCtx, adapter, config);
5148
+ if (collectResults) {
5149
+ results.push(result);
5150
+ }
5151
+ successCount++;
5152
+ } catch (error) {
5153
+ failureCount++;
5154
+ const err = error instanceof Error ? error : new Error(String(error));
5155
+ if (errorMode === "stop") {
5156
+ throw err;
5157
+ } else if (errorMode === "continue") {
5158
+ errors.push({ index: i, item, error: err });
5159
+ } else ;
5160
+ }
5161
+ }
5162
+ if (errorMode === "continue" && (errors.length > 0 || failureCount > 0)) {
5163
+ return {
5164
+ results,
5165
+ errors,
5166
+ totalItems: items.length,
5167
+ successCount,
5168
+ failureCount
5169
+ };
5170
+ }
5171
+ return results;
5172
+ }
5173
+ function createIterationContext(baseCtx, currentItem, index, totalItems, itemMode, itemKey) {
5174
+ let newInputs;
5175
+ if (itemMode === "property") {
5176
+ newInputs = {
5177
+ ...baseCtx.inputs,
5178
+ [itemKey]: currentItem,
5179
+ __forEachIndex: index,
5180
+ __forEachTotal: totalItems,
5181
+ __forEachIsLast: index === totalItems - 1
5182
+ };
5183
+ } else if (itemMode === "merge") {
5184
+ if (typeof currentItem === "object" && currentItem !== null) {
5185
+ newInputs = {
5186
+ ...baseCtx.inputs,
5187
+ ...currentItem,
5188
+ __forEachIndex: index,
5189
+ __forEachTotal: totalItems,
5190
+ __forEachIsLast: index === totalItems - 1
5191
+ };
5192
+ } else {
5193
+ throw new Error(
5194
+ `ForEach itemMode='merge' requires object items, got ${typeof currentItem}`
5195
+ );
5196
+ }
5197
+ } else if (itemMode === "replace") {
5198
+ if (typeof currentItem === "object" && currentItem !== null) {
5199
+ newInputs = {
5200
+ ...currentItem,
5201
+ __forEachIndex: index,
5202
+ __forEachTotal: totalItems,
5203
+ __forEachIsLast: index === totalItems - 1
5204
+ };
5205
+ } else {
5206
+ newInputs = currentItem;
5207
+ }
5208
+ } else {
5209
+ throw new Error(`Unknown itemMode: ${itemMode}`);
5210
+ }
5211
+ if (baseCtx instanceof ExecutionContext) {
5212
+ return baseCtx.withInputs(newInputs).withIteration(index, totalItems);
5213
+ }
5214
+ return {
5215
+ ...baseCtx,
5216
+ inputs: newInputs,
5217
+ iteration: index,
5218
+ maxIterations: totalItems,
5219
+ isLastIteration: index === totalItems - 1
5220
+ };
5221
+ }
4372
5222
  function createStepNode(component) {
4373
5223
  return {
4374
5224
  type: "step",
@@ -4402,257 +5252,17 @@ function createLoopNode(child, maxIterations) {
4402
5252
  };
4403
5253
  }
4404
5254
 
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
5255
  exports.Agent = Agent;
5256
+ exports.Conditional = Conditional;
4650
5257
  exports.DEBUG_ENABLED = DEBUG_ENABLED;
4651
5258
  exports.DebugLogger = DebugLogger;
5259
+ exports.ForEach = ForEach;
4652
5260
  exports.InMemoryStore = InMemoryStore;
4653
5261
  exports.InMemoryTrace = InMemoryTrace;
5262
+ exports.Loop = Loop;
4654
5263
  exports.Observe = Observe;
4655
5264
  exports.ObserveUtils = ObserveUtils;
5265
+ exports.Parallel = Parallel;
4656
5266
  exports.PreflightChecker = PreflightChecker;
4657
5267
  exports.Prompt = Prompt;
4658
5268
  exports.PromptResourceLoader = PromptResourceLoader;
@@ -4660,23 +5270,27 @@ exports.Result = Result;
4660
5270
  exports.ResultUtils = ResultUtils;
4661
5271
  exports.Retry = Retry;
4662
5272
  exports.RetryUtils = RetryUtils;
5273
+ exports.Sequence = Sequence;
4663
5274
  exports.System = System;
5275
+ exports.Tool = Tool;
5276
+ exports.ToolDef = ToolDef;
5277
+ exports.ToolRef = ToolRef;
5278
+ exports.Tools = Tools;
4664
5279
  exports.User = User;
4665
5280
  exports.Validate = Validate;
4666
5281
  exports.ValidateUtils = ValidateUtils;
5282
+ exports.Workflow = Workflow;
4667
5283
  exports.compileAgent = compileAgent;
4668
- exports.countToolCalls = countToolCalls;
5284
+ exports.compileWorkflow = compileWorkflow;
5285
+ exports.compileWorkflowNode = compileWorkflowNode;
4669
5286
  exports.createConditionalNode = createConditionalNode;
4670
5287
  exports.createEnhancedContext = createEnhancedContext;
4671
5288
  exports.createLoopNode = createLoopNode;
4672
- exports.createMemoryTools = createMemoryTools;
4673
5289
  exports.createParallelNode = createParallelNode;
4674
5290
  exports.createSequenceNode = createSequenceNode;
4675
5291
  exports.createStepNode = createStepNode;
4676
5292
  exports.executeComponent = executeComponent;
4677
5293
  exports.executeLLMLoop = executeLLMLoop;
4678
- exports.extractAllToolResults = extractAllToolResults;
4679
- exports.extractLastToolResult = extractLastToolResult;
4680
5294
  exports.getResourceLoader = getResourceLoader;
4681
5295
  exports.isAgentNode = isAgentNode;
4682
5296
  exports.isObserveNode = isObserveNode;
@@ -4684,12 +5298,24 @@ exports.isPromptNode = isPromptNode;
4684
5298
  exports.isResultNode = isResultNode;
4685
5299
  exports.isRetryNode = isRetryNode;
4686
5300
  exports.isSystemNode = isSystemNode;
5301
+ exports.isToolDefNode = isToolDefNode;
5302
+ exports.isToolRefNode = isToolRefNode;
5303
+ exports.isToolsNode = isToolsNode;
4687
5304
  exports.isUserNode = isUserNode;
4688
5305
  exports.isValidateNode = isValidateNode;
5306
+ exports.isWorkflowConditionalNode = isWorkflowConditionalNode;
5307
+ exports.isWorkflowForEachNode = isWorkflowForEachNode;
5308
+ exports.isWorkflowLoopNode = isWorkflowLoopNode;
5309
+ exports.isWorkflowNode = isWorkflowNode;
5310
+ exports.isWorkflowParallelNode = isWorkflowParallelNode;
5311
+ exports.isWorkflowSequenceNode = isWorkflowSequenceNode;
4689
5312
  exports.logger = logger;
4690
5313
  exports.preflight = preflight;
5314
+ exports.runTSXWorkflow = runTSXWorkflow;
4691
5315
  exports.runWorkflow = runWorkflow;
4692
5316
  exports.setResourceLoader = setResourceLoader;
4693
5317
  exports.testFullAgent = testFullAgent;
5318
+ exports.toAgent = toAgent;
5319
+ exports.toWorkflow = toWorkflow;
4694
5320
  //# sourceMappingURL=index.cjs.map
4695
5321
  //# sourceMappingURL=index.cjs.map