@ateam-ai/mcp 0.4.11 → 0.4.13
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/package.json +1 -1
- package/src/tools.js +61 -3
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -435,8 +435,9 @@ export const tools = [
|
|
|
435
435
|
core: true,
|
|
436
436
|
description:
|
|
437
437
|
"Send a chat message to a deployed solution. No skill_id needed — the system auto-routes to the right skill.\n\n" +
|
|
438
|
-
"ALWAYS ASYNC: returns a
|
|
439
|
-
"
|
|
438
|
+
"ALWAYS ASYNC: returns a chain_id immediately — the assistant's reply is NOT in this response (a conversation can run for minutes across handoffs + subcalls, so a synchronous wait would hit the 100s edge timeout → 524).\n\n" +
|
|
439
|
+
"POLL BY CHAIN, NEVER BY JOB: an individual job can terminate while the chain is still running, so poll ateam_chain_status(chain_id) on a loop (~2s) and stop when chain_done === true (or pending_question is set — the assistant is waiting on the user). That is the cheap chip-quick poll (Core's whole-chain computeChainStatus — the same thing the standard chat uses). Use ateam_get_chain(chain_id) only ONCE at the end if you want the full tree / per-job detail — it's too heavy to loop on.\n\n" +
|
|
440
|
+
"Multi-turn: pass the actor_id from a previous response back in to continue the same thread (e.g. reply to a confirmation prompt). Each call starts a new chain; the same actor_id maintains conversation context.",
|
|
440
441
|
inputSchema: {
|
|
441
442
|
type: "object",
|
|
442
443
|
properties: {
|
|
@@ -1121,6 +1122,24 @@ export const tools = [
|
|
|
1121
1122
|
required: ["job_id"],
|
|
1122
1123
|
},
|
|
1123
1124
|
},
|
|
1125
|
+
{
|
|
1126
|
+
name: "ateam_chain_status",
|
|
1127
|
+
core: true,
|
|
1128
|
+
description:
|
|
1129
|
+
"SLIM chain status — the chip-quick poll. Given a chain_id (from ateam_conversation), returns the WHOLE-CHAIN aggregate status cheaply: chain_status + chain_done (true only when the ENTIRE chain — root job + every handoff + askAnySkill subcall — is terminal), plus pending_question, result, and a short progress line.\n\n" +
|
|
1130
|
+
"This is what you poll on a loop after ateam_conversation — NOT ateam_get_chain (that returns the full tree; too heavy for periodic polling). A single job can finish while the chain is still running, so poll chain_done, not a job's status.\n\n" +
|
|
1131
|
+
"Loop: call every ~2s until chain_done === true (or pending_question is set — the assistant is waiting on the user). Then read `result` / fetch the full tree once via ateam_get_chain if you need per-job detail.",
|
|
1132
|
+
inputSchema: {
|
|
1133
|
+
type: "object",
|
|
1134
|
+
properties: {
|
|
1135
|
+
chain_id: {
|
|
1136
|
+
type: "string",
|
|
1137
|
+
description: "The chain id returned by ateam_conversation (the conversation's identity). Any job id in the chain also works — Core resolves the chain aggregate.",
|
|
1138
|
+
},
|
|
1139
|
+
},
|
|
1140
|
+
required: ["chain_id"],
|
|
1141
|
+
},
|
|
1142
|
+
},
|
|
1124
1143
|
{
|
|
1125
1144
|
name: "ateam_get_widget_catalog",
|
|
1126
1145
|
core: true,
|
|
@@ -1722,6 +1741,7 @@ const TENANT_TOOLS = new Set([
|
|
|
1722
1741
|
"ateam_test_status",
|
|
1723
1742
|
"ateam_test_abort",
|
|
1724
1743
|
"ateam_get_chain",
|
|
1744
|
+
"ateam_chain_status",
|
|
1725
1745
|
"ateam_get_widget_catalog",
|
|
1726
1746
|
"ateam_get_connector_source",
|
|
1727
1747
|
"ateam_get_metrics",
|
|
@@ -3172,7 +3192,8 @@ const handlers = {
|
|
|
3172
3192
|
_poll: chainId
|
|
3173
3193
|
? {
|
|
3174
3194
|
_note: "Conversation started (async). The reply is NOT in this response — poll the CHAIN for it.",
|
|
3175
|
-
slim: `
|
|
3195
|
+
slim: `ateam_chain_status(chain_id: "${chainId}") → cheap chip-quick poll; loop ~2s until chain_done===true (whole chain terminal, not just one job). Then read result.`,
|
|
3196
|
+
full: `ateam_get_chain(job_id: "${chainId}") → full tree + per-job detail (heavier; use once, not in a poll loop)`,
|
|
3176
3197
|
continue: kickoff?.actor_id ? `ateam_conversation(actor_id: "${kickoff.actor_id}", ...) to continue the thread` : undefined,
|
|
3177
3198
|
}
|
|
3178
3199
|
: undefined,
|
|
@@ -3421,6 +3442,43 @@ const handlers = {
|
|
|
3421
3442
|
return data;
|
|
3422
3443
|
},
|
|
3423
3444
|
|
|
3445
|
+
// SLIM chain status — the chip-quick poll. Hits Core /api/job/:id/status
|
|
3446
|
+
// (slimJob), which returns the WHOLE-CHAIN aggregate `chainStatus`/`chainDone`
|
|
3447
|
+
// (computeChainStatus over chainId) alongside the single-job status. This is
|
|
3448
|
+
// the right thing to poll on a loop after ateam_conversation: a single job
|
|
3449
|
+
// can terminate while the chain is still active — chainDone only flips when
|
|
3450
|
+
// the CHAIN is done. Cheap enough for periodic polling (no full tree).
|
|
3451
|
+
ateam_chain_status: async ({ chain_id, job_id }, sid) => {
|
|
3452
|
+
const id = chain_id || job_id;
|
|
3453
|
+
if (!id) throw new Error("chain_id required");
|
|
3454
|
+
const creds = getCredentials(sid);
|
|
3455
|
+
const apiKey = creds?.apiKey;
|
|
3456
|
+
if (!apiKey) throw new Error("No api_key in session — call ateam_auth(api_key) first.");
|
|
3457
|
+
const coreUrl = process.env.ADAS_CORE_URL || "http://adas-backend:4000";
|
|
3458
|
+
const res = await fetch(`${coreUrl}/api/job/${encodeURIComponent(id)}/status`, {
|
|
3459
|
+
method: "GET",
|
|
3460
|
+
headers: { "x-api-key": apiKey, "X-ADAS-SERVICE": "ateam-mcp.chain_status" },
|
|
3461
|
+
signal: AbortSignal.timeout(15_000),
|
|
3462
|
+
});
|
|
3463
|
+
const text = await res.text();
|
|
3464
|
+
let data;
|
|
3465
|
+
try { data = JSON.parse(text); } catch { data = { ok: false, error: text.slice(0, 400) }; }
|
|
3466
|
+
if (!res.ok) {
|
|
3467
|
+
throw new Error(`Core /api/job/${id}/status returned ${res.status}: ${data.error || JSON.stringify(data).slice(0, 200)}`);
|
|
3468
|
+
}
|
|
3469
|
+
// Surface the chain-aggregate truth as the primary fields; keep the raw
|
|
3470
|
+
// slim job under `job` for callers that want per-job detail.
|
|
3471
|
+
return {
|
|
3472
|
+
chain_id: data.chainId || id,
|
|
3473
|
+
chain_status: data.chainStatus ?? data.status ?? null,
|
|
3474
|
+
chain_done: data.chainDone ?? data.done ?? null,
|
|
3475
|
+
pending_question: data.pendingQuestion || null,
|
|
3476
|
+
result: data.result ?? null,
|
|
3477
|
+
progress: data.progress || null,
|
|
3478
|
+
job: data,
|
|
3479
|
+
};
|
|
3480
|
+
},
|
|
3481
|
+
|
|
3424
3482
|
ateam_get_widget_catalog: async ({ origin, format }, sid) => {
|
|
3425
3483
|
// Wraps Core's existing GET /api/ui-plugins (merged tenant plugin list)
|
|
3426
3484
|
// and enriches each entry with the documentation/how-to-use layer.
|