@slashfi/agents-sdk 0.22.0 → 0.23.1
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/callback/index.d.ts +90 -0
- package/dist/callback/index.d.ts.map +1 -0
- package/dist/callback/index.js +70 -0
- package/dist/callback/index.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/pack.d.ts.map +1 -1
- package/dist/pack.js +4 -1
- package/dist/pack.js.map +1 -1
- package/dist/registry.d.ts +13 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +78 -3
- package/dist/registry.js.map +1 -1
- package/dist/validate.d.ts +156 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +79 -0
- package/dist/validate.js.map +1 -0
- package/package.json +3 -2
- package/src/adk.ts +0 -0
- package/src/callback/index.ts +172 -0
- package/src/index.ts +30 -1
- package/src/pack.ts +5 -6
- package/src/registry.ts +109 -18
- package/src/validate.ts +93 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for SerializedAgentDefinition.
|
|
3
|
+
*
|
|
4
|
+
* Validates definition.json files at runtime — JSON imports have no type safety,
|
|
5
|
+
* so this catches malformed definitions before they hit the registry.
|
|
6
|
+
*
|
|
7
|
+
* Used in:
|
|
8
|
+
* - registry.register() — validate on ingest
|
|
9
|
+
* - adk pack — validate after introspection
|
|
10
|
+
* - adk publish — validate before shipping
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
export declare const SerializedToolSchema: z.ZodObject<{
|
|
14
|
+
name: z.ZodString;
|
|
15
|
+
description: z.ZodString;
|
|
16
|
+
inputSchema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
17
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
description: string;
|
|
20
|
+
name: string;
|
|
21
|
+
inputSchema: Record<string, unknown>;
|
|
22
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
23
|
+
}, {
|
|
24
|
+
description: string;
|
|
25
|
+
name: string;
|
|
26
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
27
|
+
inputSchema?: Record<string, unknown> | undefined;
|
|
28
|
+
}>;
|
|
29
|
+
export declare const SerializedAgentDefinitionSchema: z.ZodObject<{
|
|
30
|
+
path: z.ZodString;
|
|
31
|
+
name: z.ZodString;
|
|
32
|
+
description: z.ZodDefault<z.ZodString>;
|
|
33
|
+
version: z.ZodDefault<z.ZodString>;
|
|
34
|
+
visibility: z.ZodDefault<z.ZodEnum<["public", "private"]>>;
|
|
35
|
+
auth: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
36
|
+
serverSource: z.ZodOptional<z.ZodString>;
|
|
37
|
+
serverInfo: z.ZodOptional<z.ZodObject<{
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
version: z.ZodString;
|
|
40
|
+
}, "strip", z.ZodTypeAny, {
|
|
41
|
+
name: string;
|
|
42
|
+
version: string;
|
|
43
|
+
}, {
|
|
44
|
+
name: string;
|
|
45
|
+
version: string;
|
|
46
|
+
}>>;
|
|
47
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
48
|
+
name: z.ZodString;
|
|
49
|
+
description: z.ZodString;
|
|
50
|
+
inputSchema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
51
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
52
|
+
}, "strip", z.ZodTypeAny, {
|
|
53
|
+
description: string;
|
|
54
|
+
name: string;
|
|
55
|
+
inputSchema: Record<string, unknown>;
|
|
56
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
description: string;
|
|
59
|
+
name: string;
|
|
60
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
61
|
+
inputSchema?: Record<string, unknown> | undefined;
|
|
62
|
+
}>, "many">;
|
|
63
|
+
generatedAt: z.ZodOptional<z.ZodString>;
|
|
64
|
+
sdkVersion: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
66
|
+
path: z.ZodString;
|
|
67
|
+
name: z.ZodString;
|
|
68
|
+
description: z.ZodDefault<z.ZodString>;
|
|
69
|
+
version: z.ZodDefault<z.ZodString>;
|
|
70
|
+
visibility: z.ZodDefault<z.ZodEnum<["public", "private"]>>;
|
|
71
|
+
auth: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
72
|
+
serverSource: z.ZodOptional<z.ZodString>;
|
|
73
|
+
serverInfo: z.ZodOptional<z.ZodObject<{
|
|
74
|
+
name: z.ZodString;
|
|
75
|
+
version: z.ZodString;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
name: string;
|
|
78
|
+
version: string;
|
|
79
|
+
}, {
|
|
80
|
+
name: string;
|
|
81
|
+
version: string;
|
|
82
|
+
}>>;
|
|
83
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
84
|
+
name: z.ZodString;
|
|
85
|
+
description: z.ZodString;
|
|
86
|
+
inputSchema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
87
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
88
|
+
}, "strip", z.ZodTypeAny, {
|
|
89
|
+
description: string;
|
|
90
|
+
name: string;
|
|
91
|
+
inputSchema: Record<string, unknown>;
|
|
92
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
93
|
+
}, {
|
|
94
|
+
description: string;
|
|
95
|
+
name: string;
|
|
96
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
97
|
+
inputSchema?: Record<string, unknown> | undefined;
|
|
98
|
+
}>, "many">;
|
|
99
|
+
generatedAt: z.ZodOptional<z.ZodString>;
|
|
100
|
+
sdkVersion: z.ZodOptional<z.ZodString>;
|
|
101
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
102
|
+
path: z.ZodString;
|
|
103
|
+
name: z.ZodString;
|
|
104
|
+
description: z.ZodDefault<z.ZodString>;
|
|
105
|
+
version: z.ZodDefault<z.ZodString>;
|
|
106
|
+
visibility: z.ZodDefault<z.ZodEnum<["public", "private"]>>;
|
|
107
|
+
auth: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
108
|
+
serverSource: z.ZodOptional<z.ZodString>;
|
|
109
|
+
serverInfo: z.ZodOptional<z.ZodObject<{
|
|
110
|
+
name: z.ZodString;
|
|
111
|
+
version: z.ZodString;
|
|
112
|
+
}, "strip", z.ZodTypeAny, {
|
|
113
|
+
name: string;
|
|
114
|
+
version: string;
|
|
115
|
+
}, {
|
|
116
|
+
name: string;
|
|
117
|
+
version: string;
|
|
118
|
+
}>>;
|
|
119
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
120
|
+
name: z.ZodString;
|
|
121
|
+
description: z.ZodString;
|
|
122
|
+
inputSchema: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
123
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
124
|
+
}, "strip", z.ZodTypeAny, {
|
|
125
|
+
description: string;
|
|
126
|
+
name: string;
|
|
127
|
+
inputSchema: Record<string, unknown>;
|
|
128
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
129
|
+
}, {
|
|
130
|
+
description: string;
|
|
131
|
+
name: string;
|
|
132
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
133
|
+
inputSchema?: Record<string, unknown> | undefined;
|
|
134
|
+
}>, "many">;
|
|
135
|
+
generatedAt: z.ZodOptional<z.ZodString>;
|
|
136
|
+
sdkVersion: z.ZodOptional<z.ZodString>;
|
|
137
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
138
|
+
export type ValidationResult = {
|
|
139
|
+
ok: true;
|
|
140
|
+
definition: z.infer<typeof SerializedAgentDefinitionSchema>;
|
|
141
|
+
} | {
|
|
142
|
+
ok: false;
|
|
143
|
+
errors: string[];
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Validate a definition against the SerializedAgentDefinition schema.
|
|
147
|
+
*
|
|
148
|
+
* Returns either the validated definition or a list of human-readable errors.
|
|
149
|
+
*/
|
|
150
|
+
export declare function validateDefinition(input: unknown): ValidationResult;
|
|
151
|
+
/**
|
|
152
|
+
* Validate and throw if invalid.
|
|
153
|
+
* Use in register() and pack/publish where failure should be fatal.
|
|
154
|
+
*/
|
|
155
|
+
export declare function assertValidDefinition(input: unknown, context?: string): void;
|
|
156
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;EAO/B,CAAC;AAMH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAsB5B,CAAC;AAMjB,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAA;CAAE,GACzE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAUnE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAQ5E"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for SerializedAgentDefinition.
|
|
3
|
+
*
|
|
4
|
+
* Validates definition.json files at runtime — JSON imports have no type safety,
|
|
5
|
+
* so this catches malformed definitions before they hit the registry.
|
|
6
|
+
*
|
|
7
|
+
* Used in:
|
|
8
|
+
* - registry.register() — validate on ingest
|
|
9
|
+
* - adk pack — validate after introspection
|
|
10
|
+
* - adk publish — validate before shipping
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
// ============================================
|
|
14
|
+
// Tool Schema
|
|
15
|
+
// ============================================
|
|
16
|
+
export const SerializedToolSchema = z.object({
|
|
17
|
+
name: z.string().min(1, "Tool name is required"),
|
|
18
|
+
description: z.string(),
|
|
19
|
+
inputSchema: z
|
|
20
|
+
.record(z.unknown())
|
|
21
|
+
.default({ type: "object", properties: {} }),
|
|
22
|
+
outputSchema: z.record(z.unknown()).optional(),
|
|
23
|
+
});
|
|
24
|
+
// ============================================
|
|
25
|
+
// Agent Definition Schema
|
|
26
|
+
// ============================================
|
|
27
|
+
export const SerializedAgentDefinitionSchema = z
|
|
28
|
+
.object({
|
|
29
|
+
path: z.string().min(1, "Agent path is required"),
|
|
30
|
+
name: z.string().min(1, "Agent name is required"),
|
|
31
|
+
description: z.string().default(""),
|
|
32
|
+
version: z.string().default("1.0.0"),
|
|
33
|
+
visibility: z.enum(["public", "private"]).default("public"),
|
|
34
|
+
auth: z.record(z.unknown()).optional(),
|
|
35
|
+
serverSource: z.string().optional(),
|
|
36
|
+
serverInfo: z
|
|
37
|
+
.object({
|
|
38
|
+
name: z.string(),
|
|
39
|
+
version: z.string(),
|
|
40
|
+
})
|
|
41
|
+
.optional(),
|
|
42
|
+
tools: z
|
|
43
|
+
.array(SerializedToolSchema)
|
|
44
|
+
.min(1, "At least one tool is required"),
|
|
45
|
+
generatedAt: z.string().optional(),
|
|
46
|
+
sdkVersion: z.string().optional(),
|
|
47
|
+
// Allow additional fields (e.g., $defs from MCP introspection)
|
|
48
|
+
})
|
|
49
|
+
.passthrough();
|
|
50
|
+
/**
|
|
51
|
+
* Validate a definition against the SerializedAgentDefinition schema.
|
|
52
|
+
*
|
|
53
|
+
* Returns either the validated definition or a list of human-readable errors.
|
|
54
|
+
*/
|
|
55
|
+
export function validateDefinition(input) {
|
|
56
|
+
const result = SerializedAgentDefinitionSchema.safeParse(input);
|
|
57
|
+
if (result.success) {
|
|
58
|
+
return { ok: true, definition: result.data };
|
|
59
|
+
}
|
|
60
|
+
const errors = result.error.issues.map((issue) => {
|
|
61
|
+
const path = issue.path.length > 0 ? issue.path.join(".") : "root";
|
|
62
|
+
return `${path}: ${issue.message}`;
|
|
63
|
+
});
|
|
64
|
+
return { ok: false, errors };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Validate and throw if invalid.
|
|
68
|
+
* Use in register() and pack/publish where failure should be fatal.
|
|
69
|
+
*/
|
|
70
|
+
export function assertValidDefinition(input, context) {
|
|
71
|
+
const result = validateDefinition(input);
|
|
72
|
+
if (!result.ok) {
|
|
73
|
+
const prefix = context
|
|
74
|
+
? `Invalid definition (${context})`
|
|
75
|
+
: "Invalid definition";
|
|
76
|
+
throw new Error(`${prefix}:\n ${result.errors.join("\n ")}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slashfi/agents-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"author": "Slash Financial",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"types": "dist/index.d.ts",
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"cross-spawn": "^7.0.6",
|
|
62
|
-
"jose": "^6.2.2"
|
|
62
|
+
"jose": "^6.2.2",
|
|
63
|
+
"zod": "^3.23.0"
|
|
63
64
|
}
|
|
64
65
|
}
|
package/src/adk.ts
CHANGED
|
File without changes
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Callback — Deferred call_agent execution with triggers.
|
|
3
|
+
*
|
|
4
|
+
* An agent_callback is a call_agent command with an optional trigger.
|
|
5
|
+
* When the trigger fires (e.g., user submits a form), template references
|
|
6
|
+
* like {{trigger.variable_name}} are resolved with the trigger's values
|
|
7
|
+
* and the call_agent command is executed.
|
|
8
|
+
*
|
|
9
|
+
* This module provides the unopinionated contract:
|
|
10
|
+
* - Trigger schema (extensible discriminated union)
|
|
11
|
+
* - Template resolution
|
|
12
|
+
* - Store interface
|
|
13
|
+
* - Validation utilities
|
|
14
|
+
*
|
|
15
|
+
* No platform-specific code (no Slack, no CockroachDB, no Atlas).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Trigger Schema
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Base trigger type. Implementations extend this with specific trigger sources
|
|
24
|
+
* (e.g., slack_block_kit, webhook, timer).
|
|
25
|
+
*
|
|
26
|
+
* The `type` field discriminates between trigger sources.
|
|
27
|
+
* Additional fields are trigger-specific.
|
|
28
|
+
*/
|
|
29
|
+
export interface AgentCallbackTrigger {
|
|
30
|
+
type: string;
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Callback Status
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
export type AgentCallbackStatus =
|
|
39
|
+
| 'pending'
|
|
40
|
+
| 'completed'
|
|
41
|
+
| 'expired'
|
|
42
|
+
| 'cancelled';
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Callback Entry
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A stored agent_callback — a call_agent command waiting for its trigger to fire.
|
|
50
|
+
*/
|
|
51
|
+
export interface AgentCallbackEntry<TMetadata = Record<string, unknown>> {
|
|
52
|
+
id: string;
|
|
53
|
+
status: AgentCallbackStatus;
|
|
54
|
+
/** The call_agent command. Params may contain {{trigger.x}} templates. */
|
|
55
|
+
callback: Record<string, unknown>;
|
|
56
|
+
/** Trigger definition — how values are collected. */
|
|
57
|
+
trigger?: AgentCallbackTrigger;
|
|
58
|
+
/** Implementation-specific context (e.g., creator branch, user ID). */
|
|
59
|
+
metadata?: TMetadata;
|
|
60
|
+
/** Resolved values from the trigger, keyed by variable name. */
|
|
61
|
+
resolvedValues?: Record<string, string>;
|
|
62
|
+
/** Callback expires after this time. */
|
|
63
|
+
expiresAt?: Date;
|
|
64
|
+
createdAt: Date;
|
|
65
|
+
completedAt?: Date;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Create Options
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
|
|
72
|
+
export interface CreateAgentCallbackOptions<TMetadata = Record<string, unknown>> {
|
|
73
|
+
/** The call_agent command. May contain {{trigger.x}} template references in params. */
|
|
74
|
+
callback: Record<string, unknown>;
|
|
75
|
+
/** Trigger definition. */
|
|
76
|
+
trigger?: AgentCallbackTrigger;
|
|
77
|
+
/** Implementation-specific context. */
|
|
78
|
+
metadata?: TMetadata;
|
|
79
|
+
/** TTL in milliseconds (default: implementation-defined). */
|
|
80
|
+
ttlMs?: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Resolve Options
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
export interface ResolveAgentCallbackOptions {
|
|
88
|
+
/** The callback ID to resolve. */
|
|
89
|
+
id: string;
|
|
90
|
+
/** Values from the trigger source, keyed by variable name. */
|
|
91
|
+
values: Record<string, string>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Store Interface
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Agent Callback Store — persistence layer for deferred call_agent commands.
|
|
100
|
+
* Implementations can use any backing store (CockroachDB, SQLite, in-memory, etc.).
|
|
101
|
+
*/
|
|
102
|
+
export interface AgentCallbackStore<TMetadata = Record<string, unknown>> {
|
|
103
|
+
create(options: CreateAgentCallbackOptions<TMetadata>): Promise<string>;
|
|
104
|
+
get(id: string): Promise<AgentCallbackEntry<TMetadata> | null>;
|
|
105
|
+
resolve(options: ResolveAgentCallbackOptions): Promise<AgentCallbackEntry<TMetadata>>;
|
|
106
|
+
cancel(id: string): Promise<boolean>;
|
|
107
|
+
listPending(limit?: number): Promise<AgentCallbackEntry<TMetadata>[]>;
|
|
108
|
+
expireStale(): Promise<number>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Template Resolution
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Resolve {{trigger.variable}} references in an object tree.
|
|
117
|
+
* Scans all string values and replaces {{trigger.x}} with the
|
|
118
|
+
* corresponding value from triggerValues.
|
|
119
|
+
*
|
|
120
|
+
* Unresolved references are left as-is.
|
|
121
|
+
*/
|
|
122
|
+
export function resolveCallbackTemplates<T>(
|
|
123
|
+
obj: T,
|
|
124
|
+
triggerValues: Record<string, string>,
|
|
125
|
+
): T {
|
|
126
|
+
if (typeof obj === 'string') {
|
|
127
|
+
return obj.replace(/\{\{trigger\.(\w+)\}\}/g, (_match, varName: string) => {
|
|
128
|
+
return triggerValues[varName] ?? `{{trigger.${varName}}}`;
|
|
129
|
+
}) as T;
|
|
130
|
+
}
|
|
131
|
+
if (Array.isArray(obj)) {
|
|
132
|
+
return obj.map((item) => resolveCallbackTemplates(item, triggerValues)) as T;
|
|
133
|
+
}
|
|
134
|
+
if (obj !== null && typeof obj === 'object') {
|
|
135
|
+
const result: Record<string, unknown> = {};
|
|
136
|
+
for (const [key, val] of Object.entries(obj as Record<string, unknown>)) {
|
|
137
|
+
result[key] = resolveCallbackTemplates(val, triggerValues);
|
|
138
|
+
}
|
|
139
|
+
return result as T;
|
|
140
|
+
}
|
|
141
|
+
return obj;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Validate that all {{trigger.x}} references in a callback have
|
|
146
|
+
* corresponding variables in the provided set.
|
|
147
|
+
* Returns array of unresolved variable names, or empty if valid.
|
|
148
|
+
*/
|
|
149
|
+
export function validateCallbackTemplates(
|
|
150
|
+
callback: Record<string, unknown>,
|
|
151
|
+
knownVariables: string[],
|
|
152
|
+
): string[] {
|
|
153
|
+
const definedVars = new Set(knownVariables);
|
|
154
|
+
const referencedVars: string[] = [];
|
|
155
|
+
|
|
156
|
+
const scanForRefs = (obj: unknown): void => {
|
|
157
|
+
if (typeof obj === 'string') {
|
|
158
|
+
const matches = obj.matchAll(/\{\{trigger\.(\w+)\}\}/g);
|
|
159
|
+
for (const match of matches) {
|
|
160
|
+
referencedVars.push(match[1]);
|
|
161
|
+
}
|
|
162
|
+
} else if (Array.isArray(obj)) {
|
|
163
|
+
obj.forEach(scanForRefs);
|
|
164
|
+
} else if (obj !== null && typeof obj === 'object') {
|
|
165
|
+
Object.values(obj as Record<string, unknown>).forEach(scanForRefs);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
scanForRefs(callback);
|
|
170
|
+
|
|
171
|
+
return referencedVars.filter((v) => !definedVars.has(v));
|
|
172
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -100,7 +100,7 @@ export { defineAgent, defineTool } from "./define.js";
|
|
|
100
100
|
export type { DefineAgentOptions, DefineToolOptions, AgentWithHooks, ToolWithHooks } from "./define.js";
|
|
101
101
|
|
|
102
102
|
// Registry
|
|
103
|
-
export { createAgentRegistry } from "./registry.js";
|
|
103
|
+
export { createAgentRegistry, agentFromSerialized } from "./registry.js";
|
|
104
104
|
export type {
|
|
105
105
|
AgentRegistry,
|
|
106
106
|
AgentRegistryOptions,
|
|
@@ -340,3 +340,32 @@ export type {
|
|
|
340
340
|
|
|
341
341
|
export { introspectMcp } from "./introspect.js";
|
|
342
342
|
export type { IntrospectOptions } from "./introspect.js";
|
|
343
|
+
|
|
344
|
+
// ============================================
|
|
345
|
+
// Agent Callbacks (deferred call_agent commands)
|
|
346
|
+
// ============================================
|
|
347
|
+
|
|
348
|
+
export {
|
|
349
|
+
resolveCallbackTemplates,
|
|
350
|
+
validateCallbackTemplates,
|
|
351
|
+
} from "./callback/index.js";
|
|
352
|
+
export type {
|
|
353
|
+
AgentCallbackTrigger,
|
|
354
|
+
AgentCallbackStatus,
|
|
355
|
+
AgentCallbackEntry,
|
|
356
|
+
AgentCallbackStore,
|
|
357
|
+
CreateAgentCallbackOptions,
|
|
358
|
+
ResolveAgentCallbackOptions,
|
|
359
|
+
} from "./callback/index.js";
|
|
360
|
+
|
|
361
|
+
// ============================================
|
|
362
|
+
// Validation
|
|
363
|
+
// ============================================
|
|
364
|
+
|
|
365
|
+
export {
|
|
366
|
+
SerializedAgentDefinitionSchema,
|
|
367
|
+
SerializedToolSchema,
|
|
368
|
+
validateDefinition,
|
|
369
|
+
assertValidDefinition,
|
|
370
|
+
} from "./validate.js";
|
|
371
|
+
export type { ValidationResult } from "./validate.js";
|
package/src/pack.ts
CHANGED
|
@@ -13,15 +13,11 @@
|
|
|
13
13
|
|
|
14
14
|
import { spawnSync } from "node:child_process";
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
16
|
-
import {
|
|
17
|
-
existsSync,
|
|
18
|
-
mkdirSync,
|
|
19
|
-
readFileSync,
|
|
20
|
-
writeFileSync,
|
|
21
|
-
} from "node:fs";
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
22
17
|
import { resolve } from "node:path";
|
|
23
18
|
import { parseJsonc } from "./jsonc.js";
|
|
24
19
|
import type { SerializedAgentDefinition } from "./serialized.js";
|
|
20
|
+
import { assertValidDefinition } from "./validate.js";
|
|
25
21
|
|
|
26
22
|
// ============================================
|
|
27
23
|
// Types
|
|
@@ -159,6 +155,9 @@ export function pack(options: PackOptions): PackResult {
|
|
|
159
155
|
const agentContent = readFileSync(agentPath, "utf-8");
|
|
160
156
|
const definition = parseJsonc(agentContent) as SerializedAgentDefinition;
|
|
161
157
|
|
|
158
|
+
// Validate the definition schema
|
|
159
|
+
assertValidDefinition(definition, agentPath);
|
|
160
|
+
|
|
162
161
|
// Compute hash + version
|
|
163
162
|
const hash = contentHash(agentContent);
|
|
164
163
|
const version = `${definition.version || "1.0.0"}`;
|
package/src/registry.ts
CHANGED
|
@@ -5,12 +5,9 @@
|
|
|
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";
|
|
8
|
+
import type { AgentEvent, EventCallback, EventType } from "./events.js";
|
|
13
9
|
import { createEventBus } from "./events.js";
|
|
10
|
+
import type { SerializedAgentDefinition } from "./serialized.js";
|
|
14
11
|
import type {
|
|
15
12
|
AgentAction,
|
|
16
13
|
AgentDefinition,
|
|
@@ -28,6 +25,7 @@ import type {
|
|
|
28
25
|
ToolSchema,
|
|
29
26
|
Visibility,
|
|
30
27
|
} from "./types.js";
|
|
28
|
+
import { assertValidDefinition } from "./validate.js";
|
|
31
29
|
|
|
32
30
|
/** Default supported actions if not specified */
|
|
33
31
|
const DEFAULT_SUPPORTED_ACTIONS: AgentAction[] = [
|
|
@@ -75,8 +73,8 @@ export interface AgentRegistryOptions {
|
|
|
75
73
|
* Agent registry interface.
|
|
76
74
|
*/
|
|
77
75
|
export interface AgentRegistry {
|
|
78
|
-
/** Register an agent */
|
|
79
|
-
register(agent: AgentDefinition): void;
|
|
76
|
+
/** Register an agent (accepts both AgentDefinition and SerializedAgentDefinition) */
|
|
77
|
+
register(agent: AgentDefinition | SerializedAgentDefinition): void;
|
|
80
78
|
|
|
81
79
|
/** Get an agent by path */
|
|
82
80
|
get(path: string): AgentDefinition | undefined;
|
|
@@ -128,6 +126,43 @@ export type ContextFactory = (
|
|
|
128
126
|
baseCtx: import("./types.js").ToolContext,
|
|
129
127
|
) => import("./types.js").ToolContext;
|
|
130
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Convert a SerializedAgentDefinition to an AgentDefinition.
|
|
131
|
+
*
|
|
132
|
+
* Use this when you need an AgentDefinition but have a serialized one
|
|
133
|
+
* (e.g., from an @agentdef package or adk introspect output).
|
|
134
|
+
*
|
|
135
|
+
* Tools get a proxy execute that throws — actual execution goes through MCP.
|
|
136
|
+
* The registry's `register()` method calls this automatically.
|
|
137
|
+
*/
|
|
138
|
+
export function agentFromSerialized(
|
|
139
|
+
def: SerializedAgentDefinition,
|
|
140
|
+
): AgentDefinition {
|
|
141
|
+
return {
|
|
142
|
+
path: def.path,
|
|
143
|
+
entrypoint: def.description || `Agent for ${def.name}`,
|
|
144
|
+
config: {
|
|
145
|
+
name: def.name,
|
|
146
|
+
description: def.description,
|
|
147
|
+
visibility: def.visibility as Visibility | undefined,
|
|
148
|
+
},
|
|
149
|
+
visibility: def.visibility as Visibility | undefined,
|
|
150
|
+
tools: def.tools.map(
|
|
151
|
+
(t) =>
|
|
152
|
+
({
|
|
153
|
+
name: t.name,
|
|
154
|
+
description: t.description,
|
|
155
|
+
inputSchema: t.inputSchema,
|
|
156
|
+
execute: async () => {
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Tool "${t.name}" is from a SerializedAgentDefinition and requires MCP server execution. Use createClient() to call tools on serialized agents.`,
|
|
159
|
+
);
|
|
160
|
+
},
|
|
161
|
+
}) as unknown as ToolDefinition,
|
|
162
|
+
),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
131
166
|
export function createAgentRegistry(
|
|
132
167
|
options: AgentRegistryOptions = {},
|
|
133
168
|
): AgentRegistry {
|
|
@@ -333,8 +368,61 @@ export function createAgentRegistry(
|
|
|
333
368
|
};
|
|
334
369
|
}
|
|
335
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Detect if the input is a SerializedAgentDefinition (vs AgentDefinition).
|
|
373
|
+
* SerializedAgentDefinition has tools with inputSchema but no execute function.
|
|
374
|
+
*/
|
|
375
|
+
function isSerialized(
|
|
376
|
+
agent: AgentDefinition | SerializedAgentDefinition,
|
|
377
|
+
): agent is SerializedAgentDefinition {
|
|
378
|
+
if (!agent.tools || agent.tools.length === 0) return false;
|
|
379
|
+
// SerializedAgentDefinition tools have inputSchema but no execute
|
|
380
|
+
const firstTool = agent.tools[0] as unknown as Record<string, unknown>;
|
|
381
|
+
return "inputSchema" in firstTool && !("execute" in firstTool);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Convert a SerializedAgentDefinition to an AgentDefinition.
|
|
386
|
+
* Tools get a proxy execute that throws — actual execution goes through MCP.
|
|
387
|
+
*/
|
|
388
|
+
function fromSerialized(def: SerializedAgentDefinition): AgentDefinition {
|
|
389
|
+
return {
|
|
390
|
+
path: def.path,
|
|
391
|
+
entrypoint: def.description || `Agent for ${def.name}`,
|
|
392
|
+
config: {
|
|
393
|
+
name: def.name,
|
|
394
|
+
description: def.description,
|
|
395
|
+
visibility: def.visibility as Visibility | undefined,
|
|
396
|
+
},
|
|
397
|
+
visibility: def.visibility as Visibility | undefined,
|
|
398
|
+
tools: def.tools.map(
|
|
399
|
+
(t) =>
|
|
400
|
+
({
|
|
401
|
+
name: t.name,
|
|
402
|
+
description: t.description,
|
|
403
|
+
inputSchema: t.inputSchema,
|
|
404
|
+
execute: async () => {
|
|
405
|
+
throw new Error(
|
|
406
|
+
`Tool "${t.name}" is from a SerializedAgentDefinition and requires MCP server execution. Use createClient() to call tools on serialized agents.`,
|
|
407
|
+
);
|
|
408
|
+
},
|
|
409
|
+
}) as unknown as ToolDefinition,
|
|
410
|
+
),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
336
414
|
const registry: AgentRegistry = {
|
|
337
|
-
register(
|
|
415
|
+
register(input: AgentDefinition | SerializedAgentDefinition): void {
|
|
416
|
+
let agent: AgentDefinition;
|
|
417
|
+
if (isSerialized(input)) {
|
|
418
|
+
assertValidDefinition(
|
|
419
|
+
input,
|
|
420
|
+
`register(${(input as SerializedAgentDefinition).path || "unknown"})`,
|
|
421
|
+
);
|
|
422
|
+
agent = fromSerialized(input as SerializedAgentDefinition);
|
|
423
|
+
} else {
|
|
424
|
+
agent = input as AgentDefinition;
|
|
425
|
+
}
|
|
338
426
|
agents.set(agent.path, agent);
|
|
339
427
|
|
|
340
428
|
// Collect agent-level listeners into the bus
|
|
@@ -508,15 +596,17 @@ export function createAgentRegistry(
|
|
|
508
596
|
result = await tool.execute(request.params, ctx);
|
|
509
597
|
} catch (err) {
|
|
510
598
|
// Emit tool/error on failure
|
|
511
|
-
await eventBus
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
599
|
+
await eventBus
|
|
600
|
+
.emit({
|
|
601
|
+
type: "tool/error",
|
|
602
|
+
agentPath: agent.path,
|
|
603
|
+
tool: request.tool!,
|
|
604
|
+
params: request.params,
|
|
605
|
+
error: err,
|
|
606
|
+
durationMs: Date.now() - startMs,
|
|
607
|
+
timestamp: Date.now(),
|
|
608
|
+
})
|
|
609
|
+
.catch(() => {}); // don't let emit error mask tool error
|
|
520
610
|
|
|
521
611
|
return {
|
|
522
612
|
success: false,
|
|
@@ -544,7 +634,8 @@ export function createAgentRegistry(
|
|
|
544
634
|
// Catch-all for unexpected errors (e.g., emit failures)
|
|
545
635
|
return {
|
|
546
636
|
success: false,
|
|
547
|
-
error:
|
|
637
|
+
error:
|
|
638
|
+
outerErr instanceof Error ? outerErr.message : String(outerErr),
|
|
548
639
|
code: "TOOL_EXECUTION_ERROR",
|
|
549
640
|
} as CallAgentErrorResponse;
|
|
550
641
|
}
|