@theokit/agents 0.30.1 → 0.31.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/dist/{bridge-entry-DVhOQc_f.d.ts → bridge-entry-DtDotZGW.d.ts} +376 -7
- package/dist/bridge.d.ts +1 -1
- package/dist/bridge.js +7 -1
- package/dist/{chunk-XCQNYAVU.js → chunk-BWYBOMKR.js} +477 -61
- package/dist/chunk-BWYBOMKR.js.map +1 -0
- package/dist/index.d.ts +270 -31
- package/dist/index.js +313 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-XCQNYAVU.js.map +0 -1
|
@@ -27,13 +27,13 @@ import {
|
|
|
27
27
|
} from "./chunk-7QVYU63E.js";
|
|
28
28
|
|
|
29
29
|
// src/bridge/agent-execution-context.ts
|
|
30
|
-
function createAgentExecutionContext(base,
|
|
30
|
+
function createAgentExecutionContext(base, agent2, run, toolCall) {
|
|
31
31
|
return {
|
|
32
32
|
getRequest: /* @__PURE__ */ __name(() => base.getRequest(), "getRequest"),
|
|
33
33
|
getUrl: /* @__PURE__ */ __name(() => base.getUrl(), "getUrl"),
|
|
34
34
|
getClass: /* @__PURE__ */ __name(() => base.getClass(), "getClass"),
|
|
35
35
|
getMethodName: /* @__PURE__ */ __name(() => base.getMethodName(), "getMethodName"),
|
|
36
|
-
getAgent: /* @__PURE__ */ __name(() =>
|
|
36
|
+
getAgent: /* @__PURE__ */ __name(() => agent2, "getAgent"),
|
|
37
37
|
getRun: /* @__PURE__ */ __name(() => run, "getRun"),
|
|
38
38
|
getToolCall: /* @__PURE__ */ __name(() => toolCall ?? null, "getToolCall"),
|
|
39
39
|
isAgentContext: /* @__PURE__ */ __name(() => true, "isAgentContext")
|
|
@@ -982,7 +982,8 @@ async function loadSdkRuntime() {
|
|
|
982
982
|
InMemoryConversationStorage: InMemory,
|
|
983
983
|
FileSystemConversationStorage: "FileSystemConversationStorage" in sdk ? sdk.FileSystemConversationStorage : InMemory
|
|
984
984
|
};
|
|
985
|
-
} catch {
|
|
985
|
+
} catch (err) {
|
|
986
|
+
console.warn("[theokit] @theokit/sdk import failed:", err);
|
|
986
987
|
return null;
|
|
987
988
|
}
|
|
988
989
|
}
|
|
@@ -1124,15 +1125,34 @@ function hasZodInputSchema(schema) {
|
|
|
1124
1125
|
return typeof schema?.parse === "function";
|
|
1125
1126
|
}
|
|
1126
1127
|
__name(hasZodInputSchema, "hasZodInputSchema");
|
|
1127
|
-
function
|
|
1128
|
+
function withRunContext(handler, runContext) {
|
|
1129
|
+
return (input, ctx) => handler(input, {
|
|
1130
|
+
signal: ctx?.signal,
|
|
1131
|
+
context: runContext
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
__name(withRunContext, "withRunContext");
|
|
1135
|
+
function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext) {
|
|
1136
|
+
const has = runContext !== void 0;
|
|
1128
1137
|
return [
|
|
1129
|
-
...compiledTools.map((t) =>
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1138
|
+
...compiledTools.map((t) => {
|
|
1139
|
+
if (hasZodInputSchema(t.inputSchema)) {
|
|
1140
|
+
return defineTool({
|
|
1141
|
+
name: t.name,
|
|
1142
|
+
description: t.description,
|
|
1143
|
+
inputSchema: t.inputSchema,
|
|
1144
|
+
handler: has ? withRunContext(t.handler, runContext) : t.handler
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
return has ? {
|
|
1148
|
+
...t,
|
|
1149
|
+
handler: withRunContext(t.handler, runContext)
|
|
1150
|
+
} : t;
|
|
1151
|
+
}),
|
|
1152
|
+
...extraSdkTools.map((t) => has ? {
|
|
1153
|
+
...t,
|
|
1154
|
+
handler: withRunContext(t.handler, runContext)
|
|
1155
|
+
} : t)
|
|
1136
1156
|
];
|
|
1137
1157
|
}
|
|
1138
1158
|
__name(buildSdkTools, "buildSdkTools");
|
|
@@ -1140,6 +1160,7 @@ function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
|
1140
1160
|
const model = overrides.model ?? compiled.model ?? "openai/gpt-4o-mini";
|
|
1141
1161
|
const reasoningEffort = overrides.reasoningEffort ?? compiled.reasoningEffort;
|
|
1142
1162
|
const { parseThinkTags, stripToolDialect } = resolveTextTransformFlags(compiled, overrides);
|
|
1163
|
+
const runContext = overrides.runContext ?? compiled.runContext;
|
|
1143
1164
|
let storage = overrides.conversationStorage;
|
|
1144
1165
|
return (message, sessionId, factoryOpts) => ({
|
|
1145
1166
|
async *[Symbol.asyncIterator]() {
|
|
@@ -1155,51 +1176,35 @@ function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
|
1155
1176
|
};
|
|
1156
1177
|
return;
|
|
1157
1178
|
}
|
|
1158
|
-
const {
|
|
1159
|
-
const sdkTools = buildSdkTools(compiledTools, defineTool, overrides.sdkTools);
|
|
1160
|
-
let
|
|
1179
|
+
const { InMemoryConversationStorage, FileSystemConversationStorage } = rt;
|
|
1180
|
+
const sdkTools = buildSdkTools(compiledTools, rt.defineTool, overrides.sdkTools, runContext);
|
|
1181
|
+
let runContextSource;
|
|
1182
|
+
if (overrides.runContext !== void 0) {
|
|
1183
|
+
runContextSource = "per-run";
|
|
1184
|
+
} else if (compiled.runContext !== void 0) {
|
|
1185
|
+
runContextSource = "agent-level";
|
|
1186
|
+
} else {
|
|
1187
|
+
runContextSource = "none";
|
|
1188
|
+
}
|
|
1189
|
+
console.debug("[THEO_AGENT_M7_RUN_CONTEXT]", {
|
|
1190
|
+
source: runContextSource,
|
|
1191
|
+
keys: runContext !== void 0 ? Object.keys(runContext) : []
|
|
1192
|
+
});
|
|
1193
|
+
storage ??= newConversationStorage(compiled, InMemoryConversationStorage, FileSystemConversationStorage);
|
|
1161
1194
|
try {
|
|
1162
|
-
|
|
1163
|
-
if (overrides.cwd !== void 0) m8.local = {
|
|
1164
|
-
...m8.local,
|
|
1165
|
-
cwd: overrides.cwd
|
|
1166
|
-
};
|
|
1167
|
-
const extra = buildExtraCreateOptions(overrides, compiled);
|
|
1168
|
-
storage ??= newConversationStorage(compiled, InMemoryConversationStorage, FileSystemConversationStorage);
|
|
1169
|
-
if (applied.length > 0) {
|
|
1170
|
-
console.debug("[THEO_AGENT_M8_RUNTIME_APPLIED]", {
|
|
1171
|
-
skills: applied.includes("skills"),
|
|
1172
|
-
context: applied.includes("context"),
|
|
1173
|
-
projectContext: applied.includes("projectContext")
|
|
1174
|
-
});
|
|
1175
|
-
}
|
|
1176
|
-
agent = await Agent.getOrCreate(sessionId, {
|
|
1195
|
+
yield* streamSdkAgent(rt, compiled, sdkTools, storage, {
|
|
1177
1196
|
apiKey,
|
|
1178
|
-
model
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
...extra,
|
|
1182
|
-
conversationStorage: storage
|
|
1183
|
-
});
|
|
1184
|
-
const queue = createAsyncQueue();
|
|
1185
|
-
const { state, onDelta } = createDeltaSink(queue);
|
|
1186
|
-
const sendPromise = agent.send(message, factoryOpts?.disableTools === true ? {
|
|
1187
|
-
onDelta,
|
|
1188
|
-
toolChoice: "none"
|
|
1189
|
-
} : {
|
|
1190
|
-
onDelta
|
|
1191
|
-
});
|
|
1192
|
-
const openStream = /* @__PURE__ */ __name(async () => (await sendPromise).stream(), "openStream");
|
|
1193
|
-
const merged = mergeDeltaStream(queue, openStream, runId, state);
|
|
1194
|
-
for await (const event of applyTextTransforms(merged, {
|
|
1197
|
+
model,
|
|
1198
|
+
reasoningEffort,
|
|
1199
|
+
overrides,
|
|
1195
1200
|
parseThinkTags,
|
|
1196
|
-
stripToolDialect
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
}
|
|
1201
|
+
stripToolDialect,
|
|
1202
|
+
sessionId,
|
|
1203
|
+
message,
|
|
1204
|
+
factoryOpts,
|
|
1205
|
+
runId,
|
|
1206
|
+
t0
|
|
1207
|
+
});
|
|
1203
1208
|
} catch (err) {
|
|
1204
1209
|
yield {
|
|
1205
1210
|
type: "error",
|
|
@@ -1207,13 +1212,59 @@ function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
|
1207
1212
|
message: err instanceof Error ? err.message : "SDK agent error",
|
|
1208
1213
|
retryable: false
|
|
1209
1214
|
};
|
|
1210
|
-
} finally {
|
|
1211
|
-
await agent?.dispose();
|
|
1212
1215
|
}
|
|
1213
1216
|
}
|
|
1214
1217
|
});
|
|
1215
1218
|
}
|
|
1216
1219
|
__name(createSdkAgentStream, "createSdkAgentStream");
|
|
1220
|
+
async function* streamSdkAgent(rt, compiled, sdkTools, storage, opts) {
|
|
1221
|
+
const { Agent } = rt;
|
|
1222
|
+
const { apiKey, model, reasoningEffort, overrides, parseThinkTags, stripToolDialect, sessionId, message, factoryOpts, runId, t0 } = opts;
|
|
1223
|
+
const { options: m8, applied } = assembleM8CreateOptions(compiled);
|
|
1224
|
+
if (overrides.cwd !== void 0) m8.local = {
|
|
1225
|
+
...m8.local,
|
|
1226
|
+
cwd: overrides.cwd
|
|
1227
|
+
};
|
|
1228
|
+
const extra = buildExtraCreateOptions(overrides, compiled);
|
|
1229
|
+
if (applied.length > 0) {
|
|
1230
|
+
console.debug("[THEO_AGENT_M8_RUNTIME_APPLIED]", {
|
|
1231
|
+
skills: applied.includes("skills"),
|
|
1232
|
+
contextWindow: applied.includes("context"),
|
|
1233
|
+
projectContext: applied.includes("projectContext")
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
const agent2 = await Agent.getOrCreate(sessionId, {
|
|
1237
|
+
apiKey,
|
|
1238
|
+
model: buildModelSelection(model, reasoningEffort),
|
|
1239
|
+
tools: sdkTools,
|
|
1240
|
+
...m8,
|
|
1241
|
+
...extra,
|
|
1242
|
+
conversationStorage: storage
|
|
1243
|
+
});
|
|
1244
|
+
try {
|
|
1245
|
+
const queue = createAsyncQueue();
|
|
1246
|
+
const { state, onDelta } = createDeltaSink(queue);
|
|
1247
|
+
const sendOptions = {
|
|
1248
|
+
onDelta
|
|
1249
|
+
};
|
|
1250
|
+
if (factoryOpts?.disableTools === true) sendOptions.toolChoice = "none";
|
|
1251
|
+
const sendPromise = agent2.send(message, sendOptions);
|
|
1252
|
+
const openStream = /* @__PURE__ */ __name(async () => (await sendPromise).stream(), "openStream");
|
|
1253
|
+
const merged = mergeDeltaStream(queue, openStream, runId, state);
|
|
1254
|
+
for await (const event of applyTextTransforms(merged, {
|
|
1255
|
+
parseThinkTags,
|
|
1256
|
+
stripToolDialect
|
|
1257
|
+
})) {
|
|
1258
|
+
yield event;
|
|
1259
|
+
}
|
|
1260
|
+
if (!state.sawError) {
|
|
1261
|
+
yield realUsageDone(await (await sendPromise).wait(), t0);
|
|
1262
|
+
}
|
|
1263
|
+
} finally {
|
|
1264
|
+
await agent2.dispose();
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
__name(streamSdkAgent, "streamSdkAgent");
|
|
1217
1268
|
|
|
1218
1269
|
// src/bridge/ui-message-stream-translator.ts
|
|
1219
1270
|
function* closeOpenBlock(state, textId) {
|
|
@@ -1389,17 +1440,116 @@ function isAgentDefinition(value) {
|
|
|
1389
1440
|
return typeof value === "object" && value !== null && value[AGENT_BRAND] === true;
|
|
1390
1441
|
}
|
|
1391
1442
|
__name(isAgentDefinition, "isAgentDefinition");
|
|
1443
|
+
function toCompiledTool(tool) {
|
|
1444
|
+
const handler = tool.handler;
|
|
1445
|
+
return {
|
|
1446
|
+
name: tool.name,
|
|
1447
|
+
description: tool.description,
|
|
1448
|
+
inputSchema: tool.inputSchema,
|
|
1449
|
+
handler: /* @__PURE__ */ __name((input, ctx) => handler(input, ctx), "handler")
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
__name(toCompiledTool, "toCompiledTool");
|
|
1392
1453
|
function compileAgentDefinition(def) {
|
|
1393
1454
|
return {
|
|
1394
1455
|
model: def.model,
|
|
1395
1456
|
reasoningEffort: def.reasoningEffort,
|
|
1396
1457
|
systemPrompt: def.system,
|
|
1397
|
-
tools: def.tools ?? [],
|
|
1458
|
+
tools: (def.tools ?? []).map(toCompiledTool),
|
|
1398
1459
|
agents: {},
|
|
1399
|
-
stream: true
|
|
1460
|
+
stream: true,
|
|
1461
|
+
// M7 — run-context flows to CompiledAgentOptions.runContext (distinct from the
|
|
1462
|
+
// context-window `context` field the decorator path uses); absent ⇒ no key.
|
|
1463
|
+
...def.context !== void 0 ? {
|
|
1464
|
+
runContext: def.context
|
|
1465
|
+
} : {},
|
|
1466
|
+
// M9 — guardrails flow through unchanged; the runner applies them at the input boundary.
|
|
1467
|
+
...def.guardrails !== void 0 ? {
|
|
1468
|
+
guardrails: def.guardrails
|
|
1469
|
+
} : {},
|
|
1470
|
+
// M14 — HITL approvals compile into the same `hitl` map the decorator path produces.
|
|
1471
|
+
...def.approvals !== void 0 ? {
|
|
1472
|
+
hitl: compileApprovals(def)
|
|
1473
|
+
} : {},
|
|
1474
|
+
// M13 — skills: a static list → SDK skills.enabled; a resolver → carried for the request path.
|
|
1475
|
+
...compileSkillsSelection(def.skills)
|
|
1400
1476
|
};
|
|
1401
1477
|
}
|
|
1402
1478
|
__name(compileAgentDefinition, "compileAgentDefinition");
|
|
1479
|
+
function compileSkillsSelection(skills) {
|
|
1480
|
+
if (skills === void 0) return {};
|
|
1481
|
+
if (typeof skills === "function") return {
|
|
1482
|
+
skillsResolver: skills
|
|
1483
|
+
};
|
|
1484
|
+
return {
|
|
1485
|
+
skills: {
|
|
1486
|
+
enabled: [
|
|
1487
|
+
...skills
|
|
1488
|
+
],
|
|
1489
|
+
autoInject: true
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
__name(compileSkillsSelection, "compileSkillsSelection");
|
|
1494
|
+
function compileApprovals(def) {
|
|
1495
|
+
const toolNames = new Set((def.tools ?? []).map((t) => t.name));
|
|
1496
|
+
const gates = /* @__PURE__ */ new Map();
|
|
1497
|
+
for (const [toolName, options] of Object.entries(def.approvals ?? {})) {
|
|
1498
|
+
if (!toolNames.has(toolName)) {
|
|
1499
|
+
throw new Error(`[@theokit/agents] defineAgent approval references unknown tool "${toolName}". Declared tools: ${[
|
|
1500
|
+
...toolNames
|
|
1501
|
+
].join(", ") || "(none)"}.`);
|
|
1502
|
+
}
|
|
1503
|
+
gates.set(toolName, options);
|
|
1504
|
+
}
|
|
1505
|
+
return gates;
|
|
1506
|
+
}
|
|
1507
|
+
__name(compileApprovals, "compileApprovals");
|
|
1508
|
+
|
|
1509
|
+
// src/bridge/agent-builder.ts
|
|
1510
|
+
function contextualTool(tool, _requiredContext) {
|
|
1511
|
+
return tool;
|
|
1512
|
+
}
|
|
1513
|
+
__name(contextualTool, "contextualTool");
|
|
1514
|
+
function makeBuilder(config) {
|
|
1515
|
+
const runtime = {
|
|
1516
|
+
input: /* @__PURE__ */ __name((schema) => makeBuilder({
|
|
1517
|
+
...config,
|
|
1518
|
+
input: schema
|
|
1519
|
+
}), "input"),
|
|
1520
|
+
model: /* @__PURE__ */ __name((id) => makeBuilder({
|
|
1521
|
+
...config,
|
|
1522
|
+
model: id
|
|
1523
|
+
}), "model"),
|
|
1524
|
+
system: /* @__PURE__ */ __name((prompt) => makeBuilder({
|
|
1525
|
+
...config,
|
|
1526
|
+
system: prompt
|
|
1527
|
+
}), "system"),
|
|
1528
|
+
reasoningEffort: /* @__PURE__ */ __name((effort) => makeBuilder({
|
|
1529
|
+
...config,
|
|
1530
|
+
reasoningEffort: effort
|
|
1531
|
+
}), "reasoningEffort"),
|
|
1532
|
+
context: /* @__PURE__ */ __name((value) => makeBuilder({
|
|
1533
|
+
...config,
|
|
1534
|
+
context: value
|
|
1535
|
+
}), "context"),
|
|
1536
|
+
tool: /* @__PURE__ */ __name((tool) => makeBuilder({
|
|
1537
|
+
...config,
|
|
1538
|
+
tools: [
|
|
1539
|
+
...config.tools ?? [],
|
|
1540
|
+
tool
|
|
1541
|
+
]
|
|
1542
|
+
}), "tool"),
|
|
1543
|
+
use: /* @__PURE__ */ __name((preset) => preset(runtime), "use"),
|
|
1544
|
+
build: /* @__PURE__ */ __name(() => defineAgent(config), "build")
|
|
1545
|
+
};
|
|
1546
|
+
return runtime;
|
|
1547
|
+
}
|
|
1548
|
+
__name(makeBuilder, "makeBuilder");
|
|
1549
|
+
function agent() {
|
|
1550
|
+
return makeBuilder({});
|
|
1551
|
+
}
|
|
1552
|
+
__name(agent, "agent");
|
|
1403
1553
|
|
|
1404
1554
|
// src/bridge/hitl-plugin.ts
|
|
1405
1555
|
function createHitlPlugin(wiring) {
|
|
@@ -1419,7 +1569,7 @@ function createHitlPlugin(wiring) {
|
|
|
1419
1569
|
callbackUrl: `approve/${approvalId}`,
|
|
1420
1570
|
timeoutMs: opts.timeout ?? 3e5
|
|
1421
1571
|
});
|
|
1422
|
-
const approved = await wiring.awaitApproval(approvalId, opts);
|
|
1572
|
+
const approved = await wiring.awaitApproval(approvalId, opts, c.name);
|
|
1423
1573
|
return approved ? void 0 : {
|
|
1424
1574
|
block: true,
|
|
1425
1575
|
message: `Tool '${c.name}' denied by human approver`
|
|
@@ -1571,6 +1721,198 @@ function streamAgentUIMessages(compiled, apiKey, input) {
|
|
|
1571
1721
|
}
|
|
1572
1722
|
__name(streamAgentUIMessages, "streamAgentUIMessages");
|
|
1573
1723
|
|
|
1724
|
+
// src/guardrails/types.ts
|
|
1725
|
+
var GuardrailViolationError = class extends Error {
|
|
1726
|
+
static {
|
|
1727
|
+
__name(this, "GuardrailViolationError");
|
|
1728
|
+
}
|
|
1729
|
+
guardName;
|
|
1730
|
+
phase;
|
|
1731
|
+
reason;
|
|
1732
|
+
constructor(guardName, phase, reason) {
|
|
1733
|
+
super(`Guardrail "${guardName}" blocked ${phase}: ${reason}`), this.guardName = guardName, this.phase = phase, this.reason = reason;
|
|
1734
|
+
this.name = "GuardrailViolationError";
|
|
1735
|
+
}
|
|
1736
|
+
};
|
|
1737
|
+
var CostBudgetExceededError = class extends Error {
|
|
1738
|
+
static {
|
|
1739
|
+
__name(this, "CostBudgetExceededError");
|
|
1740
|
+
}
|
|
1741
|
+
usedTokens;
|
|
1742
|
+
maxTokens;
|
|
1743
|
+
constructor(usedTokens, maxTokens) {
|
|
1744
|
+
super(`Cost budget exceeded: ${usedTokens} > ${maxTokens} tokens`), this.usedTokens = usedTokens, this.maxTokens = maxTokens;
|
|
1745
|
+
this.name = "CostBudgetExceededError";
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
|
|
1749
|
+
// src/guardrails/detectors.ts
|
|
1750
|
+
function estimateTokens(text) {
|
|
1751
|
+
return Math.ceil(text.length / 4);
|
|
1752
|
+
}
|
|
1753
|
+
__name(estimateTokens, "estimateTokens");
|
|
1754
|
+
var INJECTION_PHRASES = [
|
|
1755
|
+
"previous instructions",
|
|
1756
|
+
"disregard the above",
|
|
1757
|
+
"you are now dan",
|
|
1758
|
+
"system prompt",
|
|
1759
|
+
"no restrictions",
|
|
1760
|
+
"without restrictions",
|
|
1761
|
+
"no rules",
|
|
1762
|
+
"override your"
|
|
1763
|
+
];
|
|
1764
|
+
function normalizeForMatch(text) {
|
|
1765
|
+
return text.toLowerCase().replace(/\s+/g, " ");
|
|
1766
|
+
}
|
|
1767
|
+
__name(normalizeForMatch, "normalizeForMatch");
|
|
1768
|
+
function promptInjectionDetector(options = {}) {
|
|
1769
|
+
const phrases = [
|
|
1770
|
+
...INJECTION_PHRASES,
|
|
1771
|
+
...(options.extra ?? []).map((p) => p.toLowerCase())
|
|
1772
|
+
];
|
|
1773
|
+
return {
|
|
1774
|
+
name: "prompt-injection",
|
|
1775
|
+
checkInput(text) {
|
|
1776
|
+
const normalized = normalizeForMatch(text);
|
|
1777
|
+
for (const phrase of phrases) {
|
|
1778
|
+
if (normalized.includes(phrase)) {
|
|
1779
|
+
return {
|
|
1780
|
+
action: "block",
|
|
1781
|
+
reason: `prompt injection phrase matched: "${phrase}"`
|
|
1782
|
+
};
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
return {
|
|
1786
|
+
action: "allow"
|
|
1787
|
+
};
|
|
1788
|
+
}
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
__name(promptInjectionDetector, "promptInjectionDetector");
|
|
1792
|
+
var CPF = /\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g;
|
|
1793
|
+
var EMAIL = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
|
|
1794
|
+
var PHONE = /\+?\d[\d\s()-]{7,13}\d/g;
|
|
1795
|
+
function piiDetector(options = {}) {
|
|
1796
|
+
const placeholder = options.placeholder ?? "[REDACTED]";
|
|
1797
|
+
return {
|
|
1798
|
+
name: "pii",
|
|
1799
|
+
checkInput(text) {
|
|
1800
|
+
let redacted = text;
|
|
1801
|
+
redacted = redacted.replace(EMAIL, placeholder);
|
|
1802
|
+
redacted = redacted.replace(CPF, placeholder);
|
|
1803
|
+
redacted = redacted.replace(PHONE, placeholder);
|
|
1804
|
+
if (redacted === text) return {
|
|
1805
|
+
action: "allow"
|
|
1806
|
+
};
|
|
1807
|
+
return {
|
|
1808
|
+
action: "redact",
|
|
1809
|
+
text: redacted,
|
|
1810
|
+
reason: "PII detected and redacted"
|
|
1811
|
+
};
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
__name(piiDetector, "piiDetector");
|
|
1816
|
+
var OBFUSCATION_CHARS = /[\u200B-\u200D\uFEFF\u202A-\u202E\u2066-\u2069]/g;
|
|
1817
|
+
function unicodeNormalizer() {
|
|
1818
|
+
return {
|
|
1819
|
+
name: "unicode-normalizer",
|
|
1820
|
+
checkInput(text) {
|
|
1821
|
+
const cleaned = text.normalize("NFKC").replace(OBFUSCATION_CHARS, "");
|
|
1822
|
+
if (cleaned === text) return {
|
|
1823
|
+
action: "allow"
|
|
1824
|
+
};
|
|
1825
|
+
return {
|
|
1826
|
+
action: "redact",
|
|
1827
|
+
text: cleaned,
|
|
1828
|
+
reason: "obfuscation characters normalized"
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
__name(unicodeNormalizer, "unicodeNormalizer");
|
|
1834
|
+
function costGuard(options) {
|
|
1835
|
+
let used = 0;
|
|
1836
|
+
return {
|
|
1837
|
+
name: "cost-guard",
|
|
1838
|
+
// Returns a Promise explicitly (not `async`) so a budget breach REJECTS uniformly — never a
|
|
1839
|
+
// sync throw — safe for direct callers and for the pipeline's `await g.checkInput()`.
|
|
1840
|
+
checkInput(text) {
|
|
1841
|
+
used += estimateTokens(text);
|
|
1842
|
+
if (used > options.maxTokens) {
|
|
1843
|
+
return Promise.reject(new CostBudgetExceededError(used, options.maxTokens));
|
|
1844
|
+
}
|
|
1845
|
+
return Promise.resolve({
|
|
1846
|
+
action: "allow"
|
|
1847
|
+
});
|
|
1848
|
+
}
|
|
1849
|
+
};
|
|
1850
|
+
}
|
|
1851
|
+
__name(costGuard, "costGuard");
|
|
1852
|
+
function outputModeration(options) {
|
|
1853
|
+
return {
|
|
1854
|
+
name: "output-moderation",
|
|
1855
|
+
async checkOutput(text) {
|
|
1856
|
+
const flagged = await options.moderate(text);
|
|
1857
|
+
return flagged ? {
|
|
1858
|
+
action: "block",
|
|
1859
|
+
reason: "output flagged by moderation predicate"
|
|
1860
|
+
} : {
|
|
1861
|
+
action: "allow"
|
|
1862
|
+
};
|
|
1863
|
+
}
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
__name(outputModeration, "outputModeration");
|
|
1867
|
+
|
|
1868
|
+
// src/guardrails/pipeline.ts
|
|
1869
|
+
async function runInputGuards(text, guards) {
|
|
1870
|
+
let current = text;
|
|
1871
|
+
for (const g of guards) {
|
|
1872
|
+
if (!g.checkInput) continue;
|
|
1873
|
+
const r = await g.checkInput(current);
|
|
1874
|
+
if (r.action === "block") {
|
|
1875
|
+
throw new GuardrailViolationError(g.name, "input", r.reason ?? "blocked");
|
|
1876
|
+
}
|
|
1877
|
+
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
1878
|
+
}
|
|
1879
|
+
return current;
|
|
1880
|
+
}
|
|
1881
|
+
__name(runInputGuards, "runInputGuards");
|
|
1882
|
+
async function runOutputGuards(text, guards) {
|
|
1883
|
+
let current = text;
|
|
1884
|
+
for (const g of guards) {
|
|
1885
|
+
if (!g.checkOutput) continue;
|
|
1886
|
+
const r = await g.checkOutput(current);
|
|
1887
|
+
if (r.action === "block") {
|
|
1888
|
+
throw new GuardrailViolationError(g.name, "output", r.reason ?? "blocked");
|
|
1889
|
+
}
|
|
1890
|
+
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
1891
|
+
}
|
|
1892
|
+
return current;
|
|
1893
|
+
}
|
|
1894
|
+
__name(runOutputGuards, "runOutputGuards");
|
|
1895
|
+
|
|
1896
|
+
// src/guardrails/stream.ts
|
|
1897
|
+
async function* moderateOutputStream(inner, guards, extractText) {
|
|
1898
|
+
const hasOutputGuard = guards.some((g) => g.checkOutput != null);
|
|
1899
|
+
if (!hasOutputGuard) return yield* inner;
|
|
1900
|
+
const buffered = [];
|
|
1901
|
+
let accumulated = "";
|
|
1902
|
+
let step = await inner.next();
|
|
1903
|
+
while (!step.done) {
|
|
1904
|
+
const event = step.value;
|
|
1905
|
+
const text = extractText(event);
|
|
1906
|
+
if (text !== void 0) accumulated += text;
|
|
1907
|
+
buffered.push(event);
|
|
1908
|
+
step = await inner.next();
|
|
1909
|
+
}
|
|
1910
|
+
await runOutputGuards(accumulated, guards);
|
|
1911
|
+
for (const event of buffered) yield event;
|
|
1912
|
+
return step.value;
|
|
1913
|
+
}
|
|
1914
|
+
__name(moderateOutputStream, "moderateOutputStream");
|
|
1915
|
+
|
|
1574
1916
|
// src/loop/compaction-strategy.ts
|
|
1575
1917
|
import { compactTranscript } from "@theokit/sdk/compaction";
|
|
1576
1918
|
import { z } from "zod";
|
|
@@ -1994,6 +2336,18 @@ var AgentRunner = class {
|
|
|
1994
2336
|
* builder set `.stream(false)`, callers should use {@link run} instead.
|
|
1995
2337
|
*/
|
|
1996
2338
|
stream(message, opts) {
|
|
2339
|
+
const guardrails = this.compiled.guardrails;
|
|
2340
|
+
if (guardrails && guardrails.length > 0) {
|
|
2341
|
+
const runUnguarded = /* @__PURE__ */ __name((m) => this.streamUnguarded(m, opts), "runUnguarded");
|
|
2342
|
+
return (/* @__PURE__ */ __name(async function* guarded() {
|
|
2343
|
+
const safe = await runInputGuards(message, guardrails);
|
|
2344
|
+
return yield* moderateOutputStream(runUnguarded(safe), guardrails, (e) => e.type === "text_delta" && typeof e.content === "string" ? e.content : void 0);
|
|
2345
|
+
}, "guarded"))();
|
|
2346
|
+
}
|
|
2347
|
+
return this.streamUnguarded(message, opts);
|
|
2348
|
+
}
|
|
2349
|
+
/** The core stream path, after input guardrails have run (M9). */
|
|
2350
|
+
streamUnguarded(message, opts) {
|
|
1997
2351
|
const tools = opts.tools ? [
|
|
1998
2352
|
...opts.tools
|
|
1999
2353
|
] : this.compiled.tools;
|
|
@@ -2108,6 +2462,10 @@ function mergeTools(parentTools, subTools) {
|
|
|
2108
2462
|
__name(mergeTools, "mergeTools");
|
|
2109
2463
|
async function delegate(SubAgentClass, message, opts = {}) {
|
|
2110
2464
|
const apiKey = requireApiKey(opts, SubAgentClass.name);
|
|
2465
|
+
const effectiveMessage = opts.onDelegationStart ? await opts.onDelegationStart({
|
|
2466
|
+
subAgent: SubAgentClass.name,
|
|
2467
|
+
input: message
|
|
2468
|
+
}) : message;
|
|
2111
2469
|
const walk = walkAgentMetadata(SubAgentClass, []);
|
|
2112
2470
|
const toolboxInstances = new Map(walk.toolboxes.map((tb) => [
|
|
2113
2471
|
tb.class,
|
|
@@ -2116,7 +2474,7 @@ async function delegate(SubAgentClass, message, opts = {}) {
|
|
|
2116
2474
|
const compiled = compileAgent(walk, toolboxInstances);
|
|
2117
2475
|
const allTools = mergeTools(opts.parentTools ?? [], compiled.tools);
|
|
2118
2476
|
const budget = Math.min(opts.budget ?? Infinity, opts.parentBudgetRemaining ?? Infinity);
|
|
2119
|
-
const streamFactory = createSdkAgentStream(compiled, allTools, apiKey, {
|
|
2477
|
+
const streamFactory = opts.streamFactory ?? createSdkAgentStream(compiled, allTools, apiKey, {
|
|
2120
2478
|
model: opts.model ?? walk.agentConfig.model,
|
|
2121
2479
|
cwd: opts.cwd,
|
|
2122
2480
|
plugins: opts.plugins,
|
|
@@ -2129,7 +2487,7 @@ async function delegate(SubAgentClass, message, opts = {}) {
|
|
|
2129
2487
|
const sessionId = opts.sessionId ?? `sub-${crypto.randomUUID()}`;
|
|
2130
2488
|
const loopStrategy = resolveLoopStrategy(walk.mainLoop.strategy, opts.maxIterations ?? walk.mainLoop.maxIterations);
|
|
2131
2489
|
const reflection = opts.reflection ?? (loopStrategy.name === "plan-act-reflect" ? ladderReflectionStrategy : noopReflectionStrategy);
|
|
2132
|
-
|
|
2490
|
+
const result = await runReflectiveLoop(streamFactory, effectiveMessage, sessionId, {
|
|
2133
2491
|
loop: loopStrategy,
|
|
2134
2492
|
reflection,
|
|
2135
2493
|
budget,
|
|
@@ -2137,9 +2495,53 @@ async function delegate(SubAgentClass, message, opts = {}) {
|
|
|
2137
2495
|
signal: opts.signal,
|
|
2138
2496
|
retry: opts.retry
|
|
2139
2497
|
});
|
|
2498
|
+
if (opts.onDelegationComplete) {
|
|
2499
|
+
return await opts.onDelegationComplete({
|
|
2500
|
+
subAgent: SubAgentClass.name,
|
|
2501
|
+
result
|
|
2502
|
+
});
|
|
2503
|
+
}
|
|
2504
|
+
return result;
|
|
2140
2505
|
}
|
|
2141
2506
|
__name(delegate, "delegate");
|
|
2142
2507
|
|
|
2508
|
+
// src/bridge/tool-hooks-plugin.ts
|
|
2509
|
+
function createToolHooksPlugin(hooks) {
|
|
2510
|
+
return {
|
|
2511
|
+
name: "theokit-tool-hooks",
|
|
2512
|
+
register(ctx) {
|
|
2513
|
+
const { beforeToolCall, afterToolCall, beforeLLMCall, afterLLMCall } = hooks;
|
|
2514
|
+
if (beforeToolCall) {
|
|
2515
|
+
ctx.on("pre_tool_call", (c) => beforeToolCall({
|
|
2516
|
+
name: c.name ?? "",
|
|
2517
|
+
args: c.args ?? {}
|
|
2518
|
+
}));
|
|
2519
|
+
}
|
|
2520
|
+
if (afterToolCall) {
|
|
2521
|
+
ctx.on("post_tool_call", (c) => afterToolCall({
|
|
2522
|
+
name: c.name ?? "",
|
|
2523
|
+
result: c.result
|
|
2524
|
+
}));
|
|
2525
|
+
}
|
|
2526
|
+
if (beforeLLMCall) {
|
|
2527
|
+
ctx.on("pre_llm_call", (c) => beforeLLMCall({
|
|
2528
|
+
agentId: c.agentId,
|
|
2529
|
+
runId: c.runId,
|
|
2530
|
+
iteration: c.iteration
|
|
2531
|
+
}));
|
|
2532
|
+
}
|
|
2533
|
+
if (afterLLMCall) {
|
|
2534
|
+
ctx.on("post_llm_call", (c) => afterLLMCall({
|
|
2535
|
+
agentId: c.agentId,
|
|
2536
|
+
runId: c.runId,
|
|
2537
|
+
iteration: c.iteration
|
|
2538
|
+
}));
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
};
|
|
2542
|
+
}
|
|
2543
|
+
__name(createToolHooksPlugin, "createToolHooksPlugin");
|
|
2544
|
+
|
|
2143
2545
|
// src/manifest/agent-manifest.ts
|
|
2144
2546
|
function generateAgentManifest(walkResults) {
|
|
2145
2547
|
return {
|
|
@@ -2295,9 +2697,22 @@ export {
|
|
|
2295
2697
|
defineAgent,
|
|
2296
2698
|
isAgentDefinition,
|
|
2297
2699
|
compileAgentDefinition,
|
|
2700
|
+
contextualTool,
|
|
2701
|
+
agent,
|
|
2298
2702
|
AgentDefinitionError,
|
|
2299
2703
|
compileAgentModule,
|
|
2300
2704
|
streamAgentUIMessages,
|
|
2705
|
+
GuardrailViolationError,
|
|
2706
|
+
CostBudgetExceededError,
|
|
2707
|
+
estimateTokens,
|
|
2708
|
+
promptInjectionDetector,
|
|
2709
|
+
piiDetector,
|
|
2710
|
+
unicodeNormalizer,
|
|
2711
|
+
costGuard,
|
|
2712
|
+
outputModeration,
|
|
2713
|
+
runInputGuards,
|
|
2714
|
+
runOutputGuards,
|
|
2715
|
+
moderateOutputStream,
|
|
2301
2716
|
DEFAULT_KEEP_TOKENS,
|
|
2302
2717
|
compactionStrategyConfigSchema,
|
|
2303
2718
|
resolveCompactionStrategy,
|
|
@@ -2313,7 +2728,8 @@ export {
|
|
|
2313
2728
|
AgentRunner,
|
|
2314
2729
|
AgentRunnerBuilder,
|
|
2315
2730
|
delegate,
|
|
2731
|
+
createToolHooksPlugin,
|
|
2316
2732
|
generateAgentManifest,
|
|
2317
2733
|
agentsPlugin
|
|
2318
2734
|
};
|
|
2319
|
-
//# sourceMappingURL=chunk-
|
|
2735
|
+
//# sourceMappingURL=chunk-BWYBOMKR.js.map
|