Fix peer chat queue sync

This commit is contained in:
Codex
2026-05-23 19:51:12 +08:00
committed by ekko
parent 7b05731d44
commit 238dbb507e
7 changed files with 53 additions and 12 deletions
+1
View File
@@ -57,6 +57,7 @@ export interface RunEvent {
role?: string
content?: string
timestamp?: number
queued?: boolean
}
}
+14 -3
View File
@@ -1887,18 +1887,29 @@ export const useChatStore = defineStore('chat', () => {
resumeServerWorkingRun(sid, true)
return
}
if (messageId && (queuedUserMessages.value.get(sid) || []).some(msg => msg.id === messageId)) {
serverWorking.value.add(sid)
resumeServerWorkingRun(sid, true)
return
}
const timestamp = typeof peer?.timestamp === 'number' && Number.isFinite(peer.timestamp)
? Math.round(peer.timestamp * 1000)
: Date.now()
addMessage(sid, {
const message: Message = {
id: messageId || uid(),
role: 'user',
content,
timestamp,
})
updateSessionTitle(sid)
queued: !!peer?.queued,
}
if (peer?.queued) {
enqueueUserMessage(sid, message)
} else {
addMessage(sid, message)
updateSessionTitle(sid)
}
serverWorking.value.add(sid)
resumeServerWorkingRun(sid, true)
}
@@ -68,7 +68,7 @@ export async function loadSessionStateFromDb(sid: string, _sessionMap: Map<strin
export async function handleApiRun(
nsp: ReturnType<Server['of']>,
socket: Socket,
data: { input: string | ContentBlock[]; session_id?: string; model?: string; provider?: string; instructions?: string; source?: string },
data: { input: string | ContentBlock[]; session_id?: string; model?: string; provider?: string; instructions?: string; source?: string; queue_id?: string; peerExcludeSocketId?: string },
profile: string,
sessionMap: Map<string, SessionState>,
skipUserMessage = false,
@@ -133,7 +133,7 @@ export async function handleApiRun(
content: inputStr,
timestamp: now,
})
peerUserMessage = { id: messageId, role: 'user', content: inputStr, timestamp: now }
peerUserMessage = { id: data.queue_id ? undefined : messageId, role: 'user', content: inputStr, timestamp: now }
} else {
const inputStr = contentBlocksToString(input)
state.messages.push({
@@ -155,15 +155,21 @@ export async function handleApiRun(
content: inputStr,
timestamp: now,
})
peerUserMessage = { id: messageId, role: 'user', content: inputStr, timestamp: now }
peerUserMessage = { id: data.queue_id ? undefined : messageId, role: 'user', content: inputStr, timestamp: now }
}
socket.join(`session:${session_id}`)
if (peerUserMessage) {
socket.to(`session:${session_id}`).emit('run.peer_user_message', {
const target = data.peerExcludeSocketId
? nsp.to(`session:${session_id}`).except(data.peerExcludeSocketId)
: socket.to(`session:${session_id}`)
target.emit('run.peer_user_message', {
event: 'run.peer_user_message',
session_id,
message: peerUserMessage,
message: {
...peerUserMessage,
id: data.queue_id || peerUserMessage.id,
},
})
}
}
@@ -94,7 +94,7 @@ function cacheBridgeContext(state: SessionState, data: Record<string, unknown> |
export async function handleBridgeRun(
nsp: ReturnType<Server['of']>,
socket: Socket,
data: { input: string | ContentBlock[]; session_id?: string; model?: string; provider?: string; model_groups?: RunModelGroup[]; instructions?: string; source?: string },
data: { input: string | ContentBlock[]; session_id?: string; model?: string; provider?: string; model_groups?: RunModelGroup[]; instructions?: string; source?: string; queue_id?: string; peerExcludeSocketId?: string },
profile: string,
sessionMap: Map<string, SessionState>,
bridge: AgentBridgeClient,
@@ -181,11 +181,14 @@ export async function handleBridgeRun(
})
socket.join(`session:${session_id}`)
socket.to(`session:${session_id}`).emit('run.peer_user_message', {
const peerTarget = data.peerExcludeSocketId
? nsp.to(`session:${session_id}`).except(data.peerExcludeSocketId)
: socket.to(`session:${session_id}`)
peerTarget.emit('run.peer_user_message', {
event: 'run.peer_user_message',
session_id,
message: {
id: messageId,
id: data.queue_id || messageId,
role: 'user',
content: inputStr,
timestamp: now,
@@ -19,6 +19,7 @@ import { handleBridgeRun } from './handle-bridge-run'
import { handleAbort } from './abort'
import { getOrCreateSession } from './compression'
import { handleSessionCommand, isSessionCommand, parseSessionCommand } from './session-command'
import { contentBlocksToString } from './content-blocks'
import type { ContentBlock, QueuedRun, SessionState } from './types'
import { authenticateUserToken, isAuthEnabled, type AuthenticatedUser } from '../../../middleware/user-auth'
import { userCanAccessProfile } from '../../../db/hermes/users-store'
@@ -146,8 +147,9 @@ export class ChatRunSocket {
return
}
if (state.isWorking) {
const queueId = data.queue_id || `queue_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`
state.queue.push({
queue_id: data.queue_id || `queue_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
queue_id: queueId,
input: data.input,
model: data.model,
provider: data.provider,
@@ -155,6 +157,18 @@ export class ChatRunSocket {
instructions: data.instructions,
profile: runProfile,
source,
originSocketId: socket.id,
})
socket.to(`session:${data.session_id}`).emit('run.peer_user_message', {
event: 'run.peer_user_message',
session_id: data.session_id,
message: {
id: queueId,
role: 'user',
content: contentBlocksToString(data.input),
timestamp: Math.floor(Date.now() / 1000),
queued: true,
},
})
this.nsp.to(`session:${data.session_id}`).emit('run.queued', {
event: 'run.queued',
@@ -249,6 +263,8 @@ export class ChatRunSocket {
model_groups?: Array<{ provider: string; models: string[] }>
instructions?: string
source?: string
queue_id?: string
peerExcludeSocketId?: string
},
profile: string,
skipUserMessage = false,
@@ -336,6 +352,8 @@ export class ChatRunSocket {
model_groups: next.model_groups,
instructions: next.instructions,
source: next.source,
queue_id: next.queue_id,
peerExcludeSocketId: next.originSocketId,
}, next.profile || fallbackProfile, true)
}
@@ -157,6 +157,7 @@ export async function handleSessionCommand(
instructions: ctx.instructions,
profile: ctx.profile,
source: 'cli',
originSocketId: ctx.socket.id,
})
emitToSession(ctx.nsp, ctx.socket, sessionId, 'run.queued', {
event: 'run.queued',
@@ -34,6 +34,7 @@ export interface QueuedRun {
instructions?: string
profile: string
source?: ChatRunSource
originSocketId?: string
}
export interface SessionState {