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