(ctx, info: DevtoolsToolPhaseCompleteInfo)
| 456 | }, |
| 457 | |
| 458 | onToolPhaseComplete(ctx, info: DevtoolsToolPhaseCompleteInfo) { |
| 459 | const base = buildEventContext(ctx) |
| 460 | |
| 461 | // Emit text:message:created for assistant message with tool calls |
| 462 | if (info.toolCalls.length > 0) { |
| 463 | safeEmit('text:message:created', { |
| 464 | ...base, |
| 465 | messageId: localMessageId ?? ctx.createId('msg'), |
| 466 | role: 'assistant' as const, |
| 467 | content: localAccumulatedContent || '', |
| 468 | toolCalls: info.toolCalls as never, |
| 469 | timestamp: Date.now(), |
| 470 | }) |
| 471 | } |
| 472 | |
| 473 | // Emit tools:approval:requested for each pending approval |
| 474 | for (const approval of info.needsApproval) { |
| 475 | safeEmit('tools:approval:requested', { |
| 476 | ...base, |
| 477 | messageId: localMessageId || undefined, |
| 478 | toolCallId: approval.toolCallId, |
| 479 | toolName: approval.toolName, |
| 480 | input: approval.input, |
| 481 | approvalId: approval.approvalId, |
| 482 | timestamp: Date.now(), |
| 483 | }) |
| 484 | } |
| 485 | |
| 486 | // Emit tools:input:available for each client tool |
| 487 | for (const clientTool of info.needsClientExecution) { |
| 488 | safeEmit('tools:input:available', { |
| 489 | ...base, |
| 490 | messageId: localMessageId || undefined, |
| 491 | toolCallId: clientTool.toolCallId, |
| 492 | toolName: clientTool.toolName, |
| 493 | input: clientTool.input, |
| 494 | timestamp: Date.now(), |
| 495 | }) |
| 496 | } |
| 497 | |
| 498 | // Emit tools:call:completed and text:message:created (tool role) for each result |
| 499 | for (const result of info.results) { |
| 500 | safeEmit('tools:call:completed', { |
| 501 | ...base, |
| 502 | messageId: localMessageId || undefined, |
| 503 | toolCallId: result.toolCallId, |
| 504 | toolName: result.toolName, |
| 505 | result: result.result, |
| 506 | duration: result.duration ?? 0, |
| 507 | timestamp: Date.now(), |
| 508 | }) |
| 509 | |
| 510 | const content = JSON.stringify(result.result) |
| 511 | safeEmit('text:message:created', { |
| 512 | ...base, |
| 513 | messageId: ctx.createId('msg'), |
| 514 | role: 'tool' as const, |
| 515 | content, |
nothing calls this directly
no test coverage detected