agenthub-multiagent-mcp 1.74.0 → 1.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1744,7 +1744,22 @@ export function registerTools() {
1744
1744
  inputSchema: {
1745
1745
  type: "object",
1746
1746
  properties: {
1747
- peer: { type: "string", description: "The peer agent id to brainstorm with (e.g. 'sumit-mobile')." },
1747
+ peer: { type: "string", description: "The peer agent id to brainstorm with (e.g. 'sumit-mobile'). For a group, use participants instead." },
1748
+ participants: {
1749
+ type: "array",
1750
+ items: { type: "string" },
1751
+ description: "Group brainstorm (add-multi-agent-conversations): the agent ids to invite, at most 5 besides you. One id behaves like peer. More than one needs AGENTHUB_GROUP_CONVERSATIONS_ENABLED on the server (else group_conversations_disabled).",
1752
+ },
1753
+ turn_policy: {
1754
+ type: "string",
1755
+ enum: ["round_robin", "free", "moderated"],
1756
+ description: "Group only. round_robin (default): the server names next_speaker in order of joining. free: anyone, but not twice in a row. moderated: the moderator speaks and hands the floor with brainstorm_yield.",
1757
+ },
1758
+ moderator: { type: "string", description: "moderated only: you (default) or one of the participants." },
1759
+ mirror_channel: {
1760
+ type: "string",
1761
+ description: "Group only: a Goshti channel (e.g. '#winery') to mirror every turn to as one thread; people's replies there become human_note turns.",
1762
+ },
1748
1763
  topic: { type: "string", description: "One-line subject of the brainstorm." },
1749
1764
  escalation: {
1750
1765
  type: "string",
@@ -1757,7 +1772,7 @@ export function registerTools() {
1757
1772
  description: "Peer-silence backstop in seconds (default 600).",
1758
1773
  },
1759
1774
  },
1760
- required: ["peer", "topic"],
1775
+ required: ["topic"],
1761
1776
  },
1762
1777
  },
1763
1778
  {
@@ -1784,6 +1799,17 @@ export function registerTools() {
1784
1799
  enum: ["message", "propose_conclude", "human_note", "system"],
1785
1800
  description: "Turn kind (default 'message').",
1786
1801
  },
1802
+ // add-live-work-graphs: these are what the brainstorm graph is drawn from.
1803
+ tag: {
1804
+ type: "string",
1805
+ enum: ["idea", "question", "objection", "decision", "summary"],
1806
+ description: "What this turn is for. Tag every turn you can: an untagged turn is drawn as a plain message.",
1807
+ },
1808
+ refs: {
1809
+ type: "array",
1810
+ items: { type: "integer" },
1811
+ description: "The seq numbers of earlier turns in this session that this turn answers or objects to (at most 20). A turn not yet written is refused with invalid_ref.",
1812
+ },
1787
1813
  },
1788
1814
  required: ["session_id", "body"],
1789
1815
  },
@@ -1800,6 +1826,18 @@ export function registerTools() {
1800
1826
  required: ["session_id"],
1801
1827
  },
1802
1828
  },
1829
+ {
1830
+ name: "brainstorm_yield",
1831
+ description: "Moderated group brainstorm only: as the moderator, hand the floor to a joined participant (yield to yourself to take it back). Refusals: not_moderated, not_moderator, yield_target_not_joined. (requires agent_register first)",
1832
+ inputSchema: {
1833
+ type: "object",
1834
+ properties: {
1835
+ session_id: { type: "string", description: "The brainstorm session id." },
1836
+ to: { type: "string", description: "The agent id that gets the floor." },
1837
+ },
1838
+ required: ["session_id", "to"],
1839
+ },
1840
+ },
1803
1841
  {
1804
1842
  name: "brainstorm_conclude",
1805
1843
  description: "Conclude a brainstorm with a structured outcome (mutual consensus). Succeeds ONLY when the peer's last turn was a propose_conclude — else returns conclusion_not_confirmed. The outcome seeds an OpenSpec change. (requires agent_register first)",
@@ -3084,6 +3122,17 @@ function requireBrainstormProject(context) {
3084
3122
  }
3085
3123
  return agentState.project_id;
3086
3124
  }
3125
+ // brainstormTurnAnnotations picks brainstorm_turn's tag and refs out of the
3126
+ // tool arguments (add-live-work-graphs). Absent ones are left out of the body;
3127
+ // the server validates both and refuses a bad ref with 400 invalid_ref.
3128
+ function brainstormTurnAnnotations(args) {
3129
+ const out = {};
3130
+ if (typeof args.tag === "string" && args.tag !== "")
3131
+ out.tag = args.tag;
3132
+ if (Array.isArray(args.refs) && args.refs.length > 0)
3133
+ out.refs = args.refs.map((r) => Number(r));
3134
+ return out;
3135
+ }
3087
3136
  // brainstormError formats a structured (non-throwing) failure result for a
