@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/src/server.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Minimal JSON-RPC server implementing the MCP protocol for agent interaction.
|
|
5
5
|
* Handles only core SDK concerns:
|
|
6
6
|
* - MCP protocol (initialize, tools/list, tools/call)
|
|
7
|
-
* - Agent registry routing (call_agent, list_agents
|
|
7
|
+
* - Agent registry routing (call_agent, list_agents)
|
|
8
8
|
* - Auth resolution (Bearer tokens, root key, JWT)
|
|
9
9
|
* - OAuth2 token exchange (client_credentials)
|
|
10
10
|
* - Health check
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
type SecretStore,
|
|
31
31
|
processSecretParams,
|
|
32
32
|
} from "./agent-definitions/secrets.js";
|
|
33
|
-
import {
|
|
33
|
+
import { createBM25Index } from "./bm25.js";
|
|
34
34
|
import { verifyJwt } from "./jwt.js";
|
|
35
35
|
import type { SigningKey } from "./jwt.js";
|
|
36
36
|
import {
|
|
@@ -44,9 +44,13 @@ import {
|
|
|
44
44
|
} from "./jwt.js";
|
|
45
45
|
import { type OIDCProviderConfig, createOIDCSignIn } from "./oidc-signin.js";
|
|
46
46
|
import type { AgentRegistry } from "./registry.js";
|
|
47
|
-
import type { AgentDefinition, CallAgentRequest
|
|
47
|
+
import type { AgentDefinition, CallAgentRequest } from "./types.js";
|
|
48
48
|
|
|
49
|
-
import {
|
|
49
|
+
import {
|
|
50
|
+
callAgentInputSchema,
|
|
51
|
+
listAgentsInputSchema,
|
|
52
|
+
listAgentsToolInputSchema,
|
|
53
|
+
} from "./call-agent-schema.js";
|
|
50
54
|
|
|
51
55
|
// ============================================
|
|
52
56
|
// Server Types
|
|
@@ -206,20 +210,22 @@ export interface AuthConfig {
|
|
|
206
210
|
tokenTtl?: number;
|
|
207
211
|
}
|
|
208
212
|
|
|
209
|
-
export interface ResolvedAuth {
|
|
210
|
-
issuer?: string;
|
|
211
|
-
callerId: string;
|
|
212
|
-
callerType: "agent" | "user" | "system";
|
|
213
|
-
scopes: string[];
|
|
214
|
-
/** All JWT claims from the verified token (passthrough) */
|
|
215
|
-
claims: Record<string, unknown>;
|
|
216
|
-
}
|
|
217
213
|
|
|
218
|
-
|
|
219
|
-
export
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
214
|
+
// Auth governance — single source of truth for visibility/access control
|
|
215
|
+
export {
|
|
216
|
+
type ResolvedAuth,
|
|
217
|
+
hasAdminScope,
|
|
218
|
+
canSeeAgent,
|
|
219
|
+
canSeeTool,
|
|
220
|
+
getVisibleTools,
|
|
221
|
+
} from "./auth-governance.js";
|
|
222
|
+
import {
|
|
223
|
+
type ResolvedAuth,
|
|
224
|
+
hasAdminScope,
|
|
225
|
+
canSeeAgent,
|
|
226
|
+
canSeeTool,
|
|
227
|
+
getVisibleTools,
|
|
228
|
+
} from "./auth-governance.js";
|
|
223
229
|
|
|
224
230
|
// ============================================
|
|
225
231
|
// HTTP Helpers
|
|
@@ -415,19 +421,6 @@ export async function resolveAuth(
|
|
|
415
421
|
};
|
|
416
422
|
}
|
|
417
423
|
|
|
418
|
-
export function canSeeAgent(
|
|
419
|
-
agent: AgentDefinition,
|
|
420
|
-
auth: ResolvedAuth | null,
|
|
421
|
-
): boolean {
|
|
422
|
-
const visibility = ((agent as any).visibility ??
|
|
423
|
-
agent.config?.visibility ??
|
|
424
|
-
"internal") as Visibility;
|
|
425
|
-
if (hasAdminScope(auth)) return true;
|
|
426
|
-
if (visibility === "public") return true;
|
|
427
|
-
if (visibility === "internal" && auth) return true;
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
424
|
/**
|
|
432
425
|
* Resolve an agent by path, handling @ prefix normalization.
|
|
433
426
|
* Tries the path as-is first, then with @ prefix.
|
|
@@ -440,33 +433,6 @@ function resolveAgent(
|
|
|
440
433
|
return registry.get(normalized) ?? registry.get(`@${normalized}`);
|
|
441
434
|
}
|
|
442
435
|
|
|
443
|
-
/**
|
|
444
|
-
* Filter tools visible on a public agent endpoint.
|
|
445
|
-
* For /agents/ routes, tools inherit the agent's visibility:
|
|
446
|
-
* - If agent is public, tools without explicit visibility are shown
|
|
447
|
-
* - Tool-level visibility still overrides (e.g. visibility: "private" hides it)
|
|
448
|
-
*/
|
|
449
|
-
function getVisibleTools(
|
|
450
|
-
agent: AgentDefinition,
|
|
451
|
-
auth: ResolvedAuth | null,
|
|
452
|
-
): typeof agent.tools {
|
|
453
|
-
const agentVisibility = ((agent as any).visibility ??
|
|
454
|
-
agent.config?.visibility ??
|
|
455
|
-
"internal") as Visibility;
|
|
456
|
-
return agent.tools.filter((t) => {
|
|
457
|
-
const tv = t.visibility;
|
|
458
|
-
if (hasAdminScope(auth)) return true;
|
|
459
|
-
// Tool has explicit visibility — respect it
|
|
460
|
-
if (tv === "public") return true;
|
|
461
|
-
if (tv === "private") return hasAdminScope(auth) ?? false;
|
|
462
|
-
if (tv === "internal" && auth) return true;
|
|
463
|
-
// No explicit tool visibility — inherit from agent
|
|
464
|
-
if (!tv && agentVisibility === "public") return true;
|
|
465
|
-
if (!tv && agentVisibility === "internal" && auth) return true;
|
|
466
|
-
return false;
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
|
|
470
436
|
// ============================================
|
|
471
437
|
// MCP Tool Definitions
|
|
472
438
|
// ============================================
|
|
@@ -481,37 +447,9 @@ function getToolDefinitions() {
|
|
|
481
447
|
},
|
|
482
448
|
{
|
|
483
449
|
name: "list_agents",
|
|
484
|
-
description: "List all registered agents and their available tools.",
|
|
485
|
-
inputSchema: {
|
|
486
|
-
type: "object",
|
|
487
|
-
properties: {},
|
|
488
|
-
},
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
name: "search_agent_tools",
|
|
492
450
|
description:
|
|
493
|
-
"
|
|
494
|
-
inputSchema:
|
|
495
|
-
type: "object",
|
|
496
|
-
properties: {
|
|
497
|
-
query: {
|
|
498
|
-
type: "string",
|
|
499
|
-
description:
|
|
500
|
-
"Natural language search query (e.g. 'send a message', 'database query')",
|
|
501
|
-
},
|
|
502
|
-
agents: {
|
|
503
|
-
type: "array",
|
|
504
|
-
items: { type: "string" },
|
|
505
|
-
description:
|
|
506
|
-
"Optional list of agent paths to search within (e.g. ['@notifications', '@db']). Searches all agents if omitted.",
|
|
507
|
-
},
|
|
508
|
-
limit: {
|
|
509
|
-
type: "number",
|
|
510
|
-
description: "Maximum number of results to return (default: 10)",
|
|
511
|
-
},
|
|
512
|
-
},
|
|
513
|
-
required: ["query"],
|
|
514
|
-
},
|
|
451
|
+
"List all registered agents and their available tools. Optionally search/filter by query using BM25 ranking.",
|
|
452
|
+
inputSchema: listAgentsInputSchema,
|
|
515
453
|
},
|
|
516
454
|
];
|
|
517
455
|
}
|
|
@@ -658,12 +596,84 @@ export function createAgentServer(
|
|
|
658
596
|
}
|
|
659
597
|
|
|
660
598
|
case "list_agents": {
|
|
599
|
+
const { query: listQuery, limit: listLimit, cursor: listCursor } =
|
|
600
|
+
listAgentsToolInputSchema.parse(args);
|
|
661
601
|
const agents = registry.list();
|
|
662
|
-
|
|
602
|
+
let visible = agents.filter((agent) => canSeeAgent(agent, auth));
|
|
603
|
+
|
|
604
|
+
// Decode cursor if provided
|
|
605
|
+
const after = listCursor
|
|
606
|
+
? (JSON.parse(
|
|
607
|
+
Buffer.from(listCursor, "base64url").toString(),
|
|
608
|
+
) as { path: string; score?: number })
|
|
609
|
+
: undefined;
|
|
610
|
+
|
|
611
|
+
const pageSize = listLimit ?? 20;
|
|
612
|
+
let page: typeof visible;
|
|
613
|
+
let nextCursor: string | undefined;
|
|
614
|
+
|
|
615
|
+
if (listQuery) {
|
|
616
|
+
// BM25 search — ranked by score desc, path asc for tie-breaking
|
|
617
|
+
const docs = visible.map((agent, i) => ({
|
|
618
|
+
id: String(i),
|
|
619
|
+
text: [
|
|
620
|
+
agent.path,
|
|
621
|
+
agent.config?.name ?? "",
|
|
622
|
+
agent.config?.description ?? "",
|
|
623
|
+
...agent.tools
|
|
624
|
+
.filter((t) => canSeeTool(t, auth))
|
|
625
|
+
.map((t) => `${t.name} ${t.description}`),
|
|
626
|
+
].join(" "),
|
|
627
|
+
}));
|
|
628
|
+
const index = createBM25Index(docs);
|
|
629
|
+
const ranked = index.search(listQuery);
|
|
630
|
+
|
|
631
|
+
// Build scored list
|
|
632
|
+
type ScoredAgent = (typeof visible)[number] & { _score: number };
|
|
633
|
+
let scored: ScoredAgent[] = ranked.map((r) => ({
|
|
634
|
+
...visible[Number(r.id)],
|
|
635
|
+
_score: r.score,
|
|
636
|
+
}));
|
|
637
|
+
|
|
638
|
+
// Apply cursor: skip past the after position
|
|
639
|
+
if (after?.score !== undefined) {
|
|
640
|
+
scored = scored.filter(
|
|
641
|
+
(a) =>
|
|
642
|
+
a._score < after.score! ||
|
|
643
|
+
(a._score === after.score! && a.path > after.path),
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
page = scored.slice(0, pageSize);
|
|
648
|
+
if (scored.length > pageSize) {
|
|
649
|
+
const last = scored[pageSize - 1] as ScoredAgent;
|
|
650
|
+
nextCursor = Buffer.from(
|
|
651
|
+
JSON.stringify({ path: last.path, score: last._score }),
|
|
652
|
+
).toString("base64url");
|
|
653
|
+
}
|
|
654
|
+
} else {
|
|
655
|
+
// Alphabetical listing — sorted by path
|
|
656
|
+
visible.sort((a, b) => a.path.localeCompare(b.path));
|
|
657
|
+
|
|
658
|
+
// Apply cursor: skip past afterPath
|
|
659
|
+
if (after) {
|
|
660
|
+
visible = visible.filter((a) => a.path > after.path);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
page = visible.slice(0, pageSize);
|
|
664
|
+
if (visible.length > pageSize) {
|
|
665
|
+
const last = page[page.length - 1];
|
|
666
|
+
nextCursor = Buffer.from(
|
|
667
|
+
JSON.stringify({ path: last.path }),
|
|
668
|
+
).toString("base64url");
|
|
669
|
+
}
|
|
670
|
+
}
|
|
663
671
|
|
|
664
672
|
return mcpResult({
|
|
665
673
|
success: true,
|
|
666
|
-
|
|
674
|
+
total: agents.filter((a) => canSeeAgent(a, auth)).length,
|
|
675
|
+
nextCursor,
|
|
676
|
+
agents: page.map((agent) => ({
|
|
667
677
|
path: agent.path,
|
|
668
678
|
name: agent.config?.name,
|
|
669
679
|
description: agent.config?.description,
|
|
@@ -678,122 +688,12 @@ export function createAgentServer(
|
|
|
678
688
|
mimeType: r.mimeType,
|
|
679
689
|
})),
|
|
680
690
|
tools: agent.tools
|
|
681
|
-
.filter((t) =>
|
|
682
|
-
const tv = t.visibility ?? "internal";
|
|
683
|
-
if (hasAdminScope(auth)) return true;
|
|
684
|
-
if (tv === "public") return true;
|
|
685
|
-
if (
|
|
686
|
-
tv === "authenticated" &&
|
|
687
|
-
auth?.callerId &&
|
|
688
|
-
auth.callerId !== "anonymous"
|
|
689
|
-
)
|
|
690
|
-
return true;
|
|
691
|
-
if (tv === "internal" && auth) return true;
|
|
692
|
-
return false;
|
|
693
|
-
})
|
|
691
|
+
.filter((t) => canSeeTool(t, auth))
|
|
694
692
|
.map((t) => t.name),
|
|
695
693
|
})),
|
|
696
694
|
});
|
|
697
695
|
}
|
|
698
696
|
|
|
699
|
-
case "search_agent_tools": {
|
|
700
|
-
const { query, agents: agentFilter, limit: resultLimit } = args as {
|
|
701
|
-
query: string;
|
|
702
|
-
agents?: string[];
|
|
703
|
-
limit?: number;
|
|
704
|
-
};
|
|
705
|
-
|
|
706
|
-
const agents = registry.list();
|
|
707
|
-
const visible = agents.filter((agent) => {
|
|
708
|
-
if (!canSeeAgent(agent, auth)) return false;
|
|
709
|
-
if (agentFilter && agentFilter.length > 0) {
|
|
710
|
-
return agentFilter.includes(agent.path);
|
|
711
|
-
}
|
|
712
|
-
return true;
|
|
713
|
-
});
|
|
714
|
-
|
|
715
|
-
// Build search documents from all visible tools
|
|
716
|
-
const documents: (BM25Document & {
|
|
717
|
-
agentPath: string;
|
|
718
|
-
toolName: string;
|
|
719
|
-
description: string;
|
|
720
|
-
agentName?: string;
|
|
721
|
-
agentDescription?: string;
|
|
722
|
-
})[] = [];
|
|
723
|
-
|
|
724
|
-
for (const agent of visible) {
|
|
725
|
-
const visibleTools = agent.tools.filter((t) => {
|
|
726
|
-
const tv = t.visibility ?? "internal";
|
|
727
|
-
if (hasAdminScope(auth)) return true;
|
|
728
|
-
if (tv === "public") return true;
|
|
729
|
-
if (
|
|
730
|
-
tv === "authenticated" &&
|
|
731
|
-
auth?.callerId &&
|
|
732
|
-
auth.callerId !== "anonymous"
|
|
733
|
-
)
|
|
734
|
-
return true;
|
|
735
|
-
if (tv === "internal" && auth) return true;
|
|
736
|
-
return false;
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
for (const tool of visibleTools) {
|
|
740
|
-
// Build searchable text from tool name, description, agent context, and schema
|
|
741
|
-
const parts = [
|
|
742
|
-
tool.name,
|
|
743
|
-
tool.description,
|
|
744
|
-
agent.config?.name ?? "",
|
|
745
|
-
agent.config?.description ?? "",
|
|
746
|
-
agent.path,
|
|
747
|
-
];
|
|
748
|
-
|
|
749
|
-
// Include property names and descriptions from input schema
|
|
750
|
-
const schema = tool.inputSchema as any;
|
|
751
|
-
if (schema?.properties) {
|
|
752
|
-
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
753
|
-
parts.push(key);
|
|
754
|
-
if ((prop as any)?.description) {
|
|
755
|
-
parts.push((prop as any).description);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
documents.push({
|
|
761
|
-
id: `${agent.path}/${tool.name}`,
|
|
762
|
-
text: parts.join(" "),
|
|
763
|
-
agentPath: agent.path,
|
|
764
|
-
toolName: tool.name,
|
|
765
|
-
description: tool.description,
|
|
766
|
-
agentName: agent.config?.name,
|
|
767
|
-
agentDescription: agent.config?.description,
|
|
768
|
-
});
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
const index = createBM25Index(documents);
|
|
773
|
-
const results = index.search(query, resultLimit ?? 10);
|
|
774
|
-
|
|
775
|
-
// Map results back to tool details
|
|
776
|
-
const docMap = new Map(documents.map((d) => [d.id, d]));
|
|
777
|
-
const matches = results.map((r) => {
|
|
778
|
-
const doc = docMap.get(r.id)!;
|
|
779
|
-
return {
|
|
780
|
-
agentPath: doc.agentPath,
|
|
781
|
-
tool: doc.toolName,
|
|
782
|
-
description: doc.description,
|
|
783
|
-
agentName: doc.agentName,
|
|
784
|
-
agentDescription: doc.agentDescription,
|
|
785
|
-
score: r.score,
|
|
786
|
-
};
|
|
787
|
-
});
|
|
788
|
-
|
|
789
|
-
return mcpResult({
|
|
790
|
-
success: true,
|
|
791
|
-
query,
|
|
792
|
-
results: matches,
|
|
793
|
-
total: matches.length,
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
|
|
797
697
|
default:
|
|
798
698
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
799
699
|
}
|
|
@@ -1266,9 +1166,12 @@ export function createAgentServer(
|
|
|
1266
1166
|
// Public registries (e.g. registry.slash.com) skip this entirely.
|
|
1267
1167
|
if (
|
|
1268
1168
|
path === "/.well-known/oauth-authorization-server" &&
|
|
1269
|
-
req.method === "GET"
|
|
1270
|
-
(options.registry?.oauthCallbackUrl || serverSigningKeys.length > 0)
|
|
1169
|
+
req.method === "GET"
|
|
1271
1170
|
) {
|
|
1171
|
+
if (!(options.registry?.oauthCallbackUrl || serverSigningKeys.length > 0)) {
|
|
1172
|
+
const res = new Response("Not Found", { status: 404 });
|
|
1173
|
+
return cors ? addCors(res) : res;
|
|
1174
|
+
}
|
|
1272
1175
|
const baseUrl = resolveBaseUrl(req);
|
|
1273
1176
|
const res = jsonResponse({
|
|
1274
1177
|
issuer: baseUrl,
|
|
@@ -1286,33 +1189,95 @@ export function createAgentServer(
|
|
|
1286
1189
|
return cors ? addCors(res) : res;
|
|
1287
1190
|
}
|
|
1288
1191
|
|
|
1289
|
-
// ── GET /list → List agents (
|
|
1192
|
+
// ── GET /list → List agents (──
|
|
1290
1193
|
if (path === "/list" && req.method === "GET") {
|
|
1291
1194
|
const agents = registry.list();
|
|
1292
|
-
|
|
1195
|
+
let visible = agents.filter((agent) =>
|
|
1293
1196
|
canSeeAgent(agent, effectiveAuth),
|
|
1294
1197
|
);
|
|
1295
|
-
|
|
1296
|
-
|
|
1198
|
+
|
|
1199
|
+
const searchQuery = url.searchParams.get("q");
|
|
1200
|
+
const searchLimit = url.searchParams.get("limit");
|
|
1201
|
+
const searchCursor = url.searchParams.get("cursor");
|
|
1202
|
+
|
|
1203
|
+
// Decode cursor
|
|
1204
|
+
const httpAfter = searchCursor
|
|
1205
|
+
? (JSON.parse(
|
|
1206
|
+
Buffer.from(searchCursor, "base64url").toString(),
|
|
1207
|
+
) as { path: string; score?: number })
|
|
1208
|
+
: undefined;
|
|
1209
|
+
|
|
1210
|
+
const httpPageSize = searchLimit ? Number(searchLimit) : 20;
|
|
1211
|
+
let httpPage: typeof visible;
|
|
1212
|
+
let httpNextCursor: string | undefined;
|
|
1213
|
+
|
|
1214
|
+
if (searchQuery) {
|
|
1215
|
+
const docs = visible.map((agent, i) => ({
|
|
1216
|
+
id: String(i),
|
|
1217
|
+
text: [
|
|
1218
|
+
agent.path,
|
|
1219
|
+
agent.config?.name ?? "",
|
|
1220
|
+
agent.config?.description ?? "",
|
|
1221
|
+
...agent.tools
|
|
1222
|
+
.filter((t) => canSeeTool(t, effectiveAuth))
|
|
1223
|
+
.map((t) => `${t.name} ${t.description}`),
|
|
1224
|
+
].join(" "),
|
|
1225
|
+
}));
|
|
1226
|
+
const index = createBM25Index(docs);
|
|
1227
|
+
const ranked = index.search(searchQuery);
|
|
1228
|
+
|
|
1229
|
+
type ScoredAgent = (typeof visible)[number] & { _score: number };
|
|
1230
|
+
let scored: ScoredAgent[] = ranked.map((r) => ({
|
|
1231
|
+
...visible[Number(r.id)],
|
|
1232
|
+
_score: r.score,
|
|
1233
|
+
}));
|
|
1234
|
+
|
|
1235
|
+
if (httpAfter?.score !== undefined) {
|
|
1236
|
+
scored = scored.filter(
|
|
1237
|
+
(a) =>
|
|
1238
|
+
a._score < httpAfter.score! ||
|
|
1239
|
+
(a._score === httpAfter.score! && a.path > httpAfter.path),
|
|
1240
|
+
);
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
httpPage = scored.slice(0, httpPageSize);
|
|
1244
|
+
if (scored.length > httpPageSize) {
|
|
1245
|
+
const last = scored[httpPageSize - 1] as ScoredAgent;
|
|
1246
|
+
httpNextCursor = Buffer.from(
|
|
1247
|
+
JSON.stringify({ path: last.path, score: last._score }),
|
|
1248
|
+
).toString("base64url");
|
|
1249
|
+
}
|
|
1250
|
+
} else {
|
|
1251
|
+
visible.sort((a, b) => a.path.localeCompare(b.path));
|
|
1252
|
+
if (httpAfter) {
|
|
1253
|
+
visible = visible.filter((a) => a.path > httpAfter.path);
|
|
1254
|
+
}
|
|
1255
|
+
httpPage = visible.slice(0, httpPageSize);
|
|
1256
|
+
if (visible.length > httpPageSize) {
|
|
1257
|
+
const last = httpPage[httpPage.length - 1];
|
|
1258
|
+
httpNextCursor = Buffer.from(
|
|
1259
|
+
JSON.stringify({ path: last.path }),
|
|
1260
|
+
).toString("base64url");
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
const res = jsonResponse({
|
|
1265
|
+
total: agents.filter((a) => canSeeAgent(a, effectiveAuth)).length,
|
|
1266
|
+
nextCursor: httpNextCursor,
|
|
1267
|
+
agents: httpPage.map((agent) => ({
|
|
1297
1268
|
path: agent.path,
|
|
1298
1269
|
name: agent.config?.name,
|
|
1299
1270
|
description: agent.config?.description,
|
|
1300
1271
|
supportedActions: agent.config?.supportedActions,
|
|
1301
1272
|
integration: agent.config?.integration || null,
|
|
1302
1273
|
tools: agent.tools
|
|
1303
|
-
.filter((t) =>
|
|
1304
|
-
const tv = t.visibility ?? "internal";
|
|
1305
|
-
if (hasAdminScope(effectiveAuth)) return true;
|
|
1306
|
-
if (tv === "public") return true;
|
|
1307
|
-
if (tv === "internal" && effectiveAuth) return true;
|
|
1308
|
-
return false;
|
|
1309
|
-
})
|
|
1274
|
+
.filter((t) => canSeeTool(t, effectiveAuth))
|
|
1310
1275
|
.map((t) => ({
|
|
1311
1276
|
name: t.name,
|
|
1312
1277
|
description: t.description,
|
|
1313
1278
|
})),
|
|
1314
1279
|
})),
|
|
1315
|
-
);
|
|
1280
|
+
});
|
|
1316
1281
|
return cors ? addCors(res) : res;
|
|
1317
1282
|
}
|
|
1318
1283
|
|
|
@@ -1611,7 +1576,7 @@ export function createAgentServer(
|
|
|
1611
1576
|
key.privateKey,
|
|
1612
1577
|
key.kid,
|
|
1613
1578
|
options.serverName ?? "agents-sdk",
|
|
1614
|
-
"1h",
|
|
1579
|
+
claims.exp != null ? undefined : "1h",
|
|
1615
1580
|
);
|
|
1616
1581
|
},
|
|
1617
1582
|
|