@chatbotkit/agent 1.28.0 → 1.29.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/README.md +67 -0
- package/dist/cjs/agent.cjs +37 -250
- package/dist/cjs/agent.d.ts +9 -53
- package/dist/cjs/execute.cjs +309 -0
- package/dist/cjs/execute.d.ts +56 -0
- package/dist/cjs/index.cjs +9 -4
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/skills.cjs +116 -0
- package/dist/cjs/skills.d.ts +18 -0
- package/dist/esm/agent.d.ts +9 -53
- package/dist/esm/agent.js +35 -248
- package/dist/esm/execute.d.ts +56 -0
- package/dist/esm/execute.js +305 -0
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/skills.d.ts +18 -0
- package/dist/esm/skills.js +111 -0
- package/package.json +44 -2
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.complete = complete;
|
|
4
|
+
exports.execute = execute;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
7
|
+
async function* complete(options) {
|
|
8
|
+
const { client, tools, abortSignal, ...request } = options;
|
|
9
|
+
const channelToTool = new Map();
|
|
10
|
+
const functions = tools
|
|
11
|
+
? Object.entries(tools).map(([name, tool]) => {
|
|
12
|
+
const randomSuffix = Math.random().toString(36).substring(2, 15);
|
|
13
|
+
const channel = `${name}_${randomSuffix}`.padEnd(16, '0');
|
|
14
|
+
channelToTool.set(channel, { name, tool });
|
|
15
|
+
if (!tool.input) {
|
|
16
|
+
return {
|
|
17
|
+
name,
|
|
18
|
+
description: tool.description,
|
|
19
|
+
parameters: ({
|
|
20
|
+
type: 'object',
|
|
21
|
+
properties: {},
|
|
22
|
+
}),
|
|
23
|
+
result: {
|
|
24
|
+
channel,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const schema = ((0, zod_to_json_schema_1.zodToJsonSchema)(tool.input, { target: 'openApi3' }));
|
|
29
|
+
const parameters = {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: schema.properties || {},
|
|
32
|
+
...(schema.required && schema.required.length > 0
|
|
33
|
+
? { required: schema.required }
|
|
34
|
+
: {}),
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
name,
|
|
38
|
+
description: tool.description,
|
|
39
|
+
parameters: (parameters),
|
|
40
|
+
result: {
|
|
41
|
+
channel,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
})
|
|
45
|
+
: undefined;
|
|
46
|
+
const stream = client.conversation
|
|
47
|
+
.complete(null, {
|
|
48
|
+
...request,
|
|
49
|
+
functions,
|
|
50
|
+
limits: {
|
|
51
|
+
iterations: 1,
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
.stream({ abortSignal });
|
|
55
|
+
const toolEventQueue = [];
|
|
56
|
+
const runningToolPromises = [];
|
|
57
|
+
const executeToolAsync = async (channel, name, tool, args) => {
|
|
58
|
+
try {
|
|
59
|
+
let parsedArgs = args;
|
|
60
|
+
if (tool.input) {
|
|
61
|
+
const parseResult = tool.input.safeParse(args);
|
|
62
|
+
if (!parseResult.success) {
|
|
63
|
+
const errorMsg = `Invalid arguments: ${parseResult.error.message}`;
|
|
64
|
+
toolEventQueue.push({
|
|
65
|
+
type: 'toolCallError',
|
|
66
|
+
data: { name, error: errorMsg },
|
|
67
|
+
});
|
|
68
|
+
await client.channel.publish(String(channel), {
|
|
69
|
+
message: { error: errorMsg },
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
parsedArgs = parseResult.data;
|
|
74
|
+
}
|
|
75
|
+
const result = await tool.handler(parsedArgs);
|
|
76
|
+
toolEventQueue.push({
|
|
77
|
+
type: 'toolCallEnd',
|
|
78
|
+
data: { name, result },
|
|
79
|
+
});
|
|
80
|
+
await client.channel.publish(String(channel), {
|
|
81
|
+
message: { data: result },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
86
|
+
toolEventQueue.push({
|
|
87
|
+
type: 'toolCallError',
|
|
88
|
+
data: { name, error: errorMessage },
|
|
89
|
+
});
|
|
90
|
+
await client.channel.publish(String(channel), {
|
|
91
|
+
message: { error: errorMessage },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
for await (const event of stream) {
|
|
96
|
+
if (abortSignal?.aborted) {
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
while (toolEventQueue.length > 0) {
|
|
100
|
+
const toolEvent = toolEventQueue.shift();
|
|
101
|
+
if (toolEvent) {
|
|
102
|
+
yield toolEvent;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (event.type === 'waitForChannelMessageBegin' &&
|
|
106
|
+
event.data &&
|
|
107
|
+
'channel' in event.data &&
|
|
108
|
+
'function' in event.data) {
|
|
109
|
+
const channel = (event.data.channel);
|
|
110
|
+
const args = (event.data.function).args;
|
|
111
|
+
const toolInfo = channelToTool.get(String(channel));
|
|
112
|
+
if (toolInfo) {
|
|
113
|
+
const { name, tool } = toolInfo;
|
|
114
|
+
yield {
|
|
115
|
+
type: 'toolCallStart',
|
|
116
|
+
data: {
|
|
117
|
+
name,
|
|
118
|
+
args,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
const toolPromise = executeToolAsync(channel, name, tool, args);
|
|
122
|
+
runningToolPromises.push(toolPromise);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
yield event;
|
|
126
|
+
}
|
|
127
|
+
while (toolEventQueue.length > 0) {
|
|
128
|
+
const toolEvent = toolEventQueue.shift();
|
|
129
|
+
if (toolEvent) {
|
|
130
|
+
yield toolEvent;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (runningToolPromises.length > 0) {
|
|
134
|
+
await Promise.allSettled(runningToolPromises);
|
|
135
|
+
while (toolEventQueue.length > 0) {
|
|
136
|
+
const toolEvent = toolEventQueue.shift();
|
|
137
|
+
if (toolEvent) {
|
|
138
|
+
yield toolEvent;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function* execute(options) {
|
|
144
|
+
const { client, tools = {}, maxIterations = 100, abortSignal, ...request } = options;
|
|
145
|
+
const messages = request.messages || [];
|
|
146
|
+
let exitResult = null;
|
|
147
|
+
let internalAbort = null;
|
|
148
|
+
const systemTools = {
|
|
149
|
+
plan: {
|
|
150
|
+
description: 'Create or update a plan for approaching the task. Break down the task into clear, actionable steps. Use this at the start and whenever you need to revise your approach.',
|
|
151
|
+
input: zod_1.z.object({
|
|
152
|
+
steps: zod_1.z
|
|
153
|
+
.array(zod_1.z.string())
|
|
154
|
+
.describe('Array of step descriptions in order of execution'),
|
|
155
|
+
rationale: zod_1.z
|
|
156
|
+
.string()
|
|
157
|
+
.optional()
|
|
158
|
+
.describe('Brief explanation of the plan approach'),
|
|
159
|
+
}),
|
|
160
|
+
handler: async (input) => {
|
|
161
|
+
return {
|
|
162
|
+
success: true,
|
|
163
|
+
message: `Plan created with ${input.steps.length} steps${input.rationale ? ': ' + input.rationale : ''}`,
|
|
164
|
+
};
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
progress: {
|
|
168
|
+
description: 'Update progress on the current task. Use this to track completed steps, report current status, and identify blockers.',
|
|
169
|
+
input: zod_1.z.object({
|
|
170
|
+
completed: zod_1.z
|
|
171
|
+
.array(zod_1.z.string())
|
|
172
|
+
.optional()
|
|
173
|
+
.describe('Steps that have been completed'),
|
|
174
|
+
current: zod_1.z.string().optional().describe('Current step being worked on'),
|
|
175
|
+
blockers: zod_1.z
|
|
176
|
+
.array(zod_1.z.string())
|
|
177
|
+
.optional()
|
|
178
|
+
.describe('Any issues preventing progress'),
|
|
179
|
+
nextSteps: zod_1.z
|
|
180
|
+
.array(zod_1.z.string())
|
|
181
|
+
.optional()
|
|
182
|
+
.describe('Next actions to take'),
|
|
183
|
+
}),
|
|
184
|
+
handler: async (input) => {
|
|
185
|
+
return {
|
|
186
|
+
success: true,
|
|
187
|
+
message: 'Progress updated',
|
|
188
|
+
...input,
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
exit: {
|
|
193
|
+
description: 'Exit the task execution with a status code and optional message. Status code 0 indicates success, non-zero indicates failure. Use this when all the tasks are complete or cannot proceed.',
|
|
194
|
+
input: zod_1.z.object({
|
|
195
|
+
code: zod_1.z
|
|
196
|
+
.number()
|
|
197
|
+
.int()
|
|
198
|
+
.min(0)
|
|
199
|
+
.max(255)
|
|
200
|
+
.describe('Exit status code (0 = success, non-zero = failure)'),
|
|
201
|
+
message: zod_1.z
|
|
202
|
+
.string()
|
|
203
|
+
.optional()
|
|
204
|
+
.describe('Optional message explaining the exit reason'),
|
|
205
|
+
}),
|
|
206
|
+
handler: async (input) => {
|
|
207
|
+
exitResult = { code: input.code, message: input.message };
|
|
208
|
+
return {
|
|
209
|
+
success: true,
|
|
210
|
+
message: `Task exiting with code ${input.code}${input.message ? ': ' + input.message : ''}`,
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
abort: {
|
|
215
|
+
description: 'Immediately abort the current task. Use this when the user explicitly asks you to stop, cancel, or abort what you are doing. Set hard to true to kill running processes immediately.',
|
|
216
|
+
input: zod_1.z.object({
|
|
217
|
+
reason: zod_1.z.string().optional().describe('Brief reason for aborting'),
|
|
218
|
+
hard: zod_1.z
|
|
219
|
+
.boolean()
|
|
220
|
+
.optional()
|
|
221
|
+
.describe('If true, immediately kill running processes. If false (default), finish the current operation gracefully.'),
|
|
222
|
+
}),
|
|
223
|
+
handler: async (input) => {
|
|
224
|
+
const reason = input.reason || 'aborted by user request';
|
|
225
|
+
exitResult = { code: 1, message: reason };
|
|
226
|
+
if (input.hard && internalAbort) {
|
|
227
|
+
internalAbort.abort(reason);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
success: true,
|
|
231
|
+
message: `Task aborted: ${reason}`,
|
|
232
|
+
};
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
const allTools = { ...tools, ...systemTools };
|
|
237
|
+
const systemInstruction = `
|
|
238
|
+
${options.extensions?.backstory || ''}
|
|
239
|
+
|
|
240
|
+
# Task Execution Guidelines
|
|
241
|
+
|
|
242
|
+
The goal is to complete the assigned task efficiently and effectively. Follow these guidelines:
|
|
243
|
+
|
|
244
|
+
1. **Plan First**: Use the 'plan' function to create a clear strategy before starting work
|
|
245
|
+
2. **Track Progress**: Regularly use the 'progress' function to update status and identify issues
|
|
246
|
+
3. **Use Tools**: Leverage available tools to accomplish each step of your plan
|
|
247
|
+
4. **Exit When Done**: Call the 'exit' function with code 0 when successful, or non-zero code if unable to complete
|
|
248
|
+
5. **Abort**: If the user asks you to stop, cancel, or abort, call the 'abort' function immediately. Use hard=true if processes are running that need to be killed right away.
|
|
249
|
+
6. **Be Autonomous**: Work through the task systematically without waiting for additional input
|
|
250
|
+
7. **Be Responsive**: If the user sends a new message while you are working, acknowledge it briefly and adjust your approach if needed. Always prioritize user input over your current plan.
|
|
251
|
+
`.trim();
|
|
252
|
+
let iteration = 0;
|
|
253
|
+
while (iteration < maxIterations && exitResult === null) {
|
|
254
|
+
if (abortSignal?.aborted) {
|
|
255
|
+
exitResult = {
|
|
256
|
+
code: 1,
|
|
257
|
+
message: 'Task execution aborted',
|
|
258
|
+
};
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
iteration++;
|
|
262
|
+
yield { type: 'iteration', data: { iteration } };
|
|
263
|
+
let lastEndReason = null;
|
|
264
|
+
internalAbort = new AbortController();
|
|
265
|
+
if (abortSignal?.aborted) {
|
|
266
|
+
internalAbort.abort(abortSignal.reason);
|
|
267
|
+
}
|
|
268
|
+
else if (abortSignal) {
|
|
269
|
+
const capturedAbort = internalAbort;
|
|
270
|
+
abortSignal.addEventListener('abort', () => capturedAbort.abort(abortSignal.reason), { once: true });
|
|
271
|
+
}
|
|
272
|
+
const iterSignal = internalAbort.signal;
|
|
273
|
+
for await (const event of complete({
|
|
274
|
+
...request,
|
|
275
|
+
client,
|
|
276
|
+
messages,
|
|
277
|
+
tools: allTools,
|
|
278
|
+
abortSignal: iterSignal,
|
|
279
|
+
extensions: {
|
|
280
|
+
...options.extensions,
|
|
281
|
+
backstory: systemInstruction,
|
|
282
|
+
},
|
|
283
|
+
})) {
|
|
284
|
+
if (event.type === 'message') {
|
|
285
|
+
messages.push(event.data);
|
|
286
|
+
}
|
|
287
|
+
if (event.type === 'result') {
|
|
288
|
+
if (event.data.end.reason) {
|
|
289
|
+
lastEndReason = event.data.end.reason;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
yield event;
|
|
293
|
+
}
|
|
294
|
+
if (exitResult) {
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
if (lastEndReason === 'stop') {
|
|
298
|
+
exitResult = { code: 0 };
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (exitResult === null) {
|
|
303
|
+
exitResult = {
|
|
304
|
+
code: 1,
|
|
305
|
+
message: `Task did not complete within ${maxIterations} iterations`,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
yield { type: 'exit', data: exitResult };
|
|
309
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function complete(options: Omit<ConversationCompleteRequest, "functions" | "limits"> & {
|
|
2
|
+
client: ChatBotKit;
|
|
3
|
+
tools?: Tools;
|
|
4
|
+
abortSignal?: AbortSignal;
|
|
5
|
+
}): AsyncGenerator<ConversationCompleteStreamType | ToolCallStartEvent | ToolCallEndEvent | ToolCallErrorEvent, void, unknown>;
|
|
6
|
+
export function execute(options: Omit<ConversationCompleteRequest, "functions" | "limits"> & {
|
|
7
|
+
client: ChatBotKit;
|
|
8
|
+
tools?: Tools;
|
|
9
|
+
maxIterations?: number;
|
|
10
|
+
abortSignal?: AbortSignal;
|
|
11
|
+
}): AsyncGenerator<ConversationCompleteStreamType | ToolCallStartEvent | ToolCallEndEvent | ToolCallErrorEvent | IterationEvent | ExitEvent, void, unknown>;
|
|
12
|
+
export type ZodObject = import("zod").ZodObject<any>;
|
|
13
|
+
export type ChatBotKit = import("@chatbotkit/sdk").ChatBotKit;
|
|
14
|
+
export type ConversationCompleteRequest = any;
|
|
15
|
+
export type ConversationCompleteStreamType = any;
|
|
16
|
+
export type ToolDefinition<T extends ZodObject> = {
|
|
17
|
+
description: string;
|
|
18
|
+
input?: T;
|
|
19
|
+
handler: (input: any) => Promise<any>;
|
|
20
|
+
};
|
|
21
|
+
export type Tools = Record<string, ToolDefinition<ZodObject>>;
|
|
22
|
+
export type ExitResult = {
|
|
23
|
+
code: number;
|
|
24
|
+
message?: string;
|
|
25
|
+
};
|
|
26
|
+
export type ToolCallStartEvent = {
|
|
27
|
+
type: "toolCallStart";
|
|
28
|
+
data: {
|
|
29
|
+
name: string;
|
|
30
|
+
args: any;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export type ToolCallEndEvent = {
|
|
34
|
+
type: "toolCallEnd";
|
|
35
|
+
data: {
|
|
36
|
+
name: string;
|
|
37
|
+
result: any;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export type ToolCallErrorEvent = {
|
|
41
|
+
type: "toolCallError";
|
|
42
|
+
data: {
|
|
43
|
+
name: string;
|
|
44
|
+
error: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export type IterationEvent = {
|
|
48
|
+
type: "iteration";
|
|
49
|
+
data: {
|
|
50
|
+
iteration: number;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export type ExitEvent = {
|
|
54
|
+
type: "exit";
|
|
55
|
+
data: ExitResult;
|
|
56
|
+
};
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.tools = exports.execute = exports.complete = void 0;
|
|
4
|
-
var
|
|
5
|
-
Object.defineProperty(exports, "complete", { enumerable: true, get: function () { return
|
|
6
|
-
Object.defineProperty(exports, "execute", { enumerable: true, get: function () { return
|
|
3
|
+
exports.loadAgent = exports.createSkillsFeature = exports.loadSkills = exports.tools = exports.execute = exports.complete = void 0;
|
|
4
|
+
var execute_js_1 = require("./execute.cjs");
|
|
5
|
+
Object.defineProperty(exports, "complete", { enumerable: true, get: function () { return execute_js_1.complete; } });
|
|
6
|
+
Object.defineProperty(exports, "execute", { enumerable: true, get: function () { return execute_js_1.execute; } });
|
|
7
7
|
var tools_js_1 = require("./tools.cjs");
|
|
8
8
|
Object.defineProperty(exports, "tools", { enumerable: true, get: function () { return tools_js_1.tools; } });
|
|
9
|
+
var skills_js_1 = require("./skills.cjs");
|
|
10
|
+
Object.defineProperty(exports, "loadSkills", { enumerable: true, get: function () { return skills_js_1.loadSkills; } });
|
|
11
|
+
Object.defineProperty(exports, "createSkillsFeature", { enumerable: true, get: function () { return skills_js_1.createSkillsFeature; } });
|
|
12
|
+
var agent_js_1 = require("./agent.cjs");
|
|
13
|
+
Object.defineProperty(exports, "loadAgent", { enumerable: true, get: function () { return agent_js_1.loadAgent; } });
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadSkills = loadSkills;
|
|
4
|
+
exports.createSkillsFeature = createSkillsFeature;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const promises_1 = require("fs/promises");
|
|
7
|
+
const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
function parseFrontMatter(content) {
|
|
10
|
+
const frontMatterRegex = /^---\s*\n([\s\S]*?)\n---/;
|
|
11
|
+
const match = content.match(frontMatterRegex);
|
|
12
|
+
if (!match) {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const frontMatter = match[1];
|
|
17
|
+
const parsed = (js_yaml_1.default.load(frontMatter));
|
|
18
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
name: typeof parsed.name === 'string' ? parsed.name : undefined,
|
|
23
|
+
description: typeof parsed.description === 'string' ? parsed.description : undefined,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function loadSkillFromDirectory(skillDir) {
|
|
31
|
+
const skillFilePath = (0, path_1.join)(skillDir, 'SKILL.md');
|
|
32
|
+
try {
|
|
33
|
+
const content = await (0, promises_1.readFile)(skillFilePath, 'utf-8');
|
|
34
|
+
const { name, description } = parseFrontMatter(content);
|
|
35
|
+
if (!name || !description) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
name,
|
|
40
|
+
description,
|
|
41
|
+
path: (0, path_1.resolve)(skillFilePath),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function loadSkills(directories, options = {}) {
|
|
49
|
+
const skills = ([]);
|
|
50
|
+
const watchControllers = ([]);
|
|
51
|
+
async function scanDirectory(baseDir) {
|
|
52
|
+
try {
|
|
53
|
+
const entries = await (0, promises_1.readdir)(baseDir);
|
|
54
|
+
for (const entry of entries) {
|
|
55
|
+
const entryPath = (0, path_1.join)(baseDir, entry);
|
|
56
|
+
const entryStat = await (0, promises_1.stat)(entryPath);
|
|
57
|
+
if (entryStat.isDirectory()) {
|
|
58
|
+
const skill = await loadSkillFromDirectory(entryPath);
|
|
59
|
+
if (skill) {
|
|
60
|
+
const existingIdx = skills.findIndex((s) => s.path === skill.path);
|
|
61
|
+
if (existingIdx !== -1) {
|
|
62
|
+
skills[existingIdx] = skill;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
skills.push(skill);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const dir of directories) {
|
|
75
|
+
await scanDirectory(dir);
|
|
76
|
+
}
|
|
77
|
+
if (options.watch) {
|
|
78
|
+
for (const dir of directories) {
|
|
79
|
+
const controller = new AbortController();
|
|
80
|
+
watchControllers.push(controller);
|
|
81
|
+
(async () => {
|
|
82
|
+
try {
|
|
83
|
+
const watcher = (0, promises_1.watch)(dir, {
|
|
84
|
+
recursive: true,
|
|
85
|
+
signal: controller.signal,
|
|
86
|
+
});
|
|
87
|
+
for await (const event of watcher) {
|
|
88
|
+
if (event.filename?.endsWith('SKILL.md')) {
|
|
89
|
+
await scanDirectory(dir);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
if (err instanceof Error &&
|
|
95
|
+
err.name !== 'AbortError' &&
|
|
96
|
+
!err.message.includes('AbortError')) {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
})();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
skills,
|
|
104
|
+
close: () => {
|
|
105
|
+
for (const controller of watchControllers) {
|
|
106
|
+
controller.abort();
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function createSkillsFeature(skills) {
|
|
112
|
+
return {
|
|
113
|
+
name: ('skills'),
|
|
114
|
+
options: { skills },
|
|
115
|
+
};
|
|
116
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function loadSkills(directories: string[], options?: {
|
|
2
|
+
watch?: boolean;
|
|
3
|
+
}): Promise<SkillsResult>;
|
|
4
|
+
export function createSkillsFeature(skills: SkillDefinition[]): {
|
|
5
|
+
name: "skills";
|
|
6
|
+
options: {
|
|
7
|
+
skills: SkillDefinition[];
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export type SkillDefinition = {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
path: string;
|
|
14
|
+
};
|
|
15
|
+
export type SkillsResult = {
|
|
16
|
+
skills: SkillDefinition[];
|
|
17
|
+
close: () => void;
|
|
18
|
+
};
|
package/dist/esm/agent.d.ts
CHANGED
|
@@ -1,54 +1,10 @@
|
|
|
1
|
-
export function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export type ZodObject = import("zod").ZodObject<any>;
|
|
11
|
-
export type ChatBotKit = import("@chatbotkit/sdk").ChatBotKit;
|
|
12
|
-
export type ConversationCompleteRequest = import("@chatbotkit/sdk/conversation/v1").ConversationCompleteRequest;
|
|
13
|
-
export type ConversationCompleteStreamType = import("@chatbotkit/sdk/conversation/v1").ConversationCompleteStreamType;
|
|
14
|
-
export type ToolDefinition<T extends ZodObject> = {
|
|
15
|
-
description: string;
|
|
16
|
-
input?: T;
|
|
17
|
-
handler: (input: any) => Promise<any>;
|
|
18
|
-
};
|
|
19
|
-
export type Tools = Record<string, ToolDefinition<ZodObject>>;
|
|
20
|
-
export type ExitResult = {
|
|
21
|
-
code: number;
|
|
22
|
-
message?: string;
|
|
23
|
-
};
|
|
24
|
-
export type ToolCallStartEvent = {
|
|
25
|
-
type: "toolCallStart";
|
|
26
|
-
data: {
|
|
27
|
-
name: string;
|
|
28
|
-
args: any;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
export type ToolCallEndEvent = {
|
|
32
|
-
type: "toolCallEnd";
|
|
33
|
-
data: {
|
|
34
|
-
name: string;
|
|
35
|
-
result: any;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
export type ToolCallErrorEvent = {
|
|
39
|
-
type: "toolCallError";
|
|
40
|
-
data: {
|
|
41
|
-
name: string;
|
|
42
|
-
error: string;
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
export type IterationEvent = {
|
|
46
|
-
type: "iteration";
|
|
47
|
-
data: {
|
|
48
|
-
iteration: number;
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
export type ExitEvent = {
|
|
52
|
-
type: "exit";
|
|
53
|
-
data: ExitResult;
|
|
1
|
+
export function loadAgent(filePath: string): Promise<AgentDefinition>;
|
|
2
|
+
export type AgentDefinition = {
|
|
3
|
+
name?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
backstory?: string;
|
|
6
|
+
model?: string;
|
|
7
|
+
botId?: string;
|
|
8
|
+
skillsetId?: string;
|
|
9
|
+
datasetId?: string;
|
|
54
10
|
};
|