mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-11 03:37:40 +08:00
PR #460 introduced fullwidth pipe characters (|) in DSML tool call formatting to improve parsing robustness, but models exposed to these fullwidth pipes in system prompts exhibit significantly higher rates of tool output hallucinations. Reverting to halfwidth pipes (|) drastically reduces tokenizer/perplexity-driven hallucinations while retaining the existing confusable-hardening in the parser. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
105 lines
2.9 KiB
JavaScript
105 lines
2.9 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
async function loadUtils() {
|
|
return import('../../webui/src/features/chatHistory/chatHistoryUtils.js');
|
|
}
|
|
|
|
test('chat history strict parser merges current input file placeholder', async () => {
|
|
const {
|
|
buildListModeMessages,
|
|
} = await loadUtils();
|
|
const t = (key) => key;
|
|
const item = {
|
|
messages: [{
|
|
role: 'user',
|
|
content: 'Continue from the latest state in the attached DS2API_HISTORY.txt context. Treat it as the current working state and answer the latest user request directly.',
|
|
}],
|
|
history_text: [
|
|
'<|begin▁of▁sentence|>',
|
|
'<|User|>hello',
|
|
'<|Assistant|>hi<|end▁of▁sentence|>',
|
|
].join(''),
|
|
};
|
|
|
|
const result = buildListModeMessages(item, t);
|
|
assert.equal(result.historyMerged, true);
|
|
assert.deepEqual(result.messages, [
|
|
{ role: 'user', content: 'hello' },
|
|
{ role: 'assistant', content: 'hi' },
|
|
]);
|
|
});
|
|
|
|
test('chat history strict parser inserts history after system messages', async () => {
|
|
const {
|
|
buildListModeMessages,
|
|
} = await loadUtils();
|
|
const t = (key) => key;
|
|
const item = {
|
|
messages: [
|
|
{ role: 'system', content: 'policy' },
|
|
{ role: 'user', content: 'latest' },
|
|
],
|
|
history_text: [
|
|
'<|begin▁of▁sentence|>',
|
|
'<|User|>old',
|
|
'<|Assistant|>done<|end▁of▁sentence|>',
|
|
].join(''),
|
|
};
|
|
|
|
const result = buildListModeMessages(item, t);
|
|
assert.equal(result.historyMerged, true);
|
|
assert.deepEqual(result.messages, [
|
|
{ role: 'system', content: 'policy' },
|
|
{ role: 'user', content: 'old' },
|
|
{ role: 'assistant', content: 'done' },
|
|
{ role: 'user', content: 'latest' },
|
|
]);
|
|
});
|
|
|
|
test('chat history transcript parser replaces current input file placeholder', async () => {
|
|
const {
|
|
buildListModeMessages,
|
|
} = await loadUtils();
|
|
const t = (key) => key;
|
|
const item = {
|
|
messages: [{
|
|
role: 'user',
|
|
content: 'Continue from the latest state in the attached DS2API_HISTORY.txt context. Treat it as the current working state and answer the latest user request directly.',
|
|
}],
|
|
history_text: [
|
|
'# DS2API_HISTORY.txt',
|
|
'Prior conversation history and tool progress.',
|
|
'',
|
|
'=== 1. SYSTEM ===',
|
|
'policy',
|
|
'',
|
|
'=== 2. USER ===',
|
|
'hello',
|
|
'',
|
|
'=== 3. ASSISTANT ===',
|
|
'hi',
|
|
'',
|
|
'=== 4. TOOL ===',
|
|
'[name=search_web tool_call_id=call_1]',
|
|
'{"ok":true}',
|
|
'',
|
|
'=== 5. USER ===',
|
|
'latest',
|
|
'',
|
|
].join('\n'),
|
|
};
|
|
|
|
const result = buildListModeMessages(item, t);
|
|
assert.equal(result.historyMerged, true);
|
|
assert.deepEqual(result.messages, [
|
|
{ role: 'system', content: 'policy' },
|
|
{ role: 'user', content: 'hello' },
|
|
{ role: 'assistant', content: 'hi' },
|
|
{ role: 'tool', content: '[name=search_web tool_call_id=call_1]\n{"ok":true}' },
|
|
{ role: 'user', content: 'latest' },
|
|
]);
|
|
});
|