@yu_robotics/remote-cli 1.1.21 → 1.1.33
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/client/MessageHandler.d.ts +23 -55
- package/dist/client/MessageHandler.d.ts.map +1 -1
- package/dist/client/MessageHandler.js +289 -265
- package/dist/client/MessageHandler.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +22 -11
- package/dist/commands/start.js.map +1 -1
- package/dist/executor/ClaudePersistentExecutor.d.ts +1 -1
- package/dist/executor/ClaudePersistentExecutor.d.ts.map +1 -1
- package/dist/executor/ClaudePersistentExecutor.js +17 -6
- package/dist/executor/ClaudePersistentExecutor.js.map +1 -1
- package/dist/executor/GeminiExecutor.d.ts +12 -0
- package/dist/executor/GeminiExecutor.d.ts.map +1 -1
- package/dist/executor/GeminiExecutor.js +174 -54
- package/dist/executor/GeminiExecutor.js.map +1 -1
- package/dist/executor/acp/SessionManager.d.ts +8 -0
- package/dist/executor/acp/SessionManager.d.ts.map +1 -1
- package/dist/executor/acp/SessionManager.js +18 -0
- package/dist/executor/acp/SessionManager.js.map +1 -1
- package/dist/executor/index.d.ts +1 -1
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +3 -3
- package/dist/executor/index.js.map +1 -1
- package/dist/thread/ThreadExecutorPool.d.ts +57 -0
- package/dist/thread/ThreadExecutorPool.d.ts.map +1 -0
- package/dist/thread/ThreadExecutorPool.js +104 -0
- package/dist/thread/ThreadExecutorPool.js.map +1 -0
- package/dist/thread/ThreadManager.d.ts +65 -0
- package/dist/thread/ThreadManager.d.ts.map +1 -0
- package/dist/thread/ThreadManager.js +182 -0
- package/dist/thread/ThreadManager.js.map +1 -0
- package/dist/thread/index.d.ts +6 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/thread/index.js +12 -0
- package/dist/thread/index.js.map +1 -0
- package/dist/thread/types.d.ts +28 -0
- package/dist/thread/types.d.ts.map +1 -0
- package/dist/thread/types.js +11 -0
- package/dist/thread/types.js.map +1 -0
- package/dist/types/index.d.ts +12 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -3,6 +3,54 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GeminiExecutor = void 0;
|
|
4
4
|
const AcpClient_1 = require("./acp/AcpClient");
|
|
5
5
|
const SessionManager_1 = require("./acp/SessionManager");
|
|
6
|
+
/** Number of most-recent conversation turns to keep after compaction. */
|
|
7
|
+
const COMPACT_KEEP_TURNS = 10;
|
|
8
|
+
/**
|
|
9
|
+
* Maps a Gemini ACP tool call (kind + title) to a Claude-compatible
|
|
10
|
+
* { name, input } shape so the router's ToolFormatter renders it with
|
|
11
|
+
* the same collapsible card style as Claude tools.
|
|
12
|
+
*
|
|
13
|
+
* Gemini ACP kinds: 'exec' | 'read' | 'write' | 'list' | 'service' | ...
|
|
14
|
+
*/
|
|
15
|
+
function mapAcpToolCall(kind, title) {
|
|
16
|
+
switch (kind) {
|
|
17
|
+
case 'exec':
|
|
18
|
+
// Shell command — map to Bash so extractBashContext renders it
|
|
19
|
+
return { name: 'Bash', input: { command: title } };
|
|
20
|
+
case 'read':
|
|
21
|
+
// File read — map to Read so extractReadContext renders it
|
|
22
|
+
return { name: 'Read', input: { file_path: title } };
|
|
23
|
+
case 'write':
|
|
24
|
+
// File write/edit — map to Write
|
|
25
|
+
return { name: 'Write', input: { file_path: title } };
|
|
26
|
+
case 'list':
|
|
27
|
+
// Directory listing — map to Glob
|
|
28
|
+
return { name: 'Glob', input: { pattern: title } };
|
|
29
|
+
case 'service':
|
|
30
|
+
// MCP / service call
|
|
31
|
+
return { name: 'Service', input: { call: title } };
|
|
32
|
+
default:
|
|
33
|
+
// Unknown kind — show raw title under generic tool name
|
|
34
|
+
return { name: kind ?? 'Tool', input: { command: title } };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gemini CLI stable model aliases used for quota fallback.
|
|
39
|
+
*
|
|
40
|
+
* These are Gemini CLI's own named aliases (not versioned model strings), so
|
|
41
|
+
* they remain valid across model releases. Gemini CLI's ACP mode does NOT
|
|
42
|
+
* implement automatic model fallback on quota exhaustion (unlike interactive
|
|
43
|
+
* mode), so we handle it here instead.
|
|
44
|
+
*
|
|
45
|
+
* Fallback order: user-configured model → flash → flash-lite
|
|
46
|
+
*/
|
|
47
|
+
const QUOTA_FALLBACK_ALIASES = ['flash', 'flash-lite'];
|
|
48
|
+
/** Returns true when the error message indicates a quota-exhaustion condition. */
|
|
49
|
+
function isQuotaError(error) {
|
|
50
|
+
if (!(error instanceof Error))
|
|
51
|
+
return false;
|
|
52
|
+
return error.message.includes('exhausted your capacity') || error.message.includes('quota');
|
|
53
|
+
}
|
|
6
54
|
/**
|
|
7
55
|
* IExecutor implementation for Gemini CLI via ACP (Agent Client Protocol).
|
|
8
56
|
*
|
|
@@ -27,6 +75,10 @@ class GeminiExecutor {
|
|
|
27
75
|
inflightClient = null;
|
|
28
76
|
constructor(directoryGuard, options = {}) {
|
|
29
77
|
this.directoryGuard = directoryGuard;
|
|
78
|
+
// Leave model unset by default so Gemini CLI uses its own default
|
|
79
|
+
// (gemini-2.5-pro). NOTE: '--model auto' maps to gemini-3-pro-preview
|
|
80
|
+
// which has stricter quota limits — do NOT default to 'auto'.
|
|
81
|
+
// Users can override via executor.gemini.model in config.
|
|
30
82
|
this.model = options.model ?? '';
|
|
31
83
|
this.autoApprove = options.autoApprove ?? true;
|
|
32
84
|
this.geminiCommand = options.geminiCommand ?? 'npx';
|
|
@@ -40,14 +92,109 @@ class GeminiExecutor {
|
|
|
40
92
|
if (!this.conversationId) {
|
|
41
93
|
this.conversationId = `conv-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
42
94
|
}
|
|
95
|
+
// Prepend history context for follow-up turns within the same conversation
|
|
96
|
+
const historyContext = this.sessionManager.buildResumeContext(this.conversationId);
|
|
97
|
+
const finalPrompt = historyContext ? `${historyContext}${prompt}` : prompt;
|
|
98
|
+
this.sessionManager.append(this.conversationId, 'user', prompt);
|
|
99
|
+
// Build fallback chain: configured model first, then quota fallback aliases.
|
|
100
|
+
// Filter out aliases that are already the configured model to avoid retrying
|
|
101
|
+
// the same model twice.
|
|
102
|
+
const fallbackAliases = QUOTA_FALLBACK_ALIASES.filter(a => a !== this.model);
|
|
103
|
+
const modelsToTry = [this.model, ...fallbackAliases];
|
|
104
|
+
for (let attempt = 0; attempt < modelsToTry.length; attempt++) {
|
|
105
|
+
const modelForAttempt = modelsToTry[attempt];
|
|
106
|
+
const modelLabel = modelForAttempt || 'pro (default)';
|
|
107
|
+
if (attempt > 0) {
|
|
108
|
+
const notice = `⚠️ Quota exhausted on **${modelsToTry[attempt - 1] || 'pro'}**, switching to **${modelLabel}**...\n\n`;
|
|
109
|
+
options.onStream?.(notice);
|
|
110
|
+
console.warn(`[GeminiExecutor] Quota exhausted on "${modelsToTry[attempt - 1] || 'pro'}", retrying with "${modelLabel}"`);
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const result = await this.executeWithModel(modelForAttempt, modelLabel, finalPrompt, prompt, options);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
if (isQuotaError(error) && attempt < modelsToTry.length - 1) {
|
|
118
|
+
// Quota exhausted on this model — try the next one in the chain
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Final attempt or non-quota error: surface a friendly message
|
|
122
|
+
console.error(`[GeminiExecutor] ❌ Execute error:`, error);
|
|
123
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
124
|
+
return { success: false, error: this.buildFriendlyError(msg, modelLabel) };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Should never reach here, but satisfy TypeScript
|
|
128
|
+
return { success: false, error: 'All Gemini models exhausted quota.' };
|
|
129
|
+
}
|
|
130
|
+
getCurrentWorkingDirectory() {
|
|
131
|
+
return this.currentWorkingDirectory;
|
|
132
|
+
}
|
|
133
|
+
async setWorkingDirectory(targetPath) {
|
|
134
|
+
const resolved = this.directoryGuard.resolveWorkingDirectory(targetPath);
|
|
135
|
+
this.currentWorkingDirectory = resolved;
|
|
136
|
+
// Changing directory resets the conversation context
|
|
137
|
+
this.conversationId = null;
|
|
138
|
+
}
|
|
139
|
+
resetContext() {
|
|
140
|
+
if (this.conversationId) {
|
|
141
|
+
this.sessionManager.remove(this.conversationId);
|
|
142
|
+
this.conversationId = null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Compact conversation history by truncating to the most recent turns.
|
|
147
|
+
* Gemini ACP has no built-in /compact command, so we reduce context size
|
|
148
|
+
* by keeping only the last COMPACT_KEEP_TURNS entries from the JSONL history.
|
|
149
|
+
*/
|
|
150
|
+
async compactWhenFull(onStream) {
|
|
151
|
+
if (!this.conversationId) {
|
|
152
|
+
return { success: true, output: 'No active conversation to compact.' };
|
|
153
|
+
}
|
|
154
|
+
onStream?.(`Truncating history to last ${COMPACT_KEEP_TURNS} turns...\n`);
|
|
155
|
+
const removed = this.sessionManager.truncate(this.conversationId, COMPACT_KEEP_TURNS);
|
|
156
|
+
if (removed === 0) {
|
|
157
|
+
return { success: true, output: 'Conversation history is already compact.' };
|
|
158
|
+
}
|
|
159
|
+
onStream?.(`Removed ${removed} older entries from conversation history.\n`);
|
|
160
|
+
return { success: true, output: `Compacted: removed ${removed} older entries, kept ${COMPACT_KEEP_TURNS} most recent turns.` };
|
|
161
|
+
}
|
|
162
|
+
async abort() {
|
|
163
|
+
if (!this.inflightClient)
|
|
164
|
+
return false;
|
|
165
|
+
this.inflightClient.destroy();
|
|
166
|
+
this.inflightClient = null;
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
async destroy() {
|
|
170
|
+
if (this.inflightClient) {
|
|
171
|
+
this.inflightClient.destroy();
|
|
172
|
+
this.inflightClient = null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ─── Internal helpers ───────────────────────────────────────────────────────
|
|
176
|
+
/**
|
|
177
|
+
* Runs a single attempt with a specific model alias.
|
|
178
|
+
* Throws on quota errors so the caller can retry with the next model.
|
|
179
|
+
*/
|
|
180
|
+
async executeWithModel(model, modelLabel, finalPrompt, originalPrompt, options) {
|
|
43
181
|
let accumulatedOutput = '';
|
|
44
182
|
const acpCallbacks = {
|
|
183
|
+
onThoughtChunk: (text) => {
|
|
184
|
+
// Stream Gemini's thinking to the user, same as Claude does for thinking blocks
|
|
185
|
+
accumulatedOutput += text;
|
|
186
|
+
options.onStream?.(text);
|
|
187
|
+
},
|
|
45
188
|
onTextChunk: (text) => {
|
|
46
189
|
accumulatedOutput += text;
|
|
47
190
|
options.onStream?.(text);
|
|
48
191
|
},
|
|
49
192
|
onToolCall: (toolCallId, title, kind) => {
|
|
50
|
-
|
|
193
|
+
// Map Gemini ACP kind → Claude-compatible tool name + structured input
|
|
194
|
+
// so the router's ToolFormatter renders it consistently with Claude tools.
|
|
195
|
+
// The tool card itself provides the progress indicator — no extra onStream needed.
|
|
196
|
+
const { name, input } = mapAcpToolCall(kind, title);
|
|
197
|
+
options.onToolUse?.({ id: toolCallId, name, input });
|
|
51
198
|
},
|
|
52
199
|
onToolResult: (toolCallId, status, output) => {
|
|
53
200
|
options.onToolResult?.({
|
|
@@ -61,25 +208,21 @@ class GeminiExecutor {
|
|
|
61
208
|
},
|
|
62
209
|
onPermissionRequest: this.autoApprove ? undefined : async () => 0,
|
|
63
210
|
};
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
const finalPrompt = historyContext ? `${historyContext}${prompt}` : prompt;
|
|
67
|
-
this.sessionManager.append(this.conversationId, 'user', prompt);
|
|
68
|
-
const client = new AcpClient_1.AcpClient(this.geminiCommand, this.buildGeminiArgs(), this.currentWorkingDirectory, acpCallbacks);
|
|
211
|
+
const args = this.buildGeminiArgs(model);
|
|
212
|
+
const client = new AcpClient_1.AcpClient(this.geminiCommand, args, this.currentWorkingDirectory, acpCallbacks);
|
|
69
213
|
this.inflightClient = client;
|
|
70
214
|
try {
|
|
71
|
-
console.log(`[GeminiExecutor] Spawning
|
|
72
|
-
console.log(`[GeminiExecutor] Gemini command: ${this.geminiCommand} ${
|
|
215
|
+
console.log(`[GeminiExecutor] Spawning ACP client (model=${modelLabel}) for cwd: ${this.currentWorkingDirectory}`);
|
|
216
|
+
console.log(`[GeminiExecutor] Gemini command: ${this.geminiCommand} ${args.join(' ')}`);
|
|
73
217
|
await client.initialize();
|
|
74
218
|
const sessionId = await client.newSession(this.currentWorkingDirectory);
|
|
75
219
|
console.log(`[GeminiExecutor] ACP session created: ${sessionId.slice(0, 8)}`);
|
|
76
220
|
if (this.autoApprove) {
|
|
77
|
-
console.log(`[GeminiExecutor] Switching session to YOLO mode...`);
|
|
78
221
|
await client.setSessionMode(sessionId, 'yolo');
|
|
79
222
|
}
|
|
80
223
|
console.log(`[GeminiExecutor] Sending prompt (length=${finalPrompt.length})...`);
|
|
81
224
|
const promptResult = await client.prompt(sessionId, finalPrompt);
|
|
82
|
-
console.log(`[GeminiExecutor] Prompt completed, stopReason=${promptResult.stopReason}`);
|
|
225
|
+
console.log(`[GeminiExecutor] Prompt completed, stopReason=${promptResult.stopReason}, model=${modelLabel}`);
|
|
83
226
|
this.sessionManager.append(this.conversationId, 'assistant', accumulatedOutput);
|
|
84
227
|
return {
|
|
85
228
|
success: promptResult.stopReason !== 'refusal',
|
|
@@ -87,61 +230,38 @@ class GeminiExecutor {
|
|
|
87
230
|
sessionAbbr: this.conversationId.slice(0, 8),
|
|
88
231
|
};
|
|
89
232
|
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
console.error(`[GeminiExecutor] ❌ Execute error:`, error);
|
|
92
|
-
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
93
|
-
const friendlyMsg = msg.includes('ENOENT') || msg.includes('not found')
|
|
94
|
-
? 'Gemini CLI is not installed or not found on PATH. Use /backend to switch to another AI backend.'
|
|
95
|
-
: msg;
|
|
96
|
-
return {
|
|
97
|
-
success: false,
|
|
98
|
-
error: friendlyMsg,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
233
|
finally {
|
|
102
234
|
client.destroy();
|
|
103
235
|
this.inflightClient = null;
|
|
104
236
|
}
|
|
105
237
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.currentWorkingDirectory = resolved;
|
|
112
|
-
// Changing directory resets the conversation context
|
|
113
|
-
this.conversationId = null;
|
|
114
|
-
}
|
|
115
|
-
resetContext() {
|
|
116
|
-
if (this.conversationId) {
|
|
117
|
-
this.sessionManager.remove(this.conversationId);
|
|
118
|
-
this.conversationId = null;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
async abort() {
|
|
122
|
-
if (!this.inflightClient)
|
|
123
|
-
return false;
|
|
124
|
-
this.inflightClient.destroy();
|
|
125
|
-
this.inflightClient = null;
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
async destroy() {
|
|
129
|
-
if (this.inflightClient) {
|
|
130
|
-
this.inflightClient.destroy();
|
|
131
|
-
this.inflightClient = null;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
// ─── Internal helpers ───────────────────────────────────────────────────────
|
|
135
|
-
buildGeminiArgs() {
|
|
136
|
-
const args = ['-y', this.geminiVersion, '--experimental-acp'];
|
|
137
|
-
if (this.model) {
|
|
138
|
-
args.push('--model', this.model);
|
|
238
|
+
buildGeminiArgs(model) {
|
|
239
|
+
const args = ['-y', this.geminiVersion, '--acp'];
|
|
240
|
+
const resolvedModel = model ?? this.model;
|
|
241
|
+
if (resolvedModel) {
|
|
242
|
+
args.push('--model', resolvedModel);
|
|
139
243
|
}
|
|
140
244
|
if (this.autoApprove) {
|
|
141
245
|
args.push('--yolo');
|
|
142
246
|
}
|
|
143
247
|
return args;
|
|
144
248
|
}
|
|
249
|
+
buildFriendlyError(msg, modelLabel) {
|
|
250
|
+
if (msg.includes('ENOENT') || msg.includes('not found')) {
|
|
251
|
+
return 'Gemini CLI is not installed or not found on PATH. Use /backend to switch to another AI backend.';
|
|
252
|
+
}
|
|
253
|
+
if (msg.includes('exhausted your capacity') || msg.includes('quota')) {
|
|
254
|
+
const resetMatch = msg.match(/reset after ([^\s.]+)/i);
|
|
255
|
+
const resetHint = resetMatch ? ` Quota resets in ${resetMatch[1]}.` : '';
|
|
256
|
+
return (`⚠️ All Gemini models (${[this.model || 'pro', ...QUOTA_FALLBACK_ALIASES].join(' → ')}) have exhausted quota.${resetHint}\n\n` +
|
|
257
|
+
`Wait for quota to reset, or switch backends:\n` +
|
|
258
|
+
`\`/backend\``);
|
|
259
|
+
}
|
|
260
|
+
if (msg.includes('Premature close') || msg.includes('Gemini CLI exited')) {
|
|
261
|
+
return `⚠️ Gemini's response stream was cut off before completing (server-side issue). The task may have partially executed — please verify your files before retrying.\n\nIf this keeps happening, try \`/backend\` to switch backends.`;
|
|
262
|
+
}
|
|
263
|
+
return msg;
|
|
264
|
+
}
|
|
145
265
|
}
|
|
146
266
|
exports.GeminiExecutor = GeminiExecutor;
|
|
147
267
|
//# sourceMappingURL=GeminiExecutor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeminiExecutor.js","sourceRoot":"","sources":["../../src/executor/GeminiExecutor.ts"],"names":[],"mappings":";;;AAEA,+CAA+D;AAC/D,yDAAsD;
|
|
1
|
+
{"version":3,"file":"GeminiExecutor.js","sourceRoot":"","sources":["../../src/executor/GeminiExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,14 @@ export declare class SessionManager {
|
|
|
23
23
|
*/
|
|
24
24
|
buildResumeContext(sessionId: string): string;
|
|
25
25
|
clear(sessionId: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Truncate session history to the most recent `keepCount` entries.
|
|
28
|
+
* Used by GeminiExecutor's compactWhenFull to reduce context size while
|
|
29
|
+
* preserving recent conversation turns.
|
|
30
|
+
*
|
|
31
|
+
* @returns The number of entries removed.
|
|
32
|
+
*/
|
|
33
|
+
truncate(sessionId: string, keepCount: number): number;
|
|
26
34
|
remove(sessionId: string): void;
|
|
27
35
|
}
|
|
28
36
|
//# sourceMappingURL=SessionManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/executor/acp/SessionManager.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAK5B,OAAO,CAAC,QAAQ;IAIhB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzE;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAgB7C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAO9B,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAMhC"}
|
|
1
|
+
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/executor/acp/SessionManager.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAK5B,OAAO,CAAC,QAAQ;IAIhB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzE;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAgB7C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAO9B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAYtD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAMhC"}
|
|
@@ -82,6 +82,24 @@ class SessionManager {
|
|
|
82
82
|
fs.writeFileSync(file, '', 'utf8');
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Truncate session history to the most recent `keepCount` entries.
|
|
87
|
+
* Used by GeminiExecutor's compactWhenFull to reduce context size while
|
|
88
|
+
* preserving recent conversation turns.
|
|
89
|
+
*
|
|
90
|
+
* @returns The number of entries removed.
|
|
91
|
+
*/
|
|
92
|
+
truncate(sessionId, keepCount) {
|
|
93
|
+
const file = this.filePath(sessionId);
|
|
94
|
+
if (!fs.existsSync(file))
|
|
95
|
+
return 0;
|
|
96
|
+
const lines = fs.readFileSync(file, 'utf8').trim().split('\n').filter(Boolean);
|
|
97
|
+
if (lines.length <= keepCount)
|
|
98
|
+
return 0;
|
|
99
|
+
const kept = lines.slice(lines.length - keepCount);
|
|
100
|
+
fs.writeFileSync(file, kept.join('\n') + '\n', 'utf8');
|
|
101
|
+
return lines.length - keepCount;
|
|
102
|
+
}
|
|
85
103
|
remove(sessionId) {
|
|
86
104
|
const file = this.filePath(sessionId);
|
|
87
105
|
if (fs.existsSync(file)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../../src/executor/acp/SessionManager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAQzB;;;;;;;;GAQG;AACH,MAAa,cAAc;IACjB,OAAO,CAAS;IAExB,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC;QACpF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAEO,QAAQ,CAAC,SAAiB;QAChC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,SAAS,QAAQ,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,SAAiB,EAAE,IAA0B,EAAE,IAAY;QAChE,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAC3D,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,SAAiB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAEpC,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAElC,MAAM,OAAO,GAAmB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAiB,CAAC,CAAC;QAEhF,MAAM,SAAS,GAAG,OAAO;aACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;aAChF,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO,kCAAkC,SAAS,yBAAyB,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,SAAiB;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAiB;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../../src/executor/acp/SessionManager.ts"],"names":[],"mappings":"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"}
|
package/dist/executor/index.d.ts
CHANGED
|
@@ -31,5 +31,5 @@ export declare function createClaudeExecutor(directoryGuard: DirectoryGuard, typ
|
|
|
31
31
|
* @param initialWorkingDirectory Optional initial working directory
|
|
32
32
|
* @returns IExecutor instance
|
|
33
33
|
*/
|
|
34
|
-
export declare function createExecutor(directoryGuard: DirectoryGuard, executorConfig?: ExecutorConfig, initialWorkingDirectory?: string): IExecutor;
|
|
34
|
+
export declare function createExecutor(directoryGuard: DirectoryGuard, executorConfig?: ExecutorConfig, initialWorkingDirectory?: string, threadId?: string): IExecutor;
|
|
35
35
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/executor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAClF,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAmB7C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,cAAc,EAC9B,IAAI,GAAE,YAAqB,EAC3B,uBAAuB,CAAC,EAAE,MAAM,GAC/B,cAAc,GAAG,wBAAwB,CAiB3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,cAAc,EAAE,cAAc,EAC9B,cAAc,GAAE,cAAiC,EACjD,uBAAuB,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/executor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAClF,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAmB7C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,cAAc,EAC9B,IAAI,GAAE,YAAqB,EAC3B,uBAAuB,CAAC,EAAE,MAAM,GAC/B,cAAc,GAAG,wBAAwB,CAiB3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,cAAc,EAAE,cAAc,EAC9B,cAAc,GAAE,cAAiC,EACjD,uBAAuB,CAAC,EAAE,MAAM,EAChC,QAAQ,CAAC,EAAE,MAAM,GAChB,SAAS,CA6BX"}
|
package/dist/executor/index.js
CHANGED
|
@@ -59,7 +59,7 @@ function createClaudeExecutor(directoryGuard, type = 'auto', initialWorkingDirec
|
|
|
59
59
|
* @param initialWorkingDirectory Optional initial working directory
|
|
60
60
|
* @returns IExecutor instance
|
|
61
61
|
*/
|
|
62
|
-
function createExecutor(directoryGuard, executorConfig = { type: 'auto' }, initialWorkingDirectory) {
|
|
62
|
+
function createExecutor(directoryGuard, executorConfig = { type: 'auto' }, initialWorkingDirectory, threadId) {
|
|
63
63
|
switch (executorConfig.type) {
|
|
64
64
|
case 'gemini':
|
|
65
65
|
console.log('[ExecutorFactory] Using Gemini CLI executor (ACP)');
|
|
@@ -72,7 +72,7 @@ function createExecutor(directoryGuard, executorConfig = { type: 'auto' }, initi
|
|
|
72
72
|
});
|
|
73
73
|
case 'claude-persistent':
|
|
74
74
|
console.log('[ExecutorFactory] Using Claude persistent executor');
|
|
75
|
-
return new ClaudePersistentExecutor_1.ClaudePersistentExecutor(directoryGuard, initialWorkingDirectory);
|
|
75
|
+
return new ClaudePersistentExecutor_1.ClaudePersistentExecutor(directoryGuard, initialWorkingDirectory, threadId);
|
|
76
76
|
case 'claude-spawn':
|
|
77
77
|
console.log('[ExecutorFactory] Using Claude spawn executor');
|
|
78
78
|
return new ClaudeExecutor_1.ClaudeExecutor(directoryGuard);
|
|
@@ -83,7 +83,7 @@ function createExecutor(directoryGuard, executorConfig = { type: 'auto' }, initi
|
|
|
83
83
|
return new ClaudeExecutor_1.ClaudeExecutor(directoryGuard);
|
|
84
84
|
}
|
|
85
85
|
console.log('[ExecutorFactory] Using Claude persistent executor (auto)');
|
|
86
|
-
return new ClaudePersistentExecutor_1.ClaudePersistentExecutor(directoryGuard, initialWorkingDirectory);
|
|
86
|
+
return new ClaudePersistentExecutor_1.ClaudePersistentExecutor(directoryGuard, initialWorkingDirectory, threadId);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/executor/index.ts"],"names":[],"mappings":";;;AA4CA,oDAqBC;AAWD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/executor/index.ts"],"names":[],"mappings":";;;AA4CA,oDAqBC;AAWD,wCAkCC;AA7GD,qDAAkD;AAClD,yEAAsE;AACtE,qDAAkD;AAMlD,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,uEAAsE;AAA7D,oIAAA,wBAAwB,OAAA;AACjC,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AAGvB;;GAEG;AACH,SAAS,yBAAyB;IAChC,4CAA4C;IAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6BAA6B;IAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAOD;;;;;;;GAOG;AACH,SAAgB,oBAAoB,CAClC,cAA8B,EAC9B,OAAqB,MAAM,EAC3B,uBAAgC;IAEhC,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,0FAA0F;QAC1F,IAAI,yBAAyB,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;YACvF,OAAO,IAAI,+BAAc,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;QACD,gCAAgC;QAChC,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;QAC9E,OAAO,IAAI,mDAAwB,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,OAAO,IAAI,mDAAwB,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,IAAI,+BAAc,CAAC,cAAc,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAC5B,cAA8B,EAC9B,iBAAiC,EAAE,IAAI,EAAE,MAAM,EAAE,EACjD,uBAAgC,EAChC,QAAiB;IAEjB,QAAQ,cAAc,CAAC,IAAI,EAAE,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO,IAAI,+BAAc,CAAC,cAAc,EAAE;gBACxC,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,KAAK;gBACnC,WAAW,EAAE,cAAc,CAAC,MAAM,EAAE,WAAW,IAAI,IAAI;gBACvD,uBAAuB;gBACvB,aAAa,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO;gBAC7C,aAAa,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO;aAC9C,CAAC,CAAC;QAEL,KAAK,mBAAmB;YACtB,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAClE,OAAO,IAAI,mDAAwB,CAAC,cAAc,EAAE,uBAAuB,EAAE,QAAQ,CAAC,CAAC;QAEzF,KAAK,cAAc;YACjB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YAC7D,OAAO,IAAI,+BAAc,CAAC,cAAc,CAAC,CAAC;QAE5C,KAAK,MAAM,CAAC;QACZ;YACE,IAAI,yBAAyB,EAAE,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;gBACvF,OAAO,IAAI,+BAAc,CAAC,cAAc,CAAC,CAAC;YAC5C,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;YACzE,OAAO,IAAI,mDAAwB,CAAC,cAAc,EAAE,uBAAuB,EAAE,QAAQ,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ThreadManager } from './ThreadManager';
|
|
2
|
+
import { ThreadSummary } from './types';
|
|
3
|
+
import type { IExecutor } from '../executor/IExecutor';
|
|
4
|
+
import type { DirectoryGuard } from '../security/DirectoryGuard';
|
|
5
|
+
import type { ExecutorConfig } from '../types/config';
|
|
6
|
+
/**
|
|
7
|
+
* Thread runtime status (not persisted — computed from locking state).
|
|
8
|
+
*/
|
|
9
|
+
type ThreadStatus = 'idle' | 'running' | 'error';
|
|
10
|
+
/**
|
|
11
|
+
* Factory function signature for creating executors (injectable for testing).
|
|
12
|
+
*/
|
|
13
|
+
export type ExecutorFactory = (directoryGuard: DirectoryGuard, config: ExecutorConfig, initialWorkingDirectory?: string, threadId?: string) => IExecutor;
|
|
14
|
+
/**
|
|
15
|
+
* Manages a pool of executor instances — one per thread.
|
|
16
|
+
* Executors are lazily created on first use.
|
|
17
|
+
* Each thread has its own per-thread busy lock and error flag.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ThreadExecutorPool {
|
|
20
|
+
private executors;
|
|
21
|
+
private busy;
|
|
22
|
+
private errorFlag;
|
|
23
|
+
private executorConfig;
|
|
24
|
+
private readonly threadManager;
|
|
25
|
+
private readonly directoryGuard;
|
|
26
|
+
private readonly factory;
|
|
27
|
+
constructor(threadManager: ThreadManager, directoryGuard: DirectoryGuard, executorConfig: ExecutorConfig, factory?: ExecutorFactory);
|
|
28
|
+
/**
|
|
29
|
+
* Get (or lazily create) the executor for a thread.
|
|
30
|
+
* Throws if the threadId is unknown.
|
|
31
|
+
*/
|
|
32
|
+
getExecutor(threadId: string): IExecutor;
|
|
33
|
+
isThreadBusy(threadId: string): boolean;
|
|
34
|
+
setThreadBusy(threadId: string, busy: boolean): void;
|
|
35
|
+
setThreadError(threadId: string, hasError: boolean): void;
|
|
36
|
+
getStatus(threadId: string): ThreadStatus;
|
|
37
|
+
/**
|
|
38
|
+
* Get runtime summaries for all threads (id, name, status).
|
|
39
|
+
*/
|
|
40
|
+
getSummaries(): ThreadSummary[];
|
|
41
|
+
/**
|
|
42
|
+
* Destroy a single thread's executor and remove it from the pool.
|
|
43
|
+
* No-op if no executor has been created for this thread.
|
|
44
|
+
*/
|
|
45
|
+
destroyThread(threadId: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Destroy all executors in the pool.
|
|
48
|
+
*/
|
|
49
|
+
destroyAll(): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Switch all threads to a new executor backend.
|
|
52
|
+
* Destroys all existing executors; new ones will be lazily created on next use.
|
|
53
|
+
*/
|
|
54
|
+
switchBackend(newConfig: ExecutorConfig): Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=ThreadExecutorPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadExecutorPool.d.ts","sourceRoot":"","sources":["../../src/thread/ThreadExecutorPool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD;;GAEG;AACH,KAAK,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,cAAc,EACtB,uBAAuB,CAAC,EAAE,MAAM,EAChC,QAAQ,CAAC,EAAE,MAAM,KACd,SAAS,CAAC;AAEf;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAGxC,aAAa,EAAE,aAAa,EAC5B,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,cAAc,EAC9B,OAAO,GAAE,eAAgC;IAQ3C;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAmBxC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIvC,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAQpD,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAOzD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAQzC;;OAEG;IACH,YAAY,IAAI,aAAa,EAAE;IAU/B;;;OAGG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAI9D"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ThreadExecutorPool = void 0;
|
|
4
|
+
const executor_1 = require("../executor");
|
|
5
|
+
/**
|
|
6
|
+
* Manages a pool of executor instances — one per thread.
|
|
7
|
+
* Executors are lazily created on first use.
|
|
8
|
+
* Each thread has its own per-thread busy lock and error flag.
|
|
9
|
+
*/
|
|
10
|
+
class ThreadExecutorPool {
|
|
11
|
+
executors = new Map();
|
|
12
|
+
busy = new Map();
|
|
13
|
+
errorFlag = new Map();
|
|
14
|
+
executorConfig;
|
|
15
|
+
threadManager;
|
|
16
|
+
directoryGuard;
|
|
17
|
+
factory;
|
|
18
|
+
constructor(threadManager, directoryGuard, executorConfig, factory = executor_1.createExecutor) {
|
|
19
|
+
this.threadManager = threadManager;
|
|
20
|
+
this.directoryGuard = directoryGuard;
|
|
21
|
+
this.executorConfig = executorConfig;
|
|
22
|
+
this.factory = factory;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get (or lazily create) the executor for a thread.
|
|
26
|
+
* Throws if the threadId is unknown.
|
|
27
|
+
*/
|
|
28
|
+
getExecutor(threadId) {
|
|
29
|
+
const thread = this.threadManager.getThread(threadId);
|
|
30
|
+
if (!thread)
|
|
31
|
+
throw new Error(`Thread not found: ${threadId}`);
|
|
32
|
+
let executor = this.executors.get(threadId);
|
|
33
|
+
if (!executor) {
|
|
34
|
+
executor = this.factory(this.directoryGuard, this.executorConfig, thread.workingDirectory || undefined, threadId);
|
|
35
|
+
this.executors.set(threadId, executor);
|
|
36
|
+
}
|
|
37
|
+
return executor;
|
|
38
|
+
}
|
|
39
|
+
// ── Per-thread locking ──────────────────────────────────────────────────
|
|
40
|
+
isThreadBusy(threadId) {
|
|
41
|
+
return this.busy.get(threadId) ?? false;
|
|
42
|
+
}
|
|
43
|
+
setThreadBusy(threadId, busy) {
|
|
44
|
+
this.busy.set(threadId, busy);
|
|
45
|
+
if (busy) {
|
|
46
|
+
// Clear error flag when thread starts running
|
|
47
|
+
this.errorFlag.set(threadId, false);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
setThreadError(threadId, hasError) {
|
|
51
|
+
this.errorFlag.set(threadId, hasError);
|
|
52
|
+
if (hasError) {
|
|
53
|
+
this.busy.set(threadId, false);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
getStatus(threadId) {
|
|
57
|
+
if (this.errorFlag.get(threadId))
|
|
58
|
+
return 'error';
|
|
59
|
+
if (this.busy.get(threadId))
|
|
60
|
+
return 'running';
|
|
61
|
+
return 'idle';
|
|
62
|
+
}
|
|
63
|
+
// ── Thread summaries ────────────────────────────────────────────────────
|
|
64
|
+
/**
|
|
65
|
+
* Get runtime summaries for all threads (id, name, status).
|
|
66
|
+
*/
|
|
67
|
+
getSummaries() {
|
|
68
|
+
return this.threadManager.listThreads().map(t => ({
|
|
69
|
+
id: t.id,
|
|
70
|
+
name: t.name,
|
|
71
|
+
status: this.getStatus(t.id),
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
75
|
+
/**
|
|
76
|
+
* Destroy a single thread's executor and remove it from the pool.
|
|
77
|
+
* No-op if no executor has been created for this thread.
|
|
78
|
+
*/
|
|
79
|
+
async destroyThread(threadId) {
|
|
80
|
+
const executor = this.executors.get(threadId);
|
|
81
|
+
if (executor) {
|
|
82
|
+
await executor.destroy();
|
|
83
|
+
this.executors.delete(threadId);
|
|
84
|
+
this.busy.delete(threadId);
|
|
85
|
+
this.errorFlag.delete(threadId);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Destroy all executors in the pool.
|
|
90
|
+
*/
|
|
91
|
+
async destroyAll() {
|
|
92
|
+
await Promise.all(Array.from(this.executors.keys()).map(id => this.destroyThread(id)));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Switch all threads to a new executor backend.
|
|
96
|
+
* Destroys all existing executors; new ones will be lazily created on next use.
|
|
97
|
+
*/
|
|
98
|
+
async switchBackend(newConfig) {
|
|
99
|
+
await this.destroyAll();
|
|
100
|
+
this.executorConfig = newConfig;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.ThreadExecutorPool = ThreadExecutorPool;
|
|
104
|
+
//# sourceMappingURL=ThreadExecutorPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadExecutorPool.js","sourceRoot":"","sources":["../../src/thread/ThreadExecutorPool.ts"],"names":[],"mappings":"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"}
|