feat(session-manager): implement session management tools
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -27,9 +27,48 @@ function withTimeout<T>(promise: Promise<T>, ms: number, operation: string): Pro
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSessionManagerTools(ctx: PluginInput): Record<string, ToolDefinition> {
|
type SessionManagerToolDeps = {
|
||||||
|
getAllSessions: typeof getAllSessions
|
||||||
|
getMainSessions: typeof getMainSessions
|
||||||
|
getSessionInfo: typeof getSessionInfo
|
||||||
|
readSessionMessages: typeof readSessionMessages
|
||||||
|
readSessionTodos: typeof readSessionTodos
|
||||||
|
sessionExists: typeof sessionExists
|
||||||
|
setStorageClient: typeof setStorageClient
|
||||||
|
filterSessionsByDate: typeof filterSessionsByDate
|
||||||
|
formatSessionInfo: typeof formatSessionInfo
|
||||||
|
formatSessionList: typeof formatSessionList
|
||||||
|
formatSessionMessages: typeof formatSessionMessages
|
||||||
|
formatSearchResults: typeof formatSearchResults
|
||||||
|
searchInSession: typeof searchInSession
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultSessionManagerToolDeps: SessionManagerToolDeps = {
|
||||||
|
getAllSessions,
|
||||||
|
getMainSessions,
|
||||||
|
getSessionInfo,
|
||||||
|
readSessionMessages,
|
||||||
|
readSessionTodos,
|
||||||
|
sessionExists,
|
||||||
|
setStorageClient,
|
||||||
|
filterSessionsByDate,
|
||||||
|
formatSessionInfo,
|
||||||
|
formatSessionList,
|
||||||
|
formatSessionMessages,
|
||||||
|
formatSearchResults,
|
||||||
|
searchInSession,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSessionManagerTools(
|
||||||
|
ctx: PluginInput,
|
||||||
|
deps: Partial<SessionManagerToolDeps> = {},
|
||||||
|
): Record<string, ToolDefinition> {
|
||||||
|
const resolvedDeps: SessionManagerToolDeps = {
|
||||||
|
...defaultSessionManagerToolDeps,
|
||||||
|
...deps,
|
||||||
|
}
|
||||||
// Initialize storage client for SDK-based operations (beta mode)
|
// Initialize storage client for SDK-based operations (beta mode)
|
||||||
setStorageClient(ctx.client)
|
resolvedDeps.setStorageClient(ctx.client)
|
||||||
|
|
||||||
const session_list: ToolDefinition = tool({
|
const session_list: ToolDefinition = tool({
|
||||||
description: SESSION_LIST_DESCRIPTION,
|
description: SESSION_LIST_DESCRIPTION,
|
||||||
@@ -42,18 +81,18 @@ export function createSessionManagerTools(ctx: PluginInput): Record<string, Tool
|
|||||||
execute: async (args: SessionListArgs, _context) => {
|
execute: async (args: SessionListArgs, _context) => {
|
||||||
try {
|
try {
|
||||||
const directory = args.project_path ?? ctx.directory
|
const directory = args.project_path ?? ctx.directory
|
||||||
let sessions = await getMainSessions({ directory })
|
let sessions = await resolvedDeps.getMainSessions({ directory })
|
||||||
let sessionIDs = sessions.map((s) => s.id)
|
let sessionIDs = sessions.map((s) => s.id)
|
||||||
|
|
||||||
if (args.from_date || args.to_date) {
|
if (args.from_date || args.to_date) {
|
||||||
sessionIDs = await filterSessionsByDate(sessionIDs, args.from_date, args.to_date)
|
sessionIDs = await resolvedDeps.filterSessionsByDate(sessionIDs, args.from_date, args.to_date)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.limit && args.limit > 0) {
|
if (args.limit && args.limit > 0) {
|
||||||
sessionIDs = sessionIDs.slice(0, args.limit)
|
sessionIDs = sessionIDs.slice(0, args.limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
return await formatSessionList(sessionIDs)
|
return await resolvedDeps.formatSessionList(sessionIDs)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
||||||
}
|
}
|
||||||
@@ -70,11 +109,11 @@ export function createSessionManagerTools(ctx: PluginInput): Record<string, Tool
|
|||||||
},
|
},
|
||||||
execute: async (args: SessionReadArgs, _context) => {
|
execute: async (args: SessionReadArgs, _context) => {
|
||||||
try {
|
try {
|
||||||
if (!(await sessionExists(args.session_id))) {
|
if (!(await resolvedDeps.sessionExists(args.session_id))) {
|
||||||
return `Session not found: ${args.session_id}`
|
return `Session not found: ${args.session_id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
let messages = await readSessionMessages(args.session_id)
|
let messages = await resolvedDeps.readSessionMessages(args.session_id)
|
||||||
|
|
||||||
if (messages.length === 0) {
|
if (messages.length === 0) {
|
||||||
return `Session not found: ${args.session_id}`
|
return `Session not found: ${args.session_id}`
|
||||||
@@ -84,9 +123,9 @@ export function createSessionManagerTools(ctx: PluginInput): Record<string, Tool
|
|||||||
messages = messages.slice(0, args.limit)
|
messages = messages.slice(0, args.limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
const todos = args.include_todos ? await readSessionTodos(args.session_id) : undefined
|
const todos = args.include_todos ? await resolvedDeps.readSessionTodos(args.session_id) : undefined
|
||||||
|
|
||||||
return formatSessionMessages(messages, args.include_todos, todos)
|
return resolvedDeps.formatSessionMessages(messages, args.include_todos, todos)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
||||||
}
|
}
|
||||||
@@ -107,10 +146,10 @@ export function createSessionManagerTools(ctx: PluginInput): Record<string, Tool
|
|||||||
|
|
||||||
const searchOperation = async (): Promise<SearchResult[]> => {
|
const searchOperation = async (): Promise<SearchResult[]> => {
|
||||||
if (args.session_id) {
|
if (args.session_id) {
|
||||||
return searchInSession(args.session_id, args.query, args.case_sensitive, resultLimit)
|
return resolvedDeps.searchInSession(args.session_id, args.query, args.case_sensitive, resultLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
const allSessions = await getAllSessions()
|
const allSessions = await resolvedDeps.getAllSessions()
|
||||||
const sessionsToScan = allSessions.slice(0, MAX_SESSIONS_TO_SCAN)
|
const sessionsToScan = allSessions.slice(0, MAX_SESSIONS_TO_SCAN)
|
||||||
|
|
||||||
const allResults: SearchResult[] = []
|
const allResults: SearchResult[] = []
|
||||||
@@ -118,7 +157,7 @@ export function createSessionManagerTools(ctx: PluginInput): Record<string, Tool
|
|||||||
if (allResults.length >= resultLimit) break
|
if (allResults.length >= resultLimit) break
|
||||||
|
|
||||||
const remaining = resultLimit - allResults.length
|
const remaining = resultLimit - allResults.length
|
||||||
const sessionResults = await searchInSession(sid, args.query, args.case_sensitive, remaining)
|
const sessionResults = await resolvedDeps.searchInSession(sid, args.query, args.case_sensitive, remaining)
|
||||||
allResults.push(...sessionResults)
|
allResults.push(...sessionResults)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +166,7 @@ export function createSessionManagerTools(ctx: PluginInput): Record<string, Tool
|
|||||||
|
|
||||||
const results = await withTimeout(searchOperation(), SEARCH_TIMEOUT_MS, "Search")
|
const results = await withTimeout(searchOperation(), SEARCH_TIMEOUT_MS, "Search")
|
||||||
|
|
||||||
return formatSearchResults(results)
|
return resolvedDeps.formatSearchResults(results)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
||||||
}
|
}
|
||||||
@@ -141,13 +180,13 @@ export function createSessionManagerTools(ctx: PluginInput): Record<string, Tool
|
|||||||
},
|
},
|
||||||
execute: async (args: SessionInfoArgs, _context) => {
|
execute: async (args: SessionInfoArgs, _context) => {
|
||||||
try {
|
try {
|
||||||
const info = await getSessionInfo(args.session_id)
|
const info = await resolvedDeps.getSessionInfo(args.session_id)
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return `Session not found: ${args.session_id}`
|
return `Session not found: ${args.session_id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatSessionInfo(info)
|
return resolvedDeps.formatSessionInfo(info)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user