@theokit/agents 13.0.0-next.9 → 13.1.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 +1821 -0
- package/README.md +31 -0
- package/dist/{agent-compiler-DZorqtK2.d.ts → agent-compiler-B_Z3OZel.d.ts} +196 -194
- package/dist/ask.d.ts +1 -0
- package/dist/auth.d.ts +175 -1
- package/dist/auth.js +94 -0
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-B0FqqPlt.d.ts → bridge-entry-vzdHNu_x.d.ts} +72 -6
- package/dist/bridge.d.ts +6 -4
- package/dist/bridge.js +9 -4
- package/dist/{chunk-TZCHACY7.js → chunk-AAW4I45J.js} +118 -18
- package/dist/chunk-AAW4I45J.js.map +1 -0
- package/dist/{chunk-6WFRR24F.js → chunk-HBHZV3KL.js} +566 -342
- package/dist/chunk-HBHZV3KL.js.map +1 -0
- package/dist/chunk-M5DRNOIU.js +109 -0
- package/dist/chunk-M5DRNOIU.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-LPS65NGG.js → chunk-PMMOOXR6.js} +33 -10
- 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 +205 -36
- package/dist/config.js +221 -18
- package/dist/config.js.map +1 -1
- package/dist/{define-agent-D9b3h3VU.d.ts → define-agent-Cm7UGHx-.d.ts} +27 -3
- package/dist/{delegation-scoring-MbnqL68u.d.ts → delegation-scoring-195_ROT3.d.ts} +14 -2
- 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 -16
- 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-6WFRR24F.js.map +0 -1
- package/dist/chunk-LPS65NGG.js.map +0 -1
- package/dist/chunk-RKWCXVYG.js.map +0 -1
- package/dist/chunk-TZCHACY7.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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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;
|
|
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);
|
|
481
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,52 @@ __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 CAPABILITY_KEYS = [
|
|
584
|
+
"register",
|
|
585
|
+
"profile",
|
|
586
|
+
"createProvider"
|
|
587
|
+
];
|
|
588
|
+
var BUNDLE_KEYS = [
|
|
589
|
+
"path",
|
|
590
|
+
"type",
|
|
591
|
+
"source",
|
|
592
|
+
"marketplace"
|
|
593
|
+
];
|
|
594
|
+
function assertCodePlugins(list) {
|
|
595
|
+
for (const entry of list) {
|
|
596
|
+
if (isCodePlugin(entry)) continue;
|
|
597
|
+
const looksLikeBundle = typeof entry === "object" && entry !== null && BUNDLE_KEYS.some((k) => k in entry);
|
|
598
|
+
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)}.`, {
|
|
599
|
+
code: "plugins_expects_code_objects"
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
__name(assertCodePlugins, "assertCodePlugins");
|
|
604
|
+
function describe(entry) {
|
|
605
|
+
return entry === null ? "null" : typeof entry;
|
|
606
|
+
}
|
|
607
|
+
__name(describe, "describe");
|
|
608
|
+
function isCodePlugin(entry) {
|
|
609
|
+
if (typeof entry !== "object" || entry === null) return false;
|
|
610
|
+
const candidate = entry;
|
|
611
|
+
if (typeof candidate.name !== "string") return false;
|
|
612
|
+
return CAPABILITY_KEYS.some((key) => candidate[key] !== void 0);
|
|
613
|
+
}
|
|
614
|
+
__name(isCodePlugin, "isCodePlugin");
|
|
615
|
+
|
|
616
|
+
// src/bridge/sdk-adapter-create-options.ts
|
|
523
617
|
var HOOK_GATE_SINCE = {
|
|
524
618
|
major: 5,
|
|
525
619
|
minor: 4
|
|
526
620
|
};
|
|
621
|
+
var COMPAT_IMPORT_SINCE = {
|
|
622
|
+
major: 5,
|
|
623
|
+
minor: 4
|
|
624
|
+
};
|
|
527
625
|
var HookGateUnsupportedError = class extends TheokitAgentError2 {
|
|
528
626
|
static {
|
|
529
627
|
__name(this, "HookGateUnsupportedError");
|
|
@@ -536,6 +634,41 @@ var HookGateUnsupportedError = class extends TheokitAgentError2 {
|
|
|
536
634
|
});
|
|
537
635
|
}
|
|
538
636
|
};
|
|
637
|
+
var CompatImportUnsupportedError = class extends TheokitAgentError2 {
|
|
638
|
+
static {
|
|
639
|
+
__name(this, "CompatImportUnsupportedError");
|
|
640
|
+
}
|
|
641
|
+
name = "CompatImportUnsupportedError";
|
|
642
|
+
constructor(version) {
|
|
643
|
+
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).`, {
|
|
644
|
+
code: "compat_import_unsupported",
|
|
645
|
+
isRetryable: false
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
function compatSourcesForSdk(sources) {
|
|
650
|
+
const out = [];
|
|
651
|
+
for (const source of sources) {
|
|
652
|
+
if (typeof source === "string") {
|
|
653
|
+
out.push(source);
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
const forSdk = source.import.filter((surface) => surface !== "commands");
|
|
657
|
+
if (forSdk.length > 0) out.push({
|
|
658
|
+
kind: source.kind,
|
|
659
|
+
import: forSdk
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
return out;
|
|
663
|
+
}
|
|
664
|
+
__name(compatSourcesForSdk, "compatSourcesForSdk");
|
|
665
|
+
function assertSdkCanReadNarrowedImport(version) {
|
|
666
|
+
const [major, minor] = (version ?? "").split(".").map((n) => Number.parseInt(n, 10));
|
|
667
|
+
const known = Number.isFinite(major) && Number.isFinite(minor);
|
|
668
|
+
const supported = known && (major > COMPAT_IMPORT_SINCE.major || major === COMPAT_IMPORT_SINCE.major && minor >= COMPAT_IMPORT_SINCE.minor);
|
|
669
|
+
if (!supported) throw new CompatImportUnsupportedError(version);
|
|
670
|
+
}
|
|
671
|
+
__name(assertSdkCanReadNarrowedImport, "assertSdkCanReadNarrowedImport");
|
|
539
672
|
function assertSdkCanGateHooks(version) {
|
|
540
673
|
const [major, minor] = (version ?? "").split(".").map((n) => Number.parseInt(n, 10));
|
|
541
674
|
const known = Number.isFinite(major) && Number.isFinite(minor);
|
|
@@ -566,6 +699,29 @@ function warnIfSdkCannotReadCompatSources() {
|
|
|
566
699
|
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
700
|
}
|
|
568
701
|
__name(warnIfSdkCannotReadCompatSources, "warnIfSdkCannotReadCompatSources");
|
|
702
|
+
function applyPlugins(compiled, options, applied) {
|
|
703
|
+
if (compiled.plugins) {
|
|
704
|
+
assertCodePlugins(compiled.plugins);
|
|
705
|
+
options.plugins = compiled.plugins;
|
|
706
|
+
applied.push("plugins");
|
|
707
|
+
}
|
|
708
|
+
if (compiled.canUseTool !== void 0) {
|
|
709
|
+
options.plugins = [
|
|
710
|
+
...options.plugins ?? [],
|
|
711
|
+
// An engine with NO rules and the SDK's fail-closed default: every call resolves to `ask`,
|
|
712
|
+
// so every call reaches the gate. That IS "one callback sees every tool call the earlier
|
|
713
|
+
// steps did not resolve" — there are no earlier steps to resolve one.
|
|
714
|
+
//
|
|
715
|
+
// A consumer who also wants rules composes them through the SDK directly; declaring both here
|
|
716
|
+
// would mean inventing a precedence between a rule set and a gate that nobody stated.
|
|
717
|
+
PermissionPlugin.create(new PermissionEngine([]), {
|
|
718
|
+
canUseTool: compiled.canUseTool
|
|
719
|
+
})
|
|
720
|
+
];
|
|
721
|
+
applied.push("canUseTool");
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
__name(applyPlugins, "applyPlugins");
|
|
569
725
|
function applyLocalSources(compiled, options, applied) {
|
|
570
726
|
if (compiled.settingSources !== void 0 && compiled.settingSources.length > 0) {
|
|
571
727
|
options.local = {
|
|
@@ -576,15 +732,26 @@ function applyLocalSources(compiled, options, applied) {
|
|
|
576
732
|
};
|
|
577
733
|
applied.push("settingSources");
|
|
578
734
|
}
|
|
579
|
-
if (compiled.
|
|
735
|
+
if (compiled.sessionStore !== void 0) {
|
|
580
736
|
options.local = {
|
|
581
737
|
...options.local,
|
|
582
|
-
|
|
583
|
-
...compiled.compatSources
|
|
584
|
-
]
|
|
738
|
+
sessionStore: compiled.sessionStore
|
|
585
739
|
};
|
|
586
|
-
applied.push("
|
|
587
|
-
|
|
740
|
+
applied.push("sessionStore");
|
|
741
|
+
}
|
|
742
|
+
if (compiled.compatSources !== void 0 && compiled.compatSources.length > 0) {
|
|
743
|
+
const forSdk = compatSourcesForSdk(compiled.compatSources);
|
|
744
|
+
if (forSdk.some((c) => typeof c === "object" && "import" in c)) {
|
|
745
|
+
assertSdkCanReadNarrowedImport(installedSdkVersion());
|
|
746
|
+
}
|
|
747
|
+
if (forSdk.length > 0) {
|
|
748
|
+
options.local = {
|
|
749
|
+
...options.local,
|
|
750
|
+
compatSources: forSdk
|
|
751
|
+
};
|
|
752
|
+
applied.push("compatSources");
|
|
753
|
+
warnIfSdkCannotReadCompatSources();
|
|
754
|
+
}
|
|
588
755
|
}
|
|
589
756
|
}
|
|
590
757
|
__name(applyLocalSources, "applyLocalSources");
|
|
@@ -606,9 +773,10 @@ function assembleM8CreateOptions(compiled, deps = {}) {
|
|
|
606
773
|
options.skills = compiled.skills;
|
|
607
774
|
applied.push("skills");
|
|
608
775
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
776
|
+
applyPlugins(compiled, options, applied);
|
|
777
|
+
if (compiled.agents !== void 0 && Object.keys(compiled.agents).length > 0) {
|
|
778
|
+
options.agents = compiled.agents;
|
|
779
|
+
applied.push("agents");
|
|
612
780
|
}
|
|
613
781
|
applyLocalSources(compiled, options, applied);
|
|
614
782
|
applyHookApproval(compiled, options, applied, deps.sdkVersion);
|
|
@@ -641,6 +809,10 @@ function assembleM8CreateOptions(compiled, deps = {}) {
|
|
|
641
809
|
}
|
|
642
810
|
applied.push("memory");
|
|
643
811
|
}
|
|
812
|
+
if (compiled.telemetry !== void 0) {
|
|
813
|
+
options.telemetry = compiled.telemetry;
|
|
814
|
+
applied.push("telemetry");
|
|
815
|
+
}
|
|
644
816
|
return {
|
|
645
817
|
options,
|
|
646
818
|
applied
|
|
@@ -1056,6 +1228,54 @@ function resolveProjection(def, overrides) {
|
|
|
1056
1228
|
}
|
|
1057
1229
|
__name(resolveProjection, "resolveProjection");
|
|
1058
1230
|
|
|
1231
|
+
// src/bridge/handle-wrappers.ts
|
|
1232
|
+
function withStepCeiling(handle, maxIterations) {
|
|
1233
|
+
if (maxIterations === void 0) return handle;
|
|
1234
|
+
return {
|
|
1235
|
+
get agentId() {
|
|
1236
|
+
return handle.agentId;
|
|
1237
|
+
},
|
|
1238
|
+
dispose: /* @__PURE__ */ __name(() => handle.dispose(), "dispose"),
|
|
1239
|
+
// Forwarded — see {@link SdkAgentHandle.generate} for why, and why it is not guarded.
|
|
1240
|
+
...handle.generate === void 0 ? {} : {
|
|
1241
|
+
generate: handle.generate.bind(handle)
|
|
1242
|
+
},
|
|
1243
|
+
send: /* @__PURE__ */ __name((msg, sendOpts) => handle.send(msg, {
|
|
1244
|
+
maxIterations,
|
|
1245
|
+
...sendOpts
|
|
1246
|
+
}), "send")
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
__name(withStepCeiling, "withStepCeiling");
|
|
1250
|
+
function withGuardrails(handle, guardrails) {
|
|
1251
|
+
if (guardrails === void 0 || guardrails.length === 0) return handle;
|
|
1252
|
+
return {
|
|
1253
|
+
get agentId() {
|
|
1254
|
+
return handle.agentId;
|
|
1255
|
+
},
|
|
1256
|
+
dispose: /* @__PURE__ */ __name(() => handle.dispose(), "dispose"),
|
|
1257
|
+
// Forwarded — see {@link SdkAgentHandle.generate} for why, and why it is not guarded.
|
|
1258
|
+
...handle.generate === void 0 ? {} : {
|
|
1259
|
+
generate: handle.generate.bind(handle)
|
|
1260
|
+
},
|
|
1261
|
+
send: /* @__PURE__ */ __name(async (msg, sendOpts) => {
|
|
1262
|
+
const guarded = await runInputGuards(msg, guardrails);
|
|
1263
|
+
const turn = await handle.send(guarded, sendOpts);
|
|
1264
|
+
return {
|
|
1265
|
+
wait: /* @__PURE__ */ __name(async () => {
|
|
1266
|
+
const out = await turn.wait();
|
|
1267
|
+
if (out.result === void 0) return out;
|
|
1268
|
+
return {
|
|
1269
|
+
...out,
|
|
1270
|
+
result: await runOutputGuards(out.result, guardrails)
|
|
1271
|
+
};
|
|
1272
|
+
}, "wait")
|
|
1273
|
+
};
|
|
1274
|
+
}, "send")
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
__name(withGuardrails, "withGuardrails");
|
|
1278
|
+
|
|
1059
1279
|
// src/bridge/sdk-error.ts
|
|
1060
1280
|
function sdkErrorEvent(err) {
|
|
1061
1281
|
const sdkErr = err;
|
|
@@ -1635,44 +1855,6 @@ function toAgentFactory(def, opts) {
|
|
|
1635
1855
|
};
|
|
1636
1856
|
}
|
|
1637
1857
|
__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
1858
|
|
|
1677
1859
|
// src/loop/compaction-strategy.ts
|
|
1678
1860
|
import { compactTranscript } from "@theokit/sdk/compaction";
|
|
@@ -1862,7 +2044,9 @@ async function* consumeRoundOrThrow(inputs, agentName) {
|
|
|
1862
2044
|
try {
|
|
1863
2045
|
return yield* consumeOneRound(inputs.factory, inputs.prompt, inputs.sessionId, inputs.signal, inputs.retry);
|
|
1864
2046
|
} catch (err) {
|
|
1865
|
-
if (err instanceof DelegationBudgetExceededError || err instanceof DelegationError
|
|
2047
|
+
if (err instanceof DelegationBudgetExceededError || err instanceof DelegationError || err instanceof GuardrailError) {
|
|
2048
|
+
throw err;
|
|
2049
|
+
}
|
|
1866
2050
|
throw new DelegationError(agentName, err);
|
|
1867
2051
|
}
|
|
1868
2052
|
}
|
|
@@ -2125,7 +2309,33 @@ var AgentRunner = class {
|
|
|
2125
2309
|
const runUnguarded = /* @__PURE__ */ __name((m) => this.streamUnguarded(m, opts), "runUnguarded");
|
|
2126
2310
|
return (/* @__PURE__ */ __name(async function* guarded() {
|
|
2127
2311
|
const safe = await runInputGuards(message, guardrails);
|
|
2128
|
-
return yield* moderateOutputStream(
|
|
2312
|
+
return yield* moderateOutputStream(
|
|
2313
|
+
moderateOutputStream(
|
|
2314
|
+
runUnguarded(safe),
|
|
2315
|
+
guardrails,
|
|
2316
|
+
// B-021 — the shared extractor, so "this kind, content unreadable" throws instead of
|
|
2317
|
+
// sharing a return value with "not this kind". The hand-written form here returned
|
|
2318
|
+
// `undefined` for a non-string, which reads as "carries no text": the payload was never
|
|
2319
|
+
// shown to a guard and was yielded verbatim.
|
|
2320
|
+
textPayloadExtractor("text_delta", (e) => e.content),
|
|
2321
|
+
(content) => ({
|
|
2322
|
+
type: "text_delta",
|
|
2323
|
+
content
|
|
2324
|
+
}),
|
|
2325
|
+
(content, result) => ({
|
|
2326
|
+
...result,
|
|
2327
|
+
response: content
|
|
2328
|
+
})
|
|
2329
|
+
),
|
|
2330
|
+
guardrails,
|
|
2331
|
+
textPayloadExtractor("thinking", (e) => e.content),
|
|
2332
|
+
(content) => ({
|
|
2333
|
+
type: "thinking",
|
|
2334
|
+
content
|
|
2335
|
+
}),
|
|
2336
|
+
// The reasoning pass does NOT touch the aggregate — the visible pass already did.
|
|
2337
|
+
(_content, result) => result
|
|
2338
|
+
);
|
|
2129
2339
|
}, "guarded"))();
|
|
2130
2340
|
}
|
|
2131
2341
|
return this.streamUnguarded(message, opts);
|
|
@@ -2349,11 +2559,13 @@ function mergeTools(parentTools, subTools) {
|
|
|
2349
2559
|
__name(mergeTools, "mergeTools");
|
|
2350
2560
|
async function delegate(spec, message, opts = {}) {
|
|
2351
2561
|
const apiKey = requireApiKey(opts, spec.name);
|
|
2352
|
-
const
|
|
2562
|
+
const rewritten = opts.onDelegationStart ? await opts.onDelegationStart({
|
|
2353
2563
|
subAgent: spec.name,
|
|
2354
2564
|
input: message
|
|
2355
2565
|
}) : message;
|
|
2356
2566
|
const { compiled } = spec;
|
|
2567
|
+
const guardrails = compiled.guardrails ?? [];
|
|
2568
|
+
const effectiveMessage = await runInputGuards(rewritten, guardrails);
|
|
2357
2569
|
const allTools = mergeTools(opts.parentTools ?? [], compiled.tools);
|
|
2358
2570
|
const budget = Math.min(opts.budget ?? Infinity, opts.parentBudgetRemaining ?? Infinity);
|
|
2359
2571
|
const compiledForMember = withInheritedHooks(compiled, opts.parentHooks);
|
|
@@ -2377,15 +2589,21 @@ async function delegate(spec, message, opts = {}) {
|
|
|
2377
2589
|
signal: opts.signal,
|
|
2378
2590
|
retry: opts.retry
|
|
2379
2591
|
});
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
}
|
|
2386
|
-
return result;
|
|
2592
|
+
const transformed = opts.onDelegationComplete ? await opts.onDelegationComplete({
|
|
2593
|
+
subAgent: spec.name,
|
|
2594
|
+
result
|
|
2595
|
+
}) : result;
|
|
2596
|
+
return await moderateDelegationResult(transformed, guardrails);
|
|
2387
2597
|
}
|
|
2388
2598
|
__name(delegate, "delegate");
|
|
2599
|
+
async function moderateDelegationResult(result, guardrails) {
|
|
2600
|
+
if (guardrails.length === 0) return result;
|
|
2601
|
+
return {
|
|
2602
|
+
...result,
|
|
2603
|
+
response: await runOutputGuards(result.response, guardrails)
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
__name(moderateDelegationResult, "moderateDelegationResult");
|
|
2389
2607
|
|
|
2390
2608
|
// src/bridge/delegation-lifecycle.ts
|
|
2391
2609
|
import { TheokitAgentError as TheokitAgentError5 } from "@theokit/sdk/errors";
|
|
@@ -2436,7 +2654,8 @@ __name(withEphemeralAgent, "withEphemeralAgent");
|
|
|
2436
2654
|
|
|
2437
2655
|
// src/bridge/delegation-scoring.ts
|
|
2438
2656
|
function isPort(target) {
|
|
2439
|
-
|
|
2657
|
+
if ("compiled" in target) return false;
|
|
2658
|
+
return typeof target.run === "function";
|
|
2440
2659
|
}
|
|
2441
2660
|
__name(isPort, "isPort");
|
|
2442
2661
|
async function runOnce(target, message, delegateFn, opts) {
|
|
@@ -2502,7 +2721,16 @@ __name(delegateWithScoring, "delegateWithScoring");
|
|
|
2502
2721
|
export {
|
|
2503
2722
|
projectContextMetadataOnlyKnobs,
|
|
2504
2723
|
compileProjectContext,
|
|
2724
|
+
APPROVAL_MODES,
|
|
2725
|
+
WRITE_SCOPED_TOOLS,
|
|
2726
|
+
shouldAutoApprove,
|
|
2727
|
+
createHitlPlugin,
|
|
2728
|
+
createToolHooksPlugin,
|
|
2729
|
+
applyPosture,
|
|
2730
|
+
GuardrailError,
|
|
2731
|
+
MalformedGuardrailResultError,
|
|
2505
2732
|
GuardrailViolationError,
|
|
2733
|
+
UnreadableTextPayloadError,
|
|
2506
2734
|
CostBudgetExceededError,
|
|
2507
2735
|
estimateTokens,
|
|
2508
2736
|
promptInjectionDetector,
|
|
@@ -2513,15 +2741,11 @@ export {
|
|
|
2513
2741
|
runInputGuards,
|
|
2514
2742
|
runOutputGuards,
|
|
2515
2743
|
moderateOutputStream,
|
|
2516
|
-
|
|
2517
|
-
WRITE_SCOPED_TOOLS,
|
|
2518
|
-
shouldAutoApprove,
|
|
2519
|
-
createHitlPlugin,
|
|
2520
|
-
createToolHooksPlugin,
|
|
2521
|
-
applyPosture,
|
|
2744
|
+
textPayloadExtractor,
|
|
2522
2745
|
buildModelSelection,
|
|
2523
2746
|
reasoningEffortOf,
|
|
2524
2747
|
HookGateUnsupportedError,
|
|
2748
|
+
CompatImportUnsupportedError,
|
|
2525
2749
|
translateSdkEvent,
|
|
2526
2750
|
createThinkTagExtractor,
|
|
2527
2751
|
extractThinkTagStream,
|
|
@@ -2553,4 +2777,4 @@ export {
|
|
|
2553
2777
|
delegateBackground,
|
|
2554
2778
|
delegateWithScoring
|
|
2555
2779
|
};
|
|
2556
|
-
//# sourceMappingURL=chunk-
|
|
2780
|
+
//# sourceMappingURL=chunk-HBHZV3KL.js.map
|