@xiaoso/dsh-tool-plus 0.1.6 → 0.1.7-beta.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/THIRD_PARTY_NOTICES.md +9 -3
- package/lib/{abort-Cwwm4Err.mjs → abort-Caqff3M6.mjs} +2 -2
- package/lib/alibaba-coding-plan-DTupMiAi.mjs +73 -0
- package/lib/alibaba-token-plan-CHGyWOfX.mjs +46 -0
- package/lib/alibaba-token-plan-Dj3OZhEE.mjs +82 -0
- package/lib/{amazon-bedrock-TVMpUTRG.mjs → amazon-bedrock-DbFSYXfJ.mjs} +117 -38
- package/lib/{anthropic-BL6LFDQS.mjs → anthropic-CTJ3IQVa.mjs} +675 -166
- package/lib/anthropic-CXfWlp-x.mjs +105 -0
- package/lib/{aws-credentials-B20dliS7.mjs → anthropic-wire-CKuhDwZ1.mjs} +74 -14
- package/lib/{api-key-login-CIDnXeYd.mjs → api-key-validation-CGCJFbFr.mjs} +27 -68
- package/lib/{azure-openai-responses-BkhsLmN3.mjs → azure-openai-responses-ChFbWaGj.mjs} +27 -16
- package/lib/{browser-render-CmgvSNte.mjs → browser-render-9o0Rknop.mjs} +4 -4
- package/lib/bun-shim.mjs +71 -2
- package/lib/{bundled-references-ChZSPDFw.mjs → bundled-references-DY3EJxZV.mjs} +6 -5
- package/lib/cline-pass-Bwg3esu9.mjs +44 -0
- package/lib/cloudflare-ai-gateway-BupNXyKK.mjs +35 -0
- package/lib/cloudflare-ai-gateway-EWo0VkP5.mjs +44 -0
- package/lib/collapse-DOR8sOGf.mjs +2304 -0
- package/lib/coreweave-C82HrLpb.mjs +31 -0
- package/lib/coreweave-Ct8cF-da.mjs +14 -0
- package/lib/{cursor-B6HcmplF.mjs → cursor-B95LzVWV.mjs} +11 -3
- package/lib/{cursor-CRpLpaZ3.mjs → cursor-DJV_dcgB.mjs} +887 -1784
- package/lib/{cursor-B8m6SqAH.mjs → cursor-LKGjucn2.mjs} +48 -38
- package/lib/cursor-proto-B8Wj8bv9.mjs +10513 -0
- package/lib/{deterministic-id-D-yIV_eI.mjs → deterministic-id-CUEIMSqR.mjs} +1 -1
- package/lib/devin-BMTdx_hx.mjs +316 -0
- package/lib/{devin-DUAfvBsW.mjs → devin-DSp0Rw_E.mjs} +172 -86
- package/lib/devin-ExGIghmx.mjs +69 -0
- package/lib/devin-proto-Br8fdyNl.mjs +2888 -0
- package/lib/{dom-CawWi8fa.mjs → dom-DG3sPESc.mjs} +8 -8
- package/lib/effort-BdtQMN-_.mjs +23 -0
- package/lib/{error-C-f_Wnw4.mjs → error-CORgGg5a.mjs} +275 -154
- package/lib/{event-stream-Dh2guZxS.mjs → event-stream-ulcDenZD.mjs} +20 -4
- package/lib/{gemini-headers-DKUShltF.mjs → gemini-headers-Co9cVvex.mjs} +2 -2
- package/lib/{github-copilot-suDymKrx.mjs → github-copilot-Dstq1D3s.mjs} +69 -29
- package/lib/github-copilot-headers-DOh1gt_w.mjs +312 -0
- package/lib/gitlab-duo-DSCMrU0m.mjs +11 -0
- package/lib/google-CtsKkOQK.mjs +38 -0
- package/lib/google-antigravity-z-5KsEci.mjs +252 -0
- package/lib/{google-auth-DYJLM792.mjs → google-auth-ieLBaneO.mjs} +4 -4
- package/lib/{google-gemini-cli-8BT513Ul.mjs → google-gemini-cli-C6NE5mWz.mjs} +28 -54
- package/lib/{google-gemini-cli-D6cSmfvB.mjs → google-gemini-cli-CAIPSl7e.mjs} +23 -29
- package/lib/google-oauth-shared-DhMllAkt.mjs +53 -0
- package/lib/{google-shared-CVbHK5vZ.mjs → google-shared-B0aNCYEH.mjs} +140 -44
- package/lib/{google-validation-Cgbn3tWJ.mjs → google-validation-BEkNs-Bx.mjs} +1 -1
- package/lib/{google-vertex-Bui-ypAe.mjs → google-vertex-Bbd1tYNc.mjs} +8 -8
- package/lib/hosts-00rjRzUD.mjs +203 -0
- package/lib/id-AL5obQzR.mjs +71 -0
- package/lib/{idle-iterator-CYAxUkSD.mjs → idle-iterator-DlUkEfzW.mjs} +3 -3
- package/lib/index.mjs +587 -5266
- package/lib/kilo-ChJL54wq.mjs +81 -0
- package/lib/kimi-C2c_Zq8A.mjs +67 -0
- package/lib/{launch-BmgEUycu.mjs → launch-DKDH71En.mjs} +1 -1
- package/lib/markit-CmRfm4E2.mjs +9885 -0
- package/lib/models-DnXMYGcJ.mjs +381604 -0
- package/lib/muse-code-Di1VZmB1.mjs +143 -0
- package/lib/{ollama-Df9ce-Cp.mjs → ollama-B8ic3sEp.mjs} +15 -30
- package/lib/{openai-codex-CAVI3Me-.mjs → openai-codex-DuJNC99x.mjs} +29 -99
- package/lib/{openai-codex-responses-BcnOotRB.mjs → openai-codex-responses-BL29nh9K.mjs} +204 -116
- package/lib/{openai-completions-Bq4WT47M.mjs → openai-completions-BK2f2dBv.mjs} +152 -82
- package/lib/openai-configuration-update-xMYUjaK_.mjs +150 -0
- package/lib/{openai-reasoning-fallback-DXsfiSXO.mjs → openai-reasoning-fallback-BdB3RCbj.mjs} +106 -12
- package/lib/{openai-responses-Mq_-PjvE.mjs → openai-responses-CGQPlIIy.mjs} +76 -82
- package/lib/{perplexity-XgLF73E7.mjs → perplexity-TBjz3VMB.mjs} +52 -9
- package/lib/{pkce-BlQikGPu.mjs → pkce-BYjmugmw.mjs} +1 -1
- package/lib/protobuf-aab1UGVn.mjs +717 -0
- package/lib/{provider-response-C6vcbQyO.mjs → provider-response-SqKSkkUc.mjs} +1 -1
- package/lib/{proxy-D9lm7ONA.mjs → proxy-5nWqRL1f.mjs} +45 -5
- package/lib/{readability-Cpm-ocau.mjs → readability-uGhqb4GC.mjs} +2 -2
- package/lib/reference-CtvM4zLU.mjs +114 -0
- package/lib/{request-debug-HJMoJncL.mjs → request-debug-NQN0BjHH.mjs} +1 -1
- package/lib/{sanitize-text-CfcXzw5X.mjs → sanitize-text-BCf5KmCf.mjs} +1 -1
- package/lib/{scrapers-Cg5w77td.mjs → scrapers-D8oWspgW.mjs} +12 -12
- package/lib/{src-BcD0_rQR.mjs → src-BwW51vA5.mjs} +979 -388
- package/lib/{sse-debug-CYdjOC96.mjs → sse-debug-B-tkLCPW.mjs} +1 -1
- package/lib/{stream-Bjq8wjfr.mjs → stream-B_7qN-bA.mjs} +3802 -2623
- package/lib/stream-markup-healing-DKT1lnkW.mjs +267 -0
- package/lib/{strict-tool-validation-imVLUcbI.mjs → strict-tool-validation-CBTz1dAA.mjs} +2 -2
- package/lib/taxonomy-DSIM99rS.mjs +15392 -0
- package/lib/{stream-markup-healing-DZ6bVDxH.mjs → thinking-CiLa2LFB.mjs} +31 -186
- package/lib/{turndown-DN7ByzEI.mjs → turndown-DrX1M4WG.mjs} +4 -4
- package/lib/{type-guards-B9VVjRDK.mjs → type-guards-CttAANEx.mjs} +1 -1
- package/lib/{types-DX_bvuus.mjs → types-PVueGi9S.mjs} +2 -2
- package/lib/{utils-C-dSORPa.mjs → utils-CCfhUQen.mjs} +2364 -2676
- package/lib/{utils-Cp2Mxf_U.mjs → utils-CUPhpw9A.mjs} +413 -134
- package/lib/{utils-CQHPEQ3W.mjs → utils-DeWqNWV8.mjs} +2 -2
- package/lib/{vision-guard-mBmtAHx0.mjs → vision-guard-_XwsL1DF.mjs} +14 -29
- package/lib/xai-oauth-CXhnz0gO.mjs +210 -0
- package/lib/{xiaomi-7mE345KX.mjs → xiaomi-psoUItal.mjs} +8 -37
- package/lib/{zai-CeNpMV3W.mjs → zai-ApJ8HBgT.mjs} +8 -71
- package/lib/{zip-BK7UHCwX.mjs → zip-Kd602XNe.mjs} +1 -1
- package/package.json +11 -11
- package/presets/package.json +1 -1
- package/presets/tool-plus-ptc/agent.cordis.yml +1 -1
- package/presets/tool-plus-standard/agent.cordis.yml +1 -1
- package/lib/agent_pb-Rizyt9Zg.mjs +0 -805
- package/lib/anthropic-CDmj476p.mjs +0 -262
- package/lib/api_server_pb-CDZgLMta.mjs +0 -252
- package/lib/callback-server-CFJK-jvK.mjs +0 -398
- package/lib/codex-P1dGpX7G.mjs +0 -54
- package/lib/device-code-CuXTWYwY.mjs +0 -51
- package/lib/devin-BcQwht1W.mjs +0 -114
- package/lib/devin-BvMfGevz.mjs +0 -95
- package/lib/github-copilot-B3kQl0g0.mjs +0 -104
- package/lib/gitlab-duo-BriUTP8k.mjs +0 -155
- package/lib/gitlab-duo-workflow-wK5Ljzmc.mjs +0 -91
- package/lib/google-CE5tFDod.mjs +0 -30
- package/lib/google-antigravity-C1jgNljz.mjs +0 -198
- package/lib/google-oauth-shared-BLVTvokk.mjs +0 -147
- package/lib/grammar-D-NqNUxQ.mjs +0 -49
- package/lib/identity-HNO1Oe9B.mjs +0 -219
- package/lib/kimi-DgcUpPtK.mjs +0 -236
- package/lib/markit-DtGoRE6M.mjs +0 -1417
- package/lib/minimax-code-Y3h5li9N.mjs +0 -53
- package/lib/models-DRA2c_8U.mjs +0 -104660
- package/lib/opencode-BsVw9rCD.mjs +0 -38
- package/lib/to-binary-B1BEBIPC.mjs +0 -6002
- package/lib/wafer-BlhWLweO.mjs +0 -17
- package/lib/xai-oauth-5pORHUrg.mjs +0 -446
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { E as createInbandScanner } from "./utils-CUPhpw9A.mjs";
|
|
4
|
+
import { t as ThinkingInbandScanner } from "./thinking-CiLa2LFB.mjs";
|
|
5
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/dialect/qwen-xml.ts
|
|
6
|
+
const SECTION_OPEN = "<tool_calls>";
|
|
7
|
+
const SECTION_CLOSE = "</tool_calls>";
|
|
8
|
+
const TOOL_ELEMENT = /^<([A-Za-z_][\w.-]*)(\s[^<>]*?)?\s*\/>$/s;
|
|
9
|
+
const ATTRIBUTE = /([A-Za-z_][\w.-]*)\s*=\s*("([^"]*)"|'([^']*)')/g;
|
|
10
|
+
var QwenXmlInbandScanner = class {
|
|
11
|
+
#buffer = "";
|
|
12
|
+
#insideSection = false;
|
|
13
|
+
feed(chunk) {
|
|
14
|
+
this.#buffer += chunk;
|
|
15
|
+
return this.#drain(false);
|
|
16
|
+
}
|
|
17
|
+
flush() {
|
|
18
|
+
return this.#drain(true);
|
|
19
|
+
}
|
|
20
|
+
#drain(flush) {
|
|
21
|
+
const events = [];
|
|
22
|
+
while (this.#buffer.length > 0) {
|
|
23
|
+
if (!this.#insideSection) {
|
|
24
|
+
const open = this.#buffer.indexOf(SECTION_OPEN);
|
|
25
|
+
if (open >= 0) {
|
|
26
|
+
if (open > 0) events.push({
|
|
27
|
+
type: "text",
|
|
28
|
+
text: this.#buffer.slice(0, open)
|
|
29
|
+
});
|
|
30
|
+
this.#buffer = this.#buffer.slice(open + 12);
|
|
31
|
+
this.#insideSection = true;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (flush) {
|
|
35
|
+
events.push({
|
|
36
|
+
type: "text",
|
|
37
|
+
text: this.#buffer
|
|
38
|
+
});
|
|
39
|
+
this.#buffer = "";
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
const held = longestSuffixPrefix(this.#buffer, SECTION_OPEN);
|
|
43
|
+
const visibleLength = this.#buffer.length - held;
|
|
44
|
+
if (visibleLength > 0) {
|
|
45
|
+
events.push({
|
|
46
|
+
type: "text",
|
|
47
|
+
text: this.#buffer.slice(0, visibleLength)
|
|
48
|
+
});
|
|
49
|
+
this.#buffer = this.#buffer.slice(visibleLength);
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
const close = this.#buffer.indexOf(SECTION_CLOSE);
|
|
54
|
+
if (close < 0) {
|
|
55
|
+
if (flush) this.#buffer = "";
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
const section = this.#buffer.slice(0, close);
|
|
59
|
+
for (const element of section.match(/<[^<>]+\/>/gs) ?? []) {
|
|
60
|
+
const call = parseToolElement(element);
|
|
61
|
+
if (!call) continue;
|
|
62
|
+
const id = `call_${crypto.randomUUID().replace(/-/g, "").slice(0, 24)}`;
|
|
63
|
+
events.push({
|
|
64
|
+
type: "toolStart",
|
|
65
|
+
id,
|
|
66
|
+
name: call.name
|
|
67
|
+
});
|
|
68
|
+
events.push({
|
|
69
|
+
type: "toolEnd",
|
|
70
|
+
id,
|
|
71
|
+
name: call.name,
|
|
72
|
+
arguments: call.arguments,
|
|
73
|
+
rawBlock: element
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
this.#buffer = this.#buffer.slice(close + 13);
|
|
77
|
+
this.#insideSection = false;
|
|
78
|
+
}
|
|
79
|
+
return events;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
function parseToolElement(element) {
|
|
83
|
+
const match = TOOL_ELEMENT.exec(element);
|
|
84
|
+
if (!match) return void 0;
|
|
85
|
+
const args = {};
|
|
86
|
+
for (const attribute of match[2]?.matchAll(ATTRIBUTE) ?? []) args[attribute[1]] = attribute[3] ?? attribute[4] ?? "";
|
|
87
|
+
return {
|
|
88
|
+
name: match[1],
|
|
89
|
+
arguments: args
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function longestSuffixPrefix(text, target) {
|
|
93
|
+
const max = Math.min(text.length, target.length - 1);
|
|
94
|
+
for (let length = max; length > 0; length--) if (text.endsWith(target.slice(0, length))) return length;
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/utils/stream-markup-healing.ts
|
|
99
|
+
/**
|
|
100
|
+
* Streaming-safe filters for leaked chat-template tool-call and thinking markup.
|
|
101
|
+
*
|
|
102
|
+
* Hosted models sometimes leak raw template markup into visible `content` instead
|
|
103
|
+
* of returning structured events. Tool-call healing delegates to the same
|
|
104
|
+
* dialect scanners used by owned in-band tool calling; this file keeps the
|
|
105
|
+
* provider-facing compatibility wrapper and model/provider gating.
|
|
106
|
+
*/
|
|
107
|
+
const KIMI_SECTION_END = "<|tool_calls_section_end|>";
|
|
108
|
+
const DSML_TOOL_CALLS_CLOSE_FULLWIDTH = "</|DSML|tool_calls>";
|
|
109
|
+
const DSML_TOOL_CALLS_CLOSE_ASCII = "</|DSML|tool_calls>";
|
|
110
|
+
/**
|
|
111
|
+
* State machine that consumes streamed visible text and emits cleaned text,
|
|
112
|
+
* thinking deltas, and reconstructed tool calls.
|
|
113
|
+
*
|
|
114
|
+
* A {@link ThinkingInbandScanner} always heals leaked reasoning idioms
|
|
115
|
+
* (`<think>`, `<thinking>`, ` ```thinking `, Gemma/Harmony channels, …) out of
|
|
116
|
+
* the visible channel. For Kimi / DeepSeek-DSML the provider tool-call grammar
|
|
117
|
+
* runs first and its cleaned text is piped through that thinking healer, so a
|
|
118
|
+
* model can leak tool-call markup and reasoning in the same stream.
|
|
119
|
+
*
|
|
120
|
+
* Feed only one stream channel (usually `delta.content` / `message.content`).
|
|
121
|
+
* Mixing reasoning and visible text into the same instance can corrupt held-back
|
|
122
|
+
* partial tag buffers.
|
|
123
|
+
*/
|
|
124
|
+
var StreamMarkupHealing = class {
|
|
125
|
+
#pattern;
|
|
126
|
+
/** Provider tool-call grammar (Kimi tokens / DSML envelope); absent for plain text streams. */
|
|
127
|
+
#toolScanner;
|
|
128
|
+
/** Always-on healer for leaked reasoning idioms in the visible text channel. */
|
|
129
|
+
#thinkingScanner = new ThinkingInbandScanner();
|
|
130
|
+
#sectionTerminated = false;
|
|
131
|
+
#completed = [];
|
|
132
|
+
constructor(options) {
|
|
133
|
+
this.#pattern = options.pattern;
|
|
134
|
+
this.#toolScanner = options.pattern === "kimi" ? createInbandScanner("kimi") : options.pattern === "dsml" ? createInbandScanner("xml", { xmlTagset: "dsml" }) : options.pattern === "qwen" ? new QwenXmlInbandScanner() : void 0;
|
|
135
|
+
}
|
|
136
|
+
get pattern() {
|
|
137
|
+
return this.#pattern;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Feed a chunk and return visible text only. Reconstructed tool calls are
|
|
141
|
+
* stored for {@link drainCompleted}; thinking blocks are intentionally not
|
|
142
|
+
* returned by this compatibility helper. Use {@link feedEvents} when the caller
|
|
143
|
+
* needs ordered text/thinking/tool-call events.
|
|
144
|
+
*/
|
|
145
|
+
feed(text) {
|
|
146
|
+
let clean = "";
|
|
147
|
+
for (const event of this.feedEvents(text)) if (event.type === "text") clean += event.text;
|
|
148
|
+
else if (event.type === "toolCall") this.#completed.push(event.call);
|
|
149
|
+
return clean;
|
|
150
|
+
}
|
|
151
|
+
/** Feed a chunk and return cleaned text/thinking/tool-call events in stream order. */
|
|
152
|
+
feedEvents(text) {
|
|
153
|
+
if (text.length === 0) return [];
|
|
154
|
+
this.#markSectionClosed(text);
|
|
155
|
+
if (!this.#toolScanner) return this.#convertScannerEvents(this.#thinkingScanner.feed(text));
|
|
156
|
+
return this.#convertScannerEvents(this.#healThinking(this.#toolScanner.feed(text)));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Feed a chunk and return cleaned events, excluding synthesized tool calls.
|
|
160
|
+
* Used when the upstream chunk also carries structured `tool_calls`, keeping
|
|
161
|
+
* that structured payload as the single source of truth while preserving
|
|
162
|
+
* adjacent text and thinking events.
|
|
163
|
+
*/
|
|
164
|
+
feedEventsWithoutCalls(text) {
|
|
165
|
+
const events = this.feedEvents(text);
|
|
166
|
+
let out;
|
|
167
|
+
for (let i = 0; i < events.length; i++) {
|
|
168
|
+
const event = events[i];
|
|
169
|
+
if (event.type === "toolCall") out ??= events.slice(0, i);
|
|
170
|
+
else if (out) out.push(event);
|
|
171
|
+
}
|
|
172
|
+
return out ?? events;
|
|
173
|
+
}
|
|
174
|
+
/** Drain accumulated tool calls from calls to {@link feed}. */
|
|
175
|
+
drainCompleted() {
|
|
176
|
+
if (this.#completed.length === 0) return [];
|
|
177
|
+
return this.#completed.splice(0, this.#completed.length);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Flush held-back stream-end fragments as ordered events. Partial tool-call
|
|
181
|
+
* sections/envelopes are dropped by the delegated scanners; unterminated
|
|
182
|
+
* thinking blocks are emitted as thinking, matching the previous MiniMax parser
|
|
183
|
+
* behavior.
|
|
184
|
+
*/
|
|
185
|
+
flushEvents() {
|
|
186
|
+
const tail = this.#toolScanner ? this.#healThinking(this.#toolScanner.flush()) : [];
|
|
187
|
+
tail.push(...this.#thinkingScanner.flush());
|
|
188
|
+
return this.#convertScannerEvents(tail);
|
|
189
|
+
}
|
|
190
|
+
/** Flush held-back text only. Reconstructed calls are retained for {@link drainCompleted}. */
|
|
191
|
+
flushPending() {
|
|
192
|
+
let clean = "";
|
|
193
|
+
for (const event of this.flushEvents()) if (event.type === "text") clean += event.text;
|
|
194
|
+
else if (event.type === "toolCall") this.#completed.push(event.call);
|
|
195
|
+
return clean;
|
|
196
|
+
}
|
|
197
|
+
/** True once any configured tool-call section/envelope has fully closed. */
|
|
198
|
+
get sectionClosed() {
|
|
199
|
+
return this.#sectionTerminated;
|
|
200
|
+
}
|
|
201
|
+
#markSectionClosed(text) {
|
|
202
|
+
if (this.#sectionTerminated || !this.#toolScanner) return;
|
|
203
|
+
if (this.#pattern === "kimi") {
|
|
204
|
+
this.#sectionTerminated = text.includes(KIMI_SECTION_END);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (this.#pattern === "qwen") {
|
|
208
|
+
this.#sectionTerminated = text.includes("</tool_calls>");
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
this.#sectionTerminated = text.includes(DSML_TOOL_CALLS_CLOSE_FULLWIDTH) || text.includes(DSML_TOOL_CALLS_CLOSE_ASCII);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Re-scan the tool scanner's visible text through the always-on thinking
|
|
215
|
+
* healer: `text` events are healed for leaked reasoning idioms, while the tool
|
|
216
|
+
* scanner's own thinking / tool-call events pass through in stream order.
|
|
217
|
+
*/
|
|
218
|
+
#healThinking(toolEvents) {
|
|
219
|
+
const out = [];
|
|
220
|
+
for (const event of toolEvents) if (event.type === "text") out.push(...this.#thinkingScanner.feed(event.text));
|
|
221
|
+
else out.push(event);
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
#convertScannerEvents(events) {
|
|
225
|
+
const out = [];
|
|
226
|
+
for (const event of events) switch (event.type) {
|
|
227
|
+
case "text":
|
|
228
|
+
out.push({
|
|
229
|
+
type: "text",
|
|
230
|
+
text: event.text
|
|
231
|
+
});
|
|
232
|
+
break;
|
|
233
|
+
case "thinkingDelta":
|
|
234
|
+
if (event.delta.length > 0) out.push({
|
|
235
|
+
type: "thinking",
|
|
236
|
+
thinking: event.delta
|
|
237
|
+
});
|
|
238
|
+
break;
|
|
239
|
+
case "toolEnd": out.push({
|
|
240
|
+
type: "toolCall",
|
|
241
|
+
call: {
|
|
242
|
+
id: generateHealedToolCallId(),
|
|
243
|
+
name: event.name,
|
|
244
|
+
arguments: JSON.stringify(event.arguments)
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
return out;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
function generateHealedToolCallId() {
|
|
252
|
+
return `call_${crypto.randomUUID().replace(/-/g, "").slice(0, 24)}`;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Pick the leaked-markup healer for an OpenAI-compatible / Ollama visible-text
|
|
256
|
+
* stream. Kimi chat-template tokens and DeepSeek DSML envelopes need their
|
|
257
|
+
* dedicated tool-call grammars; every other model uses `"thinking"`. All three
|
|
258
|
+
* patterns run the generic {@link ThinkingInbandScanner}, so leaked reasoning
|
|
259
|
+
* idioms (e.g. a Gemini ` ```thinking ` fence on OpenRouter) are always healed.
|
|
260
|
+
*/
|
|
261
|
+
function getStreamMarkupHealingPattern(model) {
|
|
262
|
+
if (model.identity.class === "kimi") return "kimi";
|
|
263
|
+
if (model.identity.class === "deepseek") return "dsml";
|
|
264
|
+
return "thinking";
|
|
265
|
+
}
|
|
266
|
+
//#endregion
|
|
267
|
+
export { getStreamMarkupHealingPattern as n, StreamMarkupHealing as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
2
|
__installBunShim();
|
|
3
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@
|
|
3
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@18.1.17/node_modules/@oh-my-pi/pi-ai/src/utils/schema/strict-tool-validation.ts
|
|
4
4
|
const SCHEMA_TYPE_NAMES = {
|
|
5
5
|
string: true,
|
|
6
6
|
number: true,
|
|
@@ -73,7 +73,7 @@ function findStrictToolSchemaViolation(schema, path = "#", options) {
|
|
|
73
73
|
if (Array.isArray(node.enum) && node.enum.some((v) => !types.some((t) => jsonValueMatchesType(v, t)))) return `${path}/enum`;
|
|
74
74
|
if ("const" in node && !types.some((t) => jsonValueMatchesType(node.const, t))) return `${path}/const`;
|
|
75
75
|
}
|
|
76
|
-
if (options?.
|
|
76
|
+
if (options?.rejectRootObjectUnion && path === "#" && (types.includes("object") || node.properties !== void 0 && typeof node.properties === "object")) for (const key of ["anyOf", "oneOf"]) {
|
|
77
77
|
const arr = node[key];
|
|
78
78
|
if (!Array.isArray(arr) || arr.length === 0) continue;
|
|
79
79
|
if (arr.some((branch) => {
|