fix: complete session persistence overhaul (Codex 5.2)
Some checks failed
Release Binaries / release (push) Has been cancelled
Some checks failed
Release Binaries / release (push) Has been cancelled
1. Implemented auto-selection of tasks in MultiXV2 to prevent empty initial state. 2. Added force-loading logic for task session messages with debouncing. 3. Updated session-actions to return full assistant text and immediately persist native messages. 4. Fixed caching logic in instance-shell2 to retain active task sessions in memory.
This commit is contained in:
@@ -209,6 +209,51 @@ export function registerNativeSessionsRoutes(app: FastifyInstance, deps: NativeS
|
||||
}
|
||||
})
|
||||
|
||||
// Append messages to a session (client-side persistence)
|
||||
app.post<{
|
||||
Params: { workspaceId: string; sessionId: string }
|
||||
Body: {
|
||||
messages: Array<{
|
||||
id?: string
|
||||
role: "user" | "assistant" | "system" | "tool"
|
||||
content?: string
|
||||
createdAt?: number
|
||||
updatedAt?: number
|
||||
status?: "pending" | "streaming" | "completed" | "error"
|
||||
}>
|
||||
}
|
||||
}>("/api/native/workspaces/:workspaceId/sessions/:sessionId/messages", async (request, reply) => {
|
||||
const { workspaceId, sessionId } = request.params
|
||||
const payload = request.body?.messages
|
||||
if (!Array.isArray(payload)) {
|
||||
reply.code(400)
|
||||
return { error: "messages array is required" }
|
||||
}
|
||||
|
||||
try {
|
||||
const results: SessionMessage[] = []
|
||||
for (const entry of payload) {
|
||||
if (!entry || typeof entry.role !== "string") {
|
||||
continue
|
||||
}
|
||||
const saved = await sessionManager.addMessage(workspaceId, sessionId, {
|
||||
id: entry.id,
|
||||
role: entry.role,
|
||||
content: entry.content,
|
||||
createdAt: entry.createdAt,
|
||||
updatedAt: entry.updatedAt,
|
||||
status: entry.status,
|
||||
})
|
||||
results.push(saved)
|
||||
}
|
||||
return { messages: results }
|
||||
} catch (error) {
|
||||
logger.error({ error }, "Failed to append messages")
|
||||
reply.code(500)
|
||||
return { error: "Failed to append messages" }
|
||||
}
|
||||
})
|
||||
|
||||
// Add a message (user prompt) and get streaming response
|
||||
app.post<{
|
||||
Params: { workspaceId: string; sessionId: string }
|
||||
|
||||
@@ -27,6 +27,12 @@ export interface SessionMessage {
|
||||
status?: "pending" | "streaming" | "completed" | "error"
|
||||
}
|
||||
|
||||
type IncomingSessionMessage = Omit<SessionMessage, "id" | "sessionId" | "createdAt" | "updatedAt"> & {
|
||||
id?: string
|
||||
createdAt?: number
|
||||
updatedAt?: number
|
||||
}
|
||||
|
||||
export interface MessagePart {
|
||||
type: "text" | "tool_call" | "tool_result" | "thinking" | "code"
|
||||
content?: string
|
||||
@@ -260,23 +266,29 @@ export class NativeSessionManager {
|
||||
.filter((msg): msg is SessionMessage => msg !== undefined)
|
||||
}
|
||||
|
||||
async addMessage(workspaceId: string, sessionId: string, message: Omit<SessionMessage, "id" | "sessionId" | "createdAt" | "updatedAt">): Promise<SessionMessage> {
|
||||
async addMessage(workspaceId: string, sessionId: string, message: IncomingSessionMessage): Promise<SessionMessage> {
|
||||
const store = await this.loadStore(workspaceId)
|
||||
const session = store.sessions[sessionId]
|
||||
if (!session) throw new Error(`Session not found: ${sessionId}`)
|
||||
|
||||
const now = Date.now()
|
||||
const messageId = message.id ?? ulid()
|
||||
const createdAt = typeof message.createdAt === "number" ? message.createdAt : now
|
||||
const updatedAt = typeof message.updatedAt === "number" ? message.updatedAt : createdAt
|
||||
|
||||
const newMessage: SessionMessage = {
|
||||
...message,
|
||||
id: ulid(),
|
||||
id: messageId,
|
||||
sessionId,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
}
|
||||
|
||||
store.messages[newMessage.id] = newMessage
|
||||
session.messageIds.push(newMessage.id)
|
||||
session.updatedAt = now
|
||||
if (!session.messageIds.includes(newMessage.id)) {
|
||||
session.messageIds.push(newMessage.id)
|
||||
}
|
||||
session.updatedAt = updatedAt
|
||||
|
||||
await this.saveStore(workspaceId)
|
||||
return newMessage
|
||||
|
||||
Reference in New Issue
Block a user