@integrity-labs/agt-cli 0.28.288 → 0.28.290

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.
@@ -43,6 +43,46 @@ function buildEnableToolsetRequest(toolset) {
43
43
  params: { name: "enable_toolset", arguments: { name: toolset } }
44
44
  });
45
45
  }
46
+ function buildToolsListRequest() {
47
+ return JSON.stringify({ jsonrpc: "2.0", id: "agt-union-list", method: "tools/list", params: {} });
48
+ }
49
+ function toolName(t) {
50
+ return t && typeof t === "object" && typeof t.name === "string" ? t.name : "";
51
+ }
52
+ function extractToolsArray(message) {
53
+ try {
54
+ const tools = JSON.parse(message)?.result?.tools;
55
+ return Array.isArray(tools) ? tools : [];
56
+ } catch {
57
+ return [];
58
+ }
59
+ }
60
+ function parseEnableToolsetResponse(message) {
61
+ let payload;
62
+ try {
63
+ const obj = JSON.parse(message);
64
+ payload = obj?.result ?? obj;
65
+ const content = payload?.content;
66
+ if (Array.isArray(content)) {
67
+ const textPart = content.find(
68
+ (c) => c && typeof c === "object" && c.type === "text" && typeof c.text === "string"
69
+ );
70
+ if (textPart?.text) {
71
+ try {
72
+ payload = JSON.parse(textPart.text);
73
+ } catch {
74
+ }
75
+ }
76
+ }
77
+ } catch {
78
+ return { activated: null, newlyAvailable: [] };
79
+ }
80
+ const p = payload && typeof payload === "object" ? payload : null;
81
+ const activated = p && typeof p.activated === "string" ? p.activated : null;
82
+ const nat = p && Array.isArray(p.newly_available_tools) ? p.newly_available_tools : [];
83
+ const newlyAvailable = nat.map((t) => typeof t === "string" ? t : toolName(t)).filter((n) => typeof n === "string" && n.length > 0);
84
+ return { activated, newlyAvailable };
85
+ }
46
86
  function parseToolAllowlist(raw) {
47
87
  const out = /* @__PURE__ */ new Set();
48
88
  for (const part of (raw || "").split(",")) {
@@ -126,53 +166,85 @@ function extractJsonRpcMessages(contentType, body) {
126
166
  }
127
167
  return out;
128
168
  }
129
- var preEnabledOnce = null;
130
- function ensurePreEnabled(token) {
131
- if (preEnabledOnce) return preEnabledOnce;
132
- preEnabledOnce = Promise.allSettled(
133
- preEnableToolsets.map(async (name) => {
134
- const res = await fetch(remoteUrl, {
135
- method: "POST",
136
- headers: {
137
- "Content-Type": "application/json",
138
- Accept: "application/json, text/event-stream",
139
- Authorization: `Bearer ${token}`
140
- },
141
- body: buildEnableToolsetRequest(name),
142
- signal: AbortSignal.timeout(REMOTE_FETCH_TIMEOUT_MS)
143
- });
144
- const body = await res.text().catch(() => "");
145
- if (!res.ok) {
146
- throw new Error(`HTTP ${res.status}${body ? ` (${body.slice(0, 200).replace(/\s+/g, " ").trim()})` : ""}`);
147
- }
148
- let rpcError;
169
+ async function postRpc(token, body) {
170
+ const res = await fetch(remoteUrl, {
171
+ method: "POST",
172
+ headers: {
173
+ "Content-Type": "application/json",
174
+ Accept: "application/json, text/event-stream",
175
+ Authorization: `Bearer ${token}`
176
+ },
177
+ body,
178
+ signal: AbortSignal.timeout(REMOTE_FETCH_TIMEOUT_MS)
179
+ });
180
+ const text = await res.text().catch(() => "");
181
+ return { ok: res.ok, status: res.status, ct: res.headers.get("content-type") ?? "", text };
182
+ }
183
+ var unionOnce = null;
184
+ var unionToolByName = /* @__PURE__ */ new Map();
185
+ var toolGroupByName = /* @__PURE__ */ new Map();
186
+ function mergeToolsListInto(ct, text) {
187
+ for (const m of extractJsonRpcMessages(ct, text)) {
188
+ for (const t of extractToolsArray(m)) {
189
+ const n = toolName(t);
190
+ if (n) unionToolByName.set(n, t);
191
+ }
192
+ }
193
+ }
194
+ function ensureUnionManifest(token) {
195
+ if (unionOnce) return unionOnce;
196
+ unionOnce = (async () => {
197
+ try {
198
+ const seed = await postRpc(token, buildToolsListRequest());
199
+ mergeToolsListInto(seed.ct, seed.text);
200
+ } catch (err) {
201
+ logErr(`union: seed tools/list failed: ${err.message}`);
202
+ }
203
+ for (const group of preEnableToolsets) {
149
204
  try {
150
- rpcError = JSON.parse(body)?.error?.message;
151
- } catch {
152
- }
153
- if (rpcError) throw new Error(rpcError);
154
- return name;
155
- })
156
- ).then((results) => {
157
- results.forEach((r, i) => {
158
- const name = preEnableToolsets[i];
159
- if (r.status === "fulfilled") {
160
- logErr(`pre-enabled toolset "${name}"`);
161
- } else {
162
- logErr(`pre-enable toolset "${name}" failed: ${r.reason.message}`);
205
+ const en = await postRpc(token, buildEnableToolsetRequest(group));
206
+ if (!en.ok) {
207
+ logErr(`union: enable "${group}" HTTP ${en.status}`);
208
+ continue;
209
+ }
210
+ for (const m of extractJsonRpcMessages(en.ct, en.text)) {
211
+ for (const nm of parseEnableToolsetResponse(m).newlyAvailable) toolGroupByName.set(nm, group);
212
+ }
213
+ for (const nm of parseEnableToolsetResponse(en.text).newlyAvailable) toolGroupByName.set(nm, group);
214
+ const li = await postRpc(token, buildToolsListRequest());
215
+ mergeToolsListInto(li.ct, li.text);
216
+ logErr(`union: enabled "${group}" (union now ${unionToolByName.size} tools, ${toolGroupByName.size} mapped)`);
217
+ } catch (err) {
218
+ logErr(`union: enable "${group}" failed: ${err.message}`);
163
219
  }
164
- });
165
- });
166
- return preEnabledOnce;
220
+ }
221
+ })();
222
+ return unionOnce;
167
223
  }
168
- async function forward(line, id, isNotification, method) {
224
+ async function forward(line, id, isNotification, method, params) {
169
225
  const token = readCurrentToken(tokenFile, tokenVar);
170
226
  if (!token) {
171
227
  logErr(`no token in ${tokenFile} (var ${tokenVar})`);
172
228
  return isNotification ? [] : [jsonRpcError(id, -32e3, `${label}: no current access token available (reconnect the integration)`)];
173
229
  }
174
230
  if (method === "tools/list" && preEnableToolsets.length > 0) {
175
- await ensurePreEnabled(token);
231
+ await ensureUnionManifest(token);
232
+ let tools = [...unionToolByName.values()];
233
+ if (toolAllowlist.size > 0) tools = tools.filter((t) => toolAllowlist.has(toolName(t)));
234
+ return [JSON.stringify({ jsonrpc: "2.0", id: id ?? null, result: { tools } })];
235
+ }
236
+ if (method === "tools/call" && preEnableToolsets.length > 0) {
237
+ await ensureUnionManifest(token);
238
+ const callName = params && typeof params === "object" && typeof params.name === "string" ? params.name : "";
239
+ const group = callName ? toolGroupByName.get(callName) : void 0;
240
+ if (group) {
241
+ try {
242
+ const en = await postRpc(token, buildEnableToolsetRequest(group));
243
+ if (!en.ok) logErr(`per-call enable "${group}" for "${callName}" HTTP ${en.status}`);
244
+ } catch (err) {
245
+ logErr(`per-call enable "${group}" for "${callName}" failed: ${err.message}`);
246
+ }
247
+ }
176
248
  }
177
249
  let res;
178
250
  try {
@@ -265,7 +337,7 @@ async function main() {
265
337
  return;
266
338
  }
267
339
  }
268
- const task = forward(text, id, isNotification, parsed.method).then(writeReplies).catch((err) => {
340
+ const task = forward(text, id, isNotification, parsed.method, parsed.params).then(writeReplies).catch((err) => {
269
341
  logErr(`handler error: ${err.message}`);
270
342
  });
271
343
  inflight.add(task);
@@ -289,11 +361,15 @@ if (invokedDirectly) {
289
361
  }
290
362
  export {
291
363
  buildEnableToolsetRequest,
364
+ buildToolsListRequest,
292
365
  extractJsonRpcMessages,
366
+ extractToolsArray,
293
367
  filterToolsListMessage,
294
368
  isToolCallBlocked,
295
369
  main,
370
+ parseEnableToolsetResponse,
296
371
  parsePreEnableToolsets,
297
372
  parseToolAllowlist,
298
- readCurrentToken
373
+ readCurrentToken,
374
+ toolName
299
375
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.288",
3
+ "version": "0.28.290",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {