mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-20 16:07:47 +08:00
fix(js): avoid false tool-call capture on plain tool_calls prose
This commit is contained in:
@@ -197,7 +197,11 @@ function findToolSegmentStart(state, s) {
|
|||||||
}
|
}
|
||||||
const keyIdx = bestKeyIdx;
|
const keyIdx = bestKeyIdx;
|
||||||
const start = s.slice(0, keyIdx).lastIndexOf('{');
|
const start = s.slice(0, keyIdx).lastIndexOf('{');
|
||||||
let candidateStart = start >= 0 ? start : keyIdx;
|
if (start < 0) {
|
||||||
|
offset = keyIdx + matchedKeyword.length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let candidateStart = start;
|
||||||
// If the keyword matched inside an XML tag (e.g. "tool_calls" in "<tool_calls>"),
|
// If the keyword matched inside an XML tag (e.g. "tool_calls" in "<tool_calls>"),
|
||||||
// back up past the '<' to capture the full tag.
|
// back up past the '<' to capture the full tag.
|
||||||
if (candidateStart > 0 && s[candidateStart - 1] === '<') {
|
if (candidateStart > 0 && s[candidateStart - 1] === '<') {
|
||||||
|
|||||||
@@ -252,6 +252,18 @@ test('sieve keeps plain text intact in tool mode when no tool call appears', ()
|
|||||||
assert.equal(leakedText, '你好,这是普通文本回复。请继续。');
|
assert.equal(leakedText, '你好,这是普通文本回复。请继续。');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('sieve does not start capture on plain "tool_calls" prose without opening json brace', () => {
|
||||||
|
const events = runSieve(
|
||||||
|
['前置。', '这里提到 tool_calls 只是解释,不是调用。', '后置。'],
|
||||||
|
['read_file'],
|
||||||
|
);
|
||||||
|
const leakedText = collectText(events);
|
||||||
|
const hasToolCall = events.some((evt) => evt.type === 'tool_calls' && evt.calls?.length > 0);
|
||||||
|
assert.equal(hasToolCall, false);
|
||||||
|
assert.equal(leakedText.includes('tool_calls'), true);
|
||||||
|
assert.equal(leakedText, '前置。这里提到 tool_calls 只是解释,不是调用。后置。');
|
||||||
|
});
|
||||||
|
|
||||||
test('sieve emits unknown tool payload (no args) as executable tool call', () => {
|
test('sieve emits unknown tool payload (no args) as executable tool call', () => {
|
||||||
const events = runSieve(
|
const events = runSieve(
|
||||||
['{"tool_calls":[{"name":"not_in_schema"}]}', '后置正文G。'],
|
['{"tool_calls":[{"name":"not_in_schema"}]}', '后置正文G。'],
|
||||||
|
|||||||
Reference in New Issue
Block a user