@@ -31,6 +31,138 @@ struct AcpTerminalRenderState<'a> {
3131 pending_terminal_output : & ' a mut HashMap < String , String > ,
3232}
3333
34+ struct AcpSessionUpdateRender < ' a > {
35+ session_id : SessionId ,
36+ update : AcpSessionUpdate ,
37+ terminal_state : AcpTerminalRenderState < ' a > ,
38+ }
39+
40+ impl From < AcpSessionUpdateRender < ' _ > > for Vec < WorkerEvent > {
41+ fn from ( render : AcpSessionUpdateRender < ' _ > ) -> Self {
42+ let AcpSessionUpdateRender {
43+ session_id,
44+ update,
45+ terminal_state,
46+ } = render;
47+ match update {
48+ AcpSessionUpdate :: AgentMessageChunk {
49+ content,
50+ message_id,
51+ ..
52+ } => acp_content_display_text ( & content)
53+ . into_iter ( )
54+ . map ( |delta| {
55+ if let Some ( item_id) = message_item_id ( message_id. as_deref ( ) ) {
56+ WorkerEvent :: TextItemDelta {
57+ item_id,
58+ kind : TextItemKind :: Assistant ,
59+ delta,
60+ }
61+ } else {
62+ WorkerEvent :: TextDelta ( delta)
63+ }
64+ } )
65+ . collect ( ) ,
66+ AcpSessionUpdate :: AgentThoughtChunk {
67+ content,
68+ message_id,
69+ ..
70+ } => acp_content_display_text ( & content)
71+ . into_iter ( )
72+ . map ( |delta| {
73+ if let Some ( item_id) = message_item_id ( message_id. as_deref ( ) ) {
74+ WorkerEvent :: TextItemDelta {
75+ item_id,
76+ kind : TextItemKind :: Reasoning ,
77+ delta,
78+ }
79+ } else {
80+ WorkerEvent :: ReasoningDelta ( delta)
81+ }
82+ } )
83+ . collect ( ) ,
84+ AcpSessionUpdate :: Plan { entries, .. } => vec ! [ WorkerEvent :: PlanUpdated {
85+ explanation: None ,
86+ steps: entries
87+ . into_iter( )
88+ . map( |entry| PlanStep {
89+ text: entry. content,
90+ status: match entry. status {
91+ AcpPlanEntryStatus :: Pending => PlanStepStatus :: Pending ,
92+ AcpPlanEntryStatus :: InProgress => PlanStepStatus :: InProgress ,
93+ AcpPlanEntryStatus :: Completed => PlanStepStatus :: Completed ,
94+ } ,
95+ } )
96+ . collect( ) ,
97+ } ] ,
98+ AcpSessionUpdate :: SessionInfoUpdate {
99+ title : Some ( title) , ..
100+ } => vec ! [ WorkerEvent :: SessionTitleUpdated {
101+ session_id: session_id. to_string( ) ,
102+ title,
103+ } ] ,
104+ AcpSessionUpdate :: AvailableCommandsUpdate {
105+ available_commands, ..
106+ } => vec ! [ WorkerEvent :: AcpAvailableCommandsUpdated {
107+ commands: available_commands,
108+ } ] ,
109+ AcpSessionUpdate :: CurrentModeUpdate {
110+ current_mode_id, ..
111+ } => vec ! [ WorkerEvent :: AcpCurrentModeUpdated { current_mode_id } ] ,
112+ AcpSessionUpdate :: ConfigOptionUpdate { config_options, .. } => {
113+ vec ! [ WorkerEvent :: AcpConfigOptionsUpdated { config_options } ]
114+ }
115+ AcpSessionUpdate :: UsageUpdate {
116+ used, size, cost, ..
117+ } => vec ! [ WorkerEvent :: AcpUsageUpdated { used, size, cost } ] ,
118+ AcpSessionUpdate :: ToolCall {
119+ tool_call_id,
120+ title,
121+ kind,
122+ status,
123+ raw_input,
124+ raw_output,
125+ content,
126+ ..
127+ } => worker_events_from_acp_tool_call (
128+ AcpToolCallEventData {
129+ tool_call_id,
130+ title : Some ( title) ,
131+ status : Some ( status) ,
132+ raw_input,
133+ raw_output,
134+ content,
135+ } ,
136+ kind,
137+ terminal_state,
138+ ) ,
139+ AcpSessionUpdate :: ToolCallUpdate {
140+ tool_call_id,
141+ title,
142+ kind,
143+ status,
144+ raw_input,
145+ raw_output,
146+ content,
147+ ..
148+ } => worker_events_from_acp_tool_call_update (
149+ AcpToolCallEventData {
150+ tool_call_id,
151+ title,
152+ status,
153+ raw_input,
154+ raw_output,
155+ content,
156+ } ,
157+ kind,
158+ terminal_state,
159+ ) ,
160+ AcpSessionUpdate :: UserMessageChunk { .. }
161+ | AcpSessionUpdate :: SessionInfoUpdate { title : None , .. } => Vec :: new ( ) ,
162+ }
163+ }
164+ }
165+
34166pub ( super ) fn acp_terminal_output_event (
35167 params : & serde_json:: Value ,
36168 visible_terminal_ids : & HashSet < String > ,
@@ -80,128 +212,14 @@ pub(super) fn worker_events_from_acp_notification_with_terminal_state(
80212 if Some ( notification. session_id ) != active_session_id {
81213 return Vec :: new ( ) ;
82214 }
83- match notification. update {
84- AcpSessionUpdate :: AgentMessageChunk {
85- content,
86- message_id,
87- ..
88- } => acp_content_display_text ( & content)
89- . into_iter ( )
90- . map ( |delta| {
91- if let Some ( item_id) = message_item_id ( message_id. as_deref ( ) ) {
92- WorkerEvent :: TextItemDelta {
93- item_id,
94- kind : TextItemKind :: Assistant ,
95- delta,
96- }
97- } else {
98- WorkerEvent :: TextDelta ( delta)
99- }
100- } )
101- . collect ( ) ,
102- AcpSessionUpdate :: AgentThoughtChunk {
103- content,
104- message_id,
105- ..
106- } => acp_content_display_text ( & content)
107- . into_iter ( )
108- . map ( |delta| {
109- if let Some ( item_id) = message_item_id ( message_id. as_deref ( ) ) {
110- WorkerEvent :: TextItemDelta {
111- item_id,
112- kind : TextItemKind :: Reasoning ,
113- delta,
114- }
115- } else {
116- WorkerEvent :: ReasoningDelta ( delta)
117- }
118- } )
119- . collect ( ) ,
120- AcpSessionUpdate :: Plan { entries, .. } => vec ! [ WorkerEvent :: PlanUpdated {
121- explanation: None ,
122- steps: entries
123- . into_iter( )
124- . map( |entry| PlanStep {
125- text: entry. content,
126- status: match entry. status {
127- AcpPlanEntryStatus :: Pending => PlanStepStatus :: Pending ,
128- AcpPlanEntryStatus :: InProgress => PlanStepStatus :: InProgress ,
129- AcpPlanEntryStatus :: Completed => PlanStepStatus :: Completed ,
130- } ,
131- } )
132- . collect( ) ,
133- } ] ,
134- AcpSessionUpdate :: SessionInfoUpdate {
135- title : Some ( title) , ..
136- } => vec ! [ WorkerEvent :: SessionTitleUpdated {
137- session_id: notification. session_id. to_string( ) ,
138- title,
139- } ] ,
140- AcpSessionUpdate :: AvailableCommandsUpdate {
141- available_commands, ..
142- } => vec ! [ WorkerEvent :: AcpAvailableCommandsUpdated {
143- commands: available_commands,
144- } ] ,
145- AcpSessionUpdate :: CurrentModeUpdate {
146- current_mode_id, ..
147- } => vec ! [ WorkerEvent :: AcpCurrentModeUpdated { current_mode_id } ] ,
148- AcpSessionUpdate :: ConfigOptionUpdate { config_options, .. } => {
149- vec ! [ WorkerEvent :: AcpConfigOptionsUpdated { config_options } ]
150- }
151- AcpSessionUpdate :: UsageUpdate {
152- used, size, cost, ..
153- } => vec ! [ WorkerEvent :: AcpUsageUpdated { used, size, cost } ] ,
154- AcpSessionUpdate :: ToolCall {
155- tool_call_id,
156- title,
157- kind,
158- status,
159- raw_input,
160- raw_output,
161- content,
162- ..
163- } => worker_events_from_acp_tool_call (
164- AcpToolCallEventData {
165- tool_call_id,
166- title : Some ( title) ,
167- status : Some ( status) ,
168- raw_input,
169- raw_output,
170- content,
171- } ,
172- kind,
173- AcpTerminalRenderState {
174- visible_terminal_ids,
175- pending_terminal_output,
176- } ,
177- ) ,
178- AcpSessionUpdate :: ToolCallUpdate {
179- tool_call_id,
180- title,
181- kind,
182- status,
183- raw_input,
184- raw_output,
185- content,
186- ..
187- } => worker_events_from_acp_tool_call_update (
188- AcpToolCallEventData {
189- tool_call_id,
190- title,
191- status,
192- raw_input,
193- raw_output,
194- content,
195- } ,
196- kind,
197- AcpTerminalRenderState {
198- visible_terminal_ids,
199- pending_terminal_output,
200- } ,
201- ) ,
202- AcpSessionUpdate :: UserMessageChunk { .. }
203- | AcpSessionUpdate :: SessionInfoUpdate { title : None , .. } => Vec :: new ( ) ,
204- }
215+ Vec :: from ( AcpSessionUpdateRender {
216+ session_id : notification. session_id ,
217+ update : notification. update ,
218+ terminal_state : AcpTerminalRenderState {
219+ visible_terminal_ids,
220+ pending_terminal_output,
221+ } ,
222+ } )
205223}
206224
207225fn message_item_id ( message_id : Option < & str > ) -> Option < ItemId > {
0 commit comments