@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.js CHANGED
@@ -42,7 +42,7 @@ var init_compile_observe = __esm({
42
42
 
43
43
  // src/components/Agent.tsx
44
44
  function Agent(props) {
45
- const { id, input, output, description, tags, loopValidator, loopConfig, tools, children } = props;
45
+ const { id, input, output, description, tags, loopValidator, loopConfig, tools: propsTools, children } = props;
46
46
  if (!id) {
47
47
  throw new Error("Agent: id is required");
48
48
  }
@@ -55,9 +55,11 @@ function Agent(props) {
55
55
  if (!children || children.length === 0) {
56
56
  throw new Error("Agent: must have at least Prompt and Result children");
57
57
  }
58
- const [prompt, ...rest] = children;
58
+ const toolsNode = children.find((child) => child?.type === "Tools");
59
+ const nonToolsChildren = children.filter((child) => child?.type !== "Tools");
60
+ const [prompt, ...rest] = nonToolsChildren;
59
61
  if (!prompt || prompt.type !== "Prompt") {
60
- throw new Error("Agent: first child must be a Prompt component");
62
+ throw new Error("Agent: first non-Tools child must be a Prompt component");
61
63
  }
62
64
  const result = rest.find((child) => child?.type === "Result");
63
65
  if (!result) {
@@ -66,6 +68,7 @@ function Agent(props) {
66
68
  const observe = rest.find((child) => child?.type === "Observe");
67
69
  const validate = rest.find((child) => child?.type === "Validate");
68
70
  const retry = rest.find((child) => child?.type === "Retry");
71
+ const mergedTools = mergeTools(propsTools, toolsNode);
69
72
  const orderedChildren = [
70
73
  prompt
71
74
  ];
@@ -73,6 +76,7 @@ function Agent(props) {
73
76
  orderedChildren.push(result);
74
77
  if (validate) orderedChildren.push(validate);
75
78
  if (retry) orderedChildren.push(retry);
79
+ if (toolsNode) orderedChildren.push(toolsNode);
76
80
  return {
77
81
  type: "Agent",
78
82
  props: {
@@ -83,11 +87,24 @@ function Agent(props) {
83
87
  tags,
84
88
  loopValidator,
85
89
  loopConfig,
86
- tools
90
+ tools: mergedTools
87
91
  },
88
92
  children: orderedChildren
89
93
  };
90
94
  }
95
+ function mergeTools(propsTools, toolsNode) {
96
+ if (!propsTools && !toolsNode) {
97
+ return void 0;
98
+ }
99
+ const staticToolsFromNode = toolsNode ? (toolsNode.children || []).filter((child) => child?.type === "Tools:Def" && child.props?.tool).map((child) => child.props.tool) : [];
100
+ if (!toolsNode) {
101
+ return propsTools;
102
+ }
103
+ if (!propsTools) {
104
+ return staticToolsFromNode.length > 0 ? staticToolsFromNode : void 0;
105
+ }
106
+ return [...propsTools, ...staticToolsFromNode];
107
+ }
91
108
 
92
109
  // src/components/Prompt.tsx
93
110
  function Prompt(props) {
@@ -135,6 +152,40 @@ function System(props) {
135
152
  if (children.length === 0) {
136
153
  throw new Error("System: children array is empty");
137
154
  }
155
+ const hasToolRef = children.some(
156
+ (child) => typeof child === "object" && child !== null && "type" in child && child.type === "ToolRef"
157
+ );
158
+ if (hasToolRef) {
159
+ const parts = [];
160
+ for (const child of children) {
161
+ if (typeof child === "object" && child !== null && "type" in child) {
162
+ const node = child;
163
+ if (node.type === "Text" && node.props?.content) {
164
+ parts.push({ kind: "text", value: node.props.content });
165
+ } else if (node.type === "ComputedText" && node.props?.compute) {
166
+ parts.push({ kind: "computed", compute: node.props.compute });
167
+ } else if (node.type === "ToolRef" && node.props?.toolName) {
168
+ parts.push({ kind: "toolref", toolName: node.props.toolName });
169
+ } else {
170
+ throw new Error(`System: invalid child type in template mode: ${node.type}`);
171
+ }
172
+ } else if (typeof child === "string") {
173
+ parts.push({ kind: "text", value: child });
174
+ } else if (typeof child === "function") {
175
+ parts.push({ kind: "computed", compute: child });
176
+ } else {
177
+ throw new Error("System: invalid child in template mode");
178
+ }
179
+ }
180
+ return {
181
+ type: "System",
182
+ props: {
183
+ source,
184
+ required,
185
+ templateParts: parts
186
+ }
187
+ };
188
+ }
138
189
  if (children.length > 1) {
139
190
  throw new Error("System: can only have one child");
140
191
  }
@@ -191,6 +242,38 @@ function User(props) {
191
242
  if (children.length === 0) {
192
243
  throw new Error("User: children array is empty");
193
244
  }
245
+ const hasToolRef = children.some(
246
+ (child) => typeof child === "object" && child !== null && "type" in child && child.type === "ToolRef"
247
+ );
248
+ if (hasToolRef) {
249
+ const parts = [];
250
+ for (const child of children) {
251
+ if (typeof child === "object" && child !== null && "type" in child) {
252
+ const node = child;
253
+ if (node.type === "Text" && node.props?.content) {
254
+ parts.push({ kind: "text", value: node.props.content });
255
+ } else if (node.type === "ComputedText" && node.props?.compute) {
256
+ parts.push({ kind: "computed", compute: node.props.compute });
257
+ } else if (node.type === "ToolRef" && node.props?.toolName) {
258
+ parts.push({ kind: "toolref", toolName: node.props.toolName });
259
+ } else {
260
+ throw new Error(`User: invalid child type in template mode: ${node.type}`);
261
+ }
262
+ } else if (typeof child === "string") {
263
+ parts.push({ kind: "text", value: child });
264
+ } else if (typeof child === "function") {
265
+ parts.push({ kind: "computed", compute: child });
266
+ } else {
267
+ throw new Error("User: invalid child in template mode");
268
+ }
269
+ }
270
+ return {
271
+ type: "User",
272
+ props: {
273
+ templateParts: parts
274
+ }
275
+ };
276
+ }
194
277
  if (children.length > 1) {
195
278
  throw new Error("User: can only have one child");
196
279
  }
@@ -374,6 +457,241 @@ function Retry(props = {}) {
374
457
  }
375
458
  };
376
459
  }
460
+
461
+ // src/components/Tools.tsx
462
+ function Tools(props) {
463
+ const { children } = props;
464
+ const toolDefs = (children || []).filter(
465
+ (child) => child?.type === "Tools:Def"
466
+ );
467
+ return {
468
+ type: "Tools",
469
+ props: {},
470
+ children: toolDefs
471
+ };
472
+ }
473
+ function ToolDef(props) {
474
+ return {
475
+ type: "Tools:Def",
476
+ props: { tool: props.tool }
477
+ };
478
+ }
479
+ function Tool(props) {
480
+ const { name, description, input, execute, children } = props;
481
+ if (!name) {
482
+ throw new Error("Tool: name is required");
483
+ }
484
+ if (!description) {
485
+ throw new Error("Tool: description is required");
486
+ }
487
+ if (!input) {
488
+ throw new Error("Tool: input schema is required");
489
+ }
490
+ let executeFn;
491
+ if (children) {
492
+ if (execute) {
493
+ throw new Error("Tool: cannot use both children and execute prop");
494
+ }
495
+ let actualChild = children;
496
+ if (Array.isArray(children)) {
497
+ if (children.length === 0) {
498
+ throw new Error("Tool: children array is empty");
499
+ }
500
+ if (children.length > 1) {
501
+ throw new Error("Tool: can only have one child (the execute function)");
502
+ }
503
+ actualChild = children[0];
504
+ }
505
+ if (typeof actualChild === "object" && actualChild !== null && "type" in actualChild) {
506
+ const node = actualChild;
507
+ if (node.type === "ComputedText" && node.props?.compute) {
508
+ executeFn = node.props.compute;
509
+ } else {
510
+ throw new Error("Tool: invalid child node type (expected ComputedText with execute function)");
511
+ }
512
+ } else if (typeof actualChild === "function") {
513
+ executeFn = actualChild;
514
+ } else {
515
+ throw new Error("Tool: children must be a function");
516
+ }
517
+ } else if (execute) {
518
+ executeFn = execute;
519
+ } else {
520
+ throw new Error("Tool: must provide children (execute function) or execute prop");
521
+ }
522
+ const toolSpec = {
523
+ name,
524
+ description,
525
+ inputSchema: input,
526
+ execute: executeFn
527
+ };
528
+ return {
529
+ type: "Tools:Def",
530
+ props: { tool: toolSpec }
531
+ };
532
+ }
533
+
534
+ // src/components/ToolRef.tsx
535
+ function ToolRef(props) {
536
+ const { tool } = props;
537
+ let toolName;
538
+ if (tool === null || tool === void 0) {
539
+ throw new Error(
540
+ "ToolRef: `tool` prop must be a tool component with .toolName, a ToolSpec with .name, or a string tool ID"
541
+ );
542
+ }
543
+ if (typeof tool === "string") {
544
+ toolName = tool;
545
+ } else if (typeof tool === "function" && "toolName" in tool && typeof tool.toolName === "string") {
546
+ toolName = tool.toolName;
547
+ } else if (typeof tool === "object" && "toolName" in tool && typeof tool.toolName === "string") {
548
+ toolName = tool.toolName;
549
+ } else if (typeof tool === "object" && "name" in tool && typeof tool.name === "string") {
550
+ toolName = tool.name;
551
+ } else {
552
+ throw new Error(
553
+ "ToolRef: `tool` prop must be a tool component with .toolName, a ToolSpec with .name, or a string tool ID"
554
+ );
555
+ }
556
+ return {
557
+ type: "ToolRef",
558
+ props: { toolName }
559
+ };
560
+ }
561
+
562
+ // src/components/Sequence.tsx
563
+ function Sequence(props) {
564
+ const { children } = props;
565
+ if (!children || children.length === 0) {
566
+ throw new Error("Sequence: must have at least one child");
567
+ }
568
+ return {
569
+ type: "WorkflowSequence",
570
+ children
571
+ };
572
+ }
573
+
574
+ // src/components/Parallel.tsx
575
+ function Parallel(props) {
576
+ const { children } = props;
577
+ if (!children || children.length === 0) {
578
+ throw new Error("Parallel: must have at least one child");
579
+ }
580
+ return {
581
+ type: "WorkflowParallel",
582
+ children
583
+ };
584
+ }
585
+
586
+ // src/components/Conditional.tsx
587
+ function Conditional(props) {
588
+ const { condition, children } = props;
589
+ if (!condition) {
590
+ throw new Error("Conditional: condition prop is required");
591
+ }
592
+ if (!children) {
593
+ throw new Error("Conditional: must have at least one child (true branch)");
594
+ }
595
+ if (children.length < 1 || children.length > 2) {
596
+ throw new Error("Conditional: must have 1-2 children (true branch required, false branch optional)");
597
+ }
598
+ return {
599
+ type: "WorkflowConditional",
600
+ props: {
601
+ condition
602
+ },
603
+ children
604
+ };
605
+ }
606
+
607
+ // src/components/Loop.tsx
608
+ function Loop(props) {
609
+ const { iterations, children } = props;
610
+ if (!iterations || iterations < 1) {
611
+ throw new Error("Loop: iterations must be >= 1");
612
+ }
613
+ if (!children) {
614
+ throw new Error("Loop: must have exactly one child");
615
+ }
616
+ const childArray = Array.isArray(children) ? children : [children];
617
+ if (childArray.length !== 1) {
618
+ throw new Error("Loop: must have exactly one child");
619
+ }
620
+ return {
621
+ type: "WorkflowLoop",
622
+ props: {
623
+ iterations
624
+ },
625
+ children: [childArray[0]]
626
+ };
627
+ }
628
+
629
+ // src/components/ForEach.tsx
630
+ function ForEach(props) {
631
+ const {
632
+ items,
633
+ itemMode = "property",
634
+ itemKey = "currentItem",
635
+ errorMode = "stop",
636
+ collectResults = true,
637
+ children
638
+ } = props;
639
+ if (!items) {
640
+ throw new Error("ForEach: items prop is required");
641
+ }
642
+ if (!children) {
643
+ throw new Error("ForEach: must have exactly one child");
644
+ }
645
+ const childArray = Array.isArray(children) ? children : [children];
646
+ if (childArray.length !== 1) {
647
+ throw new Error("ForEach: must have exactly one child");
648
+ }
649
+ const validModes = ["merge", "replace", "property"];
650
+ if (!validModes.includes(itemMode)) {
651
+ throw new Error(`ForEach: itemMode must be one of: ${validModes.join(", ")}`);
652
+ }
653
+ const validErrorModes = ["stop", "continue", "skip"];
654
+ if (!validErrorModes.includes(errorMode)) {
655
+ throw new Error(`ForEach: errorMode must be one of: ${validErrorModes.join(", ")}`);
656
+ }
657
+ return {
658
+ type: "WorkflowForEach",
659
+ props: {
660
+ items,
661
+ itemMode,
662
+ itemKey,
663
+ errorMode,
664
+ collectResults
665
+ },
666
+ children: [childArray[0]]
667
+ };
668
+ }
669
+
670
+ // src/components/Workflow.tsx
671
+ function Workflow(props) {
672
+ const { name, description, defaultModel, state, enhancements, children } = props;
673
+ if (!name) {
674
+ throw new Error("Workflow: name is required");
675
+ }
676
+ if (!children) {
677
+ throw new Error("Workflow: must have exactly one child (workflow graph)");
678
+ }
679
+ const childArray = Array.isArray(children) ? children : [children];
680
+ if (childArray.length !== 1) {
681
+ throw new Error("Workflow: must have exactly one child (workflow graph)");
682
+ }
683
+ return {
684
+ type: "Workflow",
685
+ props: {
686
+ name,
687
+ description,
688
+ defaultModel,
689
+ state,
690
+ enhancements
691
+ },
692
+ children: [childArray[0]]
693
+ };
694
+ }
377
695
  var PromptResourceLoader = class {
378
696
  cache = /* @__PURE__ */ new Map();
379
697
  options;
@@ -583,7 +901,25 @@ function compilePrompt(promptNode) {
583
901
  };
584
902
  }
585
903
  async function resolveSystemContent(node, ctx) {
586
- const { source, content, compute, required = false } = node.props;
904
+ const { source, content, compute, required = false, templateParts } = node.props;
905
+ if (templateParts) {
906
+ const resolved = await Promise.all(
907
+ templateParts.map(async (part) => {
908
+ switch (part.kind) {
909
+ case "text":
910
+ return part.value;
911
+ case "computed":
912
+ return await Promise.resolve(part.compute(ctx));
913
+ case "toolref":
914
+ return part.toolName;
915
+ default:
916
+ const _exhaustive = part;
917
+ throw new Error(`Unknown template part kind: ${_exhaustive.kind}`);
918
+ }
919
+ })
920
+ );
921
+ return resolved.join("");
922
+ }
587
923
  if (source) {
588
924
  if (!source.startsWith("file:")) {
589
925
  throw new Error(`Invalid source format: ${source} (must start with "file:")`);
@@ -604,17 +940,35 @@ async function resolveSystemContent(node, ctx) {
604
940
  if (compute) {
605
941
  return await Promise.resolve(compute(ctx));
606
942
  }
607
- throw new Error("System node must have source, content, or compute");
943
+ throw new Error("System node must have source, content, compute, or templateParts");
608
944
  }
609
945
  async function resolveUserContent(node, ctx) {
610
- const { content, compute } = node.props;
946
+ const { content, compute, templateParts } = node.props;
947
+ if (templateParts) {
948
+ const resolved = await Promise.all(
949
+ templateParts.map(async (part) => {
950
+ switch (part.kind) {
951
+ case "text":
952
+ return part.value;
953
+ case "computed":
954
+ return await Promise.resolve(part.compute(ctx));
955
+ case "toolref":
956
+ return part.toolName;
957
+ default:
958
+ const _exhaustive = part;
959
+ throw new Error(`Unknown template part kind: ${_exhaustive.kind}`);
960
+ }
961
+ })
962
+ );
963
+ return resolved.join("");
964
+ }
611
965
  if (content !== void 0) {
612
966
  return content;
613
967
  }
614
968
  if (compute) {
615
969
  return await Promise.resolve(compute(ctx));
616
970
  }
617
- throw new Error("User node must have content or compute");
971
+ throw new Error("User node must have content, compute, or templateParts");
618
972
  }
619
973
 
620
974
  // src/compiler/compile-agent.ts
@@ -744,6 +1098,184 @@ function compileAgent(ast) {
744
1098
  // src/compiler/index.ts
745
1099
  init_compile_observe();
746
1100
 
1101
+ // src/compiler/compile-workflow-node.ts
1102
+ function compileWorkflowNode(node) {
1103
+ switch (node.type) {
1104
+ case "Agent":
1105
+ return compileAgentNode(node);
1106
+ case "WorkflowSequence":
1107
+ return compileSequenceNode(node);
1108
+ case "WorkflowParallel":
1109
+ return compileParallelNode(node);
1110
+ case "WorkflowConditional":
1111
+ return compileConditionalNode(node);
1112
+ case "WorkflowLoop":
1113
+ return compileLoopNode(node);
1114
+ case "WorkflowForEach":
1115
+ return compileForEachNode(node);
1116
+ default:
1117
+ throw new Error(`Unknown workflow node type: ${node.type}`);
1118
+ }
1119
+ }
1120
+ function compileAgentNode(node) {
1121
+ const lazyComponent = createLazyAgentComponent(node);
1122
+ return {
1123
+ type: "step",
1124
+ component: lazyComponent
1125
+ };
1126
+ }
1127
+ function compileSequenceNode(node) {
1128
+ if (!node.children || node.children.length === 0) {
1129
+ throw new Error("Sequence node must have children");
1130
+ }
1131
+ const children = node.children.map((child) => compileWorkflowNode(child));
1132
+ return {
1133
+ type: "sequence",
1134
+ children
1135
+ };
1136
+ }
1137
+ function compileParallelNode(node) {
1138
+ if (!node.children || node.children.length === 0) {
1139
+ throw new Error("Parallel node must have children");
1140
+ }
1141
+ const children = node.children.map((child) => compileWorkflowNode(child));
1142
+ return {
1143
+ type: "parallel",
1144
+ children
1145
+ };
1146
+ }
1147
+ function compileConditionalNode(node) {
1148
+ if (!node.props?.condition) {
1149
+ throw new Error("Conditional node must have a condition function");
1150
+ }
1151
+ if (!node.children || node.children.length < 1 || node.children.length > 2) {
1152
+ throw new Error("Conditional node must have 1-2 children (true branch required, false branch optional)");
1153
+ }
1154
+ const children = node.children.map((child) => compileWorkflowNode(child));
1155
+ return {
1156
+ type: "conditional",
1157
+ condition: node.props.condition,
1158
+ children
1159
+ };
1160
+ }
1161
+ function compileLoopNode(node) {
1162
+ if (!node.props?.iterations || node.props.iterations < 1) {
1163
+ throw new Error("Loop node must have iterations >= 1");
1164
+ }
1165
+ if (!node.children || node.children.length !== 1) {
1166
+ throw new Error("Loop node must have exactly one child");
1167
+ }
1168
+ const child = compileWorkflowNode(node.children[0]);
1169
+ return {
1170
+ type: "loop",
1171
+ maxIterations: node.props.iterations,
1172
+ children: [child]
1173
+ };
1174
+ }
1175
+ function compileForEachNode(node) {
1176
+ if (!node.props?.items) {
1177
+ throw new Error("ForEach node must have items prop");
1178
+ }
1179
+ if (!node.children || node.children.length !== 1) {
1180
+ throw new Error("ForEach node must have exactly one child");
1181
+ }
1182
+ const child = compileWorkflowNode(node.children[0]);
1183
+ return {
1184
+ type: "foreach",
1185
+ itemsAccessor: node.props.items,
1186
+ itemMode: node.props.itemMode,
1187
+ itemKey: node.props.itemKey,
1188
+ errorMode: node.props.errorMode,
1189
+ collectResults: node.props.collectResults,
1190
+ children: [child]
1191
+ };
1192
+ }
1193
+ function createLazyAgentComponent(astNode) {
1194
+ let compiled = null;
1195
+ const ensureCompiled = () => {
1196
+ if (!compiled) {
1197
+ compiled = compileAgent(astNode);
1198
+ }
1199
+ return compiled;
1200
+ };
1201
+ const proxy = {
1202
+ get id() {
1203
+ return astNode.props.id;
1204
+ },
1205
+ get inputSchema() {
1206
+ return astNode.props.input;
1207
+ },
1208
+ get outputSchema() {
1209
+ return astNode.props.output;
1210
+ },
1211
+ get tools() {
1212
+ return astNode.props.tools;
1213
+ },
1214
+ get loopValidator() {
1215
+ return astNode.props.loopValidator;
1216
+ },
1217
+ get loopConfig() {
1218
+ return astNode.props.loopConfig;
1219
+ },
1220
+ // Lazy methods - compile on first call
1221
+ buildPrompt(ctx) {
1222
+ return ensureCompiled().buildPrompt(ctx);
1223
+ },
1224
+ get retry() {
1225
+ return ensureCompiled().retry;
1226
+ },
1227
+ get model() {
1228
+ return ensureCompiled().model;
1229
+ }
1230
+ };
1231
+ const hasResultNode = astNode.children.some((child) => child.type === "Result");
1232
+ if (hasResultNode) {
1233
+ proxy.extractOutput = (ctx, llmResult) => {
1234
+ return ensureCompiled().extractOutput(ctx, llmResult);
1235
+ };
1236
+ }
1237
+ const hasValidateNode = astNode.children.some((child) => child.type === "Validate");
1238
+ if (hasValidateNode) {
1239
+ proxy.validateOutput = (output, ctx) => {
1240
+ const comp = ensureCompiled();
1241
+ return comp.validateOutput(output, ctx);
1242
+ };
1243
+ }
1244
+ return proxy;
1245
+ }
1246
+
1247
+ // src/compiler/compile-workflow.ts
1248
+ function compileWorkflow(ast) {
1249
+ if (ast.type !== "Workflow") {
1250
+ throw new Error(`Expected Workflow node, got ${ast.type}`);
1251
+ }
1252
+ if (!ast.children || ast.children.length !== 1) {
1253
+ throw new Error("Workflow must have exactly one child (workflow graph)");
1254
+ }
1255
+ const { name, description, defaultModel, state, enhancements } = ast.props;
1256
+ if (!name) {
1257
+ throw new Error("Workflow must have a name");
1258
+ }
1259
+ const graph = compileWorkflowNode(ast.children[0]);
1260
+ const config = {
1261
+ name,
1262
+ graph
1263
+ };
1264
+ if (description) {
1265
+ config.description = description;
1266
+ }
1267
+ if (defaultModel) {
1268
+ config.defaultModel = defaultModel;
1269
+ }
1270
+ if (state) {
1271
+ config.state = state;
1272
+ }
1273
+ if (enhancements) {
1274
+ config.enhancements = enhancements;
1275
+ }
1276
+ return config;
1277
+ }
1278
+
747
1279
  // src/ast/types.ts
748
1280
  function isAgentNode(node) {
749
1281
  return node.type === "Agent";
@@ -769,6 +1301,33 @@ function isValidateNode(node) {
769
1301
  function isRetryNode(node) {
770
1302
  return node.type === "Retry";
771
1303
  }
1304
+ function isToolsNode(node) {
1305
+ return node.type === "Tools";
1306
+ }
1307
+ function isToolDefNode(node) {
1308
+ return node.type === "Tools:Def";
1309
+ }
1310
+ function isToolRefNode(node) {
1311
+ return node.type === "ToolRef";
1312
+ }
1313
+ function isWorkflowSequenceNode(node) {
1314
+ return node.type === "WorkflowSequence";
1315
+ }
1316
+ function isWorkflowParallelNode(node) {
1317
+ return node.type === "WorkflowParallel";
1318
+ }
1319
+ function isWorkflowConditionalNode(node) {
1320
+ return node.type === "WorkflowConditional";
1321
+ }
1322
+ function isWorkflowLoopNode(node) {
1323
+ return node.type === "WorkflowLoop";
1324
+ }
1325
+ function isWorkflowForEachNode(node) {
1326
+ return node.type === "WorkflowForEach";
1327
+ }
1328
+ function isWorkflowNode(node) {
1329
+ return node.type === "Workflow";
1330
+ }
772
1331
 
773
1332
  // src/utilities/observe-utils.ts
774
1333
  var ObserveUtils = class {
@@ -1964,6 +2523,20 @@ var RetryUtils = class {
1964
2523
  }
1965
2524
  };
1966
2525
 
2526
+ // src/utilities/jsx-helpers.ts
2527
+ function toWorkflow(element) {
2528
+ if (element.type !== "Workflow") {
2529
+ throw new Error(`Expected Workflow element, got ${element.type}`);
2530
+ }
2531
+ return element;
2532
+ }
2533
+ function toAgent(element) {
2534
+ if (element.type !== "Agent") {
2535
+ throw new Error(`Expected Agent element, got ${element.type}`);
2536
+ }
2537
+ return element;
2538
+ }
2539
+
1967
2540
  // src/utilities/preflight.ts
1968
2541
  var PreflightChecker = class {
1969
2542
  options;
@@ -2391,6 +2964,7 @@ async function executeLLMLoop(adapter, initialMessages, tools, config, ctx, loop
2391
2964
  });
2392
2965
  }
2393
2966
  }
2967
+ const allPreExecuted = response.toolCalls.every((tc) => tc._alreadyExecuted);
2394
2968
  if (validator) {
2395
2969
  const loopState = {
2396
2970
  rounds,
@@ -2410,6 +2984,9 @@ async function executeLLMLoop(adapter, initialMessages, tools, config, ctx, loop
2410
2984
  });
2411
2985
  }
2412
2986
  }
2987
+ if (allPreExecuted) {
2988
+ break;
2989
+ }
2413
2990
  }
2414
2991
  return {
2415
2992
  response,
@@ -2749,10 +3326,11 @@ async function executeComponent(component, ctx, adapter, config) {
2749
3326
  ctx.ui?.stepProgress(component.id, 50, "Executing LLM...");
2750
3327
  const promptMessages = await Promise.resolve(component.buildPrompt(ctx));
2751
3328
  const messages = feedbackMessages ? [...promptMessages, ...feedbackMessages] : promptMessages;
3329
+ const resolvedTools = component.tools;
2752
3330
  const llmResult = await executeLLMLoop(
2753
3331
  adapter,
2754
3332
  messages,
2755
- component.tools,
3333
+ resolvedTools,
2756
3334
  config,
2757
3335
  ctx,
2758
3336
  component.loopConfig,
@@ -2862,6 +3440,8 @@ var ExecutionContext = class _ExecutionContext {
2862
3440
  ui;
2863
3441
  /** Session store (optional) */
2864
3442
  session;
3443
+ /** Application state store (optional, isolated from AI memory) */
3444
+ appState;
2865
3445
  /** Current stage ID (for UI updates) */
2866
3446
  currentStageId;
2867
3447
  // ========== Constructor ==========
@@ -2874,6 +3454,7 @@ var ExecutionContext = class _ExecutionContext {
2874
3454
  this.conversation = params.conversation;
2875
3455
  this.memory = params.memory;
2876
3456
  this.session = params.session;
3457
+ this.appState = params.appState;
2877
3458
  this.ui = params.ui;
2878
3459
  this.currentStageId = params.currentStageId;
2879
3460
  this.iteration = params.iteration;
@@ -2922,6 +3503,7 @@ var ExecutionContext = class _ExecutionContext {
2922
3503
  conversation: this.conversation,
2923
3504
  memory: this.memory,
2924
3505
  session: this.session,
3506
+ appState: this.appState,
2925
3507
  ui: this.ui,
2926
3508
  currentStageId: updates.currentStageId ?? this.currentStageId,
2927
3509
  iteration: updates.iteration ?? this.iteration,
@@ -2950,6 +3532,27 @@ var ExecutionContext = class _ExecutionContext {
2950
3532
  iterationHistory: this.iterationHistory
2951
3533
  });
2952
3534
  }
3535
+ /**
3536
+ * Update inputs (for ForEach iterations)
3537
+ */
3538
+ withInputs(inputs) {
3539
+ return new _ExecutionContext({
3540
+ inputs,
3541
+ previousOutputs: this.previousOutputs,
3542
+ store: this.store,
3543
+ trace: this.trace,
3544
+ stats: this.stats,
3545
+ conversation: this.conversation,
3546
+ memory: this.memory,
3547
+ session: this.session,
3548
+ appState: this.appState,
3549
+ ui: this.ui,
3550
+ currentStageId: this.currentStageId,
3551
+ iteration: this.iteration,
3552
+ maxIterations: this.maxIterations,
3553
+ iterationHistory: this.iterationHistory
3554
+ });
3555
+ }
2953
3556
  /**
2954
3557
  * Add to iteration history
2955
3558
  */
@@ -2983,6 +3586,12 @@ var ExecutionContext = class _ExecutionContext {
2983
3586
  hasUI() {
2984
3587
  return this.ui !== void 0;
2985
3588
  }
3589
+ /**
3590
+ * Check if appState is enabled
3591
+ */
3592
+ hasAppState() {
3593
+ return this.appState !== void 0;
3594
+ }
2986
3595
  /**
2987
3596
  * Get conversation manager (throws if not available)
2988
3597
  */
@@ -3019,6 +3628,15 @@ var ExecutionContext = class _ExecutionContext {
3019
3628
  }
3020
3629
  return this.ui;
3021
3630
  }
3631
+ /**
3632
+ * Get application state store (throws if not available)
3633
+ */
3634
+ requireAppState() {
3635
+ if (!this.appState) {
3636
+ throw new Error("Application state store not available in this context");
3637
+ }
3638
+ return this.appState;
3639
+ }
3022
3640
  // ========== Debugging ==========
3023
3641
  /**
3024
3642
  * Get context summary for debugging
@@ -3033,7 +3651,8 @@ var ExecutionContext = class _ExecutionContext {
3033
3651
  conversation: this.hasConversation(),
3034
3652
  memory: this.hasMemory(),
3035
3653
  session: this.hasSession(),
3036
- ui: this.hasUI()
3654
+ ui: this.hasUI(),
3655
+ appState: this.hasAppState()
3037
3656
  },
3038
3657
  stats: this.stats
3039
3658
  };
@@ -3469,6 +4088,81 @@ var LimoMemoryManager = class {
3469
4088
  getDetailedMemories() {
3470
4089
  return Array.from(this.detailedMemories.values());
3471
4090
  }
4091
+ /**
4092
+ * Get all memory keys (core + detailed)
4093
+ *
4094
+ * @returns Array of all memory keys
4095
+ */
4096
+ getAllKeys() {
4097
+ const keys = /* @__PURE__ */ new Set();
4098
+ for (const key of this.coreMemories.keys()) keys.add(key);
4099
+ for (const key of this.detailedMemories.keys()) keys.add(key);
4100
+ return Array.from(keys);
4101
+ }
4102
+ /**
4103
+ * Get all Memory objects (core + detailed)
4104
+ *
4105
+ * @returns Array of all Memory entries
4106
+ */
4107
+ getAllMemories() {
4108
+ return [
4109
+ ...Array.from(this.coreMemories.values()),
4110
+ ...Array.from(this.detailedMemories.values())
4111
+ ];
4112
+ }
4113
+ /**
4114
+ * Get raw Memory object by key (without triggering access metadata update)
4115
+ *
4116
+ * @param key - Memory key
4117
+ * @returns Memory object or undefined
4118
+ */
4119
+ getMemory(key) {
4120
+ return this.coreMemories.get(key) || this.detailedMemories.get(key);
4121
+ }
4122
+ /**
4123
+ * Update an existing memory entry
4124
+ *
4125
+ * @param key - Memory key to update
4126
+ * @param updates - Partial updates (content, importance, category, tags)
4127
+ * @returns true if updated, false if key not found
4128
+ */
4129
+ async update(key, updates) {
4130
+ const memory = this.coreMemories.get(key) || this.detailedMemories.get(key);
4131
+ if (!memory) return false;
4132
+ if (updates.content !== void 0) memory.content = updates.content;
4133
+ if (updates.importance !== void 0) memory.importance = updates.importance;
4134
+ if (updates.category !== void 0) memory.category = updates.category;
4135
+ if (updates.tags !== void 0) memory.tags = updates.tags;
4136
+ return true;
4137
+ }
4138
+ /**
4139
+ * Promote a memory to core by key
4140
+ *
4141
+ * @param key - Memory key to promote
4142
+ * @returns true if promoted, false if key not found or already in core
4143
+ */
4144
+ promoteToCoreByKey(key) {
4145
+ const memory = this.detailedMemories.get(key);
4146
+ if (!memory) {
4147
+ return this.coreMemories.has(key) ? false : false;
4148
+ }
4149
+ this.promoteToCore(memory);
4150
+ return true;
4151
+ }
4152
+ /**
4153
+ * Demote a memory from core to detailed by key
4154
+ *
4155
+ * @param key - Memory key to demote
4156
+ * @returns true if demoted, false if key not found in core
4157
+ */
4158
+ demoteFromCore(key) {
4159
+ const memory = this.coreMemories.get(key);
4160
+ if (!memory) return false;
4161
+ memory.is_core = false;
4162
+ this.detailedMemories.set(memory.id, memory);
4163
+ this.coreMemories.delete(memory.id);
4164
+ return true;
4165
+ }
3472
4166
  /**
3473
4167
  * Get memory statistics
3474
4168
  */
@@ -3600,8 +4294,6 @@ var LimoMemoryManager = class {
3600
4294
  return diffMs / (1e3 * 60 * 60 * 24);
3601
4295
  }
3602
4296
  };
3603
-
3604
- // src/session/types.ts
3605
4297
  var DEFAULT_SESSION_CONFIG = {
3606
4298
  directory: ".deity/sessions",
3607
4299
  autoSaveInterval: 3e4,
@@ -3610,6 +4302,32 @@ var DEFAULT_SESSION_CONFIG = {
3610
4302
  maxBackups: 5,
3611
4303
  compress: false
3612
4304
  };
4305
+ var PauseReasonSchema = z.enum(["manual", "timeout", "error"]);
4306
+ var ExecutionStatsSchema = z.object({
4307
+ totalToolCalls: z.number().int().min(0),
4308
+ totalRetries: z.number().int().min(0)
4309
+ }).passthrough();
4310
+ var PausedSessionStateSchema = z.object({
4311
+ inputs: z.unknown(),
4312
+ outputs: z.record(z.string(), z.unknown()),
4313
+ conversation: z.string().optional(),
4314
+ memory: z.string().optional(),
4315
+ appState: z.string().optional(),
4316
+ stats: ExecutionStatsSchema
4317
+ });
4318
+ var PausedSessionMetadataSchema = z.object({
4319
+ pauseReason: PauseReasonSchema,
4320
+ resumable: z.boolean(),
4321
+ notes: z.string().optional()
4322
+ });
4323
+ z.object({
4324
+ sessionId: z.string().min(1, "Session ID cannot be empty"),
4325
+ workflowName: z.string().min(1, "Workflow name cannot be empty"),
4326
+ pausedAt: z.string().datetime("Must be ISO 8601 datetime"),
4327
+ version: z.string().regex(/^\d+\.\d+\.\d+$/, "Must be semver format (e.g., 4.0.0)"),
4328
+ state: PausedSessionStateSchema,
4329
+ metadata: PausedSessionMetadataSchema
4330
+ });
3613
4331
 
3614
4332
  // src/session/serializer.ts
3615
4333
  var TYPE_MARKERS = {
@@ -4038,6 +4756,58 @@ var FileSystemSessionStore = class {
4038
4756
  }
4039
4757
  };
4040
4758
 
4759
+ // src/engine/stores.ts
4760
+ var InMemoryStore = class {
4761
+ data = /* @__PURE__ */ new Map();
4762
+ async get(key) {
4763
+ return this.data.get(key);
4764
+ }
4765
+ async set(key, value) {
4766
+ this.data.set(key, value);
4767
+ }
4768
+ async has(key) {
4769
+ return this.data.has(key);
4770
+ }
4771
+ async delete(key) {
4772
+ this.data.delete(key);
4773
+ }
4774
+ async clear() {
4775
+ this.data.clear();
4776
+ }
4777
+ // Extra methods beyond StateStore interface
4778
+ size() {
4779
+ return this.data.size;
4780
+ }
4781
+ keys() {
4782
+ return Array.from(this.data.keys());
4783
+ }
4784
+ entries() {
4785
+ return Array.from(this.data.entries());
4786
+ }
4787
+ values() {
4788
+ return Array.from(this.data.values());
4789
+ }
4790
+ };
4791
+ var InMemoryTrace = class {
4792
+ entries = [];
4793
+ async log(entry) {
4794
+ this.entries.push(entry);
4795
+ }
4796
+ async getEntries() {
4797
+ return [...this.entries];
4798
+ }
4799
+ // Extra methods for testing
4800
+ clear() {
4801
+ this.entries = [];
4802
+ }
4803
+ count() {
4804
+ return this.entries.length;
4805
+ }
4806
+ getEntriesByType(type) {
4807
+ return this.entries.filter((e) => e.type === type);
4808
+ }
4809
+ };
4810
+
4041
4811
  // src/engine/stats.ts
4042
4812
  var StatsManager = class {
4043
4813
  stats;
@@ -4166,6 +4936,14 @@ async function createEnhancedContext(config) {
4166
4936
  session = new FileSystemSessionStore(sessionConfig);
4167
4937
  await session.init();
4168
4938
  }
4939
+ let appState;
4940
+ if (config.enableAppState) {
4941
+ if (typeof config.enableAppState === "boolean") {
4942
+ appState = new InMemoryStore();
4943
+ } else {
4944
+ appState = config.enableAppState;
4945
+ }
4946
+ }
4169
4947
  return new ExecutionContext({
4170
4948
  inputs: config.inputs,
4171
4949
  previousOutputs: config.previousOutputs ?? {},
@@ -4175,6 +4953,7 @@ async function createEnhancedContext(config) {
4175
4953
  conversation,
4176
4954
  memory,
4177
4955
  session,
4956
+ appState,
4178
4957
  ui: config.ui,
4179
4958
  currentStageId: config.currentStageId,
4180
4959
  iteration: config.loop?.iteration,
@@ -4183,52 +4962,6 @@ async function createEnhancedContext(config) {
4183
4962
  });
4184
4963
  }
4185
4964
 
4186
- // src/engine/stores.ts
4187
- var InMemoryStore = class {
4188
- data = /* @__PURE__ */ new Map();
4189
- async get(key) {
4190
- return this.data.get(key);
4191
- }
4192
- async set(key, value) {
4193
- this.data.set(key, value);
4194
- }
4195
- async has(key) {
4196
- return this.data.has(key);
4197
- }
4198
- async delete(key) {
4199
- this.data.delete(key);
4200
- }
4201
- async clear() {
4202
- this.data.clear();
4203
- }
4204
- // Extra methods for testing
4205
- size() {
4206
- return this.data.size;
4207
- }
4208
- keys() {
4209
- return Array.from(this.data.keys());
4210
- }
4211
- };
4212
- var InMemoryTrace = class {
4213
- entries = [];
4214
- async log(entry) {
4215
- this.entries.push(entry);
4216
- }
4217
- async getEntries() {
4218
- return [...this.entries];
4219
- }
4220
- // Extra methods for testing
4221
- clear() {
4222
- this.entries = [];
4223
- }
4224
- count() {
4225
- return this.entries.length;
4226
- }
4227
- getEntriesByType(type) {
4228
- return this.entries.filter((e) => e.type === type);
4229
- }
4230
- };
4231
-
4232
4965
  // src/engine/workflow.ts
4233
4966
  async function runWorkflow(config, inputs) {
4234
4967
  const store = config.state?.store ?? new InMemoryStore();
@@ -4240,6 +4973,7 @@ async function runWorkflow(config, inputs) {
4240
4973
  enableConversation: config.enhancements?.conversation !== void 0,
4241
4974
  enableMemory: config.enhancements?.memory !== void 0,
4242
4975
  enableSession: config.enhancements?.session !== void 0,
4976
+ enableAppState: config.enhancements?.appState,
4243
4977
  ui: config.enhancements?.ui
4244
4978
  });
4245
4979
  const result = await executeNode(
@@ -4250,6 +4984,10 @@ async function runWorkflow(config, inputs) {
4250
4984
  );
4251
4985
  return result;
4252
4986
  }
4987
+ async function runTSXWorkflow(workflowAST, inputs) {
4988
+ const config = compileWorkflow(workflowAST);
4989
+ return runWorkflow(config, inputs);
4990
+ }
4253
4991
  async function executeNode(node, ctx, adapter, config) {
4254
4992
  switch (node.type) {
4255
4993
  case "step":
@@ -4262,6 +5000,8 @@ async function executeNode(node, ctx, adapter, config) {
4262
5000
  return executeConditionalNode(node, ctx, adapter, config);
4263
5001
  case "loop":
4264
5002
  return executeLoopNode(node, ctx, adapter, config);
5003
+ case "foreach":
5004
+ return executeForEachNode(node, ctx, adapter, config);
4265
5005
  default:
4266
5006
  throw new Error(`Unknown node type: ${node.type}`);
4267
5007
  }
@@ -4347,6 +5087,116 @@ async function executeLoopNode(node, ctx, adapter, config) {
4347
5087
  }
4348
5088
  return results;
4349
5089
  }
5090
+ async function executeForEachNode(node, ctx, adapter, config) {
5091
+ if (!node.children || node.children.length === 0) {
5092
+ throw new Error("ForEach node has no children");
5093
+ }
5094
+ if (!node.itemsAccessor) {
5095
+ throw new Error("ForEach node missing itemsAccessor");
5096
+ }
5097
+ let items;
5098
+ if (typeof node.itemsAccessor === "function") {
5099
+ items = await Promise.resolve(node.itemsAccessor(ctx));
5100
+ } else {
5101
+ items = node.itemsAccessor;
5102
+ }
5103
+ if (!Array.isArray(items)) {
5104
+ throw new Error("ForEach items must be an array");
5105
+ }
5106
+ const itemMode = node.itemMode ?? "property";
5107
+ const itemKey = node.itemKey ?? "currentItem";
5108
+ const errorMode = node.errorMode ?? "stop";
5109
+ const collectResults = node.collectResults ?? true;
5110
+ const results = [];
5111
+ const errors = [];
5112
+ let successCount = 0;
5113
+ let failureCount = 0;
5114
+ for (let i = 0; i < items.length; i++) {
5115
+ const item = items[i];
5116
+ try {
5117
+ const iterationCtx = createIterationContext(
5118
+ ctx,
5119
+ item,
5120
+ i,
5121
+ items.length,
5122
+ itemMode,
5123
+ itemKey
5124
+ );
5125
+ const result = await executeNode(node.children[0], iterationCtx, adapter, config);
5126
+ if (collectResults) {
5127
+ results.push(result);
5128
+ }
5129
+ successCount++;
5130
+ } catch (error) {
5131
+ failureCount++;
5132
+ const err = error instanceof Error ? error : new Error(String(error));
5133
+ if (errorMode === "stop") {
5134
+ throw err;
5135
+ } else if (errorMode === "continue") {
5136
+ errors.push({ index: i, item, error: err });
5137
+ } else ;
5138
+ }
5139
+ }
5140
+ if (errorMode === "continue" && (errors.length > 0 || failureCount > 0)) {
5141
+ return {
5142
+ results,
5143
+ errors,
5144
+ totalItems: items.length,
5145
+ successCount,
5146
+ failureCount
5147
+ };
5148
+ }
5149
+ return results;
5150
+ }
5151
+ function createIterationContext(baseCtx, currentItem, index, totalItems, itemMode, itemKey) {
5152
+ let newInputs;
5153
+ if (itemMode === "property") {
5154
+ newInputs = {
5155
+ ...baseCtx.inputs,
5156
+ [itemKey]: currentItem,
5157
+ __forEachIndex: index,
5158
+ __forEachTotal: totalItems,
5159
+ __forEachIsLast: index === totalItems - 1
5160
+ };
5161
+ } else if (itemMode === "merge") {
5162
+ if (typeof currentItem === "object" && currentItem !== null) {
5163
+ newInputs = {
5164
+ ...baseCtx.inputs,
5165
+ ...currentItem,
5166
+ __forEachIndex: index,
5167
+ __forEachTotal: totalItems,
5168
+ __forEachIsLast: index === totalItems - 1
5169
+ };
5170
+ } else {
5171
+ throw new Error(
5172
+ `ForEach itemMode='merge' requires object items, got ${typeof currentItem}`
5173
+ );
5174
+ }
5175
+ } else if (itemMode === "replace") {
5176
+ if (typeof currentItem === "object" && currentItem !== null) {
5177
+ newInputs = {
5178
+ ...currentItem,
5179
+ __forEachIndex: index,
5180
+ __forEachTotal: totalItems,
5181
+ __forEachIsLast: index === totalItems - 1
5182
+ };
5183
+ } else {
5184
+ newInputs = currentItem;
5185
+ }
5186
+ } else {
5187
+ throw new Error(`Unknown itemMode: ${itemMode}`);
5188
+ }
5189
+ if (baseCtx instanceof ExecutionContext) {
5190
+ return baseCtx.withInputs(newInputs).withIteration(index, totalItems);
5191
+ }
5192
+ return {
5193
+ ...baseCtx,
5194
+ inputs: newInputs,
5195
+ iteration: index,
5196
+ maxIterations: totalItems,
5197
+ isLastIteration: index === totalItems - 1
5198
+ };
5199
+ }
4350
5200
  function createStepNode(component) {
4351
5201
  return {
4352
5202
  type: "step",
@@ -4380,250 +5230,6 @@ function createLoopNode(child, maxIterations) {
4380
5230
  };
4381
5231
  }
4382
5232
 
4383
- // src/engine/tool-result-extractor.ts
4384
- function extractLastToolResult(llmResult, toolName, options = {}) {
4385
- const { unwrap = true, required = true } = options;
4386
- if (llmResult.response?.toolCalls && llmResult.response.toolCalls.length > 0) {
4387
- const toolCalls = llmResult.response.toolCalls.filter(
4388
- (tc) => tc.name === toolName
4389
- );
4390
- if (toolCalls.length > 0) {
4391
- const lastCall = toolCalls[toolCalls.length - 1];
4392
- return parseToolCall(lastCall, unwrap);
4393
- }
4394
- }
4395
- const toolMessages = llmResult.messages.filter(
4396
- (msg) => msg.role === "tool" && msg.name === toolName
4397
- );
4398
- if (toolMessages.length === 0) {
4399
- if (required) {
4400
- throw new Error(`Tool '${toolName}' was not called`);
4401
- }
4402
- return null;
4403
- }
4404
- const lastMessage = toolMessages[toolMessages.length - 1];
4405
- return parseToolResult(lastMessage.content, unwrap);
4406
- }
4407
- function extractAllToolResults(llmResult, toolName, options = {}) {
4408
- const { unwrap = true, filterSuccess = false } = options;
4409
- if (llmResult.response?.toolCalls && llmResult.response.toolCalls.length > 0) {
4410
- const toolCalls = llmResult.response.toolCalls.filter(
4411
- (tc) => tc.name === toolName
4412
- );
4413
- if (toolCalls.length > 0) {
4414
- let results2 = toolCalls.map((tc) => {
4415
- try {
4416
- return parseToolCall(tc, unwrap);
4417
- } catch {
4418
- return null;
4419
- }
4420
- }).filter((r) => r !== null);
4421
- if (filterSuccess && unwrap) {
4422
- results2 = results2.filter((result) => {
4423
- if (result && typeof result === "object" && "success" in result) {
4424
- return result.success === true;
4425
- }
4426
- return true;
4427
- });
4428
- }
4429
- return results2;
4430
- }
4431
- }
4432
- const toolMessages = llmResult.messages.filter(
4433
- (msg) => msg.role === "tool" && msg.name === toolName
4434
- );
4435
- let results = toolMessages.map((msg) => {
4436
- try {
4437
- return parseToolResult(msg.content, unwrap);
4438
- } catch {
4439
- return null;
4440
- }
4441
- }).filter((r) => r !== null);
4442
- if (filterSuccess && unwrap) {
4443
- results = results.filter((result) => {
4444
- if (result && typeof result === "object" && "success" in result) {
4445
- return result.success === true;
4446
- }
4447
- return true;
4448
- });
4449
- }
4450
- return results;
4451
- }
4452
- function countToolCalls(llmResult, toolName, filter) {
4453
- if (llmResult.response?.toolCalls && llmResult.response.toolCalls.length > 0) {
4454
- const toolCalls = llmResult.response.toolCalls.filter(
4455
- (tc) => tc.name === toolName
4456
- );
4457
- if (toolCalls.length > 0) {
4458
- if (!filter) {
4459
- return toolCalls.length;
4460
- }
4461
- return toolCalls.filter((tc) => {
4462
- try {
4463
- const parsed = parseToolCall(tc, true);
4464
- return filter(parsed);
4465
- } catch {
4466
- return false;
4467
- }
4468
- }).length;
4469
- }
4470
- }
4471
- const toolMessages = llmResult.messages.filter(
4472
- (msg) => msg.role === "tool" && msg.name === toolName
4473
- );
4474
- if (!filter) {
4475
- return toolMessages.length;
4476
- }
4477
- return toolMessages.filter((msg) => {
4478
- try {
4479
- const result = JSON.parse(msg.content);
4480
- return filter(result);
4481
- } catch {
4482
- return false;
4483
- }
4484
- }).length;
4485
- }
4486
- function parseToolCall(toolCall, unwrap) {
4487
- try {
4488
- if (toolCall._executionResult) {
4489
- const result = JSON.parse(toolCall._executionResult);
4490
- if (unwrap && result && typeof result === "object") {
4491
- if ("success" in result) {
4492
- if (result.success === false && result.error) {
4493
- throw new Error(`Tool execution failed: ${result.error}`);
4494
- }
4495
- return result.data !== void 0 ? result.data : result;
4496
- }
4497
- }
4498
- return result;
4499
- }
4500
- return toolCall.arguments;
4501
- } catch (error) {
4502
- throw new Error(`Failed to parse tool call: ${error.message}`);
4503
- }
4504
- }
4505
- function parseToolResult(content, unwrap) {
4506
- try {
4507
- const parsed = JSON.parse(content);
4508
- if (unwrap && parsed && typeof parsed === "object") {
4509
- if ("success" in parsed) {
4510
- if (parsed.success === false && parsed.error) {
4511
- throw new Error(`Tool execution failed: ${parsed.error}`);
4512
- }
4513
- return parsed.data !== void 0 ? parsed.data : parsed;
4514
- }
4515
- }
4516
- return parsed;
4517
- } catch (error) {
4518
- throw new Error(`Failed to parse tool result: ${error.message}`);
4519
- }
4520
- }
4521
- var MemoryStoreInputSchema = z.object({
4522
- key: z.string().describe("Unique identifier for this memory entry"),
4523
- content: z.string().min(20).describe("Content to store (minimum 20 characters for meaningful data)"),
4524
- importance: z.number().min(0).max(10).optional().default(5).describe("Importance level (0-10, higher = more important, default: 5)"),
4525
- category: z.string().optional().describe('Category for filtering and organization (e.g., "architecture", "planning")'),
4526
- tags: z.array(z.string()).optional().default([]).describe("Tags for relevance matching and retrieval")
4527
- });
4528
- var MemoryRecallInputSchema = z.object({
4529
- query: z.string().describe("Search query or keywords to find relevant memories"),
4530
- category: z.string().optional().describe("Filter results by category"),
4531
- limit: z.number().min(1).max(20).optional().default(5).describe("Maximum number of memories to return (default: 5, max: 20)")
4532
- });
4533
- function createMemoryTools(ctx) {
4534
- if (!ctx.memory) {
4535
- throw new Error(
4536
- "Cannot create memory tools: Memory is not enabled in ExecutionContext. Use createEnhancedContext({ enableMemory: true }) to enable memory."
4537
- );
4538
- }
4539
- const memory = ctx.memory;
4540
- return [
4541
- // ========================================================================
4542
- // memory_store
4543
- // ========================================================================
4544
- {
4545
- name: "memory_store",
4546
- description: "Store important findings, insights, or context for later retrieval. Use this to remember key information that will be useful in subsequent analysis phases.",
4547
- inputSchema: MemoryStoreInputSchema,
4548
- execute: async (params) => {
4549
- try {
4550
- const memoryData = {
4551
- content: params.content,
4552
- importance: params.importance,
4553
- category: params.category,
4554
- tags: params.tags,
4555
- stored_at: (/* @__PURE__ */ new Date()).toISOString()
4556
- };
4557
- await memory.set(params.key, memoryData);
4558
- return {
4559
- success: true,
4560
- key: params.key,
4561
- stored_at: memoryData.stored_at,
4562
- message: `Memory '${params.key}' stored successfully`
4563
- };
4564
- } catch (error) {
4565
- const errorMsg = error instanceof Error ? error.message : String(error);
4566
- return {
4567
- success: false,
4568
- error: `Failed to store memory: ${errorMsg}`
4569
- };
4570
- }
4571
- }
4572
- },
4573
- // ========================================================================
4574
- // memory_recall
4575
- // ========================================================================
4576
- {
4577
- name: "memory_recall",
4578
- description: "Recall previously stored memories by searching with keywords or queries. Returns the most relevant memories based on content similarity, category, tags, and importance.",
4579
- inputSchema: MemoryRecallInputSchema,
4580
- execute: async (params) => {
4581
- try {
4582
- const keywords = params.query.toLowerCase().split(/\s+/).filter((word) => word.length > 3);
4583
- const memories = await memory.loadWorkingMemory({
4584
- currentTask: params.query,
4585
- keywords,
4586
- categories: params.category ? [params.category] : void 0
4587
- });
4588
- const limit = params.limit ?? 5;
4589
- const results = memories.slice(0, limit);
4590
- const formattedMemories = results.map((m) => {
4591
- let content = m.content;
4592
- try {
4593
- const parsed = JSON.parse(m.content);
4594
- content = parsed.content || m.content;
4595
- } catch {
4596
- }
4597
- return {
4598
- key: m.id,
4599
- content,
4600
- importance: m.importance,
4601
- category: m.category,
4602
- tags: m.tags,
4603
- stored_at: m.stored_at,
4604
- access_count: m.access_count
4605
- };
4606
- });
4607
- return {
4608
- success: true,
4609
- count: formattedMemories.length,
4610
- total_available: memories.length,
4611
- memories: formattedMemories,
4612
- message: `Found ${formattedMemories.length} relevant memories`
4613
- };
4614
- } catch (error) {
4615
- const errorMsg = error instanceof Error ? error.message : String(error);
4616
- return {
4617
- success: false,
4618
- error: `Failed to recall memories: ${errorMsg}`,
4619
- memories: []
4620
- };
4621
- }
4622
- }
4623
- }
4624
- ];
4625
- }
4626
-
4627
- export { Agent, DEBUG_ENABLED, DebugLogger, InMemoryStore, InMemoryTrace, Observe, ObserveUtils, PreflightChecker, Prompt, PromptResourceLoader, Result, ResultUtils, Retry, RetryUtils, System, User, Validate, ValidateUtils, compileAgent, countToolCalls, createConditionalNode, createEnhancedContext, createLoopNode, createMemoryTools, createParallelNode, createSequenceNode, createStepNode, executeComponent, executeLLMLoop, extractAllToolResults, extractLastToolResult, getResourceLoader, isAgentNode, isObserveNode, isPromptNode, isResultNode, isRetryNode, isSystemNode, isUserNode, isValidateNode, logger, preflight, runWorkflow, setResourceLoader, testFullAgent };
5233
+ export { Agent, Conditional, DEBUG_ENABLED, DebugLogger, ForEach, InMemoryStore, InMemoryTrace, Loop, Observe, ObserveUtils, Parallel, PreflightChecker, Prompt, PromptResourceLoader, Result, ResultUtils, Retry, RetryUtils, Sequence, System, Tool, ToolDef, ToolRef, Tools, User, Validate, ValidateUtils, Workflow, compileAgent, compileWorkflow, compileWorkflowNode, createConditionalNode, createEnhancedContext, createLoopNode, createParallelNode, createSequenceNode, createStepNode, executeComponent, executeLLMLoop, getResourceLoader, isAgentNode, isObserveNode, isPromptNode, isResultNode, isRetryNode, isSystemNode, isToolDefNode, isToolRefNode, isToolsNode, isUserNode, isValidateNode, isWorkflowConditionalNode, isWorkflowForEachNode, isWorkflowLoopNode, isWorkflowNode, isWorkflowParallelNode, isWorkflowSequenceNode, logger, preflight, runTSXWorkflow, runWorkflow, setResourceLoader, testFullAgent, toAgent, toWorkflow };
4628
5234
  //# sourceMappingURL=index.js.map
4629
5235
  //# sourceMappingURL=index.js.map