@theokit/agents 4.30.1 → 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-LWF36KFK.js → chunk-JXR45RAW.js} +180 -113
- 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-LWF36KFK.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);
|
|
@@ -786,6 +949,20 @@ function resolverProjecao(def, overrides) {
|
|
|
786
949
|
}
|
|
787
950
|
__name(resolverProjecao, "resolverProjecao");
|
|
788
951
|
|
|
952
|
+
// src/bridge/erro-do-sdk.ts
|
|
953
|
+
function eventoDeErroDoSdk(err) {
|
|
954
|
+
const sdkErr = err;
|
|
955
|
+
return {
|
|
956
|
+
type: "error",
|
|
957
|
+
code: sdkErr.code ?? "SDK_ERROR",
|
|
958
|
+
message: err instanceof Error ? err.message : "SDK agent error",
|
|
959
|
+
// O SDK computa `isRetryable` por classe de erro na construção; fixá-lo em `false` aqui
|
|
960
|
+
// contradizia o próprio erro.
|
|
961
|
+
retryable: sdkErr.isRetryable === true
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
__name(eventoDeErroDoSdk, "eventoDeErroDoSdk");
|
|
965
|
+
|
|
789
966
|
// src/bridge/sdk-adapter-create-options.ts
|
|
790
967
|
function assembleM8CreateOptions(compiled) {
|
|
791
968
|
const options = {};
|
|
@@ -1189,18 +1366,6 @@ function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext
|
|
|
1189
1366
|
}
|
|
1190
1367
|
__name(buildSdkTools, "buildSdkTools");
|
|
1191
1368
|
var resolverApiKey = /* @__PURE__ */ __name(async (k) => typeof k === "function" ? await k() : k, "resolverApiKey");
|
|
1192
|
-
function eventoDeErroDoSdk(err) {
|
|
1193
|
-
const sdkErr = err;
|
|
1194
|
-
return {
|
|
1195
|
-
type: "error",
|
|
1196
|
-
code: sdkErr.code ?? "SDK_ERROR",
|
|
1197
|
-
message: err instanceof Error ? err.message : "SDK agent error",
|
|
1198
|
-
// O SDK computa `isRetryable` por classe de erro na construção; fixá-lo em `false` aqui
|
|
1199
|
-
// contradizia o próprio erro.
|
|
1200
|
-
retryable: sdkErr.isRetryable === true
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
__name(eventoDeErroDoSdk, "eventoDeErroDoSdk");
|
|
1204
1369
|
function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
1205
1370
|
const model = overrides.model ?? compiled.model ?? "openai/gpt-4o-mini";
|
|
1206
1371
|
const reasoningEffort = overrides.reasoningEffort ?? compiled.reasoningEffort;
|
|
@@ -1340,6 +1505,7 @@ function toAgentFactory(def, opts) {
|
|
|
1340
1505
|
baseDir: overrides.baseDir
|
|
1341
1506
|
};
|
|
1342
1507
|
const extra = buildExtraCreateOptions(overrides, compiled);
|
|
1508
|
+
aplicarPostura(extra, m8, opts.approvals, compiled.hitl);
|
|
1343
1509
|
const agent = await rt.Agent.getOrCreate(sessionId, {
|
|
1344
1510
|
apiKey: await resolverApiKey(opts.apiKey),
|
|
1345
1511
|
model: buildModelSelection(model, reasoningEffort),
|
|
@@ -2096,52 +2262,6 @@ var AgentBuilder = {
|
|
|
2096
2262
|
}
|
|
2097
2263
|
};
|
|
2098
2264
|
|
|
2099
|
-
// src/bridge/hitl-plugin.ts
|
|
2100
|
-
function createHitlPlugin(wiring) {
|
|
2101
|
-
return {
|
|
2102
|
-
name: "theokit-hitl",
|
|
2103
|
-
version: "1.0.0",
|
|
2104
|
-
// `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
|
|
2105
|
-
// the HITL veto never fires (the run would proceed WITHOUT waiting for human approval).
|
|
2106
|
-
kind: "general",
|
|
2107
|
-
register(ctx) {
|
|
2108
|
-
ctx.on("pre_tool_call", async (c) => {
|
|
2109
|
-
const opts = wiring.gated.get(c.name);
|
|
2110
|
-
if (!opts) return void 0;
|
|
2111
|
-
const approvalId = crypto.randomUUID();
|
|
2112
|
-
wiring.emit({
|
|
2113
|
-
type: "approval_required",
|
|
2114
|
-
callId: approvalId,
|
|
2115
|
-
toolName: c.name,
|
|
2116
|
-
question: opts.question,
|
|
2117
|
-
input: c.args,
|
|
2118
|
-
callbackUrl: `approve/${approvalId}`,
|
|
2119
|
-
timeoutMs: opts.timeout ?? 3e5,
|
|
2120
|
-
// M20 — carry the declared custom-payload schema so the UI knows what to collect.
|
|
2121
|
-
...opts.payloadSchema !== void 0 ? {
|
|
2122
|
-
payloadSchema: opts.payloadSchema
|
|
2123
|
-
} : {}
|
|
2124
|
-
});
|
|
2125
|
-
const raw = await wiring.awaitApproval(approvalId, opts, c.name);
|
|
2126
|
-
const decision = typeof raw === "boolean" ? {
|
|
2127
|
-
approved: raw
|
|
2128
|
-
} : raw;
|
|
2129
|
-
if (decision.approved) return void 0;
|
|
2130
|
-
let message = `Tool '${c.name}' denied by human approver`;
|
|
2131
|
-
if (decision.reason) message += `: ${decision.reason}`;
|
|
2132
|
-
if (decision.payload !== void 0) {
|
|
2133
|
-
message += ` (payload: ${JSON.stringify(decision.payload)})`;
|
|
2134
|
-
}
|
|
2135
|
-
return {
|
|
2136
|
-
block: true,
|
|
2137
|
-
message
|
|
2138
|
-
};
|
|
2139
|
-
});
|
|
2140
|
-
}
|
|
2141
|
-
};
|
|
2142
|
-
}
|
|
2143
|
-
__name(createHitlPlugin, "createHitlPlugin");
|
|
2144
|
-
|
|
2145
2265
|
// src/bridge/agent-endpoint.ts
|
|
2146
2266
|
var AgentDefinitionError = class extends Error {
|
|
2147
2267
|
static {
|
|
@@ -3138,59 +3258,6 @@ async function delegate(spec, message, opts = {}) {
|
|
|
3138
3258
|
}
|
|
3139
3259
|
__name(delegate, "delegate");
|
|
3140
3260
|
|
|
3141
|
-
// src/bridge/tool-hooks-plugin.ts
|
|
3142
|
-
function createToolHooksPlugin(hooks) {
|
|
3143
|
-
return {
|
|
3144
|
-
name: "theokit-tool-hooks",
|
|
3145
|
-
version: "1.0.0",
|
|
3146
|
-
// `kind: 'general'` is load-bearing — without it the SDK's isCodePlugin() drops this plugin and
|
|
3147
|
-
// no hook fires (M10/M19 latent bug, proven via a real OpenRouter run).
|
|
3148
|
-
kind: "general",
|
|
3149
|
-
register(ctx) {
|
|
3150
|
-
const { beforeToolCall, afterToolCall, beforeLLMCall, afterLLMCall, processInput } = hooks;
|
|
3151
|
-
if (beforeToolCall) {
|
|
3152
|
-
ctx.on("pre_tool_call", (c) => beforeToolCall({
|
|
3153
|
-
name: c.name ?? "",
|
|
3154
|
-
args: c.args ?? {}
|
|
3155
|
-
}));
|
|
3156
|
-
}
|
|
3157
|
-
if (afterToolCall) {
|
|
3158
|
-
ctx.on("post_tool_call", (c) => afterToolCall({
|
|
3159
|
-
name: c.name ?? "",
|
|
3160
|
-
result: c.result
|
|
3161
|
-
}));
|
|
3162
|
-
}
|
|
3163
|
-
if (beforeLLMCall) {
|
|
3164
|
-
ctx.on("pre_llm_call", (c) => beforeLLMCall({
|
|
3165
|
-
agentId: c.agentId,
|
|
3166
|
-
runId: c.runId,
|
|
3167
|
-
iteration: c.iteration
|
|
3168
|
-
}));
|
|
3169
|
-
}
|
|
3170
|
-
if (afterLLMCall) {
|
|
3171
|
-
ctx.on("post_llm_call", (c) => afterLLMCall({
|
|
3172
|
-
agentId: c.agentId,
|
|
3173
|
-
runId: c.runId,
|
|
3174
|
-
iteration: c.iteration
|
|
3175
|
-
}));
|
|
3176
|
-
}
|
|
3177
|
-
if (processInput) {
|
|
3178
|
-
ctx.on("pre_user_send", async (c) => {
|
|
3179
|
-
const injected = await processInput({
|
|
3180
|
-
prompt: c.prompt ?? "",
|
|
3181
|
-
agentId: c.agentId,
|
|
3182
|
-
runId: c.runId
|
|
3183
|
-
});
|
|
3184
|
-
return injected !== void 0 && injected.length > 0 ? {
|
|
3185
|
-
recalledContext: injected
|
|
3186
|
-
} : void 0;
|
|
3187
|
-
});
|
|
3188
|
-
}
|
|
3189
|
-
}
|
|
3190
|
-
};
|
|
3191
|
-
}
|
|
3192
|
-
__name(createToolHooksPlugin, "createToolHooksPlugin");
|
|
3193
|
-
|
|
3194
3261
|
// src/bridge/api-error-handler.ts
|
|
3195
3262
|
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
3196
3263
|
async function runWithApiErrorHandling(thunk, policy) {
|
|
@@ -3495,6 +3562,7 @@ export {
|
|
|
3495
3562
|
isError,
|
|
3496
3563
|
isApprovalRequired,
|
|
3497
3564
|
generateAgentRoutes,
|
|
3565
|
+
createToolHooksPlugin,
|
|
3498
3566
|
translateSdkEvent,
|
|
3499
3567
|
buildModelSelection,
|
|
3500
3568
|
createThinkTagExtractor,
|
|
@@ -3536,7 +3604,6 @@ export {
|
|
|
3536
3604
|
GoalRunner,
|
|
3537
3605
|
JudgeCredentialError,
|
|
3538
3606
|
delegate,
|
|
3539
|
-
createToolHooksPlugin,
|
|
3540
3607
|
runWithApiErrorHandling,
|
|
3541
3608
|
createApiErrorHandler,
|
|
3542
3609
|
delegateBackground,
|
|
@@ -3547,4 +3614,4 @@ export {
|
|
|
3547
3614
|
generateAgentManifest,
|
|
3548
3615
|
agentsPlugin
|
|
3549
3616
|
};
|
|
3550
|
-
//# sourceMappingURL=chunk-
|
|
3617
|
+
//# sourceMappingURL=chunk-JXR45RAW.js.map
|