@slashfi/agents-sdk 0.15.0 → 0.17.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.
Files changed (93) hide show
  1. package/dist/agent-definitions/auth.d.ts.map +1 -1
  2. package/dist/agent-definitions/auth.js +44 -11
  3. package/dist/agent-definitions/auth.js.map +1 -1
  4. package/dist/agent-definitions/integrations.d.ts.map +1 -1
  5. package/dist/agent-definitions/integrations.js +106 -45
  6. package/dist/agent-definitions/integrations.js.map +1 -1
  7. package/dist/agent-definitions/remote-registry.d.ts.map +1 -1
  8. package/dist/agent-definitions/remote-registry.js +174 -45
  9. package/dist/agent-definitions/remote-registry.js.map +1 -1
  10. package/dist/agent-definitions/secrets.d.ts.map +1 -1
  11. package/dist/agent-definitions/secrets.js +1 -4
  12. package/dist/agent-definitions/secrets.js.map +1 -1
  13. package/dist/agent-definitions/users.d.ts.map +1 -1
  14. package/dist/agent-definitions/users.js +14 -3
  15. package/dist/agent-definitions/users.js.map +1 -1
  16. package/dist/define-config.d.ts +125 -0
  17. package/dist/define-config.d.ts.map +1 -0
  18. package/dist/define-config.js +75 -0
  19. package/dist/define-config.js.map +1 -0
  20. package/dist/define.d.ts +11 -2
  21. package/dist/define.d.ts.map +1 -1
  22. package/dist/define.js +57 -26
  23. package/dist/define.js.map +1 -1
  24. package/dist/events.d.ts +133 -0
  25. package/dist/events.d.ts.map +1 -0
  26. package/dist/events.js +57 -0
  27. package/dist/events.js.map +1 -0
  28. package/dist/index.d.ts +16 -8
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +9 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/integration-interface.d.ts +3 -3
  33. package/dist/integration-interface.d.ts.map +1 -1
  34. package/dist/integration-interface.js +29 -21
  35. package/dist/integration-interface.js.map +1 -1
  36. package/dist/integrations-store.d.ts +2 -2
  37. package/dist/integrations-store.d.ts.map +1 -1
  38. package/dist/integrations-store.js +3 -3
  39. package/dist/integrations-store.js.map +1 -1
  40. package/dist/jwt.d.ts.map +1 -1
  41. package/dist/jwt.js +7 -5
  42. package/dist/jwt.js.map +1 -1
  43. package/dist/key-manager.d.ts.map +1 -1
  44. package/dist/key-manager.js +5 -3
  45. package/dist/key-manager.js.map +1 -1
  46. package/dist/oidc-signin.d.ts +32 -0
  47. package/dist/oidc-signin.d.ts.map +1 -0
  48. package/dist/oidc-signin.js +138 -0
  49. package/dist/oidc-signin.js.map +1 -0
  50. package/dist/registry-consumer.d.ts +104 -0
  51. package/dist/registry-consumer.d.ts.map +1 -0
  52. package/dist/registry-consumer.js +230 -0
  53. package/dist/registry-consumer.js.map +1 -0
  54. package/dist/registry.d.ts +20 -1
  55. package/dist/registry.d.ts.map +1 -1
  56. package/dist/registry.js +167 -20
  57. package/dist/registry.js.map +1 -1
  58. package/dist/secret-collection.d.ts.map +1 -1
  59. package/dist/secret-collection.js.map +1 -1
  60. package/dist/server.d.ts +3 -0
  61. package/dist/server.d.ts.map +1 -1
  62. package/dist/server.js +222 -27
  63. package/dist/server.js.map +1 -1
  64. package/dist/test-utils/mock-oidc-server.d.ts +36 -0
  65. package/dist/test-utils/mock-oidc-server.d.ts.map +1 -0
  66. package/dist/test-utils/mock-oidc-server.js +96 -0
  67. package/dist/test-utils/mock-oidc-server.js.map +1 -0
  68. package/dist/types.d.ts +27 -0
  69. package/dist/types.d.ts.map +1 -1
  70. package/package.json +1 -1
  71. package/src/agent-definitions/auth.ts +106 -38
  72. package/src/agent-definitions/integrations.ts +201 -73
  73. package/src/agent-definitions/remote-registry.ts +262 -65
  74. package/src/agent-definitions/secrets.ts +22 -8
  75. package/src/agent-definitions/users.ts +16 -4
  76. package/src/consumer.test.ts +536 -0
  77. package/src/define-config.ts +205 -0
  78. package/src/define.ts +134 -46
  79. package/src/events.ts +237 -0
  80. package/src/index.ts +90 -8
  81. package/src/integration-interface.ts +52 -28
  82. package/src/integrations-store.ts +9 -5
  83. package/src/jwt.ts +48 -19
  84. package/src/key-manager.test.ts +22 -13
  85. package/src/key-manager.ts +8 -10
  86. package/src/oidc-signin.ts +223 -0
  87. package/src/registry-consumer.ts +413 -0
  88. package/src/registry.ts +237 -29
  89. package/src/secret-collection.ts +2 -1
  90. package/src/server.test.ts +304 -238
  91. package/src/server.ts +371 -69
  92. package/src/test-utils/mock-oidc-server.ts +123 -0
  93. package/src/types.ts +80 -18
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Mock OIDC Provider for testing.
3
+ *
4
+ * A minimal OpenID Connect provider that runs locally.
5
+ * Supports the authorization code flow with no user interaction.
6
+ *
7
+ * Usage:
8
+ * const server = await startMockOIDC({ port: 0 });
9
+ * // server.url = 'http://localhost:XXXXX'
10
+ * // server.issuer = server.url
11
+ * // Configure your app to use server.url as the OIDC provider
12
+ * await server.stop();
13
+ */
14
+
15
+ const TEST_USER = {
16
+ sub: "test-user-001",
17
+ email: "test@example.com",
18
+ name: "Test User",
19
+ picture: "https://example.com/avatar.png",
20
+ "https://slack.com/team_id": "T_TEST",
21
+ "https://slack.com/team_name": "Test Workspace",
22
+ };
23
+
24
+ const TEST_CLIENT_ID = "test-client-id";
25
+ const TEST_CLIENT_SECRET = "test-client-secret";
26
+ const VALID_CODE = "test-auth-code-12345";
27
+ const ACCESS_TOKEN = `test-access-token-${Date.now()}`;
28
+
29
+ export interface MockOIDCServer {
30
+ url: string;
31
+ port: number;
32
+ issuer: string;
33
+ clientId: string;
34
+ clientSecret: string;
35
+ testUser: typeof TEST_USER;
36
+ accessToken: string;
37
+ stop: () => Promise<void>;
38
+ }
39
+
40
+ export async function startMockOIDC(
41
+ opts: { port?: number } = {},
42
+ ): Promise<MockOIDCServer> {
43
+ const server: ReturnType<typeof Bun.serve> = Bun.serve({
44
+ port: opts.port ?? 0,
45
+ fetch(req): Response | Promise<Response> {
46
+ const url = new URL(req.url);
47
+
48
+ // Discovery
49
+ if (url.pathname === "/.well-known/openid-configuration") {
50
+ const base: string = `http://localhost:${server.port}`;
51
+ return Response.json({
52
+ issuer: base,
53
+ authorization_endpoint: `${base}/authorize`,
54
+ token_endpoint: `${base}/token`,
55
+ userinfo_endpoint: `${base}/userinfo`,
56
+ jwks_uri: `${base}/jwks`,
57
+ response_types_supported: ["code"],
58
+ subject_types_supported: ["public"],
59
+ id_token_signing_alg_values_supported: ["RS256"],
60
+ scopes_supported: ["openid", "email", "profile"],
61
+ });
62
+ }
63
+
64
+ // Authorize - immediately redirect back with code
65
+ if (url.pathname === "/authorize") {
66
+ const redirectUri = url.searchParams.get("redirect_uri")!;
67
+ const state = url.searchParams.get("state") ?? "";
68
+ const sep = redirectUri.includes("?") ? "&" : "?";
69
+ return Response.redirect(
70
+ `${redirectUri}${sep}code=${VALID_CODE}&state=${state}`,
71
+ 302,
72
+ );
73
+ }
74
+
75
+ // Token exchange
76
+ if (url.pathname === "/token" && req.method === "POST") {
77
+ return Response.json({
78
+ access_token: ACCESS_TOKEN,
79
+ token_type: "bearer",
80
+ expires_in: 3600,
81
+ scope: "openid email profile",
82
+ id_token: "fake.id.token",
83
+ });
84
+ }
85
+
86
+ // UserInfo
87
+ if (url.pathname === "/userinfo") {
88
+ const auth = req.headers.get("authorization");
89
+ if (auth !== `Bearer ${ACCESS_TOKEN}`) {
90
+ return new Response("Unauthorized", { status: 401 });
91
+ }
92
+ return Response.json({ ok: true, ...TEST_USER });
93
+ }
94
+
95
+ // Also support Slack-style openid.connect.userInfo
96
+ if (url.pathname === "/api/openid.connect.userInfo") {
97
+ return Response.json({ ok: true, ...TEST_USER });
98
+ }
99
+
100
+ // JWKS (empty - we don't validate JWTs in tests)
101
+ if (url.pathname === "/jwks") {
102
+ return Response.json({ keys: [] });
103
+ }
104
+
105
+ return new Response("Not found", { status: 404 });
106
+ },
107
+ });
108
+
109
+ const base = `http://localhost:${server.port}`;
110
+
111
+ return {
112
+ url: base,
113
+ port: server.port as number,
114
+ issuer: base,
115
+ clientId: TEST_CLIENT_ID,
116
+ clientSecret: TEST_CLIENT_SECRET,
117
+ testUser: TEST_USER,
118
+ accessToken: ACCESS_TOKEN,
119
+ stop: async () => {
120
+ server.stop();
121
+ },
122
+ };
123
+ }
package/src/types.ts CHANGED
@@ -4,6 +4,15 @@
4
4
  * Defines the fundamental types for agent definitions, tools, and contexts.
