feat(conversation): replicate in-place user message editing (TODO 03)
This commit is contained in:
1 parent
ed31a7c1b4
commit
ee51208931
18 files changed
+992
-67
No files matched your search
+9
-2
@@ -29,7 +29,7 @@ import { createInteractionBroker, respondToInteraction } from './interaction-bro
|
||||
import { attachmentPrompt, commitAttachments, getAttachment, removeAttachment, stageAttachment, stageAttachmentPath } from './attachments'
|
||||
import { transcribeAudio } from './speech'
|
||||
import { getRevertChanges } from '@shared/revert'
|
||||
import { restoreWorkspaceFiles } from './workspace-revert'
|
||||
import { restoreWorkspaceFiles, rollbackEditedArtifacts } from './workspace-revert'
|
||||
import { assistantWireHistory } from './agent/history'
|
||||
import * as models from './models'
|
||||
import * as workspaces from './workspaces'
|
||||
@@ -563,7 +563,10 @@ export function registerIpc(getWindow: () => BrowserWindow | null): void {
|
||||
}
|
||||
const target = history[targetIndex]
|
||||
if (!target || target.role !== 'user') throw new Error('未找到对应用户消息')
|
||||
if (kernel) {
|
||||
// 原版编辑语义(userMessage.edit.hint):产物回退至此消息前版本,再从此处重新开始对话。
|
||||
const editUndo = payload.action === 'edit' ? await rollbackEditedArtifacts(workspaceRoot, history, payload.fromMessageId!) : undefined
|
||||
try {
|
||||
if (kernel) {
|
||||
if (target.nativeSessionPath && target.nativeSessionPath !== ompSessionPath(sessionId)) throw new Error('这条历史消息没有当前 OMP 会话的分支记录')
|
||||
let entryId = target.nativeEntryId
|
||||
if (!entryId) {
|
||||
@@ -588,6 +591,10 @@ export function registerIpc(getWindow: () => BrowserWindow | null): void {
|
||||
}
|
||||
const entry = ompKernels.get(sessionId)
|
||||
if (entry && entryId) entry.appliedBranchId = entryId
|
||||
}
|
||||
} catch (error) {
|
||||
if (editUndo) await editUndo().catch(() => undefined)
|
||||
throw error
|
||||
}
|
||||
history = history.slice(0, targetIndex)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import { promises as fs } from 'node:fs'
|
||||
import { dirname, isAbsolute, relative, resolve, sep, join } from 'node:path'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import type { RevertChange } from '@shared/revert'
|
||||
import { getRevertChanges } from '@shared/revert'
|
||||
import type { ChatMessage } from '@shared/types'
|
||||
|
||||
async function replaceFile(path: string, content: string | null): Promise<void> {
|
||||
if (content === null) { await fs.unlink(path); return }
|
||||
@@ -33,3 +35,14 @@ export async function restoreWorkspaceFiles(workspace: string, changes: RevertCh
|
||||
} catch (error) { await undo(); throw error }
|
||||
return undo
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑提交前的产物回退(原版 userMessage.edit.hint:产物回退至此消息前版本)。
|
||||
* 返回撤销函数;该消息之后没有可回退的写入时返回 undefined。
|
||||
* 记录不完整时由 getRevertChanges 抛错,调用方应中止提交而不是静默保留文件修改。
|
||||
*/
|
||||
export async function rollbackEditedArtifacts(workspace: string, messages: ChatMessage[], userMessageId: string): Promise<(() => Promise<void>) | undefined> {
|
||||
const changes = getRevertChanges(messages, userMessageId)
|
||||
if (!changes.length) return undefined
|
||||
return restoreWorkspaceFiles(workspace, changes)
|
||||
}
|
||||
Reference in new issue
Block a user