@kernel.chat/kbot 2.22.3 → 2.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/a2a.d.ts +131 -0
- package/dist/a2a.d.ts.map +1 -0
- package/dist/a2a.js +504 -0
- package/dist/a2a.js.map +1 -0
- package/dist/guardrails.d.ts +61 -0
- package/dist/guardrails.d.ts.map +1 -0
- package/dist/guardrails.js +447 -0
- package/dist/guardrails.js.map +1 -0
- package/dist/handoffs.d.ts +54 -0
- package/dist/handoffs.d.ts.map +1 -0
- package/dist/handoffs.js +257 -0
- package/dist/handoffs.js.map +1 -0
- package/dist/marketplace.d.ts +55 -0
- package/dist/marketplace.d.ts.map +1 -1
- package/dist/marketplace.js +502 -0
- package/dist/marketplace.js.map +1 -1
- package/dist/tools/browser-agent.d.ts +47 -0
- package/dist/tools/browser-agent.d.ts.map +1 -0
- package/dist/tools/browser-agent.js +509 -0
- package/dist/tools/browser-agent.js.map +1 -0
- package/dist/tools/composio.d.ts +11 -0
- package/dist/tools/composio.d.ts.map +1 -0
- package/dist/tools/composio.js +488 -0
- package/dist/tools/composio.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +9 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/workflows.d.ts +92 -0
- package/dist/workflows.d.ts.map +1 -0
- package/dist/workflows.js +619 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +23 -3
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface Guardrail {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
type: 'input' | 'output' | 'tool';
|
|
5
|
+
severity: 'block' | 'warn' | 'log';
|
|
6
|
+
/** Regex pattern to match against content */
|
|
7
|
+
pattern?: RegExp;
|
|
8
|
+
/** Name of a built-in validator function */
|
|
9
|
+
validator?: string;
|
|
10
|
+
/** Message shown when the guardrail triggers */
|
|
11
|
+
message: string;
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface GuardrailViolation {
|
|
15
|
+
guardrailId: string;
|
|
16
|
+
severity: 'block' | 'warn' | 'log';
|
|
17
|
+
message: string;
|
|
18
|
+
evidence: string;
|
|
19
|
+
}
|
|
20
|
+
export interface GuardrailResult {
|
|
21
|
+
passed: boolean;
|
|
22
|
+
violations: GuardrailViolation[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Load built-in guardrails and merge with user-defined custom guardrails
|
|
26
|
+
* from ~/.kbot/guardrails.json.
|
|
27
|
+
*/
|
|
28
|
+
export declare function loadGuardrails(): Guardrail[];
|
|
29
|
+
/**
|
|
30
|
+
* Check input message before the agent processes it.
|
|
31
|
+
* Runs all 'input' type guardrails.
|
|
32
|
+
*/
|
|
33
|
+
export declare function checkInput(message: string): GuardrailResult;
|
|
34
|
+
/**
|
|
35
|
+
* Check agent output before showing to the user.
|
|
36
|
+
* Runs all 'output' type guardrails.
|
|
37
|
+
*/
|
|
38
|
+
export declare function checkOutput(response: string): GuardrailResult;
|
|
39
|
+
/**
|
|
40
|
+
* Check a tool call before execution.
|
|
41
|
+
* Runs all 'tool' type guardrails against the tool name + serialized args.
|
|
42
|
+
*/
|
|
43
|
+
export declare function checkToolCall(toolName: string, args: Record<string, unknown>): GuardrailResult;
|
|
44
|
+
/**
|
|
45
|
+
* Add a custom guardrail at runtime and persist to ~/.kbot/guardrails.json.
|
|
46
|
+
*/
|
|
47
|
+
export declare function addGuardrail(guardrail: Guardrail): void;
|
|
48
|
+
/**
|
|
49
|
+
* Remove a custom guardrail by ID. Built-in guardrails cannot be removed
|
|
50
|
+
* (they can only be disabled).
|
|
51
|
+
*/
|
|
52
|
+
export declare function removeGuardrail(id: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Set the token budget for the output token-budget guardrail.
|
|
55
|
+
*/
|
|
56
|
+
export declare function setTokenBudget(budget: number): void;
|
|
57
|
+
/**
|
|
58
|
+
* Get all currently loaded guardrails (built-in + custom).
|
|
59
|
+
*/
|
|
60
|
+
export declare function getGuardrails(): readonly Guardrail[];
|
|
61
|
+
//# sourceMappingURL=guardrails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../src/guardrails.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;IAClC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,kBAAkB,EAAE,CAAA;CACjC;AAgND;;;GAGG;AACH,wBAAgB,cAAc,IAAI,SAAS,EAAE,CA0C5C;AA6CD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CA+B3D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAqB7D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,eAAe,CAoCjB;AAID;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAYvD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAoBnD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,SAAS,SAAS,EAAE,CAGpD"}
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
// K:BOT Guardrails System — Safety checks on inputs, outputs, and tool calls
|
|
2
|
+
//
|
|
3
|
+
// Three layers of protection:
|
|
4
|
+
// 1. Input guardrails — validate user messages before the agent processes them
|
|
5
|
+
// 2. Output guardrails — scan agent responses before showing to the user
|
|
6
|
+
// 3. Tool guardrails — check tool calls before execution
|
|
7
|
+
//
|
|
8
|
+
// Built-in guardrails are always active. Users can add custom rules
|
|
9
|
+
// via ~/.kbot/guardrails.json.
|
|
10
|
+
//
|
|
11
|
+
// Complements permissions.ts (confirmation dialogs) and bash.ts
|
|
12
|
+
// (blocked command patterns). Guardrails operate at a higher level —
|
|
13
|
+
// they inspect content semantics, not just command syntax.
|
|
14
|
+
import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import { homedir } from 'node:os';
|
|
17
|
+
import { printWarn, printError } from './ui.js';
|
|
18
|
+
// ── Guardrail registry ──
|
|
19
|
+
const guardrails = [];
|
|
20
|
+
let loaded = false;
|
|
21
|
+
/** Default token budget for output (configurable via custom guardrails) */
|
|
22
|
+
let tokenBudget = 16_000;
|
|
23
|
+
// ── Built-in guardrails ──
|
|
24
|
+
/** API key / secret patterns that should never appear in output */
|
|
25
|
+
const SECRET_PATTERNS = [
|
|
26
|
+
{ pattern: /sk-[a-zA-Z0-9]{20,}/, label: 'OpenAI API key (sk-)' },
|
|
27
|
+
{ pattern: /sk-ant-[a-zA-Z0-9-]{20,}/, label: 'Anthropic API key (sk-ant-)' },
|
|
28
|
+
{ pattern: /AKIA[A-Z0-9]{16}/, label: 'AWS access key (AKIA)' },
|
|
29
|
+
{ pattern: /ghp_[a-zA-Z0-9]{36,}/, label: 'GitHub personal access token (ghp_)' },
|
|
30
|
+
{ pattern: /gho_[a-zA-Z0-9]{36,}/, label: 'GitHub OAuth token (gho_)' },
|
|
31
|
+
{ pattern: /ghu_[a-zA-Z0-9]{36,}/, label: 'GitHub user-to-server token (ghu_)' },
|
|
32
|
+
{ pattern: /ghs_[a-zA-Z0-9]{36,}/, label: 'GitHub server-to-server token (ghs_)' },
|
|
33
|
+
{ pattern: /github_pat_[a-zA-Z0-9_]{22,}/, label: 'GitHub fine-grained PAT' },
|
|
34
|
+
{ pattern: /xoxb-[0-9]+-[a-zA-Z0-9]+/, label: 'Slack bot token (xoxb-)' },
|
|
35
|
+
{ pattern: /xoxp-[0-9]+-[a-zA-Z0-9]+/, label: 'Slack user token (xoxp-)' },
|
|
36
|
+
{ pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/, label: 'Private key (PEM)' },
|
|
37
|
+
{ pattern: /eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}/, label: 'JWT token' },
|
|
38
|
+
{ pattern: /SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}/, label: 'SendGrid API key' },
|
|
39
|
+
{ pattern: /sk_live_[a-zA-Z0-9]{24,}/, label: 'Stripe secret key (sk_live_)' },
|
|
40
|
+
{ pattern: /rk_live_[a-zA-Z0-9]{24,}/, label: 'Stripe restricted key (rk_live_)' },
|
|
41
|
+
];
|
|
42
|
+
/** Destructive command patterns — extends bash.ts BLOCKED_PATTERNS */
|
|
43
|
+
const DESTRUCTIVE_PATTERNS = [
|
|
44
|
+
{ pattern: /rm\s+-rf\s+\//, label: 'rm -rf /' },
|
|
45
|
+
{ pattern: /rm\s+-rf\s+~/, label: 'rm -rf ~' },
|
|
46
|
+
{ pattern: /rm\s+-rf\s+\*/, label: 'rm -rf *' },
|
|
47
|
+
{ pattern: /DROP\s+TABLE/i, label: 'DROP TABLE' },
|
|
48
|
+
{ pattern: /DROP\s+DATABASE/i, label: 'DROP DATABASE' },
|
|
49
|
+
{ pattern: /TRUNCATE\s+TABLE/i, label: 'TRUNCATE TABLE' },
|
|
50
|
+
{ pattern: /DELETE\s+FROM\s+\w+\s*;/i, label: 'DELETE FROM (no WHERE clause)' },
|
|
51
|
+
{ pattern: /git\s+push\s+.*--force/i, label: 'git push --force' },
|
|
52
|
+
{ pattern: /git\s+reset\s+--hard/i, label: 'git reset --hard' },
|
|
53
|
+
{ pattern: /mkfs\./i, label: 'mkfs (format filesystem)' },
|
|
54
|
+
{ pattern: /dd\s+if=.*of=\/dev\//i, label: 'dd to raw device' },
|
|
55
|
+
{ pattern: /chmod\s+-R\s+777/i, label: 'chmod -R 777' },
|
|
56
|
+
{ pattern: /:\(\)\s*\{.*\|.*&\s*\}/, label: 'fork bomb' },
|
|
57
|
+
];
|
|
58
|
+
/** PII patterns for detection */
|
|
59
|
+
const PII_PATTERNS = [
|
|
60
|
+
{ pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/, label: 'email address' },
|
|
61
|
+
{ pattern: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/, label: 'phone number' },
|
|
62
|
+
{ pattern: /\b\d{3}-\d{2}-\d{4}\b/, label: 'SSN' },
|
|
63
|
+
{ pattern: /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/, label: 'credit card number' },
|
|
64
|
+
];
|
|
65
|
+
const VALIDATORS = {
|
|
66
|
+
/** Detect secrets / API keys in content */
|
|
67
|
+
'no-secrets': (content) => {
|
|
68
|
+
const violations = [];
|
|
69
|
+
for (const { pattern, label } of SECRET_PATTERNS) {
|
|
70
|
+
const match = pattern.exec(content);
|
|
71
|
+
if (match) {
|
|
72
|
+
violations.push({
|
|
73
|
+
guardrailId: 'no-secrets-in-output',
|
|
74
|
+
severity: 'block',
|
|
75
|
+
message: `Detected ${label} in content`,
|
|
76
|
+
evidence: match[0].slice(0, 8) + '...' + match[0].slice(-4),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return violations;
|
|
81
|
+
},
|
|
82
|
+
/** Detect destructive commands */
|
|
83
|
+
'no-destructive': (content) => {
|
|
84
|
+
const violations = [];
|
|
85
|
+
for (const { pattern, label } of DESTRUCTIVE_PATTERNS) {
|
|
86
|
+
const match = pattern.exec(content);
|
|
87
|
+
if (match) {
|
|
88
|
+
violations.push({
|
|
89
|
+
guardrailId: 'no-destructive-commands',
|
|
90
|
+
severity: 'warn',
|
|
91
|
+
message: `Destructive command detected: ${label}`,
|
|
92
|
+
evidence: match[0],
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return violations;
|
|
97
|
+
},
|
|
98
|
+
/** Check that file paths in write_file calls refer to existing directories */
|
|
99
|
+
'no-hallucinated-files': (_content, args) => {
|
|
100
|
+
const violations = [];
|
|
101
|
+
if (!args)
|
|
102
|
+
return violations;
|
|
103
|
+
const filePath = args.file_path || args.path;
|
|
104
|
+
if (typeof filePath === 'string' && filePath.length > 0) {
|
|
105
|
+
// Check that the parent directory exists
|
|
106
|
+
const parentDir = filePath.replace(/\/[^/]+$/, '');
|
|
107
|
+
if (parentDir && parentDir !== filePath && !existsSync(parentDir)) {
|
|
108
|
+
violations.push({
|
|
109
|
+
guardrailId: 'no-hallucinated-files',
|
|
110
|
+
severity: 'warn',
|
|
111
|
+
message: `Parent directory does not exist: ${parentDir}`,
|
|
112
|
+
evidence: filePath,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return violations;
|
|
117
|
+
},
|
|
118
|
+
/** Warn if output exceeds token budget (rough estimate: 1 token ~ 4 chars) */
|
|
119
|
+
'token-budget': (content) => {
|
|
120
|
+
const violations = [];
|
|
121
|
+
const estimatedTokens = Math.ceil(content.length / 4);
|
|
122
|
+
if (estimatedTokens > tokenBudget) {
|
|
123
|
+
violations.push({
|
|
124
|
+
guardrailId: 'token-budget',
|
|
125
|
+
severity: 'warn',
|
|
126
|
+
message: `Output exceeds token budget: ~${estimatedTokens} tokens (budget: ${tokenBudget})`,
|
|
127
|
+
evidence: `${content.length} characters (~${estimatedTokens} tokens)`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return violations;
|
|
131
|
+
},
|
|
132
|
+
/** Detect PII (emails, phone numbers, SSNs, credit cards) */
|
|
133
|
+
'pii-filter': (content) => {
|
|
134
|
+
const violations = [];
|
|
135
|
+
for (const { pattern, label } of PII_PATTERNS) {
|
|
136
|
+
const match = pattern.exec(content);
|
|
137
|
+
if (match) {
|
|
138
|
+
// Mask the evidence for safety
|
|
139
|
+
const raw = match[0];
|
|
140
|
+
const masked = raw.slice(0, 3) + '***' + raw.slice(-2);
|
|
141
|
+
violations.push({
|
|
142
|
+
guardrailId: 'pii-filter',
|
|
143
|
+
severity: 'warn',
|
|
144
|
+
message: `Possible ${label} detected in output`,
|
|
145
|
+
evidence: masked,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return violations;
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
/** Built-in guardrail definitions (always active) */
|
|
153
|
+
const BUILTIN_GUARDRAILS = [
|
|
154
|
+
{
|
|
155
|
+
id: 'no-secrets-in-output',
|
|
156
|
+
name: 'No Secrets in Output',
|
|
157
|
+
type: 'output',
|
|
158
|
+
severity: 'block',
|
|
159
|
+
validator: 'no-secrets',
|
|
160
|
+
message: 'Response contains API keys or secrets. Blocked to prevent accidental exposure.',
|
|
161
|
+
enabled: true,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: 'no-destructive-commands',
|
|
165
|
+
name: 'No Destructive Commands',
|
|
166
|
+
type: 'tool',
|
|
167
|
+
severity: 'warn',
|
|
168
|
+
validator: 'no-destructive',
|
|
169
|
+
message: 'Tool call contains a destructive command. Review carefully before proceeding.',
|
|
170
|
+
enabled: true,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: 'no-hallucinated-files',
|
|
174
|
+
name: 'No Hallucinated File Paths',
|
|
175
|
+
type: 'tool',
|
|
176
|
+
severity: 'warn',
|
|
177
|
+
validator: 'no-hallucinated-files',
|
|
178
|
+
message: 'File write targets a path whose parent directory does not exist.',
|
|
179
|
+
enabled: true,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: 'token-budget',
|
|
183
|
+
name: 'Token Budget',
|
|
184
|
+
type: 'output',
|
|
185
|
+
severity: 'warn',
|
|
186
|
+
validator: 'token-budget',
|
|
187
|
+
message: 'Response exceeds the configured token budget.',
|
|
188
|
+
enabled: true,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: 'pii-filter',
|
|
192
|
+
name: 'PII Filter',
|
|
193
|
+
type: 'output',
|
|
194
|
+
severity: 'warn',
|
|
195
|
+
validator: 'pii-filter',
|
|
196
|
+
message: 'Response may contain personally identifiable information.',
|
|
197
|
+
enabled: true,
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
// ── Loading ──
|
|
201
|
+
/** Path to user-defined custom guardrails */
|
|
202
|
+
function customGuardrailsPath() {
|
|
203
|
+
return join(homedir(), '.kbot', 'guardrails.json');
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Load built-in guardrails and merge with user-defined custom guardrails
|
|
207
|
+
* from ~/.kbot/guardrails.json.
|
|
208
|
+
*/
|
|
209
|
+
export function loadGuardrails() {
|
|
210
|
+
guardrails.length = 0;
|
|
211
|
+
// Built-in guardrails
|
|
212
|
+
for (const g of BUILTIN_GUARDRAILS) {
|
|
213
|
+
guardrails.push({ ...g });
|
|
214
|
+
}
|
|
215
|
+
// Custom guardrails from ~/.kbot/guardrails.json
|
|
216
|
+
const customPath = customGuardrailsPath();
|
|
217
|
+
if (existsSync(customPath)) {
|
|
218
|
+
try {
|
|
219
|
+
const raw = readFileSync(customPath, 'utf-8');
|
|
220
|
+
const customs = JSON.parse(raw);
|
|
221
|
+
for (const c of customs) {
|
|
222
|
+
if (!c.id || !c.name || !c.type || !c.severity || !c.message)
|
|
223
|
+
continue;
|
|
224
|
+
guardrails.push({
|
|
225
|
+
id: c.id,
|
|
226
|
+
name: c.name,
|
|
227
|
+
type: c.type,
|
|
228
|
+
severity: c.severity,
|
|
229
|
+
pattern: c.pattern ? new RegExp(c.pattern, 'i') : undefined,
|
|
230
|
+
message: c.message,
|
|
231
|
+
enabled: c.enabled !== false,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
printWarn(`Failed to load custom guardrails: ${err instanceof Error ? err.message : String(err)}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
loaded = true;
|
|
240
|
+
return guardrails;
|
|
241
|
+
}
|
|
242
|
+
/** Ensure guardrails are loaded (lazy initialization) */
|
|
243
|
+
function ensureLoaded() {
|
|
244
|
+
if (!loaded)
|
|
245
|
+
loadGuardrails();
|
|
246
|
+
}
|
|
247
|
+
// ── Core check functions ──
|
|
248
|
+
/**
|
|
249
|
+
* Run a single guardrail against content and optional tool args.
|
|
250
|
+
*/
|
|
251
|
+
function runGuardrail(guardrail, content, args) {
|
|
252
|
+
if (!guardrail.enabled)
|
|
253
|
+
return [];
|
|
254
|
+
const violations = [];
|
|
255
|
+
// Pattern-based check (custom guardrails)
|
|
256
|
+
if (guardrail.pattern) {
|
|
257
|
+
const match = guardrail.pattern.exec(content);
|
|
258
|
+
if (match) {
|
|
259
|
+
violations.push({
|
|
260
|
+
guardrailId: guardrail.id,
|
|
261
|
+
severity: guardrail.severity,
|
|
262
|
+
message: guardrail.message,
|
|
263
|
+
evidence: match[0].length > 80 ? match[0].slice(0, 80) + '...' : match[0],
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Validator-based check (built-in guardrails)
|
|
268
|
+
if (guardrail.validator) {
|
|
269
|
+
const validatorFn = VALIDATORS[guardrail.validator];
|
|
270
|
+
if (validatorFn) {
|
|
271
|
+
violations.push(...validatorFn(content, args));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return violations;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Check input message before the agent processes it.
|
|
278
|
+
* Runs all 'input' type guardrails.
|
|
279
|
+
*/
|
|
280
|
+
export function checkInput(message) {
|
|
281
|
+
ensureLoaded();
|
|
282
|
+
const violations = [];
|
|
283
|
+
for (const g of guardrails) {
|
|
284
|
+
if (g.type !== 'input')
|
|
285
|
+
continue;
|
|
286
|
+
violations.push(...runGuardrail(g, message));
|
|
287
|
+
}
|
|
288
|
+
// Also run secrets check on input (prevent prompt injection with keys)
|
|
289
|
+
const secretViolations = VALIDATORS['no-secrets'](message);
|
|
290
|
+
for (const v of secretViolations) {
|
|
291
|
+
v.guardrailId = 'no-secrets-in-input';
|
|
292
|
+
v.severity = 'warn';
|
|
293
|
+
v.message = `Input contains ${v.message.replace('Detected ', '').replace(' in content', '')} — be cautious`;
|
|
294
|
+
}
|
|
295
|
+
violations.push(...secretViolations);
|
|
296
|
+
const hasBlocking = violations.some(v => v.severity === 'block');
|
|
297
|
+
// Log violations
|
|
298
|
+
for (const v of violations) {
|
|
299
|
+
if (v.severity === 'block') {
|
|
300
|
+
printError(`[guardrail] ${v.message}`);
|
|
301
|
+
}
|
|
302
|
+
else if (v.severity === 'warn') {
|
|
303
|
+
printWarn(`[guardrail] ${v.message}`);
|
|
304
|
+
}
|
|
305
|
+
// 'log' severity: silent (can be checked by caller)
|
|
306
|
+
}
|
|
307
|
+
return { passed: !hasBlocking, violations };
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Check agent output before showing to the user.
|
|
311
|
+
* Runs all 'output' type guardrails.
|
|
312
|
+
*/
|
|
313
|
+
export function checkOutput(response) {
|
|
314
|
+
ensureLoaded();
|
|
315
|
+
const violations = [];
|
|
316
|
+
for (const g of guardrails) {
|
|
317
|
+
if (g.type !== 'output')
|
|
318
|
+
continue;
|
|
319
|
+
violations.push(...runGuardrail(g, response));
|
|
320
|
+
}
|
|
321
|
+
const hasBlocking = violations.some(v => v.severity === 'block');
|
|
322
|
+
// Log violations
|
|
323
|
+
for (const v of violations) {
|
|
324
|
+
if (v.severity === 'block') {
|
|
325
|
+
printError(`[guardrail] ${v.message}`);
|
|
326
|
+
}
|
|
327
|
+
else if (v.severity === 'warn') {
|
|
328
|
+
printWarn(`[guardrail] ${v.message}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return { passed: !hasBlocking, violations };
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Check a tool call before execution.
|
|
335
|
+
* Runs all 'tool' type guardrails against the tool name + serialized args.
|
|
336
|
+
*/
|
|
337
|
+
export function checkToolCall(toolName, args) {
|
|
338
|
+
ensureLoaded();
|
|
339
|
+
// Build content string from tool name + args for pattern matching
|
|
340
|
+
const content = `${toolName} ${JSON.stringify(args)}`;
|
|
341
|
+
const violations = [];
|
|
342
|
+
for (const g of guardrails) {
|
|
343
|
+
if (g.type !== 'tool')
|
|
344
|
+
continue;
|
|
345
|
+
violations.push(...runGuardrail(g, content, args));
|
|
346
|
+
}
|
|
347
|
+
// Special handling for write_file — check hallucinated paths
|
|
348
|
+
if (toolName === 'write_file' || toolName === 'edit_file') {
|
|
349
|
+
const pathViolations = VALIDATORS['no-hallucinated-files']('', args);
|
|
350
|
+
violations.push(...pathViolations);
|
|
351
|
+
}
|
|
352
|
+
// Check for destructive commands in bash tool calls
|
|
353
|
+
if (toolName === 'bash' && typeof args.command === 'string') {
|
|
354
|
+
const destructiveViolations = VALIDATORS['no-destructive'](args.command);
|
|
355
|
+
violations.push(...destructiveViolations);
|
|
356
|
+
}
|
|
357
|
+
const hasBlocking = violations.some(v => v.severity === 'block');
|
|
358
|
+
// Log violations
|
|
359
|
+
for (const v of violations) {
|
|
360
|
+
if (v.severity === 'block') {
|
|
361
|
+
printError(`[guardrail] ${v.message}`);
|
|
362
|
+
}
|
|
363
|
+
else if (v.severity === 'warn') {
|
|
364
|
+
printWarn(`[guardrail] ${v.message}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return { passed: !hasBlocking, violations };
|
|
368
|
+
}
|
|
369
|
+
// ── Custom guardrail management ──
|
|
370
|
+
/**
|
|
371
|
+
* Add a custom guardrail at runtime and persist to ~/.kbot/guardrails.json.
|
|
372
|
+
*/
|
|
373
|
+
export function addGuardrail(guardrail) {
|
|
374
|
+
ensureLoaded();
|
|
375
|
+
// Replace if same ID exists
|
|
376
|
+
const existingIdx = guardrails.findIndex(g => g.id === guardrail.id);
|
|
377
|
+
if (existingIdx >= 0) {
|
|
378
|
+
guardrails[existingIdx] = guardrail;
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
guardrails.push(guardrail);
|
|
382
|
+
}
|
|
383
|
+
persistCustomGuardrails();
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Remove a custom guardrail by ID. Built-in guardrails cannot be removed
|
|
387
|
+
* (they can only be disabled).
|
|
388
|
+
*/
|
|
389
|
+
export function removeGuardrail(id) {
|
|
390
|
+
ensureLoaded();
|
|
391
|
+
const builtinIds = new Set(BUILTIN_GUARDRAILS.map(g => g.id));
|
|
392
|
+
if (builtinIds.has(id)) {
|
|
393
|
+
// Cannot remove built-in — disable instead
|
|
394
|
+
const g = guardrails.find(gr => gr.id === id);
|
|
395
|
+
if (g) {
|
|
396
|
+
g.enabled = false;
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
const idx = guardrails.findIndex(g => g.id === id);
|
|
402
|
+
if (idx < 0)
|
|
403
|
+
return false;
|
|
404
|
+
guardrails.splice(idx, 1);
|
|
405
|
+
persistCustomGuardrails();
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Set the token budget for the output token-budget guardrail.
|
|
410
|
+
*/
|
|
411
|
+
export function setTokenBudget(budget) {
|
|
412
|
+
tokenBudget = Math.max(100, budget);
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Get all currently loaded guardrails (built-in + custom).
|
|
416
|
+
*/
|
|
417
|
+
export function getGuardrails() {
|
|
418
|
+
ensureLoaded();
|
|
419
|
+
return guardrails;
|
|
420
|
+
}
|
|
421
|
+
// ── Persistence ──
|
|
422
|
+
/** Persist only custom guardrails (non-builtin) to ~/.kbot/guardrails.json */
|
|
423
|
+
function persistCustomGuardrails() {
|
|
424
|
+
const builtinIds = new Set(BUILTIN_GUARDRAILS.map(g => g.id));
|
|
425
|
+
const customs = guardrails
|
|
426
|
+
.filter(g => !builtinIds.has(g.id))
|
|
427
|
+
.map(g => ({
|
|
428
|
+
id: g.id,
|
|
429
|
+
name: g.name,
|
|
430
|
+
type: g.type,
|
|
431
|
+
severity: g.severity,
|
|
432
|
+
pattern: g.pattern?.source,
|
|
433
|
+
message: g.message,
|
|
434
|
+
enabled: g.enabled,
|
|
435
|
+
}));
|
|
436
|
+
const kbotDir = join(homedir(), '.kbot');
|
|
437
|
+
if (!existsSync(kbotDir)) {
|
|
438
|
+
mkdirSync(kbotDir, { recursive: true });
|
|
439
|
+
}
|
|
440
|
+
try {
|
|
441
|
+
writeFileSync(customGuardrailsPath(), JSON.stringify(customs, null, 2), 'utf-8');
|
|
442
|
+
}
|
|
443
|
+
catch (err) {
|
|
444
|
+
printWarn(`Failed to save custom guardrails: ${err instanceof Error ? err.message : String(err)}`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
//# sourceMappingURL=guardrails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../src/guardrails.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,EAAE;AACF,8BAA8B;AAC9B,kFAAkF;AAClF,2EAA2E;AAC3E,6DAA6D;AAC7D,EAAE;AACF,oEAAoE;AACpE,+BAA+B;AAC/B,EAAE;AACF,gEAAgE;AAChE,qEAAqE;AACrE,2DAA2D;AAE3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AA8B/C,2BAA2B;AAE3B,MAAM,UAAU,GAAgB,EAAE,CAAA;AAClC,IAAI,MAAM,GAAG,KAAK,CAAA;AAElB,2EAA2E;AAC3E,IAAI,WAAW,GAAG,MAAM,CAAA;AAExB,4BAA4B;AAE5B,mEAAmE;AACnE,MAAM,eAAe,GAA8C;IACjE,EAAE,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,sBAAsB,EAAE;IACjE,EAAE,OAAO,EAAE,0BAA0B,EAAE,KAAK,EAAE,6BAA6B,EAAE;IAC7E,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,uBAAuB,EAAE;IAC/D,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,qCAAqC,EAAE;IACjF,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,2BAA2B,EAAE;IACvE,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,oCAAoC,EAAE;IAChF,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,sCAAsC,EAAE;IAClF,EAAE,OAAO,EAAE,8BAA8B,EAAE,KAAK,EAAE,yBAAyB,EAAE;IAC7E,EAAE,OAAO,EAAE,0BAA0B,EAAE,KAAK,EAAE,yBAAyB,EAAE;IACzE,EAAE,OAAO,EAAE,0BAA0B,EAAE,KAAK,EAAE,0BAA0B,EAAE;IAC1E,EAAE,OAAO,EAAE,+CAA+C,EAAE,KAAK,EAAE,mBAAmB,EAAE;IACxF,EAAE,OAAO,EAAE,+DAA+D,EAAE,KAAK,EAAE,WAAW,EAAE;IAChG,EAAE,OAAO,EAAE,0CAA0C,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAClF,EAAE,OAAO,EAAE,0BAA0B,EAAE,KAAK,EAAE,8BAA8B,EAAE;IAC9E,EAAE,OAAO,EAAE,0BAA0B,EAAE,KAAK,EAAE,kCAAkC,EAAE;CACnF,CAAA;AAED,sEAAsE;AACtE,MAAM,oBAAoB,GAA8C;IACtE,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE;IAC/C,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE;IAC9C,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE;IAC/C,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE;IACjD,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,eAAe,EAAE;IACvD,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACzD,EAAE,OAAO,EAAE,0BAA0B,EAAE,KAAK,EAAE,+BAA+B,EAAE;IAC/E,EAAE,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACjE,EAAE,OAAO,EAAE,uBAAuB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC/D,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,0BAA0B,EAAE;IACzD,EAAE,OAAO,EAAE,uBAAuB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC/D,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,cAAc,EAAE;IACvD,EAAE,OAAO,EAAE,wBAAwB,EAAE,KAAK,EAAE,WAAW,EAAE;CAC1D,CAAA;AAED,iCAAiC;AACjC,MAAM,YAAY,GAA8C;IAC9D,EAAE,OAAO,EAAE,oDAAoD,EAAE,KAAK,EAAE,eAAe,EAAE;IACzF,EAAE,OAAO,EAAE,+BAA+B,EAAE,KAAK,EAAE,cAAc,EAAE;IACnE,EAAE,OAAO,EAAE,uBAAuB,EAAE,KAAK,EAAE,KAAK,EAAE;IAClD,EAAE,OAAO,EAAE,4CAA4C,EAAE,KAAK,EAAE,oBAAoB,EAAE;CACvF,CAAA;AAMD,MAAM,UAAU,GAAgC;IAC9C,2CAA2C;IAC3C,YAAY,EAAE,CAAC,OAAe,EAAE,EAAE;QAChC,MAAM,UAAU,GAAyB,EAAE,CAAA;QAC3C,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,eAAe,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACnC,IAAI,KAAK,EAAE,CAAC;gBACV,UAAU,CAAC,IAAI,CAAC;oBACd,WAAW,EAAE,sBAAsB;oBACnC,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,YAAY,KAAK,aAAa;oBACvC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;iBAC5D,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,kCAAkC;IAClC,gBAAgB,EAAE,CAAC,OAAe,EAAE,EAAE;QACpC,MAAM,UAAU,GAAyB,EAAE,CAAA;QAC3C,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,oBAAoB,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACnC,IAAI,KAAK,EAAE,CAAC;gBACV,UAAU,CAAC,IAAI,CAAC;oBACd,WAAW,EAAE,yBAAyB;oBACtC,QAAQ,EAAE,MAAM;oBAChB,OAAO,EAAE,iCAAiC,KAAK,EAAE;oBACjD,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,8EAA8E;IAC9E,uBAAuB,EAAE,CAAC,QAAgB,EAAE,IAA8B,EAAE,EAAE;QAC5E,MAAM,UAAU,GAAyB,EAAE,CAAA;QAC3C,IAAI,CAAC,IAAI;YAAE,OAAO,UAAU,CAAA;QAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAA;QAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,yCAAyC;YACzC,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;YAClD,IAAI,SAAS,IAAI,SAAS,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAClE,UAAU,CAAC,IAAI,CAAC;oBACd,WAAW,EAAE,uBAAuB;oBACpC,QAAQ,EAAE,MAAM;oBAChB,OAAO,EAAE,oCAAoC,SAAS,EAAE;oBACxD,QAAQ,EAAE,QAAQ;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,8EAA8E;IAC9E,cAAc,EAAE,CAAC,OAAe,EAAE,EAAE;QAClC,MAAM,UAAU,GAAyB,EAAE,CAAA;QAC3C,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACrD,IAAI,eAAe,GAAG,WAAW,EAAE,CAAC;YAClC,UAAU,CAAC,IAAI,CAAC;gBACd,WAAW,EAAE,cAAc;gBAC3B,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,iCAAiC,eAAe,oBAAoB,WAAW,GAAG;gBAC3F,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,iBAAiB,eAAe,UAAU;aACtE,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,6DAA6D;IAC7D,YAAY,EAAE,CAAC,OAAe,EAAE,EAAE;QAChC,MAAM,UAAU,GAAyB,EAAE,CAAA;QAC3C,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,YAAY,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACnC,IAAI,KAAK,EAAE,CAAC;gBACV,+BAA+B;gBAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBACpB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;gBACtD,UAAU,CAAC,IAAI,CAAC;oBACd,WAAW,EAAE,YAAY;oBACzB,QAAQ,EAAE,MAAM;oBAChB,OAAO,EAAE,YAAY,KAAK,qBAAqB;oBAC/C,QAAQ,EAAE,MAAM;iBACjB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;CACF,CAAA;AAED,qDAAqD;AACrD,MAAM,kBAAkB,GAAgB;IACtC;QACE,EAAE,EAAE,sBAAsB;QAC1B,IAAI,EAAE,sBAAsB;QAC5B,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,YAAY;QACvB,OAAO,EAAE,gFAAgF;QACzF,OAAO,EAAE,IAAI;KACd;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,IAAI,EAAE,yBAAyB;QAC/B,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,gBAAgB;QAC3B,OAAO,EAAE,+EAA+E;QACxF,OAAO,EAAE,IAAI;KACd;IACD;QACE,EAAE,EAAE,uBAAuB;QAC3B,IAAI,EAAE,4BAA4B;QAClC,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,uBAAuB;QAClC,OAAO,EAAE,kEAAkE;QAC3E,OAAO,EAAE,IAAI;KACd;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,cAAc;QACzB,OAAO,EAAE,+CAA+C;QACxD,OAAO,EAAE,IAAI;KACd;IACD;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,YAAY;QACvB,OAAO,EAAE,2DAA2D;QACpE,OAAO,EAAE,IAAI;KACd;CACF,CAAA;AAED,gBAAgB;AAEhB,6CAA6C;AAC7C,SAAS,oBAAoB;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAA;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,UAAU,CAAC,MAAM,GAAG,CAAC,CAAA;IAErB,sBAAsB;IACtB,KAAK,MAAM,CAAC,IAAI,kBAAkB,EAAE,CAAC;QACnC,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;IAC3B,CAAC;IAED,iDAAiD;IACjD,MAAM,UAAU,GAAG,oBAAoB,EAAE,CAAA;IACzC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;YAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAQ5B,CAAA;YAEF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO;oBAAE,SAAQ;gBACtE,UAAU,CAAC,IAAI,CAAC;oBACd,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;oBAC3D,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,OAAO,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK;iBAC7B,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,CAAC,qCAAqC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACpG,CAAC;IACH,CAAC;IAED,MAAM,GAAG,IAAI,CAAA;IACb,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,yDAAyD;AACzD,SAAS,YAAY;IACnB,IAAI,CAAC,MAAM;QAAE,cAAc,EAAE,CAAA;AAC/B,CAAC;AAED,6BAA6B;AAE7B;;GAEG;AACH,SAAS,YAAY,CACnB,SAAoB,EACpB,OAAe,EACf,IAA8B;IAE9B,IAAI,CAAC,SAAS,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IAEjC,MAAM,UAAU,GAAyB,EAAE,CAAA;IAE3C,0CAA0C;IAC1C,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7C,IAAI,KAAK,EAAE,CAAC;YACV,UAAU,CAAC,IAAI,CAAC;gBACd,WAAW,EAAE,SAAS,CAAC,EAAE;gBACzB,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,OAAO,EAAE,SAAS,CAAC,OAAO;gBAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;aAC1E,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;QACnD,IAAI,WAAW,EAAE,CAAC;YAChB,UAAU,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;QAChD,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,YAAY,EAAE,CAAA;IAEd,MAAM,UAAU,GAAyB,EAAE,CAAA;IAC3C,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;YAAE,SAAQ;QAChC,UAAU,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED,uEAAuE;IACvE,MAAM,gBAAgB,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAA;IAC1D,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;QACjC,CAAC,CAAC,WAAW,GAAG,qBAAqB,CAAA;QACrC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAA;QACnB,CAAC,CAAC,OAAO,GAAG,kBAAkB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,gBAAgB,CAAA;IAC7G,CAAC;IACD,UAAU,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAA;IAEpC,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAA;IAEhE,iBAAiB;IACjB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACxC,CAAC;aAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACjC,SAAS,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACvC,CAAC;QACD,oDAAoD;IACtD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,CAAA;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,YAAY,EAAE,CAAA;IAEd,MAAM,UAAU,GAAyB,EAAE,CAAA;IAC3C,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAQ;QACjC,UAAU,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAA;IAEhE,iBAAiB;IACjB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACxC,CAAC;aAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACjC,SAAS,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACvC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,CAAA;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,IAA6B;IAE7B,YAAY,EAAE,CAAA;IAEd,kEAAkE;IAClE,MAAM,OAAO,GAAG,GAAG,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAA;IACrD,MAAM,UAAU,GAAyB,EAAE,CAAA;IAE3C,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;YAAE,SAAQ;QAC/B,UAAU,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;IACpD,CAAC;IAED,6DAA6D;IAC7D,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC1D,MAAM,cAAc,GAAG,UAAU,CAAC,uBAAuB,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;QACpE,UAAU,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAA;IACpC,CAAC;IAED,oDAAoD;IACpD,IAAI,QAAQ,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5D,MAAM,qBAAqB,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACxE,UAAU,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,CAAA;IAC3C,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAA;IAEhE,iBAAiB;IACjB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACxC,CAAC;aAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACjC,SAAS,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACvC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,CAAA;AAC7C,CAAC;AAED,oCAAoC;AAEpC;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,SAAoB;IAC/C,YAAY,EAAE,CAAA;IAEd,4BAA4B;IAC5B,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC,CAAA;IACpE,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAA;IACrC,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5B,CAAC;IAED,uBAAuB,EAAE,CAAA;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,YAAY,EAAE,CAAA;IAEd,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7D,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACvB,2CAA2C;QAC3C,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QAC7C,IAAI,CAAC,EAAE,CAAC;YACN,CAAC,CAAC,OAAO,GAAG,KAAK,CAAA;YACjB,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAClD,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,KAAK,CAAA;IAEzB,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IACzB,uBAAuB,EAAE,CAAA;IACzB,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,YAAY,EAAE,CAAA;IACd,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,oBAAoB;AAEpB,8EAA8E;AAC9E,SAAS,uBAAuB;IAC9B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7D,MAAM,OAAO,GAAG,UAAU;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACT,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM;QAC1B,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAC,CAAC,CAAA;IAEL,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAA;IACxC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACzC,CAAC;IAED,IAAI,CAAC;QACH,aAAa,CAAC,oBAAoB,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAClF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,SAAS,CAAC,qCAAqC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACpG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export interface Handoff {
|
|
2
|
+
from: string;
|
|
3
|
+
to: string;
|
|
4
|
+
reason: string;
|
|
5
|
+
context: string;
|
|
6
|
+
preserveHistory: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface HandoffResult {
|
|
9
|
+
agent: string;
|
|
10
|
+
response: string;
|
|
11
|
+
handoffChain: string[];
|
|
12
|
+
}
|
|
13
|
+
interface HandoffRule {
|
|
14
|
+
from: string | '*';
|
|
15
|
+
to: string;
|
|
16
|
+
triggers: RegExp[];
|
|
17
|
+
description: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Analyze if the current agent should hand off to another specialist.
|
|
21
|
+
* Checks the response and original query against handoff rules.
|
|
22
|
+
*
|
|
23
|
+
* Returns a Handoff object if a handoff is recommended, null otherwise.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectHandoff(agentId: string, response: string, query: string): Handoff | null;
|
|
26
|
+
/**
|
|
27
|
+
* Build the context string for the receiving agent.
|
|
28
|
+
* Includes a handoff header, the accumulated context, and the reason.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildHandoffContext(currentContext: string, handoff: Handoff): string;
|
|
31
|
+
/**
|
|
32
|
+
* Execute a handoff: call runAgent with the target agent and built context.
|
|
33
|
+
* Tracks the handoff chain and enforces maximum depth.
|
|
34
|
+
*
|
|
35
|
+
* The runAgent function is passed as a parameter to avoid circular imports
|
|
36
|
+
* (agent.ts imports from many modules, and those modules should not import agent.ts).
|
|
37
|
+
*/
|
|
38
|
+
export declare function executeHandoff(handoff: Handoff, query: string, runAgentFn: (message: string, options: {
|
|
39
|
+
agent?: string;
|
|
40
|
+
context?: unknown;
|
|
41
|
+
}) => Promise<{
|
|
42
|
+
content: string;
|
|
43
|
+
agent: string;
|
|
44
|
+
}>, chain?: string[]): Promise<HandoffResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Get all available handoff rules (for diagnostics / UI).
|
|
47
|
+
*/
|
|
48
|
+
export declare function getHandoffRules(): readonly HandoffRule[];
|
|
49
|
+
/**
|
|
50
|
+
* Check if an agent ID is a valid specialist that can participate in handoffs.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isHandoffTarget(agentId: string): boolean;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=handoffs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoffs.d.ts","sourceRoot":"","sources":["../src/handoffs.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAID,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,GAAG,GAAG,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB;AAwGD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,GAAG,IAAI,CAgDhB;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,MAAM,CAqBR;AAID;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAC5H,KAAK,GAAE,MAAM,EAAO,GACnB,OAAO,CAAC,aAAa,CAAC,CA8DxB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,WAAW,EAAE,CAExD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD"}
|