@slashfi/agents-sdk 0.31.0 → 0.32.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/auth-governance.d.ts +37 -0
- package/dist/auth-governance.d.ts.map +1 -0
- package/dist/auth-governance.js +73 -0
- package/dist/auth-governance.js.map +1 -0
- package/dist/call-agent-schema.d.ts +20 -0
- package/dist/call-agent-schema.d.ts.map +1 -1
- package/dist/call-agent-schema.js +19 -0
- package/dist/call-agent-schema.js.map +1 -1
- package/dist/cjs/auth-governance.js +79 -0
- package/dist/cjs/auth-governance.js.map +1 -0
- package/dist/cjs/call-agent-schema.js +20 -1
- package/dist/cjs/call-agent-schema.js.map +1 -1
- package/dist/cjs/define-config.js +1 -0
- package/dist/cjs/define-config.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/key-manager.js +9 -4
- package/dist/cjs/key-manager.js.map +1 -1
- package/dist/cjs/registry-consumer.js +122 -37
- package/dist/cjs/registry-consumer.js.map +1 -1
- package/dist/cjs/server.js +149 -209
- package/dist/cjs/server.js.map +1 -1
- package/dist/define-config.d.ts +8 -0
- package/dist/define-config.d.ts.map +1 -1
- package/dist/define-config.js +1 -0
- package/dist/define-config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/key-manager.d.ts.map +1 -1
- package/dist/key-manager.js +9 -4
- package/dist/key-manager.js.map +1 -1
- package/dist/registry-consumer.d.ts +4 -0
- package/dist/registry-consumer.d.ts.map +1 -1
- package/dist/registry-consumer.js +122 -37
- package/dist/registry-consumer.js.map +1 -1
- package/dist/server.d.ts +3 -13
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +136 -199
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/src/auth-governance.ts +94 -0
- package/src/call-agent-schema.ts +33 -0
- package/src/codegen.test.ts +10 -0
- package/src/consumer.test.ts +132 -0
- package/src/define-config.ts +12 -0
- package/src/index.ts +2 -0
- package/src/key-manager.test.ts +17 -0
- package/src/key-manager.ts +10 -4
- package/src/registry-consumer.ts +161 -37
- package/src/server.ts +180 -215
package/dist/cjs/server.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Minimal JSON-RPC server implementing the MCP protocol for agent interaction.
|
|
6
6
|
* Handles only core SDK concerns:
|
|
7
7
|
* - MCP protocol (initialize, tools/list, tools/call)
|
|
8
|
-
* - Agent registry routing (call_agent, list_agents
|
|
8
|
+
* - Agent registry routing (call_agent, list_agents)
|
|
9
9
|
* - Auth resolution (Bearer tokens, root key, JWT)
|
|
10
10
|
* - OAuth2 token exchange (client_credentials)
|
|
11
11
|
* - Health check
|
|
@@ -26,10 +26,9 @@
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.hasAdminScope =
|
|
29
|
+
exports.getVisibleTools = exports.canSeeTool = exports.canSeeAgent = exports.hasAdminScope = void 0;
|
|
30
30
|
exports.detectAuth = detectAuth;
|
|
31
31
|
exports.resolveAuth = resolveAuth;
|
|
32
|
-
exports.canSeeAgent = canSeeAgent;
|
|
33
32
|
exports.createAgentServer = createAgentServer;
|
|
34
33
|
const secrets_js_1 = require("./agent-definitions/secrets.js");
|
|
35
34
|
const bm25_js_1 = require("./bm25.js");
|
|
@@ -37,12 +36,13 @@ const jwt_js_1 = require("./jwt.js");
|
|
|
37
36
|
const jwt_js_2 = require("./jwt.js");
|
|
38
37
|
const oidc_signin_js_1 = require("./oidc-signin.js");
|
|
39
38
|
const call_agent_schema_js_1 = require("./call-agent-schema.js");
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
39
|
+
// Auth governance — single source of truth for visibility/access control
|
|
40
|
+
var auth_governance_js_1 = require("./auth-governance.js");
|
|
41
|
+
Object.defineProperty(exports, "hasAdminScope", { enumerable: true, get: function () { return auth_governance_js_1.hasAdminScope; } });
|
|
42
|
+
Object.defineProperty(exports, "canSeeAgent", { enumerable: true, get: function () { return auth_governance_js_1.canSeeAgent; } });
|
|
43
|
+
Object.defineProperty(exports, "canSeeTool", { enumerable: true, get: function () { return auth_governance_js_1.canSeeTool; } });
|
|
44
|
+
Object.defineProperty(exports, "getVisibleTools", { enumerable: true, get: function () { return auth_governance_js_1.getVisibleTools; } });
|
|
45
|
+
const auth_governance_js_2 = require("./auth-governance.js");
|
|
46
46
|
// ============================================
|
|
47
47
|
// HTTP Helpers
|
|
48
48
|
// ============================================
|
|
@@ -195,18 +195,6 @@ async function resolveAuth(req, authConfig, jwksOptions) {
|
|
|
195
195
|
claims: {},
|
|
196
196
|
};
|
|
197
197
|
}
|
|
198
|
-
function canSeeAgent(agent, auth) {
|
|
199
|
-
const visibility = (agent.visibility ??
|
|
200
|
-
agent.config?.visibility ??
|
|
201
|
-
"internal");
|
|
202
|
-
if (hasAdminScope(auth))
|
|
203
|
-
return true;
|
|
204
|
-
if (visibility === "public")
|
|
205
|
-
return true;
|
|
206
|
-
if (visibility === "internal" && auth)
|
|
207
|
-
return true;
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
198
|
/**
|
|
211
199
|
* Resolve an agent by path, handling @ prefix normalization.
|
|
212
200
|
* Tries the path as-is first, then with @ prefix.
|
|
@@ -215,35 +203,6 @@ function resolveAgent(registry, path) {
|
|
|
215
203
|
const normalized = path.replace(/^@/, "");
|
|
216
204
|
return registry.get(normalized) ?? registry.get(`@${normalized}`);
|
|
217
205
|
}
|
|
218
|
-
/**
|
|
219
|
-
* Filter tools visible on a public agent endpoint.
|
|
220
|
-
* For /agents/ routes, tools inherit the agent's visibility:
|
|
221
|
-
* - If agent is public, tools without explicit visibility are shown
|
|
222
|
-
* - Tool-level visibility still overrides (e.g. visibility: "private" hides it)
|
|
223
|
-
*/
|
|
224
|
-
function getVisibleTools(agent, auth) {
|
|
225
|
-
const agentVisibility = (agent.visibility ??
|
|
226
|
-
agent.config?.visibility ??
|
|
227
|
-
"internal");
|
|
228
|
-
return agent.tools.filter((t) => {
|
|
229
|
-
const tv = t.visibility;
|
|
230
|
-
if (hasAdminScope(auth))
|
|
231
|
-
return true;
|
|
232
|
-
// Tool has explicit visibility — respect it
|
|
233
|
-
if (tv === "public")
|
|
234
|
-
return true;
|
|
235
|
-
if (tv === "private")
|
|
236
|
-
return hasAdminScope(auth) ?? false;
|
|
237
|
-
if (tv === "internal" && auth)
|
|
238
|
-
return true;
|
|
239
|
-
// No explicit tool visibility — inherit from agent
|
|
240
|
-
if (!tv && agentVisibility === "public")
|
|
241
|
-
return true;
|
|
242
|
-
if (!tv && agentVisibility === "internal" && auth)
|
|
243
|
-
return true;
|
|
244
|
-
return false;
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
206
|
// ============================================
|
|
248
207
|
// MCP Tool Definitions
|
|
249
208
|
// ============================================
|
|
@@ -256,34 +215,8 @@ function getToolDefinitions() {
|
|
|
256
215
|
},
|
|
257
216
|
{
|
|
258
217
|
name: "list_agents",
|
|
259
|
-
description: "List all registered agents and their available tools.",
|
|
260
|
-
inputSchema:
|
|
261
|
-
type: "object",
|
|
262
|
-
properties: {},
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
name: "search_agent_tools",
|
|
267
|
-
description: "Search across all registered agent tools using natural language. Returns tools ranked by relevance using BM25 scoring.",
|
|
268
|
-
inputSchema: {
|
|
269
|
-
type: "object",
|
|
270
|
-
properties: {
|
|
271
|
-
query: {
|
|
272
|
-
type: "string",
|
|
273
|
-
description: "Natural language search query (e.g. 'send a message', 'database query')",
|
|
274
|
-
},
|
|
275
|
-
agents: {
|
|
276
|
-
type: "array",
|
|
277
|
-
items: { type: "string" },
|
|
278
|
-
description: "Optional list of agent paths to search within (e.g. ['@notifications', '@db']). Searches all agents if omitted.",
|
|
279
|
-
},
|
|
280
|
-
limit: {
|
|
281
|
-
type: "number",
|
|
282
|
-
description: "Maximum number of results to return (default: 10)",
|
|
283
|
-
},
|
|
284
|
-
},
|
|
285
|
-
required: ["query"],
|
|
286
|
-
},
|
|
218
|
+
description: "List all registered agents and their available tools. Optionally search/filter by query using BM25 ranking.",
|
|
219
|
+
inputSchema: call_agent_schema_js_1.listAgentsInputSchema,
|
|
287
220
|
},
|
|
288
221
|
];
|
|
289
222
|
}
|
|
@@ -360,7 +293,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
360
293
|
if (auth.issuer)
|
|
361
294
|
req.metadata.issuer = auth.issuer;
|
|
362
295
|
}
|
|
363
|
-
if (hasAdminScope(auth)) {
|
|
296
|
+
if ((0, auth_governance_js_2.hasAdminScope)(auth)) {
|
|
364
297
|
req.callerType = "system";
|
|
365
298
|
}
|
|
366
299
|
// Process secret params: resolve refs, store raw secrets
|
|
@@ -376,11 +309,64 @@ function createAgentServer(registry, options = {}) {
|
|
|
376
309
|
return mcpResult(result);
|
|
377
310
|
}
|
|
378
311
|
case "list_agents": {
|
|
312
|
+
const { query: listQuery, limit: listLimit, cursor: listCursor } = call_agent_schema_js_1.listAgentsToolInputSchema.parse(args);
|
|
379
313
|
const agents = registry.list();
|
|
380
|
-
|
|
314
|
+
let visible = agents.filter((agent) => (0, auth_governance_js_2.canSeeAgent)(agent, auth));
|
|
315
|
+
// Decode cursor if provided
|
|
316
|
+
const after = listCursor
|
|
317
|
+
? JSON.parse(Buffer.from(listCursor, "base64url").toString())
|
|
318
|
+
: undefined;
|
|
319
|
+
const pageSize = listLimit ?? 20;
|
|
320
|
+
let page;
|
|
321
|
+
let nextCursor;
|
|
322
|
+
if (listQuery) {
|
|
323
|
+
// BM25 search — ranked by score desc, path asc for tie-breaking
|
|
324
|
+
const docs = visible.map((agent, i) => ({
|
|
325
|
+
id: String(i),
|
|
326
|
+
text: [
|
|
327
|
+
agent.path,
|
|
328
|
+
agent.config?.name ?? "",
|
|
329
|
+
agent.config?.description ?? "",
|
|
330
|
+
...agent.tools
|
|
331
|
+
.filter((t) => (0, auth_governance_js_2.canSeeTool)(t, auth))
|
|
332
|
+
.map((t) => `${t.name} ${t.description}`),
|
|
333
|
+
].join(" "),
|
|
334
|
+
}));
|
|
335
|
+
const index = (0, bm25_js_1.createBM25Index)(docs);
|
|
336
|
+
const ranked = index.search(listQuery);
|
|
337
|
+
let scored = ranked.map((r) => ({
|
|
338
|
+
...visible[Number(r.id)],
|
|
339
|
+
_score: r.score,
|
|
340
|
+
}));
|
|
341
|
+
// Apply cursor: skip past the after position
|
|
342
|
+
if (after?.score !== undefined) {
|
|
343
|
+
scored = scored.filter((a) => a._score < after.score ||
|
|
344
|
+
(a._score === after.score && a.path > after.path));
|
|
345
|
+
}
|
|
346
|
+
page = scored.slice(0, pageSize);
|
|
347
|
+
if (scored.length > pageSize) {
|
|
348
|
+
const last = scored[pageSize - 1];
|
|
349
|
+
nextCursor = Buffer.from(JSON.stringify({ path: last.path, score: last._score })).toString("base64url");
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
// Alphabetical listing — sorted by path
|
|
354
|
+
visible.sort((a, b) => a.path.localeCompare(b.path));
|
|
355
|
+
// Apply cursor: skip past afterPath
|
|
356
|
+
if (after) {
|
|
357
|
+
visible = visible.filter((a) => a.path > after.path);
|
|
358
|
+
}
|
|
359
|
+
page = visible.slice(0, pageSize);
|
|
360
|
+
if (visible.length > pageSize) {
|
|
361
|
+
const last = page[page.length - 1];
|
|
362
|
+
nextCursor = Buffer.from(JSON.stringify({ path: last.path })).toString("base64url");
|
|
363
|
+
}
|
|
364
|
+
}
|
|
381
365
|
return mcpResult({
|
|
382
366
|
success: true,
|
|
383
|
-
|
|
367
|
+
total: agents.filter((a) => (0, auth_governance_js_2.canSeeAgent)(a, auth)).length,
|
|
368
|
+
nextCursor,
|
|
369
|
+
agents: page.map((agent) => ({
|
|
384
370
|
path: agent.path,
|
|
385
371
|
name: agent.config?.name,
|
|
386
372
|
description: agent.config?.description,
|
|
@@ -395,104 +381,11 @@ function createAgentServer(registry, options = {}) {
|
|
|
395
381
|
mimeType: r.mimeType,
|
|
396
382
|
})),
|
|
397
383
|
tools: agent.tools
|
|
398
|
-
.filter((t) =>
|
|
399
|
-
const tv = t.visibility ?? "internal";
|
|
400
|
-
if (hasAdminScope(auth))
|
|
401
|
-
return true;
|
|
402
|
-
if (tv === "public")
|
|
403
|
-
return true;
|
|
404
|
-
if (tv === "authenticated" &&
|
|
405
|
-
auth?.callerId &&
|
|
406
|
-
auth.callerId !== "anonymous")
|
|
407
|
-
return true;
|
|
408
|
-
if (tv === "internal" && auth)
|
|
409
|
-
return true;
|
|
410
|
-
return false;
|
|
411
|
-
})
|
|
384
|
+
.filter((t) => (0, auth_governance_js_2.canSeeTool)(t, auth))
|
|
412
385
|
.map((t) => t.name),
|
|
413
386
|
})),
|
|
414
387
|
});
|
|
415
388
|
}
|
|
416
|
-
case "search_agent_tools": {
|
|
417
|
-
const { query, agents: agentFilter, limit: resultLimit } = args;
|
|
418
|
-
const agents = registry.list();
|
|
419
|
-
const visible = agents.filter((agent) => {
|
|
420
|
-
if (!canSeeAgent(agent, auth))
|
|
421
|
-
return false;
|
|
422
|
-
if (agentFilter && agentFilter.length > 0) {
|
|
423
|
-
return agentFilter.includes(agent.path);
|
|
424
|
-
}
|
|
425
|
-
return true;
|
|
426
|
-
});
|
|
427
|
-
// Build search documents from all visible tools
|
|
428
|
-
const documents = [];
|
|
429
|
-
for (const agent of visible) {
|
|
430
|
-
const visibleTools = agent.tools.filter((t) => {
|
|
431
|
-
const tv = t.visibility ?? "internal";
|
|
432
|
-
if (hasAdminScope(auth))
|
|
433
|
-
return true;
|
|
434
|
-
if (tv === "public")
|
|
435
|
-
return true;
|
|
436
|
-
if (tv === "authenticated" &&
|
|
437
|
-
auth?.callerId &&
|
|
438
|
-
auth.callerId !== "anonymous")
|
|
439
|
-
return true;
|
|
440
|
-
if (tv === "internal" && auth)
|
|
441
|
-
return true;
|
|
442
|
-
return false;
|
|
443
|
-
});
|
|
444
|
-
for (const tool of visibleTools) {
|
|
445
|
-
// Build searchable text from tool name, description, agent context, and schema
|
|
446
|
-
const parts = [
|
|
447
|
-
tool.name,
|
|
448
|
-
tool.description,
|
|
449
|
-
agent.config?.name ?? "",
|
|
450
|
-
agent.config?.description ?? "",
|
|
451
|
-
agent.path,
|
|
452
|
-
];
|
|
453
|
-
// Include property names and descriptions from input schema
|
|
454
|
-
const schema = tool.inputSchema;
|
|
455
|
-
if (schema?.properties) {
|
|
456
|
-
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
457
|
-
parts.push(key);
|
|
458
|
-
if (prop?.description) {
|
|
459
|
-
parts.push(prop.description);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
documents.push({
|
|
464
|
-
id: `${agent.path}/${tool.name}`,
|
|
465
|
-
text: parts.join(" "),
|
|
466
|
-
agentPath: agent.path,
|
|
467
|
-
toolName: tool.name,
|
|
468
|
-
description: tool.description,
|
|
469
|
-
agentName: agent.config?.name,
|
|
470
|
-
agentDescription: agent.config?.description,
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
const index = (0, bm25_js_1.createBM25Index)(documents);
|
|
475
|
-
const results = index.search(query, resultLimit ?? 10);
|
|
476
|
-
// Map results back to tool details
|
|
477
|
-
const docMap = new Map(documents.map((d) => [d.id, d]));
|
|
478
|
-
const matches = results.map((r) => {
|
|
479
|
-
const doc = docMap.get(r.id);
|
|
480
|
-
return {
|
|
481
|
-
agentPath: doc.agentPath,
|
|
482
|
-
tool: doc.toolName,
|
|
483
|
-
description: doc.description,
|
|
484
|
-
agentName: doc.agentName,
|
|
485
|
-
agentDescription: doc.agentDescription,
|
|
486
|
-
score: r.score,
|
|
487
|
-
};
|
|
488
|
-
});
|
|
489
|
-
return mcpResult({
|
|
490
|
-
success: true,
|
|
491
|
-
query,
|
|
492
|
-
results: matches,
|
|
493
|
-
total: matches.length,
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
389
|
default:
|
|
497
390
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
498
391
|
}
|
|
@@ -847,8 +740,11 @@ function createAgentServer(registry, options = {}) {
|
|
|
847
740
|
// Only exposed when the server requires auth (private registries).
|
|
848
741
|
// Public registries (e.g. registry.slash.com) skip this entirely.
|
|
849
742
|
if (path === "/.well-known/oauth-authorization-server" &&
|
|
850
|
-
req.method === "GET"
|
|
851
|
-
(options.registry?.oauthCallbackUrl || serverSigningKeys.length > 0)) {
|
|
743
|
+
req.method === "GET") {
|
|
744
|
+
if (!(options.registry?.oauthCallbackUrl || serverSigningKeys.length > 0)) {
|
|
745
|
+
const res = new Response("Not Found", { status: 404 });
|
|
746
|
+
return cors ? addCors(res) : res;
|
|
747
|
+
}
|
|
852
748
|
const baseUrl = resolveBaseUrl(req);
|
|
853
749
|
const res = jsonResponse({
|
|
854
750
|
issuer: baseUrl,
|
|
@@ -865,32 +761,76 @@ function createAgentServer(registry, options = {}) {
|
|
|
865
761
|
});
|
|
866
762
|
return cors ? addCors(res) : res;
|
|
867
763
|
}
|
|
868
|
-
// ── GET /list → List agents (
|
|
764
|
+
// ── GET /list → List agents (──
|
|
869
765
|
if (path === "/list" && req.method === "GET") {
|
|
870
766
|
const agents = registry.list();
|
|
871
|
-
|
|
872
|
-
const
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
767
|
+
let visible = agents.filter((agent) => (0, auth_governance_js_2.canSeeAgent)(agent, effectiveAuth));
|
|
768
|
+
const searchQuery = url.searchParams.get("q");
|
|
769
|
+
const searchLimit = url.searchParams.get("limit");
|
|
770
|
+
const searchCursor = url.searchParams.get("cursor");
|
|
771
|
+
// Decode cursor
|
|
772
|
+
const httpAfter = searchCursor
|
|
773
|
+
? JSON.parse(Buffer.from(searchCursor, "base64url").toString())
|
|
774
|
+
: undefined;
|
|
775
|
+
const httpPageSize = searchLimit ? Number(searchLimit) : 20;
|
|
776
|
+
let httpPage;
|
|
777
|
+
let httpNextCursor;
|
|
778
|
+
if (searchQuery) {
|
|
779
|
+
const docs = visible.map((agent, i) => ({
|
|
780
|
+
id: String(i),
|
|
781
|
+
text: [
|
|
782
|
+
agent.path,
|
|
783
|
+
agent.config?.name ?? "",
|
|
784
|
+
agent.config?.description ?? "",
|
|
785
|
+
...agent.tools
|
|
786
|
+
.filter((t) => (0, auth_governance_js_2.canSeeTool)(t, effectiveAuth))
|
|
787
|
+
.map((t) => `${t.name} ${t.description}`),
|
|
788
|
+
].join(" "),
|
|
789
|
+
}));
|
|
790
|
+
const index = (0, bm25_js_1.createBM25Index)(docs);
|
|
791
|
+
const ranked = index.search(searchQuery);
|
|
792
|
+
let scored = ranked.map((r) => ({
|
|
793
|
+
...visible[Number(r.id)],
|
|
794
|
+
_score: r.score,
|
|
795
|
+
}));
|
|
796
|
+
if (httpAfter?.score !== undefined) {
|
|
797
|
+
scored = scored.filter((a) => a._score < httpAfter.score ||
|
|
798
|
+
(a._score === httpAfter.score && a.path > httpAfter.path));
|
|
799
|
+
}
|
|
800
|
+
httpPage = scored.slice(0, httpPageSize);
|
|
801
|
+
if (scored.length > httpPageSize) {
|
|
802
|
+
const last = scored[httpPageSize - 1];
|
|
803
|
+
httpNextCursor = Buffer.from(JSON.stringify({ path: last.path, score: last._score })).toString("base64url");
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
visible.sort((a, b) => a.path.localeCompare(b.path));
|
|
808
|
+
if (httpAfter) {
|
|
809
|
+
visible = visible.filter((a) => a.path > httpAfter.path);
|
|
810
|
+
}
|
|
811
|
+
httpPage = visible.slice(0, httpPageSize);
|
|
812
|
+
if (visible.length > httpPageSize) {
|
|
813
|
+
const last = httpPage[httpPage.length - 1];
|
|
814
|
+
httpNextCursor = Buffer.from(JSON.stringify({ path: last.path })).toString("base64url");
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
const res = jsonResponse({
|
|
818
|
+
total: agents.filter((a) => (0, auth_governance_js_2.canSeeAgent)(a, effectiveAuth)).length,
|
|
819
|
+
nextCursor: httpNextCursor,
|
|
820
|
+
agents: httpPage.map((agent) => ({
|
|
821
|
+
path: agent.path,
|
|
822
|
+
name: agent.config?.name,
|
|
823
|
+
description: agent.config?.description,
|
|
824
|
+
supportedActions: agent.config?.supportedActions,
|
|
825
|
+
integration: agent.config?.integration || null,
|
|
826
|
+
tools: agent.tools
|
|
827
|
+
.filter((t) => (0, auth_governance_js_2.canSeeTool)(t, effectiveAuth))
|
|
828
|
+
.map((t) => ({
|
|
829
|
+
name: t.name,
|
|
830
|
+
description: t.description,
|
|
831
|
+
})),
|
|
892
832
|
})),
|
|
893
|
-
})
|
|
833
|
+
});
|
|
894
834
|
return cors ? addCors(res) : res;
|
|
895
835
|
}
|
|
896
836
|
// ── GET /agents → List public agents (discovery endpoint) ──
|
|
@@ -900,7 +840,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
900
840
|
// Only show agents with explicit visibility
|
|
901
841
|
if (!agent.visibility)
|
|
902
842
|
return false;
|
|
903
|
-
return canSeeAgent(agent, effectiveAuth);
|
|
843
|
+
return (0, auth_governance_js_2.canSeeAgent)(agent, effectiveAuth);
|
|
904
844
|
});
|
|
905
845
|
const res = jsonResponse(visible.map((agent) => ({
|
|
906
846
|
path: agent.path,
|
|
@@ -908,7 +848,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
908
848
|
description: agent.config?.description ?? agent.entrypoint?.slice(0, 200),
|
|
909
849
|
mode: agent.mode ?? 'direct',
|
|
910
850
|
...(agent.upstream && { upstream: agent.upstream }),
|
|
911
|
-
tools: getVisibleTools(agent, effectiveAuth).map((t) => ({
|
|
851
|
+
tools: (0, auth_governance_js_2.getVisibleTools)(agent, effectiveAuth).map((t) => ({
|
|
912
852
|
name: t.name,
|
|
913
853
|
description: t.description,
|
|
914
854
|
})),
|
|
@@ -919,7 +859,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
919
859
|
if (path.startsWith("/agents/") && req.method === "GET") {
|
|
920
860
|
const agentPath = path.slice("/agents/".length); // e.g. "notion"
|
|
921
861
|
const agent = resolveAgent(registry, agentPath);
|
|
922
|
-
if (!agent || !canSeeAgent(agent, effectiveAuth)) {
|
|
862
|
+
if (!agent || !(0, auth_governance_js_2.canSeeAgent)(agent, effectiveAuth)) {
|
|
923
863
|
const res = jsonResponse({ error: "not_found", message: `Agent not found: ${agentPath}` }, 404);
|
|
924
864
|
return cors ? addCors(res) : res;
|
|
925
865
|
}
|
|
@@ -929,7 +869,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
929
869
|
description: agent.config?.description ?? agent.entrypoint?.slice(0, 200),
|
|
930
870
|
mode: agent.mode ?? 'direct',
|
|
931
871
|
...(agent.upstream && { upstream: agent.upstream }),
|
|
932
|
-
tools: getVisibleTools(agent, effectiveAuth).map((t) => ({
|
|
872
|
+
tools: (0, auth_governance_js_2.getVisibleTools)(agent, effectiveAuth).map((t) => ({
|
|
933
873
|
name: t.name,
|
|
934
874
|
description: t.description,
|
|
935
875
|
inputSchema: t.inputSchema,
|
|
@@ -943,11 +883,11 @@ function createAgentServer(registry, options = {}) {
|
|
|
943
883
|
if (path === "/call" && req.method === "POST") {
|
|
944
884
|
const body = (await req.json());
|
|
945
885
|
const agent = resolveAgent(registry, body.path);
|
|
946
|
-
if (!agent || !canSeeAgent(agent, effectiveAuth)) {
|
|
886
|
+
if (!agent || !(0, auth_governance_js_2.canSeeAgent)(agent, effectiveAuth)) {
|
|
947
887
|
const res = jsonResponse({ error: "not_found", message: `Agent not found: ${body.path}` }, 404);
|
|
948
888
|
return cors ? addCors(res) : res;
|
|
949
889
|
}
|
|
950
|
-
const visibleTools = getVisibleTools(agent, effectiveAuth);
|
|
890
|
+
const visibleTools = (0, auth_governance_js_2.getVisibleTools)(agent, effectiveAuth);
|
|
951
891
|
if (!visibleTools.find((t) => t.name === body.tool)) {
|
|
952
892
|
const res = jsonResponse({ error: "not_found", message: `Tool not found: ${body.tool}` }, 404);
|
|
953
893
|
return cors ? addCors(res) : res;
|
|
@@ -979,7 +919,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
979
919
|
if (path.startsWith("/agents/") && req.method === "POST") {
|
|
980
920
|
const agentPath = path.slice("/agents/".length);
|
|
981
921
|
const agent = resolveAgent(registry, agentPath);
|
|
982
|
-
if (!agent || !canSeeAgent(agent, effectiveAuth)) {
|
|
922
|
+
if (!agent || !(0, auth_governance_js_2.canSeeAgent)(agent, effectiveAuth)) {
|
|
983
923
|
const res = jsonResponse({ error: "not_found", message: `Agent not found: ${agentPath}` }, 404);
|
|
984
924
|
return cors ? addCors(res) : res;
|
|
985
925
|
}
|
|
@@ -997,7 +937,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
997
937
|
return cors ? addCors(res) : res;
|
|
998
938
|
}
|
|
999
939
|
if (body.method === "tools/list") {
|
|
1000
|
-
const tools = getVisibleTools(agent, effectiveAuth).map((t) => ({
|
|
940
|
+
const tools = (0, auth_governance_js_2.getVisibleTools)(agent, effectiveAuth).map((t) => ({
|
|
1001
941
|
name: t.name,
|
|
1002
942
|
description: t.description,
|
|
1003
943
|
inputSchema: t.inputSchema,
|
|
@@ -1113,7 +1053,7 @@ function createAgentServer(registry, options = {}) {
|
|
|
1113
1053
|
throw new Error("No signing keys available. Call start() or initKeys() first.");
|
|
1114
1054
|
}
|
|
1115
1055
|
const key = serverSigningKeys[0];
|
|
1116
|
-
return (0, jwt_js_2.signJwtES256)({ sub: "system", name: "atlas-os", scopes: ["*"], ...claims }, key.privateKey, key.kid, options.serverName ?? "agents-sdk", "1h");
|
|
1056
|
+
return (0, jwt_js_2.signJwtES256)({ sub: "system", name: "atlas-os", scopes: ["*"], ...claims }, key.privateKey, key.kid, options.serverName ?? "agents-sdk", claims.exp != null ? undefined : "1h");
|
|
1117
1057
|
},
|
|
1118
1058
|
async resolveAuth(req) {
|
|
1119
1059
|
const customAuth = options.resolveAuth
|