2025-12-27 17:56:40 +08:00
import { tool , type PluginInput , type ToolDefinition } from "@opencode-ai/plugin"
2025-12-12 18:39:53 +09:00
import { ALLOWED_AGENTS , CALL_OMO_AGENT_DESCRIPTION } from "./constants"
2026-02-08 21:11:07 +09:00
import type { AllowedAgentType , CallOmoAgentArgs , ToolContextWithMetadata } from "./types"
2025-12-12 18:39:53 +09:00
import type { BackgroundManager } from "../../features/background-agent"
2026-02-08 16:24:13 +09:00
import { log } from "../../shared"
2026-02-08 21:11:07 +09:00
import { executeBackground } from "./background-executor"
import { executeSync } from "./sync-executor"
2025-12-28 17:00:32 +09:00
2025-12-12 18:39:53 +09:00
export function createCallOmoAgent (
ctx : PluginInput ,
2026-02-10 18:44:45 +01:00
backgroundManager : BackgroundManager ,
disabledAgents : string [ ] = [ ]
2025-12-27 17:56:40 +08:00
) : ToolDefinition {
2025-12-12 18:39:53 +09:00
const agentDescriptions = ALLOWED_AGENTS . map (
( name ) = > ` - ${ name } : Specialized agent for ${ name } tasks `
) . join ( "\n" )
const description = CALL_OMO_AGENT_DESCRIPTION . replace ( "{agents}" , agentDescriptions )
return tool ( {
description ,
args : {
description : tool.schema.string ( ) . describe ( "A short (3-5 words) description of the task" ) ,
prompt : tool.schema.string ( ) . describe ( "The task for the agent to perform" ) ,
subagent_type : tool.schema
2026-01-23 00:55:01 +09:00
. string ( )
2026-02-04 11:38:24 +09:00
. describe ( "The type of specialized agent to use for this task (explore or librarian only)" ) ,
2025-12-12 18:39:53 +09:00
run_in_background : tool.schema
. boolean ( )
. describe ( "REQUIRED. true: run asynchronously (use background_output to get results), false: run synchronously and wait for completion" ) ,
session_id : tool.schema.string ( ) . describe ( "Existing Task session to continue" ) . optional ( ) ,
} ,
async execute ( args : CallOmoAgentArgs , toolContext ) {
2025-12-28 17:00:32 +09:00
const toolCtx = toolContext as ToolContextWithMetadata
2025-12-12 18:39:53 +09:00
log ( ` [call_omo_agent] Starting with agent: ${ args . subagent_type } , background: ${ args . run_in_background } ` )
2026-02-08 21:11:07 +09:00
// Case-insensitive agent validation - allows "Explore", "EXPLORE", "explore" etc.
if (
! ALLOWED_AGENTS . some (
( name ) = > name . toLowerCase ( ) === args . subagent_type . toLowerCase ( ) ,
)
) {
2025-12-12 18:39:53 +09:00
return ` Error: Invalid agent type " ${ args . subagent_type } ". Only ${ ALLOWED_AGENTS . join ( ", " ) } are allowed. `
}
2026-02-08 16:24:13 +09:00
2026-02-08 21:11:07 +09:00
const normalizedAgent = args . subagent_type . toLowerCase ( ) as AllowedAgentType
2026-01-23 00:55:01 +09:00
args = { . . . args , subagent_type : normalizedAgent }
2025-12-12 18:39:53 +09:00
2026-02-10 18:44:45 +01:00
// Check if agent is disabled
if ( disabledAgents . some ( ( disabled ) = > disabled . toLowerCase ( ) === normalizedAgent ) ) {
return ` Error: Agent " ${ normalizedAgent } " is disabled via disabled_agents configuration. Remove it from disabled_agents in your oh-my-opencode.json to use it. `
}
2025-12-12 18:39:53 +09:00
if ( args . run_in_background ) {
if ( args . session_id ) {
return ` Error: session_id is not supported in background mode. Use run_in_background=false to continue an existing session. `
}
2026-02-15 14:57:15 +09:00
return await executeBackground ( args , toolCtx , backgroundManager , ctx . client )
2025-12-12 18:39:53 +09:00
}
2026-02-08 21:11:07 +09:00
return await executeSync ( args , toolCtx , ctx )
2025-12-12 18:39:53 +09:00
} ,
} )
}