fix(core-agent): stabilize legacy chat timestamps (#1858)

This commit is contained in:
luyua9
2026-07-20 20:52:00 +08:00
committed by GitHub
parent 1f0aeb9fcc
commit 72b4884dbf
2 changed files with 51 additions and 2 deletions
@@ -236,6 +236,47 @@ describe('createChatOrchestratorRuntime', () => {
expect(harness.promptProjections).toHaveLength(1)
})
it('keeps timestamp prefixes stable for legacy user messages without createdAt', async () => {
const harness = createHarness()
const legacyUserMessage = {
role: 'user' as const,
content: 'legacy prompt',
id: 'legacy-user',
}
harness.sessionMessages['session-1'] = [
{ role: 'system', content: 'system prompt', createdAt: 1, id: 'system' },
legacyUserMessage,
]
const firstMessages: Message[][] = []
const secondMessages: Message[][] = []
harness.stream.mockImplementationOnce(async (_model, _chatProvider, messages, options) => {
firstMessages.push(structuredClone(messages))
await options?.onStreamEvent?.({ type: 'finish', finishReason: 'stop' })
})
harness.now.set(new Date(2026, 3, 25, 18, 47).getTime())
await harness.runtime.ingest('first send', {
model: 'gpt-test',
chatProvider: provider,
})
harness.stream.mockImplementationOnce(async (_model, _chatProvider, messages, options) => {
secondMessages.push(structuredClone(messages))
await options?.onStreamEvent?.({ type: 'finish', finishReason: 'stop' })
})
harness.now.set(new Date(2026, 3, 25, 19, 12).getTime())
await harness.runtime.ingest('second send', {
model: 'gpt-test',
chatProvider: provider,
})
expect(firstMessages[0]?.[1]?.content).toBe('[2026-04-25 18:47] legacy prompt')
expect(secondMessages[0]?.[1]?.content).toBe('[2026-04-25 18:47] legacy prompt')
expect(legacyUserMessage.createdAt).toBe(new Date(2026, 3, 25, 18, 47).getTime())
})
/**
* @example
* deps.getSystemPromptSupplement() returns tool guidance.
@@ -386,15 +386,23 @@ export function createChatOrchestratorRuntime(deps: ChatOrchestratorRuntimeDeps)
}
}
function getStablePromptTimestamp(message: ChatHistoryItem, fallbackCreatedAt: number) {
if (typeof message.createdAt === 'number')
return message.createdAt
message.createdAt = fallbackCreatedAt
return fallbackCreatedAt
}
function buildProviderMessages(sessionMessagesForSend: ChatHistoryItem[]) {
const nowTs = now()
return sessionMessagesForSend.map((msg) => {
const { context: _context, id: _id, createdAt, ...withoutContext } = msg
const { context: _context, id: _id, createdAt: _createdAt, ...withoutContext } = msg
const rawMessage = unwrapMessage(withoutContext)
if (rawMessage.role === 'user') {
return prependTextToContent(rawMessage, formatTimePrefix(createdAt ?? nowTs))
return prependTextToContent(rawMessage, formatTimePrefix(getStablePromptTimestamp(msg, nowTs)))
}
if (rawMessage.role === 'assistant') {