blank session cleanup improvements
- make the blank session cleanup system optionally fetch full message histories for each session to better judge if it's blank - make a command that does the deep clean, keep the clean that happens on new session creation shallow
This commit is contained in:
committed by
Alexis Purslane
parent
f633d75005
commit
50676416ed
10
.dir-locals.el
Normal file
10
.dir-locals.el
Normal file
@@ -0,0 +1,10 @@
|
||||
((typescript-ts-mode
|
||||
. ((eglot-workspace-configuration
|
||||
. (:typescript.format (:indentSize 2
|
||||
:tabSize 2
|
||||
:convertTabsToSpaces t
|
||||
:semicolons "remove")
|
||||
:javascript.format (:indentSize 2
|
||||
:tabSize 2
|
||||
:convertTabsToSpaces t
|
||||
:semicolons "remove"))))))
|
||||
@@ -16,6 +16,7 @@ import { showAlertDialog } from "../../stores/alerts"
|
||||
import type { Instance } from "../../types/instance"
|
||||
import type { MessageRecord } from "../../stores/message-v2/types"
|
||||
import { messageStoreBus } from "../../stores/message-v2/bus"
|
||||
import { cleanupBlankSessions } from "../../stores/session-state"
|
||||
|
||||
export interface UseCommandsOptions {
|
||||
preferences: Accessor<Preferences>
|
||||
@@ -142,6 +143,19 @@ export function useCommands(options: UseCommandsOptions) {
|
||||
},
|
||||
})
|
||||
|
||||
commandRegistry.register({
|
||||
id: "cleanup-blank-sessions",
|
||||
label: "Cleanup Blank Sessions",
|
||||
description: "Remove empty sessions from the current instance",
|
||||
category: "Session",
|
||||
keywords: ["cleanup", "blank", "empty", "sessions", "remove", "delete"],
|
||||
action: async () => {
|
||||
const instance = activeInstance()
|
||||
if (!instance) return
|
||||
await cleanupBlankSessions(instance.id, undefined, true)
|
||||
},
|
||||
})
|
||||
|
||||
commandRegistry.register({
|
||||
id: "switch-to-info",
|
||||
label: "Instance Info",
|
||||
|
||||
@@ -407,27 +407,6 @@ async function deleteSession(instanceId: string, sessionId: string): Promise<voi
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanupBlankSessions(instanceId: string, excludeSessionId?: string): Promise<void> {
|
||||
const instanceSessions = sessions().get(instanceId)
|
||||
if (!instanceSessions) return
|
||||
|
||||
const deletionPromises: Promise<void>[] = []
|
||||
|
||||
for (const [sessionId, session] of instanceSessions) {
|
||||
if (sessionId === excludeSessionId) continue
|
||||
if (!isBlankSession(session, instanceId)) continue
|
||||
|
||||
deletionPromises.push(deleteSession(instanceId, sessionId).catch((error) => {
|
||||
console.error(`Failed to delete blank session ${sessionId}:`, error)
|
||||
}))
|
||||
}
|
||||
|
||||
if (deletionPromises.length > 0) {
|
||||
console.log(`Cleaning up ${deletionPromises.length} blank sessions`)
|
||||
await Promise.all(deletionPromises)
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchAgents(instanceId: string): Promise<void> {
|
||||
const instance = instances().get(instanceId)
|
||||
if (!instance || !instance.client) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { createSignal } from "solid-js"
|
||||
|
||||
import type { Session, Agent, Provider } from "../types/session"
|
||||
import { loadMessages, deleteSession } from "./session-api"
|
||||
import { showToastNotification } from "../lib/notifications"
|
||||
|
||||
export interface SessionInfo {
|
||||
cost: number
|
||||
@@ -221,7 +223,7 @@ function getSessionInfo(instanceId: string, sessionId: string): SessionInfo | un
|
||||
return sessionInfoByInstance().get(instanceId)?.get(sessionId)
|
||||
}
|
||||
|
||||
function isBlankSession(session: Session, instanceId: string): boolean {
|
||||
async function isBlankSession(session: Session, instanceId: string, fetchIfNeeded = false): Promise<boolean> {
|
||||
if (session.parentId === null) {
|
||||
// Parent session is only blank if actually blank AND has no children
|
||||
|
||||
@@ -234,7 +236,10 @@ function isBlankSession(session: Session, instanceId: string): boolean {
|
||||
// Subagent
|
||||
|
||||
const loadedSet = messagesLoaded().get(instanceId) || new Set()
|
||||
if (!loadedSet.has(session.id)) return false
|
||||
if (!loadedSet.has(session.id)) {
|
||||
if (!fetchIfNeeded) return false
|
||||
await loadMessages(instanceId, session.id)
|
||||
}
|
||||
|
||||
if (session.messages.length === 0) return true
|
||||
|
||||
@@ -250,10 +255,14 @@ function isBlankSession(session: Session, instanceId: string): boolean {
|
||||
|
||||
// Subagent is blank if last message was NOT a tool call
|
||||
return !lastMessageWasToolCall
|
||||
} else if (session.revert?.messageID) {
|
||||
} else if (!session.title?.includes("subagent") && session.parentId !== null) {
|
||||
// Fork
|
||||
|
||||
const loadedSet = messagesLoaded().get(instanceId) || new Set()
|
||||
if (!loadedSet.has(session.id)) return false
|
||||
if (!loadedSet.has(session.id)) {
|
||||
if (!fetchIfNeeded) return false
|
||||
await loadMessages(instanceId, session.id)
|
||||
}
|
||||
|
||||
if (session.messages.length === 0) return true
|
||||
|
||||
@@ -264,6 +273,36 @@ function isBlankSession(session: Session, instanceId: string): boolean {
|
||||
return false // default to not saying it's blank, just to be safe
|
||||
}
|
||||
|
||||
async function cleanupBlankSessions(instanceId: string, excludeSessionId?: string, fetchIfNeeded = false): Promise<void> {
|
||||
const instanceSessions = sessions().get(instanceId)
|
||||
if (!instanceSessions) return
|
||||
|
||||
const cleanupPromises = Array.from(instanceSessions)
|
||||
.filter(([sessionId]) => sessionId !== excludeSessionId)
|
||||
.map(async ([sessionId, session]) => {
|
||||
const isBlank = await isBlankSession(session, instanceId, fetchIfNeeded)
|
||||
if (!isBlank) return false
|
||||
|
||||
await deleteSession(instanceId, sessionId).catch((error: Error) => {
|
||||
console.error(`Failed to delete blank session ${sessionId}:`, error)
|
||||
})
|
||||
return true
|
||||
})
|
||||
|
||||
if (cleanupPromises.length > 0) {
|
||||
console.log(`Cleaning up ${cleanupPromises.length} blank sessions`)
|
||||
const deletionResults = await Promise.all(cleanupPromises)
|
||||
const deletedCount = deletionResults.filter(Boolean).length
|
||||
|
||||
if (deletedCount > 0) {
|
||||
showToastNotification({
|
||||
message: `Cleaned up ${deletedCount} blank session${deletedCount === 1 ? '' : 's'}`,
|
||||
variant: "info"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
sessions,
|
||||
setSessions,
|
||||
@@ -303,4 +342,5 @@ export {
|
||||
isSessionMessagesLoading,
|
||||
getSessionInfo,
|
||||
isBlankSession,
|
||||
cleanupBlankSessions,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user