fix(chat): keep messages chronological across ID rollover
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import type { Message, Part } from "@opencode-ai/sdk/v2/client"
|
||||
import { mergeMessages } from "./optimistic"
|
||||
import type { SessionMaterializationReason } from "./event-reducer"
|
||||
import { sortMessagesChronologically } from "./message-ordering"
|
||||
|
||||
const cmp = (a: string, b: string) => (a < b ? -1 : a > b ? 1 : 0)
|
||||
const STREAMING_PART_FIELDS = ["text", "output"] as const
|
||||
const ACTIVE_TOOL_STATUSES = new Set(["pending", "running"])
|
||||
const FINAL_TOOL_STATUSES = new Set(["completed", "error", "aborted", "failed", "timeout", "cancelled"])
|
||||
@@ -93,10 +93,9 @@ export function getStaleRunningToolMessageID(
|
||||
return undefined
|
||||
}
|
||||
|
||||
function sortParts(parts: Part[], skipPartTypes: ReadonlySet<string>) {
|
||||
function filterMaterializedParts(parts: Part[], skipPartTypes: ReadonlySet<string>): Part[] {
|
||||
return parts
|
||||
.filter((part) => !!part?.id && !skipPartTypes.has(part.type))
|
||||
.sort((a, b) => cmp(a.id, b.id))
|
||||
}
|
||||
|
||||
function haveEquivalentPartSnapshots(left: Part[] | undefined, right: Part[]): boolean {
|
||||
@@ -252,7 +251,7 @@ function mergeMaterializedParts(
|
||||
)
|
||||
if (missingLiveParts.length === 0) return mergedParts
|
||||
|
||||
return [...mergedParts, ...missingLiveParts].sort((a, b) => cmp(a.id, b.id))
|
||||
return [...mergedParts, ...missingLiveParts]
|
||||
}
|
||||
|
||||
export function materializeSessionSnapshots(
|
||||
@@ -262,10 +261,13 @@ export function materializeSessionSnapshots(
|
||||
options: MaterializeSessionSnapshotsOptions = {},
|
||||
): MaterializeSessionSnapshotsResult {
|
||||
const skipPartTypes = options.skipPartTypes ?? new Set<string>()
|
||||
const snapshots = records
|
||||
.filter((record) => !!record?.info?.id)
|
||||
.sort((left, right) => cmp(left.info.id, right.info.id))
|
||||
const nextMessages = snapshots.map((record) => record.info)
|
||||
const recordsByMessageID = new Map(
|
||||
records
|
||||
.filter((record) => !!record?.info?.id)
|
||||
.map((record) => [record.info.id, record] as const),
|
||||
)
|
||||
const nextMessages = sortMessagesChronologically([...recordsByMessageID.values()].map((record) => record.info))
|
||||
const snapshots = nextMessages.map((message) => recordsByMessageID.get(message.id)!)
|
||||
const existingMessages = state.message[sessionID]
|
||||
const currentMessages = existingMessages ?? []
|
||||
const messages = mergeMessages(currentMessages, nextMessages)
|
||||
@@ -283,7 +285,7 @@ export function materializeSessionSnapshots(
|
||||
const existing = nextPartState[messageID]
|
||||
const nextParts = mergeMaterializedParts(
|
||||
existing,
|
||||
sortParts(record.parts ?? [], skipPartTypes),
|
||||
filterMaterializedParts(record.parts ?? [], skipPartTypes),
|
||||
skipPartTypes,
|
||||
isAssistant,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user