@slashfi/agents-sdk 0.16.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 +15 -7
  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 +5 -0
  55. package/dist/registry.d.ts.map +1 -1
  56. package/dist/registry.js +76 -4
  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 +17 -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 +89 -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 +115 -9
  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 +69 -18
package/src/registry.ts CHANGED
@@ -5,6 +5,12 @@
5
5
  */
6
6
 
7
7
  import { dirname, resolve } from "node:path";
8
+ import type {
9
+ AgentEvent,
10
+ EventCallback,
11
+ EventType,
12
+ } from "./events.js";
13
+ import { createEventBus } from "./events.js";
8
14
  import type {
9
15
  AgentAction,
10
16
  AgentDefinition,
@@ -41,8 +47,15 @@ const DEFAULT_SUPPORTED_ACTIONS: AgentAction[] = [
41
47
  */
42
48
  export interface RegistryMiddleware {
43
49
  load?: (
44
- defaultFn: (agent: AgentDefinition, request: CallAgentLoadRequest) => Promise<CallAgentLoadResponse>,
45
- ctx: { agent: AgentDefinition; request: CallAgentLoadRequest; registry: AgentRegistry },
50
+ defaultFn: (
51
+ agent: AgentDefinition,
52
+ request: CallAgentLoadRequest,
53
+ ) => Promise<CallAgentLoadResponse>,
54
+ ctx: {
55
+ agent: AgentDefinition;
56
+ request: CallAgentLoadRequest;
57
+ registry: AgentRegistry;
58
+ },
46
59
  ) => Promise<CallAgentLoadResponse>;
47
60
  }
48
61
 
@@ -79,6 +92,12 @@ export interface AgentRegistry {
79
92
 
80
93
  /** Call an agent (execute action) */
81
94
  call(request: CallAgentRequest): Promise<CallAgentResponse>;
95
+
96
+ /** Register an event listener (global scope — fires for all agents) */
97
+ on<T extends EventType>(eventType: T, callback: EventCallback<T>): void;
98
+
99
+ /** Emit an event to all listeners. Used by the runtime to push lifecycle events. */
100
+ emit(event: AgentEvent): Promise<void>;
82
101
  }
83
102
 
84
103
  // ============================================
@@ -105,13 +124,16 @@ export interface AgentRegistry {
105
124
  * Factory function that enriches the base ToolContext with application-specific data.
106
125
  * Called before every tool execution.
107
126
  */
108
- export type ContextFactory = (baseCtx: import("./types.js").ToolContext) => import("./types.js").ToolContext;
127
+ export type ContextFactory = (
128
+ baseCtx: import("./types.js").ToolContext,
129
+ ) => import("./types.js").ToolContext;
109
130
 
110
131
  export function createAgentRegistry(
111
132
  options: AgentRegistryOptions = {},
112
133
  ): AgentRegistry {
113
134
  const { defaultVisibility = "internal" } = options;
114
135
  const agents = new Map<string, AgentDefinition>();
136
+ const eventBus = createEventBus();
115
137
 
116
138
  /**
117
139
  * Check if agent supports the requested action.
@@ -268,7 +290,12 @@ export function createAgentRegistry(
268
290
  const refAgent = agents.get(refPath);
269
291
  const allTools = (refAgent?.tools ?? [])
270
292
  .filter((t: ToolDefinition) =>
271
- checkToolAccess(refAgent!, t.name, request.callerId, request.callerType),
293
+ checkToolAccess(
294
+ refAgent!,
295
+ t.name,
296
+ request.callerId,
297
+ request.callerType,
298
+ ),
272
299
  )
273
300
  .map((t: ToolDefinition) => ({
274
301
  name: t.name,
@@ -289,7 +316,8 @@ export function createAgentRegistry(
289
316
  }
290
317
  }
291
318
 
292
- const systemPrompt = agent.entrypoint + buildToolsSection(toolSchemas, agentRefs);
319
+ const systemPrompt =
320
+ agent.entrypoint + buildToolsSection(toolSchemas, agentRefs);
293
321
 
294
322
  return {
295
323
  success: true,
@@ -308,6 +336,28 @@ export function createAgentRegistry(
308
336
  const registry: AgentRegistry = {
309
337
  register(agent: AgentDefinition): void {
310
338
  agents.set(agent.path, agent);
339
+
340
+ // Collect agent-level listeners into the bus
341
+ if (agent._listeners) {
342
+ for (const entry of agent._listeners) {
343
+ eventBus._onScoped(entry.eventType, entry.callback, {
344
+ agentPath: agent.path,
345
+ toolName: entry.toolScope,
346
+ });
347
+ }
348
+ }
349
+
350
+ // Collect tool-level listeners into the bus
351
+ for (const tool of agent.tools) {
352
+ if (tool._listeners) {
353
+ for (const entry of tool._listeners) {
354
+ eventBus._onScoped(entry.eventType, entry.callback, {
355
+ agentPath: agent.path,
356
+ toolName: tool.name,
357
+ });
358
+ }
359
+ }
360
+ }
311
361
  },
312
362
 
313
363
  get(path: string): AgentDefinition | undefined {
@@ -326,6 +376,14 @@ export function createAgentRegistry(
326
376
  return Array.from(agents.keys());
327
377
  },
328
378
 
379
+ on<T extends EventType>(eventType: T, callback: EventCallback<T>): void {
380
+ eventBus.on(eventType, callback);
381
+ },
382
+
383
+ async emit(event: AgentEvent): Promise<void> {
384
+ await eventBus.emit(event);
385
+ },
386
+
329
387
  async call(request: CallAgentRequest): Promise<CallAgentResponse> {
330
388
  const agent = agents.get(request.path);
331
389
 
@@ -434,15 +492,59 @@ export function createAgentRegistry(
434
492
  error: `Tool ${request.tool} has no execute function`,
435
493
  } as CallAgentErrorResponse;
436
494
  }
437
- const result = await tool.execute(request.params, ctx);
495
+
496
+ // Emit tool/call before execution
497
+ const startMs = Date.now();
498
+ await eventBus.emit({
499
+ type: "tool/call",
500
+ agentPath: agent.path,
501
+ tool: request.tool!,
502
+ params: request.params,
503
+ timestamp: startMs,
504
+ });
505
+
506
+ let result: unknown;
507
+ try {
508
+ result = await tool.execute(request.params, ctx);
509
+ } catch (err) {
510
+ // Emit tool/error on failure
511
+ await eventBus.emit({
512
+ type: "tool/error",
513
+ agentPath: agent.path,
514
+ tool: request.tool!,
515
+ params: request.params,
516
+ error: err,
517
+ durationMs: Date.now() - startMs,
518
+ timestamp: Date.now(),
519
+ }).catch(() => {}); // don't let emit error mask tool error
520
+
521
+ return {
522
+ success: false,
523
+ error: err instanceof Error ? err.message : String(err),
524
+ code: "TOOL_EXECUTION_ERROR",
525
+ } as CallAgentErrorResponse;
526
+ }
527
+
528
+ // Emit tool/result after success
529
+ await eventBus.emit({
530
+ type: "tool/result",
531
+ agentPath: agent.path,
532
+ tool: request.tool!,
533
+ params: request.params,
534
+ result,
535
+ durationMs: Date.now() - startMs,
536
+ timestamp: Date.now(),
537
+ });
538
+
438
539
  return {
439
540
  success: true,
440
541
  result,
441
542
  } as CallAgentExecuteToolResponse;
442
- } catch (err) {
543
+ } catch (outerErr) {
544
+ // Catch-all for unexpected errors (e.g., emit failures)
443
545
  return {
444
546
  success: false,
445
- error: err instanceof Error ? err.message : String(err),
547
+ error: outerErr instanceof Error ? outerErr.message : String(outerErr),
446
548
  code: "TOOL_EXECUTION_ERROR",
447
549
  } as CallAgentErrorResponse;
448
550
  }
@@ -476,7 +578,11 @@ export function createAgentRegistry(
476
578
 
477
579
  case "load": {
478
580
  if (options.middleware?.load) {
479
- return options.middleware.load(defaultLoad, { agent, request, registry });
581
+ return options.middleware.load(defaultLoad, {
582
+ agent,
583
+ request,
584
+ registry,
585
+ });
480
586
  }
481
587
  return defaultLoad(agent, request);
482
588
  }
@@ -44,7 +44,8 @@ export const pendingCollections = new Map<string, PendingCollection>();
44
44
 
45
45
  /** Generate a random one-time token for secret collection */
46
46
  export function generateCollectionToken(): string {
47
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
47
+ const chars =
48
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
48
49
  let token = "";
49
50
  for (let i = 0; i < 48; i++) {
50
51
  token += chars[Math.floor(Math.random() * chars.length)];