@theokit/agents 13.0.0-next.8 → 13.0.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/CHANGELOG.md +1707 -0
- package/README.md +31 -0
- package/dist/{agent-compiler-C2jIZ4CZ.d.ts → agent-compiler-B0hb6HCo.d.ts} +182 -26
- package/dist/ask.d.ts +1 -0
- package/dist/auth.d.ts +148 -1
- package/dist/auth.js +36 -0
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-BJ86tO6e.d.ts → bridge-entry-DBkqwe6b.d.ts} +72 -6
- package/dist/bridge.d.ts +6 -4
- package/dist/bridge.js +9 -4
- package/dist/{chunk-3GQJ2BHT.js → chunk-G7QBDGZ4.js} +93 -18
- package/dist/chunk-G7QBDGZ4.js.map +1 -0
- package/dist/chunk-HGVT4VCE.js +97 -0
- package/dist/chunk-HGVT4VCE.js.map +1 -0
- package/dist/{chunk-NZTLBLHB.js → chunk-KTQID5V3.js} +560 -342
- package/dist/chunk-KTQID5V3.js.map +1 -0
- package/dist/chunk-M5J3Q6YC.js +17 -0
- package/dist/chunk-M5J3Q6YC.js.map +1 -0
- package/dist/{chunk-RKWCXVYG.js → chunk-MJ6FRILJ.js} +67 -5
- package/dist/chunk-MJ6FRILJ.js.map +1 -0
- package/dist/{chunk-X4IGZHOV.js → chunk-PMMOOXR6.js} +43 -8
- package/dist/chunk-PMMOOXR6.js.map +1 -0
- package/dist/chunk-U72XTMYB.js +7 -0
- package/dist/chunk-U72XTMYB.js.map +1 -0
- package/dist/client-react.d.ts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/config.d.ts +163 -36
- package/dist/config.js +119 -7
- package/dist/config.js.map +1 -1
- package/dist/{define-agent-WYnUlWaH.d.ts → define-agent-DhwNmdej.d.ts} +28 -153
- package/dist/{delegation-scoring-BrBQXvIp.d.ts → delegation-scoring-BzJEheml.d.ts} +1 -1
- package/dist/hooks.d.ts +0 -32
- package/dist/hooks.js +42 -14
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +191 -17
- package/dist/index.js +43 -5
- package/dist/index.js.map +1 -1
- package/dist/sandbox.js.map +1 -1
- package/dist/setting-sources-gate-DFu51i50.d.ts +278 -0
- package/dist/testing.d.ts +5 -2
- package/dist/testing.js +1 -1
- package/dist/tools.d.ts +4 -2
- package/dist/tools.js +22 -4
- package/dist/tools.js.map +1 -1
- package/dist/usage.d.ts +30 -0
- package/dist/usage.js +3 -0
- package/dist/usage.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-3GQJ2BHT.js.map +0 -1
- package/dist/chunk-NZTLBLHB.js.map +0 -1
- package/dist/chunk-RKWCXVYG.js.map +0 -1
- package/dist/chunk-X4IGZHOV.js.map +0 -1
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hooksPlugin,
|
|
3
3
|
inheritHooks
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MJ6FRILJ.js";
|
|
5
5
|
import {
|
|
6
6
|
compileAgentDefinition
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PMMOOXR6.js";
|
|
8
|
+
import {
|
|
9
|
+
debugLog
|
|
10
|
+
} from "./chunk-M5J3Q6YC.js";
|
|
11
|
+
import {
|
|
12
|
+
ConfigurationError
|
|
13
|
+
} from "./chunk-U72XTMYB.js";
|
|
8
14
|
import {
|
|
9
15
|
createRunUsageMeter
|
|
10
16
|
} from "./chunk-OXNDJSAJ.js";
|
|
@@ -54,209 +60,6 @@ function compileProjectContext(options, base) {
|
|
|
54
60
|
}
|
|
55
61
|
__name(compileProjectContext, "compileProjectContext");
|
|
56
62
|
|
|
57
|
-
// src/guardrails/types.ts
|
|
58
|
-
import { TheokitAgentError } from "@theokit/sdk/errors";
|
|
59
|
-
var GuardrailViolationError = class extends TheokitAgentError {
|
|
60
|
-
static {
|
|
61
|
-
__name(this, "GuardrailViolationError");
|
|
62
|
-
}
|
|
63
|
-
guardName;
|
|
64
|
-
phase;
|
|
65
|
-
reason;
|
|
66
|
-
name = "GuardrailViolationError";
|
|
67
|
-
constructor(guardName, phase, reason) {
|
|
68
|
-
super(`Guardrail "${guardName}" blocked ${phase}: ${reason}`, {
|
|
69
|
-
code: "GUARDRAIL_VIOLATION",
|
|
70
|
-
// A blocked prompt is a REFUSAL, not a hiccup. Retrying re-submits the very input a
|
|
71
|
-
// prompt-injection or PII guard just rejected.
|
|
72
|
-
isRetryable: false
|
|
73
|
-
}), this.guardName = guardName, this.phase = phase, this.reason = reason;
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
var CostBudgetExceededError = class extends TheokitAgentError {
|
|
77
|
-
static {
|
|
78
|
-
__name(this, "CostBudgetExceededError");
|
|
79
|
-
}
|
|
80
|
-
usedTokens;
|
|
81
|
-
maxTokens;
|
|
82
|
-
name = "CostBudgetExceededError";
|
|
83
|
-
constructor(usedTokens, maxTokens) {
|
|
84
|
-
super(`Cost budget exceeded: ${usedTokens} > ${maxTokens} tokens`, {
|
|
85
|
-
code: "COST_BUDGET_EXCEEDED",
|
|
86
|
-
// The budget does not refill on retry; retrying spends the next request against the same
|
|
87
|
-
// exhausted ceiling.
|
|
88
|
-
isRetryable: false
|
|
89
|
-
}), this.usedTokens = usedTokens, this.maxTokens = maxTokens;
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// src/guardrails/detectors.ts
|
|
94
|
-
function estimateTokens(text) {
|
|
95
|
-
return Math.ceil(text.length / 4);
|
|
96
|
-
}
|
|
97
|
-
__name(estimateTokens, "estimateTokens");
|
|
98
|
-
var INJECTION_PHRASES = [
|
|
99
|
-
"previous instructions",
|
|
100
|
-
"disregard the above",
|
|
101
|
-
"you are now dan",
|
|
102
|
-
"system prompt",
|
|
103
|
-
"no restrictions",
|
|
104
|
-
"without restrictions",
|
|
105
|
-
"no rules",
|
|
106
|
-
"override your"
|
|
107
|
-
];
|
|
108
|
-
function normalizeForMatch(text) {
|
|
109
|
-
return text.toLowerCase().replace(/\s+/g, " ");
|
|
110
|
-
}
|
|
111
|
-
__name(normalizeForMatch, "normalizeForMatch");
|
|
112
|
-
function promptInjectionDetector(options = {}) {
|
|
113
|
-
const phrases = [
|
|
114
|
-
...INJECTION_PHRASES,
|
|
115
|
-
...(options.extra ?? []).map((p) => p.toLowerCase())
|
|
116
|
-
];
|
|
117
|
-
return {
|
|
118
|
-
name: "prompt-injection",
|
|
119
|
-
checkInput(text) {
|
|
120
|
-
const normalized = normalizeForMatch(text);
|
|
121
|
-
for (const phrase of phrases) {
|
|
122
|
-
if (normalized.includes(phrase)) {
|
|
123
|
-
return {
|
|
124
|
-
action: "block",
|
|
125
|
-
reason: `prompt injection phrase matched: "${phrase}"`
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return {
|
|
130
|
-
action: "allow"
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
__name(promptInjectionDetector, "promptInjectionDetector");
|
|
136
|
-
var CPF = /\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g;
|
|
137
|
-
var EMAIL = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
|
|
138
|
-
var PHONE = /\+?\d[\d\s()-]{7,13}\d/g;
|
|
139
|
-
function piiDetector(options = {}) {
|
|
140
|
-
const placeholder = options.placeholder ?? "[REDACTED]";
|
|
141
|
-
return {
|
|
142
|
-
name: "pii",
|
|
143
|
-
checkInput(text) {
|
|
144
|
-
let redacted = text;
|
|
145
|
-
redacted = redacted.replace(EMAIL, placeholder);
|
|
146
|
-
redacted = redacted.replace(CPF, placeholder);
|
|
147
|
-
redacted = redacted.replace(PHONE, placeholder);
|
|
148
|
-
if (redacted === text) return {
|
|
149
|
-
action: "allow"
|
|
150
|
-
};
|
|
151
|
-
return {
|
|
152
|
-
action: "redact",
|
|
153
|
-
text: redacted,
|
|
154
|
-
reason: "PII detected and redacted"
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
__name(piiDetector, "piiDetector");
|
|
160
|
-
var OBFUSCATION_CHARS = /[\u200B-\u200D\uFEFF\u202A-\u202E\u2066-\u2069]/g;
|
|
161
|
-
function unicodeNormalizer() {
|
|
162
|
-
return {
|
|
163
|
-
name: "unicode-normalizer",
|
|
164
|
-
checkInput(text) {
|
|
165
|
-
const cleaned = text.normalize("NFKC").replace(OBFUSCATION_CHARS, "");
|
|
166
|
-
if (cleaned === text) return {
|
|
167
|
-
action: "allow"
|
|
168
|
-
};
|
|
169
|
-
return {
|
|
170
|
-
action: "redact",
|
|
171
|
-
text: cleaned,
|
|
172
|
-
reason: "obfuscation characters normalized"
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
__name(unicodeNormalizer, "unicodeNormalizer");
|
|
178
|
-
function costGuard(options) {
|
|
179
|
-
let used = 0;
|
|
180
|
-
return {
|
|
181
|
-
name: "cost-guard",
|
|
182
|
-
// Returns a Promise explicitly (not `async`) so a budget breach REJECTS uniformly — never a
|
|
183
|
-
// sync throw — safe for direct callers and for the pipeline's `await g.checkInput()`.
|
|
184
|
-
checkInput(text) {
|
|
185
|
-
used += estimateTokens(text);
|
|
186
|
-
if (used > options.maxTokens) {
|
|
187
|
-
return Promise.reject(new CostBudgetExceededError(used, options.maxTokens));
|
|
188
|
-
}
|
|
189
|
-
return Promise.resolve({
|
|
190
|
-
action: "allow"
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
__name(costGuard, "costGuard");
|
|
196
|
-
function outputModeration(options) {
|
|
197
|
-
return {
|
|
198
|
-
name: "output-moderation",
|
|
199
|
-
async checkOutput(text) {
|
|
200
|
-
const flagged = await options.moderate(text);
|
|
201
|
-
return flagged ? {
|
|
202
|
-
action: "block",
|
|
203
|
-
reason: "output flagged by moderation predicate"
|
|
204
|
-
} : {
|
|
205
|
-
action: "allow"
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
__name(outputModeration, "outputModeration");
|
|
211
|
-
|
|
212
|
-
// src/guardrails/pipeline.ts
|
|
213
|
-
async function runInputGuards(text, guards) {
|
|
214
|
-
let current = text;
|
|
215
|
-
for (const g of guards) {
|
|
216
|
-
if (!g.checkInput) continue;
|
|
217
|
-
const r = await g.checkInput(current);
|
|
218
|
-
if (r.action === "block") {
|
|
219
|
-
throw new GuardrailViolationError(g.name, "input", r.reason ?? "blocked");
|
|
220
|
-
}
|
|
221
|
-
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
222
|
-
}
|
|
223
|
-
return current;
|
|
224
|
-
}
|
|
225
|
-
__name(runInputGuards, "runInputGuards");
|
|
226
|
-
async function runOutputGuards(text, guards) {
|
|
227
|
-
let current = text;
|
|
228
|
-
for (const g of guards) {
|
|
229
|
-
if (!g.checkOutput) continue;
|
|
230
|
-
const r = await g.checkOutput(current);
|
|
231
|
-
if (r.action === "block") {
|
|
232
|
-
throw new GuardrailViolationError(g.name, "output", r.reason ?? "blocked");
|
|
233
|
-
}
|
|
234
|
-
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
235
|
-
}
|
|
236
|
-
return current;
|
|
237
|
-
}
|
|
238
|
-
__name(runOutputGuards, "runOutputGuards");
|
|
239
|
-
|
|
240
|
-
// src/guardrails/stream.ts
|
|
241
|
-
async function* moderateOutputStream(inner, guards, extractText) {
|
|
242
|
-
const hasOutputGuard = guards.some((g) => g.checkOutput != null);
|
|
243
|
-
if (!hasOutputGuard) return yield* inner;
|
|
244
|
-
const buffered = [];
|
|
245
|
-
let accumulated = "";
|
|
246
|
-
let step = await inner.next();
|
|
247
|
-
while (!step.done) {
|
|
248
|
-
const event = step.value;
|
|
249
|
-
const text = extractText(event);
|
|
250
|
-
if (text !== void 0) accumulated += text;
|
|
251
|
-
buffered.push(event);
|
|
252
|
-
step = await inner.next();
|
|
253
|
-
}
|
|
254
|
-
await runOutputGuards(accumulated, guards);
|
|
255
|
-
for (const event of buffered) yield event;
|
|
256
|
-
return step.value;
|
|
257
|
-
}
|
|
258
|
-
__name(moderateOutputStream, "moderateOutputStream");
|
|
259
|
-
|
|
260
63
|
// src/bridge/approval-decision.ts
|
|
261
64
|
var APPROVAL_MODES = [
|
|
262
65
|
"suggest",
|
|
@@ -345,15 +148,6 @@ function createToolHooksPlugin(hooks) {
|
|
|
345
148
|
}
|
|
346
149
|
__name(createToolHooksPlugin, "createToolHooksPlugin");
|
|
347
150
|
|
|
348
|
-
// src/debug-log.ts
|
|
349
|
-
function debugLog(marker, data) {
|
|
350
|
-
const flag = process.env.THEOKIT_DEBUG;
|
|
351
|
-
if (flag !== void 0 && flag !== "" && flag !== "0" && flag !== "false") {
|
|
352
|
-
console.debug(marker, data);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
__name(debugLog, "debugLog");
|
|
356
|
-
|
|
357
151
|
// src/bridge/hitl-plugin.ts
|
|
358
152
|
function createHitlPlugin(wiring) {
|
|
359
153
|
return {
|
|
@@ -413,74 +207,337 @@ function createHitlPlugin(wiring) {
|
|
|
413
207
|
}
|
|
414
208
|
};
|
|
415
209
|
}
|
|
416
|
-
__name(createHitlPlugin, "createHitlPlugin");
|
|
210
|
+
__name(createHitlPlugin, "createHitlPlugin");
|
|
211
|
+
|
|
212
|
+
// src/bridge/approval-posture.ts
|
|
213
|
+
function reasonOf(posturePolicy) {
|
|
214
|
+
return posturePolicy.kind === "interactive" ? "human approver on this surface" : posturePolicy.reason;
|
|
215
|
+
}
|
|
216
|
+
__name(reasonOf, "reasonOf");
|
|
217
|
+
function applyPosture(extra, m8, posturePolicy, gated) {
|
|
218
|
+
const ofThePosture = posturePlugins(posturePolicy, gated);
|
|
219
|
+
if (ofThePosture.length === 0) return;
|
|
220
|
+
const currentOnes = extra.plugins ?? m8.plugins;
|
|
221
|
+
if (currentOnes !== void 0 && !Array.isArray(currentOnes)) {
|
|
222
|
+
throw new Error(`[@theokit/agents] approval posture "${posturePolicy.kind}" needs to install a plugin, but \`plugins\` was supplied in the legacy object form, which cannot carry both. Pass \`plugins\` as an array so the approval gate is not dropped.`);
|
|
223
|
+
}
|
|
224
|
+
extra.plugins = [
|
|
225
|
+
...currentOnes ?? [],
|
|
226
|
+
...ofThePosture
|
|
227
|
+
];
|
|
228
|
+
}
|
|
229
|
+
__name(applyPosture, "applyPosture");
|
|
230
|
+
function posturePlugins(posturePolicy, gated) {
|
|
231
|
+
debugLog("[theokit] approval posture", {
|
|
232
|
+
kind: posturePolicy.kind,
|
|
233
|
+
reason: reasonOf(posturePolicy)
|
|
234
|
+
});
|
|
235
|
+
if (gated === void 0 || gated.size === 0) return [];
|
|
236
|
+
switch (posturePolicy.kind) {
|
|
237
|
+
case "interactive":
|
|
238
|
+
return [
|
|
239
|
+
createHitlPlugin({
|
|
240
|
+
gated,
|
|
241
|
+
emit: posturePolicy.emit,
|
|
242
|
+
awaitApproval: posturePolicy.awaitApproval
|
|
243
|
+
})
|
|
244
|
+
];
|
|
245
|
+
case "auto-approve":
|
|
246
|
+
if (!shouldAutoApprove("full-auto", "*", posturePolicy.confinedBy)) {
|
|
247
|
+
throw new Error(`[@theokit/agents] approval posture "auto-approve" claims confinement ("${posturePolicy.reason}"), but the sandbox reports it is NOT enforced: ${posturePolicy.confinedBy.detail} (mode: ${posturePolicy.confinedBy.mode}). Auto-approving gated tools without enforced confinement runs arbitrary commands with no human and no sandbox. Use "interactive" (a human decides) or "auto-reject" (fail-closed) until the sandbox reports enforced.`);
|
|
248
|
+
}
|
|
249
|
+
return [
|
|
250
|
+
createToolHooksPlugin({
|
|
251
|
+
beforeToolCall: /* @__PURE__ */ __name((ctx) => {
|
|
252
|
+
if (gated.has(ctx.name)) {
|
|
253
|
+
debugLog("[theokit] gated tool auto-approved", {
|
|
254
|
+
tool: ctx.name,
|
|
255
|
+
reason: posturePolicy.reason
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return void 0;
|
|
259
|
+
}, "beforeToolCall")
|
|
260
|
+
})
|
|
261
|
+
];
|
|
262
|
+
case "auto-reject":
|
|
263
|
+
return [
|
|
264
|
+
createToolHooksPlugin({
|
|
265
|
+
// Only GATED tools are refused: the posture describes the gate, not a universal block.
|
|
266
|
+
// Refusing everything would break every agent with a free tool next to a gated one.
|
|
267
|
+
beforeToolCall: /* @__PURE__ */ __name((ctx) => gated.has(ctx.name) ? {
|
|
268
|
+
block: true,
|
|
269
|
+
message: `Tool '${ctx.name}' requires human approval, and this surface has no approver (approval posture: auto-reject \u2014 ${posturePolicy.reason}). Refused (fail-closed).`
|
|
270
|
+
} : void 0, "beforeToolCall")
|
|
271
|
+
})
|
|
272
|
+
];
|
|
273
|
+
case "owned-by-surface":
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
__name(posturePlugins, "posturePlugins");
|
|
278
|
+
|
|
279
|
+
// src/guardrails/types.ts
|
|
280
|
+
import { TheokitAgentError } from "@theokit/sdk/errors";
|
|
281
|
+
var GuardrailError = class extends TheokitAgentError {
|
|
282
|
+
static {
|
|
283
|
+
__name(this, "GuardrailError");
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
var MalformedGuardrailResultError = class extends GuardrailError {
|
|
287
|
+
static {
|
|
288
|
+
__name(this, "MalformedGuardrailResultError");
|
|
289
|
+
}
|
|
290
|
+
guardName;
|
|
291
|
+
phase;
|
|
292
|
+
name = "MalformedGuardrailResultError";
|
|
293
|
+
constructor(guardName, phase) {
|
|
294
|
+
super(`Guardrail "${guardName}" returned action 'redact' for ${phase} with no replacement text. Nothing was redacted. Supply \`text\` (\`''\` erases), or return 'allow' or 'block'.`, {
|
|
295
|
+
code: "GUARDRAIL_RESULT_MALFORMED",
|
|
296
|
+
// A guard written wrong is not written right on the next attempt.
|
|
297
|
+
isRetryable: false
|
|
298
|
+
}), this.guardName = guardName, this.phase = phase;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
var GuardrailViolationError = class extends GuardrailError {
|
|
302
|
+
static {
|
|
303
|
+
__name(this, "GuardrailViolationError");
|
|
304
|
+
}
|
|
305
|
+
guardName;
|
|
306
|
+
phase;
|
|
307
|
+
reason;
|
|
308
|
+
name = "GuardrailViolationError";
|
|
309
|
+
constructor(guardName, phase, reason) {
|
|
310
|
+
super(`Guardrail "${guardName}" blocked ${phase}: ${reason}`, {
|
|
311
|
+
code: "GUARDRAIL_VIOLATION",
|
|
312
|
+
// A blocked prompt is a REFUSAL, not a hiccup. Retrying re-submits the very input a
|
|
313
|
+
// prompt-injection or PII guard just rejected.
|
|
314
|
+
isRetryable: false
|
|
315
|
+
}), this.guardName = guardName, this.phase = phase, this.reason = reason;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
var UnreadableTextPayloadError = class extends GuardrailError {
|
|
319
|
+
static {
|
|
320
|
+
__name(this, "UnreadableTextPayloadError");
|
|
321
|
+
}
|
|
322
|
+
eventType;
|
|
323
|
+
received;
|
|
324
|
+
name = "UnreadableTextPayloadError";
|
|
325
|
+
constructor(eventType, received) {
|
|
326
|
+
super(`A "${eventType}" event carried a non-string content (${typeof received}), which no guard can read. It was previously delivered unexamined. Fix the producer, or stop declaring the event as text-carrying.`, {
|
|
327
|
+
code: "GUARDRAIL_UNREADABLE_PAYLOAD",
|
|
328
|
+
isRetryable: false
|
|
329
|
+
}), this.eventType = eventType, this.received = received;
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
var CostBudgetExceededError = class extends GuardrailError {
|
|
333
|
+
static {
|
|
334
|
+
__name(this, "CostBudgetExceededError");
|
|
335
|
+
}
|
|
336
|
+
usedTokens;
|
|
337
|
+
maxTokens;
|
|
338
|
+
name = "CostBudgetExceededError";
|
|
339
|
+
constructor(usedTokens, maxTokens) {
|
|
340
|
+
super(`Cost budget exceeded: ${usedTokens} > ${maxTokens} tokens`, {
|
|
341
|
+
code: "COST_BUDGET_EXCEEDED",
|
|
342
|
+
// The budget does not refill on retry; retrying spends the next request against the same
|
|
343
|
+
// exhausted ceiling.
|
|
344
|
+
isRetryable: false
|
|
345
|
+
}), this.usedTokens = usedTokens, this.maxTokens = maxTokens;
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
// src/guardrails/detectors.ts
|
|
350
|
+
function estimateTokens(text) {
|
|
351
|
+
return Math.ceil(text.length / 4);
|
|
352
|
+
}
|
|
353
|
+
__name(estimateTokens, "estimateTokens");
|
|
354
|
+
var INJECTION_PHRASES = [
|
|
355
|
+
"previous instructions",
|
|
356
|
+
"disregard the above",
|
|
357
|
+
"you are now dan",
|
|
358
|
+
"system prompt",
|
|
359
|
+
"no restrictions",
|
|
360
|
+
"without restrictions",
|
|
361
|
+
"no rules",
|
|
362
|
+
"override your"
|
|
363
|
+
];
|
|
364
|
+
function normalizeForMatch(text) {
|
|
365
|
+
return text.toLowerCase().replace(/\s+/g, " ");
|
|
366
|
+
}
|
|
367
|
+
__name(normalizeForMatch, "normalizeForMatch");
|
|
368
|
+
function promptInjectionDetector(options = {}) {
|
|
369
|
+
const phrases = [
|
|
370
|
+
...INJECTION_PHRASES,
|
|
371
|
+
...(options.extra ?? []).map((p) => p.toLowerCase())
|
|
372
|
+
];
|
|
373
|
+
return {
|
|
374
|
+
name: "prompt-injection",
|
|
375
|
+
checkInput(text) {
|
|
376
|
+
const normalized = normalizeForMatch(text);
|
|
377
|
+
for (const phrase of phrases) {
|
|
378
|
+
if (normalized.includes(phrase)) {
|
|
379
|
+
return {
|
|
380
|
+
action: "block",
|
|
381
|
+
reason: `prompt injection phrase matched: "${phrase}"`
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
action: "allow"
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
__name(promptInjectionDetector, "promptInjectionDetector");
|
|
392
|
+
var CPF = /\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g;
|
|
393
|
+
var EMAIL = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
|
|
394
|
+
var PHONE = /\+?\d[\d\s()-]{7,13}\d/g;
|
|
395
|
+
function piiDetector(options = {}) {
|
|
396
|
+
const placeholder = options.placeholder ?? "[REDACTED]";
|
|
397
|
+
return {
|
|
398
|
+
name: "pii",
|
|
399
|
+
checkInput(text) {
|
|
400
|
+
let redacted = text;
|
|
401
|
+
redacted = redacted.replace(EMAIL, placeholder);
|
|
402
|
+
redacted = redacted.replace(CPF, placeholder);
|
|
403
|
+
redacted = redacted.replace(PHONE, placeholder);
|
|
404
|
+
if (redacted === text) return {
|
|
405
|
+
action: "allow"
|
|
406
|
+
};
|
|
407
|
+
return {
|
|
408
|
+
action: "redact",
|
|
409
|
+
text: redacted,
|
|
410
|
+
reason: "PII detected and redacted"
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
__name(piiDetector, "piiDetector");
|
|
416
|
+
var OBFUSCATION_CHARS = /[\u200B-\u200D\uFEFF\u202A-\u202E\u2066-\u2069]/g;
|
|
417
|
+
function unicodeNormalizer() {
|
|
418
|
+
return {
|
|
419
|
+
name: "unicode-normalizer",
|
|
420
|
+
checkInput(text) {
|
|
421
|
+
const cleaned = text.normalize("NFKC").replace(OBFUSCATION_CHARS, "");
|
|
422
|
+
if (cleaned === text) return {
|
|
423
|
+
action: "allow"
|
|
424
|
+
};
|
|
425
|
+
return {
|
|
426
|
+
action: "redact",
|
|
427
|
+
text: cleaned,
|
|
428
|
+
reason: "obfuscation characters normalized"
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
__name(unicodeNormalizer, "unicodeNormalizer");
|
|
434
|
+
function costGuard(options) {
|
|
435
|
+
let used = 0;
|
|
436
|
+
return {
|
|
437
|
+
name: "cost-guard",
|
|
438
|
+
// Returns a Promise explicitly (not `async`) so a budget breach REJECTS uniformly — never a
|
|
439
|
+
// sync throw — safe for direct callers and for the pipeline's `await g.checkInput()`.
|
|
440
|
+
checkInput(text) {
|
|
441
|
+
used += estimateTokens(text);
|
|
442
|
+
if (used > options.maxTokens) {
|
|
443
|
+
return Promise.reject(new CostBudgetExceededError(used, options.maxTokens));
|
|
444
|
+
}
|
|
445
|
+
return Promise.resolve({
|
|
446
|
+
action: "allow"
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
__name(costGuard, "costGuard");
|
|
452
|
+
function outputModeration(options) {
|
|
453
|
+
return {
|
|
454
|
+
name: "output-moderation",
|
|
455
|
+
async checkOutput(text) {
|
|
456
|
+
const flagged = await options.moderate(text);
|
|
457
|
+
return flagged ? {
|
|
458
|
+
action: "block",
|
|
459
|
+
reason: "output flagged by moderation predicate"
|
|
460
|
+
} : {
|
|
461
|
+
action: "allow"
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
__name(outputModeration, "outputModeration");
|
|
417
467
|
|
|
418
|
-
// src/
|
|
419
|
-
function
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
468
|
+
// src/guardrails/pipeline.ts
|
|
469
|
+
async function runGuards(text, guards, phase) {
|
|
470
|
+
const check = phase === "input" ? "checkInput" : "checkOutput";
|
|
471
|
+
let current = text;
|
|
472
|
+
for (const g of guards) {
|
|
473
|
+
const fn = g[check];
|
|
474
|
+
if (!fn) continue;
|
|
475
|
+
const r = await fn.call(g, current);
|
|
476
|
+
if (r.action === "block") {
|
|
477
|
+
throw new GuardrailViolationError(g.name, phase, r.reason ?? "blocked");
|
|
478
|
+
}
|
|
479
|
+
if (r.action === "redact") {
|
|
480
|
+
if (r.text === void 0) throw new MalformedGuardrailResultError(g.name, phase);
|
|
481
|
+
current = r.text;
|
|
482
|
+
}
|
|
429
483
|
}
|
|
430
|
-
|
|
431
|
-
...currentOnes ?? [],
|
|
432
|
-
...ofThePosture
|
|
433
|
-
];
|
|
484
|
+
return current;
|
|
434
485
|
}
|
|
435
|
-
__name(
|
|
436
|
-
function
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
return [
|
|
470
|
-
createToolHooksPlugin({
|
|
471
|
-
// Only GATED tools are refused: the posture describes the gate, not a universal block.
|
|
472
|
-
// Refusing everything would break every agent with a free tool next to a gated one.
|
|
473
|
-
beforeToolCall: /* @__PURE__ */ __name((ctx) => gated.has(ctx.name) ? {
|
|
474
|
-
block: true,
|
|
475
|
-
message: `Tool '${ctx.name}' requires human approval, and this surface has no approver (approval posture: auto-reject \u2014 ${posturePolicy.reason}). Refused (fail-closed).`
|
|
476
|
-
} : void 0, "beforeToolCall")
|
|
477
|
-
})
|
|
478
|
-
];
|
|
479
|
-
case "owned-by-surface":
|
|
480
|
-
return [];
|
|
486
|
+
__name(runGuards, "runGuards");
|
|
487
|
+
async function runInputGuards(text, guards) {
|
|
488
|
+
return runGuards(text, guards, "input");
|
|
489
|
+
}
|
|
490
|
+
__name(runInputGuards, "runInputGuards");
|
|
491
|
+
async function runOutputGuards(text, guards) {
|
|
492
|
+
return runGuards(text, guards, "output");
|
|
493
|
+
}
|
|
494
|
+
__name(runOutputGuards, "runOutputGuards");
|
|
495
|
+
|
|
496
|
+
// src/guardrails/stream.ts
|
|
497
|
+
async function* moderateOutputStream(inner, guards, extractText, rebuildText, rebuildResult) {
|
|
498
|
+
const hasOutputGuard = guards.some((g) => g.checkOutput != null);
|
|
499
|
+
if (!hasOutputGuard) return yield* inner;
|
|
500
|
+
const buffered = [];
|
|
501
|
+
const textAt = [];
|
|
502
|
+
let accumulated = "";
|
|
503
|
+
let step = await inner.next();
|
|
504
|
+
while (!step.done) {
|
|
505
|
+
const event = step.value;
|
|
506
|
+
const text = extractText(event);
|
|
507
|
+
if (text !== void 0) accumulated += text;
|
|
508
|
+
buffered.push(event);
|
|
509
|
+
textAt.push(text !== void 0);
|
|
510
|
+
step = await inner.next();
|
|
511
|
+
}
|
|
512
|
+
if (!textAt.includes(true)) {
|
|
513
|
+
for (const event of buffered) yield event;
|
|
514
|
+
return step.value;
|
|
515
|
+
}
|
|
516
|
+
const moderated = await runOutputGuards(accumulated, guards);
|
|
517
|
+
if (moderated === accumulated) {
|
|
518
|
+
for (const event of buffered) yield event;
|
|
519
|
+
return step.value;
|
|
481
520
|
}
|
|
521
|
+
const last = textAt.lastIndexOf(true);
|
|
522
|
+
for (const [index, event] of buffered.entries()) {
|
|
523
|
+
if (!textAt[index]) {
|
|
524
|
+
yield event;
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
if (index === last) yield rebuildText(moderated, event);
|
|
528
|
+
}
|
|
529
|
+
return rebuildResult(moderated, step.value);
|
|
482
530
|
}
|
|
483
|
-
__name(
|
|
531
|
+
__name(moderateOutputStream, "moderateOutputStream");
|
|
532
|
+
function textPayloadExtractor(kind, read) {
|
|
533
|
+
return (event) => {
|
|
534
|
+
if (event.type !== kind) return void 0;
|
|
535
|
+
const content = read(event);
|
|
536
|
+
if (typeof content !== "string") throw new UnreadableTextPayloadError(kind, content);
|
|
537
|
+
return content;
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
__name(textPayloadExtractor, "textPayloadExtractor");
|
|
484
541
|
|
|
485
542
|
// src/bridge/model-selection.ts
|
|
486
543
|
var PARAM_THINKING = "thinking";
|
|
@@ -519,11 +576,46 @@ __name(reasoningEffortOf, "reasoningEffortOf");
|
|
|
519
576
|
|
|
520
577
|
// src/bridge/sdk-adapter-create-options.ts
|
|
521
578
|
import { createRequire } from "module";
|
|
579
|
+
import { PermissionEngine, PermissionPlugin } from "@theokit/sdk";
|
|
522
580
|
import { TheokitAgentError as TheokitAgentError2 } from "@theokit/sdk/errors";
|
|
581
|
+
|
|
582
|
+
// src/bridge/code-plugins.ts
|
|
583
|
+
var BUNDLE_KEYS = [
|
|
584
|
+
"path",
|
|
585
|
+
"type",
|
|
586
|
+
"source",
|
|
587
|
+
"marketplace"
|
|
588
|
+
];
|
|
589
|
+
function assertCodePlugins(list) {
|
|
590
|
+
for (const entry of list) {
|
|
591
|
+
if (isCodePlugin(entry)) continue;
|
|
592
|
+
const looksLikeBundle = typeof entry === "object" && entry !== null && BUNDLE_KEYS.some((k) => k in entry);
|
|
593
|
+
throw new ConfigurationError(looksLikeBundle ? "plugins() takes CODE plugins \u2014 { name, register } objects registered with the runtime's lifecycle seam. The entry given describes a filesystem bundle, which is not declared here: put the bundle in a `plugins/` directory under `.theokit/` or `.claude/`, where its `skills/` and `agents/` are discovered. Note that the manifest (`.claude-plugin/plugin.json`), marketplaces, hooks, MCP servers, output styles and LSP servers are NOT read from a bundle by this runtime." : `plugins() takes { name, register } objects; received ${describe(entry)}.`, {
|
|
594
|
+
code: "plugins_expects_code_objects"
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
__name(assertCodePlugins, "assertCodePlugins");
|
|
599
|
+
function describe(entry) {
|
|
600
|
+
return entry === null ? "null" : typeof entry;
|
|
601
|
+
}
|
|
602
|
+
__name(describe, "describe");
|
|
603
|
+
function isCodePlugin(entry) {
|
|
604
|
+
if (typeof entry !== "object" || entry === null) return false;
|
|
605
|
+
const candidate = entry;
|
|
606
|
+
return typeof candidate.name === "string" && typeof candidate.register === "function";
|
|
607
|
+
}
|
|
608
|
+
__name(isCodePlugin, "isCodePlugin");
|
|
609
|
+
|
|
610
|
+
// src/bridge/sdk-adapter-create-options.ts
|
|
523
611
|
var HOOK_GATE_SINCE = {
|
|
524
612
|
major: 5,
|
|
525
613
|
minor: 4
|
|
526
614
|
};
|
|
615
|
+
var COMPAT_IMPORT_SINCE = {
|
|
616
|
+
major: 5,
|
|
617
|
+
minor: 4
|
|
618
|
+
};
|
|
527
619
|
var HookGateUnsupportedError = class extends TheokitAgentError2 {
|
|
528
620
|
static {
|
|
529
621
|
__name(this, "HookGateUnsupportedError");
|
|
@@ -536,6 +628,41 @@ var HookGateUnsupportedError = class extends TheokitAgentError2 {
|
|
|
536
628
|
});
|
|
537
629
|
}
|
|
538
630
|
};
|
|
631
|
+
var CompatImportUnsupportedError = class extends TheokitAgentError2 {
|
|
632
|
+
static {
|
|
633
|
+
__name(this, "CompatImportUnsupportedError");
|
|
634
|
+
}
|
|
635
|
+
name = "CompatImportUnsupportedError";
|
|
636
|
+
constructor(version) {
|
|
637
|
+
super(`\`claudeCode.import\` narrows WHICH surfaces of a foreign configuration root to read, but the installed @theokit/sdk (${version ?? "version unreadable"}) cannot honour it: the narrowed shape landed in ${String(COMPAT_IMPORT_SINCE.major)}.${String(COMPAT_IMPORT_SINCE.minor)}.0. An older runtime drops the unrecognised shape in silence, so the root would not be read AT ALL \u2014 less than you asked for, not more. Upgrade @theokit/sdk, or omit \`import\` to read every surface of the root (usetheokit/theokit#686).`, {
|
|
638
|
+
code: "compat_import_unsupported",
|
|
639
|
+
isRetryable: false
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
function compatSourcesForSdk(sources) {
|
|
644
|
+
const out = [];
|
|
645
|
+
for (const source of sources) {
|
|
646
|
+
if (typeof source === "string") {
|
|
647
|
+
out.push(source);
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
650
|
+
const forSdk = source.import.filter((surface) => surface !== "commands");
|
|
651
|
+
if (forSdk.length > 0) out.push({
|
|
652
|
+
kind: source.kind,
|
|
653
|
+
import: forSdk
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
return out;
|
|
657
|
+
}
|
|
658
|
+
__name(compatSourcesForSdk, "compatSourcesForSdk");
|
|
659
|
+
function assertSdkCanReadNarrowedImport(version) {
|
|
660
|
+
const [major, minor] = (version ?? "").split(".").map((n) => Number.parseInt(n, 10));
|
|
661
|
+
const known = Number.isFinite(major) && Number.isFinite(minor);
|
|
662
|
+
const supported = known && (major > COMPAT_IMPORT_SINCE.major || major === COMPAT_IMPORT_SINCE.major && minor >= COMPAT_IMPORT_SINCE.minor);
|
|
663
|
+
if (!supported) throw new CompatImportUnsupportedError(version);
|
|
664
|
+
}
|
|
665
|
+
__name(assertSdkCanReadNarrowedImport, "assertSdkCanReadNarrowedImport");
|
|
539
666
|
function assertSdkCanGateHooks(version) {
|
|
540
667
|
const [major, minor] = (version ?? "").split(".").map((n) => Number.parseInt(n, 10));
|
|
541
668
|
const known = Number.isFinite(major) && Number.isFinite(minor);
|
|
@@ -566,6 +693,29 @@ function warnIfSdkCannotReadCompatSources() {
|
|
|
566
693
|
console.warn(`[theokit/agents] \`compatSources\` was declared, but @theokit/sdk@${version} does not know that option and will ignore it \u2014 the foreign configuration root will NOT be read. It landed in 5.0.0. Until this package's floor can name a stable 5.x, override the SDK in your workspace (usetheokit/theokit#634).`);
|
|
567
694
|
}
|
|
568
695
|
__name(warnIfSdkCannotReadCompatSources, "warnIfSdkCannotReadCompatSources");
|
|
696
|
+
function applyPlugins(compiled, options, applied) {
|
|
697
|
+
if (compiled.plugins) {
|
|
698
|
+
assertCodePlugins(compiled.plugins);
|
|
699
|
+
options.plugins = compiled.plugins;
|
|
700
|
+
applied.push("plugins");
|
|
701
|
+
}
|
|
702
|
+
if (compiled.canUseTool !== void 0) {
|
|
703
|
+
options.plugins = [
|
|
704
|
+
...options.plugins ?? [],
|
|
705
|
+
// An engine with NO rules and the SDK's fail-closed default: every call resolves to `ask`,
|
|
706
|
+
// so every call reaches the gate. That IS "one callback sees every tool call the earlier
|
|
707
|
+
// steps did not resolve" — there are no earlier steps to resolve one.
|
|
708
|
+
//
|
|
709
|
+
// A consumer who also wants rules composes them through the SDK directly; declaring both here
|
|
710
|
+
// would mean inventing a precedence between a rule set and a gate that nobody stated.
|
|
711
|
+
PermissionPlugin.create(new PermissionEngine([]), {
|
|
712
|
+
canUseTool: compiled.canUseTool
|
|
713
|
+
})
|
|
714
|
+
];
|
|
715
|
+
applied.push("canUseTool");
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
__name(applyPlugins, "applyPlugins");
|
|
569
719
|
function applyLocalSources(compiled, options, applied) {
|
|
570
720
|
if (compiled.settingSources !== void 0 && compiled.settingSources.length > 0) {
|
|
571
721
|
options.local = {
|
|
@@ -576,15 +726,26 @@ function applyLocalSources(compiled, options, applied) {
|
|
|
576
726
|
};
|
|
577
727
|
applied.push("settingSources");
|
|
578
728
|
}
|
|
579
|
-
if (compiled.
|
|
729
|
+
if (compiled.sessionStore !== void 0) {
|
|
580
730
|
options.local = {
|
|
581
731
|
...options.local,
|
|
582
|
-
|
|
583
|
-
...compiled.compatSources
|
|
584
|
-
]
|
|
732
|
+
sessionStore: compiled.sessionStore
|
|
585
733
|
};
|
|
586
|
-
applied.push("
|
|
587
|
-
|
|
734
|
+
applied.push("sessionStore");
|
|
735
|
+
}
|
|
736
|
+
if (compiled.compatSources !== void 0 && compiled.compatSources.length > 0) {
|
|
737
|
+
const forSdk = compatSourcesForSdk(compiled.compatSources);
|
|
738
|
+
if (forSdk.some((c) => typeof c === "object" && "import" in c)) {
|
|
739
|
+
assertSdkCanReadNarrowedImport(installedSdkVersion());
|
|
740
|
+
}
|
|
741
|
+
if (forSdk.length > 0) {
|
|
742
|
+
options.local = {
|
|
743
|
+
...options.local,
|
|
744
|
+
compatSources: forSdk
|
|
745
|
+
};
|
|
746
|
+
applied.push("compatSources");
|
|
747
|
+
warnIfSdkCannotReadCompatSources();
|
|
748
|
+
}
|
|
588
749
|
}
|
|
589
750
|
}
|
|
590
751
|
__name(applyLocalSources, "applyLocalSources");
|
|
@@ -606,9 +767,10 @@ function assembleM8CreateOptions(compiled, deps = {}) {
|
|
|
606
767
|
options.skills = compiled.skills;
|
|
607
768
|
applied.push("skills");
|
|
608
769
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
770
|
+
applyPlugins(compiled, options, applied);
|
|
771
|
+
if (compiled.agents !== void 0 && Object.keys(compiled.agents).length > 0) {
|
|
772
|
+
options.agents = compiled.agents;
|
|
773
|
+
applied.push("agents");
|
|
612
774
|
}
|
|
613
775
|
applyLocalSources(compiled, options, applied);
|
|
614
776
|
applyHookApproval(compiled, options, applied, deps.sdkVersion);
|
|
@@ -641,6 +803,10 @@ function assembleM8CreateOptions(compiled, deps = {}) {
|
|
|
641
803
|
}
|
|
642
804
|
applied.push("memory");
|
|
643
805
|
}
|
|
806
|
+
if (compiled.telemetry !== void 0) {
|
|
807
|
+
options.telemetry = compiled.telemetry;
|
|
808
|
+
applied.push("telemetry");
|
|
809
|
+
}
|
|
644
810
|
return {
|
|
645
811
|
options,
|
|
646
812
|
applied
|
|
@@ -1056,6 +1222,54 @@ function resolveProjection(def, overrides) {
|
|
|
1056
1222
|
}
|
|
1057
1223
|
__name(resolveProjection, "resolveProjection");
|
|
1058
1224
|
|
|
1225
|
+
// src/bridge/handle-wrappers.ts
|
|
1226
|
+
function withStepCeiling(handle, maxIterations) {
|
|
1227
|
+
if (maxIterations === void 0) return handle;
|
|
1228
|
+
return {
|
|
1229
|
+
get agentId() {
|
|
1230
|
+
return handle.agentId;
|
|
1231
|
+
},
|
|
1232
|
+
dispose: /* @__PURE__ */ __name(() => handle.dispose(), "dispose"),
|
|
1233
|
+
// Forwarded — see {@link SdkAgentHandle.generate} for why, and why it is not guarded.
|
|
1234
|
+
...handle.generate === void 0 ? {} : {
|
|
1235
|
+
generate: handle.generate.bind(handle)
|
|
1236
|
+
},
|
|
1237
|
+
send: /* @__PURE__ */ __name((msg, sendOpts) => handle.send(msg, {
|
|
1238
|
+
maxIterations,
|
|
1239
|
+
...sendOpts
|
|
1240
|
+
}), "send")
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
__name(withStepCeiling, "withStepCeiling");
|
|
1244
|
+
function withGuardrails(handle, guardrails) {
|
|
1245
|
+
if (guardrails === void 0 || guardrails.length === 0) return handle;
|
|
1246
|
+
return {
|
|
1247
|
+
get agentId() {
|
|
1248
|
+
return handle.agentId;
|
|
1249
|
+
},
|
|
1250
|
+
dispose: /* @__PURE__ */ __name(() => handle.dispose(), "dispose"),
|
|
1251
|
+
// Forwarded — see {@link SdkAgentHandle.generate} for why, and why it is not guarded.
|
|
1252
|
+
...handle.generate === void 0 ? {} : {
|
|
1253
|
+
generate: handle.generate.bind(handle)
|
|
1254
|
+
},
|
|
1255
|
+
send: /* @__PURE__ */ __name(async (msg, sendOpts) => {
|
|
1256
|
+
const guarded = await runInputGuards(msg, guardrails);
|
|
1257
|
+
const turn = await handle.send(guarded, sendOpts);
|
|
1258
|
+
return {
|
|
1259
|
+
wait: /* @__PURE__ */ __name(async () => {
|
|
1260
|
+
const out = await turn.wait();
|
|
1261
|
+
if (out.result === void 0) return out;
|
|
1262
|
+
return {
|
|
1263
|
+
...out,
|
|
1264
|
+
result: await runOutputGuards(out.result, guardrails)
|
|
1265
|
+
};
|
|
1266
|
+
}, "wait")
|
|
1267
|
+
};
|
|
1268
|
+
}, "send")
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
__name(withGuardrails, "withGuardrails");
|
|
1272
|
+
|
|
1059
1273
|
// src/bridge/sdk-error.ts
|
|
1060
1274
|
function sdkErrorEvent(err) {
|
|
1061
1275
|
const sdkErr = err;
|
|
@@ -1635,44 +1849,6 @@ function toAgentFactory(def, opts) {
|
|
|
1635
1849
|
};
|
|
1636
1850
|
}
|
|
1637
1851
|
__name(toAgentFactory, "toAgentFactory");
|
|
1638
|
-
function withStepCeiling(handle, maxIterations) {
|
|
1639
|
-
if (maxIterations === void 0) return handle;
|
|
1640
|
-
return {
|
|
1641
|
-
get agentId() {
|
|
1642
|
-
return handle.agentId;
|
|
1643
|
-
},
|
|
1644
|
-
dispose: /* @__PURE__ */ __name(() => handle.dispose(), "dispose"),
|
|
1645
|
-
send: /* @__PURE__ */ __name((msg, sendOpts) => handle.send(msg, {
|
|
1646
|
-
maxIterations,
|
|
1647
|
-
...sendOpts
|
|
1648
|
-
}), "send")
|
|
1649
|
-
};
|
|
1650
|
-
}
|
|
1651
|
-
__name(withStepCeiling, "withStepCeiling");
|
|
1652
|
-
function withGuardrails(handle, guardrails) {
|
|
1653
|
-
if (guardrails === void 0 || guardrails.length === 0) return handle;
|
|
1654
|
-
return {
|
|
1655
|
-
get agentId() {
|
|
1656
|
-
return handle.agentId;
|
|
1657
|
-
},
|
|
1658
|
-
dispose: /* @__PURE__ */ __name(() => handle.dispose(), "dispose"),
|
|
1659
|
-
send: /* @__PURE__ */ __name(async (msg, sendOpts) => {
|
|
1660
|
-
const guarded = await runInputGuards(msg, guardrails);
|
|
1661
|
-
const turn = await handle.send(guarded, sendOpts);
|
|
1662
|
-
return {
|
|
1663
|
-
wait: /* @__PURE__ */ __name(async () => {
|
|
1664
|
-
const out = await turn.wait();
|
|
1665
|
-
if (out.result === void 0) return out;
|
|
1666
|
-
return {
|
|
1667
|
-
...out,
|
|
1668
|
-
result: await runOutputGuards(out.result, guardrails)
|
|
1669
|
-
};
|
|
1670
|
-
}, "wait")
|
|
1671
|
-
};
|
|
1672
|
-
}, "send")
|
|
1673
|
-
};
|
|
1674
|
-
}
|
|
1675
|
-
__name(withGuardrails, "withGuardrails");
|
|
1676
1852
|
|
|
1677
1853
|
// src/loop/compaction-strategy.ts
|
|
1678
1854
|
import { compactTranscript } from "@theokit/sdk/compaction";
|
|
@@ -1862,7 +2038,9 @@ async function* consumeRoundOrThrow(inputs, agentName) {
|
|
|
1862
2038
|
try {
|
|
1863
2039
|
return yield* consumeOneRound(inputs.factory, inputs.prompt, inputs.sessionId, inputs.signal, inputs.retry);
|
|
1864
2040
|
} catch (err) {
|
|
1865
|
-
if (err instanceof DelegationBudgetExceededError || err instanceof DelegationError
|
|
2041
|
+
if (err instanceof DelegationBudgetExceededError || err instanceof DelegationError || err instanceof GuardrailError) {
|
|
2042
|
+
throw err;
|
|
2043
|
+
}
|
|
1866
2044
|
throw new DelegationError(agentName, err);
|
|
1867
2045
|
}
|
|
1868
2046
|
}
|
|
@@ -2125,7 +2303,33 @@ var AgentRunner = class {
|
|
|
2125
2303
|
const runUnguarded = /* @__PURE__ */ __name((m) => this.streamUnguarded(m, opts), "runUnguarded");
|
|
2126
2304
|
return (/* @__PURE__ */ __name(async function* guarded() {
|
|
2127
2305
|
const safe = await runInputGuards(message, guardrails);
|
|
2128
|
-
return yield* moderateOutputStream(
|
|
2306
|
+
return yield* moderateOutputStream(
|
|
2307
|
+
moderateOutputStream(
|
|
2308
|
+
runUnguarded(safe),
|
|
2309
|
+
guardrails,
|
|
2310
|
+
// B-021 — the shared extractor, so "this kind, content unreadable" throws instead of
|
|
2311
|
+
// sharing a return value with "not this kind". The hand-written form here returned
|
|
2312
|
+
// `undefined` for a non-string, which reads as "carries no text": the payload was never
|
|
2313
|
+
// shown to a guard and was yielded verbatim.
|
|
2314
|
+
textPayloadExtractor("text_delta", (e) => e.content),
|
|
2315
|
+
(content) => ({
|
|
2316
|
+
type: "text_delta",
|
|
2317
|
+
content
|
|
2318
|
+
}),
|
|
2319
|
+
(content, result) => ({
|
|
2320
|
+
...result,
|
|
2321
|
+
response: content
|
|
2322
|
+
})
|
|
2323
|
+
),
|
|
2324
|
+
guardrails,
|
|
2325
|
+
textPayloadExtractor("thinking", (e) => e.content),
|
|
2326
|
+
(content) => ({
|
|
2327
|
+
type: "thinking",
|
|
2328
|
+
content
|
|
2329
|
+
}),
|
|
2330
|
+
// The reasoning pass does NOT touch the aggregate — the visible pass already did.
|
|
2331
|
+
(_content, result) => result
|
|
2332
|
+
);
|
|
2129
2333
|
}, "guarded"))();
|
|
2130
2334
|
}
|
|
2131
2335
|
return this.streamUnguarded(message, opts);
|
|
@@ -2349,11 +2553,13 @@ function mergeTools(parentTools, subTools) {
|
|
|
2349
2553
|
__name(mergeTools, "mergeTools");
|
|
2350
2554
|
async function delegate(spec, message, opts = {}) {
|
|
2351
2555
|
const apiKey = requireApiKey(opts, spec.name);
|
|
2352
|
-
const
|
|
2556
|
+
const rewritten = opts.onDelegationStart ? await opts.onDelegationStart({
|
|
2353
2557
|
subAgent: spec.name,
|
|
2354
2558
|
input: message
|
|
2355
2559
|
}) : message;
|
|
2356
2560
|
const { compiled } = spec;
|
|
2561
|
+
const guardrails = compiled.guardrails ?? [];
|
|
2562
|
+
const effectiveMessage = await runInputGuards(rewritten, guardrails);
|
|
2357
2563
|
const allTools = mergeTools(opts.parentTools ?? [], compiled.tools);
|
|
2358
2564
|
const budget = Math.min(opts.budget ?? Infinity, opts.parentBudgetRemaining ?? Infinity);
|
|
2359
2565
|
const compiledForMember = withInheritedHooks(compiled, opts.parentHooks);
|
|
@@ -2377,15 +2583,21 @@ async function delegate(spec, message, opts = {}) {
|
|
|
2377
2583
|
signal: opts.signal,
|
|
2378
2584
|
retry: opts.retry
|
|
2379
2585
|
});
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
}
|
|
2386
|
-
return result;
|
|
2586
|
+
const transformed = opts.onDelegationComplete ? await opts.onDelegationComplete({
|
|
2587
|
+
subAgent: spec.name,
|
|
2588
|
+
result
|
|
2589
|
+
}) : result;
|
|
2590
|
+
return await moderateDelegationResult(transformed, guardrails);
|
|
2387
2591
|
}
|
|
2388
2592
|
__name(delegate, "delegate");
|
|
2593
|
+
async function moderateDelegationResult(result, guardrails) {
|
|
2594
|
+
if (guardrails.length === 0) return result;
|
|
2595
|
+
return {
|
|
2596
|
+
...result,
|
|
2597
|
+
response: await runOutputGuards(result.response, guardrails)
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
__name(moderateDelegationResult, "moderateDelegationResult");
|
|
2389
2601
|
|
|
2390
2602
|
// src/bridge/delegation-lifecycle.ts
|
|
2391
2603
|
import { TheokitAgentError as TheokitAgentError5 } from "@theokit/sdk/errors";
|
|
@@ -2436,7 +2648,8 @@ __name(withEphemeralAgent, "withEphemeralAgent");
|
|
|
2436
2648
|
|
|
2437
2649
|
// src/bridge/delegation-scoring.ts
|
|
2438
2650
|
function isPort(target) {
|
|
2439
|
-
|
|
2651
|
+
if ("compiled" in target) return false;
|
|
2652
|
+
return typeof target.run === "function";
|
|
2440
2653
|
}
|
|
2441
2654
|
__name(isPort, "isPort");
|
|
2442
2655
|
async function runOnce(target, message, delegateFn, opts) {
|
|
@@ -2502,7 +2715,16 @@ __name(delegateWithScoring, "delegateWithScoring");
|
|
|
2502
2715
|
export {
|
|
2503
2716
|
projectContextMetadataOnlyKnobs,
|
|
2504
2717
|
compileProjectContext,
|
|
2718
|
+
APPROVAL_MODES,
|
|
2719
|
+
WRITE_SCOPED_TOOLS,
|
|
2720
|
+
shouldAutoApprove,
|
|
2721
|
+
createHitlPlugin,
|
|
2722
|
+
createToolHooksPlugin,
|
|
2723
|
+
applyPosture,
|
|
2724
|
+
GuardrailError,
|
|
2725
|
+
MalformedGuardrailResultError,
|
|
2505
2726
|
GuardrailViolationError,
|
|
2727
|
+
UnreadableTextPayloadError,
|
|
2506
2728
|
CostBudgetExceededError,
|
|
2507
2729
|
estimateTokens,
|
|
2508
2730
|
promptInjectionDetector,
|
|
@@ -2513,15 +2735,11 @@ export {
|
|
|
2513
2735
|
runInputGuards,
|
|
2514
2736
|
runOutputGuards,
|
|
2515
2737
|
moderateOutputStream,
|
|
2516
|
-
|
|
2517
|
-
WRITE_SCOPED_TOOLS,
|
|
2518
|
-
shouldAutoApprove,
|
|
2519
|
-
createHitlPlugin,
|
|
2520
|
-
createToolHooksPlugin,
|
|
2521
|
-
applyPosture,
|
|
2738
|
+
textPayloadExtractor,
|
|
2522
2739
|
buildModelSelection,
|
|
2523
2740
|
reasoningEffortOf,
|
|
2524
2741
|
HookGateUnsupportedError,
|
|
2742
|
+
CompatImportUnsupportedError,
|
|
2525
2743
|
translateSdkEvent,
|
|
2526
2744
|
createThinkTagExtractor,
|
|
2527
2745
|
extractThinkTagStream,
|
|
@@ -2553,4 +2771,4 @@ export {
|
|
|
2553
2771
|
delegateBackground,
|
|
2554
2772
|
delegateWithScoring
|
|
2555
2773
|
};
|
|
2556
|
-
//# sourceMappingURL=chunk-
|
|
2774
|
+
//# sourceMappingURL=chunk-KTQID5V3.js.map
|