Fix peer chat queue sync
This commit is contained in:
@@ -57,6 +57,7 @@ export interface RunEvent {
|
|||||||
role?: string
|
role?: string
|
||||||
content?: string
|
content?: string
|
||||||
timestamp?: number
|
timestamp?: number
|
||||||
|
queued?: boolean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1887,18 +1887,29 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
resumeServerWorkingRun(sid, true)
|
resumeServerWorkingRun(sid, true)
|
||||||
return
|
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)
|
const timestamp = typeof peer?.timestamp === 'number' && Number.isFinite(peer.timestamp)
|
||||||
? Math.round(peer.timestamp * 1000)
|
? Math.round(peer.timestamp * 1000)
|
||||||
: Date.now()
|
: Date.now()
|
||||||
|
|
||||||
addMessage(sid, {
|
const message: Message = {
|
||||||
id: messageId || uid(),
|
id: messageId || uid(),
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content,
|
content,
|
||||||
timestamp,
|
timestamp,
|
||||||
})
|
queued: !!peer?.queued,
|
||||||
updateSessionTitle(sid)
|
}
|
||||||
|
if (peer?.queued) {
|
||||||
|
enqueueUserMessage(sid, message)
|
||||||
|
} else {
|
||||||
|
addMessage(sid, message)
|
||||||
|
updateSessionTitle(sid)
|
||||||
|
}
|
||||||
serverWorking.value.add(sid)
|
serverWorking.value.add(sid)
|
||||||
resumeServerWorkingRun(sid, true)
|
resumeServerWorkingRun(sid, true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export async function loadSessionStateFromDb(sid: string, _sessionMap: Map<strin
|
|||||||
export async function handleApiRun(
|
export async function handleApiRun(
|
||||||
nsp: ReturnType<Server['of']>,
|
nsp: ReturnType<Server['of']>,
|
||||||
socket: Socket,
|
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,
|
profile: string,
|
||||||
sessionMap: Map<string, SessionState>,
|
sessionMap: Map<string, SessionState>,
|
||||||
skipUserMessage = false,
|
skipUserMessage = false,
|
||||||
@@ -133,7 +133,7 @@ export async function handleApiRun(
|
|||||||
content: inputStr,
|
content: inputStr,
|
||||||
timestamp: now,
|
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 {
|
} else {
|
||||||
const inputStr = contentBlocksToString(input)
|
const inputStr = contentBlocksToString(input)
|
||||||
state.messages.push({
|
state.messages.push({
|
||||||
@@ -155,15 +155,21 @@ export async function handleApiRun(
|
|||||||
content: inputStr,
|
content: inputStr,
|
||||||
timestamp: now,
|
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}`)
|
socket.join(`session:${session_id}`)
|
||||||
if (peerUserMessage) {
|
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',
|
event: 'run.peer_user_message',
|
||||||
session_id,
|
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(
|
export async function handleBridgeRun(
|
||||||
nsp: ReturnType<Server['of']>,
|
nsp: ReturnType<Server['of']>,
|
||||||
socket: Socket,
|
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,
|
profile: string,
|
||||||
sessionMap: Map<string, SessionState>,
|
sessionMap: Map<string, SessionState>,
|
||||||
bridge: AgentBridgeClient,
|
bridge: AgentBridgeClient,
|
||||||
@@ -181,11 +181,14 @@ export async function handleBridgeRun(
|
|||||||
})
|
})
|
||||||
|
|
||||||
socket.join(`session:${session_id}`)
|
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',
|
event: 'run.peer_user_message',
|
||||||
session_id,
|
session_id,
|
||||||
message: {
|
message: {
|
||||||
id: messageId,
|
id: data.queue_id || messageId,
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: inputStr,
|
content: inputStr,
|
||||||
timestamp: now,
|
timestamp: now,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { handleBridgeRun } from './handle-bridge-run'
|
|||||||
import { handleAbort } from './abort'
|
import { handleAbort } from './abort'
|
||||||
import { getOrCreateSession } from './compression'
|
import { getOrCreateSession } from './compression'
|
||||||
import { handleSessionCommand, isSessionCommand, parseSessionCommand } from './session-command'
|
import { handleSessionCommand, isSessionCommand, parseSessionCommand } from './session-command'
|
||||||
|
import { contentBlocksToString } from './content-blocks'
|
||||||
import type { ContentBlock, QueuedRun, SessionState } from './types'
|
import type { ContentBlock, QueuedRun, SessionState } from './types'
|
||||||
import { authenticateUserToken, isAuthEnabled, type AuthenticatedUser } from '../../../middleware/user-auth'
|
import { authenticateUserToken, isAuthEnabled, type AuthenticatedUser } from '../../../middleware/user-auth'
|
||||||
import { userCanAccessProfile } from '../../../db/hermes/users-store'
|
import { userCanAccessProfile } from '../../../db/hermes/users-store'
|
||||||
@@ -146,8 +147,9 @@ export class ChatRunSocket {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (state.isWorking) {
|
if (state.isWorking) {
|
||||||
|
const queueId = data.queue_id || `queue_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`
|
||||||
state.queue.push({
|
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,
|
input: data.input,
|
||||||
model: data.model,
|
model: data.model,
|
||||||
provider: data.provider,
|
provider: data.provider,
|
||||||
@@ -155,6 +157,18 @@ export class ChatRunSocket {
|
|||||||
instructions: data.instructions,
|
instructions: data.instructions,
|
||||||
profile: runProfile,
|
profile: runProfile,
|
||||||
source,
|
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', {
|
this.nsp.to(`session:${data.session_id}`).emit('run.queued', {
|
||||||
event: 'run.queued',
|
event: 'run.queued',
|
||||||
@@ -249,6 +263,8 @@ export class ChatRunSocket {
|
|||||||
model_groups?: Array<{ provider: string; models: string[] }>
|
model_groups?: Array<{ provider: string; models: string[] }>
|
||||||
instructions?: string
|
instructions?: string
|
||||||
source?: string
|
source?: string
|
||||||
|
queue_id?: string
|
||||||
|
peerExcludeSocketId?: string
|
||||||
},
|
},
|
||||||
profile: string,
|
profile: string,
|
||||||
skipUserMessage = false,
|
skipUserMessage = false,
|
||||||
@@ -336,6 +352,8 @@ export class ChatRunSocket {
|
|||||||
model_groups: next.model_groups,
|
model_groups: next.model_groups,
|
||||||
instructions: next.instructions,
|
instructions: next.instructions,
|
||||||
source: next.source,
|
source: next.source,
|
||||||
|
queue_id: next.queue_id,
|
||||||
|
peerExcludeSocketId: next.originSocketId,
|
||||||
}, next.profile || fallbackProfile, true)
|
}, next.profile || fallbackProfile, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ export async function handleSessionCommand(
|
|||||||
instructions: ctx.instructions,
|
instructions: ctx.instructions,
|
||||||
profile: ctx.profile,
|
profile: ctx.profile,
|
||||||
source: 'cli',
|
source: 'cli',
|
||||||
|
originSocketId: ctx.socket.id,
|
||||||
})
|
})
|
||||||
emitToSession(ctx.nsp, ctx.socket, sessionId, 'run.queued', {
|
emitToSession(ctx.nsp, ctx.socket, sessionId, 'run.queued', {
|
||||||
event: 'run.queued',
|
event: 'run.queued',
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export interface QueuedRun {
|
|||||||
instructions?: string
|
instructions?: string
|
||||||
profile: string
|
profile: string
|
||||||
source?: ChatRunSource
|
source?: ChatRunSource
|
||||||
|
originSocketId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SessionState {
|
export interface SessionState {
|
||||||
|
|||||||
Reference in New Issue
Block a user