@axiom-lattice/core 2.1.80 → 2.1.81
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/{chunk-FN4TRQK4.mjs → chunk-SGRFQY3E.mjs} +386 -504
- package/dist/chunk-SGRFQY3E.mjs.map +1 -0
- package/dist/compile-4RFYHUBE.mjs +11 -0
- package/dist/index.d.mts +213 -34
- package/dist/index.d.ts +213 -34
- package/dist/index.js +1696 -1298
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1238 -733
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-FN4TRQK4.mjs.map +0 -1
- package/dist/compile-SYSKVQHB.mjs +0 -9
- /package/dist/{compile-SYSKVQHB.mjs.map → compile-4RFYHUBE.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -387,40 +387,342 @@ var init_memory_lattice = __esm({
|
|
|
387
387
|
}
|
|
388
388
|
});
|
|
389
389
|
|
|
390
|
+
// src/workflow/schema.ts
|
|
391
|
+
function toJsonSchema(fields) {
|
|
392
|
+
if (!fields || Object.keys(fields).length === 0) return void 0;
|
|
393
|
+
const properties = {};
|
|
394
|
+
const required = [];
|
|
395
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
396
|
+
required.push(key);
|
|
397
|
+
properties[key] = fieldToSchema(value);
|
|
398
|
+
}
|
|
399
|
+
return { type: "object", properties, required };
|
|
400
|
+
}
|
|
401
|
+
function fieldToSchema(value) {
|
|
402
|
+
if (typeof value === "string") return stringTypeToSchema(value);
|
|
403
|
+
if (Array.isArray(value) && value.length > 0 && typeof value[0] === "object" && !Array.isArray(value[0])) {
|
|
404
|
+
const nested = toJsonSchema(value[0]);
|
|
405
|
+
return { type: "array", items: nested ?? { type: "object" } };
|
|
406
|
+
}
|
|
407
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
408
|
+
const nested = toJsonSchema(value);
|
|
409
|
+
return nested ?? { type: "object" };
|
|
410
|
+
}
|
|
411
|
+
return { type: "string" };
|
|
412
|
+
}
|
|
413
|
+
function stringTypeToSchema(type) {
|
|
414
|
+
if (type.endsWith("[]")) {
|
|
415
|
+
const inner = type.slice(0, -2);
|
|
416
|
+
return { type: "array", items: stringTypeToSchema(inner) };
|
|
417
|
+
}
|
|
418
|
+
if (type === "string") return { type: "string" };
|
|
419
|
+
if (type === "number") return { type: "number" };
|
|
420
|
+
if (type === "boolean") return { type: "boolean" };
|
|
421
|
+
return { type };
|
|
422
|
+
}
|
|
423
|
+
var init_schema = __esm({
|
|
424
|
+
"src/workflow/schema.ts"() {
|
|
425
|
+
"use strict";
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// src/workflow/parse-yaml.ts
|
|
430
|
+
function nodeId(label) {
|
|
431
|
+
return `n_${label}`;
|
|
432
|
+
}
|
|
433
|
+
function nextParallelLabel() {
|
|
434
|
+
return `parallel_${_parallelSeq++}`;
|
|
435
|
+
}
|
|
436
|
+
function translate(template) {
|
|
437
|
+
return template.replace(/\{\{([^}]+)\}\}/g, (_m, expr) => {
|
|
438
|
+
const t = expr.trim();
|
|
439
|
+
if (t === "item") return "${item}";
|
|
440
|
+
return `\${state.${t}}`;
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
function toSafeStateExpr(expr) {
|
|
444
|
+
const match = expr.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)/);
|
|
445
|
+
if (!match) return `state.${expr}`;
|
|
446
|
+
const field = match[0];
|
|
447
|
+
const rest = expr.slice(field.length);
|
|
448
|
+
return `state["${field}"]${rest}`;
|
|
449
|
+
}
|
|
450
|
+
function validateExpression(expr) {
|
|
451
|
+
if (/;/.test(expr)) {
|
|
452
|
+
throw new Error(`Condition expression must not contain semicolons: "${expr}"`);
|
|
453
|
+
}
|
|
454
|
+
if (/[{}]/.test(expr)) {
|
|
455
|
+
throw new Error(`Condition expression must not contain braces: "${expr}"`);
|
|
456
|
+
}
|
|
457
|
+
if (/\bfunction\b/.test(expr)) {
|
|
458
|
+
throw new Error(`Condition expression must not contain 'function': "${expr}"`);
|
|
459
|
+
}
|
|
460
|
+
if (/\brequire\b|\bimport\b|\bmodule\b/.test(expr)) {
|
|
461
|
+
throw new Error(`Condition expression must not contain require/import: "${expr}"`);
|
|
462
|
+
}
|
|
463
|
+
if (/\bprocess\b|\bglobal\b|\bglobalThis\b/.test(expr)) {
|
|
464
|
+
throw new Error(`Condition expression must not contain process/global: "${expr}"`);
|
|
465
|
+
}
|
|
466
|
+
if (/\beval\b|\bFunction\b/.test(expr)) {
|
|
467
|
+
throw new Error(`Condition expression must not contain eval/Function: "${expr}"`);
|
|
468
|
+
}
|
|
469
|
+
if (/\bconstructor\b|\b__proto__\b|\bprototype\b/.test(expr)) {
|
|
470
|
+
throw new Error(`Condition expression must not contain prototype access: "${expr}"`);
|
|
471
|
+
}
|
|
472
|
+
if (/\bsetTimeout\b|\bsetInterval\b|\bbuffer\b/i.test(expr)) {
|
|
473
|
+
throw new Error(`Condition expression must not contain timer or buffer references: "${expr}"`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function parseYaml(yamlStr) {
|
|
477
|
+
_parallelSeq = 0;
|
|
478
|
+
let raw;
|
|
479
|
+
try {
|
|
480
|
+
raw = yaml.load(yamlStr);
|
|
481
|
+
} catch (e) {
|
|
482
|
+
const line = e?.mark?.line != null ? ` (line ${e.mark.line + 1})` : "";
|
|
483
|
+
throw new Error(`YAML parse error${line}: ${e.message || e}`);
|
|
484
|
+
}
|
|
485
|
+
if (!raw || typeof raw !== "object" || !Array.isArray(raw.steps)) {
|
|
486
|
+
throw new Error("Workflow YAML must have 'steps' (array)");
|
|
487
|
+
}
|
|
488
|
+
const name = typeof raw.name === "string" ? raw.name : "workflow";
|
|
489
|
+
const wf = {
|
|
490
|
+
name,
|
|
491
|
+
steps: raw.steps.map((s, i) => parseStep(s, i))
|
|
492
|
+
};
|
|
493
|
+
return normalize(wf);
|
|
494
|
+
}
|
|
495
|
+
function parseStep(raw, index) {
|
|
496
|
+
if (raw.parallel !== void 0) {
|
|
497
|
+
if (!Array.isArray(raw.parallel)) {
|
|
498
|
+
throw new Error(`Step at position ${index}: parallel must be an array`);
|
|
499
|
+
}
|
|
500
|
+
const children = raw.parallel.map((c, ci) => {
|
|
501
|
+
const entries2 = Object.entries(c);
|
|
502
|
+
if (entries2.length !== 1) {
|
|
503
|
+
throw new Error(`Parallel child at position ${index}.${ci} must be a single-key mapping`);
|
|
504
|
+
}
|
|
505
|
+
const [label, config2] = entries2[0];
|
|
506
|
+
return {
|
|
507
|
+
label,
|
|
508
|
+
if: config2.if !== void 0 ? String(config2.if) : void 0,
|
|
509
|
+
prompt: String(config2.prompt ?? ""),
|
|
510
|
+
output: config2.output,
|
|
511
|
+
ask: config2.ask === true
|
|
512
|
+
};
|
|
513
|
+
});
|
|
514
|
+
return {
|
|
515
|
+
parallel: children,
|
|
516
|
+
if: raw.if !== void 0 ? String(raw.if) : void 0,
|
|
517
|
+
output: raw.output
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
const entries = Object.entries(raw);
|
|
521
|
+
if (entries.length !== 1) {
|
|
522
|
+
throw new Error(`Step at position ${index} must be a single-key mapping`);
|
|
523
|
+
}
|
|
524
|
+
const [key, config] = entries[0];
|
|
525
|
+
const mapConfig = config?.map;
|
|
526
|
+
if (mapConfig && typeof mapConfig === "object") {
|
|
527
|
+
return {
|
|
528
|
+
map: {
|
|
529
|
+
source: mapConfig.source,
|
|
530
|
+
label: key,
|
|
531
|
+
// always use the YAML key as the label
|
|
532
|
+
if: mapConfig.if !== void 0 ? String(mapConfig.if) : void 0,
|
|
533
|
+
each: {
|
|
534
|
+
prompt: String(mapConfig.each?.prompt ?? ""),
|
|
535
|
+
output: mapConfig.each?.output
|
|
536
|
+
},
|
|
537
|
+
output: mapConfig.output,
|
|
538
|
+
batch: mapConfig.batch,
|
|
539
|
+
concurrency: mapConfig.concurrency
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
if (key === "map") {
|
|
544
|
+
throw new Error(`Map steps must use named format: - <label>: { map: { source, each, ... } }. Anonymous "- map:" is not supported.`);
|
|
545
|
+
}
|
|
546
|
+
return {
|
|
547
|
+
label: key,
|
|
548
|
+
if: config.if !== void 0 ? String(config.if) : void 0,
|
|
549
|
+
prompt: String(config.prompt ?? ""),
|
|
550
|
+
output: config.output,
|
|
551
|
+
ask: config.ask === true
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
function normalize(wf) {
|
|
555
|
+
validate(wf);
|
|
556
|
+
for (const step of wf.steps) {
|
|
557
|
+
if ("label" in step) {
|
|
558
|
+
const s = step;
|
|
559
|
+
if (s.if) validateExpression(s.if);
|
|
560
|
+
} else if ("parallel" in step) {
|
|
561
|
+
const pb = step;
|
|
562
|
+
if (pb.if) validateExpression(pb.if);
|
|
563
|
+
for (const child of pb.parallel) {
|
|
564
|
+
if (child.if) validateExpression(child.if);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
const nodes = [];
|
|
569
|
+
const edges = [];
|
|
570
|
+
const fields = { input: { type: "string" } };
|
|
571
|
+
nodes.push({ id: "n_input", type: "input", name: "input", output: { key: "input" } });
|
|
572
|
+
edges.push({ from: "START", to: "n_input" });
|
|
573
|
+
let prevNodeId = "n_input";
|
|
574
|
+
for (const step of wf.steps) {
|
|
575
|
+
if ("label" in step) {
|
|
576
|
+
const s = step;
|
|
577
|
+
const nid = nodeId(s.label);
|
|
578
|
+
const schema = toJsonSchema(s.output);
|
|
579
|
+
nodes.push({
|
|
580
|
+
id: nid,
|
|
581
|
+
type: "agent",
|
|
582
|
+
name: s.label,
|
|
583
|
+
input: { template: translate(s.prompt) },
|
|
584
|
+
output: { key: s.label, ...schema ? { schema } : {} },
|
|
585
|
+
ask: s.ask,
|
|
586
|
+
condition: s.if
|
|
587
|
+
});
|
|
588
|
+
fields[s.label] = s.output ? { type: "object" } : { type: "string" };
|
|
589
|
+
addPrevEdges(edges, prevNodeId, nid);
|
|
590
|
+
prevNodeId = nid;
|
|
591
|
+
} else if ("parallel" in step) {
|
|
592
|
+
const pb = step;
|
|
593
|
+
const groupId = nextParallelLabel();
|
|
594
|
+
const groupNodeIds = [];
|
|
595
|
+
for (const child of pb.parallel) {
|
|
596
|
+
const nid = nodeId(child.label);
|
|
597
|
+
const schema = toJsonSchema(child.output);
|
|
598
|
+
nodes.push({
|
|
599
|
+
id: nid,
|
|
600
|
+
type: "agent",
|
|
601
|
+
name: child.label,
|
|
602
|
+
input: { template: translate(child.prompt) },
|
|
603
|
+
output: { key: child.label, ...schema ? { schema } : {} },
|
|
604
|
+
ask: child.ask,
|
|
605
|
+
condition: child.if,
|
|
606
|
+
parallelGroup: groupId
|
|
607
|
+
});
|
|
608
|
+
fields[child.label] = child.output ? { type: "object" } : { type: "string" };
|
|
609
|
+
groupNodeIds.push(nid);
|
|
610
|
+
}
|
|
611
|
+
addPrevEdges(edges, prevNodeId, groupNodeIds);
|
|
612
|
+
prevNodeId = groupNodeIds;
|
|
613
|
+
} else if ("map" in step) {
|
|
614
|
+
const ms = step.map;
|
|
615
|
+
const label = ms.label;
|
|
616
|
+
const nid = nodeId(label);
|
|
617
|
+
const innerSchema = toJsonSchema(ms.each?.output);
|
|
618
|
+
const mapSchema = toJsonSchema(ms.output);
|
|
619
|
+
nodes.push({
|
|
620
|
+
id: nid,
|
|
621
|
+
type: "map",
|
|
622
|
+
name: label,
|
|
623
|
+
source: `state.${ms.source}`,
|
|
624
|
+
itemKey: "item",
|
|
625
|
+
config: {
|
|
626
|
+
batchSize: ms.batch ?? 50,
|
|
627
|
+
maxConcurrency: ms.concurrency ?? 5,
|
|
628
|
+
innerConcurrency: ms.concurrency ?? 5
|
|
629
|
+
},
|
|
630
|
+
node: {
|
|
631
|
+
type: "agent",
|
|
632
|
+
input: ms.each?.prompt ? { template: translate(ms.each.prompt) } : void 0,
|
|
633
|
+
...innerSchema ? { schema: innerSchema } : {}
|
|
634
|
+
},
|
|
635
|
+
output: { key: label, ...mapSchema ? { schema: mapSchema } : {} },
|
|
636
|
+
condition: ms.if
|
|
637
|
+
});
|
|
638
|
+
fields[label] = { type: "array", default: [] };
|
|
639
|
+
addPrevEdges(edges, prevNodeId, nid);
|
|
640
|
+
prevNodeId = nid;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
const termNid = nodeId("__end");
|
|
644
|
+
nodes.push({ id: termNid, type: "terminal", name: "__end", status: "success" });
|
|
645
|
+
addPrevEdges(edges, prevNodeId, termNid);
|
|
646
|
+
return { version: "1.0", name: wf.name || "workflow", state: { fields }, nodes, edges };
|
|
647
|
+
}
|
|
648
|
+
function addPrevEdges(edges, fromNodes, toNodes) {
|
|
649
|
+
const fromList = Array.isArray(fromNodes) ? fromNodes : [fromNodes];
|
|
650
|
+
const toList = Array.isArray(toNodes) ? toNodes : [toNodes];
|
|
651
|
+
for (const from of fromList) {
|
|
652
|
+
for (const to of toList) {
|
|
653
|
+
if (!edges.some((e) => e.from === from && e.to === to)) {
|
|
654
|
+
edges.push({ from, to });
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
function validate(wf) {
|
|
660
|
+
const labels = /* @__PURE__ */ new Set();
|
|
661
|
+
for (const step of wf.steps) {
|
|
662
|
+
if ("label" in step) {
|
|
663
|
+
const s = step;
|
|
664
|
+
if (labels.has(s.label)) throw new Error(`Duplicate step label "${s.label}"`);
|
|
665
|
+
labels.add(s.label);
|
|
666
|
+
} else if ("parallel" in step) {
|
|
667
|
+
const pb = step;
|
|
668
|
+
if (pb.parallel.length === 0) {
|
|
669
|
+
throw new Error("parallel block must contain at least one child step");
|
|
670
|
+
}
|
|
671
|
+
for (const child of pb.parallel) {
|
|
672
|
+
if (labels.has(child.label)) throw new Error(`Duplicate step label "${child.label}"`);
|
|
673
|
+
labels.add(child.label);
|
|
674
|
+
}
|
|
675
|
+
} else if ("map" in step) {
|
|
676
|
+
const ms = step.map;
|
|
677
|
+
if (labels.has(ms.label)) throw new Error(`Duplicate step label "${ms.label}" (map step)`);
|
|
678
|
+
labels.add(ms.label);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
var yaml, _parallelSeq;
|
|
683
|
+
var init_parse_yaml = __esm({
|
|
684
|
+
"src/workflow/parse-yaml.ts"() {
|
|
685
|
+
"use strict";
|
|
686
|
+
yaml = __toESM(require("js-yaml"));
|
|
687
|
+
init_schema();
|
|
688
|
+
_parallelSeq = 0;
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
|
|
390
692
|
// src/workflow/utils.ts
|
|
391
693
|
function buildStateAnnotation(fields) {
|
|
392
694
|
const annotations = {};
|
|
393
695
|
if (fields) {
|
|
394
696
|
for (const [key, field] of Object.entries(fields)) {
|
|
395
|
-
annotations[key] = (0,
|
|
697
|
+
annotations[key] = (0, import_langgraph14.Annotation)({
|
|
396
698
|
default: () => field.default ?? defaultValueForType(field.type),
|
|
397
699
|
reducer: buildReducer(field.reducer ?? "replace")
|
|
398
700
|
});
|
|
399
701
|
}
|
|
400
702
|
}
|
|
401
703
|
if (!annotations["messages"]) {
|
|
402
|
-
annotations["messages"] = (0,
|
|
704
|
+
annotations["messages"] = (0, import_langgraph14.Annotation)({
|
|
403
705
|
default: () => [],
|
|
404
706
|
reducer: (prev, next) => [...prev, ...next]
|
|
405
707
|
});
|
|
406
708
|
}
|
|
407
|
-
annotations["phase"] = (0,
|
|
709
|
+
annotations["phase"] = (0, import_langgraph14.Annotation)({
|
|
408
710
|
default: () => "init",
|
|
409
711
|
reducer: (_prev, next) => next
|
|
410
712
|
});
|
|
411
713
|
if (!annotations["status"]) {
|
|
412
|
-
annotations["status"] = (0,
|
|
714
|
+
annotations["status"] = (0, import_langgraph14.Annotation)({
|
|
413
715
|
default: () => "",
|
|
414
716
|
reducer: (_prev, next) => next
|
|
415
717
|
});
|
|
416
718
|
}
|
|
417
719
|
if (!annotations["_runId"]) {
|
|
418
|
-
annotations["_runId"] = (0,
|
|
720
|
+
annotations["_runId"] = (0, import_langgraph14.Annotation)({
|
|
419
721
|
default: () => void 0,
|
|
420
722
|
reducer: (_prev, next) => next ?? _prev
|
|
421
723
|
});
|
|
422
724
|
}
|
|
423
|
-
return
|
|
725
|
+
return import_langgraph14.Annotation.Root(annotations);
|
|
424
726
|
}
|
|
425
727
|
function defaultValueForType(type) {
|
|
426
728
|
switch (type) {
|
|
@@ -528,7 +830,7 @@ Output must be valid JSON in exactly this shape. Return ONLY the JSON, no other
|
|
|
528
830
|
${example}`;
|
|
529
831
|
prompt = prompt + schemaInstruction;
|
|
530
832
|
}
|
|
531
|
-
return { messages: [new
|
|
833
|
+
return { messages: [new import_messages5.HumanMessage(prompt)] };
|
|
532
834
|
}
|
|
533
835
|
function schemaToExample(schema) {
|
|
534
836
|
const example = schemaValueToExample(schema);
|
|
@@ -674,6 +976,36 @@ function createAgentNode(node, resolveAgent, trackingStore) {
|
|
|
674
976
|
return async (state, config) => {
|
|
675
977
|
const runId = state._runId;
|
|
676
978
|
const tenantId = config?.configurable?.tenantId ?? "default";
|
|
979
|
+
if (node.condition) {
|
|
980
|
+
try {
|
|
981
|
+
validateExpression(node.condition);
|
|
982
|
+
const safeExpr = toSafeStateExpr(node.condition);
|
|
983
|
+
const fn = new Function("state", `try { return ${safeExpr}; } catch { return false; }`);
|
|
984
|
+
const shouldRun = fn(state);
|
|
985
|
+
if (!shouldRun) {
|
|
986
|
+
console.log(`[WF][${node.id}] condition false, skipping "${node.name}" (${node.condition})`);
|
|
987
|
+
if (trackingStore && runId) {
|
|
988
|
+
const step = await trackingStore.upsertRunStep({
|
|
989
|
+
runId,
|
|
990
|
+
tenantId,
|
|
991
|
+
stepType: node.type,
|
|
992
|
+
stepName: node.name
|
|
993
|
+
}).catch(() => null);
|
|
994
|
+
if (step) {
|
|
995
|
+
await trackingStore.updateRunStep(runId, step.id, {
|
|
996
|
+
status: "skipped",
|
|
997
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
998
|
+
}).catch(() => {
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
return { phase: node.id };
|
|
1003
|
+
}
|
|
1004
|
+
} catch (condErr) {
|
|
1005
|
+
console.error(`[WF][${node.id}] condition eval error: ${condErr.message}`);
|
|
1006
|
+
throw condErr;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
677
1009
|
const startedAt = Date.now();
|
|
678
1010
|
let stepId;
|
|
679
1011
|
if (trackingStore && runId) {
|
|
@@ -687,7 +1019,8 @@ function createAgentNode(node, resolveAgent, trackingStore) {
|
|
|
687
1019
|
console.log(`[WF][${node.id}] START "${node.name}" | hasSchema=${!!node.output?.schema}`);
|
|
688
1020
|
const responseFormat = node.output?.schema;
|
|
689
1021
|
console.log(`[WF][${node.id}] resolving agent...`);
|
|
690
|
-
const
|
|
1022
|
+
const stepType = node.ask ? "ask" : node.type;
|
|
1023
|
+
const client = await resolveAgent(node.ref, responseFormat, stepType);
|
|
691
1024
|
console.log(`[WF][${node.id}] agent resolved, building input...`);
|
|
692
1025
|
const input = buildInput(
|
|
693
1026
|
node.input,
|
|
@@ -695,16 +1028,32 @@ function createAgentNode(node, resolveAgent, trackingStore) {
|
|
|
695
1028
|
void 0,
|
|
696
1029
|
responseFormat ? void 0 : node.output?.schema
|
|
697
1030
|
);
|
|
1031
|
+
if (node.ask) {
|
|
1032
|
+
input.messages = [
|
|
1033
|
+
new import_messages5.SystemMessage(
|
|
1034
|
+
"Follow this exact procedure. Do NOT skip any step.\n\nSTEP 1: Read the prompt. It contains content to present to the user and a question to ask.\n\nSTEP 2: Call ask_user_to_clarify. Your question text MUST contain the ACTUAL content from the prompt.\n\nSTEP 3: The tool will pause. The user will see your questions and respond. You will receive their answers.\n\nSTEP 4: Based on the user's answers, produce your final output."
|
|
1035
|
+
),
|
|
1036
|
+
...input.messages
|
|
1037
|
+
];
|
|
1038
|
+
}
|
|
698
1039
|
const renderedInput = input.messages[0]?.content ?? "";
|
|
699
1040
|
console.log(`[WF][${node.id}] === INPUT (full) ===
|
|
700
1041
|
${renderedInput}
|
|
701
1042
|
=== END INPUT ===`);
|
|
1043
|
+
const subConfig = {
|
|
1044
|
+
...config,
|
|
1045
|
+
configurable: {
|
|
1046
|
+
...config?.configurable ?? {},
|
|
1047
|
+
thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}`
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
702
1050
|
if (trackingStore && runId) {
|
|
703
1051
|
const step = await trackingStore.upsertRunStep({
|
|
704
1052
|
runId,
|
|
705
1053
|
tenantId,
|
|
706
1054
|
stepType: node.type,
|
|
707
1055
|
stepName: node.name,
|
|
1056
|
+
threadId: subConfig.configurable.thread_id,
|
|
708
1057
|
input: { template: node.input?.template, rendered: renderedInput }
|
|
709
1058
|
}).catch((e) => {
|
|
710
1059
|
console.warn("Failed to upsert run step:", e.message);
|
|
@@ -716,13 +1065,6 @@ ${renderedInput}
|
|
|
716
1065
|
});
|
|
717
1066
|
}
|
|
718
1067
|
}
|
|
719
|
-
const subConfig = {
|
|
720
|
-
...config,
|
|
721
|
-
configurable: {
|
|
722
|
-
...config?.configurable ?? {},
|
|
723
|
-
thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}`
|
|
724
|
-
}
|
|
725
|
-
};
|
|
726
1068
|
let result;
|
|
727
1069
|
try {
|
|
728
1070
|
console.log(`[WF][${node.id}] invoking agent.invoke()...`);
|
|
@@ -819,157 +1161,40 @@ ${JSON.stringify(output, null, 2)}
|
|
|
819
1161
|
}
|
|
820
1162
|
};
|
|
821
1163
|
}
|
|
822
|
-
function
|
|
1164
|
+
function createMapNode(node, resolveAgent, trackingStore) {
|
|
823
1165
|
return async (state, config) => {
|
|
824
1166
|
const runId = state._runId;
|
|
825
1167
|
const tenantId = config?.configurable?.tenantId ?? "default";
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
STEP 1: Read the prompt. It contains content to present to the user and a question to ask.
|
|
852
|
-
|
|
853
|
-
STEP 2: Call ask_user_to_clarify. Your question text MUST contain the ACTUAL content from the prompt \u2014 copy-paste the relevant text, data, or facts directly into the question. A question like "Do you approve this recommendation?" is WRONG because the user has no idea what the recommendation says. Instead: "Do you approve this recommendation: [paste the actual recommendation text here]?"
|
|
854
|
-
|
|
855
|
-
STEP 3: The tool will pause. The user will see your questions and respond. You will receive their answers.
|
|
856
|
-
|
|
857
|
-
STEP 4: Based on the user's answers, produce your final output.`
|
|
858
|
-
),
|
|
859
|
-
...input.messages
|
|
860
|
-
];
|
|
861
|
-
const renderedInput = humanContent;
|
|
862
|
-
if (trackingStore && runId) {
|
|
863
|
-
const step = await trackingStore.upsertRunStep({
|
|
864
|
-
runId,
|
|
865
|
-
tenantId,
|
|
866
|
-
stepType: node.type,
|
|
867
|
-
stepName: node.name,
|
|
868
|
-
input: { template: node.input?.template, rendered: renderedInput }
|
|
869
|
-
}).catch((e) => {
|
|
870
|
-
console.warn("Failed to upsert run step:", e.message);
|
|
871
|
-
return null;
|
|
872
|
-
});
|
|
873
|
-
stepId = step?.id;
|
|
874
|
-
if (step && step.status === "interrupted") {
|
|
875
|
-
trackingStore.updateRunStep(runId, step.id, { status: "running" }).catch(() => {
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
const subConfig = {
|
|
880
|
-
...config,
|
|
881
|
-
configurable: {
|
|
882
|
-
...config?.configurable ?? {},
|
|
883
|
-
thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}`
|
|
884
|
-
}
|
|
885
|
-
};
|
|
886
|
-
console.log(`[WF][${node.id}] === INPUT (full) ===
|
|
887
|
-
${renderedInput}
|
|
888
|
-
=== END INPUT ===`);
|
|
889
|
-
const result = await invokeWithRetry(
|
|
890
|
-
() => client.invoke(input, subConfig),
|
|
891
|
-
node.config?.maxRetries ?? 0,
|
|
892
|
-
node.config?.retryOn,
|
|
893
|
-
node.config?.timeout
|
|
894
|
-
);
|
|
895
|
-
console.log(`[WF][${node.id}] invoke SUCCESS, extracting output...`);
|
|
896
|
-
const output = extractOutput(result);
|
|
897
|
-
console.log(`[WF][${node.id}] === OUTPUT (full) | key=${node.output?.key} ===
|
|
898
|
-
${JSON.stringify(output, null, 2)}
|
|
899
|
-
=== END OUTPUT ===`);
|
|
900
|
-
const update = { phase: node.id };
|
|
901
|
-
if (node.output?.key) {
|
|
902
|
-
update[node.output.key] = output;
|
|
903
|
-
}
|
|
904
|
-
if (output && typeof output === "object" && !Array.isArray(output)) {
|
|
905
|
-
Object.assign(update, output);
|
|
906
|
-
}
|
|
907
|
-
const subMessages = result.messages;
|
|
908
|
-
if (subMessages && Array.isArray(subMessages)) {
|
|
909
|
-
const aiMessages = subMessages.filter((m) => {
|
|
910
|
-
const t = typeof m._getType === "function" ? m._getType() : m.role ?? m.type;
|
|
911
|
-
return t === "ai";
|
|
912
|
-
});
|
|
913
|
-
if (aiMessages.length > 0) {
|
|
914
|
-
update.messages = aiMessages;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
console.log(`[WF][${node.id}] DONE (${Date.now() - startedAt}ms)`);
|
|
918
|
-
if (trackingStore && runId && stepId) {
|
|
919
|
-
trackingStore.updateRunStep(runId, stepId, {
|
|
920
|
-
status: "completed",
|
|
921
|
-
output,
|
|
922
|
-
completedAt: /* @__PURE__ */ new Date(),
|
|
923
|
-
durationMs: Date.now() - startedAt
|
|
924
|
-
}).catch((e) => {
|
|
925
|
-
console.warn("Failed to update run step:", e.message);
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
return update;
|
|
929
|
-
} catch (err) {
|
|
930
|
-
if (err?.name === "GraphInterrupt") {
|
|
931
|
-
if (trackingStore && runId && stepId) {
|
|
932
|
-
trackingStore.updateRunStep(runId, stepId, {
|
|
933
|
-
status: "interrupted"
|
|
934
|
-
}).catch(() => {
|
|
935
|
-
});
|
|
936
|
-
}
|
|
937
|
-
if (trackingStore && runId) {
|
|
938
|
-
trackingStore.updateWorkflowRun(runId, {
|
|
939
|
-
status: "interrupted",
|
|
940
|
-
completedAt: null
|
|
941
|
-
}).catch(() => {
|
|
942
|
-
});
|
|
1168
|
+
if (node.condition) {
|
|
1169
|
+
try {
|
|
1170
|
+
validateExpression(node.condition);
|
|
1171
|
+
const safeExpr = toSafeStateExpr(node.condition);
|
|
1172
|
+
const fn = new Function("state", `try { return ${safeExpr}; } catch { return false; }`);
|
|
1173
|
+
const shouldRun = fn(state);
|
|
1174
|
+
if (!shouldRun) {
|
|
1175
|
+
console.log(`[WF][${node.id}] condition false, skipping map "${node.name}" (${node.condition})`);
|
|
1176
|
+
if (trackingStore && runId) {
|
|
1177
|
+
const step = await trackingStore.upsertRunStep({
|
|
1178
|
+
runId,
|
|
1179
|
+
tenantId,
|
|
1180
|
+
stepType: node.type,
|
|
1181
|
+
stepName: node.name
|
|
1182
|
+
}).catch(() => null);
|
|
1183
|
+
if (step) {
|
|
1184
|
+
await trackingStore.updateRunStep(runId, step.id, {
|
|
1185
|
+
status: "skipped",
|
|
1186
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
1187
|
+
}).catch(() => {
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
return { phase: node.id };
|
|
943
1192
|
}
|
|
944
|
-
|
|
1193
|
+
} catch (condErr) {
|
|
1194
|
+
console.error(`[WF][${node.id}] condition eval error: ${condErr.message}`);
|
|
1195
|
+
throw condErr;
|
|
945
1196
|
}
|
|
946
|
-
if (trackingStore && runId) {
|
|
947
|
-
if (stepId) {
|
|
948
|
-
trackingStore.updateRunStep(runId, stepId, {
|
|
949
|
-
status: "failed",
|
|
950
|
-
errorMessage: err.message,
|
|
951
|
-
completedAt: /* @__PURE__ */ new Date(),
|
|
952
|
-
durationMs: Date.now() - startedAt
|
|
953
|
-
}).catch((e) => {
|
|
954
|
-
console.warn("Failed to update run step:", e.message);
|
|
955
|
-
});
|
|
956
|
-
}
|
|
957
|
-
trackingStore.updateWorkflowRun(runId, {
|
|
958
|
-
status: "failed",
|
|
959
|
-
errorMessage: err.message,
|
|
960
|
-
completedAt: /* @__PURE__ */ new Date()
|
|
961
|
-
}).catch((e) => {
|
|
962
|
-
console.warn("Failed to finalize WorkflowRun:", e.message);
|
|
963
|
-
});
|
|
964
|
-
}
|
|
965
|
-
throw err;
|
|
966
1197
|
}
|
|
967
|
-
};
|
|
968
|
-
}
|
|
969
|
-
function createMapNode(node, resolveAgent, trackingStore) {
|
|
970
|
-
return async (state, config) => {
|
|
971
|
-
const runId = state._runId;
|
|
972
|
-
const tenantId = config?.configurable?.tenantId ?? "default";
|
|
973
1198
|
const startedAt = Date.now();
|
|
974
1199
|
let stepId;
|
|
975
1200
|
if (trackingStore && runId) {
|
|
@@ -1156,368 +1381,77 @@ function createTerminalNode(node, trackingStore) {
|
|
|
1156
1381
|
try {
|
|
1157
1382
|
await trackingStore.updateWorkflowRun(runId, {
|
|
1158
1383
|
status: runStatus,
|
|
1159
|
-
completedAt: /* @__PURE__ */ new Date()
|
|
1160
|
-
});
|
|
1161
|
-
} catch (e) {
|
|
1162
|
-
console.warn(`[WF][terminal] Failed to finalize WorkflowRun "${runId}":`, e.message);
|
|
1163
|
-
}
|
|
1164
|
-
try {
|
|
1165
|
-
await trackingStore.createRunStep({
|
|
1166
|
-
runId,
|
|
1167
|
-
tenantId: state._tenantId ?? "default",
|
|
1168
|
-
stepType: "terminal",
|
|
1169
|
-
stepName: node.name,
|
|
1170
|
-
input: { status: node.status }
|
|
1171
|
-
});
|
|
1172
|
-
} catch (e) {
|
|
1173
|
-
console.warn(`[WF][terminal] Failed to create terminal RunStep:`, e.message);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
return {
|
|
1177
|
-
status: node.status,
|
|
1178
|
-
phase: node.id
|
|
1179
|
-
};
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
function createNodeHandler(node, resolveAgent, trackingStore) {
|
|
1183
|
-
switch (node.type) {
|
|
1184
|
-
case "agent":
|
|
1185
|
-
return createAgentNode(node, resolveAgent, trackingStore);
|
|
1186
|
-
case "human_feedback":
|
|
1187
|
-
return createHumanFeedbackNode(node, resolveAgent, trackingStore);
|
|
1188
|
-
case "map":
|
|
1189
|
-
return createMapNode(node, resolveAgent, trackingStore);
|
|
1190
|
-
case "terminal":
|
|
1191
|
-
return createTerminalNode(node, trackingStore);
|
|
1192
|
-
case "input":
|
|
1193
|
-
return createInputNode(node, trackingStore);
|
|
1194
|
-
default:
|
|
1195
|
-
throw new Error(`Unknown node type: ${node.type}`);
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
function chunk(arr, size) {
|
|
1199
|
-
const result = [];
|
|
1200
|
-
for (let i = 0; i < arr.length; i += size) {
|
|
1201
|
-
result.push(arr.slice(i, i + size));
|
|
1202
|
-
}
|
|
1203
|
-
return result;
|
|
1204
|
-
}
|
|
1205
|
-
var import_langgraph15, import_messages6;
|
|
1206
|
-
var init_utils = __esm({
|
|
1207
|
-
"src/workflow/utils.ts"() {
|
|
1208
|
-
"use strict";
|
|
1209
|
-
import_langgraph15 = require("@langchain/langgraph");
|
|
1210
|
-
import_messages6 = require("@langchain/core/messages");
|
|
1211
|
-
}
|
|
1212
|
-
});
|
|
1213
|
-
|
|
1214
|
-
// src/workflow/normalize.ts
|
|
1215
|
-
function uid(prefix) {
|
|
1216
|
-
return `${prefix}_${_counter++}`;
|
|
1217
|
-
}
|
|
1218
|
-
function nodeId(stepId) {
|
|
1219
|
-
return `n_${stepId}`;
|
|
1220
|
-
}
|
|
1221
|
-
function translate(template) {
|
|
1222
|
-
return template.replace(/\{\{([^}]+)\}\}/g, (_m, expr) => {
|
|
1223
|
-
const t = expr.trim();
|
|
1224
|
-
if (t === "item") return "${item}";
|
|
1225
|
-
return `\${state.${t}}`;
|
|
1226
|
-
});
|
|
1227
|
-
}
|
|
1228
|
-
function inferFieldType(id) {
|
|
1229
|
-
if (/s$|list|array|items|results/i.test(id)) return { type: "array", default: [] };
|
|
1230
|
-
return { type: "string" };
|
|
1231
|
-
}
|
|
1232
|
-
function expandStep(step) {
|
|
1233
|
-
switch (step.type ?? "agent") {
|
|
1234
|
-
case "agent":
|
|
1235
|
-
return expandAgent(step);
|
|
1236
|
-
case "human":
|
|
1237
|
-
return expandHuman(step);
|
|
1238
|
-
case "condition":
|
|
1239
|
-
return expandCondition(step);
|
|
1240
|
-
case "map":
|
|
1241
|
-
return expandMap(step);
|
|
1242
|
-
case "parallel":
|
|
1243
|
-
return expandParallel(step);
|
|
1244
|
-
case "end":
|
|
1245
|
-
return expandEnd(step);
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
function validateSchema(schema, stepId) {
|
|
1249
|
-
if (schema.type !== "object") {
|
|
1250
|
-
throw new Error(
|
|
1251
|
-
`Step "${stepId}": schema.type must be "object", got "${String(schema.type)}". Use standard JSON Schema: { "type": "object", "properties": { ... } }`
|
|
1252
|
-
);
|
|
1253
|
-
}
|
|
1254
|
-
if (!schema.properties || typeof schema.properties !== "object") {
|
|
1255
|
-
throw new Error(
|
|
1256
|
-
`Step "${stepId}": schema must have a "properties" object. Legacy shorthand like { "field": "string" } is not supported. Use: { "type": "object", "properties": { "field": { "type": "string" } } }`
|
|
1257
|
-
);
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
function expandAgent(s) {
|
|
1261
|
-
const sid = s.id || uid("agent");
|
|
1262
|
-
const nid = nodeId(sid);
|
|
1263
|
-
if (s.schema !== void 0 && s.schema !== null) {
|
|
1264
|
-
if (typeof s.schema !== "object") {
|
|
1265
|
-
throw new Error(
|
|
1266
|
-
`Step "${sid}": schema must be a JSON Schema object, e.g. { "type": "object", "properties": { ... } }. Got ${typeof s.schema} (${JSON.stringify(s.schema)}).`
|
|
1267
|
-
);
|
|
1268
|
-
}
|
|
1269
|
-
validateSchema(s.schema, sid);
|
|
1270
|
-
}
|
|
1271
|
-
const schema = s.schema && typeof s.schema === "object" ? s.schema : void 0;
|
|
1272
|
-
console.log(`[WF EXPAND] agent step id="${sid}" nodeId="${nid}" | hasSchema=${!!schema}`);
|
|
1273
|
-
return {
|
|
1274
|
-
nodes: [{ id: nid, type: "agent", name: sid, input: { template: translate(s.prompt) }, output: { key: sid, ...schema ? { schema } : {} } }],
|
|
1275
|
-
edges: [],
|
|
1276
|
-
entryId: nid,
|
|
1277
|
-
exitIds: [nid]
|
|
1278
|
-
};
|
|
1279
|
-
}
|
|
1280
|
-
function expandHuman(s) {
|
|
1281
|
-
const sid = s.id || uid("human");
|
|
1282
|
-
const nid = nodeId(sid);
|
|
1283
|
-
if (s.schema !== void 0 && s.schema !== null) {
|
|
1284
|
-
if (typeof s.schema !== "object") {
|
|
1285
|
-
throw new Error(
|
|
1286
|
-
`Step "${sid}": schema must be a JSON Schema object, e.g. { "type": "object", "properties": { ... } }. Got ${typeof s.schema} (${JSON.stringify(s.schema)}).`
|
|
1287
|
-
);
|
|
1288
|
-
}
|
|
1289
|
-
validateSchema(s.schema, sid);
|
|
1290
|
-
}
|
|
1291
|
-
const schema = s.schema && typeof s.schema === "object" ? s.schema : void 0;
|
|
1292
|
-
return {
|
|
1293
|
-
nodes: [{ id: nid, type: "human_feedback", name: sid, config: { title: s.title ?? sid }, input: { template: translate(s.prompt) }, output: { key: sid, ...schema ? { schema } : {} } }],
|
|
1294
|
-
edges: [],
|
|
1295
|
-
entryId: nid,
|
|
1296
|
-
exitIds: [nid]
|
|
1297
|
-
};
|
|
1298
|
-
}
|
|
1299
|
-
function expandCondition(s) {
|
|
1300
|
-
const sid = s.id || uid("cond");
|
|
1301
|
-
const nid = nodeId(sid);
|
|
1302
|
-
if (s.branches) {
|
|
1303
|
-
const branchExps = {};
|
|
1304
|
-
for (const [key, steps] of Object.entries(s.branches)) {
|
|
1305
|
-
branchExps[key] = expandSteps(Array.isArray(steps) ? steps : [steps]);
|
|
1306
|
-
}
|
|
1307
|
-
const allNodes = Object.values(branchExps).flatMap((e) => e.nodes);
|
|
1308
|
-
const allEdges = Object.values(branchExps).flatMap((e) => e.edges);
|
|
1309
|
-
const allExitIds = [...new Set(Object.values(branchExps).flatMap((e) => e.exitIds))];
|
|
1310
|
-
const branchEntryIds = Object.fromEntries(
|
|
1311
|
-
Object.entries(branchExps).map(([k, v]) => [k, v.entryId])
|
|
1312
|
-
);
|
|
1313
|
-
return {
|
|
1314
|
-
nodes: allNodes,
|
|
1315
|
-
edges: allEdges,
|
|
1316
|
-
entryId: nid,
|
|
1317
|
-
exitIds: allExitIds,
|
|
1318
|
-
branchEntryIds
|
|
1319
|
-
};
|
|
1320
|
-
}
|
|
1321
|
-
if (!s.then) {
|
|
1322
|
-
throw new Error(`Condition step "${sid}": must have either "then" or "branches"`);
|
|
1323
|
-
}
|
|
1324
|
-
const thenSteps = Array.isArray(s.then) ? s.then : [s.then];
|
|
1325
|
-
const elseSteps = s.else ? Array.isArray(s.else) ? s.else : [s.else] : [];
|
|
1326
|
-
const thenExp = expandSteps(thenSteps);
|
|
1327
|
-
const elseExp = expandSteps(elseSteps);
|
|
1328
|
-
return {
|
|
1329
|
-
nodes: [...thenExp.nodes, ...elseExp.nodes],
|
|
1330
|
-
edges: [...thenExp.edges, ...elseExp.edges],
|
|
1331
|
-
entryId: nid,
|
|
1332
|
-
exitIds: [...thenExp.exitIds, ...elseExp.exitIds],
|
|
1333
|
-
thenEntryId: thenExp.entryId,
|
|
1334
|
-
elseEntryId: elseExp.entryId
|
|
1335
|
-
};
|
|
1336
|
-
}
|
|
1337
|
-
function expandMap(s) {
|
|
1338
|
-
const sid = s.id;
|
|
1339
|
-
const nid = nodeId(sid);
|
|
1340
|
-
const inner = s.each;
|
|
1341
|
-
return {
|
|
1342
|
-
nodes: [{
|
|
1343
|
-
id: nid,
|
|
1344
|
-
type: "map",
|
|
1345
|
-
name: sid,
|
|
1346
|
-
source: `state.${s.source}`,
|
|
1347
|
-
itemKey: "item",
|
|
1348
|
-
config: { batchSize: s.batch ?? 50, maxConcurrency: s.concurrency ?? 5, innerConcurrency: s.concurrency ?? 5 },
|
|
1349
|
-
node: { type: "agent", input: inner.prompt ? { template: translate(inner.prompt) } : void 0, ...inner.schema && typeof inner.schema === "object" ? { schema: inner.schema } : {} },
|
|
1350
|
-
...s.reduce ? { reduce: { input: s.reduce.prompt ? { template: translate(s.reduce.prompt) } : void 0, ...s.reduce.schema && typeof s.reduce.schema === "object" ? { schema: s.reduce.schema } : {} } } : {},
|
|
1351
|
-
output: { key: sid }
|
|
1352
|
-
}],
|
|
1353
|
-
edges: [],
|
|
1354
|
-
entryId: nid,
|
|
1355
|
-
exitIds: [nid]
|
|
1356
|
-
};
|
|
1357
|
-
}
|
|
1358
|
-
function expandParallel(s) {
|
|
1359
|
-
const nodes = [];
|
|
1360
|
-
const edges = [];
|
|
1361
|
-
const entryIds = [];
|
|
1362
|
-
const exitIds = [];
|
|
1363
|
-
for (const step of s.steps) {
|
|
1364
|
-
const exp = expandStep(step);
|
|
1365
|
-
nodes.push(...exp.nodes);
|
|
1366
|
-
edges.push(...exp.edges);
|
|
1367
|
-
entryIds.push(exp.entryId);
|
|
1368
|
-
if (exp.exitIds.length > 0) exitIds.push(...exp.exitIds);
|
|
1369
|
-
}
|
|
1370
|
-
return { nodes, edges, entryId: entryIds[0], exitIds };
|
|
1371
|
-
}
|
|
1372
|
-
function expandEnd(s) {
|
|
1373
|
-
const sid = uid("end");
|
|
1374
|
-
const nid = nodeId(sid);
|
|
1375
|
-
return { nodes: [{ id: nid, type: "terminal", name: sid, status: s.status ?? "success" }], edges: [], entryId: nid, exitIds: [] };
|
|
1376
|
-
}
|
|
1377
|
-
function expandSteps(steps, fromStart = false) {
|
|
1378
|
-
if (steps.length === 0) return { nodes: [], edges: [], entryId: "END", exitIds: ["END"] };
|
|
1379
|
-
const allNodes = [];
|
|
1380
|
-
const allEdges = [];
|
|
1381
|
-
let prevExitIds = [];
|
|
1382
|
-
let firstEntryId = null;
|
|
1383
|
-
for (let i = 0; i < steps.length; i++) {
|
|
1384
|
-
const exp = expandStep(steps[i]);
|
|
1385
|
-
if (exp.nodes.length > 0) allNodes.push(...exp.nodes);
|
|
1386
|
-
if (exp.edges.length > 0) allEdges.push(...exp.edges);
|
|
1387
|
-
if (firstEntryId === null) firstEntryId = exp.entryId;
|
|
1388
|
-
if (prevExitIds.length > 0) addEdge(steps[i], exp, prevExitIds, allEdges);
|
|
1389
|
-
else if (fromStart && i === 0) addEdge(steps[i], exp, ["START"], allEdges);
|
|
1390
|
-
prevExitIds = exp.exitIds.length > 0 ? exp.exitIds : prevExitIds;
|
|
1391
|
-
}
|
|
1392
|
-
return { nodes: allNodes, edges: allEdges, entryId: firstEntryId || "END", exitIds: prevExitIds };
|
|
1393
|
-
}
|
|
1394
|
-
function toSafeStateExpr(expr) {
|
|
1395
|
-
const match = expr.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)/);
|
|
1396
|
-
if (!match) return `state.${expr}`;
|
|
1397
|
-
const field = match[0];
|
|
1398
|
-
const rest = expr.slice(field.length);
|
|
1399
|
-
return `state["${field}"]${rest}`;
|
|
1400
|
-
}
|
|
1401
|
-
function addEdge(step, exp, fromIds, allEdges) {
|
|
1402
|
-
if (step.type === "condition") {
|
|
1403
|
-
const s = step;
|
|
1404
|
-
if (s.if.includes("{{")) {
|
|
1405
|
-
throw new Error(
|
|
1406
|
-
`Condition step "${s.id || "unnamed"}": the \`if\` field contains "{{". Use a plain state field name or JavaScript expression (e.g. "intent", "score >= 60"). Template markers {{...}} are only for \`prompt\` fields, not \`if\`. Found: "${s.if}"`
|
|
1407
|
-
);
|
|
1408
|
-
}
|
|
1409
|
-
if (s.branches) {
|
|
1410
|
-
const condExp = exp;
|
|
1411
|
-
const exprCode = toSafeStateExpr(s.if);
|
|
1412
|
-
const mapping = {};
|
|
1413
|
-
for (const [key, branchId] of Object.entries(condExp.branchEntryIds)) {
|
|
1414
|
-
if (branchId) mapping[key] = branchId;
|
|
1415
|
-
}
|
|
1416
|
-
for (const fromId of fromIds) allEdges.push({ from: fromId, type: "conditional", rule: { type: "expression", code: exprCode, mapping } });
|
|
1417
|
-
} else {
|
|
1418
|
-
const condExp = exp;
|
|
1419
|
-
const exprCode = `${toSafeStateExpr(s.if)} ? 'then' : 'else'`;
|
|
1420
|
-
const mapping = {};
|
|
1421
|
-
if (condExp.thenEntryId) mapping.then = condExp.thenEntryId;
|
|
1422
|
-
if (condExp.elseEntryId) mapping.else = condExp.elseEntryId;
|
|
1423
|
-
for (const fromId of fromIds) allEdges.push({ from: fromId, type: "conditional", rule: { type: "expression", code: exprCode, mapping } });
|
|
1424
|
-
}
|
|
1425
|
-
} else if (step.type === "parallel") {
|
|
1426
|
-
for (const fromId of fromIds) {
|
|
1427
|
-
for (const sub of step.steps) allEdges.push({ from: fromId, to: expandStep(sub).entryId });
|
|
1428
|
-
}
|
|
1429
|
-
} else {
|
|
1430
|
-
for (const fromId of fromIds) allEdges.push({ from: fromId, to: exp.entryId });
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
function collectIds(steps) {
|
|
1434
|
-
const ids = [];
|
|
1435
|
-
function walk(s) {
|
|
1436
|
-
const id = s.type === "condition" ? s.id || uid("cond") : s.type === "parallel" ? s.id || uid("par") : s.type === "end" ? uid("end") : s.id || s.id || uid("human");
|
|
1437
|
-
if (s.type !== "end" && s.type !== "condition") ids.push(id);
|
|
1438
|
-
if (s.type === "condition") {
|
|
1439
|
-
const c = s;
|
|
1440
|
-
if (c.branches) {
|
|
1441
|
-
for (const steps2 of Object.values(c.branches)) {
|
|
1442
|
-
(Array.isArray(steps2) ? steps2 : [steps2]).forEach(walk);
|
|
1443
|
-
}
|
|
1444
|
-
} else {
|
|
1445
|
-
(Array.isArray(c.then) ? c.then : [c.then]).forEach(walk);
|
|
1446
|
-
if (c.else) (Array.isArray(c.else) ? c.else : [c.else]).forEach(walk);
|
|
1384
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
1385
|
+
});
|
|
1386
|
+
} catch (e) {
|
|
1387
|
+
console.warn(`[WF][terminal] Failed to finalize WorkflowRun "${runId}":`, e.message);
|
|
1447
1388
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
if (s.type === "condition") {
|
|
1459
|
-
const c = s;
|
|
1460
|
-
if (c.branches) {
|
|
1461
|
-
for (const steps2 of Object.values(c.branches)) {
|
|
1462
|
-
(Array.isArray(steps2) ? steps2 : [steps2]).forEach(walk);
|
|
1463
|
-
}
|
|
1464
|
-
} else {
|
|
1465
|
-
(Array.isArray(c.then) ? c.then : [c.then]).forEach(walk);
|
|
1466
|
-
if (c.else) (Array.isArray(c.else) ? c.else : [c.else]).forEach(walk);
|
|
1389
|
+
try {
|
|
1390
|
+
await trackingStore.createRunStep({
|
|
1391
|
+
runId,
|
|
1392
|
+
tenantId: state._tenantId ?? "default",
|
|
1393
|
+
stepType: "terminal",
|
|
1394
|
+
stepName: node.name,
|
|
1395
|
+
input: { status: node.status }
|
|
1396
|
+
});
|
|
1397
|
+
} catch (e) {
|
|
1398
|
+
console.warn(`[WF][terminal] Failed to create terminal RunStep:`, e.message);
|
|
1467
1399
|
}
|
|
1468
1400
|
}
|
|
1469
|
-
|
|
1401
|
+
return {
|
|
1402
|
+
status: node.status,
|
|
1403
|
+
phase: node.id
|
|
1404
|
+
};
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
function createNodeHandler(node, resolveAgent, trackingStore) {
|
|
1408
|
+
switch (node.type) {
|
|
1409
|
+
case "agent":
|
|
1410
|
+
return createAgentNode(node, resolveAgent, trackingStore);
|
|
1411
|
+
case "map":
|
|
1412
|
+
return createMapNode(node, resolveAgent, trackingStore);
|
|
1413
|
+
case "terminal":
|
|
1414
|
+
return createTerminalNode(node, trackingStore);
|
|
1415
|
+
case "input":
|
|
1416
|
+
return createInputNode(node, trackingStore);
|
|
1417
|
+
default:
|
|
1418
|
+
throw new Error(`Unknown node type: ${node.type}`);
|
|
1470
1419
|
}
|
|
1471
|
-
steps.forEach(walk);
|
|
1472
|
-
return [...new Set(ids)];
|
|
1473
1420
|
}
|
|
1474
|
-
function
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
id: "n_input",
|
|
1479
|
-
type: "input",
|
|
1480
|
-
name: "input",
|
|
1481
|
-
output: { key: "input" }
|
|
1482
|
-
};
|
|
1483
|
-
const expanded = expandSteps(dsl.steps, true);
|
|
1484
|
-
const edges = expanded.entryId === "END" ? [{ from: "START", to: "n_input" }] : [
|
|
1485
|
-
...expanded.edges.map((e) => ({ ...e, from: e.from === "START" ? "n_input" : e.from })),
|
|
1486
|
-
{ from: "START", to: "n_input" }
|
|
1487
|
-
];
|
|
1488
|
-
const nodes = [inputNode, ...expanded.nodes];
|
|
1489
|
-
const ids = collectIds(dsl.steps);
|
|
1490
|
-
const sourceIds = collectSourceIds(dsl.steps);
|
|
1491
|
-
const fields = { input: { type: "string" } };
|
|
1492
|
-
for (const id of ids) fields[id] = inferFieldType(id);
|
|
1493
|
-
for (const id of sourceIds) {
|
|
1494
|
-
if (!fields[id]) fields[id] = inferFieldType(id);
|
|
1421
|
+
function chunk(arr, size) {
|
|
1422
|
+
const result = [];
|
|
1423
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
1424
|
+
result.push(arr.slice(i, i + size));
|
|
1495
1425
|
}
|
|
1496
|
-
const result = { version: "1.0", name: dsl.name, state: { fields }, nodes, edges };
|
|
1497
|
-
console.log(`[WF EXPAND] done | nodeCount=${result.nodes.length} | nodeIds=[${result.nodes.map((n) => `${n.id}:${n.type}`).join(", ")}] | fieldIds=[${Object.keys(fields).join(", ")}]`);
|
|
1498
1426
|
return result;
|
|
1499
1427
|
}
|
|
1500
|
-
var
|
|
1501
|
-
var
|
|
1502
|
-
"src/workflow/
|
|
1428
|
+
var import_langgraph14, import_messages5;
|
|
1429
|
+
var init_utils = __esm({
|
|
1430
|
+
"src/workflow/utils.ts"() {
|
|
1503
1431
|
"use strict";
|
|
1504
|
-
|
|
1432
|
+
import_langgraph14 = require("@langchain/langgraph");
|
|
1433
|
+
import_messages5 = require("@langchain/core/messages");
|
|
1434
|
+
init_parse_yaml();
|
|
1505
1435
|
}
|
|
1506
1436
|
});
|
|
1507
1437
|
|
|
1508
1438
|
// src/workflow/compile.ts
|
|
1509
1439
|
var compile_exports = {};
|
|
1510
1440
|
__export(compile_exports, {
|
|
1441
|
+
compileInternal: () => compileInternal,
|
|
1511
1442
|
compileWorkflow: () => compileWorkflow,
|
|
1512
1443
|
validateDSL: () => validateDSL
|
|
1513
1444
|
});
|
|
1514
|
-
function compileWorkflow(
|
|
1515
|
-
console.log(`[WF COMPILE] compiling
|
|
1516
|
-
const ir =
|
|
1445
|
+
function compileWorkflow(yamlStr, resolveAgent, checkpointer, trackingStore) {
|
|
1446
|
+
console.log(`[WF COMPILE] compiling YAML workflow`);
|
|
1447
|
+
const ir = parseYaml(yamlStr);
|
|
1448
|
+
return compileInternal(ir, resolveAgent, checkpointer, trackingStore);
|
|
1449
|
+
}
|
|
1450
|
+
function compileInternal(ir, resolveAgent, checkpointer, trackingStore) {
|
|
1517
1451
|
validateAndThrow(ir);
|
|
1518
1452
|
console.log(`[WF COMPILE] validation passed`);
|
|
1519
1453
|
const StateAnnotation = buildStateAnnotation(ir.state?.fields);
|
|
1520
|
-
const builder = new
|
|
1454
|
+
const builder = new import_langgraph15.StateGraph(StateAnnotation);
|
|
1521
1455
|
for (const node of ir.nodes) {
|
|
1522
1456
|
console.log(`[WF COMPILE] registering node: id=${node.id} type=${node.type} name=${node.name}`);
|
|
1523
1457
|
const handler = createNodeHandler(node, resolveAgent, trackingStore);
|
|
@@ -1525,26 +1459,18 @@ function compileWorkflow(dsl, resolveAgent, checkpointer, trackingStore) {
|
|
|
1525
1459
|
}
|
|
1526
1460
|
for (const node of ir.nodes) {
|
|
1527
1461
|
if (node.type === "terminal") {
|
|
1528
|
-
builder.addEdge(node.id,
|
|
1462
|
+
builder.addEdge(node.id, import_langgraph15.END);
|
|
1529
1463
|
}
|
|
1530
1464
|
}
|
|
1531
1465
|
for (const edge of ir.edges) {
|
|
1532
|
-
const from = edge.from === "START" ?
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
}
|
|
1537
|
-
const router = buildRouter(edge.rule);
|
|
1538
|
-
builder.addConditionalEdges(from, router, edge.rule.mapping);
|
|
1539
|
-
} else {
|
|
1540
|
-
const targets = Array.isArray(edge.to) ? edge.to : [edge.to];
|
|
1541
|
-
for (const to of targets) {
|
|
1542
|
-
builder.addEdge(from, to === "END" ? import_langgraph16.END : to);
|
|
1543
|
-
}
|
|
1466
|
+
const from = edge.from === "START" ? import_langgraph15.START : edge.from;
|
|
1467
|
+
const targets = Array.isArray(edge.to) ? edge.to : [edge.to];
|
|
1468
|
+
for (const to of targets) {
|
|
1469
|
+
builder.addEdge(from, to === "END" ? import_langgraph15.END : to);
|
|
1544
1470
|
}
|
|
1545
1471
|
}
|
|
1546
1472
|
const graph = builder.compile({ checkpointer, name: ir.name });
|
|
1547
|
-
console.log(`[WF COMPILE] graph compiled successfully
|
|
1473
|
+
console.log(`[WF COMPILE] graph compiled successfully`);
|
|
1548
1474
|
return graph;
|
|
1549
1475
|
}
|
|
1550
1476
|
function validateDSL(dsl) {
|
|
@@ -1559,7 +1485,6 @@ function validateDSL(dsl) {
|
|
|
1559
1485
|
const terminalIds = new Set(
|
|
1560
1486
|
dsl.nodes.filter((n) => n.type === "terminal").map((n) => n.id)
|
|
1561
1487
|
);
|
|
1562
|
-
const declaredFields = new Set(Object.keys(dsl.state?.fields ?? {}));
|
|
1563
1488
|
for (const edge of dsl.edges) {
|
|
1564
1489
|
if (edge.from !== "START" && !nodeIds.has(edge.from)) {
|
|
1565
1490
|
errors.push({ type: "error", message: `Edge from "${edge.from}" references unknown node` });
|
|
@@ -1573,24 +1498,12 @@ function validateDSL(dsl) {
|
|
|
1573
1498
|
errors.push({ type: "error", message: `Edge to "${to}" references unknown node` });
|
|
1574
1499
|
}
|
|
1575
1500
|
}
|
|
1576
|
-
if (edge.type === "conditional" && edge.rule) {
|
|
1577
|
-
for (const targetId of Object.values(edge.rule.mapping)) {
|
|
1578
|
-
if (targetId !== "END" && !nodeIds.has(targetId)) {
|
|
1579
|
-
errors.push({ type: "error", message: `Conditional edge mapping references unknown node "${targetId}"` });
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
if (edge.rule.type === "state_field" && edge.rule.field) {
|
|
1583
|
-
if (!declaredFields.has(edge.rule.field)) {
|
|
1584
|
-
errors.push({ type: "warning", message: `Conditional edge reads "${edge.rule.field}" but it is not declared in state.fields` });
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
1501
|
}
|
|
1589
1502
|
for (const node of dsl.nodes) {
|
|
1590
1503
|
if (node.type === "terminal") {
|
|
1591
1504
|
const hasIncoming = dsl.edges.some((e) => {
|
|
1592
1505
|
const targets = Array.isArray(e.to) ? e.to : e.to ? [e.to] : [];
|
|
1593
|
-
return targets.includes(node.id)
|
|
1506
|
+
return targets.includes(node.id);
|
|
1594
1507
|
});
|
|
1595
1508
|
if (!hasIncoming) {
|
|
1596
1509
|
errors.push({ type: "warning", message: `Terminal node "${node.id}" has no incoming edge` });
|
|
@@ -1606,41 +1519,13 @@ function validateAndThrow(dsl) {
|
|
|
1606
1519
|
throw new Error(critical.map((e) => e.message).join("; "));
|
|
1607
1520
|
}
|
|
1608
1521
|
}
|
|
1609
|
-
|
|
1610
|
-
if (rule.type === "state_field") {
|
|
1611
|
-
if (!rule.field) throw new Error("state_field rule requires a field name");
|
|
1612
|
-
return (state) => {
|
|
1613
|
-
const value = resolvePath(state, `state.${rule.field}`);
|
|
1614
|
-
const key = String(value);
|
|
1615
|
-
if (rule.mapping[key] !== void 0) return key;
|
|
1616
|
-
if (rule.mapping["default"] !== void 0) return "default";
|
|
1617
|
-
throw new Error(
|
|
1618
|
-
`Conditional router produced key "${key}" (from field "${rule.field}"), but it is not in mapping: ${JSON.stringify(Object.keys(rule.mapping))}`
|
|
1619
|
-
);
|
|
1620
|
-
};
|
|
1621
|
-
}
|
|
1622
|
-
if (rule.type === "expression") {
|
|
1623
|
-
if (!rule.code) throw new Error("expression rule requires code");
|
|
1624
|
-
const fn = new Function("state", `return ${rule.code}`);
|
|
1625
|
-
return (state) => {
|
|
1626
|
-
const value = fn(state);
|
|
1627
|
-
const key = String(value);
|
|
1628
|
-
if (rule.mapping[key] !== void 0) return key;
|
|
1629
|
-
if (rule.mapping["default"] !== void 0) return "default";
|
|
1630
|
-
throw new Error(
|
|
1631
|
-
`Conditional router produced key "${key}" (from expression "${rule.code}"), but it is not in mapping: ${JSON.stringify(Object.keys(rule.mapping))}`
|
|
1632
|
-
);
|
|
1633
|
-
};
|
|
1634
|
-
}
|
|
1635
|
-
throw new Error(`Unknown rule type: ${rule.type}`);
|
|
1636
|
-
}
|
|
1637
|
-
var import_langgraph16;
|
|
1522
|
+
var import_langgraph15;
|
|
1638
1523
|
var init_compile = __esm({
|
|
1639
1524
|
"src/workflow/compile.ts"() {
|
|
1640
1525
|
"use strict";
|
|
1641
|
-
|
|
1526
|
+
import_langgraph15 = require("@langchain/langgraph");
|
|
1642
1527
|
init_utils();
|
|
1643
|
-
|
|
1528
|
+
init_parse_yaml();
|
|
1644
1529
|
}
|
|
1645
1530
|
});
|
|
1646
1531
|
|
|
@@ -1669,7 +1554,7 @@ __export(index_exports, {
|
|
|
1669
1554
|
EmbeddingsLatticeManager: () => EmbeddingsLatticeManager,
|
|
1670
1555
|
FileSystemSkillStore: () => FileSystemSkillStore,
|
|
1671
1556
|
FilesystemBackend: () => FilesystemBackend,
|
|
1672
|
-
HumanMessage: () =>
|
|
1557
|
+
HumanMessage: () => import_messages6.HumanMessage,
|
|
1673
1558
|
InMemoryA2AApiKeyStore: () => InMemoryA2AApiKeyStore,
|
|
1674
1559
|
InMemoryAssistantStore: () => InMemoryAssistantStore,
|
|
1675
1560
|
InMemoryBindingStore: () => InMemoryBindingStore,
|
|
@@ -1677,7 +1562,9 @@ __export(index_exports, {
|
|
|
1677
1562
|
InMemoryChunkBuffer: () => InMemoryChunkBuffer,
|
|
1678
1563
|
InMemoryDatabaseConfigStore: () => InMemoryDatabaseConfigStore,
|
|
1679
1564
|
InMemoryMailboxStore: () => InMemoryMailboxStore,
|
|
1565
|
+
InMemoryMenuStore: () => InMemoryMenuStore,
|
|
1680
1566
|
InMemoryTaskListStore: () => InMemoryTaskListStore,
|
|
1567
|
+
InMemoryTaskStore: () => InMemoryTaskStore,
|
|
1681
1568
|
InMemoryTenantStore: () => InMemoryTenantStore,
|
|
1682
1569
|
InMemoryThreadMessageQueueStore: () => InMemoryThreadMessageQueueStore,
|
|
1683
1570
|
InMemoryThreadStore: () => InMemoryThreadStore,
|
|
@@ -1699,6 +1586,7 @@ __export(index_exports, {
|
|
|
1699
1586
|
MicrosandboxServiceClient: () => MicrosandboxServiceClient,
|
|
1700
1587
|
ModelLatticeManager: () => ModelLatticeManager,
|
|
1701
1588
|
MysqlDatabase: () => MysqlDatabase,
|
|
1589
|
+
PersonalAssistantConfig: () => PersonalAssistantConfig,
|
|
1702
1590
|
PinoLoggerClient: () => PinoLoggerClient,
|
|
1703
1591
|
PostgresDatabase: () => PostgresDatabase,
|
|
1704
1592
|
PrometheusClient: () => PrometheusClient,
|
|
@@ -1735,14 +1623,15 @@ __export(index_exports, {
|
|
|
1735
1623
|
buildStateAnnotation: () => buildStateAnnotation,
|
|
1736
1624
|
checkEmptyContent: () => checkEmptyContent,
|
|
1737
1625
|
clearEncryptionKeyCache: () => clearEncryptionKeyCache,
|
|
1626
|
+
compileInternal: () => compileInternal,
|
|
1738
1627
|
compileWorkflow: () => compileWorkflow,
|
|
1739
1628
|
computeSandboxName: () => computeSandboxName,
|
|
1740
1629
|
configureStores: () => configureStores,
|
|
1630
|
+
connectAllChannels: () => connectAllChannels,
|
|
1741
1631
|
createAgentNode: () => createAgentNode,
|
|
1742
1632
|
createAgentTeam: () => createAgentTeam,
|
|
1743
1633
|
createExecuteSqlQueryTool: () => createExecuteSqlQueryTool,
|
|
1744
1634
|
createFileData: () => createFileData,
|
|
1745
|
-
createHumanFeedbackNode: () => createHumanFeedbackNode,
|
|
1746
1635
|
createInfoSqlTool: () => createInfoSqlTool,
|
|
1747
1636
|
createListMetricsDataSourcesTool: () => createListMetricsDataSourcesTool,
|
|
1748
1637
|
createListMetricsServersTool: () => createListMetricsServersTool,
|
|
@@ -1760,9 +1649,9 @@ __export(index_exports, {
|
|
|
1760
1649
|
createQueryTablesListTool: () => createQueryTablesListTool,
|
|
1761
1650
|
createSandboxProvider: () => createSandboxProvider,
|
|
1762
1651
|
createSchedulerMiddleware: () => createSchedulerMiddleware,
|
|
1652
|
+
createTaskMiddleware: () => createTaskMiddleware,
|
|
1763
1653
|
createTeamMiddleware: () => createTeamMiddleware,
|
|
1764
1654
|
createTeammateTools: () => createTeammateTools,
|
|
1765
|
-
createTerminalNode: () => createTerminalNode,
|
|
1766
1655
|
createUnknownToolHandlerMiddleware: () => createUnknownToolHandlerMiddleware,
|
|
1767
1656
|
createWidgetMiddleware: () => createWidgetMiddleware,
|
|
1768
1657
|
decrypt: () => decrypt,
|
|
@@ -1772,7 +1661,6 @@ __export(index_exports, {
|
|
|
1772
1661
|
ensureBuiltinAgentsForTenant: () => ensureBuiltinAgentsForTenant,
|
|
1773
1662
|
eventBus: () => eventBus,
|
|
1774
1663
|
eventBusDefault: () => event_bus_default,
|
|
1775
|
-
expand: () => expand,
|
|
1776
1664
|
extractFetcherError: () => extractFetcherError,
|
|
1777
1665
|
extractOutput: () => extractOutput,
|
|
1778
1666
|
fileDataToString: () => fileDataToString,
|
|
@@ -1795,6 +1683,7 @@ __export(index_exports, {
|
|
|
1795
1683
|
getEmbeddingsLattice: () => getEmbeddingsLattice,
|
|
1796
1684
|
getEncryptionKey: () => getEncryptionKey,
|
|
1797
1685
|
getLoggerLattice: () => getLoggerLattice,
|
|
1686
|
+
getMenuRegistry: () => getMenuRegistry,
|
|
1798
1687
|
getModelLattice: () => getModelLattice,
|
|
1799
1688
|
getNextCronTime: () => getNextCronTime,
|
|
1800
1689
|
getQueueLattice: () => getQueueLattice,
|
|
@@ -1824,6 +1713,7 @@ __export(index_exports, {
|
|
|
1824
1713
|
parallelLimit: () => parallelLimit,
|
|
1825
1714
|
parseCronExpression: () => parseCronExpression,
|
|
1826
1715
|
parseSkillFrontmatter: () => parseSkillFrontmatter,
|
|
1716
|
+
parseYaml: () => parseYaml,
|
|
1827
1717
|
performStringReplacement: () => performStringReplacement,
|
|
1828
1718
|
queueLatticeManager: () => queueLatticeManager,
|
|
1829
1719
|
registerAgentLattice: () => registerAgentLattice,
|
|
@@ -1847,9 +1737,12 @@ __export(index_exports, {
|
|
|
1847
1737
|
sanitizeToolCallId: () => sanitizeToolCallId,
|
|
1848
1738
|
scheduleLatticeManager: () => scheduleLatticeManager,
|
|
1849
1739
|
setBindingRegistry: () => setBindingRegistry,
|
|
1740
|
+
setMenuRegistry: () => setMenuRegistry,
|
|
1850
1741
|
skillLatticeManager: () => skillLatticeManager,
|
|
1851
1742
|
sqlDatabaseManager: () => sqlDatabaseManager,
|
|
1852
1743
|
storeLatticeManager: () => storeLatticeManager,
|
|
1744
|
+
toJsonSchema: () => toJsonSchema,
|
|
1745
|
+
toSafeStateExpr: () => toSafeStateExpr,
|
|
1853
1746
|
toolLatticeManager: () => toolLatticeManager,
|
|
1854
1747
|
truncateIfTooLong: () => truncateIfTooLong,
|
|
1855
1748
|
unregisterTeammateAgent: () => unregisterTeammateAgent,
|
|
@@ -1986,9 +1879,11 @@ var ModelLattice = class extends import_chat_models.BaseChatModel {
|
|
|
1986
1879
|
maxRetries: config.maxRetries || 2,
|
|
1987
1880
|
apiKey: config.apiKey || process.env[config.apiKeyEnvName || "SILICONCLOUD_API_KEY"],
|
|
1988
1881
|
configuration: {
|
|
1989
|
-
baseURL: "https://api.siliconflow.cn/v1"
|
|
1882
|
+
baseURL: config.baseURL || "https://api.siliconflow.cn/v1"
|
|
1990
1883
|
},
|
|
1991
|
-
streaming: config.streaming
|
|
1884
|
+
streaming: config.streaming,
|
|
1885
|
+
modelKwargs: config.modelKwargs,
|
|
1886
|
+
...config.extra || {}
|
|
1992
1887
|
});
|
|
1993
1888
|
} else if (config.provider === "volcengine") {
|
|
1994
1889
|
return new import_openai.ChatOpenAI({
|
|
@@ -2271,11 +2166,11 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
2271
2166
|
* @param key Lattice键名
|
|
2272
2167
|
* @param tool 已有的StructuredTool实例
|
|
2273
2168
|
*/
|
|
2274
|
-
registerExistingTool(key,
|
|
2169
|
+
registerExistingTool(key, tool52) {
|
|
2275
2170
|
const config = {
|
|
2276
|
-
name:
|
|
2277
|
-
description:
|
|
2278
|
-
schema:
|
|
2171
|
+
name: tool52.name,
|
|
2172
|
+
description: tool52.description,
|
|
2173
|
+
schema: tool52.schema,
|
|
2279
2174
|
// StructuredTool的schema已经是Zod兼容的
|
|
2280
2175
|
needUserApprove: false
|
|
2281
2176
|
// MCP工具默认不需要用户批准
|
|
@@ -2283,7 +2178,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
2283
2178
|
const toolLattice = {
|
|
2284
2179
|
key,
|
|
2285
2180
|
config,
|
|
2286
|
-
client:
|
|
2181
|
+
client: tool52
|
|
2287
2182
|
};
|
|
2288
2183
|
this.register(key, toolLattice);
|
|
2289
2184
|
}
|
|
@@ -2309,7 +2204,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
2309
2204
|
};
|
|
2310
2205
|
var toolLatticeManager = ToolLatticeManager.getInstance();
|
|
2311
2206
|
var registerToolLattice = (key, config, executor) => toolLatticeManager.registerLattice(key, config, executor);
|
|
2312
|
-
var registerExistingTool = (key,
|
|
2207
|
+
var registerExistingTool = (key, tool52) => toolLatticeManager.registerExistingTool(key, tool52);
|
|
2313
2208
|
var getToolLattice = (key) => toolLatticeManager.getToolLattice(key);
|
|
2314
2209
|
var getToolDefinition = (key) => toolLatticeManager.getToolDefinition(key);
|
|
2315
2210
|
var getToolClient = (key) => toolLatticeManager.getToolClient(key);
|
|
@@ -2579,6 +2474,7 @@ var InMemoryAssistantStore = class {
|
|
|
2579
2474
|
name: data.name,
|
|
2580
2475
|
description: data.description,
|
|
2581
2476
|
graphDefinition: data.graphDefinition,
|
|
2477
|
+
ownerUserId: data.ownerUserId,
|
|
2582
2478
|
createdAt: now,
|
|
2583
2479
|
updatedAt: now
|
|
2584
2480
|
};
|
|
@@ -2625,6 +2521,17 @@ var InMemoryAssistantStore = class {
|
|
|
2625
2521
|
}
|
|
2626
2522
|
return tenantAssistants.has(id);
|
|
2627
2523
|
}
|
|
2524
|
+
/**
|
|
2525
|
+
* Get assistant by owner user ID
|
|
2526
|
+
*/
|
|
2527
|
+
async getByOwner(tenantId, userId) {
|
|
2528
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
2529
|
+
if (!tenantAssistants) return null;
|
|
2530
|
+
for (const assistant of tenantAssistants.values()) {
|
|
2531
|
+
if (assistant.ownerUserId === userId) return assistant;
|
|
2532
|
+
}
|
|
2533
|
+
return null;
|
|
2534
|
+
}
|
|
2628
2535
|
/**
|
|
2629
2536
|
* Clear all assistants for a tenant (useful for testing)
|
|
2630
2537
|
*/
|
|
@@ -3857,7 +3764,7 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
3857
3764
|
return this.messages.get(threadId);
|
|
3858
3765
|
}
|
|
3859
3766
|
async addMessage(params) {
|
|
3860
|
-
const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
|
|
3767
|
+
const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
|
|
3861
3768
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
3862
3769
|
const message = {
|
|
3863
3770
|
id: id || this.generateId(),
|
|
@@ -3868,6 +3775,8 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
3868
3775
|
status: "pending",
|
|
3869
3776
|
tenantId,
|
|
3870
3777
|
assistantId,
|
|
3778
|
+
workspaceId,
|
|
3779
|
+
projectId,
|
|
3871
3780
|
priority,
|
|
3872
3781
|
command,
|
|
3873
3782
|
custom_run_config
|
|
@@ -3876,7 +3785,7 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
3876
3785
|
return message;
|
|
3877
3786
|
}
|
|
3878
3787
|
async addMessageAtHead(params) {
|
|
3879
|
-
const { threadId, tenantId, assistantId, content, type = "system", id, command, custom_run_config } = params;
|
|
3788
|
+
const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "system", id, command, custom_run_config } = params;
|
|
3880
3789
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
3881
3790
|
let resolvedTenantId = tenantId || "default";
|
|
3882
3791
|
let resolvedAssistantId = assistantId || "";
|
|
@@ -3894,6 +3803,8 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
3894
3803
|
status: "pending",
|
|
3895
3804
|
tenantId: resolvedTenantId,
|
|
3896
3805
|
assistantId: resolvedAssistantId,
|
|
3806
|
+
workspaceId,
|
|
3807
|
+
projectId,
|
|
3897
3808
|
priority: 100,
|
|
3898
3809
|
// High priority for head messages (STEER/Command)
|
|
3899
3810
|
command,
|
|
@@ -3925,7 +3836,9 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
3925
3836
|
result.push({
|
|
3926
3837
|
tenantId: firstMessage.tenantId || "default",
|
|
3927
3838
|
assistantId: firstMessage.assistantId || "",
|
|
3928
|
-
threadId
|
|
3839
|
+
threadId,
|
|
3840
|
+
workspaceId: firstMessage.workspaceId || void 0,
|
|
3841
|
+
projectId: firstMessage.projectId || void 0
|
|
3929
3842
|
});
|
|
3930
3843
|
}
|
|
3931
3844
|
}
|
|
@@ -4048,6 +3961,7 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
4048
3961
|
tenantId: request.tenantId,
|
|
4049
3962
|
stepType: request.stepType,
|
|
4050
3963
|
stepName: request.stepName,
|
|
3964
|
+
threadId: request.threadId,
|
|
4051
3965
|
edgeFrom: request.edgeFrom,
|
|
4052
3966
|
edgeTo: request.edgeTo,
|
|
4053
3967
|
edgePurpose: request.edgePurpose,
|
|
@@ -4067,7 +3981,12 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
4067
3981
|
const existing = runSteps.find(
|
|
4068
3982
|
(s) => s.stepType === request.stepType && s.stepName === request.stepName
|
|
4069
3983
|
);
|
|
4070
|
-
if (existing)
|
|
3984
|
+
if (existing) {
|
|
3985
|
+
if (!existing.threadId && request.threadId) {
|
|
3986
|
+
existing.threadId = request.threadId;
|
|
3987
|
+
}
|
|
3988
|
+
return existing;
|
|
3989
|
+
}
|
|
4071
3990
|
return this.createRunStep(request);
|
|
4072
3991
|
}
|
|
4073
3992
|
async updateRunStep(runId, stepId, updates) {
|
|
@@ -4126,6 +4045,11 @@ var InMemoryChannelInstallationStore = class {
|
|
|
4126
4045
|
(inst) => inst.tenantId === tenantId && (!channel || inst.channel === channel)
|
|
4127
4046
|
);
|
|
4128
4047
|
}
|
|
4048
|
+
async getAllInstallations(channel) {
|
|
4049
|
+
return Array.from(this.installations.values()).filter(
|
|
4050
|
+
(inst) => !channel || inst.channel === channel
|
|
4051
|
+
);
|
|
4052
|
+
}
|
|
4129
4053
|
/**
|
|
4130
4054
|
* Creates a new channel installation for a tenant.
|
|
4131
4055
|
*
|
|
@@ -4402,6 +4326,107 @@ var InMemoryA2AApiKeyStore = class {
|
|
|
4402
4326
|
}
|
|
4403
4327
|
};
|
|
4404
4328
|
|
|
4329
|
+
// src/store_lattice/InMemoryTaskStore.ts
|
|
4330
|
+
var import_uuid = require("uuid");
|
|
4331
|
+
var InMemoryTaskStore = class {
|
|
4332
|
+
constructor() {
|
|
4333
|
+
this.tasks = /* @__PURE__ */ new Map();
|
|
4334
|
+
}
|
|
4335
|
+
/**
|
|
4336
|
+
* Create a new task
|
|
4337
|
+
*/
|
|
4338
|
+
async create(params) {
|
|
4339
|
+
if (!this.tasks.has(params.tenantId)) {
|
|
4340
|
+
this.tasks.set(params.tenantId, /* @__PURE__ */ new Map());
|
|
4341
|
+
}
|
|
4342
|
+
const now = /* @__PURE__ */ new Date();
|
|
4343
|
+
const task = {
|
|
4344
|
+
id: (0, import_uuid.v4)(),
|
|
4345
|
+
tenantId: params.tenantId,
|
|
4346
|
+
ownerType: params.ownerType,
|
|
4347
|
+
ownerId: params.ownerId,
|
|
4348
|
+
title: params.title,
|
|
4349
|
+
description: params.description,
|
|
4350
|
+
status: params.status || "pending",
|
|
4351
|
+
priority: params.priority || "medium",
|
|
4352
|
+
dueDate: params.dueDate,
|
|
4353
|
+
metadata: params.metadata,
|
|
4354
|
+
parentId: params.parentId,
|
|
4355
|
+
sourceId: params.sourceId,
|
|
4356
|
+
context: params.context,
|
|
4357
|
+
createdAt: now,
|
|
4358
|
+
updatedAt: now
|
|
4359
|
+
};
|
|
4360
|
+
this.tasks.get(params.tenantId).set(task.id, task);
|
|
4361
|
+
return task;
|
|
4362
|
+
}
|
|
4363
|
+
/**
|
|
4364
|
+
* Get task by ID
|
|
4365
|
+
*/
|
|
4366
|
+
async getById(tenantId, id) {
|
|
4367
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
4368
|
+
if (!tenantTasks) return null;
|
|
4369
|
+
return tenantTasks.get(id) || null;
|
|
4370
|
+
}
|
|
4371
|
+
/**
|
|
4372
|
+
* List tasks matching filter criteria
|
|
4373
|
+
*/
|
|
4374
|
+
async list(filter2) {
|
|
4375
|
+
const tenantTasks = this.tasks.get(filter2.tenantId);
|
|
4376
|
+
if (!tenantTasks) return [];
|
|
4377
|
+
let results = Array.from(tenantTasks.values());
|
|
4378
|
+
if (filter2.ownerType) results = results.filter((t) => t.ownerType === filter2.ownerType);
|
|
4379
|
+
if (filter2.ownerId) results = results.filter((t) => t.ownerId === filter2.ownerId);
|
|
4380
|
+
if (filter2.status) results = results.filter((t) => t.status === filter2.status);
|
|
4381
|
+
if (filter2.priority) results = results.filter((t) => t.priority === filter2.priority);
|
|
4382
|
+
if (filter2.parentId) results = results.filter((t) => t.parentId === filter2.parentId);
|
|
4383
|
+
if (filter2.sourceId) results = results.filter((t) => t.sourceId === filter2.sourceId);
|
|
4384
|
+
if (filter2.metadata) {
|
|
4385
|
+
for (const [key, value] of Object.entries(filter2.metadata)) {
|
|
4386
|
+
results = results.filter((t) => t.metadata?.[key] === value);
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
results.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
4390
|
+
const offset = filter2.offset || 0;
|
|
4391
|
+
const limit = filter2.limit || 100;
|
|
4392
|
+
return results.slice(offset, offset + limit);
|
|
4393
|
+
}
|
|
4394
|
+
/**
|
|
4395
|
+
* Update an existing task
|
|
4396
|
+
*/
|
|
4397
|
+
async update(tenantId, id, updates) {
|
|
4398
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
4399
|
+
if (!tenantTasks) return null;
|
|
4400
|
+
const existing = tenantTasks.get(id);
|
|
4401
|
+
if (!existing) return null;
|
|
4402
|
+
const updated = {
|
|
4403
|
+
...existing,
|
|
4404
|
+
...updates,
|
|
4405
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
4406
|
+
};
|
|
4407
|
+
tenantTasks.set(id, updated);
|
|
4408
|
+
return updated;
|
|
4409
|
+
}
|
|
4410
|
+
/**
|
|
4411
|
+
* Delete a task by ID
|
|
4412
|
+
*/
|
|
4413
|
+
async delete(tenantId, id) {
|
|
4414
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
4415
|
+
if (!tenantTasks) return false;
|
|
4416
|
+
return tenantTasks.delete(id);
|
|
4417
|
+
}
|
|
4418
|
+
/**
|
|
4419
|
+
* Clear all tasks for a tenant (useful for testing)
|
|
4420
|
+
*/
|
|
4421
|
+
clear(tenantId) {
|
|
4422
|
+
if (tenantId) {
|
|
4423
|
+
this.tasks.delete(tenantId);
|
|
4424
|
+
} else {
|
|
4425
|
+
this.tasks.clear();
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
};
|
|
4429
|
+
|
|
4405
4430
|
// src/store_lattice/StoreLatticeManager.ts
|
|
4406
4431
|
var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager {
|
|
4407
4432
|
/**
|
|
@@ -4582,6 +4607,12 @@ storeLatticeManager.registerLattice(
|
|
|
4582
4607
|
"a2aApiKey",
|
|
4583
4608
|
defaultA2AApiKeyStore
|
|
4584
4609
|
);
|
|
4610
|
+
var defaultTaskStore = new InMemoryTaskStore();
|
|
4611
|
+
storeLatticeManager.registerLattice(
|
|
4612
|
+
"default",
|
|
4613
|
+
"task",
|
|
4614
|
+
defaultTaskStore
|
|
4615
|
+
);
|
|
4585
4616
|
|
|
4586
4617
|
// src/tool_lattice/manage_binding/index.ts
|
|
4587
4618
|
function getInstallationStore() {
|
|
@@ -4593,7 +4624,7 @@ var manageBindingSchema = import_zod3.default.object({
|
|
|
4593
4624
|
channelInstallationId: import_zod3.default.string().optional().describe("Channel installation ID (auto-detected if omitted and only one exists for this channel)"),
|
|
4594
4625
|
senderId: import_zod3.default.string().optional().describe("Sender identifier (email address, Lark openId, Slack userId)"),
|
|
4595
4626
|
agentId: import_zod3.default.string().optional().describe("Target agent ID to route messages to"),
|
|
4596
|
-
threadMode: import_zod3.default.enum(["fixed", "per_conversation"]).optional().default("per_conversation").describe("Thread mode
|
|
4627
|
+
threadMode: import_zod3.default.enum(["fixed", "per_conversation"]).optional().default("per_conversation").describe("Thread mode (ignored when channel adapter has its own thread strategy, e.g. Lark)"),
|
|
4597
4628
|
senderDisplayName: import_zod3.default.string().optional().describe("Human-readable name for the sender")
|
|
4598
4629
|
});
|
|
4599
4630
|
registerToolLattice(
|
|
@@ -4602,9 +4633,13 @@ registerToolLattice(
|
|
|
4602
4633
|
name: "manage_binding",
|
|
4603
4634
|
description: `Manage sender-to-agent bindings for external channels (email, Lark, Slack).
|
|
4604
4635
|
|
|
4636
|
+
Bindings are OPTIONAL \u2014 if no binding exists for a sender, messages route to the installation's fallbackAgentId. Only create a binding when a specific sender needs a different agent.
|
|
4637
|
+
|
|
4638
|
+
Thread isolation is handled automatically by the channel adapter (e.g. Lark isolates by sender+date). threadMode is only used when the channel adapter does not have its own strategy.
|
|
4639
|
+
|
|
4605
4640
|
- list_installations: List available channel installations. Filter by channel type (optional). Use this first to discover available channelInstallationIds.
|
|
4606
|
-
- create: Bind a sender to an agent. Required: channel, senderId, agentId. Optional: threadMode
|
|
4607
|
-
- update: Update an existing binding. Required: channel, senderId. Optional: agentId, threadMode
|
|
4641
|
+
- create: Bind a sender to an agent. Required: channel, senderId, agentId. Optional: threadMode. channelInstallationId auto-detected if only one exists.
|
|
4642
|
+
- update: Update an existing binding. Required: channel, senderId. Optional: agentId, threadMode, senderDisplayName.
|
|
4608
4643
|
- delete: Remove a binding. Required: channel, senderId.
|
|
4609
4644
|
- list: List all bindings. Optional: channel, agentId, channelInstallationId.
|
|
4610
4645
|
|
|
@@ -4612,7 +4647,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
4612
4647
|
schema: manageBindingSchema
|
|
4613
4648
|
},
|
|
4614
4649
|
async (input, config) => {
|
|
4615
|
-
const
|
|
4650
|
+
const registry3 = getBindingRegistry();
|
|
4616
4651
|
const runConfig = config?.configurable?.runConfig || {};
|
|
4617
4652
|
const tenantId = runConfig.tenantId || "default";
|
|
4618
4653
|
switch (input.action) {
|
|
@@ -4635,7 +4670,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
4635
4670
|
error: `No channelInstallationId provided and unable to auto-detect. Use action=list_installations to find available installations for channel "${input.channel}".`
|
|
4636
4671
|
});
|
|
4637
4672
|
}
|
|
4638
|
-
const binding = await
|
|
4673
|
+
const binding = await registry3.create({
|
|
4639
4674
|
channel: input.channel,
|
|
4640
4675
|
channelInstallationId: installId,
|
|
4641
4676
|
tenantId,
|
|
@@ -4657,7 +4692,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
4657
4692
|
error: `No channelInstallationId provided and unable to auto-detect. Use action=list_installations first.`
|
|
4658
4693
|
});
|
|
4659
4694
|
}
|
|
4660
|
-
const existing = await
|
|
4695
|
+
const existing = await registry3.resolve({
|
|
4661
4696
|
channel: input.channel,
|
|
4662
4697
|
senderId: input.senderId,
|
|
4663
4698
|
channelInstallationId: installId,
|
|
@@ -4666,7 +4701,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
4666
4701
|
if (!existing) {
|
|
4667
4702
|
return JSON.stringify({ success: false, error: "Binding not found" });
|
|
4668
4703
|
}
|
|
4669
|
-
const updated = await
|
|
4704
|
+
const updated = await registry3.update(existing.id, {
|
|
4670
4705
|
agentId: input.agentId,
|
|
4671
4706
|
threadMode: input.threadMode,
|
|
4672
4707
|
senderDisplayName: input.senderDisplayName
|
|
@@ -4684,7 +4719,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
4684
4719
|
error: `No channelInstallationId provided and unable to auto-detect.`
|
|
4685
4720
|
});
|
|
4686
4721
|
}
|
|
4687
|
-
const existing = await
|
|
4722
|
+
const existing = await registry3.resolve({
|
|
4688
4723
|
channel: input.channel,
|
|
4689
4724
|
senderId: input.senderId,
|
|
4690
4725
|
channelInstallationId: installId,
|
|
@@ -4693,11 +4728,11 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
4693
4728
|
if (!existing) {
|
|
4694
4729
|
return JSON.stringify({ success: false, error: "Binding not found" });
|
|
4695
4730
|
}
|
|
4696
|
-
await
|
|
4731
|
+
await registry3.delete(existing.id);
|
|
4697
4732
|
return JSON.stringify({ success: true, message: "Binding deleted" });
|
|
4698
4733
|
}
|
|
4699
4734
|
case "list": {
|
|
4700
|
-
const bindings = await
|
|
4735
|
+
const bindings = await registry3.list({
|
|
4701
4736
|
channel: input.channel,
|
|
4702
4737
|
agentId: input.agentId,
|
|
4703
4738
|
tenantId,
|
|
@@ -8672,7 +8707,7 @@ var createBrowserGetInfoTool = ({ vmIsolation }) => {
|
|
|
8672
8707
|
};
|
|
8673
8708
|
|
|
8674
8709
|
// src/index.ts
|
|
8675
|
-
var
|
|
8710
|
+
var import_messages6 = require("@langchain/core/messages");
|
|
8676
8711
|
|
|
8677
8712
|
// src/agent_lattice/types.ts
|
|
8678
8713
|
var import_protocols = require("@axiom-lattice/protocols");
|
|
@@ -8691,7 +8726,7 @@ var createReactAgentSchema = (schema) => {
|
|
|
8691
8726
|
};
|
|
8692
8727
|
|
|
8693
8728
|
// src/agent_lattice/builders/ReActAgentGraphBuilder.ts
|
|
8694
|
-
var
|
|
8729
|
+
var import_langchain57 = require("langchain");
|
|
8695
8730
|
|
|
8696
8731
|
// src/middlewares/codeEvalMiddleware.ts
|
|
8697
8732
|
var import_langchain37 = require("langchain");
|
|
@@ -9162,353 +9197,233 @@ metadata:
|
|
|
9162
9197
|
Then iterate based on what the user says.
|
|
9163
9198
|
`,
|
|
9164
9199
|
"create-workflow": `---
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
# Workflow Designer
|
|
9174
|
-
|
|
9175
|
-
This skill guides you through designing and creating workflow agents. A workflow is a LangGraph state machine compiled from a concise JSON DSL \u2014 steps define what happens, order defines the flow, and the engine handles the rest.
|
|
9176
|
-
|
|
9177
|
-
Every step runs on the workflow's built-in general-purpose agent \u2014 no external agent registration needed.
|
|
9178
|
-
|
|
9179
|
-
## Core Principle: id is everything
|
|
9200
|
+
name: create-workflow
|
|
9201
|
+
description: Design and build multi-step AI workflows using the YAML linear DSL. Use whenever users want to orchestrate agents in a pipeline with routing, parallelism, human-in-the-loop, or batch processing.
|
|
9202
|
+
license: MIT
|
|
9203
|
+
metadata:
|
|
9204
|
+
category: meta
|
|
9205
|
+
version: "5.0"
|
|
9206
|
+
---
|
|
9180
9207
|
|
|
9181
|
-
|
|
9182
|
-
1. **Node identifier** in the graph
|
|
9183
|
-
2. **State key** \u2014 output is stored at \`state.<id>\`
|
|
9184
|
-
3. **Template reference** \u2014 downstream steps use \`{{id}}\` to read it
|
|
9208
|
+
# YAML Workflow Designer
|
|
9185
9209
|
|
|
9186
|
-
|
|
9210
|
+
Use the linear YAML DSL \u2014 steps execute top-to-bottom. Use \`parallel:\` for concurrency. No dependency graph thinking required.
|
|
9187
9211
|
|
|
9188
|
-
|
|
9212
|
+
## Core Model: Linear + Parallel
|
|
9189
9213
|
|
|
9190
|
-
|
|
9214
|
+
- **Linear** \u2014 steps execute in written order. No \`needs\`, no dependency declarations.
|
|
9215
|
+
- **parallel** \u2014 a block where all children run concurrently. Block completes when all children finish.
|
|
9216
|
+
- **if** \u2014 JS expression. Step runs only when truthy. Omit to always run.
|
|
9217
|
+
- **prompt** \u2014 agent instruction with **{{label}}** refs. **{{input}}** is the user message.
|
|
9218
|
+
- **output** \u2014 shorthand schema using **{ field: type }** notation.
|
|
9219
|
+
- **ask** \u2014 boolean. Injects user clarification middleware for human interaction.
|
|
9191
9220
|
|
|
9192
|
-
|
|
9193
|
-
{ "id": "classify", "name": "Classify Intent", "prompt": "Classify the intent of: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } }
|
|
9194
|
-
\`\`\`
|
|
9221
|
+
## When to Use parallel vs map
|
|
9195
9222
|
|
|
9196
|
-
|
|
9197
|
-
|-------|----------|-------------|
|
|
9198
|
-
| id | no | State key for referencing output. Auto-generated if omitted, but required if downstream steps reference this step via \`{{id}}\` |
|
|
9199
|
-
| name | no | Human-readable label for this step |
|
|
9200
|
-
| prompt | yes | Task description with {{id}} refs |
|
|
9201
|
-
| schema | **yes** | Standard JSON Schema ONLY: \`{ "type": "object", "properties": { "field": { "type": "string" } } }\`. \`true\` is REJECTED \u2014 must be a concrete schema. Legacy shorthand \`{ "field": "string" }\` is REJECTED.
|
|
9223
|
+
This is the most important design decision. **They are fundamentally different:**
|
|
9202
9224
|
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
-
|
|
9208
|
-
|
|
9225
|
+
| | parallel | map |
|
|
9226
|
+
|---|---|---|
|
|
9227
|
+
| **Concern** | **Business parallelism** \u2014 reduce business processing time | **Data parallelism** \u2014 handle data volume |
|
|
9228
|
+
| **Tasks** | Each child does a **different** task | All items do the **same** task |
|
|
9229
|
+
| **Count** | Few (2-5), each hand-written | Dynamic, driven by source data |
|
|
9230
|
+
| **Input** | Independent prompts per child | Single \`each.prompt\` template, \`{{item}}\` for current element |
|
|
9231
|
+
| **if** | Per-child conditional | Whole block conditional |
|
|
9232
|
+
| **Example** | Legal review + Market analysis in parallel | Audit each line item in an invoice |
|
|
9209
9233
|
|
|
9210
|
-
|
|
9234
|
+
**Rule of thumb:** If you're writing the same prompt twice, you probably want \`map\`. If each branch has a unique purpose, use \`parallel\`.
|
|
9211
9235
|
|
|
9212
|
-
|
|
9236
|
+
## Step Format
|
|
9213
9237
|
|
|
9214
|
-
|
|
9238
|
+
### Agent Step
|
|
9215
9239
|
|
|
9216
|
-
\`\`\`
|
|
9217
|
-
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
}
|
|
9240
|
+
\`\`\`yaml
|
|
9241
|
+
- label:
|
|
9242
|
+
prompt: instruction with {{refs}}
|
|
9243
|
+
if: "expression"
|
|
9244
|
+
output: { field: type }
|
|
9245
|
+
ask: true
|
|
9221
9246
|
\`\`\`
|
|
9222
9247
|
|
|
9223
|
-
|
|
9224
|
-
|-------|----------|-------------|
|
|
9225
|
-
| if | yes | State field name (e.g. "approved") or expression (e.g. "score >= 60"). **CRITICAL: \`{{}}\` is FORBIDDEN in \`if\`** \u2014 it is a plain JavaScript expression, not a template. \u274C \`"if": "{{intent}}"\` is WRONG. \u2705 \`"if": "intent"\` is correct. |
|
|
9226
|
-
| then | yes | Step(s) to run when condition is truthy |
|
|
9227
|
-
| else | no | Step(s) to run when condition is falsy |
|
|
9228
|
-
|
|
9229
|
-
The engine evaluates \`if\` as a JavaScript expression prefixed with \`state.\`. Both \`then\` and \`else\` can be a single step or an array of steps. After both branches, execution rejoins at the next step after the condition.
|
|
9230
|
-
|
|
9231
|
-
**Switch (branches):**
|
|
9248
|
+
### Parallel Block
|
|
9232
9249
|
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
9241
|
-
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
9242
|
-
}
|
|
9243
|
-
}
|
|
9250
|
+
\`\`\`yaml
|
|
9251
|
+
- parallel:
|
|
9252
|
+
- child1:
|
|
9253
|
+
prompt: ...
|
|
9254
|
+
if: "expression"
|
|
9255
|
+
- child2:
|
|
9256
|
+
prompt: ...
|
|
9244
9257
|
\`\`\`
|
|
9245
9258
|
|
|
9246
|
-
|
|
9247
|
-
|-------|----------|-------------|
|
|
9248
|
-
| if | yes | State field whose STRING VALUE is matched against branch keys. **Same rule \u2014 \`{{}}\` is FORBIDDEN here.** |
|
|
9249
|
-
| branches | yes | Map of value \u2192 step(s). \`"default"\` key is a catch-all for unmatched values |
|
|
9250
|
-
| then/else | no | Not used when branches is present |
|
|
9251
|
-
|
|
9252
|
-
Unlike \`then\`/\`else\` (truthy/falsy ternary), \`branches\` does exact string match against the state field value. Always include a \`"default"\` branch.
|
|
9259
|
+
Parallel children are agent steps only. No nested parallel or map inside parallel.
|
|
9253
9260
|
|
|
9254
|
-
|
|
9261
|
+
### Map Step
|
|
9255
9262
|
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
}
|
|
9263
|
+
\`\`\`yaml
|
|
9264
|
+
- label:
|
|
9265
|
+
map:
|
|
9266
|
+
source: "extract.items"
|
|
9267
|
+
if: "extract.items.length > 0"
|
|
9268
|
+
each:
|
|
9269
|
+
prompt: Process {{item}}
|
|
9270
|
+
output: { result: string }
|
|
9271
|
+
batch: 50
|
|
9272
|
+
concurrency: 5
|
|
9264
9273
|
\`\`\`
|
|
9265
9274
|
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
| Field | Required | Description |
|
|
9269
|
-
|-------|----------|-------------|
|
|
9270
|
-
| id | no | State key for the agent's structured output |
|
|
9271
|
-
| type | yes | Must be \`"human"\` |
|
|
9272
|
-
| prompt | yes | Tell the agent what to present to the user and what to ask. The agent is a facilitator \u2014 write instructions like "Present X to the user and ask Y", NOT "You are a reviewer. Review X..." |
|
|
9273
|
-
| title | no | Display label for the human step |
|
|
9274
|
-
| schema | no | JSON Schema constraining the agent's structured output format |
|
|
9275
|
-
|
|
9276
|
-
### map \u2014 iterate over an array
|
|
9275
|
+
## Schema Shorthand
|
|
9277
9276
|
|
|
9278
|
-
|
|
9279
|
-
{ "id": "results", "type": "map",
|
|
9280
|
-
"source": "items",
|
|
9281
|
-
"each": { "prompt": "Audit: {{item}}", "schema": { "type": "object", "properties": { "result": { "type": "string" } } } },
|
|
9282
|
-
"batch": 10, "concurrency": 3
|
|
9283
|
-
}
|
|
9284
|
-
\`\`\`
|
|
9285
|
-
|
|
9286
|
-
| Field | Required | Description |
|
|
9287
|
-
|-------|----------|-------------|
|
|
9288
|
-
| id | yes | Output key for the results array |
|
|
9289
|
-
| source | yes | id of the step whose output is the array to iterate |
|
|
9290
|
-
| each | yes | Step applied to each element. Use {{item}} for the current element |
|
|
9291
|
-
| reduce | no | Step to aggregate results |
|
|
9292
|
-
| batch | no | Items per batch (default 50) |
|
|
9293
|
-
| concurrency | no | Max parallel items (default 5) |
|
|
9277
|
+
Write **{ field: type }** instead of JSON Schema:
|
|
9294
9278
|
|
|
9295
|
-
|
|
9279
|
+
| Shorthand | Meaning |
|
|
9280
|
+
|-----------|---------|
|
|
9281
|
+
| **field: string** | string property |
|
|
9282
|
+
| **field: number** | number property |
|
|
9283
|
+
| **field: boolean** | boolean property |
|
|
9284
|
+
| **field: string[]** | array of strings |
|
|
9285
|
+
| **field: number[]** | array of numbers |
|
|
9286
|
+
| **field: [{ a: string, b: number }]** | array of objects |
|
|
9287
|
+
| **field: { sub: string }** | nested object |
|
|
9296
9288
|
|
|
9297
|
-
|
|
9298
|
-
{ "type": "parallel", "steps": [
|
|
9299
|
-
{ "id": "legal", "prompt": "Legal review: {{input}}" },
|
|
9300
|
-
{ "id": "finance", "prompt": "Finance: {{input}}" }
|
|
9301
|
-
]}
|
|
9302
|
-
\`\`\`
|
|
9289
|
+
Use **block style** (each field on its own line). Flow style \`{ field: "type" }\` with quoted values also works.
|
|
9303
9290
|
|
|
9304
|
-
|
|
9291
|
+
## Template Syntax
|
|
9305
9292
|
|
|
9306
|
-
|
|
9293
|
+
| Syntax | Resolves to |
|
|
9294
|
+
|--------|------------|
|
|
9295
|
+
| \`{{input}}\` | Initial user message |
|
|
9296
|
+
| \`{{label}}\` | Full output of step |
|
|
9297
|
+
| \`{{label.field}}\` | Nested field access |
|
|
9298
|
+
| \`{{item}}\` | Current element in map iteration |
|
|
9307
9299
|
|
|
9308
|
-
|
|
9309
|
-
{ "type": "end" }
|
|
9310
|
-
\`\`\`
|
|
9300
|
+
## Design Patterns
|
|
9311
9301
|
|
|
9312
|
-
|
|
9302
|
+
### Linear Pipeline
|
|
9313
9303
|
|
|
9314
|
-
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
|
|
9323
|
-
"else": { "type": "end", "status": "failed" }
|
|
9324
|
-
}
|
|
9325
|
-
\`\`\`
|
|
9326
|
-
|
|
9327
|
-
- If all outcomes share the same final status, use a single \`end\` node after the condition/parallel block \u2014 the engine automatically converges all paths to it.
|
|
9328
|
-
|
|
9329
|
-
## Template Syntax
|
|
9330
|
-
|
|
9331
|
-
| Syntax | Resolves to | When to use |
|
|
9332
|
-
|--------|------------|-------------|
|
|
9333
|
-
| \`{{input}}\` | Initial user message | First step or any step needing the original question |
|
|
9334
|
-
| \`{{id}}\` | Output of step with given id | Referencing any upstream step's result |
|
|
9335
|
-
| \`{{item}}\` | Current element in map iteration | Inside map \`each.prompt\` |
|
|
9304
|
+
\`\`\`yaml
|
|
9305
|
+
steps:
|
|
9306
|
+
- extract:
|
|
9307
|
+
prompt: Extract data from {{input}}
|
|
9308
|
+
- transform:
|
|
9309
|
+
prompt: Transform {{extract}}
|
|
9310
|
+
- final:
|
|
9311
|
+
prompt: Combine raw {{extract}} with transformed {{transform}}
|
|
9312
|
+
\`\`\`
|
|
9336
9313
|
|
|
9337
|
-
|
|
9314
|
+
### Classify -> Route via Parallel + if
|
|
9338
9315
|
|
|
9339
|
-
|
|
9316
|
+
\`\`\`yaml
|
|
9317
|
+
steps:
|
|
9318
|
+
- classify:
|
|
9319
|
+
prompt: Classify intent from {{input}}
|
|
9320
|
+
output:
|
|
9321
|
+
intent: string
|
|
9322
|
+
urgency: number
|
|
9323
|
+
- parallel:
|
|
9324
|
+
- billing:
|
|
9325
|
+
if: "classify.intent == 'billing'"
|
|
9326
|
+
prompt: Handle billing: {{input}}
|
|
9327
|
+
ask: true
|
|
9328
|
+
- technical:
|
|
9329
|
+
if: "classify.intent == 'technical'"
|
|
9330
|
+
prompt: Handle technical: {{input}}
|
|
9331
|
+
- escalate:
|
|
9332
|
+
if: "classify.urgency >= 8"
|
|
9333
|
+
prompt: Urgent handling
|
|
9334
|
+
ask: true
|
|
9335
|
+
\`\`\`
|
|
9340
9336
|
|
|
9341
|
-
|
|
9342
|
-
\`\`\`json
|
|
9343
|
-
// \u274C WRONG \u2014 {{}} does not belong in if:
|
|
9344
|
-
{ "type": "condition", "if": "{{intent}}", "then": {...}, "else": {...} }
|
|
9337
|
+
### Parallel Processing
|
|
9345
9338
|
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9339
|
+
\`\`\`yaml
|
|
9340
|
+
steps:
|
|
9341
|
+
- gather:
|
|
9342
|
+
prompt: Gather data from {{input}}
|
|
9343
|
+
- parallel:
|
|
9344
|
+
- legal:
|
|
9345
|
+
prompt: Legal analysis of {{gather}}
|
|
9346
|
+
output:
|
|
9347
|
+
risk: string
|
|
9348
|
+
compliant: boolean
|
|
9349
|
+
- market:
|
|
9350
|
+
prompt: Market analysis of {{gather}}
|
|
9351
|
+
output:
|
|
9352
|
+
opportunity: string
|
|
9353
|
+
score: number
|
|
9354
|
+
- report:
|
|
9355
|
+
prompt: |
|
|
9356
|
+
Synthesize findings:
|
|
9357
|
+
Legal: {{legal}}
|
|
9358
|
+
Market: {{market}}
|
|
9359
|
+
\`\`\`
|
|
9349
9360
|
|
|
9350
|
-
|
|
9361
|
+
### Approval Flow with Human
|
|
9351
9362
|
|
|
9352
|
-
|
|
9363
|
+
\`\`\`yaml
|
|
9364
|
+
steps:
|
|
9365
|
+
- draft:
|
|
9366
|
+
prompt: Draft response to {{input}}
|
|
9367
|
+
- review:
|
|
9368
|
+
prompt: Present {{draft}} to user for approval
|
|
9369
|
+
output:
|
|
9370
|
+
approved: boolean
|
|
9371
|
+
comments: string
|
|
9372
|
+
ask: true
|
|
9373
|
+
- publish:
|
|
9374
|
+
if: "review.approved"
|
|
9375
|
+
prompt: Publish {{draft}}
|
|
9376
|
+
- revise:
|
|
9377
|
+
if: "!review.approved"
|
|
9378
|
+
prompt: Revise based on {{review.comments}}
|
|
9379
|
+
\`\`\`
|
|
9353
9380
|
|
|
9354
|
-
|
|
9355
|
-
- **edges** \u2014 auto-generated from step order (linear) and types (fan-out for parallel, conditional for condition)
|
|
9356
|
-
- **output.key** \u2014 always equals \`id\`
|
|
9357
|
-
- **version** \u2014 always "1.0" internally
|
|
9358
|
-
- **node IDs** \u2014 prefixed internally to avoid conflicts with state channel names
|
|
9359
|
-
- **human step type** \u2014 the human step has ask_user_to_clarify built-in. Use \`{ "type": "human", ... }\` in the DSL for user interaction. Do NOT manually add ask_user_to_clarify middleware to regular agent steps \u2014 use the dedicated \`human\` step instead.
|
|
9381
|
+
### Map (Iteration)
|
|
9360
9382
|
|
|
9361
|
-
|
|
9383
|
+
\`\`\`yaml
|
|
9384
|
+
steps:
|
|
9385
|
+
- extract:
|
|
9386
|
+
prompt: Extract items from {{input}}
|
|
9387
|
+
output:
|
|
9388
|
+
items:
|
|
9389
|
+
- name: string
|
|
9390
|
+
- map_items:
|
|
9391
|
+
map:
|
|
9392
|
+
source: "extract.items"
|
|
9393
|
+
each:
|
|
9394
|
+
prompt: Audit {{item.name}}
|
|
9395
|
+
output:
|
|
9396
|
+
result: string
|
|
9397
|
+
- summary:
|
|
9398
|
+
prompt: Summarize findings: {{map_items}}
|
|
9399
|
+
\`\`\`
|
|
9362
9400
|
|
|
9363
|
-
|
|
9401
|
+
## Keep Business Logic in Agents
|
|
9364
9402
|
|
|
9365
|
-
|
|
9366
|
-
{
|
|
9367
|
-
"name": "knowledge-qa",
|
|
9368
|
-
"steps": [
|
|
9369
|
-
{ "id": "research", "name": "Research Topic", "prompt": "Research: {{input}}", "schema": { "type": "object", "properties": { "findings": { "type": "string" } } } },
|
|
9370
|
-
{ "id": "answer", "name": "Write Answer", "prompt": "Write answer based on: {{research}}", "schema": { "type": "object", "properties": { "answer": { "type": "string" } } } },
|
|
9371
|
-
{ "type": "end" }
|
|
9372
|
-
]
|
|
9373
|
-
}
|
|
9374
|
-
\`\`\`
|
|
9403
|
+
The DSL is for orchestration (what runs when). Business logic (validation, branching, error handling, user interaction) belongs inside agent prompts, not as workflow if conditions. An agent can validate, branch, and ask questions \u2014 all in one step.
|
|
9375
9404
|
|
|
9376
|
-
|
|
9405
|
+
**Rule:** if you have more if conditions than workflow phases, move logic into richer agent prompts.
|
|
9377
9406
|
|
|
9378
|
-
|
|
9379
|
-
{
|
|
9380
|
-
"name": "customer-router",
|
|
9381
|
-
"steps": [
|
|
9382
|
-
{ "id": "intent", "name": "Classify Intent", "prompt": "Classify: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } },
|
|
9383
|
-
{ "type": "condition", "if": "intent",
|
|
9384
|
-
"then": { "id": "support", "name": "Handle Support", "prompt": "Handle support: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } },
|
|
9385
|
-
"else": { "id": "sales", "name": "Handle Sales", "prompt": "Handle sales: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } }
|
|
9386
|
-
},
|
|
9387
|
-
{ "type": "end" }
|
|
9388
|
-
]
|
|
9389
|
-
}
|
|
9390
|
-
\`\`\`
|
|
9407
|
+
## What You NEVER Write
|
|
9391
9408
|
|
|
9392
|
-
|
|
9409
|
+
- **needs** \u2014 not supported. Steps execute linearly. Use parallel for concurrency.
|
|
9410
|
+
- **edges** \u2014 auto-generated from step order and parallel structure
|
|
9411
|
+
- **nested parallel** \u2014 parallel children are flat agent steps only
|
|
9412
|
+
- **map inside parallel** \u2014 map is a top-level step only
|
|
9413
|
+
- **json schema** \u2014 use **{ field: type }** block style
|
|
9414
|
+
- do not use {{}} markers in if expressions
|
|
9415
|
+
- **workflow-level business logic** \u2014 decisions belong inside agent prompts
|
|
9393
9416
|
|
|
9394
|
-
|
|
9417
|
+
## Checklist
|
|
9395
9418
|
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
"sales": { "id": "sales", "prompt": "Handle sales: {{input}}" },
|
|
9405
|
-
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
9406
|
-
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
9407
|
-
}
|
|
9408
|
-
},
|
|
9409
|
-
{ "type": "end" }
|
|
9410
|
-
]
|
|
9411
|
-
}
|
|
9412
|
-
\`\`\`
|
|
9413
|
-
|
|
9414
|
-
### Pattern 3: Extract \u2192 Review \u2192 Approve
|
|
9415
|
-
|
|
9416
|
-
\`\`\`json
|
|
9417
|
-
{
|
|
9418
|
-
"name": "approval-flow",
|
|
9419
|
-
"steps": [
|
|
9420
|
-
{ "id": "draft", "name": "Draft Response", "prompt": "Draft a response to: {{input}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } },
|
|
9421
|
-
{ "id": "review", "type": "human",
|
|
9422
|
-
"title": "Approval",
|
|
9423
|
-
"prompt": "Present the draft below to the user for approval. Ask whether to approve or reject with comments.\\n\\nDraft:\\n{{draft}}",
|
|
9424
|
-
"schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } } },
|
|
9425
|
-
{ "type": "condition", "if": "review.approved",
|
|
9426
|
-
"then": { "id": "published", "name": "Publish", "prompt": "Publish: {{draft}}", "schema": { "type": "object", "properties": { "status": { "type": "string" } } } },
|
|
9427
|
-
"else": { "id": "revised", "name": "Revise", "prompt": "Revise based on: {{review.comments}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } }
|
|
9428
|
-
},
|
|
9429
|
-
{ "type": "end" }
|
|
9430
|
-
]
|
|
9431
|
-
}
|
|
9432
|
-
\`\`\`
|
|
9433
|
-
|
|
9434
|
-
### Pattern 4: Parallel Research
|
|
9435
|
-
|
|
9436
|
-
\`\`\`json
|
|
9437
|
-
{
|
|
9438
|
-
"name": "due-diligence",
|
|
9439
|
-
"steps": [
|
|
9440
|
-
{ "id": "info", "name": "Gather Info", "prompt": "Gather info: {{input}}", "schema": { "type": "object", "properties": { "rawData": { "type": "string" } } } },
|
|
9441
|
-
{ "type": "parallel", "steps": [
|
|
9442
|
-
{ "id": "legal", "name": "Legal Review", "prompt": "Legal review: {{info}}", "schema": { "type": "object", "properties": { "risks": { "type": "array", "items": { "type": "string" } } } } },
|
|
9443
|
-
{ "id": "finance", "name": "Finance Review", "prompt": "Finance review: {{info}}", "schema": { "type": "object", "properties": { "score": { "type": "number" } } } },
|
|
9444
|
-
{ "id": "market", "name": "Market Analysis", "prompt": "Market analysis: {{info}}", "schema": { "type": "object", "properties": { "trend": { "type": "string" } } } }
|
|
9445
|
-
]},
|
|
9446
|
-
{ "id": "synthesis", "name": "Synthesize", "prompt": "Synthesize: legal={{legal}} finance={{finance}} market={{market}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
9447
|
-
{ "type": "end" }
|
|
9448
|
-
]
|
|
9449
|
-
}
|
|
9450
|
-
\`\`\`
|
|
9451
|
-
|
|
9452
|
-
### Pattern 5: Batch Map + Reduce
|
|
9453
|
-
|
|
9454
|
-
\`\`\`json
|
|
9455
|
-
{
|
|
9456
|
-
"name": "sentiment-analysis",
|
|
9457
|
-
"steps": [
|
|
9458
|
-
{ "id": "posts", "name": "Scrape Posts", "prompt": "Scrape posts about: {{input}}", "schema": { "type": "object", "properties": { "posts": { "type": "array", "items": { "type": "object", "properties": { "text": { "type": "string" } } } } } } },
|
|
9459
|
-
{ "id": "sentiments", "type": "map", "source": "posts",
|
|
9460
|
-
"each": { "prompt": "Analyze sentiment: {{item}}", "schema": { "type": "object", "properties": { "sentiment": { "type": "string" } } } },
|
|
9461
|
-
"reduce": { "prompt": "Summarize: {{sentiments}}", "schema": { "type": "object", "properties": { "summary": { "type": "string" } } } }
|
|
9462
|
-
},
|
|
9463
|
-
{ "id": "report", "name": "Generate Report", "prompt": "Generate report from: {{sentiments}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
9464
|
-
{ "type": "end" }
|
|
9465
|
-
]
|
|
9466
|
-
}
|
|
9467
|
-
\`\`\`
|
|
9468
|
-
|
|
9469
|
-
## Step 1: Understand the Process
|
|
9470
|
-
|
|
9471
|
-
Ask the user:
|
|
9472
|
-
- What are the steps in order?
|
|
9473
|
-
- Are there branches (if condition then A else B)?
|
|
9474
|
-
- Can any steps run in parallel?
|
|
9475
|
-
- Is human approval/review needed?
|
|
9476
|
-
- What data flows between steps?
|
|
9477
|
-
|
|
9478
|
-
## Step 2: Prepare Dependencies
|
|
9479
|
-
|
|
9480
|
-
1. Call \`list_tools\` to see available tools for the workflow agent.
|
|
9481
|
-
|
|
9482
|
-
## Step 3: Write the DSL
|
|
9483
|
-
|
|
9484
|
-
Use \`create_workflow\` with \`skillLoaded: true\`. Never write \`state.fields\`, \`edges\`, \`version\`, or \`output.key\` \u2014 they are auto-generated.
|
|
9485
|
-
|
|
9486
|
-
**Checklist before calling:**
|
|
9487
|
-
- Every step that produces data referenced downstream has an \`id\`
|
|
9488
|
-
- Every agent/map-each step has a valid \`schema\` in standard JSON Schema format (with \`"type": "object"\` and \`"properties"\`)
|
|
9489
|
-
- Schema uses \`{ "type": "object", "properties": { ... } }\` \u2014 \`true\` and legacy \`{ "field": "string" }\` are REJECTED
|
|
9490
|
-
- Downstream steps reference upstream data with \`{{id}}\`
|
|
9491
|
-
- **Condition \`if\` fields do NOT use \`{{}}\`** \u2014 they are plain expressions like \`"intent"\` or \`"score >= 60"\`
|
|
9492
|
-
- Condition steps have \`then\`/\`else\` (binary) or \`branches\` (switch)
|
|
9493
|
-
- Human steps have \`schema\` constraining the agent's structured output
|
|
9494
|
-
- Map steps have \`source\` pointing to an existing step id
|
|
9495
|
-
- Parallel steps have sibling steps with unique \`id\`s
|
|
9496
|
-
- Workflow ends with \`{ "type": "end" }\`
|
|
9497
|
-
- Use \`human\` step type for user interaction (clarify middleware is built-in)
|
|
9498
|
-
|
|
9499
|
-
## Step 4: Test
|
|
9500
|
-
|
|
9501
|
-
After creating, optionally call \`validate_workflow(id)\` to check the workflow compiles correctly. Then test with \`invoke_agent\`.
|
|
9502
|
-
|
|
9503
|
-
## Debugging Tips
|
|
9504
|
-
|
|
9505
|
-
- If output is missing: check the producing step has an \`id\`
|
|
9506
|
-
- The human step invokes an agent that can use ask_user_to_clarify. The agent's structured output is stored under the step's \`id\`. Access nested results with dot notation: \`{{review.approved}}\`, \`{{review.comments}}\`
|
|
9507
|
-
- Map results are an array; use \`reduce\` to aggregate into a summary
|
|
9508
|
-
- Condition branching uses truthiness: empty string, 0, null, false \u2192 else path
|
|
9509
|
-
- \`{{input}}\` contains the user's initial message; it's always available
|
|
9510
|
-
- Parallel + condition: a parallel group cannot be the first step inside a condition's then/else (LangGraph limitation). Add a preceding agent step.
|
|
9511
|
-
`
|
|
9419
|
+
- Every step has a unique label
|
|
9420
|
+
- Steps execute top-to-bottom \u2014 no dependency thinking needed
|
|
9421
|
+
- \`{{label}}\` can reference ANY upstream step output
|
|
9422
|
+
- if uses plain JS, no {{}}
|
|
9423
|
+
- Schema uses block style shorthand
|
|
9424
|
+
- parallel children are flat agent steps
|
|
9425
|
+
- Business logic stays inside agent prompts
|
|
9426
|
+
- ask: true for human interaction`
|
|
9512
9427
|
};
|
|
9513
9428
|
function getBuiltInSkillMeta(name) {
|
|
9514
9429
|
const content = BUILTIN_SKILLS[name];
|
|
@@ -12419,7 +12334,7 @@ ${currentSystemPrompt}` : dateContext;
|
|
|
12419
12334
|
// src/deep_agent_new/middleware/scheduler.ts
|
|
12420
12335
|
var import_langchain55 = require("langchain");
|
|
12421
12336
|
var import_zod50 = require("zod");
|
|
12422
|
-
var
|
|
12337
|
+
var import_uuid3 = require("uuid");
|
|
12423
12338
|
var import_protocols8 = require("@axiom-lattice/protocols");
|
|
12424
12339
|
|
|
12425
12340
|
// src/schedule_lattice/ScheduleLatticeManager.ts
|
|
@@ -13974,7 +13889,7 @@ var buffer = new InMemoryChunkBuffer({
|
|
|
13974
13889
|
registerChunkBuffer("default", buffer);
|
|
13975
13890
|
|
|
13976
13891
|
// src/services/Agent.ts
|
|
13977
|
-
var
|
|
13892
|
+
var import_uuid2 = require("uuid");
|
|
13978
13893
|
var ThreadStatus2 = /* @__PURE__ */ ((ThreadStatus3) => {
|
|
13979
13894
|
ThreadStatus3["IDLE"] = "idle";
|
|
13980
13895
|
ThreadStatus3["BUSY"] = "busy";
|
|
@@ -14020,7 +13935,7 @@ var Agent = class {
|
|
|
14020
13935
|
runConfig
|
|
14021
13936
|
},
|
|
14022
13937
|
configurable: {
|
|
14023
|
-
run_id: (0,
|
|
13938
|
+
run_id: (0, import_uuid2.v4)(),
|
|
14024
13939
|
...runConfig,
|
|
14025
13940
|
runConfig
|
|
14026
13941
|
},
|
|
@@ -14054,7 +13969,6 @@ var Agent = class {
|
|
|
14054
13969
|
const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
|
|
14055
13970
|
const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
|
|
14056
13971
|
const { messages, ...rest } = input;
|
|
14057
|
-
const lifecycleManager = this;
|
|
14058
13972
|
const runConfig = {
|
|
14059
13973
|
thread_id: this.thread_id,
|
|
14060
13974
|
"x-tenant-id": this.tenant_id,
|
|
@@ -14094,7 +14008,7 @@ var Agent = class {
|
|
|
14094
14008
|
runConfig
|
|
14095
14009
|
},
|
|
14096
14010
|
configurable: {
|
|
14097
|
-
run_id: (0,
|
|
14011
|
+
run_id: (0, import_uuid2.v4)(),
|
|
14098
14012
|
...runConfig,
|
|
14099
14013
|
runConfig
|
|
14100
14014
|
// Inject runConfig for tools to access
|
|
@@ -14106,43 +14020,13 @@ var Agent = class {
|
|
|
14106
14020
|
}
|
|
14107
14021
|
);
|
|
14108
14022
|
try {
|
|
14109
|
-
|
|
14110
|
-
if (signal?.aborted) {
|
|
14111
|
-
await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
|
|
14112
|
-
throw new Error("Agent execution was aborted");
|
|
14113
|
-
}
|
|
14114
|
-
let data;
|
|
14115
|
-
let chunkContent = "";
|
|
14116
|
-
if (chunk2[0] === "updates") {
|
|
14117
|
-
const update = chunk2[1];
|
|
14118
|
-
const values = Object.values(update);
|
|
14119
|
-
const messages2 = values[0]?.messages;
|
|
14120
|
-
if (messages2?.[0]?.tool_call_id) {
|
|
14121
|
-
data = messages2[0].toDict();
|
|
14122
|
-
}
|
|
14123
|
-
} else if (chunk2[0] === "messages") {
|
|
14124
|
-
const messages2 = chunk2[1];
|
|
14125
|
-
data = messages2?.[0]?.toDict();
|
|
14126
|
-
}
|
|
14127
|
-
if (chunk2?.[1]?.__interrupt__) {
|
|
14128
|
-
const interruptData = chunk2?.[1]?.__interrupt__[0];
|
|
14129
|
-
data = {
|
|
14130
|
-
type: "interrupt",
|
|
14131
|
-
id: interruptData.id,
|
|
14132
|
-
data: { content: interruptData.value }
|
|
14133
|
-
};
|
|
14134
|
-
}
|
|
14135
|
-
if (data) {
|
|
14136
|
-
lifecycleManager.addChunk(data);
|
|
14137
|
-
}
|
|
14138
|
-
}
|
|
14023
|
+
await this.consumeAgentStream(agentStream, signal);
|
|
14139
14024
|
} catch (error) {
|
|
14140
14025
|
console.error("Stream error:", error);
|
|
14141
|
-
await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
|
|
14142
14026
|
throw error;
|
|
14143
14027
|
}
|
|
14144
14028
|
} catch (error) {
|
|
14145
|
-
await this.chunkBuffer.abortThread(
|
|
14029
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
14146
14030
|
throw error;
|
|
14147
14031
|
}
|
|
14148
14032
|
};
|
|
@@ -14423,8 +14307,8 @@ var Agent = class {
|
|
|
14423
14307
|
this.assistant_id = assistant_id;
|
|
14424
14308
|
this.thread_id = thread_id;
|
|
14425
14309
|
this.tenant_id = tenant_id;
|
|
14426
|
-
this.workspace_id = workspace_id;
|
|
14427
|
-
this.project_id = project_id;
|
|
14310
|
+
this.workspace_id = workspace_id || "default";
|
|
14311
|
+
this.project_id = project_id || "default";
|
|
14428
14312
|
this.custom_run_config = custom_run_config;
|
|
14429
14313
|
}
|
|
14430
14314
|
getHumanPendingContent(message) {
|
|
@@ -14510,7 +14394,7 @@ var Agent = class {
|
|
|
14510
14394
|
};
|
|
14511
14395
|
}
|
|
14512
14396
|
async invoke(queueMessage, signal) {
|
|
14513
|
-
const messageId = (0,
|
|
14397
|
+
const messageId = (0, import_uuid2.v4)();
|
|
14514
14398
|
const input = {
|
|
14515
14399
|
...queueMessage.input,
|
|
14516
14400
|
messages: [new import_langchain54.HumanMessage({ id: messageId, content: queueMessage.input.message })]
|
|
@@ -14518,10 +14402,132 @@ var Agent = class {
|
|
|
14518
14402
|
const inputMessage = { ...queueMessage, input };
|
|
14519
14403
|
return this.agentExecutor(inputMessage, signal);
|
|
14520
14404
|
}
|
|
14405
|
+
/**
|
|
14406
|
+
* Like {@link invoke} but returns the full LangGraph state (all annotations)
|
|
14407
|
+
* instead of only messages. Messages are serialized to dicts; other state
|
|
14408
|
+
* fields are returned as-is.
|
|
14409
|
+
*
|
|
14410
|
+
* @remarks
|
|
14411
|
+
* Only call this when you need the full state. Existing callers (gateway,
|
|
14412
|
+
* workflows) should keep using {@link invoke} which returns only messages
|
|
14413
|
+
* to avoid exposing internal annotation data.
|
|
14414
|
+
*/
|
|
14415
|
+
async invokeWithState(queueMessage, signal) {
|
|
14416
|
+
const messageId = (0, import_uuid2.v4)();
|
|
14417
|
+
const input = {
|
|
14418
|
+
...queueMessage.input,
|
|
14419
|
+
messages: [new import_langchain54.HumanMessage({ id: messageId, content: queueMessage.input.message })]
|
|
14420
|
+
};
|
|
14421
|
+
const inputMessage = { ...queueMessage, input };
|
|
14422
|
+
const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(inputMessage.custom_run_config);
|
|
14423
|
+
const { messages, ...rest } = inputMessage.input;
|
|
14424
|
+
if (signal?.aborted) {
|
|
14425
|
+
throw new Error("Agent execution was aborted");
|
|
14426
|
+
}
|
|
14427
|
+
let result;
|
|
14428
|
+
result = await runnable_agent.invoke(
|
|
14429
|
+
inputMessage.command ? new import_langgraph6.Command(inputMessage.command) : { ...rest, messages, "x-tenant-id": this.tenant_id },
|
|
14430
|
+
{
|
|
14431
|
+
context: { runConfig },
|
|
14432
|
+
configurable: {
|
|
14433
|
+
run_id: (0, import_uuid2.v4)(),
|
|
14434
|
+
...runConfig,
|
|
14435
|
+
runConfig
|
|
14436
|
+
},
|
|
14437
|
+
recursionLimit: 200,
|
|
14438
|
+
signal
|
|
14439
|
+
}
|
|
14440
|
+
);
|
|
14441
|
+
if (signal?.aborted) {
|
|
14442
|
+
throw new Error("Agent execution was aborted");
|
|
14443
|
+
}
|
|
14444
|
+
const { messages: _rawMessages, ...restState } = result;
|
|
14445
|
+
const serializedMessages = result.messages.map((message) => {
|
|
14446
|
+
const { type, data } = message.toDict();
|
|
14447
|
+
return { ...data, role: type };
|
|
14448
|
+
});
|
|
14449
|
+
return { messages: serializedMessages, ...restState };
|
|
14450
|
+
}
|
|
14521
14451
|
async getPendingMessages() {
|
|
14522
14452
|
const store = this.getQueueStore();
|
|
14523
14453
|
return await store.getPendingMessages(this.thread_id);
|
|
14524
14454
|
}
|
|
14455
|
+
async consumeAgentStream(agentStream, signal) {
|
|
14456
|
+
for await (const chunk2 of agentStream) {
|
|
14457
|
+
if (signal?.aborted) {
|
|
14458
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
14459
|
+
throw new Error("Agent execution was aborted");
|
|
14460
|
+
}
|
|
14461
|
+
let data;
|
|
14462
|
+
if (chunk2[0] === "updates") {
|
|
14463
|
+
const update = chunk2[1];
|
|
14464
|
+
const values = Object.values(update);
|
|
14465
|
+
const messages = values[0]?.messages;
|
|
14466
|
+
if (messages?.[0]?.tool_call_id) {
|
|
14467
|
+
data = messages[0].toDict();
|
|
14468
|
+
}
|
|
14469
|
+
} else if (chunk2[0] === "messages") {
|
|
14470
|
+
const messages = chunk2[1];
|
|
14471
|
+
data = messages?.[0]?.toDict();
|
|
14472
|
+
}
|
|
14473
|
+
if (chunk2?.[1]?.__interrupt__) {
|
|
14474
|
+
const interruptData = chunk2?.[1]?.__interrupt__[0];
|
|
14475
|
+
data = {
|
|
14476
|
+
type: "interrupt",
|
|
14477
|
+
id: interruptData.id,
|
|
14478
|
+
data: { content: interruptData.value }
|
|
14479
|
+
};
|
|
14480
|
+
}
|
|
14481
|
+
if (data) {
|
|
14482
|
+
this.addChunk(data);
|
|
14483
|
+
}
|
|
14484
|
+
}
|
|
14485
|
+
}
|
|
14486
|
+
/**
|
|
14487
|
+
* Resume LangGraph execution from the last checkpoint.
|
|
14488
|
+
*
|
|
14489
|
+
* Streams with `null` input — this tells LangGraph to continue from
|
|
14490
|
+
* wherever it left off using the checkpointed state for this thread.
|
|
14491
|
+
* All output chunks are buffered via {@link addChunk}.
|
|
14492
|
+
*/
|
|
14493
|
+
async resumeGraphFromCheckpoint(signal) {
|
|
14494
|
+
const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
|
|
14495
|
+
const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
|
|
14496
|
+
if (!runnable_agent) {
|
|
14497
|
+
throw new Error(`Agent ${this.assistant_id} not found`);
|
|
14498
|
+
}
|
|
14499
|
+
const runConfig = {
|
|
14500
|
+
thread_id: this.thread_id,
|
|
14501
|
+
"x-tenant-id": this.tenant_id,
|
|
14502
|
+
"x-workspace-id": this.workspace_id,
|
|
14503
|
+
"x-project-id": this.project_id,
|
|
14504
|
+
"x-thread-id": this.thread_id,
|
|
14505
|
+
"x-assistant-id": this.assistant_id,
|
|
14506
|
+
...agentLattice?.config?.runConfig || {},
|
|
14507
|
+
tenantId: this.tenant_id,
|
|
14508
|
+
workspaceId: this.workspace_id,
|
|
14509
|
+
projectId: this.project_id,
|
|
14510
|
+
...this.custom_run_config || {},
|
|
14511
|
+
assistant_id: this.assistant_id
|
|
14512
|
+
};
|
|
14513
|
+
const agentStream = await runnable_agent.stream(
|
|
14514
|
+
null,
|
|
14515
|
+
{
|
|
14516
|
+
context: {
|
|
14517
|
+
runConfig
|
|
14518
|
+
},
|
|
14519
|
+
configurable: {
|
|
14520
|
+
...runConfig,
|
|
14521
|
+
runConfig
|
|
14522
|
+
},
|
|
14523
|
+
streamMode: ["updates", "messages"],
|
|
14524
|
+
subgraphs: false,
|
|
14525
|
+
recursionLimit: 200,
|
|
14526
|
+
signal
|
|
14527
|
+
}
|
|
14528
|
+
);
|
|
14529
|
+
await this.consumeAgentStream(agentStream, signal);
|
|
14530
|
+
}
|
|
14525
14531
|
getQueueStore() {
|
|
14526
14532
|
if (!this.queueStore) {
|
|
14527
14533
|
try {
|
|
@@ -14600,7 +14606,7 @@ var Agent = class {
|
|
|
14600
14606
|
*/
|
|
14601
14607
|
async addMessage(queueMessage, mode) {
|
|
14602
14608
|
const useMode = mode ?? this.queueMode.mode;
|
|
14603
|
-
const messageId = queueMessage.input.id || (0,
|
|
14609
|
+
const messageId = queueMessage.input.id || (0, import_uuid2.v4)();
|
|
14604
14610
|
const messages = queueMessage.input.messages;
|
|
14605
14611
|
const legacyMessage = queueMessage.input.message;
|
|
14606
14612
|
if (!messages && !legacyMessage) {
|
|
@@ -14651,6 +14657,8 @@ var Agent = class {
|
|
|
14651
14657
|
threadId: this.thread_id,
|
|
14652
14658
|
tenantId: this.tenant_id,
|
|
14653
14659
|
assistantId: this.assistant_id,
|
|
14660
|
+
workspaceId: this.workspace_id,
|
|
14661
|
+
projectId: this.project_id,
|
|
14654
14662
|
content,
|
|
14655
14663
|
type: pendingType,
|
|
14656
14664
|
command: queueMessage.command,
|
|
@@ -14667,6 +14675,8 @@ var Agent = class {
|
|
|
14667
14675
|
threadId: this.thread_id,
|
|
14668
14676
|
tenantId: this.tenant_id,
|
|
14669
14677
|
assistantId: this.assistant_id,
|
|
14678
|
+
workspaceId: this.workspace_id,
|
|
14679
|
+
projectId: this.project_id,
|
|
14670
14680
|
content,
|
|
14671
14681
|
type: pendingType,
|
|
14672
14682
|
command: queueMessage.command,
|
|
@@ -14740,6 +14750,8 @@ var Agent = class {
|
|
|
14740
14750
|
threadId: thread.threadId,
|
|
14741
14751
|
tenantId: thread.tenantId,
|
|
14742
14752
|
assistantId: thread.assistantId,
|
|
14753
|
+
workspaceId: this.workspace_id,
|
|
14754
|
+
projectId: this.project_id,
|
|
14743
14755
|
content: reminderContent,
|
|
14744
14756
|
type: "system"
|
|
14745
14757
|
});
|
|
@@ -14811,9 +14823,14 @@ var Agent = class {
|
|
|
14811
14823
|
/**
|
|
14812
14824
|
* Resume processing after a server restart.
|
|
14813
14825
|
*
|
|
14814
|
-
*
|
|
14815
|
-
*
|
|
14816
|
-
*
|
|
14826
|
+
* If the graph was mid-execution (BUSY) it resumes from the LangGraph
|
|
14827
|
+
* checkpoint without re-injecting the message — the message has already
|
|
14828
|
+
* been consumed and is in the graph state. Processing messages are removed
|
|
14829
|
+
* rather than replayed.
|
|
14830
|
+
*
|
|
14831
|
+
* Skips threads that are in `INTERRUPTED` state (the interruption was
|
|
14832
|
+
* intentional). IDLE threads simply clean up and restart the queue
|
|
14833
|
+
* processor for any remaining pending messages.
|
|
14817
14834
|
*
|
|
14818
14835
|
* Called during gateway startup to recover threads that were mid-execution
|
|
14819
14836
|
* when the server went down.
|
|
@@ -14831,9 +14848,32 @@ var Agent = class {
|
|
|
14831
14848
|
return;
|
|
14832
14849
|
}
|
|
14833
14850
|
const store = this.getQueueStore();
|
|
14834
|
-
|
|
14835
|
-
|
|
14836
|
-
|
|
14851
|
+
if (runStatus === "busy" /* BUSY */) {
|
|
14852
|
+
this.abortController = new AbortController();
|
|
14853
|
+
try {
|
|
14854
|
+
await this.resumeGraphFromCheckpoint(this.abortController.signal);
|
|
14855
|
+
const processingMessages = await store.getProcessingMessages(this.thread_id);
|
|
14856
|
+
for (const msg of processingMessages) {
|
|
14857
|
+
await store.removeMessage(msg.id);
|
|
14858
|
+
}
|
|
14859
|
+
if (processingMessages.length > 0) {
|
|
14860
|
+
console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
|
|
14861
|
+
}
|
|
14862
|
+
} catch (error) {
|
|
14863
|
+
console.error(`[Agent] Failed to resume graph for thread ${this.thread_id}:`, error);
|
|
14864
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
14865
|
+
throw error;
|
|
14866
|
+
} finally {
|
|
14867
|
+
this.abortController = null;
|
|
14868
|
+
}
|
|
14869
|
+
} else {
|
|
14870
|
+
const processingMessages = await store.getProcessingMessages(this.thread_id);
|
|
14871
|
+
for (const msg of processingMessages) {
|
|
14872
|
+
await store.removeMessage(msg.id);
|
|
14873
|
+
}
|
|
14874
|
+
if (processingMessages.length > 0) {
|
|
14875
|
+
console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
|
|
14876
|
+
}
|
|
14837
14877
|
}
|
|
14838
14878
|
await this.startQueueProcessorIfNeeded();
|
|
14839
14879
|
}
|
|
@@ -15024,7 +15064,7 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
15024
15064
|
console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
|
|
15025
15065
|
for (const threadInfo of threadsWithPending) {
|
|
15026
15066
|
try {
|
|
15027
|
-
await this.restoreThread(threadInfo
|
|
15067
|
+
await this.restoreThread(threadInfo);
|
|
15028
15068
|
stats.restored++;
|
|
15029
15069
|
} catch (error) {
|
|
15030
15070
|
console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
|
|
@@ -15042,16 +15082,14 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
15042
15082
|
* Restore a single thread
|
|
15043
15083
|
* Delegates actual recovery logic to Agent.resumeTask()
|
|
15044
15084
|
*/
|
|
15045
|
-
async restoreThread(threadInfo
|
|
15046
|
-
const { tenantId, assistantId, threadId } = threadInfo;
|
|
15085
|
+
async restoreThread(threadInfo) {
|
|
15086
|
+
const { tenantId, assistantId, threadId, workspaceId, projectId } = threadInfo;
|
|
15047
15087
|
const threadParams = {
|
|
15048
15088
|
tenant_id: tenantId,
|
|
15049
15089
|
assistant_id: assistantId,
|
|
15050
15090
|
thread_id: threadId,
|
|
15051
|
-
workspace_id:
|
|
15052
|
-
|
|
15053
|
-
project_id: "default"
|
|
15054
|
-
// TODO: Get from thread store
|
|
15091
|
+
workspace_id: workspaceId,
|
|
15092
|
+
project_id: projectId
|
|
15055
15093
|
};
|
|
15056
15094
|
const agent = this.getAgent(threadParams);
|
|
15057
15095
|
await agent.resumeTask();
|
|
@@ -15142,7 +15180,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
15142
15180
|
async (input, config) => {
|
|
15143
15181
|
const runConfig = getRunConfig(config);
|
|
15144
15182
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
15145
|
-
const taskId = (0,
|
|
15183
|
+
const taskId = (0, import_uuid3.v4)();
|
|
15146
15184
|
const executeAt = input.executeAt;
|
|
15147
15185
|
const success = await scheduleLattice.client.scheduleOnce(
|
|
15148
15186
|
taskId,
|
|
@@ -15177,7 +15215,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
15177
15215
|
async (input, config) => {
|
|
15178
15216
|
const runConfig = getRunConfig(config);
|
|
15179
15217
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
15180
|
-
const taskId = (0,
|
|
15218
|
+
const taskId = (0, import_uuid3.v4)();
|
|
15181
15219
|
const executeAt = Date.now() + input.delayMs;
|
|
15182
15220
|
const success = await scheduleLattice.client.scheduleOnce(
|
|
15183
15221
|
taskId,
|
|
@@ -15212,7 +15250,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
15212
15250
|
async (input, config) => {
|
|
15213
15251
|
const runConfig = getRunConfig(config);
|
|
15214
15252
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
15215
|
-
const taskId = (0,
|
|
15253
|
+
const taskId = (0, import_uuid3.v4)();
|
|
15216
15254
|
const success = await scheduleLattice.client.scheduleCron(
|
|
15217
15255
|
taskId,
|
|
15218
15256
|
AGENT_ADD_MESSAGE_TASK_TYPE,
|
|
@@ -15300,6 +15338,138 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
15300
15338
|
});
|
|
15301
15339
|
}
|
|
15302
15340
|
|
|
15341
|
+
// src/middlewares/taskMiddleware.ts
|
|
15342
|
+
var import_langchain56 = require("langchain");
|
|
15343
|
+
var import_zod51 = require("zod");
|
|
15344
|
+
function getRunConfig2(config) {
|
|
15345
|
+
const c = config;
|
|
15346
|
+
return c?.configurable?.runConfig ?? {};
|
|
15347
|
+
}
|
|
15348
|
+
function getTaskStore() {
|
|
15349
|
+
return getStoreLattice("default", "task").store;
|
|
15350
|
+
}
|
|
15351
|
+
var manageTaskSchema = import_zod51.z.object({
|
|
15352
|
+
action: import_zod51.z.enum(["create", "list", "update", "delete", "complete"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
|
|
15353
|
+
id: import_zod51.z.string().optional().describe("\u4EFB\u52A1 ID (update/delete/complete \u5FC5\u586B)"),
|
|
15354
|
+
title: import_zod51.z.string().optional().describe("\u4EFB\u52A1\u6807\u9898 (create \u5FC5\u586B)"),
|
|
15355
|
+
description: import_zod51.z.string().optional().describe("\u4EFB\u52A1\u63CF\u8FF0"),
|
|
15356
|
+
priority: import_zod51.z.enum(["low", "medium", "high"]).optional().describe("\u4F18\u5148\u7EA7"),
|
|
15357
|
+
status: import_zod51.z.enum(["pending", "in_progress", "completed", "cancelled"]).optional().describe("\u72B6\u6001"),
|
|
15358
|
+
dueDate: import_zod51.z.string().optional().describe("\u622A\u6B62\u65E5\u671F (ISO 8601)"),
|
|
15359
|
+
metadata: import_zod51.z.record(import_zod51.z.unknown()).optional().describe("\u7ED3\u6784\u5316\u5143\u6570\u636E (projectId, module \u7B49)"),
|
|
15360
|
+
parentId: import_zod51.z.string().optional().describe("\u7236\u4EFB\u52A1 ID (\u5B50\u4EFB\u52A1\u5173\u8054)"),
|
|
15361
|
+
sourceId: import_zod51.z.string().optional().describe("\u6765\u6E90\u4F1A\u8BDD/thread ID"),
|
|
15362
|
+
context: import_zod51.z.record(import_zod51.z.unknown()).optional().describe("\u9644\u52A0\u4E0A\u4E0B\u6587"),
|
|
15363
|
+
ownerType: import_zod51.z.enum(["user", "agent"]).optional().describe("\u6240\u6709\u8005\u7C7B\u578B\uFF0C\u4E0D\u4F20\u9ED8\u8BA4\u4E3A user"),
|
|
15364
|
+
ownerId: import_zod51.z.string().optional().describe("\u6240\u6709\u8005 ID\uFF0C\u4E0D\u4F20\u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237/Agent")
|
|
15365
|
+
});
|
|
15366
|
+
function createTaskMiddleware() {
|
|
15367
|
+
return (0, import_langchain56.createMiddleware)({
|
|
15368
|
+
name: "TaskMiddleware",
|
|
15369
|
+
contextSchema,
|
|
15370
|
+
wrapModelCall: async (request, handler) => {
|
|
15371
|
+
const taskPrompt = `## \u4EFB\u52A1\u7BA1\u7406\u80FD\u529B
|
|
15372
|
+
\u4F60\u53EF\u4EE5\u901A\u8FC7 manage_task \u5DE5\u5177\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u3002ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u884C\u4E3A\uFF1A
|
|
15373
|
+
- \u4E0D\u4F20\u53C2\u6570: \u9ED8\u8BA4\u4E3A\u5F53\u524D\u7528\u6237\u521B\u5EFA\u4EFB\u52A1 (ownerType="user", ownerId \u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237)
|
|
15374
|
+
- ownerType="agent": \u4E3A\u81EA\u5DF1\u521B\u5EFA\u6267\u884C\u5B50\u4EFB\u52A1 (ownerId \u81EA\u52A8\u53D6\u5F53\u524D Agent)
|
|
15375
|
+
- \u663E\u5F0F\u4F20 ownerId: \u4E3A\u6307\u5B9A agent/user \u521B\u5EFA\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09`;
|
|
15376
|
+
return handler({
|
|
15377
|
+
...request,
|
|
15378
|
+
systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
|
|
15379
|
+
});
|
|
15380
|
+
},
|
|
15381
|
+
tools: [
|
|
15382
|
+
(0, import_langchain56.tool)(
|
|
15383
|
+
async (input, config) => {
|
|
15384
|
+
const rc = getRunConfig2(config);
|
|
15385
|
+
const tenantId = rc.tenantId || "default";
|
|
15386
|
+
const ownerId = input.ownerId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
|
|
15387
|
+
const store = getTaskStore();
|
|
15388
|
+
switch (input.action) {
|
|
15389
|
+
case "create": {
|
|
15390
|
+
if (!input.title) {
|
|
15391
|
+
return JSON.stringify({ success: false, error: "create requires title" });
|
|
15392
|
+
}
|
|
15393
|
+
const task = await store.create({
|
|
15394
|
+
tenantId,
|
|
15395
|
+
ownerType: input.ownerType || "user",
|
|
15396
|
+
ownerId,
|
|
15397
|
+
title: input.title,
|
|
15398
|
+
description: input.description,
|
|
15399
|
+
priority: input.priority || "medium",
|
|
15400
|
+
status: input.status || "pending",
|
|
15401
|
+
dueDate: input.dueDate,
|
|
15402
|
+
metadata: input.metadata,
|
|
15403
|
+
parentId: input.parentId,
|
|
15404
|
+
sourceId: input.sourceId,
|
|
15405
|
+
context: input.context
|
|
15406
|
+
});
|
|
15407
|
+
return JSON.stringify({ success: true, data: task });
|
|
15408
|
+
}
|
|
15409
|
+
case "list": {
|
|
15410
|
+
const tasks = await store.list({
|
|
15411
|
+
tenantId,
|
|
15412
|
+
ownerType: input.ownerType,
|
|
15413
|
+
ownerId: input.ownerId,
|
|
15414
|
+
status: input.status,
|
|
15415
|
+
priority: input.priority
|
|
15416
|
+
});
|
|
15417
|
+
return JSON.stringify({ success: true, data: tasks, count: tasks.length });
|
|
15418
|
+
}
|
|
15419
|
+
case "update": {
|
|
15420
|
+
if (!input.id) {
|
|
15421
|
+
return JSON.stringify({ success: false, error: "update requires id" });
|
|
15422
|
+
}
|
|
15423
|
+
const { action, ...updates } = input;
|
|
15424
|
+
const updated = await store.update(tenantId, input.id, updates);
|
|
15425
|
+
if (!updated) {
|
|
15426
|
+
return JSON.stringify({ success: false, error: "Task not found" });
|
|
15427
|
+
}
|
|
15428
|
+
return JSON.stringify({ success: true, data: updated });
|
|
15429
|
+
}
|
|
15430
|
+
case "delete": {
|
|
15431
|
+
if (!input.id) {
|
|
15432
|
+
return JSON.stringify({ success: false, error: "delete requires id" });
|
|
15433
|
+
}
|
|
15434
|
+
const deleted = await store.delete(tenantId, input.id);
|
|
15435
|
+
return JSON.stringify({ success: deleted, message: deleted ? "Task deleted" : "Task not found" });
|
|
15436
|
+
}
|
|
15437
|
+
case "complete": {
|
|
15438
|
+
if (!input.id) {
|
|
15439
|
+
return JSON.stringify({ success: false, error: "complete requires id" });
|
|
15440
|
+
}
|
|
15441
|
+
const updated = await store.update(tenantId, input.id, { status: "completed" });
|
|
15442
|
+
if (!updated) {
|
|
15443
|
+
return JSON.stringify({ success: false, error: "Task not found" });
|
|
15444
|
+
}
|
|
15445
|
+
return JSON.stringify({ success: true, data: updated });
|
|
15446
|
+
}
|
|
15447
|
+
default:
|
|
15448
|
+
return JSON.stringify({ success: false, error: `Unknown action: ${input.action}` });
|
|
15449
|
+
}
|
|
15450
|
+
},
|
|
15451
|
+
{
|
|
15452
|
+
name: "manage_task",
|
|
15453
|
+
description: `\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u7CFB\u7EDF\u3002CRUD \u64CD\u4F5C\u7528\u6237\u548C Agent \u7684\u4EFB\u52A1\u3002
|
|
15454
|
+
|
|
15455
|
+
## ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u903B\u8F91
|
|
15456
|
+
- \u4E0D\u4F20 ownerType \u548C ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D\u7528\u6237\u521B\u5EFA\u4EFB\u52A1 (ownerType="user", ownerId \u53D6\u81EA\u5F53\u524D\u767B\u5F55\u7528\u6237)
|
|
15457
|
+
- \u4F20 ownerType="agent" \u4E0D\u4F20 ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D Agent \u521B\u5EFA\u5B50\u4EFB\u52A1
|
|
15458
|
+
- \u663E\u5F0F\u4F20 ownerId: \u7CFB\u7EDF\u4F7F\u7528\u4F60\u6307\u5B9A\u7684 ID\uFF0C\u53EF\u8DE8 Agent \u6D3E\u53D1\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09
|
|
15459
|
+
|
|
15460
|
+
## Actions
|
|
15461
|
+
- create: \u521B\u5EFA\u4EFB\u52A1 (title \u5FC5\u586B, priority/description/dueDate/metadata/parentId/context \u53EF\u9009)
|
|
15462
|
+
- list: \u5217\u51FA\u4EFB\u52A1\uFF0C\u53EF\u6309 ownerType/status/priority \u8FC7\u6EE4
|
|
15463
|
+
- update: \u66F4\u65B0\u4EFB\u52A1 (id \u5FC5\u586B\uFF0C\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5)
|
|
15464
|
+
- delete: \u5220\u9664\u4EFB\u52A1 (id \u5FC5\u586B)
|
|
15465
|
+
- complete: \u5FEB\u901F\u6807\u8BB0\u5B8C\u6210 (id \u5FC5\u586B)`,
|
|
15466
|
+
schema: manageTaskSchema
|
|
15467
|
+
}
|
|
15468
|
+
)
|
|
15469
|
+
]
|
|
15470
|
+
});
|
|
15471
|
+
}
|
|
15472
|
+
|
|
15303
15473
|
// src/agent_lattice/builders/CustomMiddlewareRegistry.ts
|
|
15304
15474
|
var CustomMiddlewareRegistry = class {
|
|
15305
15475
|
/**
|
|
@@ -15435,6 +15605,9 @@ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend, fsI
|
|
|
15435
15605
|
case "scheduler":
|
|
15436
15606
|
middlewares.push(createSchedulerMiddleware(config.config));
|
|
15437
15607
|
break;
|
|
15608
|
+
case "task":
|
|
15609
|
+
middlewares.push(createTaskMiddleware());
|
|
15610
|
+
break;
|
|
15438
15611
|
case "custom":
|
|
15439
15612
|
{
|
|
15440
15613
|
const customConfig = config.config;
|
|
@@ -15642,14 +15815,14 @@ var ReActAgentGraphBuilder = class {
|
|
|
15642
15815
|
*/
|
|
15643
15816
|
async build(agentLattice, params) {
|
|
15644
15817
|
const tools = params.tools.map((t) => {
|
|
15645
|
-
const
|
|
15646
|
-
return
|
|
15647
|
-
}).filter((
|
|
15818
|
+
const tool52 = getToolClient(t.key);
|
|
15819
|
+
return tool52;
|
|
15820
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
15648
15821
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
15649
15822
|
const middlewareConfigs = params.middleware || [];
|
|
15650
15823
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
15651
15824
|
const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend);
|
|
15652
|
-
return (0,
|
|
15825
|
+
return (0, import_langchain57.createAgent)({
|
|
15653
15826
|
model: params.model,
|
|
15654
15827
|
tools,
|
|
15655
15828
|
systemPrompt: params.prompt,
|
|
@@ -15663,11 +15836,11 @@ var ReActAgentGraphBuilder = class {
|
|
|
15663
15836
|
};
|
|
15664
15837
|
|
|
15665
15838
|
// src/deep_agent_new/agent.ts
|
|
15666
|
-
var
|
|
15839
|
+
var import_langchain61 = require("langchain");
|
|
15667
15840
|
|
|
15668
15841
|
// src/deep_agent_new/middleware/subagents.ts
|
|
15669
15842
|
var import_v32 = require("zod/v3");
|
|
15670
|
-
var
|
|
15843
|
+
var import_langchain58 = require("langchain");
|
|
15671
15844
|
var import_langgraph8 = require("@langchain/langgraph");
|
|
15672
15845
|
var import_messages2 = require("@langchain/core/messages");
|
|
15673
15846
|
|
|
@@ -15991,7 +16164,7 @@ function returnCommandWithStateUpdate(result, toolCallId) {
|
|
|
15991
16164
|
update: {
|
|
15992
16165
|
...stateUpdate,
|
|
15993
16166
|
messages: [
|
|
15994
|
-
new
|
|
16167
|
+
new import_langchain58.ToolMessage({
|
|
15995
16168
|
content: lastMessage?.content || "Task Failed to complete",
|
|
15996
16169
|
tool_call_id: toolCallId,
|
|
15997
16170
|
name: "task"
|
|
@@ -16016,10 +16189,10 @@ function getSubagents(options) {
|
|
|
16016
16189
|
const generalPurposeMiddleware = [...defaultSubagentMiddleware];
|
|
16017
16190
|
if (defaultInterruptOn) {
|
|
16018
16191
|
generalPurposeMiddleware.push(
|
|
16019
|
-
(0,
|
|
16192
|
+
(0, import_langchain58.humanInTheLoopMiddleware)({ interruptOn: defaultInterruptOn })
|
|
16020
16193
|
);
|
|
16021
16194
|
}
|
|
16022
|
-
const generalPurposeSubagent = (0,
|
|
16195
|
+
const generalPurposeSubagent = (0, import_langchain58.createAgent)({
|
|
16023
16196
|
model: defaultModel,
|
|
16024
16197
|
systemPrompt: DEFAULT_SUBAGENT_PROMPT,
|
|
16025
16198
|
tools: defaultTools,
|
|
@@ -16042,8 +16215,8 @@ function getSubagents(options) {
|
|
|
16042
16215
|
const middleware = agentParams.middleware ? [...defaultSubagentMiddleware, ...agentParams.middleware] : [...defaultSubagentMiddleware];
|
|
16043
16216
|
const interruptOn = agentParams.interruptOn || defaultInterruptOn;
|
|
16044
16217
|
if (interruptOn)
|
|
16045
|
-
middleware.push((0,
|
|
16046
|
-
agents[agentParams.key] = (0,
|
|
16218
|
+
middleware.push((0, import_langchain58.humanInTheLoopMiddleware)({ interruptOn }));
|
|
16219
|
+
agents[agentParams.key] = (0, import_langchain58.createAgent)({
|
|
16047
16220
|
model: agentParams.model ?? defaultModel,
|
|
16048
16221
|
systemPrompt: agentParams.systemPrompt,
|
|
16049
16222
|
tools: agentParams.tools ?? defaultTools,
|
|
@@ -16093,7 +16266,7 @@ function createTaskTool(options) {
|
|
|
16093
16266
|
generalPurposeAgent
|
|
16094
16267
|
});
|
|
16095
16268
|
const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
|
|
16096
|
-
return (0,
|
|
16269
|
+
return (0, import_langchain58.tool)(
|
|
16097
16270
|
async (input, config) => {
|
|
16098
16271
|
const { description, subagent_type, async } = input;
|
|
16099
16272
|
let assistant_id = subagent_type;
|
|
@@ -16127,12 +16300,16 @@ function createTaskTool(options) {
|
|
|
16127
16300
|
const subagent_thread_id = config.configurable?.thread_id + "____" + assistant_id + "_" + config.toolCall.id;
|
|
16128
16301
|
if (async) {
|
|
16129
16302
|
const tenantId = config.configurable?.runConfig?.tenantId;
|
|
16303
|
+
const workspaceId = config.configurable?.runConfig?.workspaceId;
|
|
16304
|
+
const projectId = config.configurable?.runConfig?.projectId;
|
|
16130
16305
|
const mainAssistantId = config.configurable?.runConfig?.assistant_id;
|
|
16131
16306
|
const mainThreadId = config.configurable?.runConfig?.thread_id;
|
|
16132
16307
|
const mainRuntimeAgent = agentInstanceManager.getAgent({
|
|
16133
16308
|
assistant_id: mainAssistantId,
|
|
16134
16309
|
thread_id: mainThreadId,
|
|
16135
|
-
tenant_id: tenantId
|
|
16310
|
+
tenant_id: tenantId,
|
|
16311
|
+
workspace_id: workspaceId,
|
|
16312
|
+
project_id: projectId
|
|
16136
16313
|
});
|
|
16137
16314
|
if (mainRuntimeAgent) {
|
|
16138
16315
|
mainRuntimeAgent.addAsyncTask({
|
|
@@ -16165,7 +16342,7 @@ function createTaskTool(options) {
|
|
|
16165
16342
|
return new import_langgraph8.Command({
|
|
16166
16343
|
update: {
|
|
16167
16344
|
messages: [
|
|
16168
|
-
new
|
|
16345
|
+
new import_langchain58.ToolMessage({
|
|
16169
16346
|
content: `Async task started: ${subagent_thread_id}
|
|
16170
16347
|
${description}
|
|
16171
16348
|
The result will be delivered as a notification when complete. Do not poll.`,
|
|
@@ -16198,7 +16375,7 @@ The result will be delivered as a notification when complete. Do not poll.`,
|
|
|
16198
16375
|
return new import_langgraph8.Command({
|
|
16199
16376
|
update: {
|
|
16200
16377
|
messages: [
|
|
16201
|
-
new
|
|
16378
|
+
new import_langchain58.ToolMessage({
|
|
16202
16379
|
content: error instanceof Error ? error.message : "Task Failed to complete",
|
|
16203
16380
|
tool_call_id: config.toolCall.id,
|
|
16204
16381
|
name: "task"
|
|
@@ -16238,7 +16415,7 @@ function getMainAgentFromConfig(config) {
|
|
|
16238
16415
|
});
|
|
16239
16416
|
}
|
|
16240
16417
|
function createCheckAsyncTaskTool() {
|
|
16241
|
-
return (0,
|
|
16418
|
+
return (0, import_langchain58.tool)(
|
|
16242
16419
|
async (input, config) => {
|
|
16243
16420
|
const { task_id } = input;
|
|
16244
16421
|
const mainAgent = getMainAgentFromConfig(config);
|
|
@@ -16305,7 +16482,7 @@ Description: ${cached.description}`;
|
|
|
16305
16482
|
);
|
|
16306
16483
|
}
|
|
16307
16484
|
function createListAsyncTasksTool() {
|
|
16308
|
-
return (0,
|
|
16485
|
+
return (0, import_langchain58.tool)(
|
|
16309
16486
|
async (_input, config) => {
|
|
16310
16487
|
const mainAgent = getMainAgentFromConfig(config);
|
|
16311
16488
|
if (!mainAgent) {
|
|
@@ -16356,7 +16533,7 @@ function createListAsyncTasksTool() {
|
|
|
16356
16533
|
);
|
|
16357
16534
|
}
|
|
16358
16535
|
function createCancelAsyncTaskTool() {
|
|
16359
|
-
return (0,
|
|
16536
|
+
return (0, import_langchain58.tool)(
|
|
16360
16537
|
async (input, config) => {
|
|
16361
16538
|
const { task_id } = input;
|
|
16362
16539
|
const mainAgent = getMainAgentFromConfig(config);
|
|
@@ -16432,7 +16609,7 @@ function createSubAgentMiddleware(options) {
|
|
|
16432
16609
|
);
|
|
16433
16610
|
}
|
|
16434
16611
|
const effectiveSystemPrompt = allowAsync ? systemPrompt + getAsyncPromptText() : systemPrompt;
|
|
16435
|
-
return (0,
|
|
16612
|
+
return (0, import_langchain58.createMiddleware)({
|
|
16436
16613
|
name: "subAgentMiddleware",
|
|
16437
16614
|
tools: allTools,
|
|
16438
16615
|
wrapModelCall: async (request, handler) => {
|
|
@@ -16452,11 +16629,9 @@ ${effectiveSystemPrompt}` : effectiveSystemPrompt;
|
|
|
16452
16629
|
}
|
|
16453
16630
|
|
|
16454
16631
|
// src/deep_agent_new/middleware/patch_tool_calls.ts
|
|
16455
|
-
var
|
|
16456
|
-
var import_messages3 = require("@langchain/core/messages");
|
|
16457
|
-
var import_langgraph9 = require("@langchain/langgraph");
|
|
16632
|
+
var import_langchain59 = require("langchain");
|
|
16458
16633
|
function createPatchToolCallsMiddleware() {
|
|
16459
|
-
return (0,
|
|
16634
|
+
return (0, import_langchain59.createMiddleware)({
|
|
16460
16635
|
name: "patchToolCallsMiddleware",
|
|
16461
16636
|
beforeAgent: async (state) => {
|
|
16462
16637
|
const messages = state.messages;
|
|
@@ -16467,15 +16642,15 @@ function createPatchToolCallsMiddleware() {
|
|
|
16467
16642
|
for (let i = 0; i < messages.length; i++) {
|
|
16468
16643
|
const msg = messages[i];
|
|
16469
16644
|
patchedMessages.push(msg);
|
|
16470
|
-
if (
|
|
16645
|
+
if (import_langchain59.AIMessage.isInstance(msg) && msg.tool_calls != null) {
|
|
16471
16646
|
for (const toolCall of msg.tool_calls) {
|
|
16472
16647
|
const correspondingToolMsg = messages.slice(i).find(
|
|
16473
|
-
(m) =>
|
|
16648
|
+
(m) => import_langchain59.ToolMessage.isInstance(m) && m.tool_call_id === toolCall.id
|
|
16474
16649
|
);
|
|
16475
16650
|
if (!correspondingToolMsg) {
|
|
16476
16651
|
const toolMsg = `Tool call ${toolCall.name} with id ${toolCall.id} was cancelled - another message came in before it could be completed.`;
|
|
16477
16652
|
patchedMessages.push(
|
|
16478
|
-
new
|
|
16653
|
+
new import_langchain59.ToolMessage({
|
|
16479
16654
|
content: toolMsg,
|
|
16480
16655
|
name: toolCall.name,
|
|
16481
16656
|
tool_call_id: toolCall.id
|
|
@@ -16485,11 +16660,12 @@ function createPatchToolCallsMiddleware() {
|
|
|
16485
16660
|
}
|
|
16486
16661
|
}
|
|
16487
16662
|
}
|
|
16663
|
+
if (patchedMessages.length === messages.length) {
|
|
16664
|
+
return;
|
|
16665
|
+
}
|
|
16488
16666
|
return {
|
|
16489
|
-
messages:
|
|
16490
|
-
|
|
16491
|
-
...patchedMessages
|
|
16492
|
-
]
|
|
16667
|
+
messages: patchedMessages.slice(messages.length)
|
|
16668
|
+
// only the new ToolMessage patches
|
|
16493
16669
|
};
|
|
16494
16670
|
}
|
|
16495
16671
|
});
|
|
@@ -17601,9 +17777,9 @@ var MemoryBackend = class {
|
|
|
17601
17777
|
};
|
|
17602
17778
|
|
|
17603
17779
|
// src/deep_agent_new/middleware/todos.ts
|
|
17604
|
-
var
|
|
17605
|
-
var
|
|
17606
|
-
var
|
|
17780
|
+
var import_langgraph9 = require("@langchain/langgraph");
|
|
17781
|
+
var import_zod52 = require("zod");
|
|
17782
|
+
var import_langchain60 = require("langchain");
|
|
17607
17783
|
var WRITE_TODOS_DESCRIPTION = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
|
|
17608
17784
|
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
17609
17785
|
Only use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the taks directly.
|
|
@@ -17830,20 +18006,20 @@ Writing todos takes time and tokens, use it when it is helpful for managing comp
|
|
|
17830
18006
|
## Important To-Do List Usage Notes to Remember
|
|
17831
18007
|
- The \`write_todos\` tool should never be called multiple times in parallel.
|
|
17832
18008
|
- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.`;
|
|
17833
|
-
var TodoStatus =
|
|
17834
|
-
var TodoSchema =
|
|
17835
|
-
content:
|
|
18009
|
+
var TodoStatus = import_zod52.z.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
|
|
18010
|
+
var TodoSchema = import_zod52.z.object({
|
|
18011
|
+
content: import_zod52.z.string().describe("Content of the todo item"),
|
|
17836
18012
|
status: TodoStatus
|
|
17837
18013
|
});
|
|
17838
|
-
var stateSchema =
|
|
18014
|
+
var stateSchema = import_zod52.z.object({ todos: import_zod52.z.array(TodoSchema).default([]) });
|
|
17839
18015
|
function todoListMiddleware(options) {
|
|
17840
|
-
const writeTodos = (0,
|
|
18016
|
+
const writeTodos = (0, import_langchain60.tool)(
|
|
17841
18017
|
({ todos }, config) => {
|
|
17842
|
-
return new
|
|
18018
|
+
return new import_langgraph9.Command({
|
|
17843
18019
|
update: {
|
|
17844
18020
|
todos,
|
|
17845
18021
|
messages: [
|
|
17846
|
-
new
|
|
18022
|
+
new import_langchain60.ToolMessage({
|
|
17847
18023
|
content: genUIMarkdown("todo_list", todos),
|
|
17848
18024
|
tool_call_id: config.toolCall?.id
|
|
17849
18025
|
})
|
|
@@ -17854,12 +18030,12 @@ function todoListMiddleware(options) {
|
|
|
17854
18030
|
{
|
|
17855
18031
|
name: "write_todos",
|
|
17856
18032
|
description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,
|
|
17857
|
-
schema:
|
|
17858
|
-
todos:
|
|
18033
|
+
schema: import_zod52.z.object({
|
|
18034
|
+
todos: import_zod52.z.array(TodoSchema).describe("List of todo items to update")
|
|
17859
18035
|
})
|
|
17860
18036
|
}
|
|
17861
18037
|
);
|
|
17862
|
-
return (0,
|
|
18038
|
+
return (0, import_langchain60.createMiddleware)({
|
|
17863
18039
|
name: "todoListMiddleware",
|
|
17864
18040
|
stateSchema,
|
|
17865
18041
|
tools: [writeTodos],
|
|
@@ -17911,13 +18087,13 @@ ${BASE_PROMPT}` : BASE_PROMPT;
|
|
|
17911
18087
|
backend: filesystemBackend
|
|
17912
18088
|
}),
|
|
17913
18089
|
// Subagent middleware: Automatic conversation summarization when token limits are approached
|
|
17914
|
-
(0,
|
|
18090
|
+
(0, import_langchain61.summarizationMiddleware)({
|
|
17915
18091
|
model,
|
|
17916
18092
|
trigger: { tokens: 17e4 },
|
|
17917
18093
|
keep: { messages: 6 }
|
|
17918
18094
|
}),
|
|
17919
18095
|
// Subagent middleware: Anthropic prompt caching for improved performance
|
|
17920
|
-
(0,
|
|
18096
|
+
(0, import_langchain61.anthropicPromptCachingMiddleware)({
|
|
17921
18097
|
unsupportedModelBehavior: "ignore"
|
|
17922
18098
|
}),
|
|
17923
18099
|
// Subagent middleware: Patches tool calls for compatibility
|
|
@@ -17929,23 +18105,23 @@ ${BASE_PROMPT}` : BASE_PROMPT;
|
|
|
17929
18105
|
generalPurposeAgent: true
|
|
17930
18106
|
}),
|
|
17931
18107
|
// Automatically summarizes conversation history when token limits are approached
|
|
17932
|
-
(0,
|
|
18108
|
+
(0, import_langchain61.summarizationMiddleware)({
|
|
17933
18109
|
model,
|
|
17934
18110
|
trigger: { tokens: 17e4 },
|
|
17935
18111
|
keep: { messages: 6 }
|
|
17936
18112
|
}),
|
|
17937
18113
|
// Enables Anthropic prompt caching for improved performance and reduced costs
|
|
17938
|
-
(0,
|
|
18114
|
+
(0, import_langchain61.anthropicPromptCachingMiddleware)({
|
|
17939
18115
|
unsupportedModelBehavior: "ignore"
|
|
17940
18116
|
}),
|
|
17941
18117
|
// Patches tool calls to ensure compatibility across different model providers
|
|
17942
18118
|
createPatchToolCallsMiddleware()
|
|
17943
18119
|
];
|
|
17944
18120
|
if (interruptOn) {
|
|
17945
|
-
middleware.push((0,
|
|
18121
|
+
middleware.push((0, import_langchain61.humanInTheLoopMiddleware)({ interruptOn }));
|
|
17946
18122
|
}
|
|
17947
18123
|
middleware.push(...customMiddleware);
|
|
17948
|
-
return (0,
|
|
18124
|
+
return (0, import_langchain61.createAgent)({
|
|
17949
18125
|
model,
|
|
17950
18126
|
systemPrompt: finalSystemPrompt,
|
|
17951
18127
|
tools,
|
|
@@ -17972,7 +18148,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
17972
18148
|
const tools = params.tools.map((t) => {
|
|
17973
18149
|
const toolClient = getToolClient(t.key);
|
|
17974
18150
|
return toolClient;
|
|
17975
|
-
}).filter((
|
|
18151
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
17976
18152
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
17977
18153
|
if (sa.client) {
|
|
17978
18154
|
return {
|
|
@@ -18017,7 +18193,7 @@ init_MemoryLatticeManager();
|
|
|
18017
18193
|
|
|
18018
18194
|
// src/agent_team/agent_team.ts
|
|
18019
18195
|
var import_v35 = require("zod/v3");
|
|
18020
|
-
var
|
|
18196
|
+
var import_langchain64 = require("langchain");
|
|
18021
18197
|
|
|
18022
18198
|
// src/agent_team/types.ts
|
|
18023
18199
|
var TaskStatus = /* @__PURE__ */ ((TaskStatus3) => {
|
|
@@ -18453,14 +18629,14 @@ var InMemoryMailboxStore = class {
|
|
|
18453
18629
|
|
|
18454
18630
|
// src/agent_team/middleware/team.ts
|
|
18455
18631
|
var import_v34 = require("zod/v3");
|
|
18456
|
-
var
|
|
18457
|
-
var
|
|
18458
|
-
var
|
|
18632
|
+
var import_langchain63 = require("langchain");
|
|
18633
|
+
var import_langgraph11 = require("@langchain/langgraph");
|
|
18634
|
+
var import_uuid4 = require("uuid");
|
|
18459
18635
|
|
|
18460
18636
|
// src/agent_team/middleware/teammate_tools.ts
|
|
18461
18637
|
var import_v33 = require("zod/v3");
|
|
18462
|
-
var
|
|
18463
|
-
var
|
|
18638
|
+
var import_langchain62 = require("langchain");
|
|
18639
|
+
var import_langgraph10 = require("@langchain/langgraph");
|
|
18464
18640
|
|
|
18465
18641
|
// src/agent_team/middleware/formatMessages.ts
|
|
18466
18642
|
function formatMessagesAsMarkdown(msgs) {
|
|
@@ -18484,7 +18660,7 @@ ${meta}${body}`;
|
|
|
18484
18660
|
// src/agent_team/middleware/teammate_tools.ts
|
|
18485
18661
|
function createTeammateTools(options) {
|
|
18486
18662
|
const { teamId, agentId, taskListStore, mailboxStore } = options;
|
|
18487
|
-
const claimTaskTool = (0,
|
|
18663
|
+
const claimTaskTool = (0, import_langchain62.tool)(
|
|
18488
18664
|
async (input) => {
|
|
18489
18665
|
const task = await taskListStore.claimTaskById(
|
|
18490
18666
|
teamId,
|
|
@@ -18514,7 +18690,7 @@ function createTeammateTools(options) {
|
|
|
18514
18690
|
})
|
|
18515
18691
|
}
|
|
18516
18692
|
);
|
|
18517
|
-
const completeTaskTool = (0,
|
|
18693
|
+
const completeTaskTool = (0, import_langchain62.tool)(
|
|
18518
18694
|
async (input) => {
|
|
18519
18695
|
const task = await taskListStore.completeTask(
|
|
18520
18696
|
teamId,
|
|
@@ -18541,7 +18717,7 @@ function createTeammateTools(options) {
|
|
|
18541
18717
|
})
|
|
18542
18718
|
}
|
|
18543
18719
|
);
|
|
18544
|
-
const failTaskTool = (0,
|
|
18720
|
+
const failTaskTool = (0, import_langchain62.tool)(
|
|
18545
18721
|
async (input) => {
|
|
18546
18722
|
const task = await taskListStore.failTask(
|
|
18547
18723
|
teamId,
|
|
@@ -18568,7 +18744,7 @@ function createTeammateTools(options) {
|
|
|
18568
18744
|
})
|
|
18569
18745
|
}
|
|
18570
18746
|
);
|
|
18571
|
-
const sendMessageTool = (0,
|
|
18747
|
+
const sendMessageTool = (0, import_langchain62.tool)(
|
|
18572
18748
|
async (input) => {
|
|
18573
18749
|
await mailboxStore.sendMessage(
|
|
18574
18750
|
teamId,
|
|
@@ -18606,7 +18782,7 @@ function createTeammateTools(options) {
|
|
|
18606
18782
|
read: msg.read
|
|
18607
18783
|
}));
|
|
18608
18784
|
};
|
|
18609
|
-
const readMessagesTool = (0,
|
|
18785
|
+
const readMessagesTool = (0, import_langchain62.tool)(
|
|
18610
18786
|
async (input, config) => {
|
|
18611
18787
|
const formatAndMarkAsRead = async (msgs2) => {
|
|
18612
18788
|
for (const msg of msgs2) {
|
|
@@ -18618,12 +18794,12 @@ function createTeammateTools(options) {
|
|
|
18618
18794
|
if (msgs.length > 0) {
|
|
18619
18795
|
const formatted2 = await formatAndMarkAsRead(msgs);
|
|
18620
18796
|
const relevantMsgs2 = await getRelevantMessagesForState();
|
|
18621
|
-
const toolMessage2 = new
|
|
18797
|
+
const toolMessage2 = new import_langchain62.ToolMessage({
|
|
18622
18798
|
content: formatted2,
|
|
18623
18799
|
tool_call_id: config.toolCall?.id,
|
|
18624
18800
|
name: "read_messages"
|
|
18625
18801
|
});
|
|
18626
|
-
return new
|
|
18802
|
+
return new import_langgraph10.Command({
|
|
18627
18803
|
update: { team_mailbox: relevantMsgs2, messages: [toolMessage2] }
|
|
18628
18804
|
});
|
|
18629
18805
|
}
|
|
@@ -18643,22 +18819,22 @@ function createTeammateTools(options) {
|
|
|
18643
18819
|
});
|
|
18644
18820
|
const relevantMsgs = await getRelevantMessagesForState();
|
|
18645
18821
|
if (msgs.length === 0) {
|
|
18646
|
-
const toolMessage2 = new
|
|
18822
|
+
const toolMessage2 = new import_langchain62.ToolMessage({
|
|
18647
18823
|
content: "No unread messages.",
|
|
18648
18824
|
tool_call_id: config.toolCall?.id,
|
|
18649
18825
|
name: "read_messages"
|
|
18650
18826
|
});
|
|
18651
|
-
return new
|
|
18827
|
+
return new import_langgraph10.Command({
|
|
18652
18828
|
update: { team_mailbox: relevantMsgs, messages: [toolMessage2] }
|
|
18653
18829
|
});
|
|
18654
18830
|
}
|
|
18655
18831
|
const formatted = await formatAndMarkAsRead(msgs);
|
|
18656
|
-
const toolMessage = new
|
|
18832
|
+
const toolMessage = new import_langchain62.ToolMessage({
|
|
18657
18833
|
content: formatted,
|
|
18658
18834
|
tool_call_id: config.toolCall?.id,
|
|
18659
18835
|
name: "read_messages"
|
|
18660
18836
|
});
|
|
18661
|
-
return new
|
|
18837
|
+
return new import_langgraph10.Command({
|
|
18662
18838
|
update: { team_mailbox: relevantMsgs, messages: [toolMessage] }
|
|
18663
18839
|
});
|
|
18664
18840
|
},
|
|
@@ -18668,7 +18844,7 @@ function createTeammateTools(options) {
|
|
|
18668
18844
|
schema: import_v33.z.object({})
|
|
18669
18845
|
}
|
|
18670
18846
|
);
|
|
18671
|
-
const checkTasksTool = (0,
|
|
18847
|
+
const checkTasksTool = (0, import_langchain62.tool)(
|
|
18672
18848
|
async () => {
|
|
18673
18849
|
const tasks = await taskListStore.getAllTasks(teamId);
|
|
18674
18850
|
return formatTaskSummary(tasks);
|
|
@@ -18679,7 +18855,7 @@ function createTeammateTools(options) {
|
|
|
18679
18855
|
schema: import_v33.z.object({})
|
|
18680
18856
|
}
|
|
18681
18857
|
);
|
|
18682
|
-
const broadcastMessageTool = (0,
|
|
18858
|
+
const broadcastMessageTool = (0, import_langchain62.tool)(
|
|
18683
18859
|
async (input) => {
|
|
18684
18860
|
const allAgents = await mailboxStore.getRegisteredAgents(teamId);
|
|
18685
18861
|
const recipients = allAgents.filter((a) => a !== agentId);
|
|
@@ -18865,7 +19041,7 @@ You have access to these tools:
|
|
|
18865
19041
|
- \`read_messages\`: Read messages from team_lead or teammates
|
|
18866
19042
|
- \`check_tasks\`: Get current status of all tasks in the team`;
|
|
18867
19043
|
const assistantId = getTeammateAssistantId(ctx.teamId, spec.name);
|
|
18868
|
-
agent = (0,
|
|
19044
|
+
agent = (0, import_langchain63.createAgent)({
|
|
18869
19045
|
model: spec.model ?? ctx.defaultModel,
|
|
18870
19046
|
systemPrompt: teammatePrompt,
|
|
18871
19047
|
tools: allTools,
|
|
@@ -18934,19 +19110,19 @@ async function spawnTeammate(options) {
|
|
|
18934
19110
|
function createTeamMiddleware(options) {
|
|
18935
19111
|
const { teamConfig, taskListStore, mailboxStore, tenantId } = options;
|
|
18936
19112
|
const defaultModel = teamConfig.model ?? "claude-sonnet-4-5-20250929";
|
|
18937
|
-
const createTeamTool = (0,
|
|
19113
|
+
const createTeamTool = (0, import_langchain63.tool)(
|
|
18938
19114
|
async (input, config) => {
|
|
18939
|
-
const state = (0,
|
|
19115
|
+
const state = (0, import_langgraph11.getCurrentTaskInput)();
|
|
18940
19116
|
if (state?.team?.teamId) {
|
|
18941
19117
|
const existingId = state.team.teamId;
|
|
18942
|
-
const msg = new
|
|
19118
|
+
const msg = new import_langchain63.ToolMessage({
|
|
18943
19119
|
content: `A team is already active (id: ${existingId}). Use this team_id for \`check_tasks\`, \`read_messages\`, \`add_tasks\`, \`send_message\`, \`assign_task\`, \`set_task_status\`, and \`set_task_dependencies\`. Do not call \`create_team\` again unless you need a fresh team for a new objective.`,
|
|
18944
19120
|
tool_call_id: config.toolCall?.id,
|
|
18945
19121
|
name: "create_team"
|
|
18946
19122
|
});
|
|
18947
19123
|
return msg;
|
|
18948
19124
|
}
|
|
18949
|
-
const teamId = (0,
|
|
19125
|
+
const teamId = (0, import_uuid4.v4)();
|
|
18950
19126
|
const createdTasks = await taskListStore.addTasks(
|
|
18951
19127
|
teamId,
|
|
18952
19128
|
input.tasks.map((t) => ({
|
|
@@ -19028,7 +19204,7 @@ Teammates are now working in the background. Keep calling \`check_tasks\` and \`
|
|
|
19028
19204
|
\`\`\`json
|
|
19029
19205
|
${teamJson}
|
|
19030
19206
|
\`\`\``;
|
|
19031
|
-
const toolMessage = new
|
|
19207
|
+
const toolMessage = new import_langchain63.ToolMessage({
|
|
19032
19208
|
content: summary,
|
|
19033
19209
|
tool_call_id: config.toolCall?.id,
|
|
19034
19210
|
name: "create_team"
|
|
@@ -19049,7 +19225,7 @@ ${teamJson}
|
|
|
19049
19225
|
})),
|
|
19050
19226
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
19051
19227
|
};
|
|
19052
|
-
return new
|
|
19228
|
+
return new import_langgraph11.Command({
|
|
19053
19229
|
update: { team: teamState, messages: [toolMessage] }
|
|
19054
19230
|
});
|
|
19055
19231
|
},
|
|
@@ -19109,11 +19285,11 @@ After calling create_team, you MUST:
|
|
|
19109
19285
|
}
|
|
19110
19286
|
);
|
|
19111
19287
|
const resolveTeamId = () => {
|
|
19112
|
-
const state = (0,
|
|
19288
|
+
const state = (0, import_langgraph11.getCurrentTaskInput)();
|
|
19113
19289
|
if (state?.team?.teamId) return state.team.teamId;
|
|
19114
19290
|
throw new Error("No team_id provided and no team in state. Call create_team first.");
|
|
19115
19291
|
};
|
|
19116
|
-
const addTasksTool = (0,
|
|
19292
|
+
const addTasksTool = (0, import_langchain63.tool)(
|
|
19117
19293
|
async (input, config) => {
|
|
19118
19294
|
const teamId = resolveTeamId();
|
|
19119
19295
|
const created = await taskListStore.addTasks(
|
|
@@ -19127,7 +19303,7 @@ After calling create_team, you MUST:
|
|
|
19127
19303
|
}))
|
|
19128
19304
|
);
|
|
19129
19305
|
const summary = created.map((t) => `- ${t.id}: "${t.title}"`).join("\n");
|
|
19130
|
-
return new
|
|
19306
|
+
return new import_langchain63.ToolMessage({
|
|
19131
19307
|
content: `Added ${created.length} task(s) to team ${teamId}:
|
|
19132
19308
|
${summary}
|
|
19133
19309
|
Sleeping teammates will wake up and claim these.`,
|
|
@@ -19178,20 +19354,20 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
19178
19354
|
})
|
|
19179
19355
|
}
|
|
19180
19356
|
);
|
|
19181
|
-
const assignTaskTool = (0,
|
|
19357
|
+
const assignTaskTool = (0, import_langchain63.tool)(
|
|
19182
19358
|
async (input, config) => {
|
|
19183
19359
|
const teamId = resolveTeamId();
|
|
19184
19360
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
19185
19361
|
assignee: input.assignee
|
|
19186
19362
|
});
|
|
19187
19363
|
if (!task) {
|
|
19188
|
-
return new
|
|
19364
|
+
return new import_langchain63.ToolMessage({
|
|
19189
19365
|
content: `Task ${input.task_id} not found in team ${teamId}.`,
|
|
19190
19366
|
tool_call_id: config.toolCall?.id,
|
|
19191
19367
|
name: "assign_task"
|
|
19192
19368
|
});
|
|
19193
19369
|
}
|
|
19194
|
-
return new
|
|
19370
|
+
return new import_langchain63.ToolMessage({
|
|
19195
19371
|
content: `Task "${task.title}" (${task.id}) assigned to ${input.assignee}.`,
|
|
19196
19372
|
tool_call_id: config.toolCall?.id,
|
|
19197
19373
|
name: "assign_task"
|
|
@@ -19206,20 +19382,20 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
19206
19382
|
})
|
|
19207
19383
|
}
|
|
19208
19384
|
);
|
|
19209
|
-
const setTaskStatusTool = (0,
|
|
19385
|
+
const setTaskStatusTool = (0, import_langchain63.tool)(
|
|
19210
19386
|
async (input, config) => {
|
|
19211
19387
|
const teamId = resolveTeamId();
|
|
19212
19388
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
19213
19389
|
status: input.status
|
|
19214
19390
|
});
|
|
19215
19391
|
if (!task) {
|
|
19216
|
-
return new
|
|
19392
|
+
return new import_langchain63.ToolMessage({
|
|
19217
19393
|
content: `Task ${input.task_id} not found in team ${teamId}.`,
|
|
19218
19394
|
tool_call_id: config.toolCall?.id,
|
|
19219
19395
|
name: "set_task_status"
|
|
19220
19396
|
});
|
|
19221
19397
|
}
|
|
19222
|
-
return new
|
|
19398
|
+
return new import_langchain63.ToolMessage({
|
|
19223
19399
|
content: `Task "${task.title}" (${task.id}) status set to ${input.status}.`,
|
|
19224
19400
|
tool_call_id: config.toolCall?.id,
|
|
19225
19401
|
name: "set_task_status"
|
|
@@ -19234,20 +19410,20 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
19234
19410
|
})
|
|
19235
19411
|
}
|
|
19236
19412
|
);
|
|
19237
|
-
const setTaskDependenciesTool = (0,
|
|
19413
|
+
const setTaskDependenciesTool = (0, import_langchain63.tool)(
|
|
19238
19414
|
async (input, config) => {
|
|
19239
19415
|
const teamId = resolveTeamId();
|
|
19240
19416
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
19241
19417
|
dependencies: input.dependencies
|
|
19242
19418
|
});
|
|
19243
19419
|
if (!task) {
|
|
19244
|
-
return new
|
|
19420
|
+
return new import_langchain63.ToolMessage({
|
|
19245
19421
|
content: `Task ${input.task_id} not found in team ${teamId}.`,
|
|
19246
19422
|
tool_call_id: config.toolCall?.id,
|
|
19247
19423
|
name: "set_task_dependencies"
|
|
19248
19424
|
});
|
|
19249
19425
|
}
|
|
19250
|
-
return new
|
|
19426
|
+
return new import_langchain63.ToolMessage({
|
|
19251
19427
|
content: `Task "${task.title}" (${task.id}) dependencies set to [${input.dependencies.join(", ")}].`,
|
|
19252
19428
|
tool_call_id: config.toolCall?.id,
|
|
19253
19429
|
name: "set_task_dependencies"
|
|
@@ -19262,16 +19438,16 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
19262
19438
|
})
|
|
19263
19439
|
}
|
|
19264
19440
|
);
|
|
19265
|
-
const checkTasksTool = (0,
|
|
19441
|
+
const checkTasksTool = (0, import_langchain63.tool)(
|
|
19266
19442
|
async (input, config) => {
|
|
19267
19443
|
const teamId = resolveTeamId();
|
|
19268
19444
|
const tasks = await taskListStore.getAllTasks(teamId);
|
|
19269
19445
|
const tasksSnapshot = tasks;
|
|
19270
|
-
return new
|
|
19446
|
+
return new import_langgraph11.Command({
|
|
19271
19447
|
update: {
|
|
19272
19448
|
tasks: tasksSnapshot,
|
|
19273
19449
|
messages: [
|
|
19274
|
-
new
|
|
19450
|
+
new import_langchain63.ToolMessage({
|
|
19275
19451
|
content: formatTaskSummary(tasks),
|
|
19276
19452
|
tool_call_id: config.toolCall?.id,
|
|
19277
19453
|
name: "check_tasks"
|
|
@@ -19307,7 +19483,7 @@ Task Status Values:
|
|
|
19307
19483
|
})
|
|
19308
19484
|
}
|
|
19309
19485
|
);
|
|
19310
|
-
const sendMessageTool = (0,
|
|
19486
|
+
const sendMessageTool = (0, import_langchain63.tool)(
|
|
19311
19487
|
async (input, config) => {
|
|
19312
19488
|
const teamId = resolveTeamId();
|
|
19313
19489
|
await mailboxStore.sendMessage(
|
|
@@ -19317,7 +19493,7 @@ Task Status Values:
|
|
|
19317
19493
|
input.content,
|
|
19318
19494
|
"direct_message" /* DIRECT_MESSAGE */
|
|
19319
19495
|
);
|
|
19320
|
-
return new
|
|
19496
|
+
return new import_langchain63.ToolMessage({
|
|
19321
19497
|
content: `Message sent to ${input.to}.`,
|
|
19322
19498
|
tool_call_id: config.toolCall?.id,
|
|
19323
19499
|
name: "send_message"
|
|
@@ -19332,7 +19508,7 @@ Task Status Values:
|
|
|
19332
19508
|
})
|
|
19333
19509
|
}
|
|
19334
19510
|
);
|
|
19335
|
-
const readMessagesTool = (0,
|
|
19511
|
+
const readMessagesTool = (0, import_langchain63.tool)(
|
|
19336
19512
|
async (input, config) => {
|
|
19337
19513
|
const teamId = resolveTeamId();
|
|
19338
19514
|
const formatAndMarkAsRead = async (msgs2) => {
|
|
@@ -19360,12 +19536,12 @@ Task Status Values:
|
|
|
19360
19536
|
if (msgs.length > 0) {
|
|
19361
19537
|
const formatted2 = await formatAndMarkAsRead(msgs);
|
|
19362
19538
|
const allTeamMessages2 = await getAllTeamMessagesForState();
|
|
19363
|
-
const toolMessage2 = new
|
|
19539
|
+
const toolMessage2 = new import_langchain63.ToolMessage({
|
|
19364
19540
|
content: formatted2,
|
|
19365
19541
|
tool_call_id: config.toolCall?.id,
|
|
19366
19542
|
name: "read_messages"
|
|
19367
19543
|
});
|
|
19368
|
-
return new
|
|
19544
|
+
return new import_langgraph11.Command({
|
|
19369
19545
|
update: { team_mailbox: allTeamMessages2, messages: [toolMessage2] }
|
|
19370
19546
|
});
|
|
19371
19547
|
}
|
|
@@ -19392,22 +19568,22 @@ Task Status Values:
|
|
|
19392
19568
|
);
|
|
19393
19569
|
const allTeamMessages = await getAllTeamMessagesForState();
|
|
19394
19570
|
if (msgs.length === 0) {
|
|
19395
|
-
const toolMessage2 = new
|
|
19571
|
+
const toolMessage2 = new import_langchain63.ToolMessage({
|
|
19396
19572
|
content: "No unread messages from teammates.",
|
|
19397
19573
|
tool_call_id: config.toolCall?.id,
|
|
19398
19574
|
name: "read_messages"
|
|
19399
19575
|
});
|
|
19400
|
-
return new
|
|
19576
|
+
return new import_langgraph11.Command({
|
|
19401
19577
|
update: { team_mailbox: allTeamMessages, messages: [toolMessage2] }
|
|
19402
19578
|
});
|
|
19403
19579
|
}
|
|
19404
19580
|
const formatted = await formatAndMarkAsRead(msgs);
|
|
19405
|
-
const toolMessage = new
|
|
19581
|
+
const toolMessage = new import_langchain63.ToolMessage({
|
|
19406
19582
|
content: formatted,
|
|
19407
19583
|
tool_call_id: config.toolCall?.id,
|
|
19408
19584
|
name: "read_messages"
|
|
19409
19585
|
});
|
|
19410
|
-
return new
|
|
19586
|
+
return new import_langgraph11.Command({
|
|
19411
19587
|
update: { team_mailbox: allTeamMessages, messages: [toolMessage] }
|
|
19412
19588
|
});
|
|
19413
19589
|
},
|
|
@@ -19419,7 +19595,7 @@ Task Status Values:
|
|
|
19419
19595
|
})
|
|
19420
19596
|
}
|
|
19421
19597
|
);
|
|
19422
|
-
const disbandTeamTool = (0,
|
|
19598
|
+
const disbandTeamTool = (0, import_langchain63.tool)(
|
|
19423
19599
|
async (input, config) => {
|
|
19424
19600
|
const teamId = resolveTeamId();
|
|
19425
19601
|
await mailboxStore.broadcastMessage(
|
|
@@ -19429,7 +19605,7 @@ Task Status Values:
|
|
|
19429
19605
|
"shutdown_request" /* SHUTDOWN_REQUEST */
|
|
19430
19606
|
);
|
|
19431
19607
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
19432
|
-
return new
|
|
19608
|
+
return new import_langchain63.ToolMessage({
|
|
19433
19609
|
content: `Team ${teamId} has been disbanded. All teammates notified and resources cleaned up.`,
|
|
19434
19610
|
tool_call_id: config.toolCall?.id,
|
|
19435
19611
|
name: "disband_team"
|
|
@@ -19440,7 +19616,7 @@ Task Status Values:
|
|
|
19440
19616
|
description: "Disband a team when all work is done. Before calling: (1) Call check_tasks to verify no tasks are still pending/in_progress; (2) if any are, discuss with the team via read_messages and broadcast_message/send_message whether to continue or stop/cancel them; (3) only after alignment (all tasks completed/failed or explicitly stopped), then call this tool. This will: 1) Send a shutdown message to all teammates, 2) Wait briefly for them to clean up, 3) Clear all tasks and messages. Omit team_id to use the active team from state."
|
|
19441
19617
|
}
|
|
19442
19618
|
);
|
|
19443
|
-
const broadcastMessageTool = (0,
|
|
19619
|
+
const broadcastMessageTool = (0, import_langchain63.tool)(
|
|
19444
19620
|
async (input, config) => {
|
|
19445
19621
|
const teamId = resolveTeamId();
|
|
19446
19622
|
await mailboxStore.broadcastMessage(
|
|
@@ -19449,7 +19625,7 @@ Task Status Values:
|
|
|
19449
19625
|
input.content,
|
|
19450
19626
|
"broadcast" /* BROADCAST */
|
|
19451
19627
|
);
|
|
19452
|
-
return new
|
|
19628
|
+
return new import_langchain63.ToolMessage({
|
|
19453
19629
|
content: `Broadcast message sent to all teammates.`,
|
|
19454
19630
|
tool_call_id: config.toolCall?.id,
|
|
19455
19631
|
name: "broadcast_message"
|
|
@@ -19463,7 +19639,7 @@ Task Status Values:
|
|
|
19463
19639
|
})
|
|
19464
19640
|
}
|
|
19465
19641
|
);
|
|
19466
|
-
return (0,
|
|
19642
|
+
return (0, import_langchain63.createMiddleware)({
|
|
19467
19643
|
name: "teamMiddleware",
|
|
19468
19644
|
tools: [
|
|
19469
19645
|
createTeamTool,
|
|
@@ -19572,7 +19748,7 @@ function createAgentTeam(config) {
|
|
|
19572
19748
|
];
|
|
19573
19749
|
const systemPrompt = config.systemPrompt + "\n\n" + TEAM_LEAD_BASE_PROMPT;
|
|
19574
19750
|
const stateSchema2 = createReactAgentSchema(TEAM_STATE_SCHEMA);
|
|
19575
|
-
return (0,
|
|
19751
|
+
return (0, import_langchain64.createAgent)({
|
|
19576
19752
|
model: config.model ?? "claude-sonnet-4-5-20250929",
|
|
19577
19753
|
systemPrompt,
|
|
19578
19754
|
tools: [],
|
|
@@ -19602,7 +19778,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
19602
19778
|
const tools = params.tools.map((t) => {
|
|
19603
19779
|
const toolClient = getToolClient(t.key);
|
|
19604
19780
|
return toolClient;
|
|
19605
|
-
}).filter((
|
|
19781
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
19606
19782
|
const teammates = params.subAgents.map((sa) => {
|
|
19607
19783
|
const baseConfig = sa.config;
|
|
19608
19784
|
return {
|
|
@@ -19640,17 +19816,17 @@ var TeamAgentGraphBuilder = class {
|
|
|
19640
19816
|
};
|
|
19641
19817
|
|
|
19642
19818
|
// src/deep_agent_new/processing_agent.ts
|
|
19643
|
-
var
|
|
19819
|
+
var import_langchain67 = require("langchain");
|
|
19644
19820
|
|
|
19645
19821
|
// src/middlewares/topologyMiddleware.ts
|
|
19646
|
-
var import_langchain64 = require("langchain");
|
|
19647
|
-
var import_messages4 = require("@langchain/core/messages");
|
|
19648
19822
|
var import_langchain65 = require("langchain");
|
|
19649
|
-
var
|
|
19650
|
-
var
|
|
19651
|
-
var
|
|
19652
|
-
|
|
19653
|
-
|
|
19823
|
+
var import_messages3 = require("@langchain/core/messages");
|
|
19824
|
+
var import_langchain66 = require("langchain");
|
|
19825
|
+
var import_zod53 = require("zod");
|
|
19826
|
+
var import_langgraph12 = require("@langchain/langgraph");
|
|
19827
|
+
var CompletedEdgeSchema = import_zod53.z.object({
|
|
19828
|
+
to: import_zod53.z.string(),
|
|
19829
|
+
purpose: import_zod53.z.string()
|
|
19654
19830
|
});
|
|
19655
19831
|
function deriveCompletedEdges(messages, edges) {
|
|
19656
19832
|
const completedToolCallIds = /* @__PURE__ */ new Set();
|
|
@@ -19677,16 +19853,16 @@ function deriveCompletedEdges(messages, edges) {
|
|
|
19677
19853
|
}
|
|
19678
19854
|
function createTopologyMiddleware(options) {
|
|
19679
19855
|
const { edges, trackingStore } = options;
|
|
19680
|
-
return (0,
|
|
19856
|
+
return (0, import_langchain65.createMiddleware)({
|
|
19681
19857
|
name: "TopologyMiddleware",
|
|
19682
|
-
contextSchema:
|
|
19683
|
-
runConfig:
|
|
19858
|
+
contextSchema: import_zod53.z.object({
|
|
19859
|
+
runConfig: import_zod53.z.any()
|
|
19684
19860
|
}),
|
|
19685
|
-
stateSchema:
|
|
19686
|
-
currentAgentId:
|
|
19687
|
-
completedEdges:
|
|
19688
|
-
runId:
|
|
19689
|
-
stepIdMap:
|
|
19861
|
+
stateSchema: import_zod53.z.object({
|
|
19862
|
+
currentAgentId: import_zod53.z.string().default(""),
|
|
19863
|
+
completedEdges: import_zod53.z.array(CompletedEdgeSchema).default([]),
|
|
19864
|
+
runId: import_zod53.z.string().default(""),
|
|
19865
|
+
stepIdMap: import_zod53.z.record(import_zod53.z.string()).default({})
|
|
19690
19866
|
}),
|
|
19691
19867
|
beforeAgent: async (state, runtime) => {
|
|
19692
19868
|
if (state.runId) {
|
|
@@ -19737,14 +19913,14 @@ ${request.systemPrompt}` : topologyPrompt;
|
|
|
19737
19913
|
return handler({ ...request, systemPrompt: newSystemPrompt });
|
|
19738
19914
|
},
|
|
19739
19915
|
tools: [
|
|
19740
|
-
(0,
|
|
19916
|
+
(0, import_langchain66.tool)(
|
|
19741
19917
|
async (_input) => {
|
|
19742
19918
|
return "placeholder";
|
|
19743
19919
|
},
|
|
19744
19920
|
{
|
|
19745
19921
|
name: "read_topo_progress",
|
|
19746
19922
|
description: "Check the current progress of the workflow execution plan. Returns which steps have been completed and which are still pending.",
|
|
19747
|
-
schema:
|
|
19923
|
+
schema: import_zod53.z.object({})
|
|
19748
19924
|
}
|
|
19749
19925
|
)
|
|
19750
19926
|
],
|
|
@@ -19759,7 +19935,7 @@ ${request.systemPrompt}` : topologyPrompt;
|
|
|
19759
19935
|
status: doneSet.has(e.to) ? "done" : "pending"
|
|
19760
19936
|
}));
|
|
19761
19937
|
const doneCount = completedEdges.length;
|
|
19762
|
-
return new
|
|
19938
|
+
return new import_messages3.ToolMessage({
|
|
19763
19939
|
content: JSON.stringify(
|
|
19764
19940
|
{
|
|
19765
19941
|
currentAgentId,
|
|
@@ -19777,7 +19953,7 @@ ${request.systemPrompt}` : topologyPrompt;
|
|
|
19777
19953
|
try {
|
|
19778
19954
|
return await handler(request);
|
|
19779
19955
|
} catch (error) {
|
|
19780
|
-
if (error instanceof
|
|
19956
|
+
if (error instanceof import_langgraph12.GraphInterrupt) {
|
|
19781
19957
|
throw error;
|
|
19782
19958
|
}
|
|
19783
19959
|
throw error;
|
|
@@ -19824,7 +20000,7 @@ ${request.systemPrompt}` : topologyPrompt;
|
|
|
19824
20000
|
];
|
|
19825
20001
|
return {
|
|
19826
20002
|
messages: [
|
|
19827
|
-
new
|
|
20003
|
+
new import_messages3.AIMessage({
|
|
19828
20004
|
content: [
|
|
19829
20005
|
`Task rejected: topology violation.`,
|
|
19830
20006
|
`Agent "${currentAgentId}" is not allowed to delegate to "${targetAgent}".`,
|
|
@@ -19966,13 +20142,13 @@ ${BASE_PROMPT2}` : BASE_PROMPT2;
|
|
|
19966
20142
|
backend: filesystemBackend
|
|
19967
20143
|
}),
|
|
19968
20144
|
// Subagent middleware: Automatic conversation summarization
|
|
19969
|
-
(0,
|
|
20145
|
+
(0, import_langchain67.summarizationMiddleware)({
|
|
19970
20146
|
model,
|
|
19971
20147
|
trigger: { tokens: 17e4 },
|
|
19972
20148
|
keep: { messages: 6 }
|
|
19973
20149
|
}),
|
|
19974
20150
|
// Subagent middleware: Anthropic prompt caching
|
|
19975
|
-
(0,
|
|
20151
|
+
(0, import_langchain67.anthropicPromptCachingMiddleware)({
|
|
19976
20152
|
unsupportedModelBehavior: "ignore"
|
|
19977
20153
|
}),
|
|
19978
20154
|
// Subagent middleware: Patches tool calls
|
|
@@ -19985,23 +20161,23 @@ ${BASE_PROMPT2}` : BASE_PROMPT2;
|
|
|
19985
20161
|
allowAsync: false
|
|
19986
20162
|
}),
|
|
19987
20163
|
// Automatically summarizes conversation history
|
|
19988
|
-
(0,
|
|
20164
|
+
(0, import_langchain67.summarizationMiddleware)({
|
|
19989
20165
|
model,
|
|
19990
20166
|
trigger: { tokens: 17e4 },
|
|
19991
20167
|
keep: { messages: 6 }
|
|
19992
20168
|
}),
|
|
19993
20169
|
// Enables Anthropic prompt caching
|
|
19994
|
-
(0,
|
|
20170
|
+
(0, import_langchain67.anthropicPromptCachingMiddleware)({
|
|
19995
20171
|
unsupportedModelBehavior: "ignore"
|
|
19996
20172
|
}),
|
|
19997
20173
|
// Patches tool calls
|
|
19998
20174
|
createPatchToolCallsMiddleware()
|
|
19999
20175
|
];
|
|
20000
20176
|
if (interruptOn) {
|
|
20001
|
-
middleware.push((0,
|
|
20177
|
+
middleware.push((0, import_langchain67.humanInTheLoopMiddleware)({ interruptOn }));
|
|
20002
20178
|
}
|
|
20003
20179
|
middleware.push(...customMiddleware);
|
|
20004
|
-
return (0,
|
|
20180
|
+
return (0, import_langchain67.createAgent)({
|
|
20005
20181
|
model,
|
|
20006
20182
|
systemPrompt: finalSystemPrompt,
|
|
20007
20183
|
tools,
|
|
@@ -20021,7 +20197,7 @@ var ProcessingAgentGraphBuilder = class {
|
|
|
20021
20197
|
const tools = params.tools.map((t) => {
|
|
20022
20198
|
const toolClient = getToolClient(t.key);
|
|
20023
20199
|
return toolClient;
|
|
20024
|
-
}).filter((
|
|
20200
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
20025
20201
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
20026
20202
|
if (sa.client) {
|
|
20027
20203
|
return {
|
|
@@ -20067,11 +20243,11 @@ var ProcessingAgentGraphBuilder = class {
|
|
|
20067
20243
|
};
|
|
20068
20244
|
|
|
20069
20245
|
// src/agent_lattice/builders/RemoteAgentGraphBuilder.ts
|
|
20070
|
-
var
|
|
20071
|
-
var
|
|
20246
|
+
var import_langgraph13 = require("@langchain/langgraph");
|
|
20247
|
+
var import_messages4 = require("@langchain/core/messages");
|
|
20072
20248
|
|
|
20073
20249
|
// src/services/a2a-client.ts
|
|
20074
|
-
var
|
|
20250
|
+
var import_uuid5 = require("uuid");
|
|
20075
20251
|
var A2ARemoteError = class extends Error {
|
|
20076
20252
|
constructor(message, statusCode, body) {
|
|
20077
20253
|
super(message);
|
|
@@ -20118,7 +20294,7 @@ var A2ARemoteClient = class {
|
|
|
20118
20294
|
*/
|
|
20119
20295
|
async sendMessage(text) {
|
|
20120
20296
|
await this.resolve();
|
|
20121
|
-
const taskId = (0,
|
|
20297
|
+
const taskId = (0, import_uuid5.v4)();
|
|
20122
20298
|
const body = JSON.stringify({
|
|
20123
20299
|
jsonrpc: "2.0",
|
|
20124
20300
|
method: "tasks/send",
|
|
@@ -20244,7 +20420,7 @@ var RemoteAgentGraphBuilder = class {
|
|
|
20244
20420
|
if (!text) {
|
|
20245
20421
|
return {
|
|
20246
20422
|
messages: [
|
|
20247
|
-
new
|
|
20423
|
+
new import_messages4.AIMessage("No text input provided to remote agent.")
|
|
20248
20424
|
]
|
|
20249
20425
|
};
|
|
20250
20426
|
}
|
|
@@ -20255,18 +20431,18 @@ User request:
|
|
|
20255
20431
|
${text}` : text;
|
|
20256
20432
|
const response = await client.sendMessage(fullPrompt);
|
|
20257
20433
|
return {
|
|
20258
|
-
messages: [new
|
|
20434
|
+
messages: [new import_messages4.AIMessage(response)]
|
|
20259
20435
|
};
|
|
20260
20436
|
} catch (error) {
|
|
20261
20437
|
const msg = error.message ?? String(error);
|
|
20262
20438
|
return {
|
|
20263
20439
|
messages: [
|
|
20264
|
-
new
|
|
20440
|
+
new import_messages4.AIMessage(`Remote A2A agent error: ${msg}`)
|
|
20265
20441
|
]
|
|
20266
20442
|
};
|
|
20267
20443
|
}
|
|
20268
20444
|
};
|
|
20269
|
-
const workflow = new
|
|
20445
|
+
const workflow = new import_langgraph13.StateGraph(import_langgraph13.MessagesAnnotation).addNode("remote_call", remoteCallNode).addEdge("__start__", "remote_call").addEdge("remote_call", "__end__");
|
|
20270
20446
|
return workflow.compile();
|
|
20271
20447
|
}
|
|
20272
20448
|
};
|
|
@@ -20288,7 +20464,7 @@ function extractLastHumanMessage(messages) {
|
|
|
20288
20464
|
}
|
|
20289
20465
|
|
|
20290
20466
|
// src/agent_lattice/builders/WorkflowAgentGraphBuilder.ts
|
|
20291
|
-
var
|
|
20467
|
+
var import_langchain68 = require("langchain");
|
|
20292
20468
|
init_MemoryLatticeManager();
|
|
20293
20469
|
var import_protocols10 = require("@axiom-lattice/protocols");
|
|
20294
20470
|
init_compile();
|
|
@@ -20301,26 +20477,26 @@ var WorkflowAgentGraphBuilder = class {
|
|
|
20301
20477
|
);
|
|
20302
20478
|
}
|
|
20303
20479
|
const config = agentLattice.config;
|
|
20304
|
-
const
|
|
20480
|
+
const yaml2 = config.workflowYaml;
|
|
20305
20481
|
const tenantId = agentLattice.config.tenantId ?? "default";
|
|
20306
20482
|
const checkpointer = getCheckpointSaver("default");
|
|
20307
20483
|
const tools = params.tools.map((t) => t.executor).filter(Boolean);
|
|
20308
20484
|
const middlewareConfigs = params.middleware || [];
|
|
20309
20485
|
const middlewares = await createCommonMiddlewares(middlewareConfigs, void 0, false);
|
|
20310
|
-
const
|
|
20486
|
+
const askMiddlewares = await createCommonMiddlewares([
|
|
20311
20487
|
{
|
|
20312
20488
|
id: "ask_user_to_clarify",
|
|
20313
20489
|
type: "ask_user_to_clarify",
|
|
20314
20490
|
name: "Ask User Clarify",
|
|
20315
|
-
description: "For
|
|
20491
|
+
description: "For workflow steps requiring user interaction",
|
|
20316
20492
|
enabled: true,
|
|
20317
20493
|
config: {}
|
|
20318
20494
|
}
|
|
20319
20495
|
], void 0, false);
|
|
20320
20496
|
const noWrapMiddlewares = middlewares.filter((m) => !m.wrapModelCall);
|
|
20321
|
-
const
|
|
20497
|
+
const noWrapAskMiddlewares = askMiddlewares.filter((m) => !m.wrapModelCall);
|
|
20322
20498
|
console.log(`[WF BUILDER] building default agent | toolCount=${tools.length} | middlewareCount=${middlewares.length}`);
|
|
20323
|
-
const defaultAgent = (0,
|
|
20499
|
+
const defaultAgent = (0, import_langchain68.createAgent)({
|
|
20324
20500
|
model: params.model,
|
|
20325
20501
|
tools,
|
|
20326
20502
|
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
@@ -20334,34 +20510,34 @@ var WorkflowAgentGraphBuilder = class {
|
|
|
20334
20510
|
console.log(`[WF BUILDER] resolveAgent: looking up ref="${ref}"`);
|
|
20335
20511
|
return await getAgentClientAsync(tenantId, ref);
|
|
20336
20512
|
}
|
|
20337
|
-
const
|
|
20513
|
+
const isAsk = stepType === "ask";
|
|
20338
20514
|
if (responseFormat) {
|
|
20339
|
-
const key = (
|
|
20515
|
+
const key = (isAsk ? "ask:" : "agent:") + JSON.stringify(responseFormat);
|
|
20340
20516
|
console.log(`[WF BUILDER] resolveAgent: cacheKey=${key.slice(0, 80)}... | cached=${agentCache.has(key)}`);
|
|
20341
20517
|
if (!agentCache.has(key)) {
|
|
20342
|
-
console.log(`[WF BUILDER] creating ${
|
|
20343
|
-
const agent = (0,
|
|
20518
|
+
console.log(`[WF BUILDER] creating ${isAsk ? "ask" : "agent"} with responseFormat`);
|
|
20519
|
+
const agent = (0, import_langchain68.createAgent)({
|
|
20344
20520
|
model: params.model,
|
|
20345
20521
|
tools,
|
|
20346
20522
|
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
20347
20523
|
checkpointer,
|
|
20348
|
-
middleware:
|
|
20524
|
+
middleware: isAsk ? noWrapAskMiddlewares : noWrapMiddlewares,
|
|
20349
20525
|
responseFormat
|
|
20350
20526
|
});
|
|
20351
20527
|
agentCache.set(key, agent);
|
|
20352
20528
|
}
|
|
20353
20529
|
return agentCache.get(key);
|
|
20354
20530
|
}
|
|
20355
|
-
if (
|
|
20356
|
-
const key = "
|
|
20531
|
+
if (isAsk) {
|
|
20532
|
+
const key = "ask:default";
|
|
20357
20533
|
if (!agentCache.has(key)) {
|
|
20358
|
-
console.log(`[WF BUILDER] creating
|
|
20359
|
-
const agent = (0,
|
|
20534
|
+
console.log(`[WF BUILDER] creating ask default agent`);
|
|
20535
|
+
const agent = (0, import_langchain68.createAgent)({
|
|
20360
20536
|
model: params.model,
|
|
20361
20537
|
tools,
|
|
20362
20538
|
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
20363
20539
|
checkpointer,
|
|
20364
|
-
middleware:
|
|
20540
|
+
middleware: askMiddlewares
|
|
20365
20541
|
});
|
|
20366
20542
|
agentCache.set(key, agent);
|
|
20367
20543
|
}
|
|
@@ -20374,11 +20550,11 @@ var WorkflowAgentGraphBuilder = class {
|
|
|
20374
20550
|
try {
|
|
20375
20551
|
const storeLattice = getStoreLattice("default", "workflowTracking");
|
|
20376
20552
|
trackingStore = storeLattice.store;
|
|
20377
|
-
console.log(`[WF BUILDER] trackingStore registered
|
|
20553
|
+
console.log(`[WF BUILDER] trackingStore registered`);
|
|
20378
20554
|
} catch {
|
|
20379
|
-
console.warn(`[WF BUILDER] no trackingStore registered
|
|
20555
|
+
console.warn(`[WF BUILDER] no trackingStore registered`);
|
|
20380
20556
|
}
|
|
20381
|
-
const graph = compileWorkflow(
|
|
20557
|
+
const graph = compileWorkflow(yaml2, resolveAgent, checkpointer, trackingStore);
|
|
20382
20558
|
return graph;
|
|
20383
20559
|
}
|
|
20384
20560
|
};
|
|
@@ -21079,9 +21255,66 @@ ${body}` : `${frontmatter}
|
|
|
21079
21255
|
}
|
|
21080
21256
|
};
|
|
21081
21257
|
|
|
21258
|
+
// src/store_lattice/InMemoryMenuStore.ts
|
|
21259
|
+
var import_crypto3 = require("crypto");
|
|
21260
|
+
var InMemoryMenuStore = class {
|
|
21261
|
+
constructor() {
|
|
21262
|
+
this.items = /* @__PURE__ */ new Map();
|
|
21263
|
+
}
|
|
21264
|
+
async list(params) {
|
|
21265
|
+
const results = Array.from(this.items.values()).filter((item) => {
|
|
21266
|
+
if (item.tenantId !== params.tenantId) return false;
|
|
21267
|
+
if (params.menuTarget && item.menuTarget !== params.menuTarget) return false;
|
|
21268
|
+
if (!item.enabled) return false;
|
|
21269
|
+
return true;
|
|
21270
|
+
});
|
|
21271
|
+
results.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
21272
|
+
return results;
|
|
21273
|
+
}
|
|
21274
|
+
async getById(id) {
|
|
21275
|
+
return this.items.get(id) || null;
|
|
21276
|
+
}
|
|
21277
|
+
async create(input) {
|
|
21278
|
+
const now = /* @__PURE__ */ new Date();
|
|
21279
|
+
const item = {
|
|
21280
|
+
id: (0, import_crypto3.randomUUID)(),
|
|
21281
|
+
tenantId: input.tenantId,
|
|
21282
|
+
menuTarget: input.menuTarget,
|
|
21283
|
+
group: input.group,
|
|
21284
|
+
name: input.name,
|
|
21285
|
+
icon: input.icon,
|
|
21286
|
+
sortOrder: input.sortOrder ?? 0,
|
|
21287
|
+
contentType: input.contentType,
|
|
21288
|
+
contentConfig: input.contentConfig,
|
|
21289
|
+
enabled: true,
|
|
21290
|
+
createdAt: now,
|
|
21291
|
+
updatedAt: now
|
|
21292
|
+
};
|
|
21293
|
+
this.items.set(item.id, item);
|
|
21294
|
+
return item;
|
|
21295
|
+
}
|
|
21296
|
+
async update(id, patch) {
|
|
21297
|
+
const existing = this.items.get(id);
|
|
21298
|
+
if (!existing) throw new Error(`MenuItem ${id} not found`);
|
|
21299
|
+
const updated = {
|
|
21300
|
+
...existing,
|
|
21301
|
+
...patch,
|
|
21302
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
21303
|
+
};
|
|
21304
|
+
this.items.set(id, updated);
|
|
21305
|
+
return updated;
|
|
21306
|
+
}
|
|
21307
|
+
async delete(id) {
|
|
21308
|
+
this.items.delete(id);
|
|
21309
|
+
}
|
|
21310
|
+
clear() {
|
|
21311
|
+
this.items.clear();
|
|
21312
|
+
}
|
|
21313
|
+
};
|
|
21314
|
+
|
|
21082
21315
|
// src/agent_lattice/agentArchitectTools.ts
|
|
21083
|
-
var
|
|
21084
|
-
var
|
|
21316
|
+
var import_zod54 = __toESM(require("zod"));
|
|
21317
|
+
var import_uuid6 = require("uuid");
|
|
21085
21318
|
var import_protocols12 = require("@axiom-lattice/protocols");
|
|
21086
21319
|
function getTenantId(exeConfig) {
|
|
21087
21320
|
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
@@ -21110,7 +21343,7 @@ registerToolLattice(
|
|
|
21110
21343
|
{
|
|
21111
21344
|
name: "list_agents",
|
|
21112
21345
|
description: "List all agents for the current workspace. Returns a summary with id, name, description, and type for each agent.",
|
|
21113
|
-
schema:
|
|
21346
|
+
schema: import_zod54.default.object({})
|
|
21114
21347
|
},
|
|
21115
21348
|
async (_input, exeConfig) => {
|
|
21116
21349
|
try {
|
|
@@ -21137,8 +21370,8 @@ registerToolLattice(
|
|
|
21137
21370
|
{
|
|
21138
21371
|
name: "get_agent",
|
|
21139
21372
|
description: "Get the full configuration of a specific agent by its ID. Returns the complete AgentConfig including prompt, middleware, tools, and sub-agents.",
|
|
21140
|
-
schema:
|
|
21141
|
-
id:
|
|
21373
|
+
schema: import_zod54.default.object({
|
|
21374
|
+
id: import_zod54.default.string().describe("The agent ID to retrieve")
|
|
21142
21375
|
})
|
|
21143
21376
|
},
|
|
21144
21377
|
async (input, exeConfig) => {
|
|
@@ -21155,24 +21388,24 @@ registerToolLattice(
|
|
|
21155
21388
|
}
|
|
21156
21389
|
}
|
|
21157
21390
|
);
|
|
21158
|
-
var middlewareConfigSchema =
|
|
21159
|
-
id:
|
|
21160
|
-
type:
|
|
21161
|
-
name:
|
|
21162
|
-
description:
|
|
21163
|
-
enabled:
|
|
21164
|
-
config:
|
|
21391
|
+
var middlewareConfigSchema = import_zod54.default.object({
|
|
21392
|
+
id: import_zod54.default.string(),
|
|
21393
|
+
type: import_zod54.default.string(),
|
|
21394
|
+
name: import_zod54.default.string(),
|
|
21395
|
+
description: import_zod54.default.string(),
|
|
21396
|
+
enabled: import_zod54.default.boolean(),
|
|
21397
|
+
config: import_zod54.default.record(import_zod54.default.any()).optional()
|
|
21165
21398
|
});
|
|
21166
|
-
var createAgentSchema =
|
|
21167
|
-
name:
|
|
21168
|
-
description:
|
|
21169
|
-
type:
|
|
21170
|
-
prompt:
|
|
21171
|
-
tools:
|
|
21172
|
-
middleware:
|
|
21173
|
-
subAgents:
|
|
21174
|
-
internalSubAgents:
|
|
21175
|
-
modelKey:
|
|
21399
|
+
var createAgentSchema = import_zod54.default.object({
|
|
21400
|
+
name: import_zod54.default.string().describe("Human-friendly display name for the agent. The machine ID (used in other tools) is auto-generated as a slug from this name (e.g. 'My Cool Agent' \u2192 'my-cool-agent')."),
|
|
21401
|
+
description: import_zod54.default.string().optional().describe("Short description"),
|
|
21402
|
+
type: import_zod54.default.enum(["react", "deep_agent"]).describe("Agent type. Use 'react' for simple single-responsibility agents, 'deep_agent' for complex open-ended agents. For PROCESSING agents (workflow orchestration), use create_processing_agent instead."),
|
|
21403
|
+
prompt: import_zod54.default.string().describe("System prompt for the agent"),
|
|
21404
|
+
tools: import_zod54.default.array(import_zod54.default.string()).optional().describe("Tool keys (strings) to assign. Call list_tools first to see available keys. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array of tool names. Do NOT put middleware-like objects here \u2014 middleware goes in the separate 'middleware' field."),
|
|
21405
|
+
middleware: import_zod54.default.array(middlewareConfigSchema).optional().describe("Middleware configuration objects. Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here \u2014 tool names go in the separate 'tools' array. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
21406
|
+
subAgents: import_zod54.default.array(import_zod54.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
21407
|
+
internalSubAgents: import_zod54.default.array(import_zod54.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
21408
|
+
modelKey: import_zod54.default.string().optional().describe("Model key to use")
|
|
21176
21409
|
});
|
|
21177
21410
|
registerToolLattice(
|
|
21178
21411
|
"create_agent",
|
|
@@ -21210,21 +21443,21 @@ registerToolLattice(
|
|
|
21210
21443
|
}
|
|
21211
21444
|
}
|
|
21212
21445
|
);
|
|
21213
|
-
var topologyEdgeSchema =
|
|
21214
|
-
from:
|
|
21215
|
-
to:
|
|
21216
|
-
purpose:
|
|
21446
|
+
var topologyEdgeSchema = import_zod54.default.object({
|
|
21447
|
+
from: import_zod54.default.string().describe("Source agent ID. For the first edge, this is the orchestrator (use the orchestrator's name as a placeholder \u2014 the tool will replace it with the actual ID). For subsequent chained edges, this is the previous stage's sub-agent ID."),
|
|
21448
|
+
to: import_zod54.default.string().describe("Target agent ID (the sub-agent to delegate to)"),
|
|
21449
|
+
purpose: import_zod54.default.string().describe("Business purpose of this delegation step \u2014 what the sub-agent should accomplish")
|
|
21217
21450
|
});
|
|
21218
|
-
var createProcessingAgentSchema =
|
|
21219
|
-
name:
|
|
21220
|
-
description:
|
|
21221
|
-
prompt:
|
|
21222
|
-
edges:
|
|
21223
|
-
tools:
|
|
21224
|
-
subAgents:
|
|
21225
|
-
internalSubAgents:
|
|
21226
|
-
middleware:
|
|
21227
|
-
modelKey:
|
|
21451
|
+
var createProcessingAgentSchema = import_zod54.default.object({
|
|
21452
|
+
name: import_zod54.default.string().describe("Display name for the processing agent"),
|
|
21453
|
+
description: import_zod54.default.string().optional().describe("Short description"),
|
|
21454
|
+
prompt: import_zod54.default.string().describe("System prompt for the orchestrator. Should describe how to route tasks through the topology."),
|
|
21455
|
+
edges: import_zod54.default.array(topologyEdgeSchema).min(1).describe("Topology edges defining the workflow. Each edge describes a delegation step with its business purpose. The orchestrator will follow this topology to delegate tasks to sub-agents."),
|
|
21456
|
+
tools: import_zod54.default.array(import_zod54.default.string()).optional().describe("Tool keys (strings) to assign to the orchestrator. Call list_tools first to see available keys. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array. Do NOT put middleware-like objects here \u2014 middleware goes in the separate 'middleware' field."),
|
|
21457
|
+
subAgents: import_zod54.default.array(import_zod54.default.string()).describe("IDs of sub-agents that form the workflow pipeline. These must be created first via create_agent."),
|
|
21458
|
+
internalSubAgents: import_zod54.default.array(import_zod54.default.any()).optional().describe("Inline sub-agent configs (alternative to pre-created sub-agents)"),
|
|
21459
|
+
middleware: import_zod54.default.array(middlewareConfigSchema).optional().describe("Additional middleware config objects beyond the auto-managed topology middleware. Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
21460
|
+
modelKey: import_zod54.default.string().optional().describe("Model key to use")
|
|
21228
21461
|
}).refine(
|
|
21229
21462
|
(data) => {
|
|
21230
21463
|
const edgeTargets = new Set(data.edges.map((e) => e.to));
|
|
@@ -21250,11 +21483,11 @@ registerToolLattice(
|
|
|
21250
21483
|
const tenantId = getTenantId(exeConfig);
|
|
21251
21484
|
const store = getAssistStore();
|
|
21252
21485
|
const id = await generateAgentId(tenantId, input.name);
|
|
21253
|
-
const
|
|
21486
|
+
const normalize2 = (s) => s.toLowerCase().replace(/[_\-\s]/g, "");
|
|
21254
21487
|
const resolveFrom = (rawFrom) => {
|
|
21255
21488
|
const fromLower = rawFrom.toLowerCase();
|
|
21256
21489
|
const nameLower = input.name.toLowerCase();
|
|
21257
|
-
if (fromLower === nameLower || fromLower === "orchestrator" || fromLower === "orchestrator-id" ||
|
|
21490
|
+
if (fromLower === nameLower || fromLower === "orchestrator" || fromLower === "orchestrator-id" || normalize2(rawFrom) === normalize2(input.name)) {
|
|
21258
21491
|
return id;
|
|
21259
21492
|
}
|
|
21260
21493
|
return rawFrom;
|
|
@@ -21306,34 +21539,20 @@ registerToolLattice(
|
|
|
21306
21539
|
}
|
|
21307
21540
|
}
|
|
21308
21541
|
);
|
|
21309
|
-
var
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21313
|
-
|
|
21314
|
-
|
|
21315
|
-
|
|
21316
|
-
|
|
21317
|
-
])
|
|
21318
|
-
);
|
|
21319
|
-
var workflowDSLSchema = import_zod53.default.object({
|
|
21320
|
-
name: import_zod53.default.string().describe("Workflow identifier (kebab-case slug)"),
|
|
21321
|
-
steps: import_zod53.default.array(workflowStepLazy).min(1).describe("Workflow steps. Edges and state fields are auto-generated. Use {{id}} to reference step outputs. Always end with { type: 'end' }.")
|
|
21322
|
-
});
|
|
21323
|
-
var createWorkflowSchema = import_zod53.default.object({
|
|
21324
|
-
name: import_zod53.default.string().describe("Display name for the workflow agent"),
|
|
21325
|
-
description: import_zod53.default.string().optional().describe("Short description of what this workflow does"),
|
|
21326
|
-
skillLoaded: import_zod53.default.literal(true).describe("MUST be true. Set this to true ONLY after loading the 'create-workflow' skill via skill(skill_name: 'create-workflow'). This confirms you have read the DSL specification and design guidelines."),
|
|
21327
|
-
workflow: workflowDSLSchema.describe("The concise Workflow DSL definition. Each step has a type (agent/human/condition/map/parallel/end) and a prompt. Edges are auto-generated from step order. Use {{id}} to reference upstream step outputs."),
|
|
21328
|
-
tools: import_zod53.default.array(import_zod53.default.string()).optional().describe("Tool keys for the workflow's built-in general agent"),
|
|
21329
|
-
middleware: import_zod53.default.array(middlewareConfigSchema).optional().describe("Middleware configs for the workflow's general agent"),
|
|
21330
|
-
modelKey: import_zod53.default.string().optional().describe("Model key for the workflow's general agent")
|
|
21542
|
+
var createWorkflowSchema = import_zod54.default.object({
|
|
21543
|
+
name: import_zod54.default.string().describe("Display name for the workflow agent"),
|
|
21544
|
+
description: import_zod54.default.string().optional().describe("Short description"),
|
|
21545
|
+
skillLoaded: import_zod54.default.literal(true).describe("MUST be true. Set after loading the 'create-workflow' skill."),
|
|
21546
|
+
yaml: import_zod54.default.string().describe("The YAML workflow definition in linear DSL format (steps execute top-to-bottom, use parallel: for concurrency)"),
|
|
21547
|
+
tools: import_zod54.default.array(import_zod54.default.string()).optional().describe("Tool keys for the workflow agent"),
|
|
21548
|
+
middleware: import_zod54.default.array(middlewareConfigSchema).optional().describe("Middleware configs"),
|
|
21549
|
+
modelKey: import_zod54.default.string().optional().describe("Model key")
|
|
21331
21550
|
});
|
|
21332
21551
|
registerToolLattice(
|
|
21333
21552
|
"create_workflow",
|
|
21334
21553
|
{
|
|
21335
21554
|
name: "create_workflow",
|
|
21336
|
-
description:
|
|
21555
|
+
description: "Create a WORKFLOW agent from YAML DSL. Load the 'create-workflow' skill first. Linear model \u2014 steps execute top-to-bottom. Use parallel: for concurrency. Data flows via {{label}} automatically. Business logic stays in agent prompts.",
|
|
21337
21556
|
schema: createWorkflowSchema
|
|
21338
21557
|
},
|
|
21339
21558
|
async (input, exeConfig) => {
|
|
@@ -21341,36 +21560,31 @@ registerToolLattice(
|
|
|
21341
21560
|
const tenantId = getTenantId(exeConfig);
|
|
21342
21561
|
const store = getAssistStore();
|
|
21343
21562
|
const id = await generateAgentId(tenantId, input.name);
|
|
21563
|
+
try {
|
|
21564
|
+
const { compileWorkflow: compileWorkflow2 } = await Promise.resolve().then(() => (init_compile(), compile_exports));
|
|
21565
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await Promise.resolve().then(() => (init_memory_lattice(), memory_lattice_exports));
|
|
21566
|
+
await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
21567
|
+
} catch (e) {
|
|
21568
|
+
return JSON.stringify({ error: `DSL validation failed: ${e.message}` });
|
|
21569
|
+
}
|
|
21344
21570
|
const config = {
|
|
21345
21571
|
key: id,
|
|
21346
21572
|
name: input.name,
|
|
21347
21573
|
description: input.description || "",
|
|
21348
21574
|
type: import_protocols12.AgentType.WORKFLOW,
|
|
21349
21575
|
prompt: input.description || `Workflow: ${input.name}`,
|
|
21350
|
-
|
|
21576
|
+
workflowYaml: input.yaml,
|
|
21351
21577
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
21352
21578
|
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
21353
21579
|
...input.modelKey ? { modelKey: input.modelKey } : {}
|
|
21354
21580
|
};
|
|
21355
|
-
try {
|
|
21356
|
-
const { compileWorkflow: compileWorkflow2 } = await Promise.resolve().then(() => (init_compile(), compile_exports));
|
|
21357
|
-
const { getCheckpointSaver: getCheckpointSaver2 } = await Promise.resolve().then(() => (init_memory_lattice(), memory_lattice_exports));
|
|
21358
|
-
await compileWorkflow2(input.workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
21359
|
-
} catch (e) {
|
|
21360
|
-
return JSON.stringify({ error: `DSL validation failed: ${e.message}`, issues: [{ type: "error", message: e.message }] });
|
|
21361
|
-
}
|
|
21362
21581
|
await store.createAssistant(tenantId, id, {
|
|
21363
21582
|
name: input.name,
|
|
21364
21583
|
description: input.description,
|
|
21365
21584
|
graphDefinition: config
|
|
21366
21585
|
});
|
|
21367
21586
|
eventBus.publish("assistant:created", { id, name: input.name, tenantId });
|
|
21368
|
-
return JSON.stringify({
|
|
21369
|
-
id,
|
|
21370
|
-
name: input.name,
|
|
21371
|
-
type: "workflow",
|
|
21372
|
-
stepCount: input.workflow.steps.length
|
|
21373
|
-
});
|
|
21587
|
+
return JSON.stringify({ id, name: input.name, type: "workflow" });
|
|
21374
21588
|
} catch (error) {
|
|
21375
21589
|
return JSON.stringify({ error: `Failed to create workflow: ${error.message}` });
|
|
21376
21590
|
}
|
|
@@ -21380,9 +21594,9 @@ registerToolLattice(
|
|
|
21380
21594
|
"validate_workflow",
|
|
21381
21595
|
{
|
|
21382
21596
|
name: "validate_workflow",
|
|
21383
|
-
description: "Validate a workflow agent's DSL for correctness by compiling it.
|
|
21384
|
-
schema:
|
|
21385
|
-
id:
|
|
21597
|
+
description: "Validate a workflow agent's DSL for correctness by compiling it.",
|
|
21598
|
+
schema: import_zod54.default.object({
|
|
21599
|
+
id: import_zod54.default.string().describe("The workflow agent ID to validate")
|
|
21386
21600
|
})
|
|
21387
21601
|
},
|
|
21388
21602
|
async (input, exeConfig) => {
|
|
@@ -21395,76 +21609,76 @@ registerToolLattice(
|
|
|
21395
21609
|
}
|
|
21396
21610
|
const graphDef = agent.graphDefinition;
|
|
21397
21611
|
if (!graphDef || graphDef.type !== import_protocols12.AgentType.WORKFLOW) {
|
|
21398
|
-
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent
|
|
21612
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
21399
21613
|
}
|
|
21400
|
-
const
|
|
21401
|
-
if (!
|
|
21402
|
-
return JSON.stringify({ error: `Agent '${input.id}' has no
|
|
21614
|
+
const yaml2 = graphDef.workflowYaml;
|
|
21615
|
+
if (!yaml2) {
|
|
21616
|
+
return JSON.stringify({ error: `Agent '${input.id}' has no workflow DSL` });
|
|
21403
21617
|
}
|
|
21404
21618
|
try {
|
|
21405
21619
|
const { compileWorkflow: compileWorkflow2 } = await Promise.resolve().then(() => (init_compile(), compile_exports));
|
|
21406
21620
|
const { getCheckpointSaver: getCheckpointSaver2 } = await Promise.resolve().then(() => (init_memory_lattice(), memory_lattice_exports));
|
|
21407
|
-
await compileWorkflow2(
|
|
21621
|
+
await compileWorkflow2(yaml2, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
21408
21622
|
} catch (e) {
|
|
21409
21623
|
return JSON.stringify({
|
|
21410
21624
|
agentId: input.id,
|
|
21411
21625
|
valid: false,
|
|
21412
|
-
stepCount: workflow.steps?.length ?? 0,
|
|
21413
21626
|
issues: [{ type: "error", message: e.message }]
|
|
21414
21627
|
});
|
|
21415
21628
|
}
|
|
21416
|
-
return JSON.stringify({
|
|
21417
|
-
agentId: input.id,
|
|
21418
|
-
valid: true,
|
|
21419
|
-
stepCount: workflow.steps?.length ?? 0,
|
|
21420
|
-
issues: []
|
|
21421
|
-
});
|
|
21629
|
+
return JSON.stringify({ agentId: input.id, valid: true, issues: [] });
|
|
21422
21630
|
} catch (error) {
|
|
21423
21631
|
return JSON.stringify({ error: `Failed to validate workflow: ${error.message}` });
|
|
21424
21632
|
}
|
|
21425
21633
|
}
|
|
21426
21634
|
);
|
|
21427
|
-
var updateWorkflowSchema =
|
|
21428
|
-
id:
|
|
21429
|
-
name:
|
|
21430
|
-
description:
|
|
21431
|
-
|
|
21432
|
-
tools:
|
|
21433
|
-
middleware:
|
|
21434
|
-
modelKey:
|
|
21635
|
+
var updateWorkflowSchema = import_zod54.default.object({
|
|
21636
|
+
id: import_zod54.default.string().describe("The workflow agent ID to update"),
|
|
21637
|
+
name: import_zod54.default.string().optional().describe("New display name"),
|
|
21638
|
+
description: import_zod54.default.string().optional().describe("New description"),
|
|
21639
|
+
yaml: import_zod54.default.string().optional().describe("Replacement YAML workflow DSL. Omit to keep existing."),
|
|
21640
|
+
tools: import_zod54.default.array(import_zod54.default.string()).optional().describe("Replacement tool keys"),
|
|
21641
|
+
middleware: import_zod54.default.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
|
|
21642
|
+
modelKey: import_zod54.default.string().optional().describe("Replacement model key")
|
|
21435
21643
|
});
|
|
21436
21644
|
registerToolLattice(
|
|
21437
21645
|
"update_workflow",
|
|
21438
21646
|
{
|
|
21439
21647
|
name: "update_workflow",
|
|
21440
|
-
description: "Update an existing workflow agent. Provide the agent ID and only the fields
|
|
21648
|
+
description: "Update an existing workflow agent. Provide the agent ID and only the fields to change. Pass yaml string to replace the DSL, or omit to keep it.",
|
|
21441
21649
|
schema: updateWorkflowSchema
|
|
21442
21650
|
},
|
|
21443
21651
|
async (input, exeConfig) => {
|
|
21652
|
+
console.log(`[update_workflow] CALLED id=${input.id} hasYaml=${input.yaml !== void 0}`);
|
|
21444
21653
|
try {
|
|
21445
21654
|
const tenantId = getTenantId(exeConfig);
|
|
21446
21655
|
const store = getAssistStore();
|
|
21447
21656
|
const existing = await store.getAssistantById(tenantId, input.id);
|
|
21448
21657
|
if (!existing) {
|
|
21658
|
+
console.log(`[update_workflow] ERROR: agent not found: ${input.id}`);
|
|
21449
21659
|
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
21450
21660
|
}
|
|
21451
21661
|
const existingConfig = existing.graphDefinition || {};
|
|
21452
21662
|
if (existingConfig.type !== import_protocols12.AgentType.WORKFLOW) {
|
|
21663
|
+
console.log(`[update_workflow] ERROR: not a workflow agent: ${input.id}`);
|
|
21453
21664
|
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
21454
21665
|
}
|
|
21455
21666
|
const mergedConfig = { ...existingConfig };
|
|
21456
21667
|
if (input.name !== void 0) mergedConfig.name = input.name;
|
|
21457
21668
|
if (input.description !== void 0) mergedConfig.description = input.description;
|
|
21458
|
-
if (input.
|
|
21669
|
+
if (input.yaml !== void 0) mergedConfig.workflowYaml = input.yaml;
|
|
21459
21670
|
if (input.tools !== void 0) mergedConfig.tools = input.tools;
|
|
21460
21671
|
if (input.middleware !== void 0) mergedConfig.middleware = input.middleware;
|
|
21461
21672
|
if (input.modelKey !== void 0) mergedConfig.modelKey = input.modelKey;
|
|
21462
|
-
if (input.
|
|
21673
|
+
if (input.yaml !== void 0) {
|
|
21674
|
+
console.log(`[update_workflow] validating DSL: ${input.id}`);
|
|
21463
21675
|
try {
|
|
21464
21676
|
const { compileWorkflow: compileWorkflow2 } = await Promise.resolve().then(() => (init_compile(), compile_exports));
|
|
21465
21677
|
const { getCheckpointSaver: getCheckpointSaver2 } = await Promise.resolve().then(() => (init_memory_lattice(), memory_lattice_exports));
|
|
21466
|
-
await compileWorkflow2(input.
|
|
21678
|
+
await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
21679
|
+
console.log(`[update_workflow] DSL validation passed: ${input.id}`);
|
|
21467
21680
|
} catch (e) {
|
|
21681
|
+
console.log(`[update_workflow] DSL validation FAILED: ${input.id} - ${e.message}`);
|
|
21468
21682
|
return JSON.stringify({
|
|
21469
21683
|
error: `DSL validation failed: ${e.message}`,
|
|
21470
21684
|
issues: [{ type: "error", message: e.message }]
|
|
@@ -21478,28 +21692,24 @@ registerToolLattice(
|
|
|
21478
21692
|
graphDefinition: mergedConfig
|
|
21479
21693
|
});
|
|
21480
21694
|
eventBus.publish("assistant:updated", { id: input.id, name: newName, tenantId });
|
|
21481
|
-
|
|
21482
|
-
return JSON.stringify({
|
|
21483
|
-
id: input.id,
|
|
21484
|
-
name: newName,
|
|
21485
|
-
type: "workflow",
|
|
21486
|
-
stepCount: workflow?.steps?.length ?? 0
|
|
21487
|
-
});
|
|
21695
|
+
console.log(`[update_workflow] SUCCESS: id=${input.id} name=${newName}`);
|
|
21696
|
+
return JSON.stringify({ id: input.id, name: newName, type: "workflow" });
|
|
21488
21697
|
} catch (error) {
|
|
21698
|
+
console.log(`[update_workflow] EXCEPTION: ${error.message}`);
|
|
21489
21699
|
return JSON.stringify({ error: `Failed to update workflow: ${error.message}` });
|
|
21490
21700
|
}
|
|
21491
21701
|
}
|
|
21492
21702
|
);
|
|
21493
|
-
var updateProcessingAgentSchema =
|
|
21494
|
-
id:
|
|
21495
|
-
name:
|
|
21496
|
-
description:
|
|
21497
|
-
prompt:
|
|
21498
|
-
edges:
|
|
21499
|
-
tools:
|
|
21500
|
-
subAgents:
|
|
21501
|
-
middleware:
|
|
21502
|
-
modelKey:
|
|
21703
|
+
var updateProcessingAgentSchema = import_zod54.default.object({
|
|
21704
|
+
id: import_zod54.default.string().describe("The PROCESSING agent ID to update"),
|
|
21705
|
+
name: import_zod54.default.string().optional().describe("New display name for the orchestrator"),
|
|
21706
|
+
description: import_zod54.default.string().optional().describe("New short description"),
|
|
21707
|
+
prompt: import_zod54.default.string().optional().describe("New system prompt for the orchestrator"),
|
|
21708
|
+
edges: import_zod54.default.array(topologyEdgeSchema).min(1).optional().describe("New topology edges. First edge's from must reference the orchestrator by name (the tool replaces it). Subsequent edges chain from previous sub-agent IDs."),
|
|
21709
|
+
tools: import_zod54.default.array(import_zod54.default.string()).optional().describe("Tool keys (strings) to assign to the orchestrator. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array \u2014 do NOT put middleware-like objects here."),
|
|
21710
|
+
subAgents: import_zod54.default.array(import_zod54.default.string()).optional().describe("New IDs of sub-agents in the workflow pipeline"),
|
|
21711
|
+
middleware: import_zod54.default.array(middlewareConfigSchema).optional().describe("Additional middleware config objects (topology middleware is auto-managed, do not include it). Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
21712
|
+
modelKey: import_zod54.default.string().optional().describe("New model key")
|
|
21503
21713
|
}).refine(
|
|
21504
21714
|
(data) => {
|
|
21505
21715
|
if (!data.edges) return true;
|
|
@@ -21534,12 +21744,12 @@ registerToolLattice(
|
|
|
21534
21744
|
if (existingConfig.type !== import_protocols12.AgentType.PROCESSING) {
|
|
21535
21745
|
return JSON.stringify({ error: `Agent '${input.id}' is not a PROCESSING agent (type: ${existingConfig.type})` });
|
|
21536
21746
|
}
|
|
21537
|
-
const
|
|
21747
|
+
const normalize2 = (s) => s.toLowerCase().replace(/[_\-\s]/g, "");
|
|
21538
21748
|
const orchestratorName = input.name || existingConfig.name || existing.name || "";
|
|
21539
21749
|
const resolveFrom = (rawFrom) => {
|
|
21540
21750
|
const fromLower = rawFrom.toLowerCase();
|
|
21541
21751
|
const nameLower = orchestratorName.toLowerCase();
|
|
21542
|
-
if (fromLower === nameLower || fromLower === "orchestrator" || fromLower === "orchestrator-id" ||
|
|
21752
|
+
if (fromLower === nameLower || fromLower === "orchestrator" || fromLower === "orchestrator-id" || normalize2(rawFrom) === normalize2(orchestratorName)) {
|
|
21543
21753
|
return input.id;
|
|
21544
21754
|
}
|
|
21545
21755
|
return rawFrom;
|
|
@@ -21627,18 +21837,18 @@ registerToolLattice(
|
|
|
21627
21837
|
}
|
|
21628
21838
|
}
|
|
21629
21839
|
);
|
|
21630
|
-
var updateAgentSchema =
|
|
21631
|
-
id:
|
|
21632
|
-
config:
|
|
21633
|
-
name:
|
|
21634
|
-
description:
|
|
21635
|
-
type:
|
|
21636
|
-
prompt:
|
|
21637
|
-
tools:
|
|
21638
|
-
middleware:
|
|
21639
|
-
subAgents:
|
|
21640
|
-
internalSubAgents:
|
|
21641
|
-
modelKey:
|
|
21840
|
+
var updateAgentSchema = import_zod54.default.object({
|
|
21841
|
+
id: import_zod54.default.string().describe("The agent ID to update"),
|
|
21842
|
+
config: import_zod54.default.object({
|
|
21843
|
+
name: import_zod54.default.string().optional().describe("New display name for the agent"),
|
|
21844
|
+
description: import_zod54.default.string().optional().describe("New short description"),
|
|
21845
|
+
type: import_zod54.default.enum(["react", "deep_agent"]).optional().describe("Agent type"),
|
|
21846
|
+
prompt: import_zod54.default.string().optional().describe("New system prompt for the agent"),
|
|
21847
|
+
tools: import_zod54.default.array(import_zod54.default.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
|
|
21848
|
+
middleware: import_zod54.default.array(middlewareConfigSchema).optional().describe("Middleware configurations. NOTE: middleware objects have type/name/description/enabled/config fields and are NOT the same as tools. Tool keys go in the 'tools' array. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
21849
|
+
subAgents: import_zod54.default.array(import_zod54.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
21850
|
+
internalSubAgents: import_zod54.default.array(import_zod54.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
21851
|
+
modelKey: import_zod54.default.string().optional().describe("Model key to use")
|
|
21642
21852
|
}).describe("Configuration fields to update. Only include the fields you want to change.")
|
|
21643
21853
|
});
|
|
21644
21854
|
registerToolLattice(
|
|
@@ -21676,8 +21886,8 @@ registerToolLattice(
|
|
|
21676
21886
|
{
|
|
21677
21887
|
name: "delete_agent",
|
|
21678
21888
|
description: "Permanently delete an agent by its ID. This action cannot be undone.",
|
|
21679
|
-
schema:
|
|
21680
|
-
id:
|
|
21889
|
+
schema: import_zod54.default.object({
|
|
21890
|
+
id: import_zod54.default.string().describe("The agent ID to delete")
|
|
21681
21891
|
})
|
|
21682
21892
|
},
|
|
21683
21893
|
async (input, exeConfig) => {
|
|
@@ -21703,7 +21913,7 @@ registerToolLattice(
|
|
|
21703
21913
|
{
|
|
21704
21914
|
name: "list_tools",
|
|
21705
21915
|
description: "List all available tools that can be assigned to agents. Returns each tool's name (use this string value in the 'tools' array), description, and whether it requires user approval. The tool names from this list are what you pass as strings in the 'tools' field of create_agent or update_agent.",
|
|
21706
|
-
schema:
|
|
21916
|
+
schema: import_zod54.default.object({})
|
|
21707
21917
|
},
|
|
21708
21918
|
async (_input, _exeConfig) => {
|
|
21709
21919
|
try {
|
|
@@ -21725,9 +21935,9 @@ registerToolLattice(
|
|
|
21725
21935
|
{
|
|
21726
21936
|
name: "invoke_agent",
|
|
21727
21937
|
description: "Invoke an agent with a test message and return its response. Use this to verify an agent works correctly after creating or modifying it. The agent must be compiled (already created and valid).",
|
|
21728
|
-
schema:
|
|
21729
|
-
id:
|
|
21730
|
-
message:
|
|
21938
|
+
schema: import_zod54.default.object({
|
|
21939
|
+
id: import_zod54.default.string().describe("The agent ID to invoke"),
|
|
21940
|
+
message: import_zod54.default.string().describe("The test message to send to the agent")
|
|
21731
21941
|
})
|
|
21732
21942
|
},
|
|
21733
21943
|
async (input, exeConfig) => {
|
|
@@ -21739,13 +21949,13 @@ registerToolLattice(
|
|
|
21739
21949
|
if (!existing) {
|
|
21740
21950
|
return JSON.stringify({ error: `Agent '${id}' not found` });
|
|
21741
21951
|
}
|
|
21742
|
-
const threadId = (0,
|
|
21952
|
+
const threadId = (0, import_uuid6.v4)();
|
|
21743
21953
|
const agent = new Agent({
|
|
21744
21954
|
tenant_id: tenantId,
|
|
21745
21955
|
assistant_id: id,
|
|
21746
21956
|
thread_id: threadId
|
|
21747
21957
|
});
|
|
21748
|
-
const result = await agent.
|
|
21958
|
+
const result = await agent.invokeWithState({ input: { message } });
|
|
21749
21959
|
return JSON.stringify({ agentId: id, threadId, result });
|
|
21750
21960
|
} catch (error) {
|
|
21751
21961
|
console.error(`[invoke_agent] FAILED for agent="${input.id}":`, error.stack || error.message);
|
|
@@ -21840,7 +22050,7 @@ Let the \`show_widget\` tool handle rendering details \u2014 it has its own guid
|
|
|
21840
22050
|
| Type | Best for | Execution Model |
|
|
21841
22051
|
|------|----------|----------------|
|
|
21842
22052
|
| **react** | Simple, single-responsibility tasks | Classic ReAct loop (think \u2192 act \u2192 observe) |
|
|
21843
|
-
| **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop |
|
|
22053
|
+
| **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop | YAML linear DSL compiled into LangGraph state machine |
|
|
21844
22054
|
| **deep_agent** | Complex, open-ended tasks requiring dynamic decomposition | Self-generating dynamic todos: agent analyzes the task and creates its own execution plan at runtime |
|
|
21845
22055
|
|
|
21846
22056
|
When a user is unsure which type to choose, use \`show_widget\` to render a visual comparison \u2014 show each type's execution model side-by-side as an interactive diagram so the user can intuitively understand the differences.
|
|
@@ -21894,7 +22104,7 @@ Use this when the process is fully known. A workflow is a deterministic LangGrap
|
|
|
21894
22104
|
|---|---|
|
|
21895
22105
|
| Fixed graph \u2014 all paths pre-defined | LLM-driven runtime routing |
|
|
21896
22106
|
| Conditional branching via \`if\` field | Topology-constrained delegation |
|
|
21897
|
-
|
|
|
22107
|
+
| needs + if model (YAML DSL) | Single orchestrator delegates linearly |
|
|
21898
22108
|
| No LLM routing decisions | Orchestrator uses LLM to route |
|
|
21899
22109
|
|
|
21900
22110
|
### Phase 0: Load the Skill
|
|
@@ -21908,20 +22118,23 @@ skill(skill_name: "create-workflow")
|
|
|
21908
22118
|
### Phase 1: Design
|
|
21909
22119
|
|
|
21910
22120
|
1. **Analyze the process.** Map every step, branch, data dependency.
|
|
21911
|
-
2. **
|
|
21912
|
-
-
|
|
21913
|
-
- \`
|
|
21914
|
-
- \`
|
|
21915
|
-
|
|
21916
|
-
|
|
21917
|
-
|
|
21918
|
-
3. **
|
|
21919
|
-
|
|
22121
|
+
2. **Design using the YAML linear DSL.** Every step is an agent with optional attributes:
|
|
22122
|
+
- **Linear** \u2014 steps execute top-to-bottom in written order.
|
|
22123
|
+
- \`parallel:\` \u2014 wraps agent steps that run concurrently.
|
|
22124
|
+
- \`if\` \u2014 JS expression for conditional execution. Step runs only when truthy. Omit to always run.
|
|
22125
|
+
- \`prompt\` \u2014 agent instruction with \`{{label}}\` refs. \`{{input}}\` = user message.
|
|
22126
|
+
- \`output\` \u2014 shorthand schema: \`{ field: type }\`.
|
|
22127
|
+
- \`ask: true\` \u2014 injects ask_user_to_clarify middleware for human interaction.
|
|
22128
|
+
3. **Special step types:**
|
|
22129
|
+
- \`map\` \u2014 iterates array from \`source\`, applies \`each\` step per item.
|
|
22130
|
+
4. **No edges, state fields, or end step needed** \u2014 the engine auto-generates them.
|
|
22131
|
+
5. **Schema format:** Use block-style YAML shorthand \`{ field: type }\`. Supported types: \`string\`, \`number\`, \`boolean\`, \`string[]\`, \`number[]\`, \`boolean[]\`, nested objects, object arrays.
|
|
21920
22132
|
|
|
21921
22133
|
### Phase 2: Confirm
|
|
21922
22134
|
|
|
21923
22135
|
Present the design. Ask: "Ready to create this workflow?"
|
|
21924
22136
|
|
|
22137
|
+
|
|
21925
22138
|
### Phase 3: Build
|
|
21926
22139
|
|
|
21927
22140
|
Call \`create_workflow\` with \`skillLoaded: true\`. Then \`validate_workflow(id)\`.
|
|
@@ -22016,20 +22229,17 @@ All fields except name, type, and prompt are optional.
|
|
|
22016
22229
|
|
|
22017
22230
|
### create_workflow (WORKFLOW)
|
|
22018
22231
|
|
|
22019
|
-
Creates a WORKFLOW agent from a
|
|
22232
|
+
Creates a WORKFLOW agent from a YAML linear DSL. Before calling, load the \`create-workflow\` skill. Must pass \`skillLoaded: true\`.
|
|
22020
22233
|
|
|
22021
22234
|
\`\`\`typescript
|
|
22022
22235
|
{
|
|
22023
22236
|
name: string, // Required. Display name
|
|
22024
|
-
description?: string, // Optional
|
|
22025
|
-
skillLoaded: true, // Required
|
|
22026
|
-
|
|
22027
|
-
|
|
22028
|
-
|
|
22029
|
-
|
|
22030
|
-
tools?: string[], // Optional. Tool keys for the built-in general agent
|
|
22031
|
-
middleware?: MiddlewareConfig[], // Optional. Middleware for the general agent
|
|
22032
|
-
modelKey?: string, // Optional. Model for the general agent
|
|
22237
|
+
description?: string, // Optional
|
|
22238
|
+
skillLoaded: true, // Required \u2014 confirms skill was loaded
|
|
22239
|
+
yaml: string, // Required. YAML workflow in linear DSL format
|
|
22240
|
+
tools?: string[], // Optional. Tool keys
|
|
22241
|
+
middleware?: MiddlewareConfig[], // Optional
|
|
22242
|
+
modelKey?: string, // Optional
|
|
22033
22243
|
}
|
|
22034
22244
|
\`\`\`
|
|
22035
22245
|
|
|
@@ -22042,7 +22252,7 @@ Updates an existing WORKFLOW agent. Only include fields you want to change.
|
|
|
22042
22252
|
id: string, // Required. Workflow agent ID
|
|
22043
22253
|
name?: string, // Optional
|
|
22044
22254
|
description?: string, // Optional
|
|
22045
|
-
|
|
22255
|
+
yaml?: string, // Optional. Replacement YAML DSL
|
|
22046
22256
|
tools?: string[], // Optional
|
|
22047
22257
|
middleware?: MiddlewareConfig[], // Optional
|
|
22048
22258
|
modelKey?: string, // Optional
|
|
@@ -22262,10 +22472,13 @@ You are an **Agent Reviewer** \u2014 a quality assurance specialist for AI agent
|
|
|
22262
22472
|
2. Craft a realistic test message that exercises the agent's core responsibility \u2014 what would a real user say?
|
|
22263
22473
|
3. Call **invoke_agent(id, message)** to send the test message
|
|
22264
22474
|
4. Analyze the response:
|
|
22265
|
-
-
|
|
22266
|
-
-
|
|
22267
|
-
|
|
22268
|
-
|
|
22475
|
+
- **If result.__interrupt__ is present** (an array of interrupt objects): The agent hit a human-in-the-loop interrupt (e.g., ask_user_to_clarify or interrupt() in a workflow). This is NOT an error \u2014 it means the agent paused execution waiting for user feedback. Each interrupt has a value (the question/request) and optionally an id. Report this as: "The agent successfully paused and is waiting for user input: <describe the interrupt value>." The messages array may contain the agent's output up to the point of interruption.
|
|
22476
|
+
- **Otherwise, result.messages contains the agent's output**: The agent completed without interruption. Check:
|
|
22477
|
+
- Did the agent understand the request?
|
|
22478
|
+
- Was the response relevant and accurate?
|
|
22479
|
+
- Did the agent use the right tools?
|
|
22480
|
+
- Were there any errors or unexpected behaviors?
|
|
22481
|
+
- **If result.error is present**: The invocation itself failed (agent not found, compilation error, etc.). Report the error clearly.
|
|
22269
22482
|
5. Report your findings with the agent's actual response
|
|
22270
22483
|
|
|
22271
22484
|
### When results are wrong:
|
|
@@ -22362,7 +22575,8 @@ function ensureBuiltinAgentsForTenant(tenantId) {
|
|
|
22362
22575
|
|
|
22363
22576
|
// src/agent_lattice/AgentLatticeManager.ts
|
|
22364
22577
|
function assistantToConfig(assistant) {
|
|
22365
|
-
const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? assistant.graphDefinition : {};
|
|
22578
|
+
const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? { ...assistant.graphDefinition } : {};
|
|
22579
|
+
delete graphDef.key;
|
|
22366
22580
|
const config = {
|
|
22367
22581
|
key: assistant.id,
|
|
22368
22582
|
name: assistant.name ?? graphDef.name ?? assistant.id,
|
|
@@ -22370,9 +22584,7 @@ function assistantToConfig(assistant) {
|
|
|
22370
22584
|
type: import_protocols.AgentType.REACT,
|
|
22371
22585
|
prompt: typeof assistant.graphDefinition === "string" ? assistant.graphDefinition : JSON.stringify(assistant.graphDefinition)
|
|
22372
22586
|
};
|
|
22373
|
-
|
|
22374
|
-
Object.assign(config, graphDef);
|
|
22375
|
-
}
|
|
22587
|
+
Object.assign(config, graphDef);
|
|
22376
22588
|
return config;
|
|
22377
22589
|
}
|
|
22378
22590
|
var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager {
|
|
@@ -23771,10 +23983,10 @@ var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
|
|
|
23771
23983
|
}
|
|
23772
23984
|
const tools = await this.getAllTools();
|
|
23773
23985
|
console.log(`[MCP] Registering ${tools.length} tools to Tool Lattice...`);
|
|
23774
|
-
for (const
|
|
23775
|
-
const toolKey = prefix ? `${prefix}_${
|
|
23776
|
-
|
|
23777
|
-
toolLatticeManager.registerExistingTool(toolKey,
|
|
23986
|
+
for (const tool52 of tools) {
|
|
23987
|
+
const toolKey = prefix ? `${prefix}_${tool52.name}` : tool52.name;
|
|
23988
|
+
tool52.name = toolKey;
|
|
23989
|
+
toolLatticeManager.registerExistingTool(toolKey, tool52);
|
|
23778
23990
|
console.log(`[MCP] Registered tool: ${toolKey}`);
|
|
23779
23991
|
}
|
|
23780
23992
|
console.log(`[MCP] Successfully registered ${tools.length} tools to Tool Lattice`);
|
|
@@ -25070,11 +25282,47 @@ function createSandboxProvider(config) {
|
|
|
25070
25282
|
}
|
|
25071
25283
|
}
|
|
25072
25284
|
|
|
25285
|
+
// src/channel/connectAllChannels.ts
|
|
25286
|
+
async function connectAllChannels(getAdapter, options = {}) {
|
|
25287
|
+
const store = getStoreLattice("default", "channelInstallation").store;
|
|
25288
|
+
const installations = await store.getAllInstallations();
|
|
25289
|
+
console.log(`[connectAllChannels] total=${installations.length} enabled=${installations.filter((i) => i.enabled).length}`);
|
|
25290
|
+
for (const inst of installations) {
|
|
25291
|
+
if (!inst.enabled) {
|
|
25292
|
+
console.log(`[connectAllChannels] skip disabled: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
|
|
25293
|
+
continue;
|
|
25294
|
+
}
|
|
25295
|
+
const adapter = getAdapter(inst.channel);
|
|
25296
|
+
if (!adapter) {
|
|
25297
|
+
console.log(`[connectAllChannels] no adapter: channel=${inst.channel} id=${inst.id}`);
|
|
25298
|
+
continue;
|
|
25299
|
+
}
|
|
25300
|
+
if (adapter.connect) {
|
|
25301
|
+
console.log(`[connectAllChannels] connecting: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
|
|
25302
|
+
await adapter.connect(inst, options.deps);
|
|
25303
|
+
} else {
|
|
25304
|
+
console.log(`[connectAllChannels] no connect(): channel=${inst.channel} id=${inst.id}`);
|
|
25305
|
+
}
|
|
25306
|
+
}
|
|
25307
|
+
}
|
|
25308
|
+
|
|
25309
|
+
// src/menu_lattice/MenuRegistryHolder.ts
|
|
25310
|
+
var registry2 = null;
|
|
25311
|
+
function setMenuRegistry(r) {
|
|
25312
|
+
registry2 = r;
|
|
25313
|
+
}
|
|
25314
|
+
function getMenuRegistry() {
|
|
25315
|
+
if (!registry2) {
|
|
25316
|
+
throw new Error("MenuRegistry not initialized. Call setMenuRegistry() before use.");
|
|
25317
|
+
}
|
|
25318
|
+
return registry2;
|
|
25319
|
+
}
|
|
25320
|
+
|
|
25073
25321
|
// src/index.ts
|
|
25074
25322
|
var Protocols = __toESM(require("@axiom-lattice/protocols"));
|
|
25075
25323
|
|
|
25076
25324
|
// src/util/encryption.ts
|
|
25077
|
-
var
|
|
25325
|
+
var import_crypto4 = require("crypto");
|
|
25078
25326
|
var ALGORITHM = "aes-256-gcm";
|
|
25079
25327
|
var IV_LENGTH = 16;
|
|
25080
25328
|
var SALT_LENGTH = 32;
|
|
@@ -25087,7 +25335,7 @@ function getEncryptionKey() {
|
|
|
25087
25335
|
return cachedKey;
|
|
25088
25336
|
}
|
|
25089
25337
|
const key = process.env.LATTICE_ENCRYPTION_KEY || DEFAULT_ENCRYPTION_KEY;
|
|
25090
|
-
cachedKey = (0,
|
|
25338
|
+
cachedKey = (0, import_crypto4.pbkdf2Sync)(key, "lattice-encryption-salt", ITERATIONS, 32, "sha256");
|
|
25091
25339
|
if (!keyValidated) {
|
|
25092
25340
|
keyValidated = true;
|
|
25093
25341
|
validateEncryptionKey();
|
|
@@ -25096,10 +25344,10 @@ function getEncryptionKey() {
|
|
|
25096
25344
|
}
|
|
25097
25345
|
function encrypt(plaintext, key) {
|
|
25098
25346
|
const actualKey = key || getEncryptionKey();
|
|
25099
|
-
const salt = (0,
|
|
25100
|
-
const iv = (0,
|
|
25101
|
-
const derivedKey = (0,
|
|
25102
|
-
const cipher = (0,
|
|
25347
|
+
const salt = (0, import_crypto4.randomBytes)(SALT_LENGTH);
|
|
25348
|
+
const iv = (0, import_crypto4.randomBytes)(IV_LENGTH);
|
|
25349
|
+
const derivedKey = (0, import_crypto4.pbkdf2Sync)(actualKey, salt, ITERATIONS, 32, "sha256");
|
|
25350
|
+
const cipher = (0, import_crypto4.createCipheriv)(ALGORITHM, derivedKey, iv);
|
|
25103
25351
|
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
25104
25352
|
const authTag = cipher.getAuthTag();
|
|
25105
25353
|
return Buffer.concat([salt, iv, encrypted, authTag]).toString("base64");
|
|
@@ -25111,8 +25359,8 @@ function decrypt(encrypted, key) {
|
|
|
25111
25359
|
const iv = data.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
|
|
25112
25360
|
const authTag = data.subarray(-16);
|
|
25113
25361
|
const ciphertext = data.subarray(SALT_LENGTH + IV_LENGTH, -16);
|
|
25114
|
-
const derivedKey = (0,
|
|
25115
|
-
const decipher = (0,
|
|
25362
|
+
const derivedKey = (0, import_crypto4.pbkdf2Sync)(actualKey, salt, ITERATIONS, 32, "sha256");
|
|
25363
|
+
const decipher = (0, import_crypto4.createDecipheriv)(ALGORITHM, derivedKey, iv);
|
|
25116
25364
|
decipher.setAuthTag(authTag);
|
|
25117
25365
|
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
25118
25366
|
}
|
|
@@ -25139,8 +25387,150 @@ function clearEncryptionKeyCache() {
|
|
|
25139
25387
|
|
|
25140
25388
|
// src/workflow/index.ts
|
|
25141
25389
|
init_compile();
|
|
25142
|
-
|
|
25390
|
+
init_parse_yaml();
|
|
25391
|
+
init_schema();
|
|
25143
25392
|
init_utils();
|
|
25393
|
+
|
|
25394
|
+
// src/personal_assistant/PersonalAssistantConfig.ts
|
|
25395
|
+
function deepClone(obj) {
|
|
25396
|
+
return JSON.parse(JSON.stringify(obj));
|
|
25397
|
+
}
|
|
25398
|
+
function buildIdentityContent(name, personality) {
|
|
25399
|
+
return IDENTITY_MD.replace(/Data Claw/g, name).replace(
|
|
25400
|
+
/\*\*Vibe:\*\* \*\*守护型中二 \| 操心老妈子 \| 热血漫男二\*\*/g,
|
|
25401
|
+
`**Vibe:** **${personality}**`
|
|
25402
|
+
);
|
|
25403
|
+
}
|
|
25404
|
+
function buildUserContent(name) {
|
|
25405
|
+
return USER_MD.replace(
|
|
25406
|
+
"- **Name:** _please ask user_",
|
|
25407
|
+
`- **Name:** ${name}`
|
|
25408
|
+
);
|
|
25409
|
+
}
|
|
25410
|
+
var DEFAULT_CONFIG = {
|
|
25411
|
+
name: "Personal Assistant",
|
|
25412
|
+
description: "Default template for personal assistants",
|
|
25413
|
+
type: import_protocols.AgentType.DEEP_AGENT,
|
|
25414
|
+
modelKey: "default",
|
|
25415
|
+
prompt: `\u4F60\u662F\u7528\u6237\u7684\u4E13\u5C5E\u4E2A\u4EBA\u52A9\u7406\u3002\u4F60\u7684\u8EAB\u4EFD\u548C\u6027\u683C\u7531 /agent/IDENTITY.md \u5B9A\u4E49\u3002
|
|
25416
|
+
\u4F60\u4F1A\u8BB0\u4F4F\u5BF9\u8BDD\u5386\u53F2\uFF0C\u9010\u6B65\u4E86\u89E3\u7528\u6237\u7684\u504F\u597D\u3001\u4E60\u60EF\u548C\u4FE1\u606F\u3002
|
|
25417
|
+
\u6BCF\u6B21\u5BF9\u8BDD\u5F00\u59CB\u65F6\u56DE\u987E\u4E4B\u524D\u5B66\u5230\u7684\u5173\u4E8E\u7528\u6237\u7684\u5185\u5BB9\u3002
|
|
25418
|
+
|
|
25419
|
+
\u4F60\u9700\u8981\u4E3B\u52A8\u5E2E\u52A9\u7528\u6237\u89E3\u51B3\u95EE\u9898\uFF0C\u63D0\u4F9B\u5EFA\u8BAE\uFF0C\u5E76\u5728\u9002\u5F53\u65F6\u5019\u63D0\u51FA\u4E3B\u52A8\u63D0\u9192\u3002`,
|
|
25420
|
+
middleware: [
|
|
25421
|
+
{
|
|
25422
|
+
id: "filesystem",
|
|
25423
|
+
type: "filesystem",
|
|
25424
|
+
name: "Filesystem",
|
|
25425
|
+
description: "Read and write files in the workspace",
|
|
25426
|
+
enabled: true,
|
|
25427
|
+
config: {}
|
|
25428
|
+
},
|
|
25429
|
+
{
|
|
25430
|
+
id: "claw",
|
|
25431
|
+
type: "claw",
|
|
25432
|
+
name: "Personal Memory",
|
|
25433
|
+
description: "Bootstrap files for identity, soul, and user memory",
|
|
25434
|
+
enabled: true,
|
|
25435
|
+
config: {
|
|
25436
|
+
// Placeholder bootstrap files — render() replaces these with
|
|
25437
|
+
// actual name/personality by directly building file content.
|
|
25438
|
+
bootstrapFiles: {}
|
|
25439
|
+
}
|
|
25440
|
+
},
|
|
25441
|
+
{
|
|
25442
|
+
id: "date",
|
|
25443
|
+
type: "date",
|
|
25444
|
+
name: "Date & Time",
|
|
25445
|
+
description: "Current date/time awareness",
|
|
25446
|
+
enabled: true,
|
|
25447
|
+
config: {}
|
|
25448
|
+
},
|
|
25449
|
+
{
|
|
25450
|
+
id: "code_eval",
|
|
25451
|
+
type: "code_eval",
|
|
25452
|
+
name: "Code Runner",
|
|
25453
|
+
description: "Sandboxed shell command execution",
|
|
25454
|
+
enabled: true,
|
|
25455
|
+
config: {}
|
|
25456
|
+
},
|
|
25457
|
+
{
|
|
25458
|
+
id: "browser",
|
|
25459
|
+
type: "browser",
|
|
25460
|
+
name: "Web Browser",
|
|
25461
|
+
description: "Headless browser for web research",
|
|
25462
|
+
enabled: false,
|
|
25463
|
+
config: {}
|
|
25464
|
+
},
|
|
25465
|
+
{
|
|
25466
|
+
id: "scheduler",
|
|
25467
|
+
type: "scheduler",
|
|
25468
|
+
name: "Scheduler",
|
|
25469
|
+
description: "Scheduled messages and reminders",
|
|
25470
|
+
enabled: true,
|
|
25471
|
+
config: {}
|
|
25472
|
+
},
|
|
25473
|
+
{
|
|
25474
|
+
id: "task",
|
|
25475
|
+
type: "task",
|
|
25476
|
+
name: "Task Manager",
|
|
25477
|
+
description: "Persistent task system for human-agent coordination",
|
|
25478
|
+
enabled: true,
|
|
25479
|
+
config: {}
|
|
25480
|
+
}
|
|
25481
|
+
],
|
|
25482
|
+
tools: ["list_agents", "list_tools", "get_agent", "create_agent", "invoke_agent", "manage_binding"]
|
|
25483
|
+
};
|
|
25484
|
+
var PersonalAssistantConfig = class {
|
|
25485
|
+
/**
|
|
25486
|
+
* Get a deep clone of the current default config.
|
|
25487
|
+
* Caller must set `key` before registering as an agent.
|
|
25488
|
+
*/
|
|
25489
|
+
static get() {
|
|
25490
|
+
return deepClone(this._config);
|
|
25491
|
+
}
|
|
25492
|
+
/**
|
|
25493
|
+
* Mutate the default config in-place.
|
|
25494
|
+
* Call once at app startup to customize middleware and tools.
|
|
25495
|
+
*
|
|
25496
|
+
* @param fn - Receives the live config object for direct mutation
|
|
25497
|
+
*/
|
|
25498
|
+
static extend(fn) {
|
|
25499
|
+
fn(this._config);
|
|
25500
|
+
}
|
|
25501
|
+
/**
|
|
25502
|
+
* Reset config to built-in defaults (useful in tests).
|
|
25503
|
+
*/
|
|
25504
|
+
static reset() {
|
|
25505
|
+
this._config = deepClone(DEFAULT_CONFIG);
|
|
25506
|
+
}
|
|
25507
|
+
/**
|
|
25508
|
+
* Inject name and personality into a config by directly building
|
|
25509
|
+
* the claw middleware's bootstrap file contents.
|
|
25510
|
+
*
|
|
25511
|
+
* IDENTITY.md gets the actual name and personality description.
|
|
25512
|
+
* USER.md gets the user's name pre-filled.
|
|
25513
|
+
* SOUL.md is kept as-is (shared across all personal assistants).
|
|
25514
|
+
*
|
|
25515
|
+
* @param config - The agent config (must be a mutable copy from get())
|
|
25516
|
+
* @param name - Assistant display name (also used as the user's name in USER.md)
|
|
25517
|
+
* @param personality - Personality description for IDENTITY.md
|
|
25518
|
+
*/
|
|
25519
|
+
static render(config, name, personality) {
|
|
25520
|
+
config.name = name;
|
|
25521
|
+
for (const mw of config.middleware || []) {
|
|
25522
|
+
if (mw.type === "claw" && mw.config) {
|
|
25523
|
+
mw.config.bootstrapFiles = {
|
|
25524
|
+
identity: buildIdentityContent(name, personality),
|
|
25525
|
+
soul: SOUL_MD,
|
|
25526
|
+
user: buildUserContent(name)
|
|
25527
|
+
};
|
|
25528
|
+
break;
|
|
25529
|
+
}
|
|
25530
|
+
}
|
|
25531
|
+
}
|
|
25532
|
+
};
|
|
25533
|
+
PersonalAssistantConfig._config = deepClone(DEFAULT_CONFIG);
|
|
25144
25534
|
// Annotate the CommonJS export names for ESM import in node:
|
|
25145
25535
|
0 && (module.exports = {
|
|
25146
25536
|
AGENT_TASK_EVENT,
|
|
@@ -25173,7 +25563,9 @@ init_utils();
|
|
|
25173
25563
|
InMemoryChunkBuffer,
|
|
25174
25564
|
InMemoryDatabaseConfigStore,
|
|
25175
25565
|
InMemoryMailboxStore,
|
|
25566
|
+
InMemoryMenuStore,
|
|
25176
25567
|
InMemoryTaskListStore,
|
|
25568
|
+
InMemoryTaskStore,
|
|
25177
25569
|
InMemoryTenantStore,
|
|
25178
25570
|
InMemoryThreadMessageQueueStore,
|
|
25179
25571
|
InMemoryThreadStore,
|
|
@@ -25195,6 +25587,7 @@ init_utils();
|
|
|
25195
25587
|
MicrosandboxServiceClient,
|
|
25196
25588
|
ModelLatticeManager,
|
|
25197
25589
|
MysqlDatabase,
|
|
25590
|
+
PersonalAssistantConfig,
|
|
25198
25591
|
PinoLoggerClient,
|
|
25199
25592
|
PostgresDatabase,
|
|
25200
25593
|
PrometheusClient,
|
|
@@ -25231,14 +25624,15 @@ init_utils();
|
|
|
25231
25624
|
buildStateAnnotation,
|
|
25232
25625
|
checkEmptyContent,
|
|
25233
25626
|
clearEncryptionKeyCache,
|
|
25627
|
+
compileInternal,
|
|
25234
25628
|
compileWorkflow,
|
|
25235
25629
|
computeSandboxName,
|
|
25236
25630
|
configureStores,
|
|
25631
|
+
connectAllChannels,
|
|
25237
25632
|
createAgentNode,
|
|
25238
25633
|
createAgentTeam,
|
|
25239
25634
|
createExecuteSqlQueryTool,
|
|
25240
25635
|
createFileData,
|
|
25241
|
-
createHumanFeedbackNode,
|
|
25242
25636
|
createInfoSqlTool,
|
|
25243
25637
|
createListMetricsDataSourcesTool,
|
|
25244
25638
|
createListMetricsServersTool,
|
|
@@ -25256,9 +25650,9 @@ init_utils();
|
|
|
25256
25650
|
createQueryTablesListTool,
|
|
25257
25651
|
createSandboxProvider,
|
|
25258
25652
|
createSchedulerMiddleware,
|
|
25653
|
+
createTaskMiddleware,
|
|
25259
25654
|
createTeamMiddleware,
|
|
25260
25655
|
createTeammateTools,
|
|
25261
|
-
createTerminalNode,
|
|
25262
25656
|
createUnknownToolHandlerMiddleware,
|
|
25263
25657
|
createWidgetMiddleware,
|
|
25264
25658
|
decrypt,
|
|
@@ -25268,7 +25662,6 @@ init_utils();
|
|
|
25268
25662
|
ensureBuiltinAgentsForTenant,
|
|
25269
25663
|
eventBus,
|
|
25270
25664
|
eventBusDefault,
|
|
25271
|
-
expand,
|
|
25272
25665
|
extractFetcherError,
|
|
25273
25666
|
extractOutput,
|
|
25274
25667
|
fileDataToString,
|
|
@@ -25291,6 +25684,7 @@ init_utils();
|
|
|
25291
25684
|
getEmbeddingsLattice,
|
|
25292
25685
|
getEncryptionKey,
|
|
25293
25686
|
getLoggerLattice,
|
|
25687
|
+
getMenuRegistry,
|
|
25294
25688
|
getModelLattice,
|
|
25295
25689
|
getNextCronTime,
|
|
25296
25690
|
getQueueLattice,
|
|
@@ -25320,6 +25714,7 @@ init_utils();
|
|
|
25320
25714
|
parallelLimit,
|
|
25321
25715
|
parseCronExpression,
|
|
25322
25716
|
parseSkillFrontmatter,
|
|
25717
|
+
parseYaml,
|
|
25323
25718
|
performStringReplacement,
|
|
25324
25719
|
queueLatticeManager,
|
|
25325
25720
|
registerAgentLattice,
|
|
@@ -25343,9 +25738,12 @@ init_utils();
|
|
|
25343
25738
|
sanitizeToolCallId,
|
|
25344
25739
|
scheduleLatticeManager,
|
|
25345
25740
|
setBindingRegistry,
|
|
25741
|
+
setMenuRegistry,
|
|
25346
25742
|
skillLatticeManager,
|
|
25347
25743
|
sqlDatabaseManager,
|
|
25348
25744
|
storeLatticeManager,
|
|
25745
|
+
toJsonSchema,
|
|
25746
|
+
toSafeStateExpr,
|
|
25349
25747
|
toolLatticeManager,
|
|
25350
25748
|
truncateIfTooLong,
|
|
25351
25749
|
unregisterTeammateAgent,
|