( toolCallId: string, toolName: string, completion: AsyncTerminalCompletionSnapshot | null, options: OrchestratorOptions )
| 228 | * so the client would never learn the outcome without this. |
| 229 | */ |
| 230 | export async function emitSyntheticToolResult( |
| 231 | toolCallId: string, |
| 232 | toolName: string, |
| 233 | completion: AsyncTerminalCompletionSnapshot | null, |
| 234 | options: OrchestratorOptions |
| 235 | ): Promise<void> { |
| 236 | const isBackground = completion?.status === ASYNC_TOOL_CONFIRMATION_STATUS.background |
| 237 | const success = isBackground || completion?.status === MothershipStreamV1ToolOutcome.success |
| 238 | const isCancelled = completion?.status === MothershipStreamV1ToolOutcome.cancelled |
| 239 | const completionData = completion?.data |
| 240 | const syntheticStatus = isBackground |
| 241 | ? MothershipStreamV1ToolOutcome.skipped |
| 242 | : completion?.status === MothershipStreamV1ToolOutcome.success || |
| 243 | completion?.status === MothershipStreamV1ToolOutcome.error || |
| 244 | completion?.status === MothershipStreamV1ToolOutcome.cancelled |
| 245 | ? completion.status |
| 246 | : undefined |
| 247 | |
| 248 | const resultPayload = isCancelled |
| 249 | ? isRecordLike(completionData) |
| 250 | ? { ...completionData, reason: 'user_cancelled', cancelledByUser: true } |
| 251 | : completionData !== undefined |
| 252 | ? { output: completionData, reason: 'user_cancelled', cancelledByUser: true } |
| 253 | : { reason: 'user_cancelled', cancelledByUser: true } |
| 254 | : completionData |
| 255 | |
| 256 | try { |
| 257 | await options.onEvent?.({ |
| 258 | type: MothershipStreamV1EventType.tool, |
| 259 | payload: { |
| 260 | toolCallId, |
| 261 | toolName, |
| 262 | executor: MothershipStreamV1ToolExecutor.client, |
| 263 | mode: MothershipStreamV1ToolMode.async, |
| 264 | phase: MothershipStreamV1ToolPhase.result, |
| 265 | success, |
| 266 | output: resultPayload, |
| 267 | ...(syntheticStatus ? { status: syntheticStatus } : {}), |
| 268 | ...(!success && completion?.message ? { error: completion.message } : {}), |
| 269 | }, |
| 270 | }) |
| 271 | } catch (error) { |
| 272 | logger.warn('Failed to emit synthetic tool_result', { |
| 273 | toolCallId, |
| 274 | toolName, |
| 275 | error: toError(error).message, |
| 276 | }) |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | export function getToolResultErrorMessage( |
| 281 | data: MothershipStreamV1ToolResultPayload | undefined |
no test coverage detected