Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
ed4ec1ef
Unverified
提交
ed4ec1ef
authored
6月 25, 2025
作者:
Will Chen
提交者:
GitHub
6月 25, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Optimize summarization (#487)
Fixes #435
上级
fe597db5
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
190 行增加
和
3 行删除
+190
-3
formatMessagesForSummary.test.ts
src/__tests__/formatMessagesForSummary.test.ts
+166
-0
chat_stream_handlers.ts
src/ipc/handlers/chat_stream_handlers.ts
+24
-3
没有找到文件。
src/__tests__/formatMessagesForSummary.test.ts
0 → 100644
浏览文件 @
ed4ec1ef
import
{
formatMessagesForSummary
}
from
"../ipc/handlers/chat_stream_handlers"
;
describe
(
"formatMessagesForSummary"
,
()
=>
{
it
(
"should return all messages when there are 8 or fewer messages"
,
()
=>
{
const
messages
=
[
{
role
:
"user"
,
content
:
"Hello"
},
{
role
:
"assistant"
,
content
:
"Hi there!"
},
{
role
:
"user"
,
content
:
"How are you?"
},
{
role
:
"assistant"
,
content
:
"I'm doing well, thanks!"
},
];
const
result
=
formatMessagesForSummary
(
messages
);
const
expected
=
[
'<message role="user">Hello</message>'
,
'<message role="assistant">Hi there!</message>'
,
'<message role="user">How are you?</message>'
,
'<message role="assistant">I
\'
m doing well, thanks!</message>'
,
].
join
(
"
\
n"
);
expect
(
result
).
toBe
(
expected
);
});
it
(
"should return all messages when there are exactly 8 messages"
,
()
=>
{
const
messages
=
Array
.
from
({
length
:
8
},
(
_
,
i
)
=>
({
role
:
i
%
2
===
0
?
"user"
:
"assistant"
,
content
:
`Message
${
i
+
1
}
`
,
}));
const
result
=
formatMessagesForSummary
(
messages
);
const
expected
=
messages
.
map
((
m
)
=>
`<message role="
${
m
.
role
}
">
${
m
.
content
}
</message>`
)
.
join
(
"
\
n"
);
expect
(
result
).
toBe
(
expected
);
});
it
(
"should truncate messages when there are more than 8 messages"
,
()
=>
{
const
messages
=
Array
.
from
({
length
:
12
},
(
_
,
i
)
=>
({
role
:
i
%
2
===
0
?
"user"
:
"assistant"
,
content
:
`Message
${
i
+
1
}
`
,
}));
const
result
=
formatMessagesForSummary
(
messages
);
// Should contain first 2 messages
expect
(
result
).
toContain
(
'<message role="user">Message 1</message>'
);
expect
(
result
).
toContain
(
'<message role="assistant">Message 2</message>'
);
// Should contain omission indicator
expect
(
result
).
toContain
(
'<message role="system">[... 4 messages omitted ...]</message>'
,
);
// Should contain last 6 messages
expect
(
result
).
toContain
(
'<message role="user">Message 7</message>'
);
expect
(
result
).
toContain
(
'<message role="assistant">Message 8</message>'
);
expect
(
result
).
toContain
(
'<message role="user">Message 9</message>'
);
expect
(
result
).
toContain
(
'<message role="assistant">Message 10</message>'
);
expect
(
result
).
toContain
(
'<message role="user">Message 11</message>'
);
expect
(
result
).
toContain
(
'<message role="assistant">Message 12</message>'
);
// Should not contain middle messages
expect
(
result
).
not
.
toContain
(
'<message role="user">Message 3</message>'
);
expect
(
result
).
not
.
toContain
(
'<message role="assistant">Message 4</message>'
,
);
expect
(
result
).
not
.
toContain
(
'<message role="user">Message 5</message>'
);
expect
(
result
).
not
.
toContain
(
'<message role="assistant">Message 6</message>'
,
);
});
it
(
"should handle messages with undefined content"
,
()
=>
{
const
messages
=
[
{
role
:
"user"
,
content
:
"Hello"
},
{
role
:
"assistant"
,
content
:
undefined
},
{
role
:
"user"
,
content
:
"Are you there?"
},
];
const
result
=
formatMessagesForSummary
(
messages
);
const
expected
=
[
'<message role="user">Hello</message>'
,
'<message role="assistant">undefined</message>'
,
'<message role="user">Are you there?</message>'
,
].
join
(
"
\
n"
);
expect
(
result
).
toBe
(
expected
);
});
it
(
"should handle empty messages array"
,
()
=>
{
const
messages
:
{
role
:
string
;
content
:
string
|
undefined
}[]
=
[];
const
result
=
formatMessagesForSummary
(
messages
);
expect
(
result
).
toBe
(
""
);
});
it
(
"should handle single message"
,
()
=>
{
const
messages
=
[{
role
:
"user"
,
content
:
"Hello world"
}];
const
result
=
formatMessagesForSummary
(
messages
);
expect
(
result
).
toBe
(
'<message role="user">Hello world</message>'
);
});
it
(
"should correctly calculate omitted messages count"
,
()
=>
{
const
messages
=
Array
.
from
({
length
:
20
},
(
_
,
i
)
=>
({
role
:
i
%
2
===
0
?
"user"
:
"assistant"
,
content
:
`Message
${
i
+
1
}
`
,
}));
const
result
=
formatMessagesForSummary
(
messages
);
// Should indicate 12 messages omitted (20 total - 2 first - 6 last = 12)
expect
(
result
).
toContain
(
'<message role="system">[... 12 messages omitted ...]</message>'
,
);
});
it
(
"should handle messages with special characters in content"
,
()
=>
{
const
messages
=
[
{
role
:
"user"
,
content
:
'Hello <world> & "friends"'
},
{
role
:
"assistant"
,
content
:
"Hi there! <tag>content</tag>"
},
];
const
result
=
formatMessagesForSummary
(
messages
);
// Should preserve special characters as-is (no HTML escaping)
expect
(
result
).
toContain
(
'<message role="user">Hello <world> & "friends"</message>'
,
);
expect
(
result
).
toContain
(
'<message role="assistant">Hi there! <tag>content</tag></message>'
,
);
});
it
(
"should maintain message order in truncated output"
,
()
=>
{
const
messages
=
Array
.
from
({
length
:
15
},
(
_
,
i
)
=>
({
role
:
i
%
2
===
0
?
"user"
:
"assistant"
,
content
:
`Message
${
i
+
1
}
`
,
}));
const
result
=
formatMessagesForSummary
(
messages
);
const
lines
=
result
.
split
(
"
\
n"
);
// Should have exactly 9 lines (2 first + 1 omission + 6 last)
expect
(
lines
).
toHaveLength
(
9
);
// Check order: first 2, then omission, then last 6
expect
(
lines
[
0
]).
toBe
(
'<message role="user">Message 1</message>'
);
expect
(
lines
[
1
]).
toBe
(
'<message role="assistant">Message 2</message>'
);
expect
(
lines
[
2
]).
toBe
(
'<message role="system">[... 7 messages omitted ...]</message>'
,
);
// Last 6 messages are messages 10-15 (indices 9-14)
// Message 10 (index 9): 9 % 2 === 1, so "assistant"
// Message 11 (index 10): 10 % 2 === 0, so "user"
// Message 12 (index 11): 11 % 2 === 1, so "assistant"
// Message 13 (index 12): 12 % 2 === 0, so "user"
// Message 14 (index 13): 13 % 2 === 1, so "assistant"
// Message 15 (index 14): 14 % 2 === 0, so "user"
expect
(
lines
[
3
]).
toBe
(
'<message role="assistant">Message 10</message>'
);
expect
(
lines
[
4
]).
toBe
(
'<message role="user">Message 11</message>'
);
expect
(
lines
[
5
]).
toBe
(
'<message role="assistant">Message 12</message>'
);
expect
(
lines
[
6
]).
toBe
(
'<message role="user">Message 13</message>'
);
expect
(
lines
[
7
]).
toBe
(
'<message role="assistant">Message 14</message>'
);
expect
(
lines
[
8
]).
toBe
(
'<message role="user">Message 15</message>'
);
});
});
src/ipc/handlers/chat_stream_handlers.ts
浏览文件 @
ed4ec1ef
...
...
@@ -446,7 +446,7 @@ This conversation includes one or more image attachments. When the user uploads
role
:
"user"
,
content
:
"Summarize the following chat: "
+
formatMessages
(
previousChat
?.
messages
??
[]),
formatMessages
ForSummary
(
previousChat
?.
messages
??
[]),
}
satisfies
CoreMessage
,
];
}
...
...
@@ -775,10 +775,31 @@ This conversation includes one or more image attachments. When the user uploads
});
}
export
function
formatMessages
(
export
function
formatMessages
ForSummary
(
messages
:
{
role
:
string
;
content
:
string
|
undefined
}[],
)
{
return
messages
if
(
messages
.
length
<=
8
)
{
// If we have 8 or fewer messages, include all of them
return
messages
.
map
((
m
)
=>
`<message role="
${
m
.
role
}
">
${
m
.
content
}
</message>`
)
.
join
(
"
\
n"
);
}
// Take first 2 messages and last 6 messages
const
firstMessages
=
messages
.
slice
(
0
,
2
);
const
lastMessages
=
messages
.
slice
(
-
6
);
// Combine them with an indicator of skipped messages
const
combinedMessages
=
[
...
firstMessages
,
{
role
:
"system"
,
content
:
`[...
${
messages
.
length
-
8
}
messages omitted ...]`
,
},
...
lastMessages
,
];
return
combinedMessages
.
map
((
m
)
=>
`<message role="
${
m
.
role
}
">
${
m
.
content
}
</message>`
)
.
join
(
"
\
n"
);
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论