@@ -168,110 +168,7 @@ func (r *Runtime) handlePrompt(ctx context.Context, evt InputEvent) error {
168168 return nil
169169}
170170
171- func (r * Runtime ) planExecutionLoop (ctx context.Context ) {
172- for {
173- if ctx .Err () != nil {
174- return
175- }
176-
177- pass := r .incrementPassCount ()
178- r .options .Metrics .RecordPass (pass )
179- r .options .Logger .Info (ctx , "Starting plan execution pass" ,
180- Field ("pass" , pass ),
181- )
182-
183- if r .options .MaxPasses > 0 && pass > r .options .MaxPasses {
184- message := fmt .Sprintf ("Maximum pass limit (%d) reached. Stopping execution." , r .options .MaxPasses )
185- r .emit (RuntimeEvent {
186- Type : EventTypeError ,
187- Message : message ,
188- Level : StatusLevelError ,
189- Metadata : map [string ]any {"max_passes" : r .options .MaxPasses , "pass" : pass },
190- })
191- r .emitRequestInput ("Pass limit reached. Provide additional guidance to continue." )
192- if r .options .HandsFree {
193- r .close ()
194- }
195- return
196- }
197-
198- r .emit (RuntimeEvent {
199- Type : EventTypeStatus ,
200- Message : fmt .Sprintf ("Starting plan execution pass #%d." , pass ),
201- Level : StatusLevelInfo ,
202- })
203-
204- plan , toolCall , err := r .requestPlan (ctx )
205- if err != nil {
206- r .options .Logger .Error (ctx , "Failed to request plan from OpenAI" , err ,
207- Field ("pass" , pass ),
208- )
209- r .emit (RuntimeEvent {
210- Type : EventTypeError ,
211- Message : fmt .Sprintf ("Failed to contact OpenAI: %v" , err ),
212- Level : StatusLevelError ,
213- })
214- r .emitRequestInput ("You can provide another prompt." )
215- return
216- }
217-
218- if plan == nil {
219- r .options .Logger .Error (ctx , "Received nil plan response" , nil ,
220- Field ("pass" , pass ),
221- )
222- r .emit (RuntimeEvent {
223- Type : EventTypeError ,
224- Message : "Received nil plan response." ,
225- Level : StatusLevelError ,
226- })
227- r .emitRequestInput ("Unable to continue plan execution. Provide the next instruction." )
228- return
229- }
230-
231- execCount := r .recordPlanResponse (plan , toolCall )
232-
233- if plan .RequireHumanInput {
234- // The assistant explicitly requested help from the human, so surface the
235- // request and pause automated execution until the user responds.
236- r .appendToolObservation (toolCall , PlanObservationPayload {
237- Summary : "Assistant requested additional input before continuing the plan." ,
238- })
239- r .emitRequestInput ("Assistant requested additional input before continuing." )
240- return
241- }
242-
243- if execCount == 0 {
244- r .appendToolObservation (toolCall , PlanObservationPayload {
245- Summary : "Assistant returned a plan without executable steps." ,
246- })
247- r .emit (RuntimeEvent {
248- Type : EventTypeStatus ,
249- Message : "Plan has no executable steps." ,
250- Level : StatusLevelInfo ,
251- })
252- if r .options .HandsFree {
253- summary := fmt .Sprintf ("Hands-free session complete after %d pass(es); assistant reported no further work." , pass )
254- if trimmed := strings .TrimSpace (plan .Message ); trimmed != "" {
255- summary = fmt .Sprintf ("%s Summary: %s" , summary , trimmed )
256- }
257- r .emit (RuntimeEvent {
258- Type : EventTypeStatus ,
259- Message : summary ,
260- Level : StatusLevelInfo ,
261- })
262- r .close ()
263- return
264- }
265- r .emitRequestInput ("Plan has no executable steps. Provide the next instruction." )
266- return
267- }
268-
269- r .executePendingCommands (ctx , toolCall )
270- if ctx .Err () != nil {
271- return
272- }
273- }
274- }
171+ // planExecutionLoop is now implemented in plan_execution.go
275172
276173// requestPlan centralizes the logic for requesting a new plan from the assistant.
277174// It snapshots the history to guarantee a consistent view, forwards the request
0 commit comments