@aipack-ai/multi-agent 1.1.6 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -57,6 +57,10 @@ function createSharedContext(init) {
57
57
  meta: init?.meta ?? {}
58
58
  };
59
59
  }
60
+ function storeOriginalInput(ctx, input) {
61
+ const inputText = typeof input === "string" ? input : input.message;
62
+ ctx.blackboard.set("__original_input__", inputText);
63
+ }
60
64
 
61
65
  // ../agent/core/types.ts
62
66
  function extractText(content) {
@@ -2478,7 +2482,55 @@ function createRuntime(options) {
2478
2482
  return AgentRuntime.create(options);
2479
2483
  }
2480
2484
 
2485
+ // core/event-stream.ts
2486
+ function createEventStream(execute, sink) {
2487
+ const eventQueue = [];
2488
+ let resolveEvent = null;
2489
+ let done = false;
2490
+ const emit = (event) => {
2491
+ eventQueue.push(event);
2492
+ if (sink) {
2493
+ try {
2494
+ sink(event);
2495
+ } catch {
2496
+ }
2497
+ }
2498
+ resolveEvent?.();
2499
+ };
2500
+ const graphPromise = execute(emit).finally(() => {
2501
+ done = true;
2502
+ resolveEvent?.();
2503
+ });
2504
+ return (async function* () {
2505
+ while (!done || eventQueue.length > 0) {
2506
+ if (eventQueue.length > 0) {
2507
+ yield eventQueue.shift();
2508
+ } else {
2509
+ await new Promise((resolve) => {
2510
+ resolveEvent = resolve;
2511
+ });
2512
+ }
2513
+ }
2514
+ await graphPromise;
2515
+ })();
2516
+ }
2517
+
2481
2518
  // core/executor.ts
2519
+ var GraphAbortedError = class extends Error {
2520
+ constructor() {
2521
+ super("AgentGraph: \u6267\u884C\u5DF2\u88AB\u4E2D\u6B62");
2522
+ this.name = "GraphAbortedError";
2523
+ }
2524
+ };
2525
+ function toInputText(input) {
2526
+ return typeof input === "string" ? input : input.message;
2527
+ }
2528
+ var NodeTimeoutError = class extends Error {
2529
+ constructor(nodeId, timeoutMs) {
2530
+ super(`AgentGraph: \u8282\u70B9 "${nodeId}" \u6267\u884C\u8D85\u65F6\uFF08${timeoutMs}ms\uFF09`);
2531
+ this.name = "NodeTimeoutError";
2532
+ }
2533
+ };
2482
2534
  var runtimeCache = /* @__PURE__ */ new WeakMap();
2483
2535
  function ensureRuntime(node) {
2484
2536
  let rt = runtimeCache.get(node);
@@ -2491,19 +2543,52 @@ function ensureRuntime(node) {
2491
2543
  runtimeCache.set(node, rt);
2492
2544
  return rt;
2493
2545
  }
2494
- async function executeNode(node, input, ctx) {
2546
+ async function executeNodeOnce(node, req) {
2495
2547
  const runtime = ensureRuntime(node);
2548
+ if (node.timeoutMs != null && node.timeoutMs > 0) {
2549
+ let timer;
2550
+ try {
2551
+ return await Promise.race([
2552
+ runtime.run(req),
2553
+ new Promise((_, reject) => {
2554
+ timer = setTimeout(() => reject(new NodeTimeoutError(node.id, node.timeoutMs)), node.timeoutMs);
2555
+ })
2556
+ ]);
2557
+ } finally {
2558
+ if (timer !== void 0) clearTimeout(timer);
2559
+ }
2560
+ }
2561
+ return runtime.run(req);
2562
+ }
2563
+ async function executeNode(node, input, ctx) {
2496
2564
  let req;
2497
2565
  if (typeof input === "string") {
2498
2566
  req = createRequest(input, { sessionKey: `multi-agent:${node.id}` });
2499
2567
  } else {
2500
2568
  req = { ...input, sessionKey: input.sessionKey ?? `multi-agent:${node.id}` };
2501
2569
  }
2502
- const result = await runtime.run(req);
2570
+ const maxAttempts = Math.max(1, node.retry?.maxAttempts ?? 1);
2571
+ const backoffMs = node.retry?.backoffMs ?? 0;
2572
+ let lastErr;
2573
+ let succeeded;
2574
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
2575
+ if (attempt > 1 && backoffMs > 0) {
2576
+ await new Promise((resolve) => setTimeout(resolve, backoffMs));
2577
+ }
2578
+ try {
2579
+ succeeded = await executeNodeOnce(node, req);
2580
+ break;
2581
+ } catch (err) {
2582
+ lastErr = err;
2583
+ }
2584
+ }
2585
+ if (succeeded === void 0) {
2586
+ throw lastErr;
2587
+ }
2503
2588
  if (node.outputMapping) {
2504
- node.outputMapping(result, ctx);
2589
+ node.outputMapping(succeeded, ctx);
2505
2590
  }
2506
- return result;
2591
+ return succeeded;
2507
2592
  }
2508
2593
  function resolveInput(edge, prevResult, ctx, node, originalInput) {
2509
2594
  if (edge?.transform) {
@@ -2530,12 +2615,22 @@ var GraphExecutor = class {
2530
2615
  entryId;
2531
2616
  finishCondition;
2532
2617
  abortController = new AbortController();
2618
+ /** 外部事件监听(on() API 的底层接线),事件会同步分发 */
2619
+ eventSink;
2620
+ /** 并行分支最大并发数(默认不限制) */
2621
+ concurrency;
2622
+ /** 单节点最大访问次数(环图防死循环) */
2623
+ maxVisitsPerNode;
2533
2624
  state = {
2534
2625
  nodeStates: /* @__PURE__ */ new Map(),
2535
2626
  nodeResults: /* @__PURE__ */ new Map(),
2536
2627
  stepsCompleted: 0,
2537
2628
  finished: false
2538
2629
  };
2630
+ constructor(opts) {
2631
+ this.concurrency = opts?.concurrency ?? Infinity;
2632
+ this.maxVisitsPerNode = opts?.maxVisitsPerNode ?? 10;
2633
+ }
2539
2634
  addNode(node) {
2540
2635
  this.nodes.set(node.id, node);
2541
2636
  this.state.nodeStates.set(node.id, "pending");
@@ -2553,12 +2648,42 @@ var GraphExecutor = class {
2553
2648
  this.finishCondition = condition;
2554
2649
  return this;
2555
2650
  }
2651
+ /** 注入外部事件监听(由 AgentGraph 实现的 on() 接线) */
2652
+ setEventSink(sink) {
2653
+ this.eventSink = sink;
2654
+ return this;
2655
+ }
2556
2656
  getState() {
2557
- return { ...this.state };
2657
+ return {
2658
+ ...this.state,
2659
+ nodeStates: new Map(this.state.nodeStates),
2660
+ nodeResults: new Map(this.state.nodeResults)
2661
+ };
2558
2662
  }
2559
2663
  abort() {
2560
2664
  this.abortController.abort();
2561
2665
  }
2666
+ /** 每次 run/stream 前重置中止信号,避免上一次的 abort 永久失效 */
2667
+ resetAbortController() {
2668
+ this.abortController = new AbortController();
2669
+ }
2670
+ /** 每次 run/stream 前重置执行状态,避免残留上一次的 nodeStates/结果 */
2671
+ resetState() {
2672
+ this.state = {
2673
+ nodeStates: /* @__PURE__ */ new Map(),
2674
+ nodeResults: /* @__PURE__ */ new Map(),
2675
+ stepsCompleted: 0,
2676
+ finished: false
2677
+ };
2678
+ for (const id of this.nodes.keys()) {
2679
+ this.state.nodeStates.set(id, "pending");
2680
+ }
2681
+ }
2682
+ throwIfAborted() {
2683
+ if (this.abortController.signal.aborted) {
2684
+ throw new GraphAbortedError();
2685
+ }
2686
+ }
2562
2687
  /** 同步执行图 */
2563
2688
  async run(input) {
2564
2689
  if (!this.entryId) {
@@ -2567,66 +2692,78 @@ var GraphExecutor = class {
2567
2692
  if (!this.nodes.has(this.entryId)) {
2568
2693
  throw new Error(`AgentGraph: \u5165\u53E3\u8282\u70B9 "${this.entryId}" \u4E0D\u5B58\u5728`);
2569
2694
  }
2695
+ this.resetAbortController();
2696
+ this.resetState();
2570
2697
  const ctx = createSharedContext({
2571
2698
  meta: { traceId: `ma-${Date.now()}`, startTime: Date.now() }
2572
2699
  });
2573
- const events = [];
2700
+ storeOriginalInput(ctx, input);
2701
+ const emit = this.eventSink ?? (() => {
2702
+ });
2574
2703
  try {
2575
- const result = await this.executeGraph(input, ctx, (event) => events.push(event));
2704
+ const result = await this.executeGraph(input, ctx, emit);
2705
+ emit({ type: "graph_done", result });
2576
2706
  return result;
2577
2707
  } catch (err) {
2708
+ const errorMsg = err instanceof Error ? err.message : String(err);
2709
+ this.state.error = errorMsg;
2710
+ if (err instanceof GraphAbortedError) {
2711
+ const lastCompleted = [...this.state.nodeResults.values()].at(-1);
2712
+ const abortedResult = {
2713
+ content: lastCompleted?.content ?? "",
2714
+ lastAgentId: this.state.currentAgentId ?? "",
2715
+ agentResults: new Map(this.state.nodeResults),
2716
+ totalUsage: {},
2717
+ stepsCompleted: this.state.stepsCompleted,
2718
+ stopReason: "aborted",
2719
+ context: ctx,
2720
+ success: false,
2721
+ error: err.message
2722
+ };
2723
+ emit({ type: "graph_error", error: err.message });
2724
+ return abortedResult;
2725
+ }
2726
+ emit({ type: "graph_error", error: errorMsg });
2578
2727
  return {
2579
2728
  content: "",
2580
2729
  lastAgentId: this.state.currentAgentId ?? "",
2581
- agentResults: this.state.nodeResults,
2730
+ agentResults: new Map(this.state.nodeResults),
2582
2731
  totalUsage: {},
2583
2732
  stepsCompleted: this.state.stepsCompleted,
2584
2733
  stopReason: "error",
2585
2734
  context: ctx,
2586
2735
  success: false,
2587
- error: err instanceof Error ? err.message : String(err)
2736
+ error: errorMsg
2588
2737
  };
2589
2738
  }
2590
2739
  }
2591
2740
  /** 流式执行图 */
2592
- async *stream(input) {
2741
+ stream(input) {
2593
2742
  if (!this.entryId) {
2594
2743
  throw new Error("AgentGraph: \u5165\u53E3\u8282\u70B9\u672A\u8BBE\u7F6E\uFF0C\u8BF7\u8C03\u7528 setEntry()");
2595
2744
  }
2596
2745
  if (!this.nodes.has(this.entryId)) {
2597
2746
  throw new Error(`AgentGraph: \u5165\u53E3\u8282\u70B9 "${this.entryId}" \u4E0D\u5B58\u5728`);
2598
2747
  }
2748
+ this.resetAbortController();
2749
+ this.resetState();
2599
2750
  const ctx = createSharedContext({
2600
2751
  meta: { traceId: `ma-${Date.now()}`, startTime: Date.now() }
2601
2752
  });
2602
- const eventQueue = [];
2603
- let resolveEvent = null;
2604
- let done = false;
2605
- const emit = (event) => {
2606
- eventQueue.push(event);
2607
- resolveEvent?.();
2608
- };
2609
- const graphPromise = this.executeGraph(input, ctx, emit).then(
2610
- (result) => {
2611
- emit({ type: "graph_done", result });
2612
- },
2613
- (err) => {
2614
- emit({ type: "graph_error", error: err instanceof Error ? err.message : String(err) });
2615
- }
2616
- ).finally(() => {
2617
- done = true;
2618
- resolveEvent?.();
2619
- });
2620
- while (!done || eventQueue.length > 0) {
2621
- if (eventQueue.length > 0) {
2622
- yield eventQueue.shift();
2623
- } else {
2624
- await new Promise((resolve) => {
2625
- resolveEvent = resolve;
2626
- });
2627
- }
2628
- }
2629
- await graphPromise;
2753
+ storeOriginalInput(ctx, input);
2754
+ return createEventStream(
2755
+ (emit) => this.executeGraph(input, ctx, emit).then(
2756
+ (result) => {
2757
+ emit({ type: "graph_done", result });
2758
+ },
2759
+ (err) => {
2760
+ const errorMsg = err instanceof Error ? err.message : String(err);
2761
+ this.state.error = errorMsg;
2762
+ emit({ type: "graph_error", error: errorMsg });
2763
+ }
2764
+ ),
2765
+ this.eventSink
2766
+ );
2630
2767
  }
2631
2768
  /** 核心执行逻辑 */
2632
2769
  async executeGraph(input, ctx, emit) {
@@ -2639,7 +2776,7 @@ var GraphExecutor = class {
2639
2776
  const totalUsage = {};
2640
2777
  this.state.currentAgentId = currentId;
2641
2778
  this.state.nodeStates.set(currentId, "running");
2642
- emit({ type: "agent_start", agentId: currentId, agentName: entryNode.name });
2779
+ emit({ type: "agent_start", agentId: currentId, agentName: entryNode.name, input: toInputText(currentInput) });
2643
2780
  try {
2644
2781
  lastResult = await executeNode(entryNode, currentInput, ctx);
2645
2782
  this.state.nodeStates.set(currentId, "completed");
@@ -2658,50 +2795,134 @@ var GraphExecutor = class {
2658
2795
  if (this.finishCondition?.(ctx)) {
2659
2796
  return this.buildResult(lastResult, lastAgentId, ctx, totalUsage, stepsCompleted, "finish_condition");
2660
2797
  }
2661
- const visited = /* @__PURE__ */ new Set();
2798
+ let frontier = [{ id: currentId, result: lastResult }];
2662
2799
  const visitCount = /* @__PURE__ */ new Map();
2663
- const MAX_VISITS_PER_NODE = 10;
2664
- while (lastResult) {
2665
- const nextEdges = findNextEdges(currentId, this.edges, lastResult, ctx);
2666
- if (nextEdges.length === 0) {
2800
+ let stopReason = "completed";
2801
+ while (frontier.length > 0) {
2802
+ this.throwIfAborted();
2803
+ const candidates = [];
2804
+ const seenTargets = /* @__PURE__ */ new Set();
2805
+ for (const from of frontier) {
2806
+ const nextEdges = findNextEdges(from.id, this.edges, from.result, ctx);
2807
+ for (const edge of nextEdges) {
2808
+ if (seenTargets.has(edge.to)) continue;
2809
+ seenTargets.add(edge.to);
2810
+ const nextNode = this.nodes.get(edge.to);
2811
+ if (!nextNode) {
2812
+ throw new Error(`AgentGraph: \u76EE\u6807\u8282\u70B9 "${edge.to}" \u4E0D\u5B58\u5728`);
2813
+ }
2814
+ candidates.push({ edge, from, node: nextNode });
2815
+ }
2816
+ }
2817
+ if (candidates.length === 0) {
2667
2818
  break;
2668
2819
  }
2669
- const edge = nextEdges[0];
2670
- const nextNode = this.nodes.get(edge.to);
2671
- if (!nextNode) {
2672
- throw new Error(`AgentGraph: \u76EE\u6807\u8282\u70B9 "${edge.to}" \u4E0D\u5B58\u5728`);
2820
+ const allowed = [];
2821
+ let truncated = false;
2822
+ for (const c of candidates) {
2823
+ const count = (visitCount.get(c.edge.to) ?? 0) + 1;
2824
+ if (count > this.maxVisitsPerNode) {
2825
+ truncated = true;
2826
+ continue;
2827
+ }
2828
+ visitCount.set(c.edge.to, count);
2829
+ allowed.push(c);
2673
2830
  }
2674
- const count = (visitCount.get(edge.to) ?? 0) + 1;
2675
- if (count > MAX_VISITS_PER_NODE) {
2831
+ if (allowed.length === 0) {
2832
+ if (truncated) stopReason = "max_visits_exceeded";
2676
2833
  break;
2677
2834
  }
2678
- visitCount.set(edge.to, count);
2679
- currentInput = resolveInput(edge, lastResult, ctx, nextNode, input);
2680
- currentId = edge.to;
2681
- this.state.currentAgentId = currentId;
2682
- this.state.nodeStates.set(currentId, "running");
2683
- emit({ type: "edge_traversed", from: edge.from, to: edge.to });
2684
- emit({ type: "agent_start", agentId: currentId, agentName: nextNode.name });
2685
- try {
2686
- lastResult = await executeNode(nextNode, currentInput, ctx);
2687
- this.state.nodeStates.set(currentId, "completed");
2688
- this.state.nodeResults.set(currentId, lastResult);
2689
- this.mergeUsage(totalUsage, lastResult.usage);
2835
+ const tasks = allowed.map((c) => ({
2836
+ node: c.node,
2837
+ input: resolveInput(c.edge, c.from.result, ctx, c.node, input),
2838
+ fromId: c.edge.from
2839
+ }));
2840
+ let waveResults;
2841
+ if (tasks.length === 1) {
2842
+ const t = tasks[0];
2843
+ this.state.currentAgentId = t.node.id;
2844
+ this.state.nodeStates.set(t.node.id, "running");
2845
+ emit({ type: "edge_traversed", from: t.fromId, to: t.node.id });
2846
+ emit({ type: "agent_start", agentId: t.node.id, agentName: t.node.name, input: toInputText(t.input) });
2847
+ let result;
2848
+ try {
2849
+ result = await executeNode(t.node, t.input, ctx);
2850
+ } catch (err) {
2851
+ const errorMsg = err instanceof Error ? err.message : String(err);
2852
+ this.state.nodeStates.set(t.node.id, "failed");
2853
+ emit({ type: "agent_error", agentId: t.node.id, agentName: t.node.name, error: errorMsg });
2854
+ throw err;
2855
+ }
2856
+ this.state.nodeStates.set(t.node.id, "completed");
2857
+ this.state.nodeResults.set(t.node.id, result);
2858
+ this.mergeUsage(totalUsage, result.usage);
2690
2859
  stepsCompleted++;
2691
2860
  this.state.stepsCompleted = stepsCompleted;
2692
- emit({ type: "agent_result", agentId: currentId, agentName: nextNode.name, result: lastResult });
2861
+ emit({ type: "agent_result", agentId: t.node.id, agentName: t.node.name, result });
2862
+ waveResults = [{ id: t.node.id, result }];
2863
+ } else {
2864
+ waveResults = await this.executeWave(tasks, ctx, emit, totalUsage);
2865
+ stepsCompleted += waveResults.length;
2866
+ this.state.stepsCompleted = stepsCompleted;
2867
+ }
2868
+ lastResult = waveResults[waveResults.length - 1].result;
2869
+ lastAgentId = waveResults[waveResults.length - 1].id;
2870
+ frontier = waveResults;
2871
+ if (this.finishCondition?.(ctx)) {
2872
+ return this.buildResult(lastResult, lastAgentId, ctx, totalUsage, stepsCompleted, "finish_condition");
2873
+ }
2874
+ }
2875
+ return this.buildResult(lastResult, lastAgentId, ctx, totalUsage, stepsCompleted, stopReason);
2876
+ }
2877
+ /** 并行执行一个 wave 的节点(fail-fast + concurrency 限流) */
2878
+ async executeWave(tasks, ctx, emit, totalUsage) {
2879
+ const results = [];
2880
+ emit({ type: "parallel_start", agentIds: tasks.map((t) => t.node.id) });
2881
+ const runOne = async (t) => {
2882
+ this.state.currentAgentId = t.node.id;
2883
+ this.state.nodeStates.set(t.node.id, "running");
2884
+ emit({ type: "edge_traversed", from: t.fromId, to: t.node.id });
2885
+ emit({ type: "agent_start", agentId: t.node.id, agentName: t.node.name, input: toInputText(t.input) });
2886
+ try {
2887
+ const result = await executeNode(t.node, t.input, ctx);
2888
+ this.state.nodeStates.set(t.node.id, "completed");
2889
+ this.state.nodeResults.set(t.node.id, result);
2890
+ this.mergeUsage(totalUsage, result.usage);
2891
+ results.push({ id: t.node.id, result });
2892
+ emit({ type: "agent_result", agentId: t.node.id, agentName: t.node.name, result });
2693
2893
  } catch (err) {
2694
2894
  const errorMsg = err instanceof Error ? err.message : String(err);
2695
- this.state.nodeStates.set(currentId, "failed");
2696
- emit({ type: "agent_error", agentId: currentId, agentName: nextNode.name, error: errorMsg });
2895
+ this.state.nodeStates.set(t.node.id, "failed");
2896
+ emit({ type: "agent_error", agentId: t.node.id, agentName: t.node.name, error: errorMsg });
2697
2897
  throw err;
2698
2898
  }
2699
- lastAgentId = currentId;
2700
- if (this.finishCondition?.(ctx)) {
2701
- return this.buildResult(lastResult, lastAgentId, ctx, totalUsage, stepsCompleted, "finish_condition");
2899
+ };
2900
+ if (this.concurrency >= tasks.length) {
2901
+ await Promise.all(tasks.map((t) => runOne(t)));
2902
+ } else {
2903
+ let index = 0;
2904
+ const executing = /* @__PURE__ */ new Set();
2905
+ const enqueue = () => {
2906
+ if (index >= tasks.length) return null;
2907
+ const i = index++;
2908
+ const p = runOne(tasks[i]).finally(() => {
2909
+ executing.delete(p);
2910
+ });
2911
+ executing.add(p);
2912
+ p.catch(() => {
2913
+ });
2914
+ return p;
2915
+ };
2916
+ for (let i = 0; i < this.concurrency && index < tasks.length; i++) {
2917
+ enqueue();
2918
+ }
2919
+ while (executing.size > 0) {
2920
+ await Promise.race(executing);
2921
+ enqueue();
2702
2922
  }
2703
2923
  }
2704
- return this.buildResult(lastResult, lastAgentId, ctx, totalUsage, stepsCompleted, "completed");
2924
+ emit({ type: "parallel_done", results: new Map(results.map((r) => [r.id, r.result])) });
2925
+ return results;
2705
2926
  }
2706
2927
  buildResult(lastResult, lastAgentId, ctx, totalUsage, stepsCompleted, stopReason) {
2707
2928
  this.state.finished = true;
@@ -2726,8 +2947,12 @@ var GraphExecutor = class {
2726
2947
 
2727
2948
  // core/graph.ts
2728
2949
  var AgentGraphImpl = class {
2729
- executor = new GraphExecutor();
2730
- eventListeners = /* @__PURE__ */ new Map();
2950
+ executor;
2951
+ /** on() 注册的监听器,按 MultiAgentEvent.type 分发 */
2952
+ bus = new SimpleEventBus();
2953
+ constructor(opts) {
2954
+ this.executor = new GraphExecutor(opts);
2955
+ }
2731
2956
  addNode(node) {
2732
2957
  this.executor.addNode(node);
2733
2958
  return this;
@@ -2745,9 +2970,11 @@ var AgentGraphImpl = class {
2745
2970
  return this;
2746
2971
  }
2747
2972
  async run(input) {
2973
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
2748
2974
  return this.executor.run(input);
2749
2975
  }
2750
2976
  async *stream(input) {
2977
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
2751
2978
  yield* this.executor.stream(input);
2752
2979
  }
2753
2980
  getState() {
@@ -2757,17 +2984,12 @@ var AgentGraphImpl = class {
2757
2984
  this.executor.abort();
2758
2985
  }
2759
2986
  on(event, listener) {
2760
- let set = this.eventListeners.get(event);
2761
- if (!set) {
2762
- set = /* @__PURE__ */ new Set();
2763
- this.eventListeners.set(event, set);
2764
- }
2765
- set.add(listener);
2987
+ this.bus.on(event, listener);
2766
2988
  return this;
2767
2989
  }
2768
2990
  };
2769
- function createAgentGraph() {
2770
- return new AgentGraphImpl();
2991
+ function createAgentGraph(opts) {
2992
+ return new AgentGraphImpl(opts);
2771
2993
  }
2772
2994
 
2773
2995
  // patterns/pipeline.ts
@@ -2805,14 +3027,19 @@ function createRouter(router, targets, opts) {
2805
3027
  }
2806
3028
  graph.setEntry(router.id);
2807
3029
  const targetIds = new Set(targets.map((t) => t.id));
3030
+ const defaultTarget = opts.defaultTarget && targetIds.has(opts.defaultTarget) ? opts.defaultTarget : void 0;
3031
+ const resolveTarget = (routerResult) => {
3032
+ const resolvedId = opts.resolve(routerResult);
3033
+ if (targetIds.has(resolvedId)) return resolvedId;
3034
+ return defaultTarget ?? resolvedId;
3035
+ };
2808
3036
  for (const target of targets) {
2809
3037
  graph.addEdge({
2810
3038
  from: router.id,
2811
3039
  to: target.id,
2812
- // 条件:从路由器结果中解析目标ID,匹配当前目标
3040
+ // 条件:从路由器结果中解析目标ID(含 defaultTarget 兜底),匹配当前目标
2813
3041
  condition: (routerResult, _ctx) => {
2814
- const resolvedId = opts.resolve(routerResult);
2815
- return resolvedId === target.id;
3042
+ return resolveTarget(routerResult) === target.id;
2816
3043
  },
2817
3044
  // 转换:决定传给目标Agent的输入
2818
3045
  transform: (_routerResult, _ctx) => {
@@ -2824,8 +3051,6 @@ function createRouter(router, targets, opts) {
2824
3051
  }
2825
3052
  });
2826
3053
  }
2827
- if (opts.defaultTarget && targetIds.has(opts.defaultTarget)) {
2828
- }
2829
3054
  return graph;
2830
3055
  }
2831
3056
 
@@ -2834,6 +3059,11 @@ var SupervisorExecutor = class {
2834
3059
  supervisorNode;
2835
3060
  workerNodes;
2836
3061
  opts;
3062
+ abortController = new AbortController();
3063
+ /** 外部事件监听(on() API 的底层接线) */
3064
+ eventSink;
3065
+ /** 最近一次 run 中失败的 Worker ID(onWorkerError='skip' 时使用) */
3066
+ failedAgents = [];
2837
3067
  state = {
2838
3068
  nodeStates: /* @__PURE__ */ new Map(),
2839
3069
  nodeResults: /* @__PURE__ */ new Map(),
@@ -2846,7 +3076,8 @@ var SupervisorExecutor = class {
2846
3076
  this.opts = {
2847
3077
  schedule: opts?.schedule ?? "parallel",
2848
3078
  concurrency: opts?.concurrency ?? Infinity,
2849
- passOriginalInput: opts?.passOriginalInput ?? true
3079
+ passOriginalInput: opts?.passOriginalInput ?? true,
3080
+ onWorkerError: opts?.onWorkerError ?? "fail-fast"
2850
3081
  };
2851
3082
  this.state.nodeStates.set(supervisor.id, "pending");
2852
3083
  for (const w of workers) {
@@ -2854,69 +3085,91 @@ var SupervisorExecutor = class {
2854
3085
  }
2855
3086
  }
2856
3087
  getState() {
2857
- return { ...this.state };
3088
+ return {
3089
+ ...this.state,
3090
+ nodeStates: new Map(this.state.nodeStates),
3091
+ nodeResults: new Map(this.state.nodeResults)
3092
+ };
3093
+ }
3094
+ /** 注入外部事件监听(由 AgentGraph 实现的 on() 接线) */
3095
+ setEventSink(sink) {
3096
+ this.eventSink = sink;
3097
+ return this;
3098
+ }
3099
+ abort() {
3100
+ this.abortController.abort();
3101
+ }
3102
+ /** 每次 run/stream 前重置中止信号、失败记录与执行状态 */
3103
+ resetRun() {
3104
+ this.abortController = new AbortController();
3105
+ this.failedAgents = [];
3106
+ this.state = {
3107
+ nodeStates: /* @__PURE__ */ new Map(),
3108
+ nodeResults: /* @__PURE__ */ new Map(),
3109
+ stepsCompleted: 0,
3110
+ finished: false
3111
+ };
3112
+ this.state.nodeStates.set(this.supervisorNode.id, "pending");
3113
+ for (const w of this.workerNodes) {
3114
+ this.state.nodeStates.set(w.id, "pending");
3115
+ }
3116
+ }
3117
+ throwIfAborted() {
3118
+ if (this.abortController.signal.aborted) {
3119
+ throw new GraphAbortedError();
3120
+ }
2858
3121
  }
2859
3122
  /** 执行 Supervisor 模式 */
2860
3123
  async run(input) {
3124
+ this.resetRun();
2861
3125
  const ctx = createSharedContext({
2862
3126
  meta: { traceId: `sv-${Date.now()}`, startTime: Date.now() }
2863
3127
  });
2864
3128
  if (this.opts.passOriginalInput) {
2865
- const inputText = typeof input === "string" ? input : input.message;
2866
- ctx.blackboard.set("__original_input__", inputText);
3129
+ storeOriginalInput(ctx, input);
2867
3130
  }
3131
+ const emit = this.eventSink ?? (() => {
3132
+ });
2868
3133
  try {
2869
- return await this.executeSupervisor(input, ctx, () => {
2870
- });
3134
+ const result = await this.executeSupervisor(input, ctx, emit);
3135
+ emit({ type: "graph_done", result });
3136
+ return result;
2871
3137
  } catch (err) {
2872
- return this.buildErrorResult(ctx, err);
3138
+ const result = this.buildErrorResult(ctx, err);
3139
+ emit({ type: "graph_error", error: result.error ?? "" });
3140
+ return result;
2873
3141
  }
2874
3142
  }
2875
3143
  /** 流式执行 Supervisor 模式 */
2876
- async *stream(input) {
3144
+ stream(input) {
3145
+ this.resetRun();
2877
3146
  const ctx = createSharedContext({
2878
3147
  meta: { traceId: `sv-${Date.now()}`, startTime: Date.now() }
2879
3148
  });
2880
3149
  if (this.opts.passOriginalInput) {
2881
- const inputText = typeof input === "string" ? input : input.message;
2882
- ctx.blackboard.set("__original_input__", inputText);
2883
- }
2884
- const eventQueue = [];
2885
- let resolveEvent = null;
2886
- let done = false;
2887
- const emit = (event) => {
2888
- eventQueue.push(event);
2889
- resolveEvent?.();
2890
- };
2891
- const graphPromise = this.executeSupervisor(input, ctx, emit).then(
2892
- (result) => {
2893
- emit({ type: "graph_done", result });
2894
- },
2895
- (err) => {
2896
- emit({ type: "graph_error", error: err instanceof Error ? err.message : String(err) });
2897
- }
2898
- ).finally(() => {
2899
- done = true;
2900
- resolveEvent?.();
2901
- });
2902
- while (!done || eventQueue.length > 0) {
2903
- if (eventQueue.length > 0) {
2904
- yield eventQueue.shift();
2905
- } else {
2906
- await new Promise((resolve) => {
2907
- resolveEvent = resolve;
2908
- });
2909
- }
3150
+ storeOriginalInput(ctx, input);
2910
3151
  }
2911
- await graphPromise;
3152
+ return createEventStream(
3153
+ (emit) => this.executeSupervisor(input, ctx, emit).then(
3154
+ (result) => {
3155
+ emit({ type: "graph_done", result });
3156
+ },
3157
+ (err) => {
3158
+ this.state.error = err instanceof Error ? err.message : String(err);
3159
+ emit({ type: "graph_error", error: this.state.error });
3160
+ }
3161
+ ),
3162
+ this.eventSink
3163
+ );
2912
3164
  }
2913
3165
  /** 核心执行逻辑 */
2914
3166
  async executeSupervisor(input, ctx, emit) {
2915
3167
  let stepsCompleted = 0;
2916
3168
  const totalUsage = {};
3169
+ this.throwIfAborted();
2917
3170
  this.state.currentAgentId = this.supervisorNode.id;
2918
3171
  this.state.nodeStates.set(this.supervisorNode.id, "running");
2919
- emit({ type: "agent_start", agentId: this.supervisorNode.id, agentName: this.supervisorNode.name });
3172
+ emit({ type: "agent_start", agentId: this.supervisorNode.id, agentName: this.supervisorNode.name, input: toInputText(input) });
2920
3173
  let supervisorResult;
2921
3174
  try {
2922
3175
  supervisorResult = await executeNode(this.supervisorNode, input, ctx);
@@ -2943,18 +3196,21 @@ var SupervisorExecutor = class {
2943
3196
  }
2944
3197
  stepsCompleted += workerResults.size;
2945
3198
  this.state.stepsCompleted = stepsCompleted;
2946
- const lastWorkerId = this.workerNodes[this.workerNodes.length - 1].id;
2947
- const finalResult = workerResults.get(lastWorkerId) ?? supervisorResult;
3199
+ const lastEntry = [...workerResults.entries()].at(-1);
3200
+ const finalResult = lastEntry?.[1] ?? supervisorResult;
3201
+ const finalAgentId = lastEntry?.[0] ?? this.supervisorNode.id;
3202
+ const hasFailures = this.failedAgents.length > 0;
2948
3203
  this.state.finished = true;
2949
3204
  return {
2950
3205
  content: finalResult.content,
2951
- lastAgentId: lastWorkerId,
3206
+ lastAgentId: finalAgentId,
2952
3207
  agentResults: new Map(this.state.nodeResults),
2953
3208
  totalUsage,
2954
3209
  stepsCompleted,
2955
- stopReason: "completed",
3210
+ stopReason: hasFailures ? "partial_failure" : "completed",
2956
3211
  context: ctx,
2957
- success: true
3212
+ success: true,
3213
+ ...hasFailures ? { failedAgents: [...this.failedAgents] } : {}
2958
3214
  };
2959
3215
  }
2960
3216
  /** 并行执行所有 Worker */
@@ -2962,16 +3218,28 @@ var SupervisorExecutor = class {
2962
3218
  const results = /* @__PURE__ */ new Map();
2963
3219
  const workers = this.workerNodes;
2964
3220
  const concurrency = this.opts.concurrency;
3221
+ const skip = this.opts.onWorkerError === "skip";
2965
3222
  emit({ type: "parallel_start", agentIds: workers.map((w) => w.id) });
2966
3223
  if (concurrency >= workers.length) {
2967
- const promises = workers.map(async (worker) => {
2968
- return this.executeWorker(worker, ctx, emit, totalUsage);
2969
- });
2970
- const settled = await Promise.allSettled(promises);
2971
- for (let i = 0; i < settled.length; i++) {
2972
- const s = settled[i];
2973
- if (s.status === "fulfilled") {
2974
- results.set(workers[i].id, s.value);
3224
+ if (!skip) {
3225
+ await Promise.all(
3226
+ workers.map(async (worker) => {
3227
+ const r = await this.executeWorker(worker, ctx, emit, totalUsage);
3228
+ results.set(worker.id, r);
3229
+ return r;
3230
+ })
3231
+ );
3232
+ } else {
3233
+ const settled = await Promise.allSettled(
3234
+ workers.map((worker) => this.executeWorker(worker, ctx, emit, totalUsage))
3235
+ );
3236
+ for (let i = 0; i < settled.length; i++) {
3237
+ const s = settled[i];
3238
+ if (s.status === "fulfilled") {
3239
+ results.set(workers[i].id, s.value);
3240
+ } else {
3241
+ this.failedAgents.push(workers[i].id);
3242
+ }
2975
3243
  }
2976
3244
  }
2977
3245
  } else {
@@ -2980,12 +3248,20 @@ var SupervisorExecutor = class {
2980
3248
  const enqueue = () => {
2981
3249
  if (index >= workers.length) return null;
2982
3250
  const worker = workers[index++];
2983
- const p = this.executeWorker(worker, ctx, emit, totalUsage).then((r) => {
2984
- results.set(worker.id, r);
3251
+ const p = this.executeWorker(worker, ctx, emit, totalUsage).then(
3252
+ (r) => {
3253
+ results.set(worker.id, r);
3254
+ },
3255
+ (err) => {
3256
+ if (!skip) throw err;
3257
+ this.failedAgents.push(worker.id);
3258
+ }
3259
+ ).finally(() => {
2985
3260
  executing.delete(p);
2986
- return r;
2987
3261
  });
2988
3262
  executing.add(p);
3263
+ p.catch(() => {
3264
+ });
2989
3265
  return p;
2990
3266
  };
2991
3267
  for (let i = 0; i < concurrency && index < workers.length; i++) {
@@ -3002,40 +3278,122 @@ var SupervisorExecutor = class {
3002
3278
  /** 顺序执行所有 Worker */
3003
3279
  async executeWorkersSequential(ctx, emit, totalUsage) {
3004
3280
  const results = /* @__PURE__ */ new Map();
3281
+ const skip = this.opts.onWorkerError === "skip";
3005
3282
  for (const worker of this.workerNodes) {
3006
- const result = await this.executeWorker(worker, ctx, emit, totalUsage);
3007
- results.set(worker.id, result);
3283
+ try {
3284
+ const result = await this.executeWorker(worker, ctx, emit, totalUsage);
3285
+ results.set(worker.id, result);
3286
+ } catch (err) {
3287
+ if (!skip) throw err;
3288
+ this.failedAgents.push(worker.id);
3289
+ }
3008
3290
  }
3009
3291
  return results;
3010
3292
  }
3011
- /** 自动调度:根据 inputMapping 依赖分层执行 */
3293
+ /** 自动调度:按依赖分层执行
3294
+ *
3295
+ * 依赖推导规则:
3296
+ * 1. 显式声明 dependsOn 的 worker:依赖指定的 worker(依赖必须都在 workers 列表中,否则报错)
3297
+ * 2. 未声明 dependsOn 但有 inputMapping 的 worker:隐式依赖所有"第 0 层"worker(保持向后兼容)
3298
+ * 3. 其余 worker(无 dependsOn 且无 inputMapping):第 0 层,首批并行
3299
+ *
3300
+ * 按拓扑分层:同层并行执行(受 concurrency 限制),层间按序执行;依赖成环时报错。
3301
+ */
3012
3302
  async executeWorkersAuto(ctx, emit, totalUsage) {
3013
3303
  const results = /* @__PURE__ */ new Map();
3014
- const noInputMapping = this.workerNodes.filter((w) => !w.inputMapping);
3015
- const withInputMapping = this.workerNodes.filter((w) => !!w.inputMapping);
3016
- if (noInputMapping.length > 0) {
3017
- emit({ type: "parallel_start", agentIds: noInputMapping.map((w) => w.id) });
3018
- const batchResults = await Promise.all(
3019
- noInputMapping.map((w) => this.executeWorker(w, ctx, emit, totalUsage))
3020
- );
3021
- for (let i = 0; i < noInputMapping.length; i++) {
3022
- results.set(noInputMapping[i].id, batchResults[i]);
3304
+ const skip = this.opts.onWorkerError === "skip";
3305
+ const workerIds = new Set(this.workerNodes.map((w) => w.id));
3306
+ const layer0 = this.workerNodes.filter((w) => !w.inputMapping && !w.dependsOn);
3307
+ const deps = /* @__PURE__ */ new Map();
3308
+ for (const w of this.workerNodes) {
3309
+ if (w.dependsOn) {
3310
+ for (const dep of w.dependsOn) {
3311
+ if (!workerIds.has(dep)) {
3312
+ throw new Error(`Supervisor: Worker "${w.id}" \u7684 dependsOn \u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684 Worker "${dep}"`);
3313
+ }
3314
+ }
3315
+ deps.set(w.id, new Set(w.dependsOn));
3316
+ } else if (w.inputMapping) {
3317
+ deps.set(w.id, new Set(layer0.map((l) => l.id)));
3318
+ } else {
3319
+ deps.set(w.id, /* @__PURE__ */ new Set());
3023
3320
  }
3024
- emit({ type: "parallel_done", results: new Map(results) });
3025
3321
  }
3026
- for (const worker of withInputMapping) {
3027
- const result = await this.executeWorker(worker, ctx, emit, totalUsage);
3028
- results.set(worker.id, result);
3322
+ const remaining = new Map(deps);
3323
+ const layers = [];
3324
+ const doneIds = /* @__PURE__ */ new Set();
3325
+ while (remaining.size > 0) {
3326
+ const layer = [];
3327
+ for (const [id, depSet] of remaining) {
3328
+ if ([...depSet].every((d) => doneIds.has(d))) {
3329
+ layer.push(this.workerNodes.find((w) => w.id === id));
3330
+ }
3331
+ }
3332
+ if (layer.length === 0) {
3333
+ throw new Error(`Supervisor: auto \u8C03\u5EA6\u7684 Worker \u4F9D\u8D56\u5B58\u5728\u73AF\uFF08\u6D89\u53CA: ${[...remaining.keys()].join(", ")}\uFF09`);
3334
+ }
3335
+ for (const w of layer) {
3336
+ remaining.delete(w.id);
3337
+ doneIds.add(w.id);
3338
+ }
3339
+ layers.push(layer);
3340
+ }
3341
+ for (const layer of layers) {
3342
+ if (layer.length === 1) {
3343
+ try {
3344
+ const r = await this.executeWorker(layer[0], ctx, emit, totalUsage);
3345
+ results.set(layer[0].id, r);
3346
+ } catch (err) {
3347
+ if (!skip) throw err;
3348
+ this.failedAgents.push(layer[0].id);
3349
+ }
3350
+ continue;
3351
+ }
3352
+ emit({ type: "parallel_start", agentIds: layer.map((w) => w.id) });
3353
+ const runOne = async (worker) => {
3354
+ try {
3355
+ const r = await this.executeWorker(worker, ctx, emit, totalUsage);
3356
+ results.set(worker.id, r);
3357
+ } catch (err) {
3358
+ if (!skip) throw err;
3359
+ this.failedAgents.push(worker.id);
3360
+ }
3361
+ };
3362
+ if (this.opts.concurrency >= layer.length) {
3363
+ await Promise.all(layer.map((w) => runOne(w)));
3364
+ } else {
3365
+ let index = 0;
3366
+ const executing = /* @__PURE__ */ new Set();
3367
+ const enqueue = () => {
3368
+ if (index >= layer.length) return null;
3369
+ const i = index++;
3370
+ const p = runOne(layer[i]).finally(() => {
3371
+ executing.delete(p);
3372
+ });
3373
+ executing.add(p);
3374
+ p.catch(() => {
3375
+ });
3376
+ return p;
3377
+ };
3378
+ for (let i = 0; i < this.opts.concurrency && index < layer.length; i++) {
3379
+ enqueue();
3380
+ }
3381
+ while (executing.size > 0) {
3382
+ await Promise.race(executing);
3383
+ enqueue();
3384
+ }
3385
+ }
3386
+ emit({ type: "parallel_done", results: new Map(results) });
3029
3387
  }
3030
3388
  return results;
3031
3389
  }
3032
3390
  /** 执行单个 Worker */
3033
3391
  async executeWorker(worker, ctx, emit, totalUsage) {
3392
+ this.throwIfAborted();
3034
3393
  this.state.currentAgentId = worker.id;
3035
3394
  this.state.nodeStates.set(worker.id, "running");
3036
- emit({ type: "agent_start", agentId: worker.id, agentName: worker.name });
3395
+ let workerInput;
3037
3396
  try {
3038
- let workerInput;
3039
3397
  if (worker.inputMapping) {
3040
3398
  workerInput = worker.inputMapping(ctx);
3041
3399
  } else {
@@ -3043,6 +3401,14 @@ var SupervisorExecutor = class {
3043
3401
  const myTask = tasks?.find((t) => t.assignee === worker.id);
3044
3402
  workerInput = myTask ? myTask.task : ctx.blackboard.get("__original_input__") ?? "";
3045
3403
  }
3404
+ } catch (err) {
3405
+ const errorMsg = err instanceof Error ? err.message : String(err);
3406
+ this.state.nodeStates.set(worker.id, "failed");
3407
+ emit({ type: "agent_error", agentId: worker.id, agentName: worker.name, error: errorMsg });
3408
+ throw err;
3409
+ }
3410
+ emit({ type: "agent_start", agentId: worker.id, agentName: worker.name, input: toInputText(workerInput) });
3411
+ try {
3046
3412
  const result = await executeNode(worker, workerInput, ctx);
3047
3413
  this.state.nodeStates.set(worker.id, "completed");
3048
3414
  this.state.nodeResults.set(worker.id, result);
@@ -3059,16 +3425,21 @@ var SupervisorExecutor = class {
3059
3425
  }
3060
3426
  buildErrorResult(ctx, err) {
3061
3427
  this.state.finished = true;
3428
+ const aborted = err instanceof GraphAbortedError;
3429
+ const errorMsg = err instanceof Error ? err.message : String(err);
3430
+ this.state.error = errorMsg;
3431
+ const lastCompleted = [...this.state.nodeResults.values()].at(-1);
3062
3432
  return {
3063
- content: "",
3064
- lastAgentId: this.supervisorNode.id,
3433
+ content: aborted ? lastCompleted?.content ?? "" : "",
3434
+ lastAgentId: this.state.currentAgentId ?? this.supervisorNode.id,
3065
3435
  agentResults: new Map(this.state.nodeResults),
3066
3436
  totalUsage: {},
3067
3437
  stepsCompleted: this.state.stepsCompleted,
3068
- stopReason: "error",
3438
+ stopReason: aborted ? "aborted" : "error",
3069
3439
  context: ctx,
3070
3440
  success: false,
3071
- error: err instanceof Error ? err.message : String(err)
3441
+ error: errorMsg,
3442
+ ...this.failedAgents.length > 0 ? { failedAgents: [...this.failedAgents] } : {}
3072
3443
  };
3073
3444
  }
3074
3445
  mergeUsage(total, usage) {
@@ -3081,7 +3452,8 @@ var SupervisorExecutor = class {
3081
3452
  // patterns/supervisor.ts
3082
3453
  var SupervisorGraphImpl = class {
3083
3454
  executor;
3084
- eventListeners = /* @__PURE__ */ new Map();
3455
+ /** on() 注册的监听器,按 MultiAgentEvent.type 分发 */
3456
+ bus = new SimpleEventBus();
3085
3457
  constructor(supervisor, workers, opts) {
3086
3458
  this.executor = new SupervisorExecutor(supervisor, workers, opts);
3087
3459
  }
@@ -3099,23 +3471,21 @@ var SupervisorGraphImpl = class {
3099
3471
  throw new Error("Supervisor \u6A21\u5F0F\u4E0D\u652F\u6301 setFinish\uFF0C\u7EC8\u6B62\u7531 Supervisor \u5224\u5B9A");
3100
3472
  }
3101
3473
  async run(input) {
3474
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
3102
3475
  return this.executor.run(input);
3103
3476
  }
3104
3477
  async *stream(input) {
3478
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
3105
3479
  yield* this.executor.stream(input);
3106
3480
  }
3107
3481
  getState() {
3108
3482
  return this.executor.getState();
3109
3483
  }
3110
3484
  abort() {
3485
+ this.executor.abort();
3111
3486
  }
3112
3487
  on(event, listener) {
3113
- let set = this.eventListeners.get(event);
3114
- if (!set) {
3115
- set = /* @__PURE__ */ new Set();
3116
- this.eventListeners.set(event, set);
3117
- }
3118
- set.add(listener);
3488
+ this.bus.on(event, listener);
3119
3489
  return this;
3120
3490
  }
3121
3491
  };
@@ -3133,6 +3503,9 @@ var DebateExecutor = class {
3133
3503
  maxRounds;
3134
3504
  convergeWhen;
3135
3505
  feedbackTransform;
3506
+ abortController = new AbortController();
3507
+ /** 外部事件监听(on() API 的底层接线) */
3508
+ eventSink;
3136
3509
  state = {
3137
3510
  nodeStates: /* @__PURE__ */ new Map(),
3138
3511
  nodeResults: /* @__PURE__ */ new Map(),
@@ -3155,53 +3528,75 @@ ${proposerResult.content}`;
3155
3528
  this.state.nodeStates.set(reviewer.id, "pending");
3156
3529
  }
3157
3530
  getState() {
3158
- return { ...this.state };
3531
+ return {
3532
+ ...this.state,
3533
+ nodeStates: new Map(this.state.nodeStates),
3534
+ nodeResults: new Map(this.state.nodeResults)
3535
+ };
3536
+ }
3537
+ /** 注入外部事件监听(由 AgentGraph 实现的 on() 接线) */
3538
+ setEventSink(sink) {
3539
+ this.eventSink = sink;
3540
+ return this;
3541
+ }
3542
+ abort() {
3543
+ this.abortController.abort();
3544
+ }
3545
+ /** 每次 run/stream 前重置中止信号与执行状态 */
3546
+ resetAbortController() {
3547
+ this.abortController = new AbortController();
3548
+ this.state = {
3549
+ nodeStates: /* @__PURE__ */ new Map(),
3550
+ nodeResults: /* @__PURE__ */ new Map(),
3551
+ stepsCompleted: 0,
3552
+ finished: false
3553
+ };
3554
+ this.state.nodeStates.set(this.proposerNode.id, "pending");
3555
+ this.state.nodeStates.set(this.reviewerNode.id, "pending");
3556
+ }
3557
+ throwIfAborted() {
3558
+ if (this.abortController.signal.aborted) {
3559
+ throw new GraphAbortedError();
3560
+ }
3159
3561
  }
3160
3562
  /** 执行 Debate */
3161
3563
  async run(input) {
3564
+ this.resetAbortController();
3162
3565
  const ctx = createSharedContext({
3163
3566
  meta: { traceId: `debate-${Date.now()}`, startTime: Date.now() }
3164
3567
  });
3568
+ storeOriginalInput(ctx, input);
3569
+ const emit = this.eventSink ?? (() => {
3570
+ });
3165
3571
  try {
3166
- return await this.executeDebate(input, ctx, () => {
3167
- });
3572
+ const result = await this.executeDebate(input, ctx, emit);
3573
+ emit({ type: "graph_done", result });
3574
+ return result;
3168
3575
  } catch (err) {
3169
- return this.buildErrorResult(ctx, err);
3576
+ const result = this.buildErrorResult(ctx, err);
3577
+ emit({ type: "graph_error", error: result.error ?? "" });
3578
+ return result;
3170
3579
  }
3171
3580
  }
3172
3581
  /** 流式执行 Debate */
3173
- async *stream(input) {
3582
+ stream(input) {
3583
+ this.resetAbortController();
3174
3584
  const ctx = createSharedContext({
3175
3585
  meta: { traceId: `debate-${Date.now()}`, startTime: Date.now() }
3176
3586
  });
3177
- const eventQueue = [];
3178
- let resolveEvent = null;
3179
- let done = false;
3180
- const emit = (event) => {
3181
- eventQueue.push(event);
3182
- resolveEvent?.();
3183
- };
3184
- const graphPromise = this.executeDebate(input, ctx, emit).then(
3185
- (result) => {
3186
- emit({ type: "graph_done", result });
3187
- },
3188
- (err) => {
3189
- emit({ type: "graph_error", error: err instanceof Error ? err.message : String(err) });
3190
- }
3191
- ).finally(() => {
3192
- done = true;
3193
- resolveEvent?.();
3194
- });
3195
- while (!done || eventQueue.length > 0) {
3196
- if (eventQueue.length > 0) {
3197
- yield eventQueue.shift();
3198
- } else {
3199
- await new Promise((resolve) => {
3200
- resolveEvent = resolve;
3201
- });
3202
- }
3203
- }
3204
- await graphPromise;
3587
+ storeOriginalInput(ctx, input);
3588
+ return createEventStream(
3589
+ (emit) => this.executeDebate(input, ctx, emit).then(
3590
+ (result) => {
3591
+ emit({ type: "graph_done", result });
3592
+ },
3593
+ (err) => {
3594
+ this.state.error = err instanceof Error ? err.message : String(err);
3595
+ emit({ type: "graph_error", error: this.state.error });
3596
+ }
3597
+ ),
3598
+ this.eventSink
3599
+ );
3205
3600
  }
3206
3601
  /** 核心执行逻辑 */
3207
3602
  async executeDebate(input, ctx, emit) {
@@ -3213,10 +3608,11 @@ ${proposerResult.content}`;
3213
3608
  let convergeReason = "";
3214
3609
  let currentInput = input;
3215
3610
  for (let round = 1; round <= this.maxRounds; round++) {
3611
+ this.throwIfAborted();
3216
3612
  emit({ type: "round_start", round });
3217
3613
  this.state.currentAgentId = this.proposerNode.id;
3218
3614
  this.state.nodeStates.set(this.proposerNode.id, "running");
3219
- emit({ type: "agent_start", agentId: this.proposerNode.id, agentName: this.proposerNode.name });
3615
+ emit({ type: "agent_start", agentId: this.proposerNode.id, agentName: this.proposerNode.name, input: toInputText(currentInput) });
3220
3616
  try {
3221
3617
  lastProposerResult = await executeNode(this.proposerNode, currentInput, ctx);
3222
3618
  this.state.nodeStates.set(this.proposerNode.id, "completed");
@@ -3233,7 +3629,7 @@ ${proposerResult.content}`;
3233
3629
  }
3234
3630
  this.state.currentAgentId = this.reviewerNode.id;
3235
3631
  this.state.nodeStates.set(this.reviewerNode.id, "running");
3236
- emit({ type: "agent_start", agentId: this.reviewerNode.id, agentName: this.reviewerNode.name });
3632
+ emit({ type: "agent_start", agentId: this.reviewerNode.id, agentName: this.reviewerNode.name, input: lastProposerResult.content });
3237
3633
  try {
3238
3634
  lastReviewerResult = await executeNode(this.reviewerNode, lastProposerResult.content, ctx);
3239
3635
  this.state.nodeStates.set(this.reviewerNode.id, "completed");
@@ -3272,16 +3668,20 @@ ${proposerResult.content}`;
3272
3668
  }
3273
3669
  buildErrorResult(ctx, err) {
3274
3670
  this.state.finished = true;
3671
+ const aborted = err instanceof GraphAbortedError;
3672
+ const errorMsg = err instanceof Error ? err.message : String(err);
3673
+ this.state.error = errorMsg;
3674
+ const lastCompleted = [...this.state.nodeResults.values()].at(-1);
3275
3675
  return {
3276
- content: "",
3676
+ content: aborted ? lastCompleted?.content ?? "" : "",
3277
3677
  lastAgentId: this.proposerNode.id,
3278
3678
  agentResults: new Map(this.state.nodeResults),
3279
3679
  totalUsage: {},
3280
3680
  stepsCompleted: this.state.stepsCompleted,
3281
- stopReason: "error",
3681
+ stopReason: aborted ? "aborted" : "error",
3282
3682
  context: ctx,
3283
3683
  success: false,
3284
- error: err instanceof Error ? err.message : String(err)
3684
+ error: errorMsg
3285
3685
  };
3286
3686
  }
3287
3687
  mergeUsage(total, usage) {
@@ -3294,7 +3694,8 @@ ${proposerResult.content}`;
3294
3694
  // patterns/debate.ts
3295
3695
  var DebateGraphImpl = class {
3296
3696
  executor;
3297
- eventListeners = /* @__PURE__ */ new Map();
3697
+ /** on() 注册的监听器,按 MultiAgentEvent.type 分发 */
3698
+ bus = new SimpleEventBus();
3298
3699
  constructor(proposer, reviewer, opts) {
3299
3700
  this.executor = new DebateExecutor(proposer, reviewer, opts);
3300
3701
  }
@@ -3311,23 +3712,21 @@ var DebateGraphImpl = class {
3311
3712
  throw new Error("Debate \u6A21\u5F0F\u4E0D\u652F\u6301 setFinish");
3312
3713
  }
3313
3714
  async run(input) {
3715
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
3314
3716
  return this.executor.run(input);
3315
3717
  }
3316
3718
  async *stream(input) {
3719
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
3317
3720
  yield* this.executor.stream(input);
3318
3721
  }
3319
3722
  getState() {
3320
3723
  return this.executor.getState();
3321
3724
  }
3322
3725
  abort() {
3726
+ this.executor.abort();
3323
3727
  }
3324
3728
  on(event, listener) {
3325
- let set = this.eventListeners.get(event);
3326
- if (!set) {
3327
- set = /* @__PURE__ */ new Set();
3328
- this.eventListeners.set(event, set);
3329
- }
3330
- set.add(listener);
3729
+ this.bus.on(event, listener);
3331
3730
  return this;
3332
3731
  }
3333
3732
  };
@@ -3341,7 +3740,11 @@ var MapReduceExecutor = class {
3341
3740
  reducerNode;
3342
3741
  split;
3343
3742
  concurrency;
3743
+ onMapperError;
3344
3744
  reduceInputFormat;
3745
+ abortController = new AbortController();
3746
+ /** 外部事件监听(on() API 的底层接线) */
3747
+ eventSink;
3345
3748
  state = {
3346
3749
  nodeStates: /* @__PURE__ */ new Map(),
3347
3750
  nodeResults: /* @__PURE__ */ new Map(),
@@ -3353,6 +3756,7 @@ var MapReduceExecutor = class {
3353
3756
  this.reducerNode = reducer;
3354
3757
  this.split = opts.split;
3355
3758
  this.concurrency = opts.concurrency ?? Infinity;
3759
+ this.onMapperError = opts.onMapperError ?? "fail-fast";
3356
3760
  this.reduceInputFormat = opts.reduceInputFormat ?? ((mapperResults) => {
3357
3761
  const parts = [];
3358
3762
  for (const [idx, result] of mapperResults) {
@@ -3365,132 +3769,98 @@ ${result.content}`);
3365
3769
  this.state.nodeStates.set(reducer.id, "pending");
3366
3770
  }
3367
3771
  getState() {
3368
- return { ...this.state };
3772
+ return {
3773
+ ...this.state,
3774
+ nodeStates: new Map(this.state.nodeStates),
3775
+ nodeResults: new Map(this.state.nodeResults)
3776
+ };
3369
3777
  }
3370
- /** 执行 MapReduce */
3371
- async run(input) {
3778
+ /** 注入外部事件监听(由 AgentGraph 实现的 on() 接线) */
3779
+ setEventSink(sink) {
3780
+ this.eventSink = sink;
3781
+ return this;
3782
+ }
3783
+ abort() {
3784
+ this.abortController.abort();
3785
+ }
3786
+ /** 每次 run/stream 前重置中止信号与执行状态 */
3787
+ resetAbortController() {
3788
+ this.abortController = new AbortController();
3789
+ this.state = {
3790
+ nodeStates: /* @__PURE__ */ new Map(),
3791
+ nodeResults: /* @__PURE__ */ new Map(),
3792
+ stepsCompleted: 0,
3793
+ finished: false
3794
+ };
3795
+ this.state.nodeStates.set(this.mapperNode.id, "pending");
3796
+ this.state.nodeStates.set(this.reducerNode.id, "pending");
3797
+ }
3798
+ throwIfAborted() {
3799
+ if (this.abortController.signal.aborted) {
3800
+ throw new GraphAbortedError();
3801
+ }
3802
+ }
3803
+ /** 拆分输入并校验(每次 run/stream 只调用一次 split,避免副作用放大) */
3804
+ splitInput(input) {
3372
3805
  const inputText = typeof input === "string" ? input : input.message;
3373
3806
  const chunks = this.split(inputText);
3374
3807
  if (chunks.length === 0) {
3375
3808
  throw new Error("MapReduce: split \u51FD\u6570\u8FD4\u56DE\u4E86\u7A7A\u6570\u7EC4\uFF0C\u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u5B50\u4EFB\u52A1");
3376
3809
  }
3810
+ return chunks;
3811
+ }
3812
+ /** 执行 MapReduce */
3813
+ async run(input) {
3814
+ this.resetAbortController();
3815
+ const chunks = this.splitInput(input);
3377
3816
  const ctx = createSharedContext({
3378
3817
  meta: { traceId: `mr-${Date.now()}`, startTime: Date.now() }
3379
3818
  });
3819
+ storeOriginalInput(ctx, input);
3820
+ const emit = this.eventSink ?? (() => {
3821
+ });
3380
3822
  try {
3381
- return await this.executeMapReduce(input, ctx, () => {
3382
- });
3823
+ const result = await this.executeMapReduce(chunks, ctx, emit);
3824
+ emit({ type: "graph_done", result });
3825
+ return result;
3383
3826
  } catch (err) {
3384
- return this.buildErrorResult(ctx, err);
3827
+ const result = this.buildErrorResult(ctx, err);
3828
+ emit({ type: "graph_error", error: result.error ?? "" });
3829
+ return result;
3385
3830
  }
3386
3831
  }
3387
3832
  /** 流式执行 MapReduce */
3388
- async *stream(input) {
3389
- const inputText = typeof input === "string" ? input : input.message;
3390
- const chunks = this.split(inputText);
3391
- if (chunks.length === 0) {
3392
- throw new Error("MapReduce: split \u51FD\u6570\u8FD4\u56DE\u4E86\u7A7A\u6570\u7EC4\uFF0C\u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u5B50\u4EFB\u52A1");
3393
- }
3833
+ stream(input) {
3834
+ this.resetAbortController();
3835
+ const chunks = this.splitInput(input);
3394
3836
  const ctx = createSharedContext({
3395
3837
  meta: { traceId: `mr-${Date.now()}`, startTime: Date.now() }
3396
3838
  });
3397
- const eventQueue = [];
3398
- let resolveEvent = null;
3399
- let done = false;
3400
- const emit = (event) => {
3401
- eventQueue.push(event);
3402
- resolveEvent?.();
3403
- };
3404
- const graphPromise = this.executeMapReduce(input, ctx, emit).then(
3405
- (result) => {
3406
- emit({ type: "graph_done", result });
3407
- },
3408
- (err) => {
3409
- emit({ type: "graph_error", error: err instanceof Error ? err.message : String(err) });
3410
- }
3411
- ).finally(() => {
3412
- done = true;
3413
- resolveEvent?.();
3414
- });
3415
- while (!done || eventQueue.length > 0) {
3416
- if (eventQueue.length > 0) {
3417
- yield eventQueue.shift();
3418
- } else {
3419
- await new Promise((resolve) => {
3420
- resolveEvent = resolve;
3421
- });
3422
- }
3423
- }
3424
- await graphPromise;
3839
+ storeOriginalInput(ctx, input);
3840
+ return createEventStream(
3841
+ (emit) => this.executeMapReduce(chunks, ctx, emit).then(
3842
+ (result) => {
3843
+ emit({ type: "graph_done", result });
3844
+ },
3845
+ (err) => {
3846
+ this.state.error = err instanceof Error ? err.message : String(err);
3847
+ emit({ type: "graph_error", error: this.state.error });
3848
+ }
3849
+ ),
3850
+ this.eventSink
3851
+ );
3425
3852
  }
3426
3853
  /** 核心执行逻辑 */
3427
- async executeMapReduce(input, ctx, emit) {
3428
- let stepsCompleted = 0;
3854
+ async executeMapReduce(chunks, ctx, emit) {
3429
3855
  const totalUsage = {};
3430
- const inputText = typeof input === "string" ? input : input.message;
3431
- const chunks = this.split(inputText);
3432
- const mapperResults = /* @__PURE__ */ new Map();
3856
+ this.throwIfAborted();
3433
3857
  this.state.nodeStates.set(this.mapperNode.id, "running");
3434
- const mapperAgentIds = chunks.map((_, i) => `${this.mapperNode.id}_${i}`);
3435
- emit({ type: "parallel_start", agentIds: mapperAgentIds });
3436
- if (this.concurrency >= chunks.length) {
3437
- const promises = chunks.map(async (chunk, index) => {
3438
- emit({ type: "agent_start", agentId: `${this.mapperNode.id}_${index}`, agentName: `${this.mapperNode.name}#${index + 1}` });
3439
- try {
3440
- const result = await executeNode(this.mapperNode, chunk, ctx);
3441
- this.state.nodeResults.set(`${this.mapperNode.id}_${index}`, result);
3442
- this.mergeUsage(totalUsage, result.usage);
3443
- stepsCompleted++;
3444
- this.state.stepsCompleted = stepsCompleted;
3445
- emit({ type: "agent_result", agentId: `${this.mapperNode.id}_${index}`, agentName: `${this.mapperNode.name}#${index + 1}`, result });
3446
- return { index, result };
3447
- } catch (err) {
3448
- const errorMsg = err instanceof Error ? err.message : String(err);
3449
- emit({ type: "agent_error", agentId: `${this.mapperNode.id}_${index}`, agentName: `${this.mapperNode.name}#${index + 1}`, error: errorMsg });
3450
- throw err;
3451
- }
3452
- });
3453
- const settled = await Promise.allSettled(promises);
3454
- for (const s of settled) {
3455
- if (s.status === "fulfilled") {
3456
- mapperResults.set(s.value.index, s.value.result);
3457
- }
3458
- }
3459
- } else {
3460
- let index = 0;
3461
- const executing = /* @__PURE__ */ new Set();
3462
- const enqueue = () => {
3463
- if (index >= chunks.length) return null;
3464
- const currentIndex = index++;
3465
- const chunk = chunks[currentIndex];
3466
- const p = (async () => {
3467
- emit({ type: "agent_start", agentId: `${this.mapperNode.id}_${currentIndex}`, agentName: `${this.mapperNode.name}#${currentIndex + 1}` });
3468
- try {
3469
- const result = await executeNode(this.mapperNode, chunk, ctx);
3470
- mapperResults.set(currentIndex, result);
3471
- this.state.nodeResults.set(`${this.mapperNode.id}_${currentIndex}`, result);
3472
- this.mergeUsage(totalUsage, result.usage);
3473
- stepsCompleted++;
3474
- this.state.stepsCompleted = stepsCompleted;
3475
- emit({ type: "agent_result", agentId: `${this.mapperNode.id}_${currentIndex}`, agentName: `${this.mapperNode.name}#${currentIndex + 1}`, result });
3476
- } catch (err) {
3477
- const errorMsg = err instanceof Error ? err.message : String(err);
3478
- emit({ type: "agent_error", agentId: `${this.mapperNode.id}_${currentIndex}`, agentName: `${this.mapperNode.name}#${currentIndex + 1}`, error: errorMsg });
3479
- throw err;
3480
- }
3481
- })();
3482
- executing.add(p);
3483
- p.finally(() => executing.delete(p));
3484
- return p;
3485
- };
3486
- for (let i = 0; i < this.concurrency && index < chunks.length; i++) {
3487
- enqueue();
3488
- }
3489
- while (executing.size > 0) {
3490
- await Promise.race(executing);
3491
- enqueue();
3492
- }
3493
- }
3858
+ chunks.forEach((_, i) => {
3859
+ this.state.nodeStates.set(`${this.mapperNode.id}_${i}`, "pending");
3860
+ });
3861
+ const { results: mapperResults, failed } = await this.runMappers(chunks, ctx, emit, totalUsage);
3862
+ let stepsCompleted = mapperResults.size + failed.length;
3863
+ this.state.stepsCompleted = stepsCompleted;
3494
3864
  this.state.nodeStates.set(this.mapperNode.id, "completed");
3495
3865
  const mapperResultsForEmit = /* @__PURE__ */ new Map();
3496
3866
  for (const [idx, result] of mapperResults) {
@@ -3498,10 +3868,14 @@ ${result.content}`);
3498
3868
  }
3499
3869
  emit({ type: "parallel_done", results: mapperResultsForEmit });
3500
3870
  ctx.blackboard.set("mapper_results", mapperResults);
3871
+ if (failed.length > 0 && mapperResults.size === 0) {
3872
+ throw new Error(`MapReduce: \u6240\u6709 mapper \u5747\u5931\u8D25\uFF08${failed.length}/${chunks.length}\uFF09`);
3873
+ }
3501
3874
  const reduceInput = this.reduceInputFormat(mapperResults);
3875
+ this.throwIfAborted();
3502
3876
  this.state.currentAgentId = this.reducerNode.id;
3503
3877
  this.state.nodeStates.set(this.reducerNode.id, "running");
3504
- emit({ type: "agent_start", agentId: this.reducerNode.id, agentName: this.reducerNode.name });
3878
+ emit({ type: "agent_start", agentId: this.reducerNode.id, agentName: this.reducerNode.name, input: reduceInput });
3505
3879
  let reducerResult;
3506
3880
  try {
3507
3881
  reducerResult = await executeNode(this.reducerNode, reduceInput, ctx);
@@ -3518,29 +3892,94 @@ ${result.content}`);
3518
3892
  throw err;
3519
3893
  }
3520
3894
  this.state.finished = true;
3895
+ const hasFailures = failed.length > 0;
3521
3896
  return {
3522
3897
  content: reducerResult.content,
3523
3898
  lastAgentId: this.reducerNode.id,
3524
3899
  agentResults: new Map(this.state.nodeResults),
3525
3900
  totalUsage,
3526
3901
  stepsCompleted,
3527
- stopReason: "completed",
3902
+ stopReason: hasFailures ? "partial_failure" : "completed",
3528
3903
  context: ctx,
3529
- success: true
3904
+ success: true,
3905
+ ...hasFailures ? { failedAgents: failed } : {}
3530
3906
  };
3531
3907
  }
3908
+ /** 并行执行所有 mapper 子任务(统一处理并发限制与失败策略) */
3909
+ async runMappers(chunks, ctx, emit, totalUsage) {
3910
+ const results = /* @__PURE__ */ new Map();
3911
+ const failed = [];
3912
+ const skip = this.onMapperError === "skip";
3913
+ const mapperId = this.mapperNode.id;
3914
+ const mapperAgentIds = chunks.map((_, i) => `${mapperId}_${i}`);
3915
+ emit({ type: "parallel_start", agentIds: mapperAgentIds });
3916
+ const runOne = async (index) => {
3917
+ const agentId = `${mapperId}_${index}`;
3918
+ const agentName = `${this.mapperNode.name}#${index + 1}`;
3919
+ emit({ type: "agent_start", agentId, agentName, input: chunks[index] });
3920
+ this.state.nodeStates.set(agentId, "running");
3921
+ try {
3922
+ const result = await executeNode(this.mapperNode, chunks[index], ctx);
3923
+ this.state.nodeResults.set(agentId, result);
3924
+ this.state.nodeStates.set(agentId, "completed");
3925
+ this.mergeUsage(totalUsage, result.usage);
3926
+ results.set(index, result);
3927
+ emit({ type: "agent_result", agentId, agentName, result });
3928
+ } catch (err) {
3929
+ const errorMsg = err instanceof Error ? err.message : String(err);
3930
+ this.state.nodeStates.set(agentId, "failed");
3931
+ emit({ type: "agent_error", agentId, agentName, error: errorMsg });
3932
+ if (!skip) throw err;
3933
+ failed.push(agentId);
3934
+ }
3935
+ };
3936
+ if (this.concurrency >= chunks.length) {
3937
+ const promises = chunks.map((_, i) => runOne(i));
3938
+ if (!skip) {
3939
+ await Promise.all(promises);
3940
+ } else {
3941
+ await Promise.allSettled(promises);
3942
+ }
3943
+ } else {
3944
+ let index = 0;
3945
+ const executing = /* @__PURE__ */ new Set();
3946
+ const enqueue = () => {
3947
+ if (index >= chunks.length) return null;
3948
+ const i = index++;
3949
+ const p = runOne(i).finally(() => {
3950
+ executing.delete(p);
3951
+ });
3952
+ executing.add(p);
3953
+ p.catch(() => {
3954
+ });
3955
+ return p;
3956
+ };
3957
+ for (let i = 0; i < this.concurrency && index < chunks.length; i++) {
3958
+ enqueue();
3959
+ }
3960
+ while (executing.size > 0) {
3961
+ await Promise.race(executing);
3962
+ enqueue();
3963
+ }
3964
+ }
3965
+ return { results, failed };
3966
+ }
3532
3967
  buildErrorResult(ctx, err) {
3533
3968
  this.state.finished = true;
3969
+ const aborted = err instanceof GraphAbortedError;
3970
+ const errorMsg = err instanceof Error ? err.message : String(err);
3971
+ this.state.error = errorMsg;
3972
+ const lastCompleted = [...this.state.nodeResults.values()].at(-1);
3534
3973
  return {
3535
- content: "",
3974
+ content: aborted ? lastCompleted?.content ?? "" : "",
3536
3975
  lastAgentId: this.mapperNode.id,
3537
3976
  agentResults: new Map(this.state.nodeResults),
3538
3977
  totalUsage: {},
3539
3978
  stepsCompleted: this.state.stepsCompleted,
3540
- stopReason: "error",
3979
+ stopReason: aborted ? "aborted" : "error",
3541
3980
  context: ctx,
3542
3981
  success: false,
3543
- error: err instanceof Error ? err.message : String(err)
3982
+ error: errorMsg
3544
3983
  };
3545
3984
  }
3546
3985
  mergeUsage(total, usage) {
@@ -3553,7 +3992,8 @@ ${result.content}`);
3553
3992
  // patterns/map-reduce.ts
3554
3993
  var MapReduceGraphImpl = class {
3555
3994
  executor;
3556
- eventListeners = /* @__PURE__ */ new Map();
3995
+ /** on() 注册的监听器,按 MultiAgentEvent.type 分发 */
3996
+ bus = new SimpleEventBus();
3557
3997
  constructor(mapper, reducer, opts) {
3558
3998
  this.executor = new MapReduceExecutor(mapper, reducer, opts);
3559
3999
  }
@@ -3570,23 +4010,21 @@ var MapReduceGraphImpl = class {
3570
4010
  throw new Error("MapReduce \u6A21\u5F0F\u4E0D\u652F\u6301 setFinish");
3571
4011
  }
3572
4012
  async run(input) {
4013
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
3573
4014
  return this.executor.run(input);
3574
4015
  }
3575
4016
  async *stream(input) {
4017
+ this.executor.setEventSink((event) => this.bus.emit(event.type, event));
3576
4018
  yield* this.executor.stream(input);
3577
4019
  }
3578
4020
  getState() {
3579
4021
  return this.executor.getState();
3580
4022
  }
3581
4023
  abort() {
4024
+ this.executor.abort();
3582
4025
  }
3583
4026
  on(event, listener) {
3584
- let set = this.eventListeners.get(event);
3585
- if (!set) {
3586
- set = /* @__PURE__ */ new Set();
3587
- this.eventListeners.set(event, set);
3588
- }
3589
- set.add(listener);
4027
+ this.bus.on(event, listener);
3590
4028
  return this;
3591
4029
  }
3592
4030
  };
@@ -4225,6 +4663,7 @@ var GraphDebugger = class {
4225
4663
  const graphStartTime = Date.now();
4226
4664
  const steps = [];
4227
4665
  let stepIndex = 0;
4666
+ let finalResult;
4228
4667
  for await (const event of this.graph.stream(input)) {
4229
4668
  if (event.type === "agent_start") {
4230
4669
  stepIndex++;
@@ -4234,7 +4673,7 @@ var GraphDebugger = class {
4234
4673
  agentName: event.agentName,
4235
4674
  startTime: Date.now(),
4236
4675
  duration: 0,
4237
- input: "",
4676
+ input: event.input ?? "",
4238
4677
  output: "",
4239
4678
  state: "running"
4240
4679
  });
@@ -4259,6 +4698,8 @@ var GraphDebugger = class {
4259
4698
  step.error = event.error;
4260
4699
  step.state = "failed";
4261
4700
  }
4701
+ } else if (event.type === "graph_done") {
4702
+ finalResult = event.result;
4262
4703
  }
4263
4704
  }
4264
4705
  const state = this.graph.getState();
@@ -4269,10 +4710,10 @@ var GraphDebugger = class {
4269
4710
  duration: graphDuration,
4270
4711
  steps,
4271
4712
  result: {
4272
- success: !state.error,
4273
- content: state.error ?? "",
4274
- stopReason: state.error ? "error" : "completed",
4275
- stepsCompleted: state.stepsCompleted
4713
+ success: finalResult ? finalResult.success : !state.error,
4714
+ content: finalResult?.content ?? "",
4715
+ stopReason: finalResult?.stopReason ?? (state.error ? "error" : "completed"),
4716
+ stepsCompleted: finalResult?.stepsCompleted ?? state.stepsCompleted
4276
4717
  }
4277
4718
  };
4278
4719
  }
@@ -4324,13 +4765,16 @@ function createDebugger(graph) {
4324
4765
  return new GraphDebugger(graph);
4325
4766
  }
4326
4767
  export {
4768
+ GraphAbortedError,
4327
4769
  GraphDebugger,
4328
4770
  MCPBridge,
4771
+ NodeTimeoutError,
4329
4772
  SimpleEventBus,
4330
4773
  SimpleToolRegistry,
4331
4774
  createAgentGraph,
4332
4775
  createDebate,
4333
4776
  createDebugger,
4777
+ createEventStream,
4334
4778
  createMCPBridge,
4335
4779
  createMapReduce,
4336
4780
  createMultiAgentMcpServerHost,