Merge branch 'fix-empty-message-content'
This commit is contained in:
@@ -4,12 +4,14 @@ import {
|
|||||||
findEmptyMessages,
|
findEmptyMessages,
|
||||||
findEmptyMessageByIndex,
|
findEmptyMessageByIndex,
|
||||||
findMessageByIndexNeedingThinking,
|
findMessageByIndexNeedingThinking,
|
||||||
|
findMessagesWithEmptyTextParts,
|
||||||
findMessagesWithOrphanThinking,
|
findMessagesWithOrphanThinking,
|
||||||
findMessagesWithThinkingBlocks,
|
findMessagesWithThinkingBlocks,
|
||||||
findMessagesWithThinkingOnly,
|
findMessagesWithThinkingOnly,
|
||||||
injectTextPart,
|
injectTextPart,
|
||||||
prependThinkingPart,
|
prependThinkingPart,
|
||||||
readParts,
|
readParts,
|
||||||
|
replaceEmptyTextParts,
|
||||||
stripThinkingParts,
|
stripThinkingParts,
|
||||||
} from "./storage"
|
} from "./storage"
|
||||||
import type { MessageData } from "./types"
|
import type { MessageData } from "./types"
|
||||||
@@ -222,28 +224,48 @@ async function recoverEmptyContentMessage(
|
|||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const targetIndex = extractMessageIndex(error)
|
const targetIndex = extractMessageIndex(error)
|
||||||
const failedID = failedAssistantMsg.info?.id
|
const failedID = failedAssistantMsg.info?.id
|
||||||
|
let anySuccess = false
|
||||||
|
|
||||||
|
const messagesWithEmptyText = findMessagesWithEmptyTextParts(sessionID)
|
||||||
|
for (const messageID of messagesWithEmptyText) {
|
||||||
|
if (replaceEmptyTextParts(messageID, PLACEHOLDER_TEXT)) {
|
||||||
|
anySuccess = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const thinkingOnlyIDs = findMessagesWithThinkingOnly(sessionID)
|
const thinkingOnlyIDs = findMessagesWithThinkingOnly(sessionID)
|
||||||
for (const messageID of thinkingOnlyIDs) {
|
for (const messageID of thinkingOnlyIDs) {
|
||||||
injectTextPart(sessionID, messageID, PLACEHOLDER_TEXT)
|
if (injectTextPart(sessionID, messageID, PLACEHOLDER_TEXT)) {
|
||||||
|
anySuccess = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetIndex !== null) {
|
if (targetIndex !== null) {
|
||||||
const targetMessageID = findEmptyMessageByIndex(sessionID, targetIndex)
|
const targetMessageID = findEmptyMessageByIndex(sessionID, targetIndex)
|
||||||
if (targetMessageID) {
|
if (targetMessageID) {
|
||||||
return injectTextPart(sessionID, targetMessageID, PLACEHOLDER_TEXT)
|
if (replaceEmptyTextParts(targetMessageID, PLACEHOLDER_TEXT)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (injectTextPart(sessionID, targetMessageID, PLACEHOLDER_TEXT)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failedID) {
|
if (failedID) {
|
||||||
|
if (replaceEmptyTextParts(failedID, PLACEHOLDER_TEXT)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if (injectTextPart(sessionID, failedID, PLACEHOLDER_TEXT)) {
|
if (injectTextPart(sessionID, failedID, PLACEHOLDER_TEXT)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const emptyMessageIDs = findEmptyMessages(sessionID)
|
const emptyMessageIDs = findEmptyMessages(sessionID)
|
||||||
let anySuccess = thinkingOnlyIDs.length > 0
|
|
||||||
for (const messageID of emptyMessageIDs) {
|
for (const messageID of emptyMessageIDs) {
|
||||||
|
if (replaceEmptyTextParts(messageID, PLACEHOLDER_TEXT)) {
|
||||||
|
anySuccess = true
|
||||||
|
}
|
||||||
if (injectTextPart(sessionID, messageID, PLACEHOLDER_TEXT)) {
|
if (injectTextPart(sessionID, messageID, PLACEHOLDER_TEXT)) {
|
||||||
anySuccess = true
|
anySuccess = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,6 +271,55 @@ export function stripThinkingParts(messageID: string): boolean {
|
|||||||
return anyRemoved
|
return anyRemoved
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function replaceEmptyTextParts(messageID: string, replacementText: string): boolean {
|
||||||
|
const partDir = join(PART_STORAGE, messageID)
|
||||||
|
if (!existsSync(partDir)) return false
|
||||||
|
|
||||||
|
let anyReplaced = false
|
||||||
|
for (const file of readdirSync(partDir)) {
|
||||||
|
if (!file.endsWith(".json")) continue
|
||||||
|
try {
|
||||||
|
const filePath = join(partDir, file)
|
||||||
|
const content = readFileSync(filePath, "utf-8")
|
||||||
|
const part = JSON.parse(content) as StoredPart
|
||||||
|
|
||||||
|
if (part.type === "text") {
|
||||||
|
const textPart = part as StoredTextPart
|
||||||
|
if (!textPart.text?.trim()) {
|
||||||
|
textPart.text = replacementText
|
||||||
|
textPart.synthetic = true
|
||||||
|
writeFileSync(filePath, JSON.stringify(textPart, null, 2))
|
||||||
|
anyReplaced = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return anyReplaced
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findMessagesWithEmptyTextParts(sessionID: string): string[] {
|
||||||
|
const messages = readMessages(sessionID)
|
||||||
|
const result: string[] = []
|
||||||
|
|
||||||
|
for (const msg of messages) {
|
||||||
|
const parts = readParts(msg.id)
|
||||||
|
const hasEmptyTextPart = parts.some((p) => {
|
||||||
|
if (p.type !== "text") return false
|
||||||
|
const textPart = p as StoredTextPart
|
||||||
|
return !textPart.text?.trim()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (hasEmptyTextPart) {
|
||||||
|
result.push(msg.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
export function findMessageByIndexNeedingThinking(sessionID: string, targetIndex: number): string | null {
|
export function findMessageByIndexNeedingThinking(sessionID: string, targetIndex: number): string | null {
|
||||||
const messages = readMessages(sessionID)
|
const messages = readMessages(sessionID)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user