fix(ai): preserve render chart order

This commit is contained in:
digua committed 2026-06-11 22:35:07 +08:00
1 parent 3725a5bbea
commit 848a44310c
2 files changed
+42 -3

No files matched your search

+22
View File
@@ -120,6 +120,28 @@ describe('aiChat chart block helpers', () => {
assert.equal(nextBlocks[1]?.type, 'chart')
})
it('keeps render-only charts in tool call order when results arrive out of order', () => {
const blocks = [
createRenderOnlyToolPendingBlock('render_chart', { title: '第一张图' }, 'call_chart_a'),
createRenderOnlyToolPendingBlock('render_chart', { title: '第二张图' }, 'call_chart_b'),
].filter((block): block is NonNullable<typeof block> => block !== null)
const afterSecondCompletes = replaceRenderOnlyToolPendingBlockWithCharts(blocks, 'render_chart', 'call_chart_b', [
secondChart,
])
const afterFirstCompletes = replaceRenderOnlyToolPendingBlockWithCharts(
afterSecondCompletes,
'render_chart',
'call_chart_a',
[chart]
)
const chartTitles = afterFirstCompletes
.filter((block): block is { type: 'chart'; chart: ChartPayload } => block.type === 'chart')
.map((block) => block.chart.spec.title)
assert.deepEqual(chartTitles, ['Daily messages', 'Selected members'])
})
it('does not append duplicate render-only charts already present in the message', () => {
const reorderedSpecChart: ChartPayload = {
...chart,
+20 -3
View File
@@ -181,9 +181,26 @@ export function replaceRenderOnlyToolPendingBlockWithCharts<T>(
toolCallId: string | undefined,
charts: ChartPayload[]
): Array<T | ChartContentBlock> {
const withoutPending = removeRenderOnlyToolPendingBlock(blocks, toolName, toolCallId)
const uniqueCharts = charts.filter((chart) => !hasDuplicateChart(withoutPending, chart))
return [...withoutPending, ...toChartContentBlocks(uniqueCharts)]
const next = [...blocks] as Array<T | ChartContentBlock>
let pendingIndex = -1
for (let index = next.length - 1; index >= 0; index--) {
if (isMatchingPendingRenderOnlyToolBlock(next[index], toolName, toolCallId)) {
pendingIndex = index
break
}
}
const duplicateBase = pendingIndex >= 0 ? next.filter((_block, index) => index !== pendingIndex) : next
const uniqueCharts = charts.filter((chart) => !hasDuplicateChart(duplicateBase, chart))
const chartBlocks = toChartContentBlocks(uniqueCharts)
if (pendingIndex >= 0) {
next.splice(pendingIndex, 1, ...chartBlocks)
return next
}
return [...next, ...chartBlocks]
}
export function finishRenderOnlyToolResultBlocks<T>(