fix(server): accept client messageID to enable optimistic message dedup

This commit is contained in:
DoSun 2026-05-11 15:30:37 +08:00
parent d18a2af37d
commit 922bcf7660
2 changed files with 12 additions and 5 deletions

View File

@ -27,6 +27,7 @@ function ssePrompt(
content: string,
c: import('hono').Context,
parts?: Array<Record<string, unknown>>,
messageID?: string,
) {
return streamSSE(c, async stream => {
const startTime = Date.now()
@ -82,7 +83,7 @@ function ssePrompt(
})
try {
await handle.prompt(content, { parts })
await handle.prompt(content, { parts, messageID })
} catch {
if (!resultWritten) {
pendingWrite = pendingWrite.then(() =>
@ -374,6 +375,7 @@ export function createSessionRoutes(
images?: unknown[]
model?: { providerID?: string; modelID?: string }
agent?: string
messageID?: string
}>()
const textContent = body.content ?? body.parts
@ -396,7 +398,7 @@ export function createSessionRoutes(
try { await handle.setAgent(effectiveAgent) } catch {}
}
return ssePrompt(handle, id, content, c, body.parts)
return ssePrompt(handle, id, content, c, body.parts, body.messageID)
})
.post('/session/:sessionID/prompt_async', async c => {
const id = c.req.param('sessionID')
@ -427,6 +429,7 @@ export function createSessionRoutes(
images?: unknown[]
model?: { providerID?: string; modelID?: string }
agent?: string
messageID?: string
}>()
const textContent = body.content ?? body.parts
@ -457,7 +460,8 @@ export function createSessionRoutes(
if (effectiveAgent && effectiveAgent !== handle.agent) {
try { await handle.setAgent(effectiveAgent) } catch {}
}
handle.prompt(content, { parts: body.parts }).catch(() => {})
handle.prompt(content, { parts: body.parts, messageID: body.messageID }).catch(() => {})
} catch {}
})()

View File

@ -468,7 +468,7 @@ export class SessionHandle {
return (response.mcpServers as unknown[]) ?? []
}
async prompt(content: string, _opts?: { parts?: Array<Record<string, unknown>> }): Promise<{ done: boolean; error?: string }> {
async prompt(content: string, opts?: { parts?: Array<Record<string, unknown>>; messageID?: string }): Promise<{ done: boolean; error?: string }> {
if (this._status === 'stopped') {
throw new Error(
`Session ${this.sessionId} is stopped`,
@ -487,10 +487,12 @@ export class SessionHandle {
this.emitBusyStatus()
this.lastActiveAt = Date.now()
const uuid = opts?.messageID ?? crypto.randomUUID()
const userMsg = jsonStringify({
type: 'user',
content,
uuid: crypto.randomUUID(),
uuid,
session_id: this.sessionId,
message: { role: 'user', content },
parent_tool_use_id: null,
@ -499,6 +501,7 @@ export class SessionHandle {
this.emitEvent('message', {
type: 'user',
content,
uuid,
session_id: this.sessionId,
model: this._model ?? '',
provider_id: this._providerId ?? '',