11import { createLogger } from '@sim/logger'
22import type { BlockOutput } from '@/blocks/types'
33import { BlockType } from '@/executor/constants'
4+ import {
5+ parseResponseFormat ,
6+ processStructuredResponse ,
7+ resolveMessages ,
8+ } from '@/executor/handlers/shared/response-format'
49import type { BlockHandler , ExecutionContext } from '@/executor/types'
510import { buildAPIUrl , buildAuthHeaders , extractAPIErrorMessage } from '@/executor/utils/http'
611import type { SerializedBlock } from '@/serializer/types'
@@ -24,8 +29,8 @@ export class MothershipBlockHandler implements BlockHandler {
2429 block : SerializedBlock ,
2530 inputs : Record < string , any >
2631 ) : Promise < BlockOutput > {
27- const messages = this . resolveMessages ( inputs )
28- const responseFormat = this . parseResponseFormat ( inputs . responseFormat )
32+ const messages = resolveMessages ( inputs . messages )
33+ const responseFormat = parseResponseFormat ( inputs . responseFormat )
2934
3035 const memoryType = inputs . memoryType || 'none'
3136 const chatId =
@@ -68,7 +73,7 @@ export class MothershipBlockHandler implements BlockHandler {
6873 const result = await response . json ( )
6974
7075 if ( responseFormat && result . content ) {
71- return this . processStructuredResponse ( result )
76+ return processStructuredResponse ( result , 'mothership' )
7277 }
7378
7479 return {
@@ -77,76 +82,4 @@ export class MothershipBlockHandler implements BlockHandler {
7782 tokens : result . tokens || { } ,
7883 }
7984 }
80-
81- private resolveMessages (
82- inputs : Record < string , any >
83- ) : Array < { role : string ; content : string } > {
84- const raw = inputs . messages
85- if ( ! raw ) {
86- throw new Error ( 'Messages input is required for the Mothership block' )
87- }
88-
89- let messages : unknown [ ]
90- if ( typeof raw === 'string' ) {
91- try {
92- messages = JSON . parse ( raw )
93- } catch {
94- throw new Error ( 'Messages must be a valid JSON array' )
95- }
96- } else if ( Array . isArray ( raw ) ) {
97- messages = raw
98- } else {
99- throw new Error ( 'Messages must be an array of {role, content} objects' )
100- }
101-
102- return messages . map ( ( msg : any , i : number ) => {
103- if ( ! msg . role || typeof msg . content !== 'string' ) {
104- throw new Error (
105- `Message at index ${ i } must have "role" (string) and "content" (string)`
106- )
107- }
108- return { role : String ( msg . role ) , content : msg . content }
109- } )
110- }
111-
112- private parseResponseFormat ( responseFormat ?: string | object ) : any {
113- if ( ! responseFormat || responseFormat === '' ) return undefined
114-
115- if ( typeof responseFormat === 'object' ) return responseFormat
116-
117- if ( typeof responseFormat === 'string' ) {
118- const trimmed = responseFormat . trim ( )
119- if ( ! trimmed ) return undefined
120- if ( trimmed . startsWith ( '<' ) || trimmed . startsWith ( '{{' ) ) return undefined
121- try {
122- return JSON . parse ( trimmed )
123- } catch {
124- logger . warn ( 'Failed to parse responseFormat as JSON' , {
125- preview : trimmed . slice ( 0 , 100 ) ,
126- } )
127- return undefined
128- }
129- }
130-
131- return undefined
132- }
133-
134- private processStructuredResponse ( result : any ) : BlockOutput {
135- const content = result . content
136- try {
137- const parsed = JSON . parse ( content . trim ( ) )
138- return {
139- ...parsed ,
140- model : result . model || 'mothership' ,
141- tokens : result . tokens || { } ,
142- }
143- } catch {
144- logger . warn ( 'Failed to parse structured response, returning raw content' )
145- return {
146- content,
147- model : result . model || 'mothership' ,
148- tokens : result . tokens || { } ,
149- }
150- }
151- }
15285}
0 commit comments