Fix Native Mode Sessions: implemented fork, revert, and sync for native sessions

This commit is contained in:
Gemini AI
2025-12-27 10:40:45 +04:00
Unverified
parent 610057c058
commit ad76ade6ab
5 changed files with 405 additions and 83 deletions

View File

@@ -105,6 +105,42 @@ export function registerNativeSessionsRoutes(app: FastifyInstance, deps: NativeS
}
})
// Fork a session
app.post<{
Params: { workspaceId: string; sessionId: string }
}>("/api/native/workspaces/:workspaceId/sessions/:sessionId/fork", async (request, reply) => {
try {
const session = await sessionManager.forkSession(
request.params.workspaceId,
request.params.sessionId
)
return { session }
} catch (error) {
logger.error({ error }, "Failed to fork session")
reply.code(500)
return { error: "Failed to fork session" }
}
})
// Revert a session
app.post<{
Params: { workspaceId: string; sessionId: string }
Body: { messageId?: string }
}>("/api/native/workspaces/:workspaceId/sessions/:sessionId/revert", async (request, reply) => {
try {
const session = await sessionManager.revert(
request.params.workspaceId,
request.params.sessionId,
request.body.messageId
)
return { session }
} catch (error) {
logger.error({ error }, "Failed to revert session")
reply.code(500)
return { error: "Failed to revert session" }
}
})
// Delete a session
app.delete<{ Params: { workspaceId: string; sessionId: string } }>("/api/native/workspaces/:workspaceId/sessions/:sessionId", async (request, reply) => {
try {

View File

@@ -200,6 +200,54 @@ export class NativeSessionManager {
return true
}
async forkSession(workspaceId: string, sessionId: string): Promise<Session> {
const store = await this.loadStore(workspaceId)
const original = store.sessions[sessionId]
if (!original) throw new Error(`Session not found: ${sessionId}`)
const now = Date.now()
const forked: Session = {
...original,
id: ulid(),
title: original.title ? `${original.title} (fork)` : "Forked Session",
parentId: original.parentId || original.id,
createdAt: now,
updatedAt: now,
messageIds: [...original.messageIds], // Shallow copy of message IDs
}
store.sessions[forked.id] = forked
await this.saveStore(workspaceId)
return forked
}
async revert(workspaceId: string, sessionId: string, messageId?: string): Promise<Session> {
const store = await this.loadStore(workspaceId)
const session = store.sessions[sessionId]
if (!session) throw new Error(`Session not found: ${sessionId}`)
if (!messageId) {
// Revert last message
if (session.messageIds.length > 0) {
const lastId = session.messageIds.pop()
if (lastId) delete store.messages[lastId]
}
} else {
// Revert to specific message
const index = session.messageIds.indexOf(messageId)
if (index !== -1) {
const toDelete = session.messageIds.splice(index + 1)
for (const id of toDelete) {
delete store.messages[id]
}
}
}
session.updatedAt = Date.now()
await this.saveStore(workspaceId)
return session
}
// Message operations
async getSessionMessages(workspaceId: string, sessionId: string): Promise<SessionMessage[]> {