From 7daabf961721dcd1c27072001cd066b914c00f03 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 28 Dec 2025 17:00:32 +0900 Subject: [PATCH] Add ctx.metadata() calls for session navigation UI in background/subagent tasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add metadata() calls to background_task and call_omo_agent tools so that OpenCode UI displays session navigation hints (ctrl+x + arrow keys) like the original Task tool does. This enhances UX by providing consistent session navigation UI for background and subagent tasks. 🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode) --- src/tools/background-task/tools.ts | 21 ++++++++++++++++++--- src/tools/call-omo-agent/tools.ts | 27 +++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/tools/background-task/tools.ts b/src/tools/background-task/tools.ts index 2b74013..b9637e2 100644 --- a/src/tools/background-task/tools.ts +++ b/src/tools/background-task/tools.ts @@ -37,6 +37,14 @@ function formatDuration(start: Date, end?: Date): string { } } +type ToolContextWithMetadata = { + sessionID: string + messageID: string + agent: string + abort: AbortSignal + metadata?: (input: { title?: string; metadata?: Record }) => void +} + export function createBackgroundTask(manager: BackgroundManager): ToolDefinition { return tool({ description: BACKGROUND_TASK_DESCRIPTION, @@ -46,12 +54,14 @@ export function createBackgroundTask(manager: BackgroundManager): ToolDefinition agent: tool.schema.string().describe("Agent type to use (any registered agent)"), }, async execute(args: BackgroundTaskArgs, toolContext) { + const ctx = toolContext as ToolContextWithMetadata + if (!args.agent || args.agent.trim() === "") { return `❌ Agent parameter is required. Please specify which agent to use (e.g., "explore", "librarian", "build", etc.)` } try { - const messageDir = getMessageDir(toolContext.sessionID) + const messageDir = getMessageDir(ctx.sessionID) const prevMessage = messageDir ? findNearestMessageWithFields(messageDir) : null const parentModel = prevMessage?.model?.providerID && prevMessage?.model?.modelID ? { providerID: prevMessage.model.providerID, modelID: prevMessage.model.modelID } @@ -61,11 +71,16 @@ export function createBackgroundTask(manager: BackgroundManager): ToolDefinition description: args.description, prompt: args.prompt, agent: args.agent.trim(), - parentSessionID: toolContext.sessionID, - parentMessageID: toolContext.messageID, + parentSessionID: ctx.sessionID, + parentMessageID: ctx.messageID, parentModel, }) + ctx.metadata?.({ + title: args.description, + metadata: { sessionId: task.sessionID }, + }) + return `Background task launched successfully. Task ID: ${task.id} diff --git a/src/tools/call-omo-agent/tools.ts b/src/tools/call-omo-agent/tools.ts index 5f204fd..3004d33 100644 --- a/src/tools/call-omo-agent/tools.ts +++ b/src/tools/call-omo-agent/tools.ts @@ -4,6 +4,14 @@ import type { CallOmoAgentArgs } from "./types" import type { BackgroundManager } from "../../features/background-agent" import { log } from "../../shared/logger" +type ToolContextWithMetadata = { + sessionID: string + messageID: string + agent: string + abort: AbortSignal + metadata?: (input: { title?: string; metadata?: Record }) => void +} + export function createCallOmoAgent( ctx: PluginInput, backgroundManager: BackgroundManager @@ -27,6 +35,7 @@ export function createCallOmoAgent( session_id: tool.schema.string().describe("Existing Task session to continue").optional(), }, async execute(args: CallOmoAgentArgs, toolContext) { + const toolCtx = toolContext as ToolContextWithMetadata log(`[call_omo_agent] Starting with agent: ${args.subagent_type}, background: ${args.run_in_background}`) if (!ALLOWED_AGENTS.includes(args.subagent_type as typeof ALLOWED_AGENTS[number])) { @@ -37,17 +46,17 @@ export function createCallOmoAgent( if (args.session_id) { return `Error: session_id is not supported in background mode. Use run_in_background=false to continue an existing session.` } - return await executeBackground(args, toolContext, backgroundManager) + return await executeBackground(args, toolCtx, backgroundManager) } - return await executeSync(args, toolContext, ctx) + return await executeSync(args, toolCtx, ctx) }, }) } async function executeBackground( args: CallOmoAgentArgs, - toolContext: { sessionID: string; messageID: string }, + toolContext: ToolContextWithMetadata, manager: BackgroundManager ): Promise { try { @@ -59,6 +68,11 @@ async function executeBackground( parentMessageID: toolContext.messageID, }) + toolContext.metadata?.({ + title: args.description, + metadata: { sessionId: task.sessionID }, + }) + return `Background agent task launched successfully. Task ID: ${task.id} @@ -79,7 +93,7 @@ Use \`background_output\` tool with task_id="${task.id}" to check progress: async function executeSync( args: CallOmoAgentArgs, - toolContext: { sessionID: string }, + toolContext: ToolContextWithMetadata, ctx: PluginInput ): Promise { let sessionID: string @@ -112,6 +126,11 @@ async function executeSync( log(`[call_omo_agent] Created session: ${sessionID}`) } + toolContext.metadata?.({ + title: args.description, + metadata: { sessionId: sessionID }, + }) + log(`[call_omo_agent] Sending prompt to session ${sessionID}`) log(`[call_omo_agent] Prompt text:`, args.prompt.substring(0, 100))