agenthub-multiagent-mcp 1.73.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.
- package/dist/client.d.ts +25 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +19 -1
- package/dist/client.js.map +1 -1
- package/dist/tools/brainstormTurnAnnotations.test.d.ts +8 -0
- package/dist/tools/brainstormTurnAnnotations.test.d.ts.map +1 -0
- package/dist/tools/brainstormTurnAnnotations.test.js +93 -0
- package/dist/tools/brainstormTurnAnnotations.test.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +92 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/tools.test.js +101 -2
- package/dist/tools/tools.test.js.map +1 -1
- package/dist/zohoSendOutcome.d.ts +13 -0
- package/dist/zohoSendOutcome.d.ts.map +1 -0
- package/dist/zohoSendOutcome.js +37 -0
- package/dist/zohoSendOutcome.js.map +1 -0
- package/dist/zohoSendOutcome.test.d.ts +2 -0
- package/dist/zohoSendOutcome.test.d.ts.map +1 -0
- package/dist/zohoSendOutcome.test.js +58 -0
- package/dist/zohoSendOutcome.test.js.map +1 -0
- package/package.json +1 -1
- package/skills/catalog.json +7 -4
- package/skills/manifest.json +4 -2
- package/skills/skills/multiagent-brainstorm/SKILL.md +50 -4
- package/skills/skills/zoho-mail/SKILL.md +2 -0
package/dist/tools/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import * as os from "node:os";
|
|
|
23
23
|
import * as path from "node:path";
|
|
24
24
|
import { describeSendResult } from "../messageIdempotency.js";
|
|
25
25
|
import { readZohoAttachments } from "../zohoAttachments.js";
|
|
26
|
+
import { isUnknownSendOutcome, unknownSendOutcomeError } from "../zohoSendOutcome.js";
|
|
26
27
|
// fix-message-send-idempotency — shared by the four message tools.
|
|
27
28
|
const IDEMPOTENCY_KEY_DESCRIPTION = "Optional. Leave unset: a key derived from the message content is sent, so " +
|
|
28
29
|
"re-issuing this exact call (e.g. after a timeout) never delivers it twice. " +
|
|
@@ -1743,7 +1744,22 @@ export function registerTools() {
|
|
|
1743
1744
|
inputSchema: {
|
|
1744
1745
|
type: "object",
|
|
1745
1746
|
properties: {
|
|
1746
|
-
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
|
+
},
|
|
1747
1763
|
topic: { type: "string", description: "One-line subject of the brainstorm." },
|
|
1748
1764
|
escalation: {
|
|
1749
1765
|
type: "string",
|
|
@@ -1756,7 +1772,7 @@ export function registerTools() {
|
|
|
1756
1772
|
description: "Peer-silence backstop in seconds (default 600).",
|
|
1757
1773
|
},
|
|
1758
1774
|
},
|
|
1759
|
-
required: ["
|
|
1775
|
+
required: ["topic"],
|
|
1760
1776
|
},
|
|
1761
1777
|
},
|
|
1762
1778
|
{
|
|
@@ -1783,6 +1799,17 @@ export function registerTools() {
|
|
|
1783
1799
|
enum: ["message", "propose_conclude", "human_note", "system"],
|
|
1784
1800
|
description: "Turn kind (default 'message').",
|
|
1785
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
|
+
},
|
|
1786
1813
|
},
|
|
1787
1814
|
required: ["session_id", "body"],
|
|
1788
1815
|
},
|
|
@@ -1799,6 +1826,18 @@ export function registerTools() {
|
|
|
1799
1826
|
required: ["session_id"],
|
|
1800
1827
|
},
|
|
1801
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
|
+
},
|
|
1802
1841
|
{
|
|
1803
1842
|
name: "brainstorm_conclude",
|
|
1804
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)",
|
|
@@ -3083,6 +3122,17 @@ function requireBrainstormProject(context) {
|
|
|
3083
3122
|
}
|
|
3084
3123
|
return agentState.project_id;
|
|
3085
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
|
+
}
|
|
3086
3136
|
// brainstormError formats a structured (non-throwing) failure result for a
|
|
3087
3137
|
// brainstorm tool, mirroring the ticket_get error shape.
|
|
3088
3138
|
function brainstormError(tool, result) {
|
|
@@ -4514,21 +4564,31 @@ export async function handleToolCall(name, args, client, context) {
|
|
|
4514
4564
|
// =============================================================================
|
|
4515
4565
|
case "brainstorm_open": {
|
|
4516
4566
|
const projectId = requireBrainstormProject(context);
|
|
4567
|
+
const participants = Array.isArray(args.participants) ? args.participants : undefined;
|
|
4517
4568
|
const result = await client.brainstormOpen(projectId, {
|
|
4518
4569
|
peer: args.peer,
|
|
4519
4570
|
topic: args.topic,
|
|
4520
4571
|
escalation: args.escalation,
|
|
4521
4572
|
max_turns: args.max_turns,
|
|
4522
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,
|
|
4523
4578
|
});
|
|
4524
4579
|
if (!result.ok)
|
|
4525
4580
|
return brainstormError("brainstorm_open", result);
|
|
4581
|
+
const invitees = [args.peer, ...(participants ?? [])].filter(Boolean).join(", ");
|
|
4526
4582
|
return {
|
|
4527
4583
|
ok: true,
|
|
4528
4584
|
session_id: result.data.session_id,
|
|
4529
4585
|
display_number: result.data.display_number,
|
|
4530
4586
|
invite_delivered: result.data.invite_delivered ?? true,
|
|
4531
|
-
|
|
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" : ""}.`,
|
|
4532
4592
|
};
|
|
4533
4593
|
}
|
|
4534
4594
|
case "brainstorm_accept": {
|
|
@@ -4552,7 +4612,8 @@ export async function handleToolCall(name, args, client, context) {
|
|
|
4552
4612
|
}
|
|
4553
4613
|
case "brainstorm_turn": {
|
|
4554
4614
|
const projectId = requireBrainstormProject(context);
|
|
4555
|
-
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
|
+
);
|
|
4556
4617
|
if (!result.ok)
|
|
4557
4618
|
return brainstormError("brainstorm_turn", result);
|
|
4558
4619
|
return { ok: true, turn: result.data, message: `Turn ${result.data.seq} posted.` };
|
|
@@ -4563,12 +4624,32 @@ export async function handleToolCall(name, args, client, context) {
|
|
|
4563
4624
|
if (!result.ok)
|
|
4564
4625
|
return brainstormError("brainstorm_poll", result);
|
|
4565
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;
|
|
4566
4630
|
return {
|
|
4567
4631
|
ok: true,
|
|
4568
4632
|
state: result.data.state,
|
|
4569
4633
|
turn_count: result.data.turn_count,
|
|
4570
4634
|
turns,
|
|
4571
|
-
|
|
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}.`,
|
|
4572
4653
|
};
|
|
4573
4654
|
}
|
|
4574
4655
|
case "brainstorm_conclude": {
|
|
@@ -5525,6 +5606,7 @@ export async function handleToolCall(name, args, client, context) {
|
|
|
5525
5606
|
throw new Error("Not registered. Call agent_register first.");
|
|
5526
5607
|
// Read and check every local file before any request (never a partial send).
|
|
5527
5608
|
const attachments = readZohoAttachments(args.attachments);
|
|
5609
|
+
const sendMode = args.mode === "send" ? "send" : "draft";
|
|
5528
5610
|
const res = await client.zohoSend({
|
|
5529
5611
|
mailbox: args.mailbox,
|
|
5530
5612
|
to: args.to,
|
|
@@ -5539,6 +5621,11 @@ export async function handleToolCall(name, args, client, context) {
|
|
|
5539
5621
|
reply_all: args.reply_all,
|
|
5540
5622
|
mode: args.mode,
|
|
5541
5623
|
dedupe_key: args.dedupe_key,
|
|
5624
|
+
}).catch((err) => {
|
|
5625
|
+
if (isUnknownSendOutcome(err)) {
|
|
5626
|
+
throw unknownSendOutcomeError(args.mailbox, sendMode, err);
|
|
5627
|
+
}
|
|
5628
|
+
throw err;
|
|
5542
5629
|
});
|
|
5543
5630
|
const extras = (res.threaded ? " Threaded as a reply." : "") +
|
|
5544
5631
|
(attachments.length > 0 ? ` ${attachments.length} attachment(s).` : "");
|