3088
3137
  // brainstorm tool, mirroring the ticket_get error shape.
3089
3138
  function brainstormError(tool, result) {
@@ -4515,21 +4564,31 @@ export async function handleToolCall(name, args, client, context) {
4515
4564
  // =============================================================================
4516
4565
  case "brainstorm_open": {
4517
4566
  const projectId = requireBrainstormProject(context);
4567
+ const participants = Array.isArray(args.participants) ? args.participants : undefined;
4518
4568
  const result = await client.brainstormOpen(projectId, {
4519
4569
  peer: args.peer,
4520
4570
  topic: args.topic,
4521
4571
  escalation: args.escalation,
4522
4572
  max_turns: args.max_turns,
4523
4573
  silence_deadline_secs: args.silence_deadline_secs,
4574
+ participants,
4575
+ turn_policy: args.turn_policy,
4576
+ moderator: args.moderator,
4577
+ mirror_channel: args.mirror_channel,
4524
4578
  });
4525
4579
  if (!result.ok)
4526
4580
  return brainstormError("brainstorm_open", result);
4581
+ const invitees = [args.peer, ...(participants ?? [])].filter(Boolean).join(", ");
4527
4582
  return {
4528
4583
  ok: true,
4529
4584
  session_id: result.data.session_id,
4530
4585
  display_number: result.data.display_number,
4531
4586
  invite_delivered: result.data.invite_delivered ?? true,
4532
- message: `Brainstorm ${result.data.display_number} opened with ${args.peer}. Invite delivered${result.data.invite_delivered === false ? " FAILED" : ""}.`,
4587
+ turn_policy: result.data.turn_policy,
4588
+ invites: result.data.invites,
4589
+ mirror_thread_id: result.data.mirror_thread_id,
4590
+ mirror_warning: result.data.mirror_warning,
4591
+ message: `Brainstorm ${result.data.display_number} opened with ${invitees}. Invite delivered${result.data.invite_delivered === false ? " FAILED" : ""}.`,
4533
4592
  };
4534
4593
  }
4535
4594
  case "brainstorm_accept": {
@@ -4553,7 +4612,8 @@ export async function handleToolCall(name, args, client, context) {
4553
4612
  }
4554
4613
  case "brainstorm_turn": {
4555
4614
  const projectId = requireBrainstormProject(context);
4556
- const result = await client.brainstormTurn(projectId, args.session_id, args.body, args.kind);
4615
+ const result = await client.brainstormTurn(projectId, args.session_id, args.body, args.kind, brainstormTurnAnnotations(args) // add-live-work-graphs
4616
+ );
4557
4617
  if (!result.ok)
4558
4618
  return brainstormError("brainstorm_turn", result);
4559
4619
  return { ok: true, turn: result.data, message: `Turn ${result.data.seq} posted.` };
@@ -4564,12 +4624,32 @@ export async function handleToolCall(name, args, client, context) {
4564
4624
  if (!result.ok)
4565
4625
  return brainstormError("brainstorm_poll", result);
4566
4626
  const turns = Array.isArray(result.data.turns) ? result.data.turns : [];
4627
+ // add-multi-agent-conversations: a group session names who speaks next;
4628
+ // your_turn is set only when it does (undefined for two-agent and free).
4629
+ const nextSpeaker = result.data.next_speaker || undefined;
4567
4630
  return {
4568
4631
  ok: true,
4569
4632
  state: result.data.state,
4570
4633
  turn_count: result.data.turn_count,
4571
4634
  turns,
4572
- message: `${turns.length} new turn(s); state=${result.data.state}.`,
4635
+ next_speaker: nextSpeaker,
4636
+ your_turn: nextSpeaker ? nextSpeaker === agentId : undefined,
4637
+ turn_policy: result.data.turn_policy || undefined,
4638
+ conclusion_pending: result.data.conclusion_pending,
4639
+ participants: result.data.participants,
4640
+ message: `${turns.length} new turn(s); state=${result.data.state}${nextSpeaker ? `; next speaker ${nextSpeaker}` : ""}.`,
4641
+ };
4642
+ }
4643
+ case "brainstorm_yield": {
4644
+ const projectId = requireBrainstormProject(context);
4645
+ const result = await client.brainstormYield(projectId, args.session_id, args.to);
4646
+ if (!result.ok)
4647
+ return brainstormError("brainstorm_yield", result);
4648
+ return {
4649
+ ok: true,
4650
+ floor: result.data.floor,
4651
+ next_speaker: result.data.next_speaker,
4652
+ message: `Floor handed to ${result.data.next_speaker}.`,
4573
4653
  };
4574
4654
  }
4575
4655
  case "brainstorm_conclude": {