Compare commits

...

2 Commits

Author SHA1 Message Date
jiang 8cd81900f8 移除拉取请求触发,简化 CI/CD 配置
Agent CI/CD / docker-image (push) Successful in 11s
Agent CI/CD / deploy-fallback-log (push) Has been skipped
2026-05-19 16:01:57 +08:00
jiang 8281c532f2 优化会话标题生成逻辑 2026-05-19 15:59:42 +08:00
2 changed files with 29 additions and 14 deletions
+1 -4
View File
@@ -1,14 +1,11 @@
name: Agent CI/CD name: Agent CI/CD
on: on:
pull_request:
push: push:
branches:
- main
- master
tags: tags:
- "v*" - "v*"
- "latest" - "latest"
workflow_dispatch: {}
jobs: jobs:
docker-image: docker-image:
+28 -10
View File
@@ -278,18 +278,27 @@ export const buildChatRouter = (
const assistantText = collectTextContent(assistantMessage?.parts ?? []); const assistantText = collectTextContent(assistantMessage?.parts ?? []);
const existingSessionTitle = sessionBridge.getSessionTitle(binding.sessionId); const existingSessionTitle = sessionBridge.getSessionTitle(binding.sessionId);
let sessionTitle = existingSessionTitle; let sessionTitle = existingSessionTitle;
const { userMessageCount, assistantMessageCount } =
await getConversationTurnStats(runtime, binding.sessionId);
const shouldGenerateTitle = const shouldGenerateTitle =
!existingSessionTitle && userMessageCount <= 3 &&
(await isFirstRoundConversation(runtime, binding.sessionId)); assistantMessageCount >= 1;
if (shouldGenerateTitle) { if (shouldGenerateTitle) {
sessionTitle = await generateSessionTitle(runtime, { sessionTitle = await generateSessionTitle(runtime, {
sessionId: binding.sessionId, sessionId: binding.sessionId,
latestUserMessage: parsed.data.message, latestUserMessage: parsed.data.message,
fallbackTitle: existingSessionTitle,
}); });
sessionBridge.setSessionTitle(binding.sessionId, sessionTitle); if (sessionTitle !== existingSessionTitle) {
sessionBridge.setSessionTitle(binding.sessionId, sessionTitle);
}
} }
if (!streamClosed && !res.writableEnded && !res.destroyed) { if (!streamClosed && !res.writableEnded && !res.destroyed) {
if (shouldGenerateTitle && sessionTitle) { if (
shouldGenerateTitle &&
sessionTitle &&
sessionTitle !== existingSessionTitle
) {
res.write( res.write(
toSse("session_title", { toSse("session_title", {
session_id: clientSessionId, session_id: clientSessionId,
@@ -1044,16 +1053,25 @@ const buildTitleConversationContext = async (
.slice(0, 2400); .slice(0, 2400);
}; };
const isFirstRoundConversation = async ( const getConversationTurnStats = async (
runtime: OpencodeRuntimeAdapter, runtime: OpencodeRuntimeAdapter,
sessionId: string, sessionId: string,
) => { ) => {
const messages = await runtime.messages(sessionId, 12); const messages = await runtime.messages(sessionId, 12);
const chatMessageCount = messages.filter( return messages.reduce(
(message) => (stats, message) => {
message.info.role === "user" || message.info.role === "assistant", if (message.info.role === "user") {
).length; stats.userMessageCount += 1;
return chatMessageCount === 2; } else if (message.info.role === "assistant") {
stats.assistantMessageCount += 1;
}
return stats;
},
{
userMessageCount: 0,
assistantMessageCount: 0,
},
);
}; };
const normalizeGeneratedTitle = (rawTitle: string, fallback: string) => { const normalizeGeneratedTitle = (rawTitle: string, fallback: string) => {