@yu_robotics/remote-cli 1.6.48 → 1.6.53
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 +2 -0
- package/dist/client/MessageHandler.d.ts.map +1 -1
- package/dist/client/MessageHandler.js +58 -31
- package/dist/client/MessageHandler.js.map +1 -1
- package/dist/client/TaskRecovery.d.ts +31 -0
- package/dist/client/TaskRecovery.d.ts.map +1 -0
- package/dist/client/TaskRecovery.js +184 -0
- package/dist/client/TaskRecovery.js.map +1 -0
- package/dist/client/WebSocketClient.d.ts +6 -0
- package/dist/client/WebSocketClient.d.ts.map +1 -1
- package/dist/client/WebSocketClient.js +38 -2
- package/dist/client/WebSocketClient.js.map +1 -1
- package/dist/executor/ClaudePersistentExecutor.d.ts +4 -0
- package/dist/executor/ClaudePersistentExecutor.d.ts.map +1 -1
- package/dist/executor/ClaudePersistentExecutor.js +56 -12
- package/dist/executor/ClaudePersistentExecutor.js.map +1 -1
- package/dist/types/index.d.ts +14 -4
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaskRecovery = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const RESULT_TTL = 24 * 60 * 60 * 1000;
|
|
6
|
+
const MAX_RESULTS = 100;
|
|
7
|
+
const RETRY_DELAY = 15000;
|
|
8
|
+
/** Keeps bounded task metadata across socket reconnects, never process output. */
|
|
9
|
+
class TaskRecovery {
|
|
10
|
+
sendRaw;
|
|
11
|
+
tasks = new Map();
|
|
12
|
+
connected = true;
|
|
13
|
+
supported = false;
|
|
14
|
+
inFlight;
|
|
15
|
+
retryTimer;
|
|
16
|
+
constructor(sendRaw) {
|
|
17
|
+
this.sendRaw = sendRaw;
|
|
18
|
+
}
|
|
19
|
+
track(task) {
|
|
20
|
+
this.tasks.set(task.messageId, {
|
|
21
|
+
task: { ...task, threadName: task.threadName.slice(0, 100), backend: task.backend.slice(0, 100),
|
|
22
|
+
cwd: task.cwd.slice(0, 4096), preview: task.preview.replace(/\s+/g, ' ').slice(0, 240) },
|
|
23
|
+
recoveryId: (0, uuid_1.v4)(), needsRecovery: !this.connected, recovered: !this.connected,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
disconnected() {
|
|
27
|
+
this.connected = false;
|
|
28
|
+
this.clearTimer();
|
|
29
|
+
this.inFlight = undefined;
|
|
30
|
+
for (const entry of this.tasks.values()) {
|
|
31
|
+
entry.needsRecovery = true;
|
|
32
|
+
entry.recovered = true;
|
|
33
|
+
entry.recoveryId = (0, uuid_1.v4)();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
registered(supported) {
|
|
37
|
+
this.connected = true;
|
|
38
|
+
this.supported = supported;
|
|
39
|
+
if (!supported) {
|
|
40
|
+
for (const [id, entry] of this.tasks) {
|
|
41
|
+
if (entry.result)
|
|
42
|
+
this.tasks.delete(id);
|
|
43
|
+
else
|
|
44
|
+
entry.needsRecovery = false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
this.pump();
|
|
48
|
+
}
|
|
49
|
+
send(message) {
|
|
50
|
+
const entry = this.tasks.get(message.messageId);
|
|
51
|
+
if (!entry) {
|
|
52
|
+
this.sendRaw(message);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (message.type === 'response' && typeof message.success === 'boolean') {
|
|
56
|
+
entry.result = { success: message.success, error: message.error?.slice(0, 500), finishedAt: Date.now() };
|
|
57
|
+
if (typeof message.cwd === 'string')
|
|
58
|
+
entry.task.cwd = message.cwd.slice(0, 4096);
|
|
59
|
+
this.prune();
|
|
60
|
+
}
|
|
61
|
+
if (!this.connected || entry.needsRecovery) {
|
|
62
|
+
this.pump();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Aggregate plans and final bodies may contain text generated before reconnecting.
|
|
66
|
+
if (entry.recovered && (message.streamType === 'plan_mode' || message.type === 'structured'))
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
this.sendRaw(entry.recovered && message.type === 'response'
|
|
70
|
+
? { ...message, output: undefined, error: entry.result?.error } : message);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
this.disconnected();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (entry.result) {
|
|
77
|
+
if (!this.supported)
|
|
78
|
+
this.tasks.delete(message.messageId);
|
|
79
|
+
else
|
|
80
|
+
this.scheduleRetry();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
acknowledge(message) {
|
|
84
|
+
if (message.type === 'task_result_ack') {
|
|
85
|
+
if (this.tasks.get(message.messageId)?.result)
|
|
86
|
+
this.tasks.delete(message.messageId);
|
|
87
|
+
if (this.inFlight?.messageId === message.messageId) {
|
|
88
|
+
this.inFlight = undefined;
|
|
89
|
+
this.clearTimer();
|
|
90
|
+
}
|
|
91
|
+
this.pump();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const pending = this.inFlight;
|
|
95
|
+
if (!pending || pending.messageId !== message.messageId || pending.recoveryId !== message.recoveryId
|
|
96
|
+
|| pending.state !== message.state)
|
|
97
|
+
return;
|
|
98
|
+
this.inFlight = undefined;
|
|
99
|
+
this.clearTimer();
|
|
100
|
+
const entry = this.tasks.get(message.messageId);
|
|
101
|
+
if (entry && message.success === true) {
|
|
102
|
+
if (pending.state !== 'running')
|
|
103
|
+
this.tasks.delete(message.messageId);
|
|
104
|
+
else {
|
|
105
|
+
entry.needsRecovery = false;
|
|
106
|
+
if (entry.result) {
|
|
107
|
+
this.send({ type: 'response', messageId: message.messageId, openId: entry.task.openId,
|
|
108
|
+
threadId: entry.task.threadId, cwd: entry.task.cwd, success: entry.result.success,
|
|
109
|
+
error: entry.result.error, timestamp: Date.now() });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (message.success === true)
|
|
114
|
+
this.pump();
|
|
115
|
+
else
|
|
116
|
+
this.scheduleRetry();
|
|
117
|
+
}
|
|
118
|
+
hasPendingResults() {
|
|
119
|
+
this.prune();
|
|
120
|
+
return Array.from(this.tasks.values()).some(entry => !!entry.result);
|
|
121
|
+
}
|
|
122
|
+
destroy() {
|
|
123
|
+
this.clearTimer();
|
|
124
|
+
this.tasks.clear();
|
|
125
|
+
this.inFlight = undefined;
|
|
126
|
+
}
|
|
127
|
+
pump() {
|
|
128
|
+
this.prune();
|
|
129
|
+
if (!this.connected || !this.supported || this.inFlight)
|
|
130
|
+
return;
|
|
131
|
+
const entry = Array.from(this.tasks.values()).find(item => item.needsRecovery);
|
|
132
|
+
if (!entry) {
|
|
133
|
+
if (this.hasPendingResults())
|
|
134
|
+
this.scheduleRetry();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const { task, result } = entry;
|
|
138
|
+
const taskResume = {
|
|
139
|
+
recoveryId: entry.recoveryId, threadName: task.threadName, backend: task.backend,
|
|
140
|
+
cwd: task.cwd, preview: task.preview,
|
|
141
|
+
state: result ? (result.success ? 'completed' : 'failed') : 'running', error: result?.error,
|
|
142
|
+
};
|
|
143
|
+
this.inFlight = { messageId: task.messageId, recoveryId: entry.recoveryId, state: taskResume.state };
|
|
144
|
+
try {
|
|
145
|
+
this.sendRaw({ type: 'task_resume', messageId: task.messageId, openId: task.openId,
|
|
146
|
+
threadId: task.threadId, taskResume, timestamp: Date.now() });
|
|
147
|
+
this.scheduleRetry();
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
this.disconnected();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
scheduleRetry() {
|
|
154
|
+
if (this.retryTimer || !this.connected || !this.supported)
|
|
155
|
+
return;
|
|
156
|
+
this.retryTimer = setTimeout(() => {
|
|
157
|
+
this.retryTimer = undefined;
|
|
158
|
+
this.inFlight = undefined;
|
|
159
|
+
for (const entry of this.tasks.values()) {
|
|
160
|
+
if (entry.result) {
|
|
161
|
+
entry.needsRecovery = true;
|
|
162
|
+
entry.recovered = true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
this.pump();
|
|
166
|
+
}, RETRY_DELAY);
|
|
167
|
+
this.retryTimer.unref?.();
|
|
168
|
+
}
|
|
169
|
+
clearTimer() {
|
|
170
|
+
if (this.retryTimer)
|
|
171
|
+
clearTimeout(this.retryTimer);
|
|
172
|
+
this.retryTimer = undefined;
|
|
173
|
+
}
|
|
174
|
+
prune() {
|
|
175
|
+
const completed = Array.from(this.tasks.entries()).filter(([, task]) => task.result)
|
|
176
|
+
.sort(([, left], [, right]) => left.result.finishedAt - right.result.finishedAt);
|
|
177
|
+
completed.forEach(([id, task], index) => {
|
|
178
|
+
if (Date.now() - task.result.finishedAt > RESULT_TTL || index < completed.length - MAX_RESULTS)
|
|
179
|
+
this.tasks.delete(id);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.TaskRecovery = TaskRecovery;
|
|
184
|
+
//# sourceMappingURL=TaskRecovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskRecovery.js","sourceRoot":"","sources":["../../src/client/TaskRecovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RecoverableTask } from './TaskRecovery';
|
|
1
2
|
/**
|
|
2
3
|
* WebSocket client configuration
|
|
3
4
|
*/
|
|
@@ -30,6 +31,8 @@ export declare class WebSocketClient {
|
|
|
30
31
|
private heartbeatTimer;
|
|
31
32
|
private manualDisconnect;
|
|
32
33
|
private connected;
|
|
34
|
+
private lastReceivedAt;
|
|
35
|
+
private readonly taskRecovery;
|
|
33
36
|
private messageHandlers;
|
|
34
37
|
private errorHandlers;
|
|
35
38
|
private closeHandlers;
|
|
@@ -48,6 +51,9 @@ export declare class WebSocketClient {
|
|
|
48
51
|
* @param message Message object
|
|
49
52
|
*/
|
|
50
53
|
send(message: any): void;
|
|
54
|
+
trackTask(task: RecoverableTask): void;
|
|
55
|
+
hasPendingTaskResults(): boolean;
|
|
56
|
+
private sendRaw;
|
|
51
57
|
/**
|
|
52
58
|
* Check if connected
|
|
53
59
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocketClient.d.ts","sourceRoot":"","sources":["../../src/client/WebSocketClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WebSocketClient.d.ts","sourceRoot":"","sources":["../../src/client/WebSocketClient.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsD;IACnF,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,aAAa,CAAqD;IAC1E,OAAO,CAAC,eAAe,CAAyB;gBAEpC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B;IAOrF;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuF9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAmBlB;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAIxB,SAAS,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAItC,qBAAqB,IAAI,OAAO;IAIhC,OAAO,CAAC,OAAO;IAQf;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,SAAS,IAAI,gBAAgB;IAQ7B;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAIhD;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI9D;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIpC;;;;OAIG;IACH,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IACjD,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IACpD,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IACzD,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAoB3D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAexB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAM5B"}
|
|
@@ -7,6 +7,7 @@ exports.WebSocketClient = void 0;
|
|
|
7
7
|
const ws_1 = __importDefault(require("ws"));
|
|
8
8
|
const uuid_1 = require("uuid");
|
|
9
9
|
const types_1 = require("../types");
|
|
10
|
+
const TaskRecovery_1 = require("./TaskRecovery");
|
|
10
11
|
/**
|
|
11
12
|
* WebSocket Client
|
|
12
13
|
* Responsible for establishing and maintaining WebSocket connection with router server
|
|
@@ -21,6 +22,8 @@ class WebSocketClient {
|
|
|
21
22
|
heartbeatTimer = null;
|
|
22
23
|
manualDisconnect = false;
|
|
23
24
|
connected = false;
|
|
25
|
+
lastReceivedAt = 0;
|
|
26
|
+
taskRecovery = new TaskRecovery_1.TaskRecovery(message => this.sendRaw(message));
|
|
24
27
|
messageHandlers = [];
|
|
25
28
|
errorHandlers = [];
|
|
26
29
|
closeHandlers = [];
|
|
@@ -38,22 +41,31 @@ class WebSocketClient {
|
|
|
38
41
|
return new Promise((resolve, reject) => {
|
|
39
42
|
this.manualDisconnect = false;
|
|
40
43
|
try {
|
|
41
|
-
|
|
44
|
+
const socket = new ws_1.default(this.serverUrl, { handshakeTimeout: 15000 });
|
|
45
|
+
this.ws = socket;
|
|
42
46
|
const onOpen = () => {
|
|
47
|
+
if (this.ws !== socket)
|
|
48
|
+
return;
|
|
43
49
|
this.connected = true;
|
|
50
|
+
this.lastReceivedAt = Date.now();
|
|
44
51
|
this.startHeartbeat();
|
|
45
52
|
this.sendRegistration();
|
|
46
53
|
this.connectHandlers.forEach(handler => handler());
|
|
47
54
|
resolve();
|
|
48
55
|
};
|
|
49
56
|
const onError = (error) => {
|
|
57
|
+
if (this.ws !== socket)
|
|
58
|
+
return;
|
|
50
59
|
this.errorHandlers.forEach(handler => handler(error));
|
|
51
60
|
if (!this.connected) {
|
|
52
61
|
reject(error);
|
|
53
62
|
}
|
|
54
63
|
};
|
|
55
64
|
const onClose = (code, reason) => {
|
|
65
|
+
if (this.ws !== socket)
|
|
66
|
+
return;
|
|
56
67
|
this.connected = false;
|
|
68
|
+
this.taskRecovery.disconnected();
|
|
57
69
|
this.stopHeartbeat();
|
|
58
70
|
const reasonStr = reason.toString();
|
|
59
71
|
this.closeHandlers.forEach(handler => handler(code, reasonStr));
|
|
@@ -62,8 +74,18 @@ class WebSocketClient {
|
|
|
62
74
|
}
|
|
63
75
|
};
|
|
64
76
|
const onMessage = (data) => {
|
|
77
|
+
if (this.ws !== socket)
|
|
78
|
+
return;
|
|
65
79
|
try {
|
|
66
80
|
const message = JSON.parse(data.toString());
|
|
81
|
+
this.lastReceivedAt = Date.now();
|
|
82
|
+
if (message.type === 'binding_confirm' && message.data?.success === true) {
|
|
83
|
+
this.taskRecovery.registered(message.data?.capabilities?.taskRecovery === true);
|
|
84
|
+
}
|
|
85
|
+
if (message.type === 'task_resume_ack' || message.type === 'task_result_ack') {
|
|
86
|
+
this.taskRecovery.acknowledge(message);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
67
89
|
// Stop reconnecting if the router rejects this CLI version
|
|
68
90
|
if (message.type === 'error' &&
|
|
69
91
|
message.data?.code === 'PROTOCOL_VERSION_INCOMPATIBLE') {
|
|
@@ -103,6 +125,7 @@ class WebSocketClient {
|
|
|
103
125
|
this.connected = false;
|
|
104
126
|
this.stopHeartbeat();
|
|
105
127
|
this.clearReconnectTimer();
|
|
128
|
+
this.taskRecovery.destroy();
|
|
106
129
|
if (this.ws) {
|
|
107
130
|
this.ws.close();
|
|
108
131
|
this.ws = null;
|
|
@@ -118,6 +141,15 @@ class WebSocketClient {
|
|
|
118
141
|
* @param message Message object
|
|
119
142
|
*/
|
|
120
143
|
send(message) {
|
|
144
|
+
this.taskRecovery.send(message);
|
|
145
|
+
}
|
|
146
|
+
trackTask(task) {
|
|
147
|
+
this.taskRecovery.track(task);
|
|
148
|
+
}
|
|
149
|
+
hasPendingTaskResults() {
|
|
150
|
+
return this.taskRecovery.hasPendingResults();
|
|
151
|
+
}
|
|
152
|
+
sendRaw(message) {
|
|
121
153
|
if (!this.connected || !this.ws) {
|
|
122
154
|
throw new Error('Not connected to server');
|
|
123
155
|
}
|
|
@@ -197,7 +229,7 @@ class WebSocketClient {
|
|
|
197
229
|
data: {
|
|
198
230
|
deviceId: this.deviceId,
|
|
199
231
|
protocolVersion: types_1.PROTOCOL_VERSION,
|
|
200
|
-
capabilities: { queueStarted: true },
|
|
232
|
+
capabilities: { queueStarted: true, taskRecovery: true },
|
|
201
233
|
}
|
|
202
234
|
}));
|
|
203
235
|
}
|
|
@@ -209,6 +241,10 @@ class WebSocketClient {
|
|
|
209
241
|
this.stopHeartbeat();
|
|
210
242
|
this.heartbeatTimer = setInterval(() => {
|
|
211
243
|
if (this.ws && this.connected) {
|
|
244
|
+
if (Date.now() - this.lastReceivedAt >= this.heartbeatInterval * 3) {
|
|
245
|
+
this.ws.terminate();
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
212
248
|
this.ws.send(JSON.stringify({
|
|
213
249
|
type: 'heartbeat',
|
|
214
250
|
timestamp: Date.now()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocketClient.js","sourceRoot":"","sources":["../../src/client/WebSocketClient.ts"],"names":[],"mappings":";;;;;;AAAA,4CAA2B;AAC3B,+BAAoC;AACpC,oCAAyD;
|
|
1
|
+
{"version":3,"file":"WebSocketClient.js","sourceRoot":"","sources":["../../src/client/WebSocketClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,6 +60,7 @@ export declare class ClaudePersistentExecutor extends EventEmitter {
|
|
|
60
60
|
private commandQueue;
|
|
61
61
|
private isProcessing;
|
|
62
62
|
private currentOutputBuffer;
|
|
63
|
+
private textStreams;
|
|
63
64
|
private currentStreamCallback?;
|
|
64
65
|
private currentToolUseCallback?;
|
|
65
66
|
private currentToolResultCallback?;
|
|
@@ -125,6 +126,9 @@ export declare class ClaudePersistentExecutor extends EventEmitter {
|
|
|
125
126
|
* Claude is still working. Users can use /abort to cancel long-running tasks.
|
|
126
127
|
*/
|
|
127
128
|
private resetActivityTimeout;
|
|
129
|
+
private emitText;
|
|
130
|
+
private handleStreamEvent;
|
|
131
|
+
private unstreamedText;
|
|
128
132
|
/**
|
|
129
133
|
* Handle a line of JSON output from Claude
|
|
130
134
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClaudePersistentExecutor.d.ts","sourceRoot":"","sources":["../../src/executor/ClaudePersistentExecutor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAqB,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAIzG,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"ClaudePersistentExecutor.d.ts","sourceRoot":"","sources":["../../src/executor/ClaudePersistentExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,6 +37,8 @@ class ClaudePersistentExecutor extends events_1.EventEmitter {
|
|
|
37
37
|
isProcessing = false;
|
|
38
38
|
// Output handling
|
|
39
39
|
currentOutputBuffer = [];
|
|
40
|
+
// Main-agent and subagent streams have independent message IDs and block indices.
|
|
41
|
+
textStreams = new Map();
|
|
40
42
|
currentStreamCallback;
|
|
41
43
|
currentToolUseCallback;
|
|
42
44
|
currentToolResultCallback;
|
|
@@ -448,6 +450,55 @@ class ClaudePersistentExecutor extends events_1.EventEmitter {
|
|
|
448
450
|
this.completeCurrentCommand(false, 'Execution timeout: No response from Claude for 10 minutes');
|
|
449
451
|
}, this.defaultTimeout);
|
|
450
452
|
}
|
|
453
|
+
emitText(text) {
|
|
454
|
+
if (!text)
|
|
455
|
+
return;
|
|
456
|
+
this.currentOutputBuffer.push(text);
|
|
457
|
+
if (this.isInPlanMode)
|
|
458
|
+
this.planModeBuffer.push(text);
|
|
459
|
+
this.currentStreamCallback?.(text);
|
|
460
|
+
}
|
|
461
|
+
handleStreamEvent(message) {
|
|
462
|
+
const event = message.event;
|
|
463
|
+
if (!event || !this.isProcessing)
|
|
464
|
+
return;
|
|
465
|
+
const source = message.parent_tool_use_id ?? '';
|
|
466
|
+
if (event.type === 'message_start') {
|
|
467
|
+
this.textStreams.delete(source);
|
|
468
|
+
if (event.message?.id) {
|
|
469
|
+
this.textStreams.set(source, { messageId: event.message.id, blocks: new Map() });
|
|
470
|
+
}
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
const stream = this.textStreams.get(source);
|
|
474
|
+
if (!stream || event.index === undefined)
|
|
475
|
+
return;
|
|
476
|
+
if (event.type === 'content_block_start' && event.content_block?.type === 'text') {
|
|
477
|
+
const text = event.content_block.text ?? '';
|
|
478
|
+
stream.blocks.set(event.index, text);
|
|
479
|
+
this.emitText(text);
|
|
480
|
+
}
|
|
481
|
+
else if (event.type === 'content_block_delta' && event.delta?.type === 'text_delta'
|
|
482
|
+
&& stream.blocks.has(event.index)) {
|
|
483
|
+
const text = event.delta.text ?? '';
|
|
484
|
+
stream.blocks.set(event.index, stream.blocks.get(event.index) + text);
|
|
485
|
+
this.emitText(text);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
unstreamedText(message, text) {
|
|
489
|
+
const stream = this.textStreams.get(message.parent_tool_use_id ?? '');
|
|
490
|
+
if (!stream || stream.messageId !== message.message?.id)
|
|
491
|
+
return text;
|
|
492
|
+
// Claude emits complete assistant blocks without their original stream index.
|
|
493
|
+
// Consume each matching block once, preserving repeated text in later blocks.
|
|
494
|
+
for (const [index, streamedText] of stream.blocks) {
|
|
495
|
+
if (text.startsWith(streamedText)) {
|
|
496
|
+
stream.blocks.delete(index);
|
|
497
|
+
return text.slice(streamedText.length);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return text;
|
|
501
|
+
}
|
|
451
502
|
/**
|
|
452
503
|
* Handle a line of JSON output from Claude
|
|
453
504
|
*/
|
|
@@ -456,7 +507,7 @@ class ClaudePersistentExecutor extends events_1.EventEmitter {
|
|
|
456
507
|
// Parse message first to check type
|
|
457
508
|
const parsedMessage = JSON.parse(line);
|
|
458
509
|
// Skip logging for stream_event messages to avoid console spam
|
|
459
|
-
//
|
|
510
|
+
// Token deltas are handled below without logging every fragment.
|
|
460
511
|
if (parsedMessage.type !== 'stream_event') {
|
|
461
512
|
const timestamp = new Date().toISOString();
|
|
462
513
|
console.log(`[ClaudePersistent RAW ${timestamp}] ${line}`);
|
|
@@ -530,8 +581,7 @@ class ClaudePersistentExecutor extends events_1.EventEmitter {
|
|
|
530
581
|
}
|
|
531
582
|
break;
|
|
532
583
|
case 'stream_event':
|
|
533
|
-
|
|
534
|
-
// These include content_block_start, content_block_delta, etc.
|
|
584
|
+
this.handleStreamEvent(message);
|
|
535
585
|
break;
|
|
536
586
|
case 'result':
|
|
537
587
|
// Result messages contain the final response and completion status
|
|
@@ -625,15 +675,7 @@ class ClaudePersistentExecutor extends events_1.EventEmitter {
|
|
|
625
675
|
// with tool_result content. We should emit the hook when we receive tool_result.
|
|
626
676
|
}
|
|
627
677
|
else if (block.type === 'text' && block.text) {
|
|
628
|
-
|
|
629
|
-
this.currentOutputBuffer.push(block.text);
|
|
630
|
-
if (this.isInPlanMode) {
|
|
631
|
-
// Buffer plan content instead of streaming; still stream for real-time visibility
|
|
632
|
-
this.planModeBuffer.push(block.text);
|
|
633
|
-
}
|
|
634
|
-
if (this.currentStreamCallback) {
|
|
635
|
-
this.currentStreamCallback(block.text);
|
|
636
|
-
}
|
|
678
|
+
this.emitText(this.unstreamedText(message, block.text));
|
|
637
679
|
}
|
|
638
680
|
else if (block.type === 'redacted_thinking') {
|
|
639
681
|
// Handle redacted thinking blocks (Claude 3.7 Sonnet, Gemini models)
|
|
@@ -917,6 +959,7 @@ class ClaudePersistentExecutor extends events_1.EventEmitter {
|
|
|
917
959
|
*/
|
|
918
960
|
resetCurrentCommand() {
|
|
919
961
|
this.currentOutputBuffer = [];
|
|
962
|
+
this.textStreams.clear();
|
|
920
963
|
this.currentStreamCallback = undefined;
|
|
921
964
|
this.currentToolUseCallback = undefined;
|
|
922
965
|
this.currentToolResultCallback = undefined;
|
|
@@ -987,6 +1030,7 @@ class ClaudePersistentExecutor extends events_1.EventEmitter {
|
|
|
987
1030
|
// guard, which returns early without clearing it — so without this reset
|
|
988
1031
|
// the stale text would leak into this command's final output.
|
|
989
1032
|
this.currentOutputBuffer = [];
|
|
1033
|
+
this.textStreams.clear();
|
|
990
1034
|
// Reset structured content collection
|
|
991
1035
|
this.structuredContentBlocks = [];
|
|
992
1036
|
// Reset plan mode state
|