@theokit/sdk 2.15.1 → 2.15.2
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 +106 -10
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +106 -10
- package/dist/a2a/index.js.map +1 -1
- package/dist/cron.cjs +105 -9
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.js +105 -9
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +105 -9
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +105 -9
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +105 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +105 -9
- package/dist/index.js.map +1 -1
- package/dist/internal/llm/openai.d.ts +9 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13680,6 +13680,77 @@ function parseHermesParams(inner) {
|
|
|
13680
13680
|
}
|
|
13681
13681
|
return sanitizeToolInput(input, { trim: true }).value;
|
|
13682
13682
|
}
|
|
13683
|
+
var STREAM_MARKER = "<function=";
|
|
13684
|
+
var DEFAULT_STREAM_BUFFER_CAP = 8192;
|
|
13685
|
+
var isStreamWs = (c) => c === " " || c === " " || c === "\n" || c === "\r";
|
|
13686
|
+
function streamToolCallBufferState(held, allowedToolNames, cap2 = DEFAULT_STREAM_BUFFER_CAP) {
|
|
13687
|
+
if (allowedToolNames.size === 0) return "impossible";
|
|
13688
|
+
const t = held.trimStart();
|
|
13689
|
+
if (t.length < STREAM_MARKER.length) {
|
|
13690
|
+
return STREAM_MARKER.startsWith(t) ? "possible" : "impossible";
|
|
13691
|
+
}
|
|
13692
|
+
if (!t.startsWith(STREAM_MARKER)) return "impossible";
|
|
13693
|
+
const parsed = parseStreamMarkerName(t);
|
|
13694
|
+
if (parsed === "building") return "possible";
|
|
13695
|
+
if (parsed === "invalid") return "impossible";
|
|
13696
|
+
const nameOk = parsed.complete ? allowedToolNames.has(parsed.name) : someToolNameStartsWith(allowedToolNames, parsed.name);
|
|
13697
|
+
if (!nameOk) return "impossible";
|
|
13698
|
+
return held.length > cap2 ? "impossible" : "possible";
|
|
13699
|
+
}
|
|
13700
|
+
function parseStreamMarkerName(t) {
|
|
13701
|
+
let cursor = STREAM_MARKER.length;
|
|
13702
|
+
while (cursor < t.length && isStreamWs(t[cursor])) cursor += 1;
|
|
13703
|
+
const nameStart = cursor;
|
|
13704
|
+
while (cursor < t.length && t[cursor] !== ">" && !isStreamWs(t[cursor])) cursor += 1;
|
|
13705
|
+
const name = t.slice(nameStart, cursor);
|
|
13706
|
+
if (name.length === 0) return cursor >= t.length ? "building" : "invalid";
|
|
13707
|
+
return { name, complete: cursor < t.length && t[cursor] === ">" };
|
|
13708
|
+
}
|
|
13709
|
+
function someToolNameStartsWith(allowedToolNames, prefix) {
|
|
13710
|
+
for (const name of allowedToolNames) {
|
|
13711
|
+
if (name.startsWith(prefix)) return true;
|
|
13712
|
+
}
|
|
13713
|
+
return false;
|
|
13714
|
+
}
|
|
13715
|
+
function firstPossibleMarkerStart(held, allowedToolNames) {
|
|
13716
|
+
for (let i = held.indexOf("<"); i !== -1; i = held.indexOf("<", i + 1)) {
|
|
13717
|
+
if (streamToolCallBufferState(held.slice(i), allowedToolNames) === "possible") return i;
|
|
13718
|
+
}
|
|
13719
|
+
return -1;
|
|
13720
|
+
}
|
|
13721
|
+
var StreamSuppressionBuffer = class {
|
|
13722
|
+
constructor(allowedToolNames) {
|
|
13723
|
+
this.allowedToolNames = allowedToolNames;
|
|
13724
|
+
}
|
|
13725
|
+
allowedToolNames;
|
|
13726
|
+
#held = "";
|
|
13727
|
+
/** Feed a content delta; returns the text to emit as a `text_delta` now, or `undefined` to hold. */
|
|
13728
|
+
push(content) {
|
|
13729
|
+
this.#held += content;
|
|
13730
|
+
if (streamToolCallBufferState(this.#held, this.allowedToolNames) === "possible")
|
|
13731
|
+
return void 0;
|
|
13732
|
+
const holdStart = firstPossibleMarkerStart(this.#held, this.allowedToolNames);
|
|
13733
|
+
if (holdStart > 0) {
|
|
13734
|
+
const flush2 = this.#held.slice(0, holdStart);
|
|
13735
|
+
this.#held = this.#held.slice(holdStart);
|
|
13736
|
+
return flush2;
|
|
13737
|
+
}
|
|
13738
|
+
const flush = this.#held;
|
|
13739
|
+
this.#held = "";
|
|
13740
|
+
return flush;
|
|
13741
|
+
}
|
|
13742
|
+
/** Drain the held buffer at stream end. `hasNativeCalls` mirrors `finish()`'s size-guard: when
|
|
13743
|
+
* native `tool_calls` exist, `finish()` won't strip the leaked block, so stream the held text WHOLE
|
|
13744
|
+
* (keeping `accumulatedText == finish.text`); otherwise strip the recoverable blocks. Idempotent. */
|
|
13745
|
+
drain(hasNativeCalls) {
|
|
13746
|
+
if (this.#held.length === 0) return void 0;
|
|
13747
|
+
const held = this.#held;
|
|
13748
|
+
this.#held = "";
|
|
13749
|
+
if (hasNativeCalls) return held;
|
|
13750
|
+
const residual = extractHermesToolCalls(held, () => "held", this.allowedToolNames).residualText;
|
|
13751
|
+
return residual.length > 0 ? residual : void 0;
|
|
13752
|
+
}
|
|
13753
|
+
};
|
|
13683
13754
|
|
|
13684
13755
|
// src/internal/llm/openai.ts
|
|
13685
13756
|
var OpenAIClient = class {
|
|
@@ -13778,6 +13849,8 @@ var OpenAIClient = class {
|
|
|
13778
13849
|
const events = accumulator.consume(chunk);
|
|
13779
13850
|
for (const event of events) yield event;
|
|
13780
13851
|
}
|
|
13852
|
+
const drainEvent = accumulator.finalizeHeldText();
|
|
13853
|
+
if (drainEvent !== void 0) yield drainEvent;
|
|
13781
13854
|
return accumulator.finish();
|
|
13782
13855
|
}
|
|
13783
13856
|
};
|
|
@@ -13793,6 +13866,7 @@ var OpenAIStreamAccumulator = class {
|
|
|
13793
13866
|
this.extractFromContent = extractFromContent;
|
|
13794
13867
|
this.providerName = providerName;
|
|
13795
13868
|
this.allowedToolNames = allowedToolNames;
|
|
13869
|
+
this.suppress = extractFromContent && allowedToolNames !== void 0 && allowedToolNames.size > 0 ? new StreamSuppressionBuffer(allowedToolNames) : void 0;
|
|
13796
13870
|
}
|
|
13797
13871
|
extractFromContent;
|
|
13798
13872
|
providerName;
|
|
@@ -13805,18 +13879,30 @@ var OpenAIStreamAccumulator = class {
|
|
|
13805
13879
|
cacheWriteTokens;
|
|
13806
13880
|
reasoningTokens;
|
|
13807
13881
|
toolCalls = /* @__PURE__ */ new Map();
|
|
13882
|
+
/** R7: present only when recovery is enabled AND the request declares tools — holds suspected
|
|
13883
|
+
* leaked-dialect content back from the `text_delta` stream. `undefined` ⇒ stream immediately. */
|
|
13884
|
+
suppress;
|
|
13808
13885
|
consume(chunk) {
|
|
13809
13886
|
const events = [];
|
|
13810
13887
|
this.applyUsage(chunk.usage);
|
|
13811
13888
|
for (const choice of chunk.choices ?? []) {
|
|
13812
|
-
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
13816
|
-
|
|
13817
|
-
|
|
13818
|
-
|
|
13819
|
-
|
|
13889
|
+
events.push(...this.applyChoice(choice));
|
|
13890
|
+
}
|
|
13891
|
+
return events;
|
|
13892
|
+
}
|
|
13893
|
+
applyChoice(choice) {
|
|
13894
|
+
const events = [];
|
|
13895
|
+
const reasoningEvent = this.applyReasoningDelta(
|
|
13896
|
+
choice.delta?.reasoning ?? choice.delta?.reasoning_content
|
|
13897
|
+
);
|
|
13898
|
+
if (reasoningEvent !== void 0) events.push(reasoningEvent);
|
|
13899
|
+
const textEvent = this.applyContentDelta(choice.delta?.content);
|
|
13900
|
+
if (textEvent !== void 0) events.push(textEvent);
|
|
13901
|
+
this.mergeToolCallDeltas(choice.delta?.tool_calls);
|
|
13902
|
+
this.applyFinishReason(choice.finish_reason);
|
|
13903
|
+
if (choice.finish_reason !== void 0 && choice.finish_reason !== null) {
|
|
13904
|
+
const flushEvent = this.finalizeHeldText();
|
|
13905
|
+
if (flushEvent !== void 0) events.push(flushEvent);
|
|
13820
13906
|
}
|
|
13821
13907
|
return events;
|
|
13822
13908
|
}
|
|
@@ -13841,7 +13927,17 @@ var OpenAIStreamAccumulator = class {
|
|
|
13841
13927
|
applyContentDelta(content) {
|
|
13842
13928
|
if (typeof content !== "string" || content.length === 0) return void 0;
|
|
13843
13929
|
this.text += content;
|
|
13844
|
-
return { type: "text_delta", text: content };
|
|
13930
|
+
if (this.suppress === void 0) return { type: "text_delta", text: content };
|
|
13931
|
+
const emit2 = this.suppress.push(content);
|
|
13932
|
+
return emit2 !== void 0 ? { type: "text_delta", text: emit2 } : void 0;
|
|
13933
|
+
}
|
|
13934
|
+
/** R7 held-buffer finalizer, called at the `finish_reason` chunk (in `applyChoice`) AND after the
|
|
13935
|
+
* SSE loop in `stream()` — so a stream that omits a `finish_reason` terminal never silently drops
|
|
13936
|
+
* held text. `toolCalls.size > 0` (native calls present) makes `finish()` skip recovery, so the
|
|
13937
|
+
* buffer streams the held text whole. Idempotent once drained. */
|
|
13938
|
+
finalizeHeldText() {
|
|
13939
|
+
const emit2 = this.suppress?.drain(this.toolCalls.size > 0);
|
|
13940
|
+
return emit2 !== void 0 ? { type: "text_delta", text: emit2 } : void 0;
|
|
13845
13941
|
}
|
|
13846
13942
|
mergeToolCallDeltas(deltas) {
|
|
13847
13943
|
for (const call of deltas ?? []) {
|