From 1e678ecc1a452c2bb881c11294f61478ab1a51ca Mon Sep 17 00:00:00 2001 From: "CJACK." Date: Sun, 22 Feb 2026 23:05:40 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(node):=20=E7=A7=BB=E9=99=A4=E8=A2=AB?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E5=B7=A5=E5=85=B7=E8=B0=83=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E5=9B=9E=E9=80=80=E9=87=8D=E5=8F=91=E5=B9=B6=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=20Go=20=E8=A1=8C=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/js/helpers/stream-tool-sieve/parse.js | 8 -------- tests/node/stream-tool-sieve.test.js | 10 +++++++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/js/helpers/stream-tool-sieve/parse.js b/internal/js/helpers/stream-tool-sieve/parse.js index def46db..f1efdda 100644 --- a/internal/js/helpers/stream-tool-sieve/parse.js +++ b/internal/js/helpers/stream-tool-sieve/parse.js @@ -263,14 +263,6 @@ function filterToolCalls(parsed, toolNames) { } out.push({ name: tc.name, input: tc.input || {} }); } - if (out.length === 0 && parsed.length > 0) { - for (const tc of parsed) { - if (!tc || !tc.name) { - continue; - } - out.push({ name: tc.name, input: tc.input || {} }); - } - } return out; } diff --git a/tests/node/stream-tool-sieve.test.js b/tests/node/stream-tool-sieve.test.js index e96716b..2fc2ecc 100644 --- a/tests/node/stream-tool-sieve.test.js +++ b/tests/node/stream-tool-sieve.test.js @@ -52,11 +52,19 @@ test('parseToolCalls keeps non-object argument strings as _raw (Go parity)', () ]); }); -test('parseToolCalls still intercepts unknown schema names to avoid leaks', () => { +test('parseToolCalls drops unknown schema names when toolNames is provided', () => { const payload = JSON.stringify({ tool_calls: [{ name: 'not_in_schema', input: { q: 'go' } }], }); const calls = parseToolCalls(payload, ['search']); + assert.equal(calls.length, 0); +}); + +test('parseToolCalls keeps unknown names when toolNames is empty', () => { + const payload = JSON.stringify({ + tool_calls: [{ name: 'not_in_schema', input: { q: 'go' } }], + }); + const calls = parseToolCalls(payload, []); assert.equal(calls.length, 1); assert.equal(calls[0].name, 'not_in_schema'); }); From 9a57af609222cb258fb3a6f8bf4ca4d138ecf503 Mon Sep 17 00:00:00 2001 From: "CJACK." Date: Sun, 22 Feb 2026 23:28:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?ci:=20=E5=A2=9E=E5=8A=A0=20Node=20=E5=8D=95?= =?UTF-8?q?=E6=B5=8B=E5=A4=B1=E8=B4=A5=E6=91=98=E8=A6=81=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/scripts/run-unit-node.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/scripts/run-unit-node.sh b/tests/scripts/run-unit-node.sh index 515a961..69ddf4e 100755 --- a/tests/scripts/run-unit-node.sh +++ b/tests/scripts/run-unit-node.sh @@ -5,4 +5,18 @@ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)" cd "$ROOT_DIR" ./tests/scripts/check-node-split-syntax.sh -node --test tests/node/stream-tool-sieve.test.js tests/node/chat-stream.test.js tests/node/js_compat_test.js "$@" + +# Keep Node's file-level test scheduling serial to avoid intermittent cross-file +# interference when multiple suites import mutable module singletons. +NODE_TEST_LOG="$(mktemp)" +cleanup() { + rm -f "$NODE_TEST_LOG" +} +trap cleanup EXIT + +if ! node --test --test-concurrency=1 tests/node/stream-tool-sieve.test.js tests/node/chat-stream.test.js tests/node/js_compat_test.js "$@" 2>&1 | tee "$NODE_TEST_LOG"; then + echo + echo "[run-unit-node] Node tests failed. 失败摘要如下:" + rg -n "^(not ok|# fail)|ERR_TEST_FAILURE" "$NODE_TEST_LOG" || true + exit 1 +fi