@burtson-labs/agent-core 1.6.13
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 +201 -0
- package/README.md +88 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/activation.d.ts +60 -0
- package/dist/mcp/activation.d.ts.map +1 -0
- package/dist/mcp/activation.js +139 -0
- package/dist/mcp/activation.js.map +1 -0
- package/dist/mcp/clientPool.d.ts +202 -0
- package/dist/mcp/clientPool.d.ts.map +1 -0
- package/dist/mcp/clientPool.js +469 -0
- package/dist/mcp/clientPool.js.map +1 -0
- package/dist/mcp/index.d.ts +18 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +28 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +43 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +130 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/toolAdapter.d.ts +57 -0
- package/dist/mcp/toolAdapter.d.ts.map +1 -0
- package/dist/mcp/toolAdapter.js +223 -0
- package/dist/mcp/toolAdapter.js.map +1 -0
- package/dist/mcp/types.d.ts +122 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +15 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/providers/deterministic-provider.d.ts +21 -0
- package/dist/providers/deterministic-provider.d.ts.map +1 -0
- package/dist/providers/deterministic-provider.js +80 -0
- package/dist/providers/deterministic-provider.js.map +1 -0
- package/dist/providers/provider-client.d.ts +12 -0
- package/dist/providers/provider-client.d.ts.map +1 -0
- package/dist/providers/provider-client.js +11 -0
- package/dist/providers/provider-client.js.map +1 -0
- package/dist/runtime/AgentRuntime.d.ts +67 -0
- package/dist/runtime/AgentRuntime.d.ts.map +1 -0
- package/dist/runtime/AgentRuntime.js +382 -0
- package/dist/runtime/AgentRuntime.js.map +1 -0
- package/dist/security/secretPatterns.d.ts +76 -0
- package/dist/security/secretPatterns.d.ts.map +1 -0
- package/dist/security/secretPatterns.js +290 -0
- package/dist/security/secretPatterns.js.map +1 -0
- package/dist/tools/ask-user-tool.d.ts +19 -0
- package/dist/tools/ask-user-tool.d.ts.map +1 -0
- package/dist/tools/ask-user-tool.js +148 -0
- package/dist/tools/ask-user-tool.js.map +1 -0
- package/dist/tools/compactMessages.d.ts +52 -0
- package/dist/tools/compactMessages.d.ts.map +1 -0
- package/dist/tools/compactMessages.js +158 -0
- package/dist/tools/compactMessages.js.map +1 -0
- package/dist/tools/core-tools.d.ts +29 -0
- package/dist/tools/core-tools.d.ts.map +1 -0
- package/dist/tools/core-tools.js +2214 -0
- package/dist/tools/core-tools.js.map +1 -0
- package/dist/tools/git-tools.d.ts +32 -0
- package/dist/tools/git-tools.d.ts.map +1 -0
- package/dist/tools/git-tools.js +330 -0
- package/dist/tools/git-tools.js.map +1 -0
- package/dist/tools/index.d.ts +15 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +31 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/language-adapters.d.ts +48 -0
- package/dist/tools/language-adapters.d.ts.map +1 -0
- package/dist/tools/language-adapters.js +299 -0
- package/dist/tools/language-adapters.js.map +1 -0
- package/dist/tools/loop/compactionTrigger.d.ts +47 -0
- package/dist/tools/loop/compactionTrigger.d.ts.map +1 -0
- package/dist/tools/loop/compactionTrigger.js +32 -0
- package/dist/tools/loop/compactionTrigger.js.map +1 -0
- package/dist/tools/loop/finalAnswerNudges.d.ts +68 -0
- package/dist/tools/loop/finalAnswerNudges.d.ts.map +1 -0
- package/dist/tools/loop/finalAnswerNudges.js +87 -0
- package/dist/tools/loop/finalAnswerNudges.js.map +1 -0
- package/dist/tools/loop/goalAnchor.d.ts +72 -0
- package/dist/tools/loop/goalAnchor.d.ts.map +1 -0
- package/dist/tools/loop/goalAnchor.js +76 -0
- package/dist/tools/loop/goalAnchor.js.map +1 -0
- package/dist/tools/loop/llmStream.d.ts +70 -0
- package/dist/tools/loop/llmStream.d.ts.map +1 -0
- package/dist/tools/loop/llmStream.js +181 -0
- package/dist/tools/loop/llmStream.js.map +1 -0
- package/dist/tools/loop/parallelExecute.d.ts +57 -0
- package/dist/tools/loop/parallelExecute.d.ts.map +1 -0
- package/dist/tools/loop/parallelExecute.js +54 -0
- package/dist/tools/loop/parallelExecute.js.map +1 -0
- package/dist/tools/loop/singleToolExecute.d.ts +71 -0
- package/dist/tools/loop/singleToolExecute.d.ts.map +1 -0
- package/dist/tools/loop/singleToolExecute.js +139 -0
- package/dist/tools/loop/singleToolExecute.js.map +1 -0
- package/dist/tools/loop/toolCallNormalize.d.ts +57 -0
- package/dist/tools/loop/toolCallNormalize.d.ts.map +1 -0
- package/dist/tools/loop/toolCallNormalize.js +99 -0
- package/dist/tools/loop/toolCallNormalize.js.map +1 -0
- package/dist/tools/loop/turnSetup.d.ts +43 -0
- package/dist/tools/loop/turnSetup.d.ts.map +1 -0
- package/dist/tools/loop/turnSetup.js +48 -0
- package/dist/tools/loop/turnSetup.js.map +1 -0
- package/dist/tools/ocr.d.ts +52 -0
- package/dist/tools/ocr.d.ts.map +1 -0
- package/dist/tools/ocr.js +238 -0
- package/dist/tools/ocr.js.map +1 -0
- package/dist/tools/post-edit-checks.d.ts +46 -0
- package/dist/tools/post-edit-checks.d.ts.map +1 -0
- package/dist/tools/post-edit-checks.js +236 -0
- package/dist/tools/post-edit-checks.js.map +1 -0
- package/dist/tools/skill-loader.d.ts +94 -0
- package/dist/tools/skill-loader.d.ts.map +1 -0
- package/dist/tools/skill-loader.js +422 -0
- package/dist/tools/skill-loader.js.map +1 -0
- package/dist/tools/skill-registry.d.ts +44 -0
- package/dist/tools/skill-registry.d.ts.map +1 -0
- package/dist/tools/skill-registry.js +118 -0
- package/dist/tools/skill-registry.js.map +1 -0
- package/dist/tools/skill-types.d.ts +38 -0
- package/dist/tools/skill-types.d.ts.map +1 -0
- package/dist/tools/skill-types.js +10 -0
- package/dist/tools/skill-types.js.map +1 -0
- package/dist/tools/skills/code-review-skill.d.ts +9 -0
- package/dist/tools/skills/code-review-skill.d.ts.map +1 -0
- package/dist/tools/skills/code-review-skill.js +66 -0
- package/dist/tools/skills/code-review-skill.js.map +1 -0
- package/dist/tools/skills/core-skill.d.ts +13 -0
- package/dist/tools/skills/core-skill.d.ts.map +1 -0
- package/dist/tools/skills/core-skill.js +23 -0
- package/dist/tools/skills/core-skill.js.map +1 -0
- package/dist/tools/skills/git-skill.d.ts +10 -0
- package/dist/tools/skills/git-skill.d.ts.map +1 -0
- package/dist/tools/skills/git-skill.js +30 -0
- package/dist/tools/skills/git-skill.js.map +1 -0
- package/dist/tools/skills/index.d.ts +17 -0
- package/dist/tools/skills/index.d.ts.map +1 -0
- package/dist/tools/skills/index.js +49 -0
- package/dist/tools/skills/index.js.map +1 -0
- package/dist/tools/skills/interaction-skill.d.ts +14 -0
- package/dist/tools/skills/interaction-skill.d.ts.map +1 -0
- package/dist/tools/skills/interaction-skill.js +24 -0
- package/dist/tools/skills/interaction-skill.js.map +1 -0
- package/dist/tools/skills/mail-search-skill.d.ts +25 -0
- package/dist/tools/skills/mail-search-skill.d.ts.map +1 -0
- package/dist/tools/skills/mail-search-skill.js +343 -0
- package/dist/tools/skills/mail-search-skill.js.map +1 -0
- package/dist/tools/skills/plan-skill.d.ts +10 -0
- package/dist/tools/skills/plan-skill.d.ts.map +1 -0
- package/dist/tools/skills/plan-skill.js +126 -0
- package/dist/tools/skills/plan-skill.js.map +1 -0
- package/dist/tools/skills/semantic-search-skill.d.ts +22 -0
- package/dist/tools/skills/semantic-search-skill.d.ts.map +1 -0
- package/dist/tools/skills/semantic-search-skill.js +244 -0
- package/dist/tools/skills/semantic-search-skill.js.map +1 -0
- package/dist/tools/skills/test-gen-skill.d.ts +9 -0
- package/dist/tools/skills/test-gen-skill.d.ts.map +1 -0
- package/dist/tools/skills/test-gen-skill.js +123 -0
- package/dist/tools/skills/test-gen-skill.js.map +1 -0
- package/dist/tools/tool-registry.d.ts +60 -0
- package/dist/tools/tool-registry.d.ts.map +1 -0
- package/dist/tools/tool-registry.js +200 -0
- package/dist/tools/tool-registry.js.map +1 -0
- package/dist/tools/tool-types.d.ts +281 -0
- package/dist/tools/tool-types.d.ts.map +1 -0
- package/dist/tools/tool-types.js +10 -0
- package/dist/tools/tool-types.js.map +1 -0
- package/dist/tools/tool-use-loop.d.ts +231 -0
- package/dist/tools/tool-use-loop.d.ts.map +1 -0
- package/dist/tools/tool-use-loop.js +2057 -0
- package/dist/tools/tool-use-loop.js.map +1 -0
- package/dist/tools/tool-use-parser.d.ts +78 -0
- package/dist/tools/tool-use-parser.d.ts.map +1 -0
- package/dist/tools/tool-use-parser.js +427 -0
- package/dist/tools/tool-use-parser.js.map +1 -0
- package/dist/tools/toolAvailabilityDetector.d.ts +48 -0
- package/dist/tools/toolAvailabilityDetector.d.ts.map +1 -0
- package/dist/tools/toolAvailabilityDetector.js +156 -0
- package/dist/tools/toolAvailabilityDetector.js.map +1 -0
- package/dist/tools/unified-patch.d.ts +87 -0
- package/dist/tools/unified-patch.d.ts.map +1 -0
- package/dist/tools/unified-patch.js +217 -0
- package/dist/tools/unified-patch.js.map +1 -0
- package/dist/types/agent.d.ts +69 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +54 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/tasks.d.ts +22 -0
- package/dist/types/tasks.d.ts.map +1 -0
- package/dist/types/tasks.js +3 -0
- package/dist/types/tasks.js.map +1 -0
- package/dist/utils/event-emitter.d.ts +13 -0
- package/dist/utils/event-emitter.d.ts.map +1 -0
- package/dist/utils/event-emitter.js +54 -0
- package/dist/utils/event-emitter.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Skill loader — discovers and loads custom skills from the workspace.
|
|
4
|
+
*
|
|
5
|
+
* Scans `.bandit/skills/` and registers any skills it finds with the
|
|
6
|
+
* SkillRegistry. Two formats are supported:
|
|
7
|
+
*
|
|
8
|
+
* 1. Markdown (`.md`) — preferred. Matches Claude Code's shape. A skill is
|
|
9
|
+
* a context package: YAML frontmatter for metadata, markdown body for
|
|
10
|
+
* the prose instructions the agent reads when the skill activates.
|
|
11
|
+
* No `tools[]` — skills guide the agent on how to use tools it already
|
|
12
|
+
* has (run_command, git_*, write_file, …). This eliminates the nested
|
|
13
|
+
* JSON-in-JSON escaping trap that plagued the JSON format.
|
|
14
|
+
*
|
|
15
|
+
* 2. JSON (`.json`) — legacy. Still loads so existing `.bandit/skills/*.json`
|
|
16
|
+
* keep working, but new authoring should use markdown. Logs a one-time
|
|
17
|
+
* deprecation note in dev.
|
|
18
|
+
*
|
|
19
|
+
* Markdown layout (both `.bandit/skills/<name>.md` and
|
|
20
|
+
* `.bandit/skills/<name>/SKILL.md` are supported — the folder variant lets
|
|
21
|
+
* users bundle helper scripts next to the skill):
|
|
22
|
+
*
|
|
23
|
+
* ---
|
|
24
|
+
* id: github
|
|
25
|
+
* name: GitHub CLI
|
|
26
|
+
* description: Use when the user mentions GitHub — PRs, issues, commits
|
|
27
|
+
* triggers: [gh, github, pr, "pull request"]
|
|
28
|
+
* ---
|
|
29
|
+
*
|
|
30
|
+
* When the user asks about GitHub work, use `run_command` with `gh`:
|
|
31
|
+
*
|
|
32
|
+
* - `gh pr create --title "<t>" --body "<b>"` — open a PR
|
|
33
|
+
* - `gh pr list` — list open PRs
|
|
34
|
+
* - `gh issue list` — list issues
|
|
35
|
+
*
|
|
36
|
+
* Suggest `gh auth status` if commands fail.
|
|
37
|
+
*
|
|
38
|
+
* Frontmatter keys recognized: `id`, `name`, `description`, `version`,
|
|
39
|
+
* `activation` (always|auto|on-demand — defaults to auto), `triggers`
|
|
40
|
+
* (simple substring list — matched case-insensitive against the user
|
|
41
|
+
* message), and `triggerPatterns` (explicit regex list — advanced).
|
|
42
|
+
*
|
|
43
|
+
* Legacy JSON schema (still supported, deprecated for new skills):
|
|
44
|
+
*
|
|
45
|
+
* {
|
|
46
|
+
* "id": "custom/my-skill",
|
|
47
|
+
* "name": "My Custom Skill",
|
|
48
|
+
* "description": "…",
|
|
49
|
+
* "activation": "auto",
|
|
50
|
+
* "triggerPatterns": ["\\bmy-keyword\\b"],
|
|
51
|
+
* "tools": [
|
|
52
|
+
* { "name": "my_tool", "description": "…", "command": "node x.js {{arg}}" }
|
|
53
|
+
* ]
|
|
54
|
+
* }
|
|
55
|
+
*/
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.buildToolFromManifest = buildToolFromManifest;
|
|
58
|
+
exports.loadWorkspaceSkills = loadWorkspaceSkills;
|
|
59
|
+
exports.registerWorkspaceSkills = registerWorkspaceSkills;
|
|
60
|
+
exports.scaffoldMarkdownSkill = scaffoldMarkdownSkill;
|
|
61
|
+
const SKILLS_DIR = '.bandit/skills';
|
|
62
|
+
function buildToolFromManifest(raw) {
|
|
63
|
+
const parameters = (raw.parameters ?? []).map((p) => ({
|
|
64
|
+
name: p.name,
|
|
65
|
+
description: p.description,
|
|
66
|
+
required: p.required ?? false
|
|
67
|
+
}));
|
|
68
|
+
if (raw.command) {
|
|
69
|
+
// Command-based tool — executes a shell command with parameter substitution.
|
|
70
|
+
//
|
|
71
|
+
// Split the template into base + args FIRST, then substitute params into
|
|
72
|
+
// each token individually. The earlier "substitute then split on /\s+/"
|
|
73
|
+
// shape let a param value containing whitespace explode into multiple
|
|
74
|
+
// argv entries — e.g. command="git {{op}}" with op="log; touch /tmp/x"
|
|
75
|
+
// resolved to ['git', 'log;', 'touch', '/tmp/x']. ctx.runCommand passes
|
|
76
|
+
// args straight to spawn() so no shell interpretation occurred, but the
|
|
77
|
+
// injected tokens still reached the binary as extra arguments — and for
|
|
78
|
+
// commands that accept --exec-style flags (find, git, ssh), that's a
|
|
79
|
+
// privilege escalation vector. Per-token substitution keeps each param
|
|
80
|
+
// value as exactly one argv element regardless of its contents.
|
|
81
|
+
const templateParts = raw.command.trim().split(/\s+/);
|
|
82
|
+
return {
|
|
83
|
+
name: raw.name,
|
|
84
|
+
description: raw.description,
|
|
85
|
+
parameters,
|
|
86
|
+
async execute(params, ctx) {
|
|
87
|
+
const substitute = (token) => {
|
|
88
|
+
let out = token;
|
|
89
|
+
for (const [key, value] of Object.entries(params)) {
|
|
90
|
+
out = out.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value ?? '');
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
};
|
|
94
|
+
const base = substitute(templateParts[0]);
|
|
95
|
+
const args = templateParts.slice(1).map(substitute);
|
|
96
|
+
try {
|
|
97
|
+
const result = await ctx.runCommand(base, args, ctx.workspaceRoot);
|
|
98
|
+
const output = [
|
|
99
|
+
result.stdout.trim(),
|
|
100
|
+
result.stderr.trim() ? `stderr: ${result.stderr.trim()}` : ''
|
|
101
|
+
].filter(Boolean).join('\n');
|
|
102
|
+
return { output: output || '(no output)', isError: result.exitCode !== 0 };
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return { output: `Error: ${err instanceof Error ? err.message : String(err)}`, isError: true };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Placeholder tool — no command, just returns a message
|
|
111
|
+
return {
|
|
112
|
+
name: raw.name,
|
|
113
|
+
description: raw.description,
|
|
114
|
+
parameters,
|
|
115
|
+
async execute() {
|
|
116
|
+
return { output: `Tool "${raw.name}" has no command configured.`, isError: true };
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Compile activation hints into RegExp[]. Accepts both the simple `triggers`
|
|
122
|
+
* list (substrings, matched case-insensitive with word-boundary sensitivity
|
|
123
|
+
* where possible) and the advanced `triggerPatterns` list (explicit regex).
|
|
124
|
+
* Invalid patterns are dropped with a warning rather than failing the whole
|
|
125
|
+
* load — skills written by the model sometimes produce junk patterns and
|
|
126
|
+
* the whole skill shouldn't vanish because of one.
|
|
127
|
+
*/
|
|
128
|
+
function compileTriggers(simple, patterns, filePath) {
|
|
129
|
+
const compiled = [];
|
|
130
|
+
for (const term of simple ?? []) {
|
|
131
|
+
const trimmed = term.trim();
|
|
132
|
+
if (!trimmed)
|
|
133
|
+
continue;
|
|
134
|
+
// Escape regex metachars in user-supplied substrings, then anchor at
|
|
135
|
+
// word boundaries for single-word terms. Multi-word terms ("pull
|
|
136
|
+
// request") keep internal whitespace flexible via `\s+`.
|
|
137
|
+
const escaped = trimmed.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\s+/g, '\\s+');
|
|
138
|
+
const boundary = /\s/.test(trimmed) ? escaped : `\\b${escaped}\\b`;
|
|
139
|
+
try {
|
|
140
|
+
compiled.push(new RegExp(boundary, 'i'));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
console.warn(`[skill-loader] Could not compile trigger "${trimmed}" in ${filePath}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
for (const pattern of patterns ?? []) {
|
|
147
|
+
try {
|
|
148
|
+
compiled.push(new RegExp(pattern, 'i'));
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
console.warn(`[skill-loader] Invalid regex "${pattern}" in ${filePath}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return compiled;
|
|
155
|
+
}
|
|
156
|
+
function parseSkillManifest(json, filePath) {
|
|
157
|
+
try {
|
|
158
|
+
const raw = JSON.parse(json);
|
|
159
|
+
if (!raw.id || !raw.name || !Array.isArray(raw.tools) || raw.tools.length === 0) {
|
|
160
|
+
console.warn(`[skill-loader] Invalid manifest at ${filePath}: missing id, name, or tools`);
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const tools = raw.tools
|
|
164
|
+
.filter((t) => t.name && t.description)
|
|
165
|
+
.map(buildToolFromManifest);
|
|
166
|
+
if (tools.length === 0) {
|
|
167
|
+
console.warn(`[skill-loader] No valid tools in ${filePath}`);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
const triggerPatterns = compileTriggers(undefined, raw.triggerPatterns, filePath);
|
|
171
|
+
return {
|
|
172
|
+
id: raw.id,
|
|
173
|
+
name: raw.name,
|
|
174
|
+
version: raw.version ?? '0.0.0',
|
|
175
|
+
description: raw.description,
|
|
176
|
+
instructions: raw.instructions,
|
|
177
|
+
activation: raw.activation ?? 'auto',
|
|
178
|
+
triggerPatterns: triggerPatterns.length > 0 ? triggerPatterns : undefined,
|
|
179
|
+
tools
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
console.warn(`[skill-loader] Failed to parse ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Split a markdown skill file into (frontmatter object, body string).
|
|
189
|
+
* The frontmatter block is `---\n…\n---` at the top of the file. If it's
|
|
190
|
+
* missing, treat the entire file as the body and return an empty front-
|
|
191
|
+
* matter object — the caller decides whether that's fatal (it is: a skill
|
|
192
|
+
* needs at minimum an `id`).
|
|
193
|
+
*
|
|
194
|
+
* We parse just enough YAML to cover the supported keys (string scalars,
|
|
195
|
+
* quoted strings, inline `[a, b, "c d"]` arrays, and block-style dash
|
|
196
|
+
* lists). Full YAML is deliberately avoided — it's a heavy dep for a
|
|
197
|
+
* format we control, and richer YAML features would invite new ways for
|
|
198
|
+
* model-authored skills to silently corrupt.
|
|
199
|
+
*/
|
|
200
|
+
function splitFrontmatter(source) {
|
|
201
|
+
const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
202
|
+
if (!match) {
|
|
203
|
+
return { frontmatter: {}, body: source.trim() };
|
|
204
|
+
}
|
|
205
|
+
return { frontmatter: parseYamlFrontmatter(match[1]), body: match[2].trim() };
|
|
206
|
+
}
|
|
207
|
+
function parseYamlFrontmatter(block) {
|
|
208
|
+
const out = {};
|
|
209
|
+
const lines = block.split(/\r?\n/);
|
|
210
|
+
let currentKey = null;
|
|
211
|
+
let currentList = null;
|
|
212
|
+
for (const raw of lines) {
|
|
213
|
+
const line = raw.replace(/\t/g, ' ');
|
|
214
|
+
if (!line.trim() || line.trim().startsWith('#'))
|
|
215
|
+
continue;
|
|
216
|
+
// Block-style list item (continuation of the current key).
|
|
217
|
+
const listMatch = line.match(/^\s*-\s+(.*)$/);
|
|
218
|
+
if (listMatch && currentList) {
|
|
219
|
+
currentList.push(stripYamlScalar(listMatch[1]));
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// A new top-level `key:` line ends any block list we were building.
|
|
223
|
+
const kvMatch = line.match(/^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/);
|
|
224
|
+
if (!kvMatch)
|
|
225
|
+
continue;
|
|
226
|
+
currentList = null;
|
|
227
|
+
currentKey = kvMatch[1];
|
|
228
|
+
const value = kvMatch[2].trim();
|
|
229
|
+
if (value === '') {
|
|
230
|
+
// Block list follows on subsequent lines.
|
|
231
|
+
const list = [];
|
|
232
|
+
out[currentKey] = list;
|
|
233
|
+
currentList = list;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
237
|
+
out[currentKey] = parseYamlInlineArray(value);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
out[currentKey] = stripYamlScalar(value);
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
function stripYamlScalar(value) {
|
|
245
|
+
const trimmed = value.trim();
|
|
246
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
247
|
+
// Minimal escape decoding — \" and \\ only. Good enough for the keys
|
|
248
|
+
// we support; anything fancier is a red flag the author should know about.
|
|
249
|
+
return trimmed.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
|
250
|
+
}
|
|
251
|
+
if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
252
|
+
return trimmed.slice(1, -1).replace(/''/g, "'");
|
|
253
|
+
}
|
|
254
|
+
return trimmed;
|
|
255
|
+
}
|
|
256
|
+
function parseYamlInlineArray(source) {
|
|
257
|
+
const inner = source.slice(1, -1).trim();
|
|
258
|
+
if (!inner)
|
|
259
|
+
return [];
|
|
260
|
+
const out = [];
|
|
261
|
+
let buf = '';
|
|
262
|
+
let quote = null;
|
|
263
|
+
for (let i = 0; i < inner.length; i++) {
|
|
264
|
+
const ch = inner[i];
|
|
265
|
+
if (quote) {
|
|
266
|
+
if (ch === quote) {
|
|
267
|
+
quote = null;
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
if (ch === '\\' && i + 1 < inner.length) {
|
|
271
|
+
buf += inner[++i];
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
buf += ch;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
if (ch === '"' || ch === "'") {
|
|
278
|
+
quote = ch;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (ch === ',') {
|
|
282
|
+
const trimmed = buf.trim();
|
|
283
|
+
if (trimmed)
|
|
284
|
+
out.push(trimmed);
|
|
285
|
+
buf = '';
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
buf += ch;
|
|
289
|
+
}
|
|
290
|
+
const tail = buf.trim();
|
|
291
|
+
if (tail)
|
|
292
|
+
out.push(tail);
|
|
293
|
+
return out;
|
|
294
|
+
}
|
|
295
|
+
function parseMarkdownSkill(source, filePath) {
|
|
296
|
+
const { frontmatter, body } = splitFrontmatter(source);
|
|
297
|
+
if (!frontmatter.id || !frontmatter.name) {
|
|
298
|
+
console.warn(`[skill-loader] Markdown skill ${filePath} missing id or name in frontmatter — skipping`);
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const triggerPatterns = compileTriggers(frontmatter.triggers, frontmatter.triggerPatterns, filePath);
|
|
302
|
+
const activation = frontmatter.activation ?? 'auto';
|
|
303
|
+
// 'auto' activation with no triggers would silently never fire. Catch
|
|
304
|
+
// that at load time rather than leaving the author confused later.
|
|
305
|
+
if (activation === 'auto' && triggerPatterns.length === 0) {
|
|
306
|
+
console.warn(`[skill-loader] ${filePath}: activation=auto but no triggers — skill will never auto-activate`);
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
id: frontmatter.id,
|
|
310
|
+
name: frontmatter.name,
|
|
311
|
+
version: frontmatter.version ?? '0.0.0',
|
|
312
|
+
description: frontmatter.description ?? body.split('\n', 1)[0] ?? frontmatter.name,
|
|
313
|
+
instructions: body || undefined,
|
|
314
|
+
activation,
|
|
315
|
+
triggerPatterns: triggerPatterns.length > 0 ? triggerPatterns : undefined,
|
|
316
|
+
tools: []
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Load custom skills from `.bandit/skills/` in the workspace.
|
|
321
|
+
*
|
|
322
|
+
* Discovers markdown skills first (preferred), then JSON skills (legacy).
|
|
323
|
+
* When a JSON skill has the same id as a markdown one already loaded, the
|
|
324
|
+
* markdown version wins and the JSON one is skipped — that's the migration
|
|
325
|
+
* path: drop a `.md` next to the old `.json` and the new format takes over.
|
|
326
|
+
*
|
|
327
|
+
* @param listFiles lists files matching a glob pattern relative to cwd
|
|
328
|
+
* @param readFile reads a file's text content at an absolute path
|
|
329
|
+
* @param workspaceRoot absolute workspace root
|
|
330
|
+
*/
|
|
331
|
+
async function loadWorkspaceSkills(listFiles, readFile, workspaceRoot) {
|
|
332
|
+
const skills = [];
|
|
333
|
+
const loadedIds = new Set();
|
|
334
|
+
const tryLoad = async (file, parse) => {
|
|
335
|
+
try {
|
|
336
|
+
// Cross-platform absolute-path detection: POSIX `/`, tilde,
|
|
337
|
+
// Windows drive (`C:\`), or UNC (`\\srv\share`). Without the
|
|
338
|
+
// Windows checks, an absolute path like `C:\Users\…\skill.json`
|
|
339
|
+
// gets concatenated onto workspaceRoot.
|
|
340
|
+
const absPath = file.startsWith('/') ||
|
|
341
|
+
file.startsWith('~') ||
|
|
342
|
+
/^[A-Za-z]:[\\/]/.test(file) ||
|
|
343
|
+
file.startsWith('\\\\')
|
|
344
|
+
? file
|
|
345
|
+
: `${workspaceRoot}/${file}`;
|
|
346
|
+
const content = await readFile(absPath);
|
|
347
|
+
const skill = parse(content, file);
|
|
348
|
+
if (!skill)
|
|
349
|
+
return;
|
|
350
|
+
if (loadedIds.has(skill.id)) {
|
|
351
|
+
console.warn(`[skill-loader] Duplicate skill id "${skill.id}" in ${file} — ignoring (already loaded)`);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
loadedIds.add(skill.id);
|
|
355
|
+
skills.push(skill);
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// Unreadable file — silent skip, same as the JSON-era behavior.
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
// Markdown first — new format wins when ids collide.
|
|
362
|
+
try {
|
|
363
|
+
const mdFiles = await listFiles(`${SKILLS_DIR}/*.md`, workspaceRoot);
|
|
364
|
+
const nestedMd = await listFiles(`${SKILLS_DIR}/*/SKILL.md`, workspaceRoot);
|
|
365
|
+
for (const file of [...mdFiles, ...nestedMd]) {
|
|
366
|
+
await tryLoad(file, parseMarkdownSkill);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
// No markdown skills — fine.
|
|
371
|
+
}
|
|
372
|
+
try {
|
|
373
|
+
const jsonFiles = await listFiles(`${SKILLS_DIR}/*.json`, workspaceRoot);
|
|
374
|
+
for (const file of jsonFiles) {
|
|
375
|
+
await tryLoad(file, parseSkillManifest);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// No json skills either — also fine.
|
|
380
|
+
}
|
|
381
|
+
return skills;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Load workspace skills and register them with the given registry.
|
|
385
|
+
*/
|
|
386
|
+
async function registerWorkspaceSkills(registry, listFiles, readFile, workspaceRoot) {
|
|
387
|
+
const skills = await loadWorkspaceSkills(listFiles, readFile, workspaceRoot);
|
|
388
|
+
for (const skill of skills) {
|
|
389
|
+
registry.register(skill);
|
|
390
|
+
}
|
|
391
|
+
return skills.length;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* A ready-to-save markdown skill scaffold. Used by the CLI's `/skill new`
|
|
395
|
+
* slash command so users (and the agent) never have to hand-write the YAML
|
|
396
|
+
* frontmatter from scratch. Kept here so there's one canonical template
|
|
397
|
+
* and it can't drift from what the parser expects.
|
|
398
|
+
*/
|
|
399
|
+
function scaffoldMarkdownSkill(id, displayName) {
|
|
400
|
+
const safeId = id.trim() || 'my-skill';
|
|
401
|
+
const name = (displayName ?? safeId).trim();
|
|
402
|
+
return [
|
|
403
|
+
'---',
|
|
404
|
+
`id: ${safeId}`,
|
|
405
|
+
`name: ${name}`,
|
|
406
|
+
`description: One line explaining WHEN the agent should reach for this skill.`,
|
|
407
|
+
`activation: auto`,
|
|
408
|
+
`triggers: [${safeId}]`,
|
|
409
|
+
'---',
|
|
410
|
+
'',
|
|
411
|
+
`# ${name}`,
|
|
412
|
+
'',
|
|
413
|
+
'Describe the playbook the agent should follow when this skill activates.',
|
|
414
|
+
'Prefer prose + fenced examples over rigid schemas — the body is fed straight',
|
|
415
|
+
'into the system prompt when a trigger matches.',
|
|
416
|
+
'',
|
|
417
|
+
'- When the user asks …, run `…`',
|
|
418
|
+
'- If … fails, suggest `…`',
|
|
419
|
+
''
|
|
420
|
+
].join('\n');
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=skill-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../../src/tools/skill-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillRegistry — manages skill discovery, activation, and tool assembly.
|
|
3
|
+
*
|
|
4
|
+
* Builds on top of ToolRegistry. Skills are the unit of extensibility;
|
|
5
|
+
* ToolRegistry remains the unit of execution (what ToolUseLoop consumes).
|
|
6
|
+
*/
|
|
7
|
+
import type { SkillManifest } from './skill-types';
|
|
8
|
+
import { ToolRegistry } from './tool-registry';
|
|
9
|
+
export declare class SkillRegistry {
|
|
10
|
+
private readonly skills;
|
|
11
|
+
register(skill: SkillManifest): this;
|
|
12
|
+
registerAll(skills: SkillManifest[]): this;
|
|
13
|
+
get(id: string): SkillManifest | undefined;
|
|
14
|
+
getAll(): SkillManifest[];
|
|
15
|
+
has(id: string): boolean;
|
|
16
|
+
get size(): number;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve which skills should be active for a given user prompt.
|
|
19
|
+
*
|
|
20
|
+
* Returns all 'always' skills plus any 'auto' skills whose triggerPatterns
|
|
21
|
+
* match the prompt. 'on-demand' skills are excluded unless explicitly listed
|
|
22
|
+
* in the `include` array.
|
|
23
|
+
*/
|
|
24
|
+
resolveActiveSkills(prompt: string, include?: string[]): SkillManifest[];
|
|
25
|
+
/**
|
|
26
|
+
* Build a ToolRegistry containing all tools from the given active skills.
|
|
27
|
+
* Logs a warning on tool name collisions (last skill wins).
|
|
28
|
+
*/
|
|
29
|
+
buildToolRegistry(activeSkills: SkillManifest[]): ToolRegistry;
|
|
30
|
+
/**
|
|
31
|
+
* Build a ToolRegistry plus a map of tool name → owning skill id so callers
|
|
32
|
+
* can surface skill-level context (e.g. "using skill: Linter") when a tool runs.
|
|
33
|
+
*/
|
|
34
|
+
buildToolRegistryWithMap(activeSkills: SkillManifest[]): {
|
|
35
|
+
registry: ToolRegistry;
|
|
36
|
+
toolToSkill: Map<string, string>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Build system prompt section describing active skills and their tools.
|
|
40
|
+
* Includes skill instructions and delegates tool definitions to ToolRegistry.
|
|
41
|
+
*/
|
|
42
|
+
buildSkillPromptBlock(activeSkills: SkillManifest[]): string;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=skill-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-registry.d.ts","sourceRoot":"","sources":["../../src/tools/skill-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAE3D,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAQpC,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI;IAO1C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI1C,MAAM,IAAI,aAAa,EAAE;IAIzB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE;IAwBxE;;;OAGG;IACH,iBAAiB,CAAC,YAAY,EAAE,aAAa,EAAE,GAAG,YAAY;IAI9D;;;OAGG;IACH,wBAAwB,CAAC,YAAY,EAAE,aAAa,EAAE,GAAG;QACvD,QAAQ,EAAE,YAAY,CAAC;QACvB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC;IAqBD;;;OAGG;IACH,qBAAqB,CAAC,YAAY,EAAE,aAAa,EAAE,GAAG,MAAM;CAmB7D"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SkillRegistry — manages skill discovery, activation, and tool assembly.
|
|
4
|
+
*
|
|
5
|
+
* Builds on top of ToolRegistry. Skills are the unit of extensibility;
|
|
6
|
+
* ToolRegistry remains the unit of execution (what ToolUseLoop consumes).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.SkillRegistry = void 0;
|
|
10
|
+
const tool_registry_1 = require("./tool-registry");
|
|
11
|
+
class SkillRegistry {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.skills = new Map();
|
|
14
|
+
}
|
|
15
|
+
register(skill) {
|
|
16
|
+
if (this.skills.has(skill.id)) {
|
|
17
|
+
console.warn(`[SkillRegistry] Overwriting existing skill "${skill.id}"`);
|
|
18
|
+
}
|
|
19
|
+
this.skills.set(skill.id, skill);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
registerAll(skills) {
|
|
23
|
+
for (const skill of skills) {
|
|
24
|
+
this.register(skill);
|
|
25
|
+
}
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
get(id) {
|
|
29
|
+
return this.skills.get(id);
|
|
30
|
+
}
|
|
31
|
+
getAll() {
|
|
32
|
+
return [...this.skills.values()];
|
|
33
|
+
}
|
|
34
|
+
has(id) {
|
|
35
|
+
return this.skills.has(id);
|
|
36
|
+
}
|
|
37
|
+
get size() {
|
|
38
|
+
return this.skills.size;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve which skills should be active for a given user prompt.
|
|
42
|
+
*
|
|
43
|
+
* Returns all 'always' skills plus any 'auto' skills whose triggerPatterns
|
|
44
|
+
* match the prompt. 'on-demand' skills are excluded unless explicitly listed
|
|
45
|
+
* in the `include` array.
|
|
46
|
+
*/
|
|
47
|
+
resolveActiveSkills(prompt, include) {
|
|
48
|
+
const includeSet = new Set(include ?? []);
|
|
49
|
+
const active = [];
|
|
50
|
+
for (const skill of this.skills.values()) {
|
|
51
|
+
if (skill.activation === 'always') {
|
|
52
|
+
active.push(skill);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (includeSet.has(skill.id)) {
|
|
56
|
+
active.push(skill);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (skill.activation === 'auto' && skill.triggerPatterns?.length) {
|
|
60
|
+
const matches = skill.triggerPatterns.some((pattern) => pattern.test(prompt));
|
|
61
|
+
if (matches) {
|
|
62
|
+
active.push(skill);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return active;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build a ToolRegistry containing all tools from the given active skills.
|
|
70
|
+
* Logs a warning on tool name collisions (last skill wins).
|
|
71
|
+
*/
|
|
72
|
+
buildToolRegistry(activeSkills) {
|
|
73
|
+
return this.buildToolRegistryWithMap(activeSkills).registry;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build a ToolRegistry plus a map of tool name → owning skill id so callers
|
|
77
|
+
* can surface skill-level context (e.g. "using skill: Linter") when a tool runs.
|
|
78
|
+
*/
|
|
79
|
+
buildToolRegistryWithMap(activeSkills) {
|
|
80
|
+
const registry = new tool_registry_1.ToolRegistry();
|
|
81
|
+
const toolToSkill = new Map();
|
|
82
|
+
for (const skill of activeSkills) {
|
|
83
|
+
for (const tool of skill.tools) {
|
|
84
|
+
const existing = toolToSkill.get(tool.name);
|
|
85
|
+
if (existing) {
|
|
86
|
+
console.warn(`[SkillRegistry] Tool "${tool.name}" from skill "${skill.id}" ` +
|
|
87
|
+
`overwrites same-named tool from "${existing}"`);
|
|
88
|
+
}
|
|
89
|
+
registry.register(tool);
|
|
90
|
+
toolToSkill.set(tool.name, skill.id);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { registry, toolToSkill };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build system prompt section describing active skills and their tools.
|
|
97
|
+
* Includes skill instructions and delegates tool definitions to ToolRegistry.
|
|
98
|
+
*/
|
|
99
|
+
buildSkillPromptBlock(activeSkills) {
|
|
100
|
+
if (activeSkills.length === 0)
|
|
101
|
+
return '';
|
|
102
|
+
const skillDescriptions = activeSkills.map((skill) => {
|
|
103
|
+
const header = `- **${skill.name}** (v${skill.version}): ${skill.description}`;
|
|
104
|
+
return skill.instructions ? `${header}\n ${skill.instructions}` : header;
|
|
105
|
+
}).join('\n');
|
|
106
|
+
const registry = this.buildToolRegistry(activeSkills);
|
|
107
|
+
const toolBlock = registry.buildSystemPromptBlock();
|
|
108
|
+
return [
|
|
109
|
+
'## Active Skills',
|
|
110
|
+
'',
|
|
111
|
+
skillDescriptions,
|
|
112
|
+
'',
|
|
113
|
+
toolBlock
|
|
114
|
+
].join('\n');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.SkillRegistry = SkillRegistry;
|
|
118
|
+
//# sourceMappingURL=skill-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-registry.js","sourceRoot":"","sources":["../../src/tools/skill-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill types for the Bandit agent framework.
|
|
3
|
+
*
|
|
4
|
+
* A skill is a named, versioned group of tools with activation logic.
|
|
5
|
+
* Skills compose naturally with the existing ToolRegistry and ToolUseLoop —
|
|
6
|
+
* they're the unit of extensibility for the agent.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentTool } from './tool-types';
|
|
9
|
+
export interface SkillManifest {
|
|
10
|
+
/** Unique skill identifier (e.g. "core/filesystem", "git/basics"). */
|
|
11
|
+
id: string;
|
|
12
|
+
/** Human-readable name for UI display. */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Semver version string. */
|
|
15
|
+
version: string;
|
|
16
|
+
/** One-line description shown in the system prompt when the skill is active. */
|
|
17
|
+
description: string;
|
|
18
|
+
/**
|
|
19
|
+
* Extended instructions injected into the system prompt when the skill is active.
|
|
20
|
+
* Use this to give the model guidance on when and how to use this skill's tools.
|
|
21
|
+
*/
|
|
22
|
+
instructions?: string;
|
|
23
|
+
/** Tools this skill provides. */
|
|
24
|
+
tools: AgentTool[];
|
|
25
|
+
/**
|
|
26
|
+
* When to activate this skill:
|
|
27
|
+
* - 'always': Active in every conversation (core tools, git).
|
|
28
|
+
* - 'auto': Activated when triggerPatterns match the user prompt.
|
|
29
|
+
* - 'on-demand': Only activated when explicitly requested.
|
|
30
|
+
*/
|
|
31
|
+
activation: 'always' | 'auto' | 'on-demand';
|
|
32
|
+
/**
|
|
33
|
+
* Regex patterns matched against the user prompt for auto-activation.
|
|
34
|
+
* Only used when activation is 'auto'. Any match activates the skill.
|
|
35
|
+
*/
|
|
36
|
+
triggerPatterns?: RegExp[];
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=skill-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-types.d.ts","sourceRoot":"","sources":["../../src/tools/skill-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB;;;;;OAKG;IACH,UAAU,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IAC5C;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Skill types for the Bandit agent framework.
|
|
4
|
+
*
|
|
5
|
+
* A skill is a named, versioned group of tools with activation logic.
|
|
6
|
+
* Skills compose naturally with the existing ToolRegistry and ToolUseLoop —
|
|
7
|
+
* they're the unit of extensibility for the agent.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=skill-types.js.map
|