5
5
  */
6
6
 
7
+ import type { EventCallback, EventType } from "./events.js";
8
+
9
+ /** Internal listener entry stored on agents/tools */
10
+ export interface ListenerEntry {
11
+ eventType: EventType;
12
+ callback: EventCallback<EventType>;
13
+ toolScope?: string;
14
+ }
15
+
7
16
  // ============================================
8
17
  // JSON Schema
9
18
  // ============================================
@@ -28,7 +37,6 @@ export type JsonSchema = {
28
37
  [key: string]: unknown;
29
38
  };
30
39
 
31
-
32
40
  // ============================================
33
41
  // Integration Config
34
42
  // ============================================
@@ -67,19 +75,32 @@ export interface IntegrationMethodContext extends ToolContext {
67
75
  */
68
76
  export interface IntegrationMethods {
69
77
  /** Configure/initialize the integration (e.g., add a DB connection, set API key) */
70
- setup(params: Record<string, unknown>, ctx: IntegrationMethodContext): Promise<IntegrationMethodResult>;
78
+ setup(
79
+ params: Record<string, unknown>,
80
+ ctx: IntegrationMethodContext,
81
+ ): Promise<IntegrationMethodResult>;
71
82
  /** List configured instances (e.g., list DB connections, list repos) */
72
- list(params: Record<string, unknown>, ctx: IntegrationMethodContext): Promise<IntegrationMethodResult>;
83
+ list(
84
+ params: Record<string, unknown>,
85
+ ctx: IntegrationMethodContext,
86
+ ): Promise<IntegrationMethodResult>;
73
87
  /** Establish connection or authenticate (e.g., test DB connectivity, OAuth flow) */
74
- connect(params: Record<string, unknown>, ctx: IntegrationMethodContext): Promise<IntegrationMethodResult>;
88
+ connect(
89
+ params: Record<string, unknown>,
90
+ ctx: IntegrationMethodContext,
91
+ ): Promise<IntegrationMethodResult>;
75
92
  /** Get details of a specific instance */
76
- get(params: Record<string, unknown>, ctx: IntegrationMethodContext): Promise<IntegrationMethodResult>;
93
+ get(
94
+ params: Record<string, unknown>,
95
+ ctx: IntegrationMethodContext,
96
+ ): Promise<IntegrationMethodResult>;
77
97
  /** Modify an existing configuration */
78
- update(params: Record<string, unknown>, ctx: IntegrationMethodContext): Promise<IntegrationMethodResult>;
98
+ update(
99
+ params: Record<string, unknown>,
100
+ ctx: IntegrationMethodContext,
101
+ ): Promise<IntegrationMethodResult>;
79
102
  }
80
103
 
81
-
82
-
83
104
  /** Hooks for agents that implement the integrations interface. */
84
105
  export interface IntegrationHooks {
85
106
  /** Provider metadata */
@@ -90,17 +111,35 @@ export interface IntegrationHooks {
90
111
  description?: string;
91
112
 
92
113
  /** Set up this integration (discover, configure, establish trust) */
93
- setup?(params: Record<string, unknown>, ctx: ToolContext): Promise<IntegrationMethodResult>;
114
+ setup?(
115
+ params: Record<string, unknown>,
116
+ ctx: ToolContext,
117
+ ): Promise<IntegrationMethodResult>;
94
118
  /** Connect a user to this integration (OAuth, identity linking) */
95
- connect?(params: Record<string, unknown>, ctx: ToolContext): Promise<IntegrationMethodResult>;
119
+ connect?(
120
+ params: Record<string, unknown>,
121
+ ctx: ToolContext,
122
+ ): Promise<IntegrationMethodResult>;
96
123
  /** Discover available instances of this integration */
97
- discover?(params: Record<string, unknown>, ctx: ToolContext): Promise<IntegrationMethodResult>;
124
+ discover?(
125
+ params: Record<string, unknown>,
126
+ ctx: ToolContext,
127
+ ): Promise<IntegrationMethodResult>;
98
128
  /** List connected instances */
99
- list?(params: Record<string, unknown>, ctx: ToolContext): Promise<IntegrationMethodResult>;
129
+ list?(
130
+ params: Record<string, unknown>,
131
+ ctx: ToolContext,
132
+ ): Promise<IntegrationMethodResult>;
100
133
  /** Get details of a specific instance */
101
- get?(params: Record<string, unknown>, ctx: ToolContext): Promise<IntegrationMethodResult>;
134
+ get?(
135
+ params: Record<string, unknown>,
136
+ ctx: ToolContext,
137
+ ): Promise<IntegrationMethodResult>;
102
138
  /** Update an existing instance config */
103
- update?(params: Record<string, unknown>, ctx: ToolContext): Promise<IntegrationMethodResult>;
139
+ update?(
140
+ params: Record<string, unknown>,
141
+ ctx: ToolContext,
142
+ ): Promise<IntegrationMethodResult>;
104
143
  }
105
144
  export interface IntegrationConfig {
106
145
  /** Provider identifier (e.g., "databases", "slack", "github") */
@@ -163,11 +202,11 @@ export interface AgentConfig {
163
202
  modelParams?: {
164
203
  maxTokens?: number;
165
204
  temperature?: number;
166
- /** Agent refs (paths to other agents this agent can call) */
167
- refs?: Record<string, { description?: string }>;
205
+ /** Agent refs (paths to other agents this agent can call) */
206
+ refs?: Record<string, { description?: string }>;
168
207
 
169
- /** Tools to expose publicly (by name) */
170
- public?: { tools?: string[] };
208
+ /** Tools to expose publicly (by name) */
209
+ public?: { tools?: string[] };
171
210
  [key: string]: unknown;
172
211
  };
173
212
 
@@ -487,6 +526,12 @@ export interface ToolDefinition<
487
526
  * When set, rendered directly into the agent's system prompt.
488
527
  */
489
528
  doc?: string;
529
+
530
+ /**
531
+ * Internal: event listeners registered via tool.on().
532
+ * Collected by the registry on registration.
533
+ */
534
+ _listeners?: ListenerEntry[];
490
535
  }
491
536
 
492
537
  /**
@@ -542,6 +587,12 @@ export interface AgentDefinition<TContext extends ToolContext = ToolContext> {
542
587
  * Called once to load runtime hooks exported from the agent's entrypoint module.
543
588
  */
544
589
  loadListeners?: () => Promise<unknown>;
590
+
591
+ /**
592
+ * Internal: event listeners registered via agent.on().
593
+ * Collected by the registry on registration.
594
+ */
595
+ _listeners?: ListenerEntry[];
545
596
  }
546
597
 
547
598
  // ============================================
@@ -641,14 +692,25 @@ export interface CallAgentDescribeToolsResponse {
641
692
  tools: ToolSchema[];
642
693
  }
643
694
 
695
+ /** A resolved agent ref with its discovered tools */
696
+ export interface AgentRefEntry {
697
+ key: string;
698
+ path: string;
699
+ description: string;
700
+ tools: ToolSchema[];
701
+ }
702
+
644
703
  /** Success response for load */
645
704
  export interface CallAgentLoadResponse {
646
705
  success: true;
647
706
  result: {
648
707
  path: string;
649
708
  entrypoint: string;
709
+ systemPrompt: string;
710
+ contextMessages: string[];
650
711
  config: AgentConfig | undefined;
651
712
  tools: ToolSchema[];
713
+ agentRefs: AgentRefEntry[];
652
714
  };
653
715
  }
654
716