@slashfi/agents-sdk 0.11.1 → 0.12.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/agent-definitions/auth.d.ts +4 -1
- package/dist/agent-definitions/auth.d.ts.map +1 -1
- package/dist/agent-definitions/auth.js +48 -3
- package/dist/agent-definitions/auth.js.map +1 -1
- package/dist/agent-definitions/integrations.d.ts +2 -14
- package/dist/agent-definitions/integrations.d.ts.map +1 -1
- package/dist/agent-definitions/integrations.js +46 -17
- package/dist/agent-definitions/integrations.js.map +1 -1
- package/dist/agent-definitions/remote-registry.d.ts +19 -14
- package/dist/agent-definitions/remote-registry.d.ts.map +1 -1
- package/dist/agent-definitions/remote-registry.js +207 -381
- 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 +29 -1
- package/dist/agent-definitions/users.js.map +1 -1
- package/dist/define.d.ts +6 -4
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +82 -3
- package/dist/define.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jwt.js +1 -1
- package/dist/jwt.js.map +1 -1
- package/dist/server.d.ts +42 -5
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +223 -62
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +53 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/agent-definitions/auth.ts +57 -5
- package/src/agent-definitions/integrations.ts +51 -26
- package/src/agent-definitions/remote-registry.ts +210 -513
- package/src/agent-definitions/users.ts +35 -1
- package/src/define.ts +98 -6
- package/src/index.ts +2 -1
- package/src/jwt.ts +1 -1
- package/src/server.test.ts +284 -0
- package/src/server.ts +331 -75
- package/src/types.ts +44 -1
|
@@ -81,7 +81,7 @@ export interface AuthTenant {
|
|
|
81
81
|
|
|
82
82
|
export interface AuthStore {
|
|
83
83
|
/** Create a tenant. */
|
|
84
|
-
createTenant(name: string): Promise<{ tenantId: string }>;
|
|
84
|
+
createTenant(name: string, externalRef?: { issuer: string; tenantId: string }): Promise<{ tenantId: string }>;
|
|
85
85
|
|
|
86
86
|
/** Get tenant by ID. */
|
|
87
87
|
getTenant(tenantId: string): Promise<AuthTenant | null>;
|
|
@@ -220,7 +220,7 @@ export function createMemoryAuthStore(): AuthStore {
|
|
|
220
220
|
const trustedIssuers = new Set<string>();
|
|
221
221
|
|
|
222
222
|
return {
|
|
223
|
-
async createTenant(name) {
|
|
223
|
+
async createTenant(name, _externalRef) {
|
|
224
224
|
const id = `tenant_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
225
225
|
tenants.set(id, { id, name, createdAt: Date.now() });
|
|
226
226
|
return { tenantId: id };
|
|
@@ -368,6 +368,7 @@ export interface CreateAuthAgentOptions {
|
|
|
368
368
|
|
|
369
369
|
/** Custom auth store. Default: in-memory */
|
|
370
370
|
store?: AuthStore;
|
|
371
|
+
|
|
371
372
|
}
|
|
372
373
|
|
|
373
374
|
// ============================================
|
|
@@ -406,12 +407,22 @@ export function createAuthAgent(
|
|
|
406
407
|
type: "object" as const,
|
|
407
408
|
properties: {
|
|
408
409
|
name: { type: "string" as const, description: "Tenant name" },
|
|
410
|
+
externalRef: {
|
|
411
|
+
type: "object" as const,
|
|
412
|
+
description: "Link to a tenant on a remote system (for cross-registry trust)",
|
|
413
|
+
properties: {
|
|
414
|
+
issuer: { type: "string" as const, description: "Issuer URL of the remote system" },
|
|
415
|
+
tenantId: { type: "string" as const, description: "Tenant ID on the remote system" },
|
|
416
|
+
},
|
|
417
|
+
required: ["issuer", "tenantId"],
|
|
418
|
+
},
|
|
409
419
|
},
|
|
410
420
|
required: ["name"],
|
|
411
421
|
},
|
|
412
|
-
execute: async (input: { name: string }) => {
|
|
413
|
-
const result = await store.createTenant(input.name);
|
|
414
|
-
return { tenantId: result.tenantId, name: input.name };
|
|
422
|
+
execute: async (input: { name: string; externalRef?: { issuer: string; tenantId: string } }) => {
|
|
423
|
+
const result = await store.createTenant(input.name, input.externalRef);
|
|
424
|
+
return { tenantId: result.tenantId, name: input.name, externalRef: input.externalRef };
|
|
425
|
+
|
|
415
426
|
},
|
|
416
427
|
});
|
|
417
428
|
|
|
@@ -757,6 +768,46 @@ export function createAuthAgent(
|
|
|
757
768
|
},
|
|
758
769
|
});
|
|
759
770
|
|
|
771
|
+
|
|
772
|
+
const exchangeTokenTool = defineTool({
|
|
773
|
+
name: "exchange_token",
|
|
774
|
+
description:
|
|
775
|
+
"Exchange a foreign JWT for a local identity. Verifies the JWT via JWKS, " +
|
|
776
|
+
"resolves the tenant and user to local IDs. If the user is not yet linked, " +
|
|
777
|
+
"returns needsAuth=true with a connect URL for OAuth identity linking.",
|
|
778
|
+
visibility: "public" as const,
|
|
779
|
+
inputSchema: {
|
|
780
|
+
type: "object" as const,
|
|
781
|
+
properties: {
|
|
782
|
+
token: {
|
|
783
|
+
type: "string" as const,
|
|
784
|
+
description: "JWT signed by a trusted issuer",
|
|
785
|
+
},
|
|
786
|
+
connectBaseUrl: {
|
|
787
|
+
type: "string" as const,
|
|
788
|
+
description: "Base URL for the OAuth connect flow (returned in needsAuth response)",
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
required: ["token"],
|
|
792
|
+
},
|
|
793
|
+
execute: async (
|
|
794
|
+
_input: { token: string; connectBaseUrl?: string },
|
|
795
|
+
) => {
|
|
796
|
+
// This tool is a stub — the actual implementation needs:
|
|
797
|
+
// 1. JWT verification (via verifyJwtFromIssuer)
|
|
798
|
+
// 2. Tenant resolution (via tenant_identity table)
|
|
799
|
+
// 3. User resolution (via user_identity table)
|
|
800
|
+
// These depend on the store having identity lookup methods.
|
|
801
|
+
//
|
|
802
|
+
// For now, return the structure so the flow can be wired.
|
|
803
|
+
// The atlas-environments CockroachDB implementation overrides this.
|
|
804
|
+
return {
|
|
805
|
+
error: "exchange_token requires a store with identity resolution support",
|
|
806
|
+
hint: "Override this tool in your environment implementation",
|
|
807
|
+
};
|
|
808
|
+
},
|
|
809
|
+
});
|
|
810
|
+
|
|
760
811
|
const tools = [
|
|
761
812
|
createTenantTool,
|
|
762
813
|
tokenTool,
|
|
@@ -769,6 +820,7 @@ export function createAuthAgent(
|
|
|
769
820
|
rotateKeysTool,
|
|
770
821
|
trustIssuerTool,
|
|
771
822
|
apiKeyTool,
|
|
823
|
+
exchangeTokenTool,
|
|
772
824
|
];
|
|
773
825
|
|
|
774
826
|
const agent = defineAgent({
|
|
@@ -489,21 +489,13 @@ export interface IntegrationsAgentOptions {
|
|
|
489
489
|
store: IntegrationStore;
|
|
490
490
|
|
|
491
491
|
/**
|
|
492
|
-
* Callback to list all registered agents.
|
|
493
|
-
* Used by list_integrations to discover agents with integrationMethods.
|
|
494
|
-
* Typically wired to registry.list().
|
|
495
|
-
*/
|
|
496
|
-
getAgents?: () => AgentDefinition[];
|
|
497
492
|
|
|
498
493
|
/** Registry instance for calling other agents' internal tools */
|
|
499
494
|
registry?: {
|
|
495
|
+
list?(): AgentDefinition[];
|
|
500
496
|
call(request: any): Promise<any>;
|
|
501
497
|
};
|
|
502
498
|
|
|
503
|
-
/** Integrations store for tracking installed integrations */
|
|
504
|
-
integrationsStore?: {
|
|
505
|
-
create(input: { agentPath: string; config: Record<string, unknown>; installedBy?: string; tenantId?: string }): Promise<any>;
|
|
506
|
-
};
|
|
507
499
|
|
|
508
500
|
/** Secret store for storing/resolving client credentials and tokens */
|
|
509
501
|
secretStore: {
|
|
@@ -535,7 +527,7 @@ const SYSTEM_OWNER = "__integrations__";
|
|
|
535
527
|
export function createIntegrationsAgent(
|
|
536
528
|
options: IntegrationsAgentOptions,
|
|
537
529
|
): AgentDefinition {
|
|
538
|
-
const { store, callbackBaseUrl, secretStore
|
|
530
|
+
const { store, callbackBaseUrl, secretStore } = options;
|
|
539
531
|
|
|
540
532
|
// ---- setup_integration ----
|
|
541
533
|
const setupTool = defineTool({
|
|
@@ -681,15 +673,20 @@ export function createIntegrationsAgent(
|
|
|
681
673
|
|
|
682
674
|
await store.upsertProvider(config);
|
|
683
675
|
|
|
684
|
-
//
|
|
685
|
-
if (
|
|
676
|
+
// Delegate to agent's setup_integration tool via registry.call()
|
|
677
|
+
if (config.agentPath && options.registry) {
|
|
686
678
|
try {
|
|
687
|
-
await
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
679
|
+
const setupResult = await options.registry.call({
|
|
680
|
+
action: 'execute_tool',
|
|
681
|
+
path: config.agentPath,
|
|
682
|
+
tool: 'setup_integration',
|
|
683
|
+
params: input.config ?? input,
|
|
684
|
+
callerType: 'system',
|
|
691
685
|
});
|
|
692
|
-
|
|
686
|
+
result.setupResult = (setupResult as any)?.result ?? setupResult;
|
|
687
|
+
} catch (err) {
|
|
688
|
+
result.setupError = err instanceof Error ? err.message : String(err);
|
|
689
|
+
}
|
|
693
690
|
}
|
|
694
691
|
|
|
695
692
|
result.provider = config;
|
|
@@ -736,8 +733,8 @@ export function createIntegrationsAgent(
|
|
|
736
733
|
}> = [];
|
|
737
734
|
|
|
738
735
|
// 1. Agent-backed integrations
|
|
739
|
-
if (
|
|
740
|
-
for (const agent of
|
|
736
|
+
if (options.registry) {
|
|
737
|
+
for (const agent of (options.registry.list?.() ?? [])) {
|
|
741
738
|
if (agent.config?.integration) {
|
|
742
739
|
const ic = agent.config.integration;
|
|
743
740
|
catalog.push({
|
|
@@ -831,11 +828,12 @@ export function createIntegrationsAgent(
|
|
|
831
828
|
});
|
|
832
829
|
}
|
|
833
830
|
|
|
834
|
-
// 2. Agent-backed integrations (agents with config.integration +
|
|
835
|
-
if (
|
|
836
|
-
const agents =
|
|
831
|
+
// 2. Agent-backed integrations (agents with config.integration + list_integrations tool)
|
|
832
|
+
if (options.registry) {
|
|
833
|
+
const agents = options.registry.list?.() ?? [];
|
|
837
834
|
for (const agent of agents) {
|
|
838
|
-
|
|
835
|
+
const hasListTool = agent.tools?.some((t: any) => t.name === 'list_integrations');
|
|
836
|
+
if (hasListTool && agent.config?.integration) {
|
|
839
837
|
const meta = {
|
|
840
838
|
provider: agent.config.integration.provider,
|
|
841
839
|
agentPath: agent.path,
|
|
@@ -845,7 +843,8 @@ export function createIntegrationsAgent(
|
|
|
845
843
|
description: agent.config.integration.description,
|
|
846
844
|
};
|
|
847
845
|
try {
|
|
848
|
-
const
|
|
846
|
+
const callResult = options.registry ? await options.registry.call({ action: 'execute_tool', path: agent.path!, tool: 'list_integrations', params: {}, callerType: 'system' }) : null;
|
|
847
|
+
const result = (callResult as any)?.result ?? callResult ?? { success: false };
|
|
849
848
|
if (result.success && result.data) {
|
|
850
849
|
// Flatten: if data has an array field, each item becomes an integration
|
|
851
850
|
const items = Array.isArray(result.data)
|
|
@@ -929,6 +928,19 @@ export function createIntegrationsAgent(
|
|
|
929
928
|
) => {
|
|
930
929
|
const config = await store.getProvider(input.provider);
|
|
931
930
|
if (!config) return { error: `Provider '${input.provider}' not found` };
|
|
931
|
+
|
|
932
|
+
// Delegate to agent's connect_integration tool via registry.call()
|
|
933
|
+
if (config.agentPath && options.registry) {
|
|
934
|
+
const connectResult = await options.registry.call({
|
|
935
|
+
action: 'execute_tool',
|
|
936
|
+
path: config.agentPath,
|
|
937
|
+
tool: 'connect_integration',
|
|
938
|
+
params: { ...input, registryId: config.id },
|
|
939
|
+
callerType: 'system',
|
|
940
|
+
});
|
|
941
|
+
return (connectResult as any)?.result ?? connectResult;
|
|
942
|
+
}
|
|
943
|
+
|
|
932
944
|
if (!config.auth)
|
|
933
945
|
return { error: `Provider '${input.provider}' has no OAuth config` };
|
|
934
946
|
if (!callbackBaseUrl)
|
|
@@ -1158,6 +1170,19 @@ export function createIntegrationsAgent(
|
|
|
1158
1170
|
) => {
|
|
1159
1171
|
const config = await store.getProvider(input.provider);
|
|
1160
1172
|
if (!config) return { error: `Provider '${input.provider}' not found` };
|
|
1173
|
+
|
|
1174
|
+
// Delegate to agent's connect_integration tool via registry.call()
|
|
1175
|
+
if (config.agentPath && options.registry) {
|
|
1176
|
+
const connectResult = await options.registry.call({
|
|
1177
|
+
action: 'execute_tool',
|
|
1178
|
+
path: config.agentPath,
|
|
1179
|
+
tool: 'connect_integration',
|
|
1180
|
+
params: { ...input, registryId: config.id },
|
|
1181
|
+
callerType: 'system',
|
|
1182
|
+
});
|
|
1183
|
+
return (connectResult as any)?.result ?? connectResult;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1161
1186
|
if (!config.auth)
|
|
1162
1187
|
return { error: `Provider '${input.provider}' has no OAuth config` };
|
|
1163
1188
|
if (!callbackBaseUrl) return { error: "No callbackBaseUrl configured" };
|
|
@@ -1347,7 +1372,7 @@ export function createIntegrationsAgent(
|
|
|
1347
1372
|
visibility: "public" as const,
|
|
1348
1373
|
inputSchema: { type: "object" as const, properties: {} },
|
|
1349
1374
|
execute: async () => {
|
|
1350
|
-
const agents =
|
|
1375
|
+
const agents = options.registry?.list?.() ?? [];
|
|
1351
1376
|
const results: any[] = [];
|
|
1352
1377
|
if (options.registry) {
|
|
1353
1378
|
for (const agent of agents) {
|
|
@@ -1385,7 +1410,7 @@ export function createIntegrationsAgent(
|
|
|
1385
1410
|
},
|
|
1386
1411
|
},
|
|
1387
1412
|
execute: async (input: { agent_path?: string }) => {
|
|
1388
|
-
const agents =
|
|
1413
|
+
const agents = options.registry?.list?.() ?? [];
|
|
1389
1414
|
const results: any[] = [];
|
|
1390
1415
|
if (options.registry) {
|
|
1391
1416
|
const targetAgents = input.agent_path
|