@slashfi/agents-sdk 0.1.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/LICENSE +21 -0
- package/README.md +274 -0
- package/dist/auth.d.ts +109 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +329 -0
- package/dist/auth.js.map +1 -0
- package/dist/build.d.ts +68 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +159 -0
- package/dist/build.js.map +1 -0
- package/dist/define.d.ts +87 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +71 -0
- package/dist/define.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +48 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +274 -0
- package/dist/registry.js.map +1 -0
- package/dist/server.d.ts +66 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +308 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +389 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
- package/src/auth.ts +493 -0
- package/src/build.ts +238 -0
- package/src/define.ts +153 -0
- package/src/index.ts +111 -0
- package/src/registry.ts +403 -0
- package/src/server.ts +460 -0
- package/src/types.ts +524 -0
package/src/registry.ts
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Registry Implementation
|
|
3
|
+
*
|
|
4
|
+
* Manages registered agents and handles callAgent requests.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
AgentAction,
|
|
9
|
+
AgentDefinition,
|
|
10
|
+
CallAgentDescribeToolsResponse,
|
|
11
|
+
CallAgentErrorResponse,
|
|
12
|
+
CallAgentExecuteToolResponse,
|
|
13
|
+
CallAgentLearnResponse,
|
|
14
|
+
CallAgentLoadResponse,
|
|
15
|
+
CallAgentRequest,
|
|
16
|
+
CallAgentResponse,
|
|
17
|
+
ToolContext,
|
|
18
|
+
ToolDefinition,
|
|
19
|
+
ToolSchema,
|
|
20
|
+
Visibility,
|
|
21
|
+
} from "./types.js";
|
|
22
|
+
|
|
23
|
+
/** Default supported actions if not specified */
|
|
24
|
+
const DEFAULT_SUPPORTED_ACTIONS: AgentAction[] = [
|
|
25
|
+
"execute_tool",
|
|
26
|
+
"describe_tools",
|
|
27
|
+
"load",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
// ============================================
|
|
31
|
+
// Agent Registry Interface
|
|
32
|
+
// ============================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Options for creating an agent registry.
|
|
36
|
+
*/
|
|
37
|
+
export interface AgentRegistryOptions {
|
|
38
|
+
/** Default visibility for agents without explicit visibility */
|
|
39
|
+
defaultVisibility?: Visibility;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Agent registry interface.
|
|
44
|
+
*/
|
|
45
|
+
export interface AgentRegistry {
|
|
46
|
+
/** Register an agent */
|
|
47
|
+
register(agent: AgentDefinition): void;
|
|
48
|
+
|
|
49
|
+
/** Get an agent by path */
|
|
50
|
+
get(path: string): AgentDefinition | undefined;
|
|
51
|
+
|
|
52
|
+
/** Check if an agent exists */
|
|
53
|
+
has(path: string): boolean;
|
|
54
|
+
|
|
55
|
+
/** List all registered agents */
|
|
56
|
+
list(): AgentDefinition[];
|
|
57
|
+
|
|
58
|
+
/** List all registered agent paths */
|
|
59
|
+
listPaths(): string[];
|
|
60
|
+
|
|
61
|
+
/** Call an agent (execute action) */
|
|
62
|
+
call(request: CallAgentRequest): Promise<CallAgentResponse>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ============================================
|
|
66
|
+
// Create Registry
|
|
67
|
+
// ============================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Create an agent registry.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const registry = createAgentRegistry();
|
|
75
|
+
* registry.register(myAgent);
|
|
76
|
+
*
|
|
77
|
+
* const result = await registry.call({
|
|
78
|
+
* action: 'execute_tool',
|
|
79
|
+
* path: '@my-agent',
|
|
80
|
+
* tool: 'greet',
|
|
81
|
+
* params: { name: 'World' }
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export function createAgentRegistry(
|
|
86
|
+
options: AgentRegistryOptions = {},
|
|
87
|
+
): AgentRegistry {
|
|
88
|
+
const { defaultVisibility = "internal" } = options;
|
|
89
|
+
const agents = new Map<string, AgentDefinition>();
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Check if agent supports the requested action.
|
|
93
|
+
*/
|
|
94
|
+
function checkActionSupported(
|
|
95
|
+
agent: AgentDefinition,
|
|
96
|
+
action: AgentAction,
|
|
97
|
+
): boolean {
|
|
98
|
+
const supported =
|
|
99
|
+
agent.config?.supportedActions ?? DEFAULT_SUPPORTED_ACTIONS;
|
|
100
|
+
return supported.includes(action);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Check if caller is allowed to access the agent.
|
|
105
|
+
*/
|
|
106
|
+
function checkAgentAccess(
|
|
107
|
+
agent: AgentDefinition,
|
|
108
|
+
callerId?: string,
|
|
109
|
+
callerType?: string,
|
|
110
|
+
): boolean {
|
|
111
|
+
const visibility = agent.visibility ?? defaultVisibility;
|
|
112
|
+
|
|
113
|
+
// System callers can access everything
|
|
114
|
+
if (callerType === "system") return true;
|
|
115
|
+
|
|
116
|
+
// Check explicit allowlist first
|
|
117
|
+
if (agent.allowedCallers && callerId) {
|
|
118
|
+
if (agent.allowedCallers.includes(callerId)) return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Check visibility
|
|
122
|
+
switch (visibility) {
|
|
123
|
+
case "public":
|
|
124
|
+
return true;
|
|
125
|
+
case "internal":
|
|
126
|
+
// Authenticated callers (agents or users with a callerId) can access
|
|
127
|
+
return (
|
|
128
|
+
callerType === "agent" || (callerType != null && callerId != null)
|
|
129
|
+
);
|
|
130
|
+
case "private":
|
|
131
|
+
// Only self can access
|
|
132
|
+
return callerId === agent.path;
|
|
133
|
+
default:
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Check if caller is allowed to use a tool.
|
|
140
|
+
*/
|
|
141
|
+
function checkToolAccess(
|
|
142
|
+
agent: AgentDefinition,
|
|
143
|
+
toolName: string,
|
|
144
|
+
callerId?: string,
|
|
145
|
+
callerType?: string,
|
|
146
|
+
): boolean {
|
|
147
|
+
const tool = agent.tools.find((t: ToolDefinition) => t.name === toolName);
|
|
148
|
+
if (!tool) return false;
|
|
149
|
+
|
|
150
|
+
const visibility = tool.visibility ?? "public";
|
|
151
|
+
|
|
152
|
+
// System callers can access everything
|
|
153
|
+
if (callerType === "system") return true;
|
|
154
|
+
|
|
155
|
+
// Check explicit allowlist first
|
|
156
|
+
if (tool.allowedCallers && callerId) {
|
|
157
|
+
if (tool.allowedCallers.includes(callerId)) return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Check visibility
|
|
161
|
+
switch (visibility) {
|
|
162
|
+
case "public":
|
|
163
|
+
return true;
|
|
164
|
+
case "internal":
|
|
165
|
+
return (
|
|
166
|
+
callerType === "agent" || (callerType != null && callerId != null)
|
|
167
|
+
);
|
|
168
|
+
case "private":
|
|
169
|
+
return callerId === agent.path;
|
|
170
|
+
default:
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const registry: AgentRegistry = {
|
|
176
|
+
register(agent: AgentDefinition): void {
|
|
177
|
+
agents.set(agent.path, agent);
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
get(path: string): AgentDefinition | undefined {
|
|
181
|
+
return agents.get(path);
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
has(path: string): boolean {
|
|
185
|
+
return agents.has(path);
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
list(): AgentDefinition[] {
|
|
189
|
+
return Array.from(agents.values());
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
listPaths(): string[] {
|
|
193
|
+
return Array.from(agents.keys());
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
async call(request: CallAgentRequest): Promise<CallAgentResponse> {
|
|
197
|
+
const agent = agents.get(request.path);
|
|
198
|
+
|
|
199
|
+
if (!agent) {
|
|
200
|
+
return {
|
|
201
|
+
success: false,
|
|
202
|
+
error: `Agent not found: ${request.path}`,
|
|
203
|
+
code: "AGENT_NOT_FOUND",
|
|
204
|
+
} as CallAgentErrorResponse;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Check agent access
|
|
208
|
+
if (!checkAgentAccess(agent, request.callerId, request.callerType)) {
|
|
209
|
+
return {
|
|
210
|
+
success: false,
|
|
211
|
+
error: `Access denied to agent: ${request.path}`,
|
|
212
|
+
code: "ACCESS_DENIED",
|
|
213
|
+
} as CallAgentErrorResponse;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Check action is supported
|
|
217
|
+
if (!checkActionSupported(agent, request.action)) {
|
|
218
|
+
const supported =
|
|
219
|
+
agent.config?.supportedActions ?? DEFAULT_SUPPORTED_ACTIONS;
|
|
220
|
+
return {
|
|
221
|
+
success: false,
|
|
222
|
+
error: `Action '${request.action}' not supported by agent. Supported: ${supported.join(", ")}`,
|
|
223
|
+
code: "ACTION_NOT_SUPPORTED",
|
|
224
|
+
} as CallAgentErrorResponse;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
switch (request.action) {
|
|
228
|
+
case "invoke":
|
|
229
|
+
case "ask": {
|
|
230
|
+
// Get runtime if available
|
|
231
|
+
const runtime = agent.runtime?.();
|
|
232
|
+
|
|
233
|
+
// Call onInvoke hook if defined
|
|
234
|
+
if (runtime?.onInvoke) {
|
|
235
|
+
await runtime.onInvoke({
|
|
236
|
+
tenantId: "default",
|
|
237
|
+
agentPath: request.path,
|
|
238
|
+
prompt: request.prompt,
|
|
239
|
+
sessionId: request.sessionId,
|
|
240
|
+
callerId: request.callerId ?? "unknown",
|
|
241
|
+
callerType: request.callerType ?? "system",
|
|
242
|
+
metadata: request.metadata,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// These actions require an LLM runtime which this SDK doesn't provide
|
|
247
|
+
// Users can implement their own invoke/ask handlers or use a full runtime
|
|
248
|
+
return {
|
|
249
|
+
success: false,
|
|
250
|
+
error: `Action '${request.action}' requires an LLM runtime. Use execute_tool for direct tool calls.`,
|
|
251
|
+
code: "RUNTIME_REQUIRED",
|
|
252
|
+
} as CallAgentErrorResponse;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
case "execute_tool": {
|
|
256
|
+
const tool = agent.tools.find(
|
|
257
|
+
(t: ToolDefinition) => t.name === request.tool,
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
if (!tool) {
|
|
261
|
+
return {
|
|
262
|
+
success: false,
|
|
263
|
+
error: `Tool not found: ${request.tool}`,
|
|
264
|
+
code: "TOOL_NOT_FOUND",
|
|
265
|
+
} as CallAgentErrorResponse;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Check tool access
|
|
269
|
+
if (
|
|
270
|
+
!checkToolAccess(
|
|
271
|
+
agent,
|
|
272
|
+
request.tool,
|
|
273
|
+
request.callerId,
|
|
274
|
+
request.callerType,
|
|
275
|
+
)
|
|
276
|
+
) {
|
|
277
|
+
return {
|
|
278
|
+
success: false,
|
|
279
|
+
error: `Access denied to tool: ${request.tool}`,
|
|
280
|
+
code: "ACCESS_DENIED",
|
|
281
|
+
} as CallAgentErrorResponse;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const ctx: ToolContext = {
|
|
285
|
+
tenantId: "default",
|
|
286
|
+
agentPath: agent.path,
|
|
287
|
+
callerId: request.callerId ?? "unknown",
|
|
288
|
+
callerType: request.callerType ?? "system",
|
|
289
|
+
metadata: request.metadata,
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
const result = await tool.execute(request.params, ctx);
|
|
294
|
+
return {
|
|
295
|
+
success: true,
|
|
296
|
+
result,
|
|
297
|
+
} as CallAgentExecuteToolResponse;
|
|
298
|
+
} catch (err) {
|
|
299
|
+
return {
|
|
300
|
+
success: false,
|
|
301
|
+
error: err instanceof Error ? err.message : String(err),
|
|
302
|
+
code: "TOOL_EXECUTION_ERROR",
|
|
303
|
+
} as CallAgentErrorResponse;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
case "describe_tools": {
|
|
308
|
+
const toolSchemas: ToolSchema[] = agent.tools
|
|
309
|
+
.filter((t: ToolDefinition) =>
|
|
310
|
+
checkToolAccess(
|
|
311
|
+
agent,
|
|
312
|
+
t.name,
|
|
313
|
+
request.callerId,
|
|
314
|
+
request.callerType,
|
|
315
|
+
),
|
|
316
|
+
)
|
|
317
|
+
.filter((t: ToolDefinition) =>
|
|
318
|
+
request.tools ? request.tools.includes(t.name) : true,
|
|
319
|
+
)
|
|
320
|
+
.map((t: ToolDefinition) => ({
|
|
321
|
+
name: t.name,
|
|
322
|
+
description: t.description,
|
|
323
|
+
inputSchema: t.inputSchema,
|
|
324
|
+
...(t.outputSchema && { outputSchema: t.outputSchema }),
|
|
325
|
+
}));
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
success: true,
|
|
329
|
+
tools: toolSchemas,
|
|
330
|
+
} as CallAgentDescribeToolsResponse;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
case "load": {
|
|
334
|
+
const toolSchemas: ToolSchema[] = agent.tools
|
|
335
|
+
.filter((t: ToolDefinition) =>
|
|
336
|
+
checkToolAccess(
|
|
337
|
+
agent,
|
|
338
|
+
t.name,
|
|
339
|
+
request.callerId,
|
|
340
|
+
request.callerType,
|
|
341
|
+
),
|
|
342
|
+
)
|
|
343
|
+
.map((t: ToolDefinition) => ({
|
|
344
|
+
name: t.name,
|
|
345
|
+
description: t.description,
|
|
346
|
+
inputSchema: t.inputSchema,
|
|
347
|
+
...(t.outputSchema && { outputSchema: t.outputSchema }),
|
|
348
|
+
}));
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
success: true,
|
|
352
|
+
result: {
|
|
353
|
+
path: agent.path,
|
|
354
|
+
entrypoint: agent.entrypoint,
|
|
355
|
+
config: agent.config,
|
|
356
|
+
tools: toolSchemas,
|
|
357
|
+
},
|
|
358
|
+
} as CallAgentLoadResponse;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
case "learn": {
|
|
362
|
+
// Get runtime if available
|
|
363
|
+
const runtime = agent.runtime?.();
|
|
364
|
+
|
|
365
|
+
// Call onLearn hook if defined
|
|
366
|
+
if (runtime?.onLearn) {
|
|
367
|
+
await runtime.onLearn({
|
|
368
|
+
tenantId: "default",
|
|
369
|
+
agentPath: request.path,
|
|
370
|
+
content: request.content,
|
|
371
|
+
scope: request.scope ?? "session",
|
|
372
|
+
category: request.category,
|
|
373
|
+
callerId: request.callerId ?? "unknown",
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
success: true,
|
|
378
|
+
action: "stored",
|
|
379
|
+
} as CallAgentLearnResponse;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// No runtime or no onLearn hook - ignore
|
|
383
|
+
return {
|
|
384
|
+
success: true,
|
|
385
|
+
action: "ignored",
|
|
386
|
+
} as CallAgentLearnResponse;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
default: {
|
|
390
|
+
// TypeScript exhaustiveness check
|
|
391
|
+
const _exhaustive: never = request;
|
|
392
|
+
return {
|
|
393
|
+
success: false,
|
|
394
|
+
error: `Unknown action: ${(_exhaustive as CallAgentRequest).action}`,
|
|
395
|
+
code: "UNKNOWN_ACTION",
|
|
396
|
+
} as CallAgentErrorResponse;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
return registry;
|
|
403
|
+
}
|