@slashfi/agents-sdk 0.4.0 → 0.6.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.d.ts → agent-definitions/auth.d.ts} +36 -2
- package/dist/agent-definitions/auth.d.ts.map +1 -0
- package/dist/{auth.js → agent-definitions/auth.js} +69 -8
- package/dist/agent-definitions/auth.js.map +1 -0
- package/dist/agent-definitions/integrations.d.ts +162 -0
- package/dist/agent-definitions/integrations.d.ts.map +1 -0
- package/dist/agent-definitions/integrations.js +861 -0
- package/dist/agent-definitions/integrations.js.map +1 -0
- package/dist/agent-definitions/secrets.d.ts +51 -0
- package/dist/agent-definitions/secrets.d.ts.map +1 -0
- package/dist/agent-definitions/secrets.js +165 -0
- package/dist/agent-definitions/secrets.js.map +1 -0
- package/dist/agent-definitions/users.d.ts +80 -0
- package/dist/agent-definitions/users.d.ts.map +1 -0
- package/dist/agent-definitions/users.js +397 -0
- package/dist/agent-definitions/users.js.map +1 -0
- package/dist/crypto.d.ts +14 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +40 -0
- package/dist/crypto.js.map +1 -0
- package/dist/define.d.ts +6 -1
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +1 -0
- package/dist/define.js.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/jwt.d.ts +2 -0
- package/dist/jwt.d.ts.map +1 -1
- package/dist/jwt.js.map +1 -1
- package/dist/server.d.ts +28 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +478 -27
- package/dist/server.js.map +1 -1
- package/dist/slack-oauth.d.ts +27 -0
- package/dist/slack-oauth.d.ts.map +1 -0
- package/dist/slack-oauth.js +48 -0
- package/dist/slack-oauth.js.map +1 -0
- package/dist/types.d.ts +66 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/web-pages.d.ts +8 -0
- package/dist/web-pages.d.ts.map +1 -0
- package/dist/web-pages.js +169 -0
- package/dist/web-pages.js.map +1 -0
- package/package.json +2 -1
- package/src/{auth.ts → agent-definitions/auth.ts} +134 -15
- package/src/agent-definitions/integrations.ts +1209 -0
- package/src/agent-definitions/secrets.ts +241 -0
- package/src/agent-definitions/users.ts +533 -0
- package/src/crypto.ts +71 -0
- package/src/define.ts +8 -0
- package/src/index.ts +62 -4
- package/src/jwt.ts +9 -5
- package/src/server.ts +567 -35
- package/src/slack-oauth.ts +66 -0
- package/src/types.ts +83 -0
- package/src/web-pages.ts +178 -0
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js.map +0 -1
- package/dist/secrets.d.ts +0 -44
- package/dist/secrets.d.ts.map +0 -1
- package/dist/secrets.js +0 -106
- package/dist/secrets.js.map +0 -1
- package/src/secrets.ts +0 -154
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import { defineAgent, defineTool } from "
|
|
28
|
-
import
|
|
29
|
-
import {
|
|
27
|
+
import { defineAgent, defineTool } from "../define.js";
|
|
28
|
+
import { signJwt } from "../jwt.js";
|
|
29
|
+
import type { AgentDefinition, ToolContext, ToolDefinition } from "../types.js";
|
|
30
30
|
|
|
31
31
|
// ============================================
|
|
32
32
|
// Auth Types
|
|
@@ -35,6 +35,7 @@ import { signJwt } from "./jwt.js";
|
|
|
35
35
|
/** Registered client */
|
|
36
36
|
export interface AuthClient {
|
|
37
37
|
clientId: string;
|
|
38
|
+
tenantId?: string;
|
|
38
39
|
clientSecretHash: string;
|
|
39
40
|
name: string;
|
|
40
41
|
scopes: string[];
|
|
@@ -68,12 +69,32 @@ export interface AuthIdentity {
|
|
|
68
69
|
* Pluggable storage for auth state.
|
|
69
70
|
* Implement this interface to use Postgres, Redis, SQLite, etc.
|
|
70
71
|
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Tenant - organizational unit for multi-tenant isolation.
|
|
75
|
+
*/
|
|
76
|
+
export interface AuthTenant {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
createdAt: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
71
82
|
export interface AuthStore {
|
|
83
|
+
/** Create a tenant. */
|
|
84
|
+
createTenant(name: string): Promise<{ tenantId: string }>;
|
|
85
|
+
|
|
86
|
+
/** Get tenant by ID. */
|
|
87
|
+
getTenant(tenantId: string): Promise<AuthTenant | null>;
|
|
88
|
+
|
|
89
|
+
/** List tenants. */
|
|
90
|
+
listTenants(): Promise<AuthTenant[]>;
|
|
91
|
+
|
|
72
92
|
/** Create a new client. Returns the raw (unhashed) secret. */
|
|
73
93
|
createClient(
|
|
74
94
|
name: string,
|
|
75
95
|
scopes: string[],
|
|
76
96
|
selfRegistered?: boolean,
|
|
97
|
+
tenantId?: string,
|
|
77
98
|
): Promise<{ clientId: string; clientSecret: string }>;
|
|
78
99
|
|
|
79
100
|
/** Validate client credentials. Returns client if valid, null otherwise. */
|
|
@@ -102,6 +123,28 @@ export interface AuthStore {
|
|
|
102
123
|
|
|
103
124
|
/** Revoke a specific token. */
|
|
104
125
|
revokeToken(tokenString: string): Promise<boolean>;
|
|
126
|
+
|
|
127
|
+
/** Register a user under a tenant. Returns a refresh token. */
|
|
128
|
+
registerUser?(
|
|
129
|
+
tenantId: string,
|
|
130
|
+
userId: string,
|
|
131
|
+
clientId: string,
|
|
132
|
+
): Promise<{ refreshToken: string }>;
|
|
133
|
+
|
|
134
|
+
/** Validate a refresh token. Returns user info. */
|
|
135
|
+
validateRefreshToken?(
|
|
136
|
+
refreshToken: string,
|
|
137
|
+
): Promise<{ tenantId: string; userId: string; clientId: string } | null>;
|
|
138
|
+
|
|
139
|
+
/** Rotate a refresh token. */
|
|
140
|
+
rotateRefreshToken?(
|
|
141
|
+
oldToken: string,
|
|
142
|
+
): Promise<{
|
|
143
|
+
refreshToken: string;
|
|
144
|
+
tenantId: string;
|
|
145
|
+
userId: string;
|
|
146
|
+
clientId: string;
|
|
147
|
+
} | null>;
|
|
105
148
|
}
|
|
106
149
|
|
|
107
150
|
// ============================================
|
|
@@ -127,8 +170,6 @@ function generateSecret(): string {
|
|
|
127
170
|
return secret;
|
|
128
171
|
}
|
|
129
172
|
|
|
130
|
-
|
|
131
|
-
|
|
132
173
|
/** Simple hash for storing secrets (not for production - use bcrypt/argon2) */
|
|
133
174
|
async function hashSecret(secret: string): Promise<string> {
|
|
134
175
|
const encoder = new TextEncoder();
|
|
@@ -144,17 +185,33 @@ async function hashSecret(secret: string): Promise<string> {
|
|
|
144
185
|
* Suitable for development and testing. Use a persistent store for production.
|
|
145
186
|
*/
|
|
146
187
|
export function createMemoryAuthStore(): AuthStore {
|
|
188
|
+
const tenants = new Map<string, AuthTenant>();
|
|
147
189
|
const clients = new Map<string, AuthClient>();
|
|
148
190
|
const tokens = new Map<string, AuthToken>();
|
|
149
191
|
|
|
150
192
|
return {
|
|
151
|
-
async
|
|
193
|
+
async createTenant(name) {
|
|
194
|
+
const id = `tenant_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
195
|
+
tenants.set(id, { id, name, createdAt: Date.now() });
|
|
196
|
+
return { tenantId: id };
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
async getTenant(tenantId) {
|
|
200
|
+
return tenants.get(tenantId) ?? null;
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
async listTenants() {
|
|
204
|
+
return Array.from(tenants.values());
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
async createClient(name, scopes, selfRegistered, tenantId) {
|
|
152
208
|
const clientId = generateId("ag_");
|
|
153
209
|
const clientSecret = generateSecret();
|
|
154
210
|
const secretHash = await hashSecret(clientSecret);
|
|
155
211
|
|
|
156
212
|
clients.set(clientId, {
|
|
157
213
|
clientId,
|
|
214
|
+
tenantId,
|
|
158
215
|
clientSecretHash: secretHash,
|
|
159
216
|
name,
|
|
160
217
|
scopes,
|
|
@@ -195,7 +252,9 @@ export function createMemoryAuthStore(): AuthStore {
|
|
|
195
252
|
if (!client) return null;
|
|
196
253
|
const clientSecret = generateSecret();
|
|
197
254
|
client.clientSecretHash = await hashSecret(clientSecret);
|
|
198
|
-
return {
|
|
255
|
+
return {
|
|
256
|
+
clientSecret: { $agent_type: "secret", value: clientSecret },
|
|
257
|
+
} as any;
|
|
199
258
|
},
|
|
200
259
|
|
|
201
260
|
async storeToken(token) {
|
|
@@ -266,6 +325,24 @@ export function createAuthAgent(
|
|
|
266
325
|
|
|
267
326
|
// --- Public Tools ---
|
|
268
327
|
|
|
328
|
+
const createTenantTool = defineTool({
|
|
329
|
+
name: "create_tenant",
|
|
330
|
+
description:
|
|
331
|
+
"Create a new tenant (organizational unit). All clients and resources are scoped to a tenant.",
|
|
332
|
+
visibility: "public" as const,
|
|
333
|
+
inputSchema: {
|
|
334
|
+
type: "object" as const,
|
|
335
|
+
properties: {
|
|
336
|
+
name: { type: "string" as const, description: "Tenant name" },
|
|
337
|
+
},
|
|
338
|
+
required: ["name"],
|
|
339
|
+
},
|
|
340
|
+
execute: async (input: { name: string }) => {
|
|
341
|
+
const result = await store.createTenant(input.name);
|
|
342
|
+
return { tenantId: result.tenantId, name: input.name };
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
|
|
269
346
|
const tokenTool = defineTool({
|
|
270
347
|
name: "token",
|
|
271
348
|
description:
|
|
@@ -286,16 +363,47 @@ export function createAuthAgent(
|
|
|
286
363
|
},
|
|
287
364
|
execute: async (input: {
|
|
288
365
|
grantType: string;
|
|
289
|
-
clientId
|
|
290
|
-
clientSecret
|
|
366
|
+
clientId?: string;
|
|
367
|
+
clientSecret?: string;
|
|
368
|
+
userId?: string;
|
|
369
|
+
refreshToken?: string;
|
|
291
370
|
}) => {
|
|
371
|
+
if (input.grantType === "refresh_token") {
|
|
372
|
+
if (!input.refreshToken)
|
|
373
|
+
throw new Error("refreshToken is required for refresh_token grant");
|
|
374
|
+
if (!store.rotateRefreshToken)
|
|
375
|
+
throw new Error("Refresh tokens not supported by this store");
|
|
376
|
+
const result = await store.rotateRefreshToken(input.refreshToken);
|
|
377
|
+
if (!result) throw new Error("Invalid or expired refresh token");
|
|
378
|
+
const now = Math.floor(Date.now() / 1000);
|
|
379
|
+
const jwt = await signJwt(
|
|
380
|
+
{
|
|
381
|
+
sub: result.clientId,
|
|
382
|
+
name: result.userId,
|
|
383
|
+
tenantId: result.tenantId,
|
|
384
|
+
scopes: [],
|
|
385
|
+
iat: now,
|
|
386
|
+
exp: now + tokenTtl,
|
|
387
|
+
},
|
|
388
|
+
(await store.getClient(result.clientId))?.clientSecretHash ?? "",
|
|
389
|
+
);
|
|
390
|
+
return {
|
|
391
|
+
accessToken: { $agent_type: "secret", value: jwt },
|
|
392
|
+
refreshToken: { $agent_type: "secret", value: result.refreshToken },
|
|
393
|
+
tokenType: "bearer",
|
|
394
|
+
expiresIn: tokenTtl,
|
|
395
|
+
} as any;
|
|
396
|
+
}
|
|
397
|
+
|
|
292
398
|
if (input.grantType !== "client_credentials") {
|
|
293
|
-
throw new Error(
|
|
399
|
+
throw new Error(
|
|
400
|
+
"Unsupported grant type. Use 'client_credentials' or 'refresh_token'.",
|
|
401
|
+
);
|
|
294
402
|
}
|
|
295
403
|
|
|
296
404
|
const client = await store.validateClient(
|
|
297
|
-
input.clientId
|
|
298
|
-
input.clientSecret
|
|
405
|
+
input.clientId!,
|
|
406
|
+
input.clientSecret!,
|
|
299
407
|
);
|
|
300
408
|
if (!client) {
|
|
301
409
|
throw new Error("Invalid client credentials");
|
|
@@ -306,6 +414,7 @@ export function createAuthAgent(
|
|
|
306
414
|
{
|
|
307
415
|
sub: client.clientId,
|
|
308
416
|
name: client.name,
|
|
417
|
+
tenantId: client.tenantId,
|
|
309
418
|
scopes: client.scopes,
|
|
310
419
|
iat: now,
|
|
311
420
|
exp: now + tokenTtl,
|
|
@@ -314,7 +423,7 @@ export function createAuthAgent(
|
|
|
314
423
|
);
|
|
315
424
|
|
|
316
425
|
return {
|
|
317
|
-
accessToken: jwt,
|
|
426
|
+
accessToken: { $agent_type: "secret", value: jwt },
|
|
318
427
|
tokenType: "bearer",
|
|
319
428
|
expiresIn: tokenTtl,
|
|
320
429
|
scopes: client.scopes,
|
|
@@ -355,7 +464,11 @@ export function createAuthAgent(
|
|
|
355
464
|
},
|
|
356
465
|
required: ["name"],
|
|
357
466
|
},
|
|
358
|
-
execute: async (input: {
|
|
467
|
+
execute: async (input: {
|
|
468
|
+
name: string;
|
|
469
|
+
tenantId: string;
|
|
470
|
+
scopes?: string[];
|
|
471
|
+
}) => {
|
|
359
472
|
let scopes = input.scopes ?? [];
|
|
360
473
|
|
|
361
474
|
// If registration scopes are restricted, filter
|
|
@@ -367,9 +480,14 @@ export function createAuthAgent(
|
|
|
367
480
|
input.name,
|
|
368
481
|
scopes,
|
|
369
482
|
true,
|
|
483
|
+
input.tenantId,
|
|
370
484
|
);
|
|
371
485
|
|
|
372
|
-
return {
|
|
486
|
+
return {
|
|
487
|
+
clientId,
|
|
488
|
+
clientSecret: { $agent_type: "secret", value: clientSecret },
|
|
489
|
+
scopes,
|
|
490
|
+
} as any;
|
|
373
491
|
},
|
|
374
492
|
});
|
|
375
493
|
|
|
@@ -457,6 +575,7 @@ export function createAuthAgent(
|
|
|
457
575
|
// --- Assemble tools ---
|
|
458
576
|
|
|
459
577
|
const tools = [
|
|
578
|
+
createTenantTool,
|
|
460
579
|
tokenTool,
|
|
461
580
|
whoamiTool,
|
|
462
581
|
...(allowRegistration ? [registerTool] : []),
|