@@ -15,46 +15,13 @@ import {
1515} from './router-utils'
1616import { useChatStore } from '../state/chat-store'
1717import { getSystemMessage , getUserMessage } from '../utils/message-history'
18+ import {
19+ buildBashHistoryMessages ,
20+ createRunTerminalToolResult ,
21+ } from '../utils/bash-messages'
1822
19- import type { ToolMessage } from '@codebuff/common/types/messages/codebuff-message'
20- import type { ToolResultOutput } from '@codebuff/common/types/messages/content-part'
21- import type { ContentBlock } from '../types/chat'
2223import type { PendingBashMessage } from '../state/chat-store'
2324
24- /**
25- * Create a tool result output structure for terminal command results.
26- */
27- function createToolResultOutput ( params : {
28- command : string
29- cwd : string
30- stdout : string | null
31- stderr : string | null
32- exitCode : number
33- errorMessage ?: string
34- } ) : ToolResultOutput [ ] {
35- const { command, cwd, stdout, stderr, exitCode, errorMessage } = params
36- if ( errorMessage ) {
37- return [
38- {
39- type : 'json' as const ,
40- value : { command, startingCwd : cwd , errorMessage } ,
41- } ,
42- ]
43- }
44- return [
45- {
46- type : 'json' as const ,
47- value : {
48- command,
49- startingCwd : cwd ,
50- stdout : stdout || null ,
51- stderr : stderr || null ,
52- exitCode,
53- } ,
54- } ,
55- ]
56- }
57-
5825/**
5926 * Execute a bash command.
6027 * When ghost=false: adds directly to chat history with placeholder output that updates.
@@ -89,21 +56,14 @@ function executeBashCommand(
8956 cwd : commandCwd ,
9057 } )
9158 } else {
92- // Direct mode: add to chat history with placeholder
93- const resultBlock : ContentBlock = {
94- type : 'tool' ,
95- toolName : 'run_terminal_command' ,
59+ // Direct mode: add to chat history with placeholder output (user + assistant)
60+ const { assistantMessage } = buildBashHistoryMessages ( {
61+ command ,
62+ cwd : commandCwd ,
9663 toolCallId : id ,
97- input : { command } ,
9864 output : '...' ,
99- }
100- options . setMessages ( ( prev ) => [
101- ...prev ,
102- {
103- ...getUserMessage ( [ resultBlock ] ) ,
104- metadata : { bashCwd : commandCwd } ,
105- } ,
106- ] )
65+ } )
66+ options . setMessages ( ( prev ) => [ ...prev , assistantMessage ] )
10767 }
10868
10969 runTerminalCommand ( {
@@ -117,8 +77,6 @@ function executeBashCommand(
11777 const stdout = 'stdout' in value ? value . stdout || '' : ''
11878 const stderr = 'stderr' in value ? value . stderr || '' : ''
11979 const exitCode = 'exitCode' in value ? value . exitCode ?? 0 : 0
120- const rawOutput = stdout + stderr
121- const output = rawOutput || '(no output)'
12280
12381 if ( options . ghost ) {
12482 options . updatePendingBashMessage ( id , {
@@ -128,7 +86,7 @@ function executeBashCommand(
12886 isRunning : false ,
12987 } )
13088 } else {
131- const toolResultOutput = createToolResultOutput ( {
89+ const toolResultOutput = createRunTerminalToolResult ( {
13290 command,
13391 cwd : commandCwd ,
13492 stdout : stdout || null ,
@@ -140,25 +98,17 @@ function executeBashCommand(
14098 options . setMessages ( ( prev ) =>
14199 prev . map ( ( msg ) => {
142100 if ( ! msg . blocks ) return msg
143- return {
144- ...msg ,
145- blocks : msg . blocks . map ( ( block ) =>
146- 'toolCallId' in block && block . toolCallId === id
147- ? { ...block , output : outputJson }
148- : block ,
149- ) ,
150- }
101+ let didUpdate = false
102+ const blocks = msg . blocks . map ( ( block ) => {
103+ if ( 'toolCallId' in block && block . toolCallId === id ) {
104+ didUpdate = true
105+ return { ...block , output : outputJson }
106+ }
107+ return block
108+ } )
109+ return didUpdate ? { ...msg , blocks, isComplete : true } : msg
151110 } ) ,
152111 )
153-
154- // Add to pending tool results so AI can see this in the next run
155- const toolMessage : ToolMessage = {
156- role : 'tool' ,
157- toolCallId : id ,
158- toolName : 'run_terminal_command' ,
159- content : toolResultOutput ,
160- }
161- useChatStore . getState ( ) . addPendingToolResult ( toolMessage )
162112 }
163113 } )
164114 . catch ( ( error ) => {
@@ -174,7 +124,7 @@ function executeBashCommand(
174124 isRunning : false ,
175125 } )
176126 } else {
177- const errorToolResultOutput = createToolResultOutput ( {
127+ const errorToolResultOutput = createRunTerminalToolResult ( {
178128 command,
179129 cwd : commandCwd ,
180130 stdout : null ,
@@ -187,31 +137,24 @@ function executeBashCommand(
187137 options . setMessages ( ( prev ) =>
188138 prev . map ( ( msg ) => {
189139 if ( ! msg . blocks ) return msg
190- return {
191- ...msg ,
192- blocks : msg . blocks . map ( ( block ) =>
193- 'toolCallId' in block && block . toolCallId === id
194- ? { ...block , output : errorOutputJson }
195- : block ,
196- ) ,
197- }
140+ let didUpdate = false
141+ const blocks = msg . blocks . map ( ( block ) => {
142+ if ( 'toolCallId' in block && block . toolCallId === id ) {
143+ didUpdate = true
144+ return { ...block , output : errorOutputJson }
145+ }
146+ return block
147+ } )
148+ return didUpdate ? { ...msg , blocks, isComplete : true } : msg
198149 } ) ,
199150 )
200-
201- const errorToolMessage : ToolMessage = {
202- role : 'tool' ,
203- toolCallId : id ,
204- toolName : 'run_terminal_command' ,
205- content : errorToolResultOutput ,
206- }
207- useChatStore . getState ( ) . addPendingToolResult ( errorToolMessage )
208151 }
209152 } )
210153}
211154
212155/**
213156 * Add a completed bash command result to the chat message history.
214- * Also adds to pendingToolResults so the AI can see it in the next run .
157+ * Note: This is UI-only; we no longer send these commands to the AI context .
215158 */
216159export function addBashMessageToHistory ( params : {
217160 command : string
@@ -222,38 +165,24 @@ export function addBashMessageToHistory(params: {
222165 setMessages : RouterParams [ 'setMessages' ]
223166} ) {
224167 const { command, stdout, stderr, exitCode, cwd, setMessages } = params
225- const outputText = stdout || stderr || '(no output)'
226- const toolCallId = crypto . randomUUID ( )
227- const resultBlock : ContentBlock = {
228- type : 'tool' ,
229- toolName : 'run_terminal_command' ,
230- toolCallId,
231- input : { command } ,
232- output : outputText ,
233- }
234-
235- setMessages ( ( prev ) => [
236- ...prev ,
237- {
238- ...getUserMessage ( [ resultBlock ] ) ,
239- metadata : { bashCwd : cwd } ,
240- } ,
241- ] )
242-
243- const toolResultOutput = createToolResultOutput ( {
168+ const toolResultOutput = createRunTerminalToolResult ( {
244169 command,
245170 cwd,
246171 stdout : stdout || null ,
247172 stderr : stderr ?? null ,
248173 exitCode,
249174 } )
250- const toolMessage : ToolMessage = {
251- role : 'tool' ,
175+ const toolCallId = crypto . randomUUID ( )
176+ const outputJson = JSON . stringify ( toolResultOutput )
177+ const { assistantMessage } = buildBashHistoryMessages ( {
178+ command,
179+ cwd,
252180 toolCallId,
253- toolName : 'run_terminal_command' ,
254- content : toolResultOutput ,
255- }
256- useChatStore . getState ( ) . addPendingToolResult ( toolMessage )
181+ output : outputJson ,
182+ isComplete : true ,
183+ } )
184+
185+ setMessages ( ( prev ) => [ ...prev , assistantMessage ] )
257186}
258187
259188export async function routeUserPrompt (
0 commit comments