@@ -212,6 +212,56 @@ export class TaskToolUseMessage {
212212 ) { }
213213}
214214
215+ export const CODEX_SUBAGENT_ACTIONS = [
216+ 'spawn_agent' ,
217+ 'send_input' ,
218+ 'send_message' ,
219+ 'followup_task' ,
220+ 'wait_agent' ,
221+ 'interrupt_agent' ,
222+ 'list_agents' ,
223+ 'close_agent' ,
224+ 'resume_agent' ,
225+ ] as const ;
226+
227+ export type CodexSubagentAction = ( typeof CODEX_SUBAGENT_ACTIONS ) [ number ] ;
228+
229+ export interface CodexSubagentInputItem {
230+ type ?: string ;
231+ text ?: string ;
232+ imageUrl ?: string ;
233+ path ?: string ;
234+ name ?: string ;
235+ }
236+
237+ export interface CodexSubagentDetails {
238+ target ?: string ;
239+ targets ?: string [ ] ;
240+ message ?: string ;
241+ taskName ?: string ;
242+ agentType ?: string ;
243+ model ?: string ;
244+ reasoningEffort ?: string ;
245+ serviceTier ?: string ;
246+ forkContext ?: boolean ;
247+ forkTurns ?: string ;
248+ timeoutMs ?: number ;
249+ pathPrefix ?: string ;
250+ interrupt ?: boolean ;
251+ items ?: CodexSubagentInputItem [ ] ;
252+ }
253+
254+ export class CodexSubagentToolUseMessage {
255+ readonly type = 'codex-subagent-tool-use' as const ;
256+
257+ constructor (
258+ public timestamp : string ,
259+ public toolId : string ,
260+ public action : CodexSubagentAction ,
261+ public details : CodexSubagentDetails = { } ,
262+ ) { }
263+ }
264+
215265export class UpdatePlanToolUseMessage {
216266 readonly type = 'update-plan-tool-use' as const ;
217267
@@ -514,6 +564,7 @@ export type ToolUseChatMessage =
514564 | TodoWriteToolUseMessage
515565 | TodoReadToolUseMessage
516566 | TaskToolUseMessage
567+ | CodexSubagentToolUseMessage
517568 | UpdatePlanToolUseMessage
518569 | WriteStdinToolUseMessage
519570 | EnterPlanModeToolUseMessage
@@ -701,6 +752,53 @@ function asOptionalChanges(v: unknown): Array<{ path?: string; kind?: string }>
701752 return undefined ;
702753}
703754
755+ const CODEX_SUBAGENT_ACTION_SET = new Set < string > ( CODEX_SUBAGENT_ACTIONS ) ;
756+
757+ function asCodexSubagentAction ( v : unknown ) : CodexSubagentAction | undefined {
758+ return typeof v === 'string' && CODEX_SUBAGENT_ACTION_SET . has ( v )
759+ ? v as CodexSubagentAction
760+ : undefined ;
761+ }
762+
763+ function asCodexSubagentInputItems ( v : unknown ) : CodexSubagentInputItem [ ] | undefined {
764+ if ( ! Array . isArray ( v ) ) return undefined ;
765+ const items : CodexSubagentInputItem [ ] = [ ] ;
766+ for ( const entry of v ) {
767+ const raw = asRecord ( entry ) ;
768+ const item : CodexSubagentInputItem = { } ;
769+ if ( typeof raw . type === 'string' ) item . type = raw . type ;
770+ if ( typeof raw . text === 'string' ) item . text = raw . text ;
771+ if ( typeof raw . imageUrl === 'string' ) item . imageUrl = raw . imageUrl ;
772+ if ( typeof raw . path === 'string' ) item . path = raw . path ;
773+ if ( typeof raw . name === 'string' ) item . name = raw . name ;
774+ if ( Object . keys ( item ) . length > 0 ) items . push ( item ) ;
775+ }
776+ return items . length > 0 || v . length === 0 ? items : undefined ;
777+ }
778+
779+ function asCodexSubagentDetails ( v : unknown ) : CodexSubagentDetails {
780+ const raw = asRecord ( v ) ;
781+ const details : CodexSubagentDetails = { } ;
782+ if ( typeof raw . target === 'string' ) details . target = raw . target ;
783+ const targets = asStringArray ( raw . targets ) ;
784+ if ( targets !== undefined ) details . targets = targets ;
785+ if ( typeof raw . message === 'string' ) details . message = raw . message ;
786+ if ( typeof raw . taskName === 'string' ) details . taskName = raw . taskName ;
787+ if ( typeof raw . agentType === 'string' ) details . agentType = raw . agentType ;
788+ if ( typeof raw . model === 'string' ) details . model = raw . model ;
789+ if ( typeof raw . reasoningEffort === 'string' ) details . reasoningEffort = raw . reasoningEffort ;
790+ if ( typeof raw . serviceTier === 'string' ) details . serviceTier = raw . serviceTier ;
791+ if ( typeof raw . forkContext === 'boolean' ) details . forkContext = raw . forkContext ;
792+ if ( typeof raw . forkTurns === 'string' ) details . forkTurns = raw . forkTurns ;
793+ const timeoutMs = asOptionalNumber ( raw . timeoutMs ) ;
794+ if ( timeoutMs !== undefined ) details . timeoutMs = timeoutMs ;
795+ if ( typeof raw . pathPrefix === 'string' ) details . pathPrefix = raw . pathPrefix ;
796+ if ( typeof raw . interrupt === 'boolean' ) details . interrupt = raw . interrupt ;
797+ const items = asCodexSubagentInputItems ( raw . items ) ;
798+ if ( items !== undefined ) details . items = items ;
799+ return details ;
800+ }
801+
704802type ToolUseMessageType = ToolUseChatMessage [ 'type' ] ;
705803type ToolUseMessageParser = ( data : Record < string , unknown > ) => ToolUseChatMessage | null ;
706804
@@ -794,6 +892,15 @@ const TOOL_USE_MESSAGE_PARSERS = {
794892 asOptionalString ( data . model ) ,
795893 asOptionalString ( data . resume ) ) ,
796894
895+ 'codex-subagent-tool-use' : ( data ) => {
896+ const action = asCodexSubagentAction ( data . action ) ;
897+ if ( action === undefined ) return null ;
898+ return new CodexSubagentToolUseMessage (
899+ str ( data . timestamp ) , str ( data . toolId ) ,
900+ action ,
901+ asCodexSubagentDetails ( data . details ) ) ;
902+ } ,
903+
797904 'update-plan-tool-use' : ( data ) =>
798905 new UpdatePlanToolUseMessage (
799906 str ( data . timestamp ) , str ( data . toolId ) ,
0 commit comments