@theokit/sdk 2.15.0 → 2.15.1
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 +6 -0
- package/dist/a2a/index.cjs +30 -7
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +30 -7
- package/dist/a2a/index.js.map +1 -1
- package/dist/cron.cjs +30 -7
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.js +30 -7
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +30 -7
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +30 -7
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +30 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +30 -7
- package/dist/index.js.map +1 -1
- package/dist/internal/llm/hermes-tool-extract.d.ts +5 -1
- package/dist/internal/llm/openai.d.ts +5 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -13650,11 +13650,16 @@ function sanitizeToolInput(input, options) {
|
|
|
13650
13650
|
// src/internal/llm/hermes-tool-extract.ts
|
|
13651
13651
|
var HERMES_BLOCK = /<function=\s*([^>\s]+)\s*>([\s\S]*?)<\/tool_call>/g;
|
|
13652
13652
|
var HERMES_PARAM = /<parameter=\s*([^>\s]+)\s*>([\s\S]*?)<\/parameter>/g;
|
|
13653
|
-
function extractHermesToolCalls(content, makeId) {
|
|
13653
|
+
function extractHermesToolCalls(content, makeId, allowedToolNames) {
|
|
13654
|
+
const isPromoted = (name) => name.length > 0 && (allowedToolNames === void 0 || allowedToolNames.has(name));
|
|
13654
13655
|
const toolCalls = [];
|
|
13656
|
+
const droppedNames = [];
|
|
13655
13657
|
for (const block of content.matchAll(HERMES_BLOCK)) {
|
|
13656
13658
|
const name = (block[1] ?? "").trim();
|
|
13657
|
-
if (name
|
|
13659
|
+
if (!isPromoted(name)) {
|
|
13660
|
+
if (name.length > 0 && allowedToolNames !== void 0) droppedNames.push(name);
|
|
13661
|
+
continue;
|
|
13662
|
+
}
|
|
13658
13663
|
toolCalls.push({
|
|
13659
13664
|
type: "tool_use",
|
|
13660
13665
|
id: makeId(),
|
|
@@ -13662,8 +13667,11 @@ function extractHermesToolCalls(content, makeId) {
|
|
|
13662
13667
|
input: parseHermesParams(block[2] ?? "")
|
|
13663
13668
|
});
|
|
13664
13669
|
}
|
|
13665
|
-
const residualText = toolCalls.length === 0 ? content : content.replace(
|
|
13666
|
-
|
|
13670
|
+
const residualText = toolCalls.length === 0 ? content : content.replace(
|
|
13671
|
+
HERMES_BLOCK,
|
|
13672
|
+
(full, rawName) => isPromoted((rawName ?? "").trim()) ? "" : full
|
|
13673
|
+
).trim();
|
|
13674
|
+
return { toolCalls, residualText, droppedNames };
|
|
13667
13675
|
}
|
|
13668
13676
|
function parseHermesParams(inner) {
|
|
13669
13677
|
const input = {};
|
|
@@ -13747,7 +13755,10 @@ var OpenAIClient = class {
|
|
|
13747
13755
|
}
|
|
13748
13756
|
const accumulator = new OpenAIStreamAccumulator(
|
|
13749
13757
|
this.options.extractToolCallsFromContent ?? false,
|
|
13750
|
-
providerId
|
|
13758
|
+
providerId,
|
|
13759
|
+
// R5: request-scoped allowlist — leaked recovery only promotes a block whose name is a tool the
|
|
13760
|
+
// model was actually given. Empty set (no tools) recovers nothing.
|
|
13761
|
+
new Set(request.tools?.map((tool) => tool.name) ?? [])
|
|
13751
13762
|
);
|
|
13752
13763
|
for await (const record of parseSseStream(response.body, signal)) {
|
|
13753
13764
|
if (record.data === "[DONE]") break;
|
|
@@ -13777,13 +13788,18 @@ var OpenAIStreamAccumulator = class {
|
|
|
13777
13788
|
/**
|
|
13778
13789
|
* @param extractFromContent opt-in leaked-dialect safe-parse (theokit#58). Default false.
|
|
13779
13790
|
* @param providerName provider id, used only to label the recovery log line.
|
|
13791
|
+
* @param allowedToolNames R5 request-scoped allowlist — built from `request.tools` at `stream()`;
|
|
13792
|
+
* leaked recovery in `finish()` only promotes a block whose name is in this set. `undefined`
|
|
13793
|
+
* (direct construction) recovers all (back-compat); an empty set recovers nothing.
|
|
13780
13794
|
*/
|
|
13781
|
-
constructor(extractFromContent = false, providerName = "openai") {
|
|
13795
|
+
constructor(extractFromContent = false, providerName = "openai", allowedToolNames) {
|
|
13782
13796
|
this.extractFromContent = extractFromContent;
|
|
13783
13797
|
this.providerName = providerName;
|
|
13798
|
+
this.allowedToolNames = allowedToolNames;
|
|
13784
13799
|
}
|
|
13785
13800
|
extractFromContent;
|
|
13786
13801
|
providerName;
|
|
13802
|
+
allowedToolNames;
|
|
13787
13803
|
text = "";
|
|
13788
13804
|
stopReason = "end_turn";
|
|
13789
13805
|
inputTokens;
|
|
@@ -13854,7 +13870,8 @@ var OpenAIStreamAccumulator = class {
|
|
|
13854
13870
|
if (this.extractFromContent && toolCalls.length === 0) {
|
|
13855
13871
|
const recovered = extractHermesToolCalls(
|
|
13856
13872
|
this.text,
|
|
13857
|
-
() => `hermes-${globalThis.crypto.randomUUID()}
|
|
13873
|
+
() => `hermes-${globalThis.crypto.randomUUID()}`,
|
|
13874
|
+
this.allowedToolNames
|
|
13858
13875
|
);
|
|
13859
13876
|
if (recovered.toolCalls.length > 0) {
|
|
13860
13877
|
toolCalls.push(...recovered.toolCalls);
|
|
@@ -13862,6 +13879,12 @@ var OpenAIStreamAccumulator = class {
|
|
|
13862
13879
|
stopReason = "tool_use";
|
|
13863
13880
|
process.stderr.write(
|
|
13864
13881
|
`[theokit-sdk] recovered ${recovered.toolCalls.length} leaked tool call(s) from assistant content (provider="${this.providerName}", names=${recovered.toolCalls.map((c) => c.name).join(",")})
|
|
13882
|
+
`
|
|
13883
|
+
);
|
|
13884
|
+
}
|
|
13885
|
+
if (recovered.droppedNames.length > 0) {
|
|
13886
|
+
process.stderr.write(
|
|
13887
|
+
`[theokit-sdk] dropped ${recovered.droppedNames.length} leaked block(s) whose name is not a tool in the request (provider="${this.providerName}", names=${recovered.droppedNames.join(",")})
|
|
13865
13888
|
`
|
|
13866
13889
|
);
|
|
13867
13890
|
}
|