|
|
@@ -130,7 +130,9 @@ function buildChatAgentSystemPrompt(options: {
|
|
|
lines.push("当前处于资料写入模式,用户可能希望把对话内容整理写入资料库。")
|
|
|
}
|
|
|
if (options.novelMode) {
|
|
|
- lines.push("小说模式下,如果用户要求生成、续写或改写章节,只输出可直接放入章节库的正文或明确的执行结果。")
|
|
|
+ lines.push("小说模式下,如果用户要求生成、续写或改写章节,只输出可直接放入章节库的正文。")
|
|
|
+ lines.push("章节生成、续写或改写任务的最终回复必须只包含章节正文,不要把工具读取过程、写作计划或执行过程展示给用户。")
|
|
|
+ lines.push("不要输出读取说明、执行总结、完成目标表格、章节结构、后续建议、引用来源或 Markdown 表格;章节标题和正文以外的内容都不要输出。")
|
|
|
}
|
|
|
if (options.deepChapterEnabled) {
|
|
|
lines.push("用户已开启深度模式,请在必要时进行更完整的章节规划和资料读取。")
|
|
|
@@ -663,6 +665,61 @@ export function ChatPanel() {
|
|
|
.map((message) => message.content),
|
|
|
)
|
|
|
: undefined
|
|
|
+
|
|
|
+ const { assistantMessage } = appendAgentChatMessages(capturedConvId, plainText, tokens)
|
|
|
+ setConversationInputDraft(capturedConvId, "")
|
|
|
+ setFallbackReferenceText("")
|
|
|
+ setReferenceTokensByConversation((drafts) => {
|
|
|
+ const withoutCaptured = setReferenceTokensForConversation(drafts, capturedConvId, [])
|
|
|
+ return setReferenceTokensForConversation(withoutCaptured, referenceDraftConversationId, [])
|
|
|
+ })
|
|
|
+ startStreaming(capturedConvId)
|
|
|
+ const sessionId = streamSessionGuardRef.current.start(capturedConvId)
|
|
|
+ activeStreamSessionsRef.current[capturedConvId] = sessionId
|
|
|
+
|
|
|
+ const controller = new AbortController()
|
|
|
+ abortControllersRef.current[capturedConvId] = controller
|
|
|
+ let hasAgentError = false
|
|
|
+
|
|
|
+ const markDone = (record?: AgentRunRecord) => {
|
|
|
+ updateAgentAssistantMessage(assistantMessage.id, (message) => ({
|
|
|
+ ...message,
|
|
|
+ content: message.content || record?.finalText || "Agent未返回内容。",
|
|
|
+ agentToolCalls: record?.toolCalls.length ? record.toolCalls : message.agentToolCalls,
|
|
|
+ references: (() => {
|
|
|
+ const existingReferences = message.references ?? []
|
|
|
+ const existingPaths = new Set(existingReferences.map((reference) => reference.path))
|
|
|
+ const agentReferences = agentToolCallsToMessageReferences(
|
|
|
+ record?.toolCalls.length ? record.toolCalls : message.agentToolCalls,
|
|
|
+ ).filter((reference) => !existingPaths.has(reference.path))
|
|
|
+ return agentReferences.length > 0
|
|
|
+ ? [...existingReferences, ...agentReferences]
|
|
|
+ : message.references
|
|
|
+ })(),
|
|
|
+ isAgentRunning: false,
|
|
|
+ }))
|
|
|
+ }
|
|
|
+
|
|
|
+ const markError = (error: Error) => {
|
|
|
+ hasAgentError = true
|
|
|
+ updateAgentAssistantMessage(assistantMessage.id, (message) => ({
|
|
|
+ ...message,
|
|
|
+ content: message.content
|
|
|
+ ? `${message.content}\n\n出错:${error.message}`
|
|
|
+ : `出错:${error.message}`,
|
|
|
+ isAgentRunning: false,
|
|
|
+ }))
|
|
|
+ }
|
|
|
+
|
|
|
+ const finishAgentSession = (callback?: () => void) => {
|
|
|
+ streamSessionGuardRef.current.finish(capturedConvId, sessionId, () => {
|
|
|
+ callback?.()
|
|
|
+ clearStreaming(capturedConvId)
|
|
|
+ delete activeStreamSessionsRef.current[capturedConvId]
|
|
|
+ delete abortControllersRef.current[capturedConvId]
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
const targetChapterNumber = novelMode && taskRoute
|
|
|
? await resolveTargetChapterNumberForChat({
|
|
|
projectPath: pp,
|
|
|
@@ -671,6 +728,9 @@ export function ChatPanel() {
|
|
|
routeChapterNumber: taskRoute.chapterNumber,
|
|
|
selectedFile,
|
|
|
lastGeneratedChapterNumber,
|
|
|
+ }).catch((error) => {
|
|
|
+ console.warn("解析目标章节失败:", error)
|
|
|
+ return undefined
|
|
|
})
|
|
|
: undefined
|
|
|
const effectiveTaskRoute = taskRoute && targetChapterNumber
|
|
|
@@ -722,12 +782,13 @@ export function ChatPanel() {
|
|
|
if (contextPack.characterAuras.trim()) {
|
|
|
const confirmed = await requestSoulDialog(contextPack.characterAuras)
|
|
|
if (!confirmed) {
|
|
|
- const { assistantMessage } = appendAgentChatMessages(capturedConvId, plainText, tokens)
|
|
|
- updateAgentAssistantMessage(assistantMessage.id, (message) => ({
|
|
|
- ...message,
|
|
|
- content: "已取消本次生成,角色灵魂上下文未发送给模型。",
|
|
|
- isAgentRunning: false,
|
|
|
- }))
|
|
|
+ finishAgentSession(() => {
|
|
|
+ updateAgentAssistantMessage(assistantMessage.id, (message) => ({
|
|
|
+ ...message,
|
|
|
+ content: "已取消本次生成,角色灵魂上下文未发送给模型。",
|
|
|
+ isAgentRunning: false,
|
|
|
+ }))
|
|
|
+ })
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
@@ -781,60 +842,6 @@ export function ChatPanel() {
|
|
|
{ role: "user", content: userContent },
|
|
|
]
|
|
|
|
|
|
- const { assistantMessage } = appendAgentChatMessages(capturedConvId, plainText, tokens)
|
|
|
- setConversationInputDraft(capturedConvId, "")
|
|
|
- setFallbackReferenceText("")
|
|
|
- setReferenceTokensByConversation((drafts) => {
|
|
|
- const withoutCaptured = setReferenceTokensForConversation(drafts, capturedConvId, [])
|
|
|
- return setReferenceTokensForConversation(withoutCaptured, referenceDraftConversationId, [])
|
|
|
- })
|
|
|
- startStreaming(capturedConvId)
|
|
|
- const sessionId = streamSessionGuardRef.current.start(capturedConvId)
|
|
|
- activeStreamSessionsRef.current[capturedConvId] = sessionId
|
|
|
-
|
|
|
- const controller = new AbortController()
|
|
|
- abortControllersRef.current[capturedConvId] = controller
|
|
|
- let hasAgentError = false
|
|
|
-
|
|
|
- const markDone = (record?: AgentRunRecord) => {
|
|
|
- updateAgentAssistantMessage(assistantMessage.id, (message) => ({
|
|
|
- ...message,
|
|
|
- content: message.content || record?.finalText || "Agent未返回内容。",
|
|
|
- agentToolCalls: record?.toolCalls.length ? record.toolCalls : message.agentToolCalls,
|
|
|
- references: (() => {
|
|
|
- const existingReferences = message.references ?? []
|
|
|
- const existingPaths = new Set(existingReferences.map((reference) => reference.path))
|
|
|
- const agentReferences = agentToolCallsToMessageReferences(
|
|
|
- record?.toolCalls.length ? record.toolCalls : message.agentToolCalls,
|
|
|
- ).filter((reference) => !existingPaths.has(reference.path))
|
|
|
- return agentReferences.length > 0
|
|
|
- ? [...existingReferences, ...agentReferences]
|
|
|
- : message.references
|
|
|
- })(),
|
|
|
- isAgentRunning: false,
|
|
|
- }))
|
|
|
- }
|
|
|
-
|
|
|
- const markError = (error: Error) => {
|
|
|
- hasAgentError = true
|
|
|
- updateAgentAssistantMessage(assistantMessage.id, (message) => ({
|
|
|
- ...message,
|
|
|
- content: message.content
|
|
|
- ? `${message.content}\n\n出错:${error.message}`
|
|
|
- : `出错:${error.message}`,
|
|
|
- isAgentRunning: false,
|
|
|
- }))
|
|
|
- }
|
|
|
-
|
|
|
- const finishAgentSession = (callback?: () => void) => {
|
|
|
- streamSessionGuardRef.current.finish(capturedConvId, sessionId, () => {
|
|
|
- callback?.()
|
|
|
- clearStreaming(capturedConvId)
|
|
|
- delete activeStreamSessionsRef.current[capturedConvId]
|
|
|
- delete abortControllersRef.current[capturedConvId]
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
try {
|
|
|
const record = await new AgentRunner().run(
|
|
|
{
|