MCPcopy Create free account
hub / github.com/Rfym21/Qwen2API / createToolCallStreamParser

Function createToolCallStreamParser

src/utils/tool-prompt.js:267–381  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

265
266/**
267 * 从 from 起、limit 之前,下一个**像负载**的行首 '{':结构由 nextLineStartBrace 给出,
268 * 形状按位置选谓词(首位 isLeakedToolPayloadShape / 正文之后 isPlausibleAfterProsePayload)。
269 * 三个消费者共用(识别器、残片切点、抢救的锚点检查),候选的定义只有这一份。
270 * 便宜的 "name" 窗口判断先行,像负载的候选才切出(可能很长的)尾巴给谓词。
271 * @returns {number} -1 表示没有
272 */
273const nextPayloadCandidate = (text, from, atLineStart, limit, afterProse) => {
274 let at = nextLineStartBrace(text, from, atLineStart, limit);
275 while (at !== -1) {
276 if (LEAKED_PAYLOAD_NAME_RE.test(text.slice(at, at + LEAKED_PAYLOAD_NAME_WINDOW))) {
277 const shape = afterProse
278 ? isPlausibleAfterProsePayload(text.slice(at, at + AFTER_PROSE_PAYLOAD_MAX + 1))
279 : isLeakedToolPayloadShape(text.slice(at));
280 if (shape) return at;
281 }
282 at = nextLineStartBrace(text, at + 1, false, limit);
283 }
284 return -1;
285};
286
287/**
288 * index 处是否处在**行首**:上一个换行(或文本开头)到 index 之间只有空白。两条路径
289 * 共用同一个谓词(review loop 2):整段路径在每个扫描位置与残片切点之后的恢复点上问它
290 * (`fullText[position-1] === '\n'` 会把缩进过的 ` {"name":…}` 拒之门外);流式解析器
291 * 用它在每个放行点更新 lineStart —— 放行的文本没有换行时沿用之前的状态(prior),
292 * 于是切在前导空白中间的 chunk 边界也不会让下一个 '{' 失去行首身份。
293 * 代价是 index 之前那一串空白的长度,遇到第一个非空白就停。
294 * @param {string} text
295 * @param {number} index
296 * @param {boolean} [prior=true] - 文本开头之前的行首状态
297 * @returns {boolean}
298 */
299const lineStartBefore = (text, index, prior = true) => {
300 let i = index - 1;
301 while (i >= 0 && (text[i] === ' ' || text[i] === '\t' || text[i] === '\r')) i -= 1;
302 return i < 0 ? prior : text[i] === '\n';
303};
304
305/**
306 * 记录正文当前是否处在代码上下文里。文档里的例子必须保持是例子:``` 围栏内,
307 * 或同一行反引号数为奇数(行内代码)时,触发器不算触发器。
308 * 增量式:只喂**已经放行**的正文,所以流式和整段两条路径可以共用同一套判断。
309 */
310const createCodeContextTracker = () => {
311 let inFence = false;
312 let ticksOnLine = 0;
313 let run = 0;
314 let runAtLineStart = true; // 这串反引号前面,本行是不是只有空白
315 let lineIsBlank = true; // 本行到目前为止是不是只有空白
316
317 // 围栏必须**顶行**(Markdown 的规则)。之前任何位置的三连反引号都会翻转围栏状态,
318 // 于是 JSON 字符串里的 ``` 也算围栏;一旦错位就再也回不来,后面每个真实调用都被
319 // 当成文档静默丢掉 —— 正是这次要消灭的那类无声失败。
320 const settle = () => {
321 if (run === 0) return;
322 if (run >= 3 && runAtLineStart) {
323 inFence = !inFence;
324 ticksOnLine = 0;

Callers 2

handleStreamResponseFunction · 0.85
handleAnthropicStreamFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected