@chatbotkit/agent 1.27.0 → 1.28.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/README.md +0 -67
- package/dist/cjs/agent.cjs +19 -69
- package/dist/cjs/agent.d.ts +2 -4
- package/dist/cjs/index.cjs +1 -4
- package/dist/cjs/index.d.ts +0 -1
- package/dist/esm/agent.d.ts +2 -4
- package/dist/esm/agent.js +19 -69
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +0 -1
- package/package.json +2 -24
- package/dist/cjs/skills.cjs +0 -116
- package/dist/cjs/skills.d.ts +0 -18
- package/dist/esm/skills.d.ts +0 -18
- package/dist/esm/skills.js +0 -111
package/README.md
CHANGED
|
@@ -9,20 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
Build autonomous AI agents that can use custom tools and execute complex tasks with the full power of the ChatBotKit platform.
|
|
11
11
|
|
|
12
|
-
## Why ChatBotKit?
|
|
13
|
-
|
|
14
|
-
**Build lighter, future-proof AI agents.** When you build with ChatBotKit, the heavy lifting happens on our servers—not in your application. This architectural advantage delivers:
|
|
15
|
-
|
|
16
|
-
- 🪶 **Lightweight Agents**: Your agents stay lean because complex AI processing, model orchestration, and tool execution happen server-side. Less code in your app means faster load times and simpler maintenance.
|
|
17
|
-
|
|
18
|
-
- 🛡️ **Robust & Streamlined**: Server-side processing provides a more reliable experience with built-in error handling, automatic retries, and consistent behavior across all platforms.
|
|
19
|
-
|
|
20
|
-
- 🔄 **Backward & Forward Compatible**: As AI technology evolves—new models, new capabilities, new paradigms—your agents automatically benefit. No code changes required on your end.
|
|
21
|
-
|
|
22
|
-
- 🔮 **Future-Proof**: Agents you build today will remain capable tomorrow. When we add support for new AI models or capabilities, your existing agents gain those powers without any updates to your codebase.
|
|
23
|
-
|
|
24
|
-
This means you can focus on building great user experiences while ChatBotKit handles the complexity of the ever-changing AI landscape.
|
|
25
|
-
|
|
26
12
|
## Installation
|
|
27
13
|
|
|
28
14
|
```bash
|
|
@@ -192,59 +178,6 @@ The `execute` mode provides system tools for task management:
|
|
|
192
178
|
- **`progress`** - Track completion status and blockers
|
|
193
179
|
- **`exit`** - Signal task completion with status code
|
|
194
180
|
|
|
195
|
-
### Skills Loading
|
|
196
|
-
|
|
197
|
-
Load skills from local directories and pass them as a feature to the agent. Skills are defined using `SKILL.md` files with front matter containing name and description.
|
|
198
|
-
|
|
199
|
-
```javascript
|
|
200
|
-
import { execute, loadSkills, createSkillsFeature } from '@chatbotkit/agent'
|
|
201
|
-
import { ChatBotKit } from '@chatbotkit/sdk'
|
|
202
|
-
|
|
203
|
-
const client = new ChatBotKit({ secret: process.env.CHATBOTKIT_API_TOKEN })
|
|
204
|
-
|
|
205
|
-
// Load skills from directories
|
|
206
|
-
const skillsResult = await loadSkills(['./skills'], { watch: true })
|
|
207
|
-
|
|
208
|
-
// Create the skills feature for the API
|
|
209
|
-
const skillsFeature = createSkillsFeature(skillsResult.skills)
|
|
210
|
-
|
|
211
|
-
const stream = execute({
|
|
212
|
-
client,
|
|
213
|
-
model: 'gpt-4o',
|
|
214
|
-
messages: [{ type: 'user', text: 'Help me with my task' }],
|
|
215
|
-
extensions: {
|
|
216
|
-
features: [skillsFeature],
|
|
217
|
-
},
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
for await (const event of stream) {
|
|
221
|
-
// Handle events
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Clean up when done
|
|
225
|
-
skillsResult.close()
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
#### SKILL.md Format
|
|
229
|
-
|
|
230
|
-
Create a `SKILL.md` file in each skill directory:
|
|
231
|
-
|
|
232
|
-
```markdown
|
|
233
|
-
---
|
|
234
|
-
name: My Skill
|
|
235
|
-
description: A brief description of what this skill does
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
# My Skill
|
|
239
|
-
|
|
240
|
-
Additional documentation for the skill...
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
#### Skills API
|
|
244
|
-
|
|
245
|
-
- **`loadSkills(directories, options)`** - Load skills from directories containing SKILL.md files
|
|
246
|
-
- **`createSkillsFeature(skills)`** - Create a feature configuration for the API
|
|
247
|
-
|
|
248
181
|
## Documentation
|
|
249
182
|
|
|
250
183
|
For comprehensive information about the ChatBotKit Agent SDK, including detailed documentation on its functionalities, helper methods, and configuration options, please visit our [type documentation page](https://chatbotkit.github.io/node-sdk/modules/_chatbotkit_agent.html).
|
package/dist/cjs/agent.cjs
CHANGED
|
@@ -5,7 +5,7 @@ exports.execute = execute;
|
|
|
5
5
|
const zod_1 = require("zod");
|
|
6
6
|
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
7
7
|
async function* complete(options) {
|
|
8
|
-
const { client, tools,
|
|
8
|
+
const { client, tools, ...request } = options;
|
|
9
9
|
const channelToTool = new Map();
|
|
10
10
|
const functions = tools
|
|
11
11
|
? Object.entries(tools).map(([name, tool]) => {
|
|
@@ -47,13 +47,10 @@ async function* complete(options) {
|
|
|
47
47
|
.complete(null, {
|
|
48
48
|
...request,
|
|
49
49
|
functions,
|
|
50
|
-
limits: {
|
|
51
|
-
iterations: 1,
|
|
52
|
-
},
|
|
53
50
|
})
|
|
54
|
-
.stream(
|
|
51
|
+
.stream();
|
|
55
52
|
const toolEventQueue = [];
|
|
56
|
-
const
|
|
53
|
+
const runningTools = new Set();
|
|
57
54
|
const executeToolAsync = async (channel, name, tool, args) => {
|
|
58
55
|
try {
|
|
59
56
|
let parsedArgs = args;
|
|
@@ -91,11 +88,11 @@ async function* complete(options) {
|
|
|
91
88
|
message: { error: errorMessage },
|
|
92
89
|
});
|
|
93
90
|
}
|
|
91
|
+
finally {
|
|
92
|
+
runningTools.delete(channel);
|
|
93
|
+
}
|
|
94
94
|
};
|
|
95
95
|
for await (const event of stream) {
|
|
96
|
-
if (abortSignal?.aborted) {
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
96
|
while (toolEventQueue.length > 0) {
|
|
100
97
|
const toolEvent = toolEventQueue.shift();
|
|
101
98
|
if (toolEvent) {
|
|
@@ -119,7 +116,9 @@ async function* complete(options) {
|
|
|
119
116
|
},
|
|
120
117
|
};
|
|
121
118
|
const toolPromise = executeToolAsync(channel, name, tool, args);
|
|
122
|
-
|
|
119
|
+
runningTools.add(channel);
|
|
120
|
+
toolPromise.catch(() => {
|
|
121
|
+
});
|
|
123
122
|
}
|
|
124
123
|
}
|
|
125
124
|
yield event;
|
|
@@ -130,8 +129,8 @@ async function* complete(options) {
|
|
|
130
129
|
yield toolEvent;
|
|
131
130
|
}
|
|
132
131
|
}
|
|
133
|
-
|
|
134
|
-
await Promise
|
|
132
|
+
while (runningTools.size > 0) {
|
|
133
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
135
134
|
while (toolEventQueue.length > 0) {
|
|
136
135
|
const toolEvent = toolEventQueue.shift();
|
|
137
136
|
if (toolEvent) {
|
|
@@ -141,10 +140,9 @@ async function* complete(options) {
|
|
|
141
140
|
}
|
|
142
141
|
}
|
|
143
142
|
async function* execute(options) {
|
|
144
|
-
const { client, tools = {}, maxIterations =
|
|
145
|
-
const messages = request.messages || [];
|
|
143
|
+
const { client, tools = {}, maxIterations = 50, ...request } = options;
|
|
144
|
+
const messages = [...(request.messages || [])];
|
|
146
145
|
let exitResult = null;
|
|
147
|
-
let internalAbort = null;
|
|
148
146
|
const systemTools = {
|
|
149
147
|
plan: {
|
|
150
148
|
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.',
|
|
@@ -211,29 +209,8 @@ async function* execute(options) {
|
|
|
211
209
|
};
|
|
212
210
|
},
|
|
213
211
|
},
|
|
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
212
|
};
|
|
236
|
-
const allTools = { ...
|
|
213
|
+
const allTools = { ...systemTools, ...tools };
|
|
237
214
|
const systemInstruction = `
|
|
238
215
|
${options.extensions?.backstory || ''}
|
|
239
216
|
|
|
@@ -245,58 +222,31 @@ The goal is to complete the assigned task efficiently and effectively. Follow th
|
|
|
245
222
|
2. **Track Progress**: Regularly use the 'progress' function to update status and identify issues
|
|
246
223
|
3. **Use Tools**: Leverage available tools to accomplish each step of your plan
|
|
247
224
|
4. **Exit When Done**: Call the 'exit' function with code 0 when successful, or non-zero code if unable to complete
|
|
248
|
-
5. **
|
|
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.
|
|
225
|
+
5. **Be Autonomous**: Work through the task systematically without waiting for additional input
|
|
251
226
|
`.trim();
|
|
252
227
|
let iteration = 0;
|
|
253
228
|
while (iteration < maxIterations && exitResult === null) {
|
|
254
|
-
if (abortSignal?.aborted) {
|
|
255
|
-
exitResult = {
|
|
256
|
-
code: 1,
|
|
257
|
-
message: 'Task execution aborted',
|
|
258
|
-
};
|
|
259
|
-
break;
|
|
260
|
-
}
|
|
261
229
|
iteration++;
|
|
262
230
|
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
231
|
for await (const event of complete({
|
|
274
232
|
...request,
|
|
275
233
|
client,
|
|
276
234
|
messages,
|
|
277
235
|
tools: allTools,
|
|
278
|
-
abortSignal: iterSignal,
|
|
279
236
|
extensions: {
|
|
280
237
|
...options.extensions,
|
|
281
238
|
backstory: systemInstruction,
|
|
282
239
|
},
|
|
283
240
|
})) {
|
|
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
241
|
yield event;
|
|
293
242
|
}
|
|
294
243
|
if (exitResult) {
|
|
295
244
|
break;
|
|
296
245
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
246
|
+
messages.push({
|
|
247
|
+
type: 'user',
|
|
248
|
+
text: 'Continue with the next step of your plan. If all steps are complete, call exit with the appropriate status code.',
|
|
249
|
+
});
|
|
300
250
|
}
|
|
301
251
|
if (exitResult === null) {
|
|
302
252
|
exitResult = {
|
package/dist/cjs/agent.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
export function complete(options:
|
|
1
|
+
export function complete(options: ConversationCompleteRequest & {
|
|
2
2
|
client: ChatBotKit;
|
|
3
3
|
tools?: Tools;
|
|
4
|
-
abortSignal?: AbortSignal;
|
|
5
4
|
}): AsyncGenerator<ConversationCompleteStreamType | ToolCallStartEvent | ToolCallEndEvent | ToolCallErrorEvent, void, unknown>;
|
|
6
|
-
export function execute(options:
|
|
5
|
+
export function execute(options: ConversationCompleteRequest & {
|
|
7
6
|
client: ChatBotKit;
|
|
8
7
|
tools?: Tools;
|
|
9
8
|
maxIterations?: number;
|
|
10
|
-
abortSignal?: AbortSignal;
|
|
11
9
|
}): AsyncGenerator<ConversationCompleteStreamType | ToolCallStartEvent | ToolCallEndEvent | ToolCallErrorEvent | IterationEvent | ExitEvent, void, unknown>;
|
|
12
10
|
export type ZodObject = import("zod").ZodObject<any>;
|
|
13
11
|
export type ChatBotKit = import("@chatbotkit/sdk").ChatBotKit;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.tools = exports.execute = exports.complete = void 0;
|
|
4
4
|
var agent_js_1 = require("./agent.cjs");
|
|
5
5
|
Object.defineProperty(exports, "complete", { enumerable: true, get: function () { return agent_js_1.complete; } });
|
|
6
6
|
Object.defineProperty(exports, "execute", { enumerable: true, get: function () { return agent_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; } });
|
package/dist/cjs/index.d.ts
CHANGED
package/dist/esm/agent.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
export function complete(options:
|
|
1
|
+
export function complete(options: ConversationCompleteRequest & {
|
|
2
2
|
client: ChatBotKit;
|
|
3
3
|
tools?: Tools;
|
|
4
|
-
abortSignal?: AbortSignal;
|
|
5
4
|
}): AsyncGenerator<ConversationCompleteStreamType | ToolCallStartEvent | ToolCallEndEvent | ToolCallErrorEvent, void, unknown>;
|
|
6
|
-
export function execute(options:
|
|
5
|
+
export function execute(options: ConversationCompleteRequest & {
|
|
7
6
|
client: ChatBotKit;
|
|
8
7
|
tools?: Tools;
|
|
9
8
|
maxIterations?: number;
|
|
10
|
-
abortSignal?: AbortSignal;
|
|
11
9
|
}): AsyncGenerator<ConversationCompleteStreamType | ToolCallStartEvent | ToolCallEndEvent | ToolCallErrorEvent | IterationEvent | ExitEvent, void, unknown>;
|
|
12
10
|
export type ZodObject = import("zod").ZodObject<any>;
|
|
13
11
|
export type ChatBotKit = import("@chatbotkit/sdk").ChatBotKit;
|
package/dist/esm/agent.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
3
|
export async function* complete(options) {
|
|
4
|
-
const { client, tools,
|
|
4
|
+
const { client, tools, ...request } = options;
|
|
5
5
|
const channelToTool = new Map();
|
|
6
6
|
const functions = tools
|
|
7
7
|
? Object.entries(tools).map(([name, tool]) => {
|
|
@@ -43,13 +43,10 @@ export async function* complete(options) {
|
|
|
43
43
|
.complete(null, {
|
|
44
44
|
...request,
|
|
45
45
|
functions,
|
|
46
|
-
limits: {
|
|
47
|
-
iterations: 1,
|
|
48
|
-
},
|
|
49
46
|
})
|
|
50
|
-
.stream(
|
|
47
|
+
.stream();
|
|
51
48
|
const toolEventQueue = [];
|
|
52
|
-
const
|
|
49
|
+
const runningTools = new Set();
|
|
53
50
|
const executeToolAsync = async (channel, name, tool, args) => {
|
|
54
51
|
try {
|
|
55
52
|
let parsedArgs = args;
|
|
@@ -87,11 +84,11 @@ export async function* complete(options) {
|
|
|
87
84
|
message: { error: errorMessage },
|
|
88
85
|
});
|
|
89
86
|
}
|
|
87
|
+
finally {
|
|
88
|
+
runningTools.delete(channel);
|
|
89
|
+
}
|
|
90
90
|
};
|
|
91
91
|
for await (const event of stream) {
|
|
92
|
-
if (abortSignal?.aborted) {
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
92
|
while (toolEventQueue.length > 0) {
|
|
96
93
|
const toolEvent = toolEventQueue.shift();
|
|
97
94
|
if (toolEvent) {
|
|
@@ -115,7 +112,9 @@ export async function* complete(options) {
|
|
|
115
112
|
},
|
|
116
113
|
};
|
|
117
114
|
const toolPromise = executeToolAsync(channel, name, tool, args);
|
|
118
|
-
|
|
115
|
+
runningTools.add(channel);
|
|
116
|
+
toolPromise.catch(() => {
|
|
117
|
+
});
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
yield event;
|
|
@@ -126,8 +125,8 @@ export async function* complete(options) {
|
|
|
126
125
|
yield toolEvent;
|
|
127
126
|
}
|
|
128
127
|
}
|
|
129
|
-
|
|
130
|
-
await Promise
|
|
128
|
+
while (runningTools.size > 0) {
|
|
129
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
131
130
|
while (toolEventQueue.length > 0) {
|
|
132
131
|
const toolEvent = toolEventQueue.shift();
|
|
133
132
|
if (toolEvent) {
|
|
@@ -137,10 +136,9 @@ export async function* complete(options) {
|
|
|
137
136
|
}
|
|
138
137
|
}
|
|
139
138
|
export async function* execute(options) {
|
|
140
|
-
const { client, tools = {}, maxIterations =
|
|
141
|
-
const messages = request.messages || [];
|
|
139
|
+
const { client, tools = {}, maxIterations = 50, ...request } = options;
|
|
140
|
+
const messages = [...(request.messages || [])];
|
|
142
141
|
let exitResult = null;
|
|
143
|
-
let internalAbort = null;
|
|
144
142
|
const systemTools = {
|
|
145
143
|
plan: {
|
|
146
144
|
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.',
|
|
@@ -207,29 +205,8 @@ export async function* execute(options) {
|
|
|
207
205
|
};
|
|
208
206
|
},
|
|
209
207
|
},
|
|
210
|
-
abort: {
|
|
211
|
-
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.',
|
|
212
|
-
input: z.object({
|
|
213
|
-
reason: z.string().optional().describe('Brief reason for aborting'),
|
|
214
|
-
hard: z
|
|
215
|
-
.boolean()
|
|
216
|
-
.optional()
|
|
217
|
-
.describe('If true, immediately kill running processes. If false (default), finish the current operation gracefully.'),
|
|
218
|
-
}),
|
|
219
|
-
handler: async (input) => {
|
|
220
|
-
const reason = input.reason || 'aborted by user request';
|
|
221
|
-
exitResult = { code: 1, message: reason };
|
|
222
|
-
if (input.hard && internalAbort) {
|
|
223
|
-
internalAbort.abort(reason);
|
|
224
|
-
}
|
|
225
|
-
return {
|
|
226
|
-
success: true,
|
|
227
|
-
message: `Task aborted: ${reason}`,
|
|
228
|
-
};
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
208
|
};
|
|
232
|
-
const allTools = { ...
|
|
209
|
+
const allTools = { ...systemTools, ...tools };
|
|
233
210
|
const systemInstruction = `
|
|
234
211
|
${options.extensions?.backstory || ''}
|
|
235
212
|
|
|
@@ -241,58 +218,31 @@ The goal is to complete the assigned task efficiently and effectively. Follow th
|
|
|
241
218
|
2. **Track Progress**: Regularly use the 'progress' function to update status and identify issues
|
|
242
219
|
3. **Use Tools**: Leverage available tools to accomplish each step of your plan
|
|
243
220
|
4. **Exit When Done**: Call the 'exit' function with code 0 when successful, or non-zero code if unable to complete
|
|
244
|
-
5. **
|
|
245
|
-
6. **Be Autonomous**: Work through the task systematically without waiting for additional input
|
|
246
|
-
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.
|
|
221
|
+
5. **Be Autonomous**: Work through the task systematically without waiting for additional input
|
|
247
222
|
`.trim();
|
|
248
223
|
let iteration = 0;
|
|
249
224
|
while (iteration < maxIterations && exitResult === null) {
|
|
250
|
-
if (abortSignal?.aborted) {
|
|
251
|
-
exitResult = {
|
|
252
|
-
code: 1,
|
|
253
|
-
message: 'Task execution aborted',
|
|
254
|
-
};
|
|
255
|
-
break;
|
|
256
|
-
}
|
|
257
225
|
iteration++;
|
|
258
226
|
yield { type: 'iteration', data: { iteration } };
|
|
259
|
-
let lastEndReason = null;
|
|
260
|
-
internalAbort = new AbortController();
|
|
261
|
-
if (abortSignal?.aborted) {
|
|
262
|
-
internalAbort.abort(abortSignal.reason);
|
|
263
|
-
}
|
|
264
|
-
else if (abortSignal) {
|
|
265
|
-
const capturedAbort = internalAbort;
|
|
266
|
-
abortSignal.addEventListener('abort', () => capturedAbort.abort(abortSignal.reason), { once: true });
|
|
267
|
-
}
|
|
268
|
-
const iterSignal = internalAbort.signal;
|
|
269
227
|
for await (const event of complete({
|
|
270
228
|
...request,
|
|
271
229
|
client,
|
|
272
230
|
messages,
|
|
273
231
|
tools: allTools,
|
|
274
|
-
abortSignal: iterSignal,
|
|
275
232
|
extensions: {
|
|
276
233
|
...options.extensions,
|
|
277
234
|
backstory: systemInstruction,
|
|
278
235
|
},
|
|
279
236
|
})) {
|
|
280
|
-
if (event.type === 'message') {
|
|
281
|
-
messages.push(event.data);
|
|
282
|
-
}
|
|
283
|
-
if (event.type === 'result') {
|
|
284
|
-
if (event.data.end.reason) {
|
|
285
|
-
lastEndReason = event.data.end.reason;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
237
|
yield event;
|
|
289
238
|
}
|
|
290
239
|
if (exitResult) {
|
|
291
240
|
break;
|
|
292
241
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
242
|
+
messages.push({
|
|
243
|
+
type: 'user',
|
|
244
|
+
text: 'Continue with the next step of your plan. If all steps are complete, call exit with the appropriate status code.',
|
|
245
|
+
});
|
|
296
246
|
}
|
|
297
247
|
if (exitResult === null) {
|
|
298
248
|
exitResult = {
|
package/dist/esm/index.d.ts
CHANGED
package/dist/esm/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatbotkit/agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.0",
|
|
4
4
|
"description": "ChatBotKit Agent implementation",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"engines": {
|
|
@@ -72,26 +72,6 @@
|
|
|
72
72
|
"default": "./dist/cjs/index.cjs"
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
|
-
"./skills": {
|
|
76
|
-
"import": {
|
|
77
|
-
"types": "./dist/esm/skills.d.ts",
|
|
78
|
-
"default": "./dist/esm/skills.js"
|
|
79
|
-
},
|
|
80
|
-
"require": {
|
|
81
|
-
"types": "./dist/cjs/skills.d.ts",
|
|
82
|
-
"default": "./dist/cjs/skills.cjs"
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
"./skills.js": {
|
|
86
|
-
"import": {
|
|
87
|
-
"types": "./dist/esm/skills.d.ts",
|
|
88
|
-
"default": "./dist/esm/skills.js"
|
|
89
|
-
},
|
|
90
|
-
"require": {
|
|
91
|
-
"types": "./dist/cjs/skills.d.ts",
|
|
92
|
-
"default": "./dist/cjs/skills.cjs"
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
75
|
"./tools": {
|
|
96
76
|
"import": {
|
|
97
77
|
"types": "./dist/esm/tools.d.ts",
|
|
@@ -116,14 +96,12 @@
|
|
|
116
96
|
},
|
|
117
97
|
"types": "./dist/cjs/index.d.ts",
|
|
118
98
|
"dependencies": {
|
|
119
|
-
"js-yaml": "^4.1.0",
|
|
120
99
|
"tslib": "^2.6.2",
|
|
121
100
|
"zod": "^3.25.76",
|
|
122
101
|
"zod-to-json-schema": "^3.24.6",
|
|
123
|
-
"@chatbotkit/sdk": "1.
|
|
102
|
+
"@chatbotkit/sdk": "1.28.0"
|
|
124
103
|
},
|
|
125
104
|
"devDependencies": {
|
|
126
|
-
"@types/js-yaml": "^4.0.9",
|
|
127
105
|
"npm-run-all": "^4.1.5",
|
|
128
106
|
"typedoc": "^0.28.14",
|
|
129
107
|
"typedoc-plugin-markdown": "^4.9.0",
|
package/dist/cjs/skills.cjs
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
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)(skillDir),
|
|
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
|
-
}
|
package/dist/cjs/skills.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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/skills.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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/skills.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { readFile, readdir, stat, watch } from 'fs/promises';
|
|
2
|
-
import yaml from 'js-yaml';
|
|
3
|
-
import { join, resolve } from 'path';
|
|
4
|
-
function parseFrontMatter(content) {
|
|
5
|
-
const frontMatterRegex = /^---\s*\n([\s\S]*?)\n---/;
|
|
6
|
-
const match = content.match(frontMatterRegex);
|
|
7
|
-
if (!match) {
|
|
8
|
-
return {};
|
|
9
|
-
}
|
|
10
|
-
try {
|
|
11
|
-
const frontMatter = match[1];
|
|
12
|
-
const parsed = (yaml.load(frontMatter));
|
|
13
|
-
if (typeof parsed !== 'object' || parsed === null) {
|
|
14
|
-
return {};
|
|
15
|
-
}
|
|
16
|
-
return {
|
|
17
|
-
name: typeof parsed.name === 'string' ? parsed.name : undefined,
|
|
18
|
-
description: typeof parsed.description === 'string' ? parsed.description : undefined,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return {};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
async function loadSkillFromDirectory(skillDir) {
|
|
26
|
-
const skillFilePath = join(skillDir, 'SKILL.md');
|
|
27
|
-
try {
|
|
28
|
-
const content = await readFile(skillFilePath, 'utf-8');
|
|
29
|
-
const { name, description } = parseFrontMatter(content);
|
|
30
|
-
if (!name || !description) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
return {
|
|
34
|
-
name,
|
|
35
|
-
description,
|
|
36
|
-
path: resolve(skillDir),
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
export async function loadSkills(directories, options = {}) {
|
|
44
|
-
const skills = ([]);
|
|
45
|
-
const watchControllers = ([]);
|
|
46
|
-
async function scanDirectory(baseDir) {
|
|
47
|
-
try {
|
|
48
|
-
const entries = await readdir(baseDir);
|
|
49
|
-
for (const entry of entries) {
|
|
50
|
-
const entryPath = join(baseDir, entry);
|
|
51
|
-
const entryStat = await stat(entryPath);
|
|
52
|
-
if (entryStat.isDirectory()) {
|
|
53
|
-
const skill = await loadSkillFromDirectory(entryPath);
|
|
54
|
-
if (skill) {
|
|
55
|
-
const existingIdx = skills.findIndex((s) => s.path === skill.path);
|
|
56
|
-
if (existingIdx !== -1) {
|
|
57
|
-
skills[existingIdx] = skill;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
skills.push(skill);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
for (const dir of directories) {
|
|
70
|
-
await scanDirectory(dir);
|
|
71
|
-
}
|
|
72
|
-
if (options.watch) {
|
|
73
|
-
for (const dir of directories) {
|
|
74
|
-
const controller = new AbortController();
|
|
75
|
-
watchControllers.push(controller);
|
|
76
|
-
(async () => {
|
|
77
|
-
try {
|
|
78
|
-
const watcher = watch(dir, {
|
|
79
|
-
recursive: true,
|
|
80
|
-
signal: controller.signal,
|
|
81
|
-
});
|
|
82
|
-
for await (const event of watcher) {
|
|
83
|
-
if (event.filename?.endsWith('SKILL.md')) {
|
|
84
|
-
await scanDirectory(dir);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
if (err instanceof Error &&
|
|
90
|
-
err.name !== 'AbortError' &&
|
|
91
|
-
!err.message.includes('AbortError')) {
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
})();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
skills,
|
|
99
|
-
close: () => {
|
|
100
|
-
for (const controller of watchControllers) {
|
|
101
|
-
controller.abort();
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
export function createSkillsFeature(skills) {
|
|
107
|
-
return {
|
|
108
|
-
name: ('skills'),
|
|
109
|
-
options: { skills },
|
|
110
|
-
};
|
|
111
|
-
}
|