@ateam-ai/mcp 0.4.31 → 0.4.33
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 +52 -12
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -136,11 +136,13 @@ async function verifyWidgetHealth(solution_id, sid) {
|
|
|
136
136
|
} catch (e) {
|
|
137
137
|
return { ok: false, error: `widget health: could not read solution definition — ${e.message}` };
|
|
138
138
|
}
|
|
139
|
-
if (declared.length === 0) return null; // no widgets → nothing to verify
|
|
140
139
|
|
|
141
|
-
// 2. Live catalog — what Core actually discovered/serves right now.
|
|
142
|
-
//
|
|
143
|
-
//
|
|
140
|
+
// 2. Live catalog — what Core actually discovered/serves right now. Includes
|
|
141
|
+
// CONNECTOR-BUNDLED widgets that render WITHOUT being declared in ui_plugins[],
|
|
142
|
+
// so we must consult it even when ui_plugins is empty (was the bug: verify
|
|
143
|
+
// reported "no widgets declared / checked 0" while 16 widgets were live).
|
|
144
|
+
// Go through the Builder proxy (reliable from any connection), NOT
|
|
145
|
+
// ADAS_CORE_URL directly (unreachable from remote/desktop MCP).
|
|
144
146
|
let live = [];
|
|
145
147
|
try {
|
|
146
148
|
const data = await get(`/deploy/solutions/${solution_id}/ui-plugins`, sid);
|
|
@@ -150,6 +152,29 @@ async function verifyWidgetHealth(solution_id, sid) {
|
|
|
150
152
|
}
|
|
151
153
|
const liveById = new Map(live.map((p) => [p?.id, p]));
|
|
152
154
|
|
|
155
|
+
// Nothing declared AND nothing served → genuinely no widgets.
|
|
156
|
+
if (declared.length === 0 && live.length === 0) return null;
|
|
157
|
+
|
|
158
|
+
// Nothing declared but connectors SERVE widgets → verify the live
|
|
159
|
+
// (connector-bundled) set instead of falsely reporting "no widgets".
|
|
160
|
+
if (declared.length === 0) {
|
|
161
|
+
const plugins = live.map((p) => {
|
|
162
|
+
const render_ok = _widgetHasRender(p?.render);
|
|
163
|
+
return {
|
|
164
|
+
id: p?.id || "(missing)", discovered: true, render_ok, source: "connector-bundled",
|
|
165
|
+
problems: render_ok ? [] : ["no usable render block — need render.mode + iframeUrl (iframe) or reactNative.component (RN)"],
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
const unhealthy = plugins.filter((p) => p.problems.length);
|
|
169
|
+
return {
|
|
170
|
+
ok: unhealthy.length === 0,
|
|
171
|
+
checked: plugins.length,
|
|
172
|
+
note: `${plugins.length} connector-bundled widget(s) served by connectors (none declared in solution.ui_plugins[])`,
|
|
173
|
+
plugins,
|
|
174
|
+
issues: unhealthy.flatMap((p) => p.problems.map((pr) => `${p.id}: ${pr}`)),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
153
178
|
// 3. Cross-check each declared plugin against live discovery + render block
|
|
154
179
|
const plugins = declared.map((d) => {
|
|
155
180
|
const id = typeof d === "string" ? d : d?.id;
|
|
@@ -3478,12 +3503,18 @@ const handlers = {
|
|
|
3478
3503
|
// the redeploy with ateam_redeploy(solution_id, skill_id).
|
|
3479
3504
|
let redeployResult;
|
|
3480
3505
|
try {
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3506
|
+
const rdEndpoint = (target === "skill" && skill_id)
|
|
3507
|
+
? `/deploy/solutions/${solution_id}/skills/${skill_id}/redeploy`
|
|
3508
|
+
: `/deploy/solutions/${solution_id}/redeploy`;
|
|
3509
|
+
// Async-first, same as ateam_redeploy: a bulk (solution) redeploy of a
|
|
3510
|
+
// many-skill solution takes >100s and 524s on the sync path — the patch
|
|
3511
|
+
// then LOOKED like it failed / never reached Core. Kick async + poll;
|
|
3512
|
+
// fall back to sync for older backends.
|
|
3513
|
+
const kicked = await post(rdEndpoint, { async: true }, sid, { timeoutMs: 30_000 });
|
|
3514
|
+
redeployResult = (kicked?.async && kicked.job_id)
|
|
3515
|
+
? await pollDeployJob(kicked.job_id, sid, { label: skill_id ? `redeploy-skill ${skill_id}` : "redeploy-bulk", maxMs: 15 * 60_000, intervalMs: 2000 })
|
|
3516
|
+
: kicked;
|
|
3517
|
+
phases.push({ phase: "redeploy", status: redeployResult?.ok === false ? "error" : "done" });
|
|
3487
3518
|
} catch (err) {
|
|
3488
3519
|
// Partial success: patch is saved to GitHub, only redeploy failed.
|
|
3489
3520
|
// Return ok:true so the agent doesn't think the patch was lost.
|
|
@@ -3985,8 +4016,17 @@ const handlers = {
|
|
|
3985
4016
|
// Reaches the catalog through the Builder proxy (/deploy/.../ui-plugins) on
|
|
3986
4017
|
// the normal base URL — reliable from any connection. (The old direct
|
|
3987
4018
|
// ADAS_CORE_URL fetch "fetch failed" from remote/desktop MCP connections.)
|
|
3988
|
-
|
|
3989
|
-
|
|
4019
|
+
// solution_id is optional (one tenant = one solution): auto-resolve the
|
|
4020
|
+
// tenant's solution when omitted, per the doc — don't hard-error.
|
|
4021
|
+
let sol = solution_id;
|
|
4022
|
+
if (!sol) {
|
|
4023
|
+
const list = await get(`/deploy/solutions`, sid).catch((e) => { throw new Error(`solution_id omitted and could not list the tenant's solutions to auto-resolve: ${e.message}`); });
|
|
4024
|
+
const sols = Array.isArray(list?.solutions) ? list.solutions : [];
|
|
4025
|
+
if (sols.length === 1) sol = sols[0]?.id || sols[0];
|
|
4026
|
+
else if (sols.length === 0) throw new Error("solution_id omitted and this tenant has no solutions yet.");
|
|
4027
|
+
else throw new Error(`solution_id omitted and this tenant has multiple solutions (${sols.map((s) => s?.id || s).join(", ")}) — pass solution_id explicitly.`);
|
|
4028
|
+
}
|
|
4029
|
+
const data = await get(`/deploy/solutions/${sol}/ui-plugins`, sid);
|
|
3990
4030
|
if (data?.ok === false) {
|
|
3991
4031
|
throw new Error(`widget catalog unavailable: ${data.error || "unknown"}`);
|
|
3992
4032
|
}
|