Align Vercel JS toolcall filtering with Go semantics

This commit is contained in:
CJACK.
2026-03-21 00:23:22 +08:00
parent 65e0de3c82
commit b8ff678f24
4 changed files with 18 additions and 5 deletions

View File

@@ -60,6 +60,9 @@ function formatIncrementalToolCallDeltas(deltas, idStore) {
if (typeof d.arguments === 'string' && d.arguments !== '') {
fn.arguments = d.arguments;
}
if (Object.keys(fn).length === 0) {
continue;
}
if (Object.keys(fn).length > 0) {
item.function = fn;
}

View File

@@ -17,15 +17,18 @@ function extractToolNames(tools) {
return [];
}
const out = [];
const seen = new Set();
for (const t of tools) {
if (!t || typeof t !== 'object') {
continue;
}
const fn = t.function && typeof t.function === 'object' ? t.function : t;
const name = toStringSafe(fn.name);
// Keep parity with Go injectToolPrompt: object tools without name still
// enter tool mode via fallback name "unknown".
out.push(name || 'unknown');
if (!name || seen.has(name)) {
continue;
}
seen.add(name);
out.push(name);
}
return out;
}

View File

@@ -98,6 +98,12 @@ test('incremental and final tool formatting share stable id via idStore', () =>
assert.equal(incremental[0].id, finalCalls[0].id);
});
test('formatIncrementalToolCallDeltas drops empty deltas (Go parity)', () => {
const idStore = new Map();
const formatted = formatIncrementalToolCallDeltas([{ index: 0 }], idStore);
assert.deepEqual(formatted, []);
});
test('parseChunkForContent keeps split response/content fragments inside response array', () => {
const chunk = {
p: 'response',

View File

@@ -31,13 +31,14 @@ function collectText(events) {
.join('');
}
test('extractToolNames keeps tool mode enabled with unknown fallback', () => {
test('extractToolNames keeps only declared tool names (Go parity)', () => {
const names = extractToolNames([
{ function: { description: 'no name tool' } },
{ function: { name: ' read_file ' } },
{ function: { name: 'read_file' } },
{},
]);
assert.deepEqual(names, ['unknown', 'read_file', 'unknown']);
assert.deepEqual(names, ['read_file']);
});
test('parseToolCalls keeps non-object argument strings as _raw (Go parity)', () => {