echoclaw-relay-agent 0.22.5 → 0.22.7
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/RelayAgent.js +10 -1
- package/dist/RelayClient.js +8 -0
- package/dist/install/InstallHandler.js +14 -0
- package/dist/install/types.d.ts +7 -1
- package/dist/install/types.js +4 -0
- package/package.json +1 -1
package/dist/RelayAgent.js
CHANGED
|
@@ -469,11 +469,20 @@ export class RelayAgent extends EventEmitter {
|
|
|
469
469
|
this.transport.on('connect_timeout', (timeoutMs) => {
|
|
470
470
|
this.emit('error', Object.assign(new Error(`Connection timed out after ${timeoutMs / 1000}s`), { code: 'CONNECT_TIMEOUT' }));
|
|
471
471
|
});
|
|
472
|
-
// Handle server
|
|
472
|
+
// Handle server messages (DESKTOP_RECONNECTED, fatal errors, etc.)
|
|
473
473
|
const SESSION_FATAL = new Set(['SESSION_NOT_FOUND', 'INVALID_SESSION', 'SESSION_PROTOCOL_MISMATCH']);
|
|
474
474
|
this.transport.on('message', (msg) => {
|
|
475
475
|
if ((msg.type === 'CLOSE' || msg.type === 'STATUS') && msg.sender_role === 'server') {
|
|
476
476
|
const payload = typeof msg.payload === 'string' ? msg.payload : '';
|
|
477
|
+
// Desktop restarted — reset FrameCrypto receive sequence counter.
|
|
478
|
+
// Desktop creates a new FrameCrypto on resumeSession() (sendSeq starts at 0),
|
|
479
|
+
// but Agent's FrameCrypto still has recvHighestSeq from the old session.
|
|
480
|
+
// Without this reset, all messages from Desktop are rejected as "Sequence regression".
|
|
481
|
+
if (payload === 'DESKTOP_RECONNECTED') {
|
|
482
|
+
this.frameCrypto?.reset();
|
|
483
|
+
this.emit('peer_reconnected');
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
477
486
|
if (payload === 'UNPAIRED' || SESSION_FATAL.has(payload)) {
|
|
478
487
|
this.sessionStore.clear().catch(() => { });
|
|
479
488
|
this._paired = false;
|
package/dist/RelayClient.js
CHANGED
|
@@ -399,6 +399,14 @@ export class RelayClient extends EventEmitter {
|
|
|
399
399
|
this.transport.on('message', (msg) => {
|
|
400
400
|
if ((msg.type === 'CLOSE' || msg.type === 'STATUS') && msg.sender_role === 'server') {
|
|
401
401
|
const payload = typeof msg.payload === 'string' ? msg.payload : '';
|
|
402
|
+
// Agent restarted — reset FrameCrypto receive sequence counter.
|
|
403
|
+
// Same issue as DESKTOP_RECONNECTED: Agent creates new FrameCrypto on restart
|
|
404
|
+
// (sendSeq starts at 0), but Desktop's recvHighestSeq is still from old session.
|
|
405
|
+
if (payload === 'AGENT_RESTARTED') {
|
|
406
|
+
this.frameCrypto?.reset();
|
|
407
|
+
this.emit('peer_reconnected');
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
402
410
|
if (PEER_STATUS.has(payload)) {
|
|
403
411
|
this.emit('peer_status', {
|
|
404
412
|
status: payload === 'AGENT_ONLINE' ? 'online' : 'warning',
|
|
@@ -31,6 +31,11 @@ const DEFAULT_SESSION_KEY = 'main';
|
|
|
31
31
|
const STATUS_THROTTLE_MS = 3000;
|
|
32
32
|
// ── InstallHandler ───────────────────────────────────────────────
|
|
33
33
|
export class InstallHandler {
|
|
34
|
+
// ── ICP (disabled until packages are on npm) ──
|
|
35
|
+
// private readonly _icpOrchestrator: IcpOrchestrator;
|
|
36
|
+
// private static readonly ICP_ACTIONS = new Set([
|
|
37
|
+
// 'install_with_config', 'complete_template', 'generate_fresh', 'adapt',
|
|
38
|
+
// ]);
|
|
34
39
|
constructor(wsClient, chatHandler, config) {
|
|
35
40
|
Object.defineProperty(this, "_wsClient", {
|
|
36
41
|
enumerable: true,
|
|
@@ -95,6 +100,11 @@ export class InstallHandler {
|
|
|
95
100
|
this._timeoutMs = config?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
96
101
|
this._sessionKey = config?.sessionKey ?? DEFAULT_SESSION_KEY;
|
|
97
102
|
this._rpcTimeoutMs = config?.rpcTimeoutMs ?? DEFAULT_RPC_TIMEOUT_MS;
|
|
103
|
+
// ICP orchestrator init disabled until packages are on npm
|
|
104
|
+
// this._icpOrchestrator = new IcpOrchestrator({
|
|
105
|
+
// outputTimeoutMs: this._timeoutMs,
|
|
106
|
+
// reviewTimeoutMs: this._timeoutMs,
|
|
107
|
+
// });
|
|
98
108
|
// Listen for chat events — only process runs we own
|
|
99
109
|
this._wsClient.on('chat', (payload) => {
|
|
100
110
|
const runId = payload?.runId;
|
|
@@ -149,6 +159,8 @@ export class InstallHandler {
|
|
|
149
159
|
requestId,
|
|
150
160
|
status: 'accepted',
|
|
151
161
|
});
|
|
162
|
+
// ── ICP workspace routing (disabled until packages are on npm) ──
|
|
163
|
+
// if (InstallHandler.ICP_ACTIONS.has(action) && this._workspaceSynced) { ... }
|
|
152
164
|
// Create active install tracker
|
|
153
165
|
const install = {
|
|
154
166
|
requestId,
|
|
@@ -246,6 +258,8 @@ export class InstallHandler {
|
|
|
246
258
|
this._activeInstalls.clear();
|
|
247
259
|
this._runToRequest.clear();
|
|
248
260
|
}
|
|
261
|
+
// ── ICP Workspace Flow (disabled until @echoclaw/claw-engine & icp-orchestrator are on npm) ──
|
|
262
|
+
// See git history for full ICP integration code.
|
|
249
263
|
// ── Private: Event Handling ────────────────────────────────────
|
|
250
264
|
/**
|
|
251
265
|
* Handle a streaming chat event for an install run.
|
package/dist/install/types.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ export interface InstallRequest {
|
|
|
33
33
|
};
|
|
34
34
|
/** Confirmed preview plan (for action='install' following a preview). */
|
|
35
35
|
confirmedPlan?: InstallPreviewData;
|
|
36
|
+
/** User's original request text (for action='generate_fresh'). */
|
|
37
|
+
userRequest?: string;
|
|
36
38
|
/** Target app ID (for action='adapt'). */
|
|
37
39
|
appId?: string;
|
|
38
40
|
/** App manifest (for action='adapt'). */
|
|
@@ -120,7 +122,7 @@ export interface InstallAck {
|
|
|
120
122
|
reason?: string;
|
|
121
123
|
}
|
|
122
124
|
/** Install processing phases. */
|
|
123
|
-
export type InstallPhase = 'sending' | 'ai_processing' | 'parsing' | 'validating' | 'previewing' | 'awaiting_confirm' | 'executing';
|
|
125
|
+
export type InstallPhase = 'sending' | 'ai_processing' | 'parsing' | 'validating' | 'previewing' | 'awaiting_confirm' | 'executing' | 'icp_writing_task' | 'icp_waiting_output' | 'icp_validating' | 'icp_reviewing' | 'icp_fallback' | 'icp_delivering';
|
|
124
126
|
/**
|
|
125
127
|
* Progress update during install processing.
|
|
126
128
|
*/
|
|
@@ -192,6 +194,10 @@ export declare const INSTALL_ERROR_CODES: {
|
|
|
192
194
|
readonly AI_ERROR: "INSTALL_AI_ERROR";
|
|
193
195
|
/** V2: AI response didn't contain preview data. */
|
|
194
196
|
readonly NO_PREVIEW_DATA: "INSTALL_NO_PREVIEW_DATA";
|
|
197
|
+
/** V3/ICP: Workspace output timed out, falling back to chat-based. */
|
|
198
|
+
readonly ICP_TIMEOUT: "INSTALL_ICP_TIMEOUT";
|
|
199
|
+
/** V3/ICP: ICP orchestrator failed. */
|
|
200
|
+
readonly ICP_FAILED: "INSTALL_ICP_FAILED";
|
|
195
201
|
};
|
|
196
202
|
/** All install-related messages from Desktop to Agent. */
|
|
197
203
|
export type InstallIncoming = InstallRequest | InstallAbort;
|
package/dist/install/types.js
CHANGED
|
@@ -33,4 +33,8 @@ export const INSTALL_ERROR_CODES = {
|
|
|
33
33
|
AI_ERROR: 'INSTALL_AI_ERROR',
|
|
34
34
|
/** V2: AI response didn't contain preview data. */
|
|
35
35
|
NO_PREVIEW_DATA: 'INSTALL_NO_PREVIEW_DATA',
|
|
36
|
+
/** V3/ICP: Workspace output timed out, falling back to chat-based. */
|
|
37
|
+
ICP_TIMEOUT: 'INSTALL_ICP_TIMEOUT',
|
|
38
|
+
/** V3/ICP: ICP orchestrator failed. */
|
|
39
|
+
ICP_FAILED: 'INSTALL_ICP_FAILED',
|
|
36
40
|
};
|
package/package.json
CHANGED