BinaryFeedbackOption.tsx
1 import { FileEditTool } from '../../tools/FileEditTool/FileEditTool.js' 2 import { FileEditToolDiff } from '../permissions/FileEditPermissionRequest/FileEditToolDiff.js' 3 import { Message } from '../Message.js' 4 import { 5 normalizeMessages, 6 type NormalizedMessage, 7 } from '../../utils/messages.js' 8 import type { Tool } from '../../Tool.js' 9 import { useTerminalSize } from '../../hooks/useTerminalSize.js' 10 import { FileWriteTool } from '../../tools/FileWriteTool/FileWriteTool.js' 11 import { FileWriteToolDiff } from '../permissions/FileWritePermissionRequest/FileWriteToolDiff.js' 12 import type { AssistantMessage } from '../../query.js' 13 import * as React from 'react' 14 import { Box } from 'ink' 15 16 type Props = { 17 debug: boolean 18 erroredToolUseIDs: Set<string> 19 inProgressToolUseIDs: Set<string> 20 message: AssistantMessage 21 normalizedMessages: NormalizedMessage[] 22 tools: Tool[] 23 unresolvedToolUseIDs: Set<string> 24 verbose: boolean 25 } 26 27 export function BinaryFeedbackOption({ 28 debug, 29 erroredToolUseIDs, 30 inProgressToolUseIDs, 31 message, 32 normalizedMessages, 33 tools, 34 unresolvedToolUseIDs, 35 verbose, 36 }: Props): React.ReactNode { 37 const { columns } = useTerminalSize() 38 return normalizeMessages([message]) 39 .filter(_ => _.type !== 'progress') 40 .map((_, index) => ( 41 <Box flexDirection="column" key={index}> 42 <Message 43 addMargin={false} 44 erroredToolUseIDs={erroredToolUseIDs} 45 debug={debug} 46 inProgressToolUseIDs={inProgressToolUseIDs} 47 message={_} 48 messages={normalizedMessages} 49 shouldAnimate={false} 50 shouldShowDot={true} 51 tools={tools} 52 unresolvedToolUseIDs={unresolvedToolUseIDs} 53 verbose={verbose} 54 width={columns / 2 - 6} 55 /> 56 <AdditionalContext message={_} verbose={verbose} /> 57 </Box> 58 )) 59 } 60 61 function AdditionalContext({ 62 message, 63 verbose, 64 }: { 65 message: NormalizedMessage 66 verbose: boolean 67 }) { 68 const { columns } = useTerminalSize() 69 if (message.type !== 'assistant') { 70 return null 71 } 72 const content = message.message.content[0]! 73 switch (content.type) { 74 case 'tool_use': 75 switch (content.name) { 76 case FileEditTool.name: { 77 const input = FileEditTool.inputSchema.safeParse(content.input) 78 if (!input.success) { 79 return null 80 } 81 return ( 82 <FileEditToolDiff 83 file_path={input.data.file_path} 84 new_string={input.data.new_string} 85 old_string={input.data.old_string} 86 verbose={verbose} 87 width={columns / 2 - 12} 88 /> 89 ) 90 } 91 case FileWriteTool.name: { 92 const input = FileWriteTool.inputSchema.safeParse(content.input) 93 if (!input.success) { 94 return null 95 } 96 return ( 97 <FileWriteToolDiff 98 file_path={input.data.file_path} 99 content={input.data.content} 100 verbose={verbose} 101 width={columns / 2 - 12} 102 /> 103 ) 104 } 105 default: 106 return null 107 } 108 default: 109 return null 110 } 111 }