orquesta-cli 0.2.95 → 0.2.96
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.
- package/dist/core/config/config-manager.d.ts +2 -0
- package/dist/core/config/config-manager.js +10 -0
- package/dist/core/slash-command-handler.js +8 -1
- package/dist/orchestration/plan-executor.js +23 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/ui/components/TodoListView.js +2 -2
- package/package.json +1 -1
|
@@ -60,6 +60,8 @@ export declare class ConfigManager {
|
|
|
60
60
|
setMaxParallelWorkers(n: number): Promise<void>;
|
|
61
61
|
isRefinerEnabled(): boolean;
|
|
62
62
|
setRefinerEnabled(enabled: boolean): Promise<void>;
|
|
63
|
+
isSingleAgentMode(): boolean;
|
|
64
|
+
setSingleAgentMode(enabled: boolean): Promise<void>;
|
|
63
65
|
isWorktreeIsolationEnabled(): boolean;
|
|
64
66
|
setWorktreeIsolationEnabled(enabled: boolean): Promise<void>;
|
|
65
67
|
}
|
|
@@ -415,6 +415,16 @@ export class ConfigManager {
|
|
|
415
415
|
config.orchestration.refinerEnabled = enabled;
|
|
416
416
|
await this.saveConfig();
|
|
417
417
|
}
|
|
418
|
+
isSingleAgentMode() {
|
|
419
|
+
return this.config?.orchestration?.singleAgentMode ?? false;
|
|
420
|
+
}
|
|
421
|
+
async setSingleAgentMode(enabled) {
|
|
422
|
+
const config = this.getConfig();
|
|
423
|
+
if (!config.orchestration)
|
|
424
|
+
config.orchestration = {};
|
|
425
|
+
config.orchestration.singleAgentMode = enabled;
|
|
426
|
+
await this.saveConfig();
|
|
427
|
+
}
|
|
418
428
|
isWorktreeIsolationEnabled() {
|
|
419
429
|
return this.config?.orchestration?.worktreeIsolation ?? false;
|
|
420
430
|
}
|
|
@@ -141,7 +141,8 @@ export async function executeSlashCommand(command, context) {
|
|
|
141
141
|
const parallel = configManager.getMaxParallelWorkers();
|
|
142
142
|
const refiner = configManager.isRefinerEnabled() ? 'on' : 'off';
|
|
143
143
|
const worktree = configManager.isWorktreeIsolationEnabled() ? 'on' : 'off';
|
|
144
|
-
|
|
144
|
+
const single = configManager.isSingleAgentMode() ? 'on' : 'off';
|
|
145
|
+
return `Multi-role orchestration\n\n${lines.join('\n')}\n\n max parallel workers: ${parallel}\n refiner pass: ${refiner}\n worktree isolation: ${worktree}\n single-agent mode: ${single}\n\nUsage:\n /role planner <model-id>\n /role executor <model-id>\n /role refiner <model-id> | off\n /role parallel <N>\n /role worktree on|off\n /role single on|off (skip planner; one accumulative agent — best for debugging)\n /role clear`;
|
|
145
146
|
};
|
|
146
147
|
let body;
|
|
147
148
|
try {
|
|
@@ -166,6 +167,12 @@ export async function executeSlashCommand(command, context) {
|
|
|
166
167
|
await configManager.setWorktreeIsolationEnabled(args[1] === 'on');
|
|
167
168
|
body = `Worktree isolation: ${args[1]}.`;
|
|
168
169
|
}
|
|
170
|
+
else if (args[0] === 'single' && (args[1] === 'on' || args[1] === 'off')) {
|
|
171
|
+
await configManager.setSingleAgentMode(args[1] === 'on');
|
|
172
|
+
body = args[1] === 'on'
|
|
173
|
+
? 'Single-agent mode ON — planner/orchestrator bypassed; one accumulative agent (best for debugging/investigation).'
|
|
174
|
+
: 'Single-agent mode OFF — planner + orchestrator restored.';
|
|
175
|
+
}
|
|
169
176
|
else if ((args[0] === 'planner' || args[0] === 'executor' || args[0] === 'refiner') && args[1]) {
|
|
170
177
|
const role = args[0];
|
|
171
178
|
if (role === 'refiner' && args[1] === 'off') {
|
|
@@ -106,6 +106,29 @@ export class PlanExecutor {
|
|
|
106
106
|
throw new Error('INTERRUPTED');
|
|
107
107
|
}
|
|
108
108
|
let currentMessages = messages;
|
|
109
|
+
if (configManager.isSingleAgentMode()) {
|
|
110
|
+
logger.flow('Single-agent mode — bypassing planner/orchestrator');
|
|
111
|
+
callbacks.setExecutionPhase('executing');
|
|
112
|
+
callbacks.setCurrentActivity('Working (single-agent)');
|
|
113
|
+
const saTools = toolRegistry.getLLMToolDefinitions();
|
|
114
|
+
const lastUserIdx = currentMessages.map(m => m.role).lastIndexOf('user');
|
|
115
|
+
const saMessages = (lastUserIdx >= 0 && currentMessages[lastUserIdx]?.content === userMessage)
|
|
116
|
+
? currentMessages
|
|
117
|
+
: [...currentMessages, { role: 'user', content: userMessage }];
|
|
118
|
+
const saExecutorModel = configManager.getRoleModel('executor');
|
|
119
|
+
const saResult = await llmClient.chatCompletionWithTools(saMessages, saTools, {
|
|
120
|
+
getPendingMessage: callbacks.getPendingMessage,
|
|
121
|
+
clearPendingMessage: callbacks.clearPendingMessage,
|
|
122
|
+
...(saExecutorModel ? { model: saExecutorModel } : {}),
|
|
123
|
+
});
|
|
124
|
+
currentMessages = [...saMessages, ...saResult.allMessages.slice(saMessages.length)];
|
|
125
|
+
callbacks.setMessages([...currentMessages]);
|
|
126
|
+
sessionManager.autoSaveCurrentSession(currentMessages);
|
|
127
|
+
callbacks.setExecutionPhase('idle');
|
|
128
|
+
auditLog.emit(auditSid, 'run.complete', { runId, mode: 'single-agent', success: true });
|
|
129
|
+
logger.exit('PlanExecutor.executePlanMode', { singleAgent: true });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
109
132
|
callbacks.setCurrentActivity('Thinking');
|
|
110
133
|
const plannerModel = configManager.getRoleModel('planner');
|
|
111
134
|
const planningLLM = new PlanningLLM(llmClient, plannerModel ?? undefined);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Box, Text } from 'ink';
|
|
|
3
3
|
import Spinner from 'ink-spinner';
|
|
4
4
|
import { logger } from '../../utils/logger.js';
|
|
5
5
|
const STATUS_CONFIG = {
|
|
6
|
-
completed: { icon: '☑', color: '
|
|
6
|
+
completed: { icon: '☑', color: 'green' },
|
|
7
7
|
in_progress: { icon: '☐', color: 'white' },
|
|
8
8
|
failed: { icon: '☒', color: 'red' },
|
|
9
9
|
pending: { icon: '☐', color: 'gray' },
|
|
@@ -57,7 +57,7 @@ export const TodoListView = ({ todos, showProgressBar = true, }) => {
|
|
|
57
57
|
React.createElement(Box, null,
|
|
58
58
|
React.createElement(Box, { width: 2 }, isInProgress ? (React.createElement(Text, { color: "blueBright" },
|
|
59
59
|
React.createElement(Spinner, { type: "dots2" }))) : (React.createElement(Text, { color: config.color }, config.icon))),
|
|
60
|
-
React.createElement(Text, { color: isCompleted ? '
|
|
60
|
+
React.createElement(Text, { color: isCompleted ? 'green' : isInProgress ? 'white' : 'gray', dimColor: false, bold: isInProgress }, todo.title),
|
|
61
61
|
isInProgress && React.createElement(Text, { color: "blueBright" }, " \u2190"),
|
|
62
62
|
todo.dependsOn && todo.dependsOn.length > 0 && (React.createElement(Text, { color: "gray", dimColor: true },
|
|
63
63
|
" (after ",
|