enhance(background-agent): Prevent recursive tool calls and wait for session todos before completion
- Remove call_omo_agent from blocked tools (only calls explore/librarian, safe) - Keep task and background_task blocked to prevent recursion - Add checkSessionTodos() to verify incomplete todos before marking tasks complete - Update session.idle event handler to respect todo status - Add polling check in task completion to wait for todo-continuation 🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
@@ -30,6 +30,13 @@ interface Event {
|
|||||||
properties?: EventProperties
|
properties?: EventProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Todo {
|
||||||
|
content: string
|
||||||
|
status: string
|
||||||
|
priority: string
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
function getMessageDir(sessionID: string): string | null {
|
function getMessageDir(sessionID: string): string | null {
|
||||||
if (!existsSync(MESSAGE_STORAGE)) return null
|
if (!existsSync(MESSAGE_STORAGE)) return null
|
||||||
|
|
||||||
@@ -103,7 +110,6 @@ export class BackgroundManager {
|
|||||||
agent: input.agent,
|
agent: input.agent,
|
||||||
tools: {
|
tools: {
|
||||||
task: false,
|
task: false,
|
||||||
call_omo_agent: false,
|
|
||||||
background_task: false,
|
background_task: false,
|
||||||
},
|
},
|
||||||
parts: [{ type: "text", text: input.prompt }],
|
parts: [{ type: "text", text: input.prompt }],
|
||||||
@@ -151,6 +157,23 @@ export class BackgroundManager {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async checkSessionTodos(sessionID: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const response = await this.client.session.todo({
|
||||||
|
path: { id: sessionID },
|
||||||
|
})
|
||||||
|
const todos = (response.data ?? response) as Todo[]
|
||||||
|
if (!todos || todos.length === 0) return false
|
||||||
|
|
||||||
|
const incomplete = todos.filter(
|
||||||
|
(t) => t.status !== "completed" && t.status !== "cancelled"
|
||||||
|
)
|
||||||
|
return incomplete.length > 0
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleEvent(event: Event): void {
|
handleEvent(event: Event): void {
|
||||||
const props = event.properties
|
const props = event.properties
|
||||||
|
|
||||||
@@ -183,11 +206,18 @@ export class BackgroundManager {
|
|||||||
const task = this.findBySession(sessionID)
|
const task = this.findBySession(sessionID)
|
||||||
if (!task || task.status !== "running") return
|
if (!task || task.status !== "running") return
|
||||||
|
|
||||||
task.status = "completed"
|
this.checkSessionTodos(sessionID).then((hasIncompleteTodos) => {
|
||||||
task.completedAt = new Date()
|
if (hasIncompleteTodos) {
|
||||||
this.markForNotification(task)
|
log("[background-agent] Task has incomplete todos, waiting for todo-continuation:", task.id)
|
||||||
this.notifyParentSession(task)
|
return
|
||||||
log("[background-agent] Task completed via session.idle event:", task.id)
|
}
|
||||||
|
|
||||||
|
task.status = "completed"
|
||||||
|
task.completedAt = new Date()
|
||||||
|
this.markForNotification(task)
|
||||||
|
this.notifyParentSession(task)
|
||||||
|
log("[background-agent] Task completed via session.idle event:", task.id)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type === "session.deleted") {
|
if (event.type === "session.deleted") {
|
||||||
@@ -329,6 +359,12 @@ export class BackgroundManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sessionStatus.type === "idle") {
|
if (sessionStatus.type === "idle") {
|
||||||
|
const hasIncompleteTodos = await this.checkSessionTodos(task.sessionID)
|
||||||
|
if (hasIncompleteTodos) {
|
||||||
|
log("[background-agent] Task has incomplete todos via polling, waiting:", task.id)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
task.status = "completed"
|
task.status = "completed"
|
||||||
task.completedAt = new Date()
|
task.completedAt = new Date()
|
||||||
this.markForNotification(task)
|
this.markForNotification(task)
|
||||||
|
|||||||
Reference in New Issue
Block a user