@slashfi/agents-sdk 0.34.0 → 0.35.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/README.md +2 -1
- package/dist/agent-definitions/auth.d.ts +3 -3
- package/dist/agent-definitions/auth.d.ts.map +1 -1
- package/dist/agent-definitions/auth.js +10 -4
- package/dist/agent-definitions/auth.js.map +1 -1
- package/dist/agent-definitions/config.d.ts.map +1 -1
- package/dist/agent-definitions/config.js.map +1 -1
- package/dist/agent-definitions/integrations.d.ts +12 -3
- package/dist/agent-definitions/integrations.d.ts.map +1 -1
- package/dist/agent-definitions/integrations.js +35 -16
- package/dist/agent-definitions/integrations.js.map +1 -1
- package/dist/agent-definitions/remote-registry.d.ts.map +1 -1
- package/dist/agent-definitions/remote-registry.js +17 -22
- package/dist/agent-definitions/remote-registry.js.map +1 -1
- package/dist/agent-definitions/users.d.ts.map +1 -1
- package/dist/agent-definitions/users.js.map +1 -1
- package/dist/auth-governance.js.map +1 -1
- package/dist/call-agent-schema.d.ts +128 -135
- package/dist/call-agent-schema.d.ts.map +1 -1
- package/dist/call-agent-schema.js +35 -5
- package/dist/call-agent-schema.js.map +1 -1
- package/dist/cjs/agent-definitions/auth.js +10 -4
- package/dist/cjs/agent-definitions/auth.js.map +1 -1
- package/dist/cjs/agent-definitions/config.js.map +1 -1
- package/dist/cjs/agent-definitions/integrations.js +35 -16
- package/dist/cjs/agent-definitions/integrations.js.map +1 -1
- package/dist/cjs/agent-definitions/remote-registry.js +17 -22
- package/dist/cjs/agent-definitions/remote-registry.js.map +1 -1
- package/dist/cjs/agent-definitions/users.js.map +1 -1
- package/dist/cjs/auth-governance.js.map +1 -1
- package/dist/cjs/call-agent-schema.js +35 -5
- package/dist/cjs/call-agent-schema.js.map +1 -1
- package/dist/cjs/define.js.map +1 -1
- package/dist/cjs/index.js +6 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/key-manager.js.map +1 -1
- package/dist/cjs/registry-consumer.js +60 -15
- package/dist/cjs/registry-consumer.js.map +1 -1
- package/dist/cjs/registry.js +3 -1
- package/dist/cjs/registry.js.map +1 -1
- package/dist/cjs/server.js +70 -121
- package/dist/cjs/server.js.map +1 -1
- package/dist/cjs/types.js +13 -0
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/validate.js +2 -2
- package/dist/cjs/validate.js.map +1 -1
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/key-manager.d.ts.map +1 -1
- package/dist/key-manager.js +1 -1
- package/dist/key-manager.js.map +1 -1
- package/dist/registry-consumer.d.ts +8 -8
- package/dist/registry-consumer.d.ts.map +1 -1
- package/dist/registry-consumer.js +60 -15
- package/dist/registry-consumer.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +3 -1
- package/dist/registry.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +63 -114
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -1
- package/dist/types.js.map +1 -1
- package/dist/validate.d.ts +15 -15
- package/dist/validate.js +2 -2
- package/dist/validate.js.map +1 -1
- package/package.json +1 -1
- package/src/agent-definitions/auth.ts +31 -14
- package/src/agent-definitions/config.ts +4 -4
- package/src/agent-definitions/integrations.ts +119 -63
- package/src/agent-definitions/remote-registry.ts +65 -38
- package/src/agent-definitions/users.ts +36 -3
- package/src/auth-governance.ts +2 -2
- package/src/call-agent-schema.test.ts +4 -1
- package/src/call-agent-schema.ts +39 -5
- package/src/consumer.test.ts +4 -1
- package/src/define.ts +18 -12
- package/src/index.ts +11 -0
- package/src/key-manager.ts +9 -2
- package/src/registry-consumer.ts +85 -24
- package/src/registry.ts +3 -1
- package/src/server.ts +122 -153
- package/src/types.ts +62 -0
- package/src/validate.ts +2 -2
package/src/server.ts
CHANGED
|
@@ -31,9 +31,10 @@ import {
|
|
|
31
31
|
processSecretParams,
|
|
32
32
|
} from "./agent-definitions/secrets.js";
|
|
33
33
|
import { createBM25Index } from "./bm25.js";
|
|
34
|
-
import { verifyJwt } from "./jwt.js";
|
|
35
|
-
import type { SigningKey } from "./jwt.js";
|
|
36
34
|
import {
|
|
35
|
+
verifyJwt,
|
|
36
|
+
type AgentJwtPayload,
|
|
37
|
+
type SigningKey,
|
|
37
38
|
buildJwks,
|
|
38
39
|
exportSigningKey,
|
|
39
40
|
generateSigningKey,
|
|
@@ -44,8 +45,6 @@ import {
|
|
|
44
45
|
} from "./jwt.js";
|
|
45
46
|
import { type OIDCProviderConfig, createOIDCSignIn } from "./oidc-signin.js";
|
|
46
47
|
import type { AgentRegistry } from "./registry.js";
|
|
47
|
-
import type { AgentDefinition, CallAgentRequest } from "./types.js";
|
|
48
|
-
|
|
49
48
|
import {
|
|
50
49
|
callAgentInputSchema,
|
|
51
50
|
callAgentValidationSchema,
|
|
@@ -53,7 +52,33 @@ import {
|
|
|
53
52
|
listAgentsValidationSchema,
|
|
54
53
|
nullTolerant,
|
|
55
54
|
zodToOpenAiJsonSchema,
|
|
55
|
+
type CallAgentExecuteToolRequest,
|
|
56
|
+
type CallerType,
|
|
56
57
|
} from "./call-agent-schema.js";
|
|
58
|
+
import type {
|
|
59
|
+
AgentDefinition,
|
|
60
|
+
AuthClientCredentialsTokenResult,
|
|
61
|
+
CallAgentRequest,
|
|
62
|
+
ExchangeTokenToolResult,
|
|
63
|
+
} from "./types.js";
|
|
64
|
+
import {
|
|
65
|
+
isCallAgentErrorResponse,
|
|
66
|
+
isExchangeTokenLinkedSuccess,
|
|
67
|
+
isExchangeTokenNeedsIdentity,
|
|
68
|
+
} from "./types.js";
|
|
69
|
+
|
|
70
|
+
/** JWT payload claims used for reverse registry registration (jwt_exchange). */
|
|
71
|
+
interface RegistryAssertionPayload {
|
|
72
|
+
type?: string;
|
|
73
|
+
iss?: string;
|
|
74
|
+
name?: string;
|
|
75
|
+
tenantId?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function parseProxyCallerType(raw: string | null): CallerType {
|
|
79
|
+
if (raw === "agent" || raw === "user" || raw === "system") return raw;
|
|
80
|
+
return "agent";
|
|
81
|
+
}
|
|
57
82
|
|
|
58
83
|
// ============================================
|
|
59
84
|
// Server Types
|
|
@@ -231,7 +256,6 @@ export interface AuthConfig {
|
|
|
231
256
|
tokenTtl?: number;
|
|
232
257
|
}
|
|
233
258
|
|
|
234
|
-
|
|
235
259
|
// Auth governance — single source of truth for visibility/access control
|
|
236
260
|
export {
|
|
237
261
|
type ResolvedAuth,
|
|
@@ -539,8 +563,12 @@ export function createAgentServer(
|
|
|
539
563
|
...(options.registry && {
|
|
540
564
|
registry: {
|
|
541
565
|
version: options.registry.version ?? "1.0",
|
|
542
|
-
...(options.registry.features && {
|
|
543
|
-
|
|
566
|
+
...(options.registry.features && {
|
|
567
|
+
features: options.registry.features,
|
|
568
|
+
}),
|
|
569
|
+
...(options.registry.oauthCallbackUrl && {
|
|
570
|
+
oauthCallbackUrl: options.registry.oauthCallbackUrl,
|
|
571
|
+
}),
|
|
544
572
|
},
|
|
545
573
|
}),
|
|
546
574
|
},
|
|
@@ -598,9 +626,11 @@ export function createAgentServer(
|
|
|
598
626
|
case "call_agent": {
|
|
599
627
|
// Validate + strip nulls (OpenAI convention: null = absent)
|
|
600
628
|
const parsed = callAgentValidate.safeParse(args);
|
|
601
|
-
const req = (
|
|
602
|
-
|
|
603
|
-
|
|
629
|
+
const req = (
|
|
630
|
+
parsed.success
|
|
631
|
+
? ((parsed.data as Record<string, unknown>).request ?? parsed.data)
|
|
632
|
+
: (args.request ?? args)
|
|
633
|
+
) as CallAgentRequest;
|
|
604
634
|
|
|
605
635
|
// Inject auth context
|
|
606
636
|
if (auth) {
|
|
@@ -615,18 +645,19 @@ export function createAgentServer(
|
|
|
615
645
|
}
|
|
616
646
|
|
|
617
647
|
// Process secret params: resolve refs, store raw secrets
|
|
618
|
-
if (
|
|
648
|
+
if (req.action === "execute_tool" && req.params && secretStore) {
|
|
649
|
+
const execReq: CallAgentExecuteToolRequest = req;
|
|
619
650
|
const ownerId = auth?.callerId ?? "anonymous";
|
|
620
|
-
const agent = registry.get(
|
|
621
|
-
const tool = agent?.tools.find((t) => t.name ===
|
|
622
|
-
const schema = tool?.inputSchema
|
|
651
|
+
const agent = registry.get(execReq.path);
|
|
652
|
+
const tool = agent?.tools.find((t) => t.name === execReq.tool);
|
|
653
|
+
const schema = tool?.inputSchema;
|
|
623
654
|
const { resolved } = await processSecretParams(
|
|
624
|
-
|
|
625
|
-
schema,
|
|
655
|
+
execReq.params as Record<string, unknown>,
|
|
656
|
+
schema as Parameters<typeof processSecretParams>[1],
|
|
626
657
|
secretStore,
|
|
627
658
|
ownerId,
|
|
628
659
|
);
|
|
629
|
-
|
|
660
|
+
execReq.params = resolved;
|
|
630
661
|
}
|
|
631
662
|
|
|
632
663
|
const result = await registry.call(req);
|
|
@@ -634,16 +665,20 @@ export function createAgentServer(
|
|
|
634
665
|
}
|
|
635
666
|
|
|
636
667
|
case "list_agents": {
|
|
637
|
-
const {
|
|
638
|
-
|
|
668
|
+
const {
|
|
669
|
+
query: listQuery,
|
|
670
|
+
limit: listLimit,
|
|
671
|
+
cursor: listCursor,
|
|
672
|
+
} = listAgentsValidate.parse(args);
|
|
639
673
|
const agents = registry.list();
|
|
640
674
|
let visible = agents.filter((agent) => canSeeAgent(agent, auth));
|
|
641
675
|
|
|
642
676
|
// Decode cursor if provided
|
|
643
677
|
const after = listCursor
|
|
644
|
-
? (JSON.parse(
|
|
645
|
-
|
|
646
|
-
|
|
678
|
+
? (JSON.parse(Buffer.from(listCursor, "base64url").toString()) as {
|
|
679
|
+
path: string;
|
|
680
|
+
score?: number;
|
|
681
|
+
})
|
|
647
682
|
: undefined;
|
|
648
683
|
|
|
649
684
|
const pageSize = listLimit ?? 20;
|
|
@@ -798,27 +833,36 @@ export function createAgentServer(
|
|
|
798
833
|
callerType: "system",
|
|
799
834
|
});
|
|
800
835
|
|
|
801
|
-
|
|
802
|
-
// If the tool call failed, forward the error
|
|
803
|
-
if ((result as any)?.success === false) {
|
|
836
|
+
if (isCallAgentErrorResponse(result)) {
|
|
804
837
|
return jsonResponse(
|
|
805
838
|
{
|
|
806
839
|
error: "server_error",
|
|
807
|
-
error_description:
|
|
808
|
-
(result as any)?.error ?? "Exchange tool failed",
|
|
840
|
+
error_description: result.error ?? "Exchange tool failed",
|
|
809
841
|
raw: JSON.stringify(result)?.slice(0, 300),
|
|
810
842
|
},
|
|
811
843
|
500,
|
|
812
844
|
);
|
|
813
845
|
}
|
|
814
846
|
|
|
847
|
+
if (!("result" in result)) {
|
|
848
|
+
return jsonResponse(
|
|
849
|
+
{
|
|
850
|
+
error: "server_error",
|
|
851
|
+
error_description: `Unexpected exchange response: ${JSON.stringify(result)?.slice(0, 300)}`,
|
|
852
|
+
},
|
|
853
|
+
500,
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
const exchangeResult = result.result as ExchangeTokenToolResult;
|
|
858
|
+
|
|
815
859
|
// ── Reverse registration: if caller is an agent-registry, auto-store connection ──
|
|
816
860
|
try {
|
|
817
861
|
const assertionParts = assertion.split(".");
|
|
818
862
|
if (assertionParts.length === 3) {
|
|
819
863
|
const assertionPayload = JSON.parse(
|
|
820
864
|
Buffer.from(assertionParts[1], "base64url").toString(),
|
|
821
|
-
) as
|
|
865
|
+
) as RegistryAssertionPayload;
|
|
822
866
|
if (
|
|
823
867
|
assertionPayload.type === "agent-registry" &&
|
|
824
868
|
assertionPayload.iss
|
|
@@ -844,7 +888,7 @@ export function createAgentServer(
|
|
|
844
888
|
} else {
|
|
845
889
|
console.error(
|
|
846
890
|
"[jwt_exchange] Reverse connection failed:",
|
|
847
|
-
|
|
891
|
+
addResult.error,
|
|
848
892
|
);
|
|
849
893
|
}
|
|
850
894
|
}
|
|
@@ -867,7 +911,7 @@ export function createAgentServer(
|
|
|
867
911
|
}
|
|
868
912
|
|
|
869
913
|
// User not linked yet — needs OAuth identity linking
|
|
870
|
-
if (exchangeResult
|
|
914
|
+
if (isExchangeTokenNeedsIdentity(exchangeResult)) {
|
|
871
915
|
const baseUrl = resolveBaseUrl(req);
|
|
872
916
|
const authorizeUrl = new URL(`${baseUrl}${basePath}/oauth/authorize`);
|
|
873
917
|
authorizeUrl.searchParams.set("token", assertion);
|
|
@@ -890,7 +934,10 @@ export function createAgentServer(
|
|
|
890
934
|
}
|
|
891
935
|
|
|
892
936
|
// User found — sign a local access token
|
|
893
|
-
if (
|
|
937
|
+
if (
|
|
938
|
+
isExchangeTokenLinkedSuccess(exchangeResult) &&
|
|
939
|
+
serverSigningKeys.length > 0
|
|
940
|
+
) {
|
|
894
941
|
const sigKey = serverSigningKeys[0];
|
|
895
942
|
const token = await signJwtES256(
|
|
896
943
|
{
|
|
@@ -951,8 +998,28 @@ export function createAgentServer(
|
|
|
951
998
|
callerType: "system",
|
|
952
999
|
});
|
|
953
1000
|
|
|
954
|
-
|
|
955
|
-
|
|
1001
|
+
if (isCallAgentErrorResponse(result)) {
|
|
1002
|
+
return jsonResponse(
|
|
1003
|
+
{
|
|
1004
|
+
error: "invalid_client",
|
|
1005
|
+
error_description: result.error ?? "Authentication failed",
|
|
1006
|
+
},
|
|
1007
|
+
401,
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
if (!("result" in result)) {
|
|
1012
|
+
return jsonResponse(
|
|
1013
|
+
{
|
|
1014
|
+
error: "invalid_client",
|
|
1015
|
+
error_description: "Authentication failed",
|
|
1016
|
+
},
|
|
1017
|
+
401,
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
const tokenResult = result.result as AuthClientCredentialsTokenResult;
|
|
1022
|
+
if (tokenResult.accessToken == null) {
|
|
956
1023
|
return jsonResponse(
|
|
957
1024
|
{
|
|
958
1025
|
error: "invalid_client",
|
|
@@ -1020,7 +1087,7 @@ export function createAgentServer(
|
|
|
1020
1087
|
if (actorId) {
|
|
1021
1088
|
return {
|
|
1022
1089
|
callerId: actorId,
|
|
1023
|
-
callerType: (actorType
|
|
1090
|
+
callerType: parseProxyCallerType(actorType),
|
|
1024
1091
|
scopes: ["*"],
|
|
1025
1092
|
claims: {},
|
|
1026
1093
|
};
|
|
@@ -1119,12 +1186,12 @@ export function createAgentServer(
|
|
|
1119
1186
|
claims = result as unknown as Record<string, unknown>;
|
|
1120
1187
|
break;
|
|
1121
1188
|
}
|
|
1122
|
-
} catch (e:
|
|
1189
|
+
} catch (e: unknown) {
|
|
1123
1190
|
console.log(
|
|
1124
1191
|
"[oauth/authorize] verify",
|
|
1125
1192
|
issuerUrl,
|
|
1126
1193
|
"-> ERROR:",
|
|
1127
|
-
e.message,
|
|
1194
|
+
e instanceof Error ? e.message : String(e),
|
|
1128
1195
|
);
|
|
1129
1196
|
}
|
|
1130
1197
|
}
|
|
@@ -1190,24 +1257,6 @@ export function createAgentServer(
|
|
|
1190
1257
|
return cors ? addCors(res) : res;
|
|
1191
1258
|
}
|
|
1192
1259
|
|
|
1193
|
-
// ── GET /.well-known/configuration → Server discovery (deprecated, use MCP initialize capabilities) ──
|
|
1194
|
-
if (path === "/.well-known/configuration" && req.method === "GET") {
|
|
1195
|
-
const baseUrl = resolveBaseUrl(req);
|
|
1196
|
-
const res = jsonResponse({
|
|
1197
|
-
issuer: baseUrl,
|
|
1198
|
-
jwks_uri: `${baseUrl}/.well-known/jwks.json`,
|
|
1199
|
-
token_endpoint: `${baseUrl}/oauth/token`,
|
|
1200
|
-
agents_endpoint: `${baseUrl}/list`,
|
|
1201
|
-
call_endpoint: baseUrl,
|
|
1202
|
-
supported_grant_types: ["client_credentials", "jwt_exchange"],
|
|
1203
|
-
authorization_endpoint: `${baseUrl}/oauth/authorize`,
|
|
1204
|
-
...(oidcSignIn
|
|
1205
|
-
? { signin_endpoint: `${baseUrl}/signin/authorize` }
|
|
1206
|
-
: {}),
|
|
1207
|
-
});
|
|
1208
|
-
return cors ? addCors(res) : res;
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
1260
|
// ── GET /.well-known/oauth-authorization-server → OAuth Server Metadata (RFC 8414) ──
|
|
1212
1261
|
// Only exposed when the server requires auth (private registries).
|
|
1213
1262
|
// Public registries (e.g. registry.slash.com) skip this entirely.
|
|
@@ -1215,7 +1264,9 @@ export function createAgentServer(
|
|
|
1215
1264
|
path === "/.well-known/oauth-authorization-server" &&
|
|
1216
1265
|
req.method === "GET"
|
|
1217
1266
|
) {
|
|
1218
|
-
if (
|
|
1267
|
+
if (
|
|
1268
|
+
!(options.registry?.oauthCallbackUrl || serverSigningKeys.length > 0)
|
|
1269
|
+
) {
|
|
1219
1270
|
const res = new Response("Not Found", { status: 404 });
|
|
1220
1271
|
return cors ? addCors(res) : res;
|
|
1221
1272
|
}
|
|
@@ -1226,7 +1277,11 @@ export function createAgentServer(
|
|
|
1226
1277
|
token_endpoint: `${baseUrl}/oauth/token`,
|
|
1227
1278
|
jwks_uri: `${baseUrl}/.well-known/jwks.json`,
|
|
1228
1279
|
response_types_supported: ["code"],
|
|
1229
|
-
grant_types_supported: [
|
|
1280
|
+
grant_types_supported: [
|
|
1281
|
+
"authorization_code",
|
|
1282
|
+
"client_credentials",
|
|
1283
|
+
"jwt_exchange",
|
|
1284
|
+
],
|
|
1230
1285
|
code_challenge_methods_supported: ["S256"],
|
|
1231
1286
|
token_endpoint_auth_methods_supported: ["client_secret_post", "none"],
|
|
1232
1287
|
...(options.registry?.oauthCallbackUrl && {
|
|
@@ -1236,98 +1291,6 @@ export function createAgentServer(
|
|
|
1236
1291
|
return cors ? addCors(res) : res;
|
|
1237
1292
|
}
|
|
1238
1293
|
|
|
1239
|
-
// ── GET /list → List agents (──
|
|
1240
|
-
if (path === "/list" && req.method === "GET") {
|
|
1241
|
-
const agents = registry.list();
|
|
1242
|
-
let visible = agents.filter((agent) =>
|
|
1243
|
-
canSeeAgent(agent, effectiveAuth),
|
|
1244
|
-
);
|
|
1245
|
-
|
|
1246
|
-
const searchQuery = url.searchParams.get("q");
|
|
1247
|
-
const searchLimit = url.searchParams.get("limit");
|
|
1248
|
-
const searchCursor = url.searchParams.get("cursor");
|
|
1249
|
-
|
|
1250
|
-
// Decode cursor
|
|
1251
|
-
const httpAfter = searchCursor
|
|
1252
|
-
? (JSON.parse(
|
|
1253
|
-
Buffer.from(searchCursor, "base64url").toString(),
|
|
1254
|
-
) as { path: string; score?: number })
|
|
1255
|
-
: undefined;
|
|
1256
|
-
|
|
1257
|
-
const httpPageSize = searchLimit ? Number(searchLimit) : 20;
|
|
1258
|
-
let httpPage: typeof visible;
|
|
1259
|
-
let httpNextCursor: string | undefined;
|
|
1260
|
-
|
|
1261
|
-
if (searchQuery) {
|
|
1262
|
-
const docs = visible.map((agent, i) => ({
|
|
1263
|
-
id: String(i),
|
|
1264
|
-
text: [
|
|
1265
|
-
agent.path,
|
|
1266
|
-
agent.config?.name ?? "",
|
|
1267
|
-
agent.config?.description ?? "",
|
|
1268
|
-
...agent.tools
|
|
1269
|
-
.filter((t) => canSeeTool(t, effectiveAuth))
|
|
1270
|
-
.map((t) => `${t.name} ${t.description}`),
|
|
1271
|
-
].join(" "),
|
|
1272
|
-
}));
|
|
1273
|
-
const index = createBM25Index(docs);
|
|
1274
|
-
const ranked = index.search(searchQuery);
|
|
1275
|
-
|
|
1276
|
-
type ScoredAgent = (typeof visible)[number] & { _score: number };
|
|
1277
|
-
let scored: ScoredAgent[] = ranked.map((r) => ({
|
|
1278
|
-
...visible[Number(r.id)],
|
|
1279
|
-
_score: r.score,
|
|
1280
|
-
}));
|
|
1281
|
-
|
|
1282
|
-
if (httpAfter?.score !== undefined) {
|
|
1283
|
-
scored = scored.filter(
|
|
1284
|
-
(a) =>
|
|
1285
|
-
a._score < httpAfter.score! ||
|
|
1286
|
-
(a._score === httpAfter.score! && a.path > httpAfter.path),
|
|
1287
|
-
);
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
httpPage = scored.slice(0, httpPageSize);
|
|
1291
|
-
if (scored.length > httpPageSize) {
|
|
1292
|
-
const last = scored[httpPageSize - 1] as ScoredAgent;
|
|
1293
|
-
httpNextCursor = Buffer.from(
|
|
1294
|
-
JSON.stringify({ path: last.path, score: last._score }),
|
|
1295
|
-
).toString("base64url");
|
|
1296
|
-
}
|
|
1297
|
-
} else {
|
|
1298
|
-
visible.sort((a, b) => a.path.localeCompare(b.path));
|
|
1299
|
-
if (httpAfter) {
|
|
1300
|
-
visible = visible.filter((a) => a.path > httpAfter.path);
|
|
1301
|
-
}
|
|
1302
|
-
httpPage = visible.slice(0, httpPageSize);
|
|
1303
|
-
if (visible.length > httpPageSize) {
|
|
1304
|
-
const last = httpPage[httpPage.length - 1];
|
|
1305
|
-
httpNextCursor = Buffer.from(
|
|
1306
|
-
JSON.stringify({ path: last.path }),
|
|
1307
|
-
).toString("base64url");
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
const res = jsonResponse({
|
|
1312
|
-
total: agents.filter((a) => canSeeAgent(a, effectiveAuth)).length,
|
|
1313
|
-
nextCursor: httpNextCursor,
|
|
1314
|
-
agents: httpPage.map((agent) => ({
|
|
1315
|
-
path: agent.path,
|
|
1316
|
-
name: agent.config?.name,
|
|
1317
|
-
description: agent.config?.description,
|
|
1318
|
-
supportedActions: agent.config?.supportedActions,
|
|
1319
|
-
integration: agent.config?.integration || null,
|
|
1320
|
-
tools: agent.tools
|
|
1321
|
-
.filter((t) => canSeeTool(t, effectiveAuth))
|
|
1322
|
-
.map((t) => ({
|
|
1323
|
-
name: t.name,
|
|
1324
|
-
description: t.description,
|
|
1325
|
-
})),
|
|
1326
|
-
})),
|
|
1327
|
-
});
|
|
1328
|
-
return cors ? addCors(res) : res;
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
1294
|
// ── GET /agents → List public agents (discovery endpoint) ──
|
|
1332
1295
|
if (path === "/agents" && req.method === "GET") {
|
|
1333
1296
|
const agents = registry.list();
|
|
@@ -1342,7 +1305,7 @@ export function createAgentServer(
|
|
|
1342
1305
|
name: agent.config?.name,
|
|
1343
1306
|
description:
|
|
1344
1307
|
agent.config?.description ?? agent.entrypoint?.slice(0, 200),
|
|
1345
|
-
mode: agent.mode ??
|
|
1308
|
+
mode: agent.mode ?? "direct",
|
|
1346
1309
|
...(agent.upstream && { upstream: agent.upstream }),
|
|
1347
1310
|
tools: getVisibleTools(agent, effectiveAuth).map((t) => ({
|
|
1348
1311
|
name: t.name,
|
|
@@ -1369,7 +1332,7 @@ export function createAgentServer(
|
|
|
1369
1332
|
name: agent.config?.name,
|
|
1370
1333
|
description:
|
|
1371
1334
|
agent.config?.description ?? agent.entrypoint?.slice(0, 200),
|
|
1372
|
-
mode: agent.mode ??
|
|
1335
|
+
mode: agent.mode ?? "direct",
|
|
1373
1336
|
...(agent.upstream && { upstream: agent.upstream }),
|
|
1374
1337
|
tools: getVisibleTools(agent, effectiveAuth).map((t) => ({
|
|
1375
1338
|
name: t.name,
|
|
@@ -1595,7 +1558,7 @@ export function createAgentServer(
|
|
|
1595
1558
|
hostname,
|
|
1596
1559
|
fetch,
|
|
1597
1560
|
});
|
|
1598
|
-
|
|
1561
|
+
this.url = `http://${hostname}:${port}`;
|
|
1599
1562
|
console.log(
|
|
1600
1563
|
`[agents-sdk] Server listening on http://${hostname}:${port}`,
|
|
1601
1564
|
);
|
|
@@ -1605,7 +1568,7 @@ export function createAgentServer(
|
|
|
1605
1568
|
if (serverInstance) {
|
|
1606
1569
|
serverInstance.stop();
|
|
1607
1570
|
serverInstance = null;
|
|
1608
|
-
|
|
1571
|
+
this.url = null;
|
|
1609
1572
|
}
|
|
1610
1573
|
},
|
|
1611
1574
|
|
|
@@ -1618,8 +1581,14 @@ export function createAgentServer(
|
|
|
1618
1581
|
);
|
|
1619
1582
|
}
|
|
1620
1583
|
const key = serverSigningKeys[0];
|
|
1584
|
+
const payload: Omit<AgentJwtPayload, "iat" | "exp"> = {
|
|
1585
|
+
sub: "system",
|
|
1586
|
+
name: "atlas-os",
|
|
1587
|
+
scopes: ["*"],
|
|
1588
|
+
...(claims as Partial<Omit<AgentJwtPayload, "iat" | "exp">>),
|
|
1589
|
+
};
|
|
1621
1590
|
return signJwtES256(
|
|
1622
|
-
|
|
1591
|
+
payload,
|
|
1623
1592
|
key.privateKey,
|
|
1624
1593
|
key.kid,
|
|
1625
1594
|
options.serverName ?? "agents-sdk",
|
package/src/types.ts
CHANGED
|
@@ -822,3 +822,65 @@ export type CallAgentResponse =
|
|
|
822
822
|
| CallAgentListResourcesResponse
|
|
823
823
|
| CallAgentReadResourcesResponse
|
|
824
824
|
| CallAgentErrorResponse;
|
|
825
|
+
|
|
826
|
+
/** Narrowing: registry returned an error (not an executed tool result). */
|
|
827
|
+
export function isCallAgentErrorResponse(
|
|
828
|
+
r: CallAgentResponse,
|
|
829
|
+
): r is CallAgentErrorResponse {
|
|
830
|
+
return r.success === false;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Result payload from the @auth `exchange_token` tool (the `result` field of a
|
|
835
|
+
* successful `execute_tool` response).
|
|
836
|
+
*/
|
|
837
|
+
export type ExchangeTokenToolResult =
|
|
838
|
+
| ExchangeTokenLinkedSuccess
|
|
839
|
+
| ExchangeTokenNeedsIdentity
|
|
840
|
+
| ExchangeTokenRejected;
|
|
841
|
+
|
|
842
|
+
export interface ExchangeTokenLinkedSuccess {
|
|
843
|
+
success: true;
|
|
844
|
+
tenantId?: string;
|
|
845
|
+
userId: string;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
export interface ExchangeTokenNeedsIdentity {
|
|
849
|
+
success: false;
|
|
850
|
+
needsAuth: true;
|
|
851
|
+
tenantId?: string;
|
|
852
|
+
issuer: string;
|
|
853
|
+
sub: string;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
export interface ExchangeTokenRejected {
|
|
857
|
+
success: false;
|
|
858
|
+
error: string;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
export function isExchangeTokenLinkedSuccess(
|
|
862
|
+
r: ExchangeTokenToolResult,
|
|
863
|
+
): r is ExchangeTokenLinkedSuccess {
|
|
864
|
+
return r.success === true;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
export function isExchangeTokenNeedsIdentity(
|
|
868
|
+
r: ExchangeTokenToolResult,
|
|
869
|
+
): r is ExchangeTokenNeedsIdentity {
|
|
870
|
+
return r.success === false && "needsAuth" in r && r.needsAuth === true;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/** Result payload from @auth `token` tool (client_credentials). */
|
|
874
|
+
export interface AuthClientCredentialsTokenResult {
|
|
875
|
+
accessToken: unknown;
|
|
876
|
+
tokenType?: string;
|
|
877
|
+
expiresIn: number;
|
|
878
|
+
refreshToken?: unknown;
|
|
879
|
+
scopes?: string[];
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
/** Wrapped secret values returned by auth tools (serialized for wire). */
|
|
883
|
+
export interface AuthSecretValue {
|
|
884
|
+
$agent_type: "secret";
|
|
885
|
+
value: string;
|
|
886
|
+
}
|
package/src/validate.ts
CHANGED
|
@@ -22,7 +22,7 @@ export const SerializedToolSchema = z.object({
|
|
|
22
22
|
inputSchema: z
|
|
23
23
|
.record(z.unknown())
|
|
24
24
|
.default({ type: "object", properties: {} }),
|
|
25
|
-
outputSchema: z.
|
|
25
|
+
outputSchema: z.object({}).passthrough().optional(),
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
// ============================================
|
|
@@ -36,7 +36,7 @@ export const SerializedAgentDefinitionSchema = z
|
|
|
36
36
|
description: z.string().default(""),
|
|
37
37
|
version: z.string().default("1.0.0"),
|
|
38
38
|
visibility: z.enum(["public", "private"]).default("public"),
|
|
39
|
-
auth: z.
|
|
39
|
+
auth: z.object({}).passthrough().optional(),
|
|
40
40
|
serverSource: z.string().optional(),
|
|
41
41
|
serverInfo: z
|
|
42
42
|
.object({
|