2026-02-08 17:00:26 +09:00
import type { CallOmoAgentArgs } from "./types"
import type { PluginInput } from "@opencode-ai/plugin"
2026-03-11 20:09:17 +09:00
import { subagentSessions , syncSubagentSessions } from "../../features/claude-code-session-state"
import { getAgentToolRestrictions , log } from "../../shared"
2026-04-04 15:40:37 +09:00
import { applySessionPromptParams } from "../../shared/session-prompt-params-helpers"
2026-03-27 13:59:06 +09:00
import type { DelegatedModelConfig } from "../../shared/model-resolution-types"
2026-03-11 20:09:17 +09:00
import type { FallbackEntry } from "../../shared/model-requirements"
2026-04-11 14:53:01 +09:00
import { stripAgentListSortPrefix } from "../../shared/agent-display-names"
2026-02-08 17:00:26 +09:00
import { waitForCompletion } from "./completion-poller"
import { processMessages } from "./message-processor"
2026-03-11 20:09:17 +09:00
import { createOrGetSession } from "./session-creator"
2026-02-08 17:00:26 +09:00
2026-02-23 02:42:37 +09:00
type SessionWithPromptAsync = {
promptAsync : ( opts : { path : { id : string } ; body : Record < string , unknown > } ) = > Promise < unknown >
}
2026-02-14 22:06:23 +09:00
type ExecuteSyncDeps = {
createOrGetSession : typeof createOrGetSession
waitForCompletion : typeof waitForCompletion
processMessages : typeof processMessages
2026-04-18 02:35:46 +09:00
setSessionFallbackChain : ( sessionID : string , fallbackChain : FallbackEntry [ ] | undefined ) = > void
clearSessionFallbackChain : ( sessionID : string ) = > void
2026-02-14 22:06:23 +09:00
}
2026-03-11 18:44:20 +09:00
type SpawnReservation = {
commit : ( ) = > number
rollback : ( ) = > void
}
2026-02-14 22:06:23 +09:00
const defaultDeps : ExecuteSyncDeps = {
createOrGetSession ,
waitForCompletion ,
processMessages ,
2026-04-18 02:35:46 +09:00
setSessionFallbackChain : ( ) = > { } ,
clearSessionFallbackChain : ( ) = > { } ,
2026-02-14 22:06:23 +09:00
}
2026-04-04 15:40:37 +09:00
function buildPromptGenerationParams ( model : DelegatedModelConfig | undefined ) : Record < string , unknown > {
if ( ! model ) {
return { }
}
const promptOptions : Record < string , unknown > = {
. . . ( model . reasoningEffort ? { reasoningEffort : model.reasoningEffort } : { } ) ,
. . . ( model . thinking ? { thinking : model.thinking } : { } ) ,
}
return {
. . . ( model . temperature !== undefined ? { temperature : model.temperature } : { } ) ,
. . . ( model . top_p !== undefined ? { topP : model.top_p } : { } ) ,
2026-04-08 17:14:17 +09:00
. . . ( model . maxTokens !== undefined ? { maxOutputTokens : model.maxTokens } : { } ) ,
2026-04-04 15:40:37 +09:00
. . . ( Object . keys ( promptOptions ) . length > 0 ? { options : promptOptions } : { } ) ,
}
}
2026-02-08 17:00:26 +09:00
export async function executeSync (
args : CallOmoAgentArgs ,
toolContext : {
sessionID : string
messageID : string
agent : string
abort : AbortSignal
2026-03-11 18:44:20 +09:00
metadata ? : ( input : { title? : string ; metadata? : Record < string , unknown > } ) = > void | Promise < void >
2026-02-08 17:00:26 +09:00
} ,
2026-02-14 22:06:23 +09:00
ctx : PluginInput ,
2026-03-09 13:11:03 +09:00
deps : ExecuteSyncDeps = defaultDeps ,
fallbackChain? : FallbackEntry [ ] ,
2026-03-11 18:44:20 +09:00
spawnReservation? : SpawnReservation ,
2026-03-27 13:59:06 +09:00
model? : DelegatedModelConfig ,
2026-02-08 17:00:26 +09:00
) : Promise < string > {
2026-03-11 18:44:20 +09:00
let sessionID : string | undefined
2026-03-12 02:24:22 +09:00
let createdSessionForExecution = false
2026-03-12 11:04:20 +09:00
let appliedFallbackChain = false
2026-02-08 17:00:26 +09:00
2026-03-11 18:44:20 +09:00
try {
2026-05-08 20:41:05 +08:00
const session = await deps . createOrGetSession ( args , toolContext , ctx , model )
2026-03-11 18:44:20 +09:00
sessionID = session . sessionID
2026-03-12 02:24:22 +09:00
createdSessionForExecution = session . isNew
2026-03-12 11:04:20 +09:00
subagentSessions . add ( sessionID )
syncSubagentSessions . add ( sessionID )
2026-03-09 13:11:03 +09:00
2026-03-11 18:44:20 +09:00
if ( session . isNew ) {
spawnReservation ? . commit ( )
}
2026-02-08 17:00:26 +09:00
2026-03-11 18:44:20 +09:00
if ( fallbackChain && fallbackChain . length > 0 ) {
deps . setSessionFallbackChain ( sessionID , fallbackChain )
2026-03-12 11:04:20 +09:00
appliedFallbackChain = true
2026-03-11 18:44:20 +09:00
}
2026-02-08 17:00:26 +09:00
2026-04-04 15:40:37 +09:00
applySessionPromptParams ( sessionID , model )
2026-03-11 20:09:17 +09:00
await Promise . resolve (
toolContext . metadata ? . ( {
title : args.description ,
metadata : { sessionId : sessionID } ,
} )
)
2026-03-11 18:44:20 +09:00
log ( ` [call_omo_agent] Sending prompt to session ${ sessionID } ` )
log ( ` [call_omo_agent] Prompt text: ` , args . prompt . substring ( 0 , 100 ) )
2026-04-11 14:53:01 +09:00
const normalizedSubagentType = stripAgentListSortPrefix ( args . subagent_type )
2026-03-11 18:44:20 +09:00
try {
await ( ctx . client . session as unknown as SessionWithPromptAsync ) . promptAsync ( {
path : { id : sessionID } ,
body : {
2026-04-11 14:53:01 +09:00
agent : normalizedSubagentType ,
2026-03-11 18:44:20 +09:00
tools : {
2026-04-11 14:53:01 +09:00
. . . getAgentToolRestrictions ( normalizedSubagentType ) ,
2026-03-11 18:44:20 +09:00
task : false ,
question : false ,
} ,
parts : [ { type : "text" , text : args.prompt } ] ,
2026-03-27 13:59:06 +09:00
. . . ( model ? { model : { providerID : model.providerID , modelID : model.modelID } } : { } ) ,
. . . ( model ? . variant ? { variant : model.variant } : { } ) ,
2026-04-04 15:40:37 +09:00
. . . buildPromptGenerationParams ( model ) ,
2026-03-11 18:44:20 +09:00
} ,
} )
} catch ( error ) {
const errorMessage = error instanceof Error ? error.message : String ( error )
log ( ` [call_omo_agent] Prompt error: ` , errorMessage )
if ( errorMessage . includes ( "agent.name" ) || errorMessage . includes ( "undefined" ) ) {
2026-04-11 14:53:01 +09:00
return ` Error: Agent " ${ normalizedSubagentType } " not found. Make sure the agent is registered in your opencode.json or provided by a plugin. \ n \ n<task_metadata> \ nsession_id: ${ sessionID } \ n</task_metadata> `
2026-03-11 18:44:20 +09:00
}
return ` Error: Failed to send prompt: ${ errorMessage } \ n \ n<task_metadata> \ nsession_id: ${ sessionID } \ n</task_metadata> `
2026-02-08 17:00:26 +09:00
}
2026-03-11 18:44:20 +09:00
await deps . waitForCompletion ( sessionID , toolContext , ctx )
2026-02-08 17:00:26 +09:00
2026-03-11 18:44:20 +09:00
const responseText = await deps . processMessages ( sessionID , ctx )
2026-02-08 17:00:26 +09:00
2026-03-11 20:09:17 +09:00
return responseText + "\n\n" + [ "<task_metadata>" , ` session_id: ${ sessionID } ` , "</task_metadata>" ] . join ( "\n" )
2026-03-11 18:44:20 +09:00
} catch ( error ) {
spawnReservation ? . rollback ( )
throw error
2026-03-11 20:09:17 +09:00
} finally {
2026-03-12 11:04:20 +09:00
if ( sessionID && appliedFallbackChain ) {
deps . clearSessionFallbackChain ( sessionID )
}
2026-03-12 02:24:22 +09:00
if ( sessionID && createdSessionForExecution ) {
2026-03-11 20:09:17 +09:00
subagentSessions . delete ( sessionID )
syncSubagentSessions . delete ( sessionID )
}
2026-03-11 18:44:20 +09:00
}
2026-02-08 17:00:26 +09:00
}