@theokit/agents 4.30.2 → 5.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/LICENSE +201 -0
- package/dist/{bridge-entry-BL74g1Em.d.ts → bridge-entry-DD_j60GX.d.ts} +78 -42
- package/dist/bridge.d.ts +1 -1
- package/dist/bridge.js +1 -1
- package/dist/{chunk-GGB5WXHS.js → chunk-JXR45RAW.js} +166 -101
- package/dist/chunk-JXR45RAW.js.map +1 -0
- package/dist/index.d.ts +14 -4
- package/dist/index.js +29 -8
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
- package/dist/chunk-GGB5WXHS.js.map +0 -1
|
@@ -455,6 +455,59 @@ function generateAgentRoutes(ctx) {
|
|
|
455
455
|
}
|
|
456
456
|
__name(generateAgentRoutes, "generateAgentRoutes");
|
|
457
457
|
|
|
458
|
+
// src/bridge/tool-hooks-plugin.ts
|
|
459
|
+
function createToolHooksPlugin(hooks) {
|
|
460
|
+
return {
|
|
461
|
+
name: "theokit-tool-hooks",
|
|
462
|
+
version: "1.0.0",
|
|
463
|
+
// `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
|
|
464
|
+
// no hook fires (M10/M19 latent bug, proven via a real OpenRouter run).
|
|
465
|
+
kind: "general",
|
|
466
|
+
register(ctx) {
|
|
467
|
+
const { beforeToolCall, afterToolCall, beforeLLMCall, afterLLMCall, processInput } = hooks;
|
|
468
|
+
if (beforeToolCall) {
|
|
469
|
+
ctx.on("pre_tool_call", (c) => beforeToolCall({
|
|
470
|
+
name: c.name ?? "",
|
|
471
|
+
args: c.args ?? {}
|
|
472
|
+
}));
|
|
473
|
+
}
|
|
474
|
+
if (afterToolCall) {
|
|
475
|
+
ctx.on("post_tool_call", (c) => afterToolCall({
|
|
476
|
+
name: c.name ?? "",
|
|
477
|
+
result: c.result
|
|
478
|
+
}));
|
|
479
|
+
}
|
|
480
|
+
if (beforeLLMCall) {
|
|
481
|
+
ctx.on("pre_llm_call", (c) => beforeLLMCall({
|
|
482
|
+
agentId: c.agentId,
|
|
483
|
+
runId: c.runId,
|
|
484
|
+
iteration: c.iteration
|
|
485
|
+
}));
|
|
486
|
+
}
|
|
487
|
+
if (afterLLMCall) {
|
|
488
|
+
ctx.on("post_llm_call", (c) => afterLLMCall({
|
|
489
|
+
agentId: c.agentId,
|
|
490
|
+
runId: c.runId,
|
|
491
|
+
iteration: c.iteration
|
|
492
|
+
}));
|
|
493
|
+
}
|
|
494
|
+
if (processInput) {
|
|
495
|
+
ctx.on("pre_user_send", async (c) => {
|
|
496
|
+
const injected = await processInput({
|
|
497
|
+
prompt: c.prompt ?? "",
|
|
498
|
+
agentId: c.agentId,
|
|
499
|
+
runId: c.runId
|
|
500
|
+
});
|
|
501
|
+
return injected !== void 0 && injected.length > 0 ? {
|
|
502
|
+
recalledContext: injected
|
|
503
|
+
} : void 0;
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
__name(createToolHooksPlugin, "createToolHooksPlugin");
|
|
510
|
+
|
|
458
511
|
// src/bridge/event-translator.ts
|
|
459
512
|
function asString(value, fallback) {
|
|
460
513
|
if (typeof value === "string") return value;
|
|
@@ -766,6 +819,116 @@ function debugLog(marker, data) {
|
|
|
766
819
|
}
|
|
767
820
|
__name(debugLog, "debugLog");
|
|
768
821
|
|
|
822
|
+
// src/bridge/hitl-plugin.ts
|
|
823
|
+
function createHitlPlugin(wiring) {
|
|
824
|
+
return {
|
|
825
|
+
name: "theokit-hitl",
|
|
826
|
+
version: "1.0.0",
|
|
827
|
+
// `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
|
|
828
|
+
// the HITL veto never fires (the run would proceed WITHOUT waiting for human approval).
|
|
829
|
+
kind: "general",
|
|
830
|
+
register(ctx) {
|
|
831
|
+
ctx.on("pre_tool_call", async (c) => {
|
|
832
|
+
const opts = wiring.gated.get(c.name);
|
|
833
|
+
if (!opts) return void 0;
|
|
834
|
+
const approvalId = crypto.randomUUID();
|
|
835
|
+
wiring.emit({
|
|
836
|
+
type: "approval_required",
|
|
837
|
+
callId: approvalId,
|
|
838
|
+
toolName: c.name,
|
|
839
|
+
question: opts.question,
|
|
840
|
+
input: c.args,
|
|
841
|
+
callbackUrl: `approve/${approvalId}`,
|
|
842
|
+
timeoutMs: opts.timeout ?? 3e5,
|
|
843
|
+
// M20 — carry the declared custom-payload schema so the UI knows what to collect.
|
|
844
|
+
...opts.payloadSchema !== void 0 ? {
|
|
845
|
+
payloadSchema: opts.payloadSchema
|
|
846
|
+
} : {}
|
|
847
|
+
});
|
|
848
|
+
const raw = await wiring.awaitApproval(approvalId, opts, c.name);
|
|
849
|
+
const decision = typeof raw === "boolean" ? {
|
|
850
|
+
approved: raw
|
|
851
|
+
} : raw;
|
|
852
|
+
if (decision.approved) return void 0;
|
|
853
|
+
let message = `Tool '${c.name}' denied by human approver`;
|
|
854
|
+
if (decision.reason) message += `: ${decision.reason}`;
|
|
855
|
+
if (decision.payload !== void 0) {
|
|
856
|
+
message += ` (payload: ${JSON.stringify(decision.payload)})`;
|
|
857
|
+
}
|
|
858
|
+
return {
|
|
859
|
+
block: true,
|
|
860
|
+
message
|
|
861
|
+
};
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
__name(createHitlPlugin, "createHitlPlugin");
|
|
867
|
+
|
|
868
|
+
// src/bridge/approval-posture.ts
|
|
869
|
+
function razaoDe(postura) {
|
|
870
|
+
return postura.kind === "interactive" ? "human approver on this surface" : postura.reason;
|
|
871
|
+
}
|
|
872
|
+
__name(razaoDe, "razaoDe");
|
|
873
|
+
function aplicarPostura(extra, m8, postura, gated) {
|
|
874
|
+
const daPostura = pluginsDaPostura(postura, gated);
|
|
875
|
+
if (daPostura.length === 0) return;
|
|
876
|
+
const atuais = extra.plugins ?? m8.plugins;
|
|
877
|
+
if (atuais !== void 0 && !Array.isArray(atuais)) {
|
|
878
|
+
throw new Error(`[@theokit/agents] approval posture "${postura.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.`);
|
|
879
|
+
}
|
|
880
|
+
extra.plugins = [
|
|
881
|
+
...atuais ?? [],
|
|
882
|
+
...daPostura
|
|
883
|
+
];
|
|
884
|
+
}
|
|
885
|
+
__name(aplicarPostura, "aplicarPostura");
|
|
886
|
+
function pluginsDaPostura(postura, gated) {
|
|
887
|
+
debugLog("[theokit] approval posture", {
|
|
888
|
+
kind: postura.kind,
|
|
889
|
+
reason: razaoDe(postura)
|
|
890
|
+
});
|
|
891
|
+
if (gated === void 0 || gated.size === 0) return [];
|
|
892
|
+
switch (postura.kind) {
|
|
893
|
+
case "interactive":
|
|
894
|
+
return [
|
|
895
|
+
createHitlPlugin({
|
|
896
|
+
gated,
|
|
897
|
+
emit: postura.emit,
|
|
898
|
+
awaitApproval: postura.awaitApproval
|
|
899
|
+
})
|
|
900
|
+
];
|
|
901
|
+
case "auto-approve":
|
|
902
|
+
return [
|
|
903
|
+
createToolHooksPlugin({
|
|
904
|
+
beforeToolCall: /* @__PURE__ */ __name((ctx) => {
|
|
905
|
+
if (gated.has(ctx.name)) {
|
|
906
|
+
debugLog("[theokit] gated tool auto-approved", {
|
|
907
|
+
tool: ctx.name,
|
|
908
|
+
reason: postura.reason
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
return void 0;
|
|
912
|
+
}, "beforeToolCall")
|
|
913
|
+
})
|
|
914
|
+
];
|
|
915
|
+
case "auto-reject":
|
|
916
|
+
return [
|
|
917
|
+
createToolHooksPlugin({
|
|
918
|
+
// Só as tools GATEADAS são recusadas: a postura descreve o gate, não um bloqueio universal.
|
|
919
|
+
// Recusar tudo quebraria todo agente que tem uma tool livre ao lado de uma gateada.
|
|
920
|
+
beforeToolCall: /* @__PURE__ */ __name((ctx) => gated.has(ctx.name) ? {
|
|
921
|
+
block: true,
|
|
922
|
+
message: `Tool '${ctx.name}' requires human approval, and this surface has no approver (approval posture: auto-reject \u2014 ${postura.reason}). Refused (fail-closed).`
|
|
923
|
+
} : void 0, "beforeToolCall")
|
|
924
|
+
})
|
|
925
|
+
];
|
|
926
|
+
case "owned-by-surface":
|
|
927
|
+
return [];
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
__name(pluginsDaPostura, "pluginsDaPostura");
|
|
931
|
+
|
|
769
932
|
// src/bridge/definicao-ou-thunk.ts
|
|
770
933
|
function projetar(def, overrides) {
|
|
771
934
|
const compiled = compileAgentDefinition(def);
|
|
@@ -1342,6 +1505,7 @@ function toAgentFactory(def, opts) {
|
|
|
1342
1505
|
baseDir: overrides.baseDir
|
|
1343
1506
|
};
|
|
1344
1507
|
const extra = buildExtraCreateOptions(overrides, compiled);
|
|
1508
|
+
aplicarPostura(extra, m8, opts.approvals, compiled.hitl);
|
|
1345
1509
|
const agent = await rt.Agent.getOrCreate(sessionId, {
|
|
1346
1510
|
apiKey: await resolverApiKey(opts.apiKey),
|
|
1347
1511
|
model: buildModelSelection(model, reasoningEffort),
|
|
@@ -2098,52 +2262,6 @@ var AgentBuilder = {
|
|
|
2098
2262
|
}
|
|
2099
2263
|
};
|
|
2100
2264
|
|
|
2101
|
-
// src/bridge/hitl-plugin.ts
|
|
2102
|
-
function createHitlPlugin(wiring) {
|
|
2103
|
-
return {
|
|
2104
|
-
name: "theokit-hitl",
|
|
2105
|
-
version: "1.0.0",
|
|
2106
|
-
// `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
|
|
2107
|
-
// the HITL veto never fires (the run would proceed WITHOUT waiting for human approval).
|
|
2108
|
-
kind: "general",
|
|
2109
|
-
register(ctx) {
|
|
2110
|
-
ctx.on("pre_tool_call", async (c) => {
|
|
2111
|
-
const opts = wiring.gated.get(c.name);
|
|
2112
|
-
if (!opts) return void 0;
|
|
2113
|
-
const approvalId = crypto.randomUUID();
|
|
2114
|
-
wiring.emit({
|
|
2115
|
-
type: "approval_required",
|
|
2116
|
-
callId: approvalId,
|
|
2117
|
-
toolName: c.name,
|
|
2118
|
-
question: opts.question,
|
|
2119
|
-
input: c.args,
|
|
2120
|
-
callbackUrl: `approve/${approvalId}`,
|
|
2121
|
-
timeoutMs: opts.timeout ?? 3e5,
|
|
2122
|
-
// M20 — carry the declared custom-payload schema so the UI knows what to collect.
|
|
2123
|
-
...opts.payloadSchema !== void 0 ? {
|
|
2124
|
-
payloadSchema: opts.payloadSchema
|
|
2125
|
-
} : {}
|
|
2126
|
-
});
|
|
2127
|
-
const raw = await wiring.awaitApproval(approvalId, opts, c.name);
|
|
2128
|
-
const decision = typeof raw === "boolean" ? {
|
|
2129
|
-
approved: raw
|
|
2130
|
-
} : raw;
|
|
2131
|
-
if (decision.approved) return void 0;
|
|
2132
|
-
let message = `Tool '${c.name}' denied by human approver`;
|
|
2133
|
-
if (decision.reason) message += `: ${decision.reason}`;
|
|
2134
|
-
if (decision.payload !== void 0) {
|
|
2135
|
-
message += ` (payload: ${JSON.stringify(decision.payload)})`;
|
|
2136
|
-
}
|
|
2137
|
-
return {
|
|
2138
|
-
block: true,
|
|
2139
|
-
message
|
|
2140
|
-
};
|
|
2141
|
-
});
|
|
2142
|
-
}
|
|
2143
|
-
};
|
|
2144
|
-
}
|
|
2145
|
-
__name(createHitlPlugin, "createHitlPlugin");
|
|
2146
|
-
|
|
2147
2265
|
// src/bridge/agent-endpoint.ts
|
|
2148
2266
|
var AgentDefinitionError = class extends Error {
|
|
2149
2267
|
static {
|
|
@@ -3140,59 +3258,6 @@ async function delegate(spec, message, opts = {}) {
|
|
|
3140
3258
|
}
|
|
3141
3259
|
__name(delegate, "delegate");
|
|
3142
3260
|
|
|
3143
|
-
// src/bridge/tool-hooks-plugin.ts
|
|
3144
|
-
function createToolHooksPlugin(hooks) {
|
|
3145
|
-
return {
|
|
3146
|
-
name: "theokit-tool-hooks",
|
|
3147
|
-
version: "1.0.0",
|
|
3148
|
-
// `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
|
|
3149
|
-
// no hook fires (M10/M19 latent bug, proven via a real OpenRouter run).
|
|
3150
|
-
kind: "general",
|
|
3151
|
-
register(ctx) {
|
|
3152
|
-
const { beforeToolCall, afterToolCall, beforeLLMCall, afterLLMCall, processInput } = hooks;
|
|
3153
|
-
if (beforeToolCall) {
|
|
3154
|
-
ctx.on("pre_tool_call", (c) => beforeToolCall({
|
|
3155
|
-
name: c.name ?? "",
|
|
3156
|
-
args: c.args ?? {}
|
|
3157
|
-
}));
|
|
3158
|
-
}
|
|
3159
|
-
if (afterToolCall) {
|
|
3160
|
-
ctx.on("post_tool_call", (c) => afterToolCall({
|
|
3161
|
-
name: c.name ?? "",
|
|
3162
|
-
result: c.result
|
|
3163
|
-
}));
|
|
3164
|
-
}
|
|
3165
|
-
if (beforeLLMCall) {
|
|
3166
|
-
ctx.on("pre_llm_call", (c) => beforeLLMCall({
|
|
3167
|
-
agentId: c.agentId,
|
|
3168
|
-
runId: c.runId,
|
|
3169
|
-
iteration: c.iteration
|
|
3170
|
-
}));
|
|
3171
|
-
}
|
|
3172
|
-
if (afterLLMCall) {
|
|
3173
|
-
ctx.on("post_llm_call", (c) => afterLLMCall({
|
|
3174
|
-
agentId: c.agentId,
|
|
3175
|
-
runId: c.runId,
|
|
3176
|
-
iteration: c.iteration
|
|
3177
|
-
}));
|
|
3178
|
-
}
|
|
3179
|
-
if (processInput) {
|
|
3180
|
-
ctx.on("pre_user_send", async (c) => {
|
|
3181
|
-
const injected = await processInput({
|
|
3182
|
-
prompt: c.prompt ?? "",
|
|
3183
|
-
agentId: c.agentId,
|
|
3184
|
-
runId: c.runId
|
|
3185
|
-
});
|
|
3186
|
-
return injected !== void 0 && injected.length > 0 ? {
|
|
3187
|
-
recalledContext: injected
|
|
3188
|
-
} : void 0;
|
|
3189
|
-
});
|
|
3190
|
-
}
|
|
3191
|
-
}
|
|
3192
|
-
};
|
|
3193
|
-
}
|
|
3194
|
-
__name(createToolHooksPlugin, "createToolHooksPlugin");
|
|
3195
|
-
|
|
3196
3261
|
// src/bridge/api-error-handler.ts
|
|
3197
3262
|
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
3198
3263
|
async function runWithApiErrorHandling(thunk, policy) {
|
|
@@ -3497,6 +3562,7 @@ export {
|
|
|
3497
3562
|
isError,
|
|
3498
3563
|
isApprovalRequired,
|
|
3499
3564
|
generateAgentRoutes,
|
|
3565
|
+
createToolHooksPlugin,
|
|
3500
3566
|
translateSdkEvent,
|
|
3501
3567
|
buildModelSelection,
|
|
3502
3568
|
createThinkTagExtractor,
|
|
@@ -3538,7 +3604,6 @@ export {
|
|
|
3538
3604
|
GoalRunner,
|
|
3539
3605
|
JudgeCredentialError,
|
|
3540
3606
|
delegate,
|
|
3541
|
-
createToolHooksPlugin,
|
|
3542
3607
|
runWithApiErrorHandling,
|
|
3543
3608
|
createApiErrorHandler,
|
|
3544
3609
|
delegateBackground,
|
|
@@ -3549,4 +3614,4 @@ export {
|
|
|
3549
3614
|
generateAgentManifest,
|
|
3550
3615
|
agentsPlugin
|
|
3551
3616
|
};
|
|
3552
|
-
//# sourceMappingURL=chunk-
|
|
3617
|
+
//# sourceMappingURL=chunk-JXR45RAW.js.map
|