erosolar-cli 2.1.183 → 2.1.185

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2333,87 +2333,6 @@ export class InteractiveShell {
2333
2333
  }
2334
2334
  return false;
2335
2335
  }
2336
- /**
2337
- * Decide whether to automatically continue execution when the model stops after a plan/summary
2338
- * without taking actions. This keeps flows moving toward completion instead of stalling on planning.
2339
- */
2340
- shouldAutoEscalateToExecution(request, response, toolsUsed) {
2341
- // Only auto-escalate when the original request itself was action-oriented
2342
- if (!this.shouldAutoRunToCompletion(request)) {
2343
- return false;
2344
- }
2345
- if (!response || response.includes('TASK_FULLY_COMPLETE')) {
2346
- return false;
2347
- }
2348
- const lower = response.toLowerCase();
2349
- // Skip if the model explicitly says it is blocked
2350
- const blockerPatterns = [
2351
- /\bneed(s)?\s+(more\s+)?(info|information|details|clarification)\b/,
2352
- /\bmissing\s+(api\s*key|credentials?|access|permission|token)\b/,
2353
- /\b(no|not)\s+authorized\b/,
2354
- /\bcannot\s+(proceed|continue|start|run)\b/,
2355
- /\bblocked\b/,
2356
- ];
2357
- if (blockerPatterns.some((pattern) => pattern.test(lower))) {
2358
- return false;
2359
- }
2360
- const mutatingToolUsed = toolsUsed.some((tool) => WRITE_TOOL_NAMES.has(tool.toLowerCase()));
2361
- const planOnly = this.flowOrchestrator.isPlanOnlyResponse(response);
2362
- const lowActionDensity = response.split(/\s+/).length < 80;
2363
- // If it's clearly a plan-only response, continue regardless of prior tool usage
2364
- if (planOnly) {
2365
- return true;
2366
- }
2367
- // Thin responses without any mutating work should keep pushing toward completion
2368
- if (!mutatingToolUsed && lowActionDensity) {
2369
- return true;
2370
- }
2371
- return false;
2372
- }
2373
- /**
2374
- * Build a follow-through request when the model stops after planning instead of executing.
2375
- */
2376
- maybeAutoFollowThrough(request, response, toolsUsed) {
2377
- if (!this.shouldAutoEscalateToExecution(request, response, toolsUsed)) {
2378
- return null;
2379
- }
2380
- const prompt = `${request.trim()}
2381
-
2382
- Execute the plan you outlined. Use the available tools (bash, edits, git) to take the next actions and keep going until the request is fully accomplished. Do not restate the plan—perform the steps and report progress. Reply with TASK_FULLY_COMPLETE only when the work is truly done.`;
2383
- return {
2384
- prompt,
2385
- reason: 'Plan-only or low-action response detected; auto-continuing to complete the task.',
2386
- };
2387
- }
2388
- /**
2389
- * Ensure informational requests produce a user-facing answer rather than stopping after planning.
2390
- */
2391
- maybeAutoAnswerInformational(request, response) {
2392
- const trimmedRequest = request.trim();
2393
- const trimmedResponse = response.trim();
2394
- if (!trimmedResponse) {
2395
- return null;
2396
- }
2397
- if (!this.flowOrchestrator.isInformationalRequest(trimmedRequest)) {
2398
- return null;
2399
- }
2400
- if (trimmedResponse.includes('TASK_FULLY_COMPLETE')) {
2401
- return null;
2402
- }
2403
- const providesAnswer = this.flowOrchestrator.responseAnswersUserRequest(trimmedResponse);
2404
- const planOnly = this.flowOrchestrator.isPlanOnlyResponse(trimmedResponse);
2405
- const indicatesIncomplete = this.flowOrchestrator.responseIndicatesIncompleteWork(trimmedResponse);
2406
- if (providesAnswer && !planOnly && !indicatesIncomplete) {
2407
- return null;
2408
- }
2409
- const prompt = `${trimmedRequest}
2410
-
2411
- You have gathered context but did not provide a clear answer. Respond now with a concise, helpful summary that addresses the request directly. Include the key findings (not the plan), and end with "TASK_FULLY_COMPLETE" if nothing else is needed.`;
2412
- return {
2413
- prompt,
2414
- reason: 'Informational request lacked a user-facing answer; prompting to finish helpfully.',
2415
- };
2416
- }
2417
2336
  isExitCommand(input) {
2418
2337
  const lower = input.trim().toLowerCase();
2419
2338
  return (lower === 'exit' ||
@@ -5861,20 +5780,22 @@ You have gathered context but did not provide a clear answer. Respond now with a
5861
5780
  this.clearInlinePanel();
5862
5781
  this.syncRendererInput();
5863
5782
  }
5864
- async processRequest(request) {
5783
+ async runFlowControlledTask(initialRequest, options) {
5784
+ const { maxIterations, mode } = options;
5785
+ const followUpType = mode === 'continuous' ? 'continuous' : 'request';
5865
5786
  if (this.isProcessing) {
5866
- this.enqueueFollowUpAction({ type: 'request', text: request });
5867
- return;
5787
+ this.enqueueFollowUpAction({ type: followUpType, text: initialRequest });
5788
+ return null;
5868
5789
  }
5869
5790
  if (!this.agent && !this.rebuildAgent()) {
5870
5791
  display.showWarning('Configure an API key via /secrets before sending requests.');
5871
- return;
5792
+ return null;
5872
5793
  }
5873
5794
  this.inlinePanelScopeActive = false;
5874
5795
  this.clearInlinePanel();
5875
5796
  const agent = this.agent;
5876
5797
  if (!agent) {
5877
- return;
5798
+ return null;
5878
5799
  }
5879
5800
  this.toolsUsedThisRun = [];
5880
5801
  this.currentToolCalls = [];
@@ -5885,200 +5806,41 @@ You have gathered context but did not provide a clear answer. Respond now with a
5885
5806
  else {
5886
5807
  this.resetNetworkRetryState();
5887
5808
  }
5888
- // Reset per-request render tracking
5889
5809
  this.responseRendered = false;
5890
- if (this.shouldLogPrompt(request)) {
5891
- this.logUserPrompt(request);
5810
+ if (this.shouldLogPrompt(initialRequest)) {
5811
+ this.logUserPrompt(initialRequest);
5892
5812
  }
5893
5813
  this.isProcessing = true;
5894
5814
  this.uiUpdates.setMode('processing');
5895
- this.streamingTokenCount = 0; // Reset token counter for new request
5815
+ this.streamingTokenCount = 0;
5896
5816
  this.terminalInput.setStreaming(true);
5897
- // Keep the persistent input/control bar active as we transition into streaming.
5898
5817
  this.syncRendererInput();
5899
5818
  this.renderer?.render();
5900
- const requestStartTime = Date.now(); // Alpha Zero 2 timing
5901
- // Clear previous parallel agents and start fresh for new request
5819
+ const overallStartTime = Date.now();
5902
5820
  const parallelManager = getParallelAgentManager();
5903
5821
  parallelManager.clear();
5904
5822
  parallelManager.startBatch();
5905
- // AlphaZero: Track task for learning
5906
- this.lastUserQuery = request;
5907
- this.currentTaskType = classifyTaskType(request);
5823
+ this.lastUserQuery = initialRequest;
5824
+ this.currentTaskType = classifyTaskType(initialRequest);
5908
5825
  this.currentToolCalls = [];
5909
5826
  this.clearToolUsageMeta();
5910
5827
  this.renderer?.setActivity('Starting...');
5911
- this.uiAdapter.startProcessing('Working on your request');
5828
+ this.uiAdapter.startProcessing(mode === 'continuous' ? 'Continuous execution mode' : 'Working on your request');
5912
5829
  this.setProcessingStatus();
5913
5830
  this.beginAiRuntime();
5914
- let responseText = '';
5915
- let autoFollowThrough = null;
5916
- let informationalFollowUp = null;
5917
- try {
5918
- // Start streaming - no header needed, the input area already provides context
5919
- this.startStreamingHeartbeat('Streaming response');
5920
- responseText = await agent.send(request, true);
5921
- this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
5922
- await this.awaitPendingCleanup();
5923
- this.captureHistorySnapshot();
5924
- this.autosaveIfEnabled();
5925
- // Track metrics with Alpha Zero 2
5926
- const elapsedMs = Date.now() - requestStartTime;
5927
- this.alphaZeroMetrics.recordMessage(elapsedMs);
5928
- if (!responseText?.trim()) {
5929
- display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
5930
- }
5931
- // AlphaZero: Extract and track tool calls from response
5932
- const toolsUsed = this.getExecutedTools(responseText);
5933
- this.currentToolCalls = toolsUsed.map(name => ({
5934
- name,
5935
- arguments: {},
5936
- success: true, // Assume success if we got here
5937
- duration: 0,
5938
- }));
5939
- autoFollowThrough = this.maybeAutoFollowThrough(request, responseText, toolsUsed);
5940
- informationalFollowUp = this.maybeAutoAnswerInformational(request, responseText);
5941
- // AlphaZero: Check for failure in response
5942
- const failure = detectFailure(responseText, {
5943
- toolCalls: this.currentToolCalls,
5944
- userMessage: request,
5945
- });
5946
- if (failure) {
5947
- this.lastFailure = failure;
5948
- // Check if we have a recovery strategy
5949
- const strategy = findRecoveryStrategy(failure);
5950
- if (strategy) {
5951
- display.showSystemMessage(`🔄 Found recovery strategy for this type of issue (success rate: ${Math.round(strategy.successRate * 100)}%)`);
5952
- }
5953
- }
5954
- else {
5955
- // Success - record the tool pattern for this task type
5956
- if (this.currentToolCalls.length > 0) {
5957
- const toolPattern = {
5958
- taskType: this.currentTaskType,
5959
- toolSequence: this.currentToolCalls.map(t => t.name),
5960
- successRate: 1.0,
5961
- avgDuration: elapsedMs,
5962
- occurrences: 1,
5963
- };
5964
- addToolPattern(this.currentTaskType, toolPattern);
5965
- }
5966
- // Clear action history on success
5967
- clearActionHistory();
5968
- this.lastFailure = null;
5969
- }
5970
- }
5971
- catch (error) {
5972
- const handled = this.handleProviderError(error, () => this.processRequest(request));
5973
- if (!handled) {
5974
- // Pass full error object for enhanced formatting with stack trace
5975
- display.showError(error instanceof Error ? error.message : String(error), error);
5976
- }
5977
- }
5978
- finally {
5979
- // Fallback: if no assistant message was rendered (e.g., streaming hiccup), show the full response
5980
- if (!this.responseRendered && responseText.trim()) {
5981
- const finalText = responseText.trim();
5982
- display.showAssistantMessage(finalText, { isFinal: true });
5983
- this.ui.controller.recordAssistantResponse(finalText, {
5984
- source: 'final',
5985
- });
5986
- this.responseRendered = true;
5987
- }
5988
- this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
5989
- display.stopThinking(false);
5990
- this.uiUpdates.setMode('processing');
5991
- this.stopStreamingHeartbeat('complete', { quiet: true });
5992
- this.endAiRuntime();
5993
- this.isProcessing = false;
5994
- this.terminalInput.setStreaming(false);
5995
- this.uiAdapter.endProcessing('Ready for prompts');
5996
- this.updateToolUsageMeta(this.uiAdapter.getToolUsageSummary({ plain: true }));
5997
- this.setIdleStatus();
5998
- this.updateStatusMessage(null);
5999
- if (autoFollowThrough) {
6000
- display.showSystemMessage(`🔁 Auto-follow-through: ${autoFollowThrough.reason}`);
6001
- this.enqueueFollowUpAction({ type: 'continuous', text: autoFollowThrough.prompt });
6002
- }
6003
- if (informationalFollowUp) {
6004
- display.showSystemMessage(`🔁 Auto-follow-up: ${informationalFollowUp.reason}`);
6005
- this.enqueueFollowUpAction({ type: 'request', text: informationalFollowUp.prompt });
6006
- }
6007
- this.toolsUsedThisRun = [];
6008
- queueMicrotask(() => this.uiUpdates.setMode('idle'));
6009
- // CRITICAL: Ensure readline prompt is active for user input
6010
- // Erosolar-CLI style: New prompt naturally appears at bottom
6011
- this.ensureReadlineReady();
6012
- this.scheduleQueueProcessing();
6013
- this.maybeProcessPromptInbox();
6014
- this.refreshQueueIndicators();
6015
- }
6016
- }
6017
- /**
6018
- * Process a continuous/infinite loop request.
6019
- * Runs the agent in a loop until:
6020
- * 1. The agent indicates completion (verified by AI confirmation)
6021
- * 2. User interrupts (Ctrl+C)
6022
- * 3. Maximum iterations reached (safety limit)
6023
- *
6024
- * Uses intelligent task completion detection with AI verification
6025
- * to ensure tasks are truly complete before stopping.
6026
- *
6027
- * Context is automatically managed - overflow errors trigger auto-recovery.
6028
- */
6029
- async processContinuousRequest(initialRequest) {
6030
- const MAX_ITERATIONS = 100; // Safety limit to prevent truly infinite loops
6031
- if (this.isProcessing) {
6032
- this.enqueueFollowUpAction({ type: 'continuous', text: initialRequest });
6033
- return;
6034
- }
6035
- if (!this.agent && !this.rebuildAgent()) {
6036
- display.showWarning('Configure an API key via /secrets before sending requests.');
6037
- return;
6038
- }
6039
- this.inlinePanelScopeActive = false;
6040
- this.clearInlinePanel();
6041
- const agent = this.agent;
6042
- if (!agent) {
6043
- return;
6044
- }
6045
- this.toolsUsedThisRun = [];
6046
- this.currentToolCalls = [];
6047
- this.lastUserQuery = initialRequest;
6048
- this.clearToolUsageMeta();
6049
- this.isProcessing = true;
6050
- this.uiUpdates.setMode('processing');
6051
- this.streamingTokenCount = 0; // Reset token counter for new request
6052
- this.terminalInput.setStreaming(true);
6053
- if (this.suppressNextNetworkReset) {
6054
- this.suppressNextNetworkReset = false;
6055
- }
6056
- else {
6057
- this.resetNetworkRetryState();
6058
- }
6059
- const overallStartTime = Date.now();
6060
- // Clear previous parallel agents and start fresh for continuous mode
6061
- const parallelManager = getParallelAgentManager();
6062
- parallelManager.clear();
6063
- parallelManager.startBatch();
6064
- // Initialize the task completion detector
5831
+ this.startStreamingHeartbeat(mode === 'continuous' ? 'Streaming' : 'Streaming response');
6065
5832
  const completionDetector = getTaskCompletionDetector();
6066
5833
  completionDetector.reset();
6067
- // Display user prompt in scrollback (Claude Code style)
6068
- this.logUserPrompt(initialRequest);
6069
- display.showSystemMessage(`Continuous mode active. Ctrl+C to stop.`);
6070
- this.uiAdapter.startProcessing('Continuous execution mode');
6071
- this.setProcessingStatus();
6072
- this.beginAiRuntime();
6073
- // No streaming header - just start streaming directly
6074
- this.startStreamingHeartbeat('Streaming');
6075
5834
  this.flowOrchestrator.start(initialRequest);
6076
- let iteration = 0;
6077
- try {
6078
- // Enhance initial prompt with git context for self-improvement tasks
6079
- let currentPrompt = initialRequest;
6080
- if (this.isSelfImprovementRequest(initialRequest)) {
6081
- currentPrompt = `${initialRequest}
5835
+ if (mode === 'continuous') {
5836
+ display.showSystemMessage('Continuous mode active. Ctrl+C to stop.');
5837
+ }
5838
+ else {
5839
+ display.showSystemMessage('Flow orchestrator engaged; running until the request is satisfied.');
5840
+ }
5841
+ let currentPrompt = initialRequest;
5842
+ if (this.isSelfImprovementRequest(initialRequest)) {
5843
+ currentPrompt = `${initialRequest}
6082
5844
 
6083
5845
  IMPORTANT: You have full git access. After making improvements:
6084
5846
  1. Use bash to run: git status (see changes)
@@ -6088,22 +5850,26 @@ IMPORTANT: You have full git access. After making improvements:
6088
5850
 
6089
5851
  Commit frequently with descriptive messages. Push when ready.
6090
5852
  When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
6091
- }
6092
- while (iteration < MAX_ITERATIONS) {
5853
+ }
5854
+ let iteration = 0;
5855
+ let lastResponseText = '';
5856
+ let lastToolsUsed = [];
5857
+ let result = null;
5858
+ try {
5859
+ while (iteration < maxIterations) {
6093
5860
  iteration++;
6094
5861
  this.toolsUsedThisRun = [];
6095
- display.showSystemMessage(`\n📍 Iteration ${iteration}/${MAX_ITERATIONS}`);
5862
+ display.showSystemMessage(`\n📍 Iteration ${iteration}/${maxIterations}`);
6096
5863
  this.updateStatusMessage(`Working on iteration ${iteration}...`);
6097
5864
  try {
6098
- // Send the request and capture the response (streaming disabled)
6099
5865
  display.showThinking('Responding...');
6100
5866
  this.refreshStatusLine(true);
6101
5867
  const response = await agent.send(currentPrompt, true);
5868
+ lastResponseText = response ?? '';
6102
5869
  this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
6103
5870
  await this.awaitPendingCleanup();
6104
5871
  this.captureHistorySnapshot();
6105
5872
  this.autosaveIfEnabled();
6106
- // Track metrics
6107
5873
  const elapsedMs = Date.now() - overallStartTime;
6108
5874
  this.alphaZeroMetrics.recordMessage(elapsedMs);
6109
5875
  if (!response?.trim()) {
@@ -6113,10 +5879,9 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
6113
5879
  The previous reply was empty. Resume the task now: take the next action, call the necessary tools, and report progress.`;
6114
5880
  continue;
6115
5881
  }
6116
- // Extract tools used from the response (look for tool call patterns)
6117
5882
  const toolsUsed = this.getExecutedTools(response);
5883
+ lastToolsUsed = toolsUsed;
6118
5884
  toolsUsed.forEach(tool => completionDetector.recordToolCall(tool, true, true));
6119
- // Use intelligent completion detection
6120
5885
  const completionAnalysis = completionDetector.analyzeCompletion(response, toolsUsed);
6121
5886
  display.showSystemMessage(`📈 Completion confidence: ${(completionAnalysis.confidence * 100).toFixed(0)}%`);
6122
5887
  const decision = this.flowOrchestrator.decide({
@@ -6154,39 +5919,50 @@ The previous reply was empty. Resume the task now: take the next action, call th
6154
5919
  }
6155
5920
  currentPrompt = decision.prompt;
6156
5921
  }
6157
- // Small delay between iterations to prevent rate limiting
6158
5922
  await new Promise(resolve => setTimeout(resolve, 500));
6159
5923
  }
6160
5924
  catch (error) {
6161
5925
  display.stopThinking(false);
6162
- // Handle context overflow specially - the agent should auto-recover
6163
- // but if it propagates here, we continue the loop
6164
5926
  if (this.isContextOverflowError(error)) {
6165
5927
  display.showSystemMessage(`⚡ Context overflow handled. Continuing with reduced context...`);
6166
- // The agent.ts should have already handled recovery
6167
- // Continue to next iteration
6168
5928
  continue;
6169
5929
  }
6170
- // For other errors, check if handled by provider error handler
6171
- const handled = this.handleProviderError(error, () => this.processContinuousRequest(initialRequest));
5930
+ const handled = this.handleProviderError(error, () => this.runFlowControlledTask(initialRequest, options));
6172
5931
  if (!handled) {
6173
5932
  display.showError(error instanceof Error ? error.message : String(error), error);
6174
5933
  break;
6175
5934
  }
6176
5935
  }
6177
5936
  }
6178
- if (iteration >= MAX_ITERATIONS) {
6179
- display.showWarning(`\n⚠️ Reached maximum iterations (${MAX_ITERATIONS}). Stopping to prevent infinite loop.`);
5937
+ if (iteration >= maxIterations) {
5938
+ display.showWarning(`\n⚠️ Reached maximum iterations (${maxIterations}). Stopping to prevent infinite loop.`);
5939
+ }
5940
+ if (!this.responseRendered && lastResponseText.trim()) {
5941
+ const finalText = lastResponseText.trim();
5942
+ display.showAssistantMessage(finalText, { isFinal: true });
5943
+ this.ui.controller.recordAssistantResponse(finalText, {
5944
+ source: 'final',
5945
+ });
5946
+ this.responseRendered = true;
6180
5947
  }
5948
+ result = {
5949
+ finalResponse: lastResponseText,
5950
+ toolsUsed: lastToolsUsed,
5951
+ iterations: iteration,
5952
+ elapsedMs: Date.now() - overallStartTime,
5953
+ };
6181
5954
  }
6182
5955
  finally {
6183
5956
  this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
6184
5957
  const totalElapsed = Date.now() - overallStartTime;
6185
5958
  const minutes = Math.floor(totalElapsed / 60000);
6186
5959
  const seconds = Math.floor((totalElapsed % 60000) / 1000);
6187
- display.showSystemMessage(`\n🏁 Continuous execution completed: ${iteration} iterations, ${minutes}m ${seconds}s total`);
6188
- // Reset completion detector for next task
5960
+ const completionLabel = mode === 'continuous'
5961
+ ? `\n🏁 Continuous execution completed: ${iteration} iterations, ${minutes}m ${seconds}s total`
5962
+ : `\n🏁 Task run completed: ${iteration} iterations, ${minutes}m ${seconds}s total`;
5963
+ display.showSystemMessage(completionLabel);
6189
5964
  resetTaskCompletionDetector();
5965
+ display.stopThinking(false);
6190
5966
  this.uiUpdates.setMode('processing');
6191
5967
  this.stopStreamingHeartbeat('complete', { quiet: true });
6192
5968
  this.endAiRuntime();
@@ -6198,13 +5974,76 @@ The previous reply was empty. Resume the task now: take the next action, call th
6198
5974
  this.updateStatusMessage(null);
6199
5975
  this.toolsUsedThisRun = [];
6200
5976
  queueMicrotask(() => this.uiUpdates.setMode('idle'));
6201
- // CRITICAL: Ensure readline prompt is active for user input
6202
- // Erosolar-CLI style: New prompt naturally appears at bottom
6203
5977
  this.ensureReadlineReady();
6204
5978
  this.scheduleQueueProcessing();
6205
5979
  this.maybeProcessPromptInbox();
6206
5980
  this.refreshQueueIndicators();
6207
5981
  }
5982
+ return result;
5983
+ }
5984
+ handleFlowRunOutcome(request, result) {
5985
+ this.currentToolCalls = result.toolsUsed.map((name) => ({
5986
+ name,
5987
+ arguments: {},
5988
+ success: true,
5989
+ duration: 0,
5990
+ }));
5991
+ const failure = detectFailure(result.finalResponse, {
5992
+ toolCalls: this.currentToolCalls,
5993
+ userMessage: request,
5994
+ });
5995
+ if (failure) {
5996
+ this.lastFailure = failure;
5997
+ const strategy = findRecoveryStrategy(failure);
5998
+ if (strategy) {
5999
+ display.showSystemMessage(`🔄 Found recovery strategy for this type of issue (success rate: ${Math.round(strategy.successRate * 100)}%)`);
6000
+ }
6001
+ return;
6002
+ }
6003
+ if (this.currentToolCalls.length > 0) {
6004
+ const toolPattern = {
6005
+ taskType: this.currentTaskType,
6006
+ toolSequence: this.currentToolCalls.map((t) => t.name),
6007
+ successRate: 1.0,
6008
+ avgDuration: result.elapsedMs,
6009
+ occurrences: 1,
6010
+ };
6011
+ addToolPattern(this.currentTaskType, toolPattern);
6012
+ }
6013
+ clearActionHistory();
6014
+ this.lastFailure = null;
6015
+ }
6016
+ async processRequest(request) {
6017
+ const result = await this.runFlowControlledTask(request, {
6018
+ maxIterations: 12,
6019
+ mode: 'standard',
6020
+ });
6021
+ if (!result) {
6022
+ return;
6023
+ }
6024
+ this.handleFlowRunOutcome(request, result);
6025
+ }
6026
+ /**
6027
+ * Process a continuous/infinite loop request.
6028
+ * Runs the agent in a loop until:
6029
+ * 1. The agent indicates completion (verified by AI confirmation)
6030
+ * 2. User interrupts (Ctrl+C)
6031
+ * 3. Maximum iterations reached (safety limit)
6032
+ *
6033
+ * Uses intelligent task completion detection with AI verification
6034
+ * to ensure tasks are truly complete before stopping.
6035
+ *
6036
+ * Context is automatically managed - overflow errors trigger auto-recovery.
6037
+ */
6038
+ async processContinuousRequest(initialRequest) {
6039
+ const result = await this.runFlowControlledTask(initialRequest, {
6040
+ maxIterations: 100,
6041
+ mode: 'continuous',
6042
+ });
6043
+ if (!result) {
6044
+ return;
6045
+ }
6046
+ this.handleFlowRunOutcome(initialRequest, result);
6208
6047
  }
6209
6048
  /**
6210
6049
  * Resolve executed tools for the current turn. Prefer the actual tool