happy-imou-cloud 2.1.7 → 2.1.8
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/bin/happy-cloud.mjs +1 -1
- package/dist/{BaseReasoningProcessor-iSuaFeZH.cjs → BaseReasoningProcessor-CbqNgi4p.cjs} +2 -2
- package/dist/{BaseReasoningProcessor-C0A6Jr8V.mjs → BaseReasoningProcessor-DJ9zxAdt.mjs} +2 -2
- package/dist/{ProviderSelectionHandler-DI9QK1iY.cjs → ProviderSelectionHandler-BZVtGMAn.cjs} +2 -2
- package/dist/{ProviderSelectionHandler-WT-tvePy.mjs → ProviderSelectionHandler-BleheBks.mjs} +2 -2
- package/dist/{api-CdGT5hsH.cjs → api-CeIpGPqs.cjs} +86 -32
- package/dist/{api-BYKV7vX6.mjs → api-DRdn4-dL.mjs} +86 -32
- package/dist/{command-uyA8cYmL.cjs → command-CTad-7bA.cjs} +3 -3
- package/dist/{command-C1cKqmsa.mjs → command-mDMWVdh5.mjs} +3 -3
- package/dist/{index-BAhlFq45.mjs → index-C4S85XB7.mjs} +144 -29
- package/dist/{index-D_S_7bqK.cjs → index-D68EOBHW.cjs} +147 -32
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +7 -4
- package/dist/lib.d.mts +7 -4
- package/dist/lib.mjs +1 -1
- package/dist/{persistence-CMvrZ4SA.cjs → persistence-Czyd-Uei.cjs} +1 -1
- package/dist/{persistence-B8Wgn6aN.mjs → persistence-DgpGouOO.mjs} +1 -1
- package/dist/{registerKillSessionHandler-DjxtkGMv.cjs → registerKillSessionHandler-DECzSYvQ.cjs} +3 -3
- package/dist/{registerKillSessionHandler-5DVlZaJx.mjs → registerKillSessionHandler-Dg0DFPae.mjs} +3 -3
- package/dist/{runClaude-DNZFsQY0.cjs → runClaude-DtCH-nx-.cjs} +9 -5
- package/dist/{runClaude-WB884iOO.mjs → runClaude-OWT6ZYiP.mjs} +9 -5
- package/dist/{runCodex-MJar-238.mjs → runCodex-BU3BA1l8.mjs} +96 -21
- package/dist/{runCodex-WZ91ZLK7.cjs → runCodex-reARLjN0.cjs} +96 -21
- package/dist/{runGemini-B_wCHgPU.cjs → runGemini-BvJUvOvj.cjs} +11 -5
- package/dist/{runGemini-BPGpwljp.mjs → runGemini-DeLxSapY.mjs} +11 -5
- package/package.json +1 -1
- package/scripts/devtools/README.md +9 -9
- package/scripts/e2e/fake-codex-acp-agent.mjs +139 -139
- package/scripts/e2e/local-server-session-roundtrip.mjs +1063 -1063
- package/scripts/ensureAcpSdkCompat.mjs +1 -1
package/bin/happy-cloud.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
4
|
-
var api = require('./api-
|
|
3
|
+
var index = require('./index-D68EOBHW.cjs');
|
|
4
|
+
var api = require('./api-CeIpGPqs.cjs');
|
|
5
5
|
var node_events = require('node:events');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
7
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as createSessionMetadata, p as publishSessionRegistration } from './index-
|
|
2
|
-
import { s as startOfflineReconnection, c as configuration, i as isAuthenticationRequiredError, l as logger } from './api-
|
|
1
|
+
import { a as createSessionMetadata, p as publishSessionRegistration } from './index-C4S85XB7.mjs';
|
|
2
|
+
import { s as startOfflineReconnection, c as configuration, i as isAuthenticationRequiredError, l as logger } from './api-DRdn4-dL.mjs';
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
|
package/dist/{ProviderSelectionHandler-DI9QK1iY.cjs → ProviderSelectionHandler-BZVtGMAn.cjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var api = require('./api-
|
|
4
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
3
|
+
var api = require('./api-CeIpGPqs.cjs');
|
|
4
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-DECzSYvQ.cjs');
|
|
5
5
|
|
|
6
6
|
async function runModeLoop(opts) {
|
|
7
7
|
let currentMode = opts.startingMode;
|
package/dist/{ProviderSelectionHandler-WT-tvePy.mjs → ProviderSelectionHandler-BleheBks.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as logger } from './api-
|
|
2
|
-
import { g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, a as INTERACTION_TIMED_OUT_ERROR } from './registerKillSessionHandler-
|
|
1
|
+
import { l as logger } from './api-DRdn4-dL.mjs';
|
|
2
|
+
import { g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, a as INTERACTION_TIMED_OUT_ERROR } from './registerKillSessionHandler-Dg0DFPae.mjs';
|
|
3
3
|
|
|
4
4
|
async function runModeLoop(opts) {
|
|
5
5
|
let currentMode = opts.startingMode;
|
|
@@ -18,7 +18,7 @@ var node_child_process = require('node:child_process');
|
|
|
18
18
|
var expoServerSdk = require('expo-server-sdk');
|
|
19
19
|
|
|
20
20
|
var name = "happy-imou-cloud";
|
|
21
|
-
var version = "2.1.
|
|
21
|
+
var version = "2.1.8";
|
|
22
22
|
var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
|
|
23
23
|
var author = "long.zhu";
|
|
24
24
|
var license = "MIT";
|
|
@@ -433,7 +433,7 @@ async function listDaemonLogFiles(limit = 50) {
|
|
|
433
433
|
return { file, path: fullPath, modified: stats.mtime };
|
|
434
434
|
}).sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
435
435
|
try {
|
|
436
|
-
const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-
|
|
436
|
+
const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-Czyd-Uei.cjs'); });
|
|
437
437
|
const state = await readDaemonState();
|
|
438
438
|
if (!state) {
|
|
439
439
|
return logs;
|
|
@@ -1734,8 +1734,8 @@ function buildSocketAuth(opts) {
|
|
|
1734
1734
|
return auth;
|
|
1735
1735
|
}
|
|
1736
1736
|
|
|
1737
|
-
const
|
|
1738
|
-
const
|
|
1737
|
+
const MAX_PENDING_RELIABLE_SESSION_MESSAGES = 200;
|
|
1738
|
+
const MAX_PENDING_RELIABLE_SESSION_MESSAGE_BYTES = 512 * 1024;
|
|
1739
1739
|
const PROTOCOL_V3_INITIAL_SNAPSHOT_LIMIT = 150;
|
|
1740
1740
|
const PROTOCOL_V3_CHANGES_PAGE_LIMIT = 200;
|
|
1741
1741
|
const PROTOCOL_V3_CAPABILITIES_WAIT_MS = 250;
|
|
@@ -1754,8 +1754,8 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1754
1754
|
metadataLock = new AsyncLock();
|
|
1755
1755
|
encryptionKey;
|
|
1756
1756
|
encryptionVariant;
|
|
1757
|
-
|
|
1758
|
-
|
|
1757
|
+
pendingReliableSessionMessages = [];
|
|
1758
|
+
pendingReliableSessionMessageBytes = 0;
|
|
1759
1759
|
reconnectAfterServerDisconnectTimer = null;
|
|
1760
1760
|
lastSocketServerError = null;
|
|
1761
1761
|
protocolV3SessionSync = null;
|
|
@@ -1805,7 +1805,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1805
1805
|
this.clearReconnectAfterServerDisconnectTimer();
|
|
1806
1806
|
this.lastSocketServerError = null;
|
|
1807
1807
|
this.rpcHandlerManager.onSocketConnect(this.socket);
|
|
1808
|
-
this.
|
|
1808
|
+
this.flushReliableSessionMessages();
|
|
1809
1809
|
this.protocolV3Descriptor = null;
|
|
1810
1810
|
this.protocolV3SocketCapabilities = null;
|
|
1811
1811
|
this.scheduleProtocolV3SessionSync();
|
|
@@ -1988,9 +1988,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1988
1988
|
if (!this.socket.connected) {
|
|
1989
1989
|
if (this.shouldBufferReliableCodexMessage(body)) {
|
|
1990
1990
|
logger.debug("[API] Socket not connected, buffering reliable Codex message:", { type: eventType });
|
|
1991
|
-
this.
|
|
1992
|
-
this.pendingReliableCodexMessageBytes += encrypted.length;
|
|
1993
|
-
this.trimPendingReliableCodexMessages();
|
|
1991
|
+
this.bufferReliableSessionMessage({ encrypted, type: `codex:${eventType}` });
|
|
1994
1992
|
} else {
|
|
1995
1993
|
logger.debug("[API] Socket not connected, dropping non-critical Codex message:", { type: eventType });
|
|
1996
1994
|
}
|
|
@@ -2019,10 +2017,23 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2019
2017
|
};
|
|
2020
2018
|
logger.debug(`[SOCKET] Sending ACP message from ${provider}:`, { type: body.type, hasMessage: "message" in body });
|
|
2021
2019
|
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2020
|
+
const eventType = typeof body?.type === "string" ? body.type : "unknown";
|
|
2021
|
+
if (!this.socket.connected) {
|
|
2022
|
+
if (this.shouldBufferReliableAcpMessage(body)) {
|
|
2023
|
+
logger.debug("[API] Socket not connected, buffering reliable ACP message:", {
|
|
2024
|
+
provider,
|
|
2025
|
+
type: eventType
|
|
2026
|
+
});
|
|
2027
|
+
this.bufferReliableSessionMessage({ encrypted, type: `acp:${provider}:${eventType}` });
|
|
2028
|
+
} else {
|
|
2029
|
+
logger.debug("[API] Socket not connected, dropping non-critical ACP message:", {
|
|
2030
|
+
provider,
|
|
2031
|
+
type: eventType
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
return;
|
|
2035
|
+
}
|
|
2036
|
+
this.emitEncryptedSessionMessage(encrypted);
|
|
2026
2037
|
}
|
|
2027
2038
|
sendSessionEvent(event, id) {
|
|
2028
2039
|
let content = {
|
|
@@ -2034,10 +2045,16 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2034
2045
|
}
|
|
2035
2046
|
};
|
|
2036
2047
|
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
2037
|
-
this.socket.
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2048
|
+
if (!this.socket.connected) {
|
|
2049
|
+
if (this.shouldBufferReliableSessionEvent(event)) {
|
|
2050
|
+
logger.debug("[API] Socket not connected, buffering session event:", { type: event.type });
|
|
2051
|
+
this.bufferReliableSessionMessage({ encrypted, type: `event:${event.type}` });
|
|
2052
|
+
} else {
|
|
2053
|
+
logger.debug("[API] Socket not connected, dropping session event:", { type: event.type });
|
|
2054
|
+
}
|
|
2055
|
+
return;
|
|
2056
|
+
}
|
|
2057
|
+
this.emitEncryptedSessionMessage(encrypted);
|
|
2041
2058
|
}
|
|
2042
2059
|
/**
|
|
2043
2060
|
* Send a ping message to keep the connection alive
|
|
@@ -2091,7 +2108,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2091
2108
|
* @param handler - Handler function that returns the updated metadata
|
|
2092
2109
|
*/
|
|
2093
2110
|
updateMetadata(handler) {
|
|
2094
|
-
this.metadataLock.inLock(async () => {
|
|
2111
|
+
void this.metadataLock.inLock(async () => {
|
|
2095
2112
|
await backoff(async () => {
|
|
2096
2113
|
let updated = handler(this.metadata);
|
|
2097
2114
|
const sessionIndex = buildSessionRuntimeIndex(updated);
|
|
@@ -2114,6 +2131,8 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2114
2131
|
throw new Error("Metadata version mismatch");
|
|
2115
2132
|
} else if (answer.result === "error") ;
|
|
2116
2133
|
});
|
|
2134
|
+
}).catch((error) => {
|
|
2135
|
+
logger.debug("[API] Metadata update failed unexpectedly", error);
|
|
2117
2136
|
});
|
|
2118
2137
|
}
|
|
2119
2138
|
/**
|
|
@@ -2122,7 +2141,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2122
2141
|
*/
|
|
2123
2142
|
updateAgentState(handler) {
|
|
2124
2143
|
logger.debugLargeJson("Updating agent state", this.agentState);
|
|
2125
|
-
this.agentStateLock.inLock(async () => {
|
|
2144
|
+
void this.agentStateLock.inLock(async () => {
|
|
2126
2145
|
await backoff(async () => {
|
|
2127
2146
|
let updated = handler(this.agentState || {});
|
|
2128
2147
|
const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) : null });
|
|
@@ -2140,6 +2159,8 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2140
2159
|
throw new Error("Agent state version mismatch");
|
|
2141
2160
|
} else if (answer.result === "error") ;
|
|
2142
2161
|
});
|
|
2162
|
+
}).catch((error) => {
|
|
2163
|
+
logger.debug("[API] Agent state update failed unexpectedly", error);
|
|
2143
2164
|
});
|
|
2144
2165
|
}
|
|
2145
2166
|
/**
|
|
@@ -2441,13 +2462,18 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2441
2462
|
message: encrypted
|
|
2442
2463
|
});
|
|
2443
2464
|
}
|
|
2444
|
-
|
|
2445
|
-
|
|
2465
|
+
bufferReliableSessionMessage(message) {
|
|
2466
|
+
this.pendingReliableSessionMessages.push(message);
|
|
2467
|
+
this.pendingReliableSessionMessageBytes += message.encrypted.length;
|
|
2468
|
+
this.trimPendingReliableSessionMessages();
|
|
2469
|
+
}
|
|
2470
|
+
flushReliableSessionMessages() {
|
|
2471
|
+
if (!this.socket.connected || this.pendingReliableSessionMessages.length === 0) {
|
|
2446
2472
|
return;
|
|
2447
2473
|
}
|
|
2448
|
-
const buffered = this.
|
|
2449
|
-
this.
|
|
2450
|
-
logger.debug("[API] Flushing buffered
|
|
2474
|
+
const buffered = this.pendingReliableSessionMessages.splice(0, this.pendingReliableSessionMessages.length);
|
|
2475
|
+
this.pendingReliableSessionMessageBytes = 0;
|
|
2476
|
+
logger.debug("[API] Flushing buffered session messages after reconnect", {
|
|
2451
2477
|
count: buffered.length,
|
|
2452
2478
|
types: buffered.map((message) => message.type)
|
|
2453
2479
|
});
|
|
@@ -2471,21 +2497,49 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2471
2497
|
return false;
|
|
2472
2498
|
}
|
|
2473
2499
|
}
|
|
2474
|
-
|
|
2500
|
+
shouldBufferReliableAcpMessage(body) {
|
|
2501
|
+
switch (body?.type) {
|
|
2502
|
+
case "message":
|
|
2503
|
+
case "tool-call":
|
|
2504
|
+
case "tool-result":
|
|
2505
|
+
case "file-edit":
|
|
2506
|
+
case "terminal-output":
|
|
2507
|
+
case "task_started":
|
|
2508
|
+
case "task_complete":
|
|
2509
|
+
case "turn_aborted":
|
|
2510
|
+
case "turn-report":
|
|
2511
|
+
case "permission-request":
|
|
2512
|
+
return true;
|
|
2513
|
+
default:
|
|
2514
|
+
return false;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
shouldBufferReliableSessionEvent(event) {
|
|
2518
|
+
switch (event.type) {
|
|
2519
|
+
case "switch":
|
|
2520
|
+
case "message":
|
|
2521
|
+
case "permission-mode-changed":
|
|
2522
|
+
case "ready":
|
|
2523
|
+
return true;
|
|
2524
|
+
default:
|
|
2525
|
+
return false;
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
trimPendingReliableSessionMessages() {
|
|
2475
2529
|
let dropped = 0;
|
|
2476
|
-
while (this.
|
|
2477
|
-
const removed = this.
|
|
2530
|
+
while (this.pendingReliableSessionMessages.length > MAX_PENDING_RELIABLE_SESSION_MESSAGES || this.pendingReliableSessionMessageBytes > MAX_PENDING_RELIABLE_SESSION_MESSAGE_BYTES) {
|
|
2531
|
+
const removed = this.pendingReliableSessionMessages.shift();
|
|
2478
2532
|
if (!removed) {
|
|
2479
2533
|
break;
|
|
2480
2534
|
}
|
|
2481
|
-
this.
|
|
2535
|
+
this.pendingReliableSessionMessageBytes -= removed.encrypted.length;
|
|
2482
2536
|
dropped += 1;
|
|
2483
2537
|
}
|
|
2484
2538
|
if (dropped > 0) {
|
|
2485
|
-
logger.debug("[API] Dropped oldest buffered
|
|
2539
|
+
logger.debug("[API] Dropped oldest buffered session messages to cap reconnect memory usage", {
|
|
2486
2540
|
dropped,
|
|
2487
|
-
remaining: this.
|
|
2488
|
-
bytes: this.
|
|
2541
|
+
remaining: this.pendingReliableSessionMessages.length,
|
|
2542
|
+
bytes: this.pendingReliableSessionMessageBytes
|
|
2489
2543
|
});
|
|
2490
2544
|
}
|
|
2491
2545
|
}
|
|
@@ -16,7 +16,7 @@ import { spawn } from 'node:child_process';
|
|
|
16
16
|
import { Expo } from 'expo-server-sdk';
|
|
17
17
|
|
|
18
18
|
var name = "happy-imou-cloud";
|
|
19
|
-
var version = "2.1.
|
|
19
|
+
var version = "2.1.8";
|
|
20
20
|
var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
|
|
21
21
|
var author = "long.zhu";
|
|
22
22
|
var license = "MIT";
|
|
@@ -431,7 +431,7 @@ async function listDaemonLogFiles(limit = 50) {
|
|
|
431
431
|
return { file, path: fullPath, modified: stats.mtime };
|
|
432
432
|
}).sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
433
433
|
try {
|
|
434
|
-
const { readDaemonState } = await import('./persistence-
|
|
434
|
+
const { readDaemonState } = await import('./persistence-DgpGouOO.mjs');
|
|
435
435
|
const state = await readDaemonState();
|
|
436
436
|
if (!state) {
|
|
437
437
|
return logs;
|
|
@@ -1732,8 +1732,8 @@ function buildSocketAuth(opts) {
|
|
|
1732
1732
|
return auth;
|
|
1733
1733
|
}
|
|
1734
1734
|
|
|
1735
|
-
const
|
|
1736
|
-
const
|
|
1735
|
+
const MAX_PENDING_RELIABLE_SESSION_MESSAGES = 200;
|
|
1736
|
+
const MAX_PENDING_RELIABLE_SESSION_MESSAGE_BYTES = 512 * 1024;
|
|
1737
1737
|
const PROTOCOL_V3_INITIAL_SNAPSHOT_LIMIT = 150;
|
|
1738
1738
|
const PROTOCOL_V3_CHANGES_PAGE_LIMIT = 200;
|
|
1739
1739
|
const PROTOCOL_V3_CAPABILITIES_WAIT_MS = 250;
|
|
@@ -1752,8 +1752,8 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1752
1752
|
metadataLock = new AsyncLock();
|
|
1753
1753
|
encryptionKey;
|
|
1754
1754
|
encryptionVariant;
|
|
1755
|
-
|
|
1756
|
-
|
|
1755
|
+
pendingReliableSessionMessages = [];
|
|
1756
|
+
pendingReliableSessionMessageBytes = 0;
|
|
1757
1757
|
reconnectAfterServerDisconnectTimer = null;
|
|
1758
1758
|
lastSocketServerError = null;
|
|
1759
1759
|
protocolV3SessionSync = null;
|
|
@@ -1803,7 +1803,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1803
1803
|
this.clearReconnectAfterServerDisconnectTimer();
|
|
1804
1804
|
this.lastSocketServerError = null;
|
|
1805
1805
|
this.rpcHandlerManager.onSocketConnect(this.socket);
|
|
1806
|
-
this.
|
|
1806
|
+
this.flushReliableSessionMessages();
|
|
1807
1807
|
this.protocolV3Descriptor = null;
|
|
1808
1808
|
this.protocolV3SocketCapabilities = null;
|
|
1809
1809
|
this.scheduleProtocolV3SessionSync();
|
|
@@ -1986,9 +1986,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1986
1986
|
if (!this.socket.connected) {
|
|
1987
1987
|
if (this.shouldBufferReliableCodexMessage(body)) {
|
|
1988
1988
|
logger.debug("[API] Socket not connected, buffering reliable Codex message:", { type: eventType });
|
|
1989
|
-
this.
|
|
1990
|
-
this.pendingReliableCodexMessageBytes += encrypted.length;
|
|
1991
|
-
this.trimPendingReliableCodexMessages();
|
|
1989
|
+
this.bufferReliableSessionMessage({ encrypted, type: `codex:${eventType}` });
|
|
1992
1990
|
} else {
|
|
1993
1991
|
logger.debug("[API] Socket not connected, dropping non-critical Codex message:", { type: eventType });
|
|
1994
1992
|
}
|
|
@@ -2017,10 +2015,23 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2017
2015
|
};
|
|
2018
2016
|
logger.debug(`[SOCKET] Sending ACP message from ${provider}:`, { type: body.type, hasMessage: "message" in body });
|
|
2019
2017
|
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2018
|
+
const eventType = typeof body?.type === "string" ? body.type : "unknown";
|
|
2019
|
+
if (!this.socket.connected) {
|
|
2020
|
+
if (this.shouldBufferReliableAcpMessage(body)) {
|
|
2021
|
+
logger.debug("[API] Socket not connected, buffering reliable ACP message:", {
|
|
2022
|
+
provider,
|
|
2023
|
+
type: eventType
|
|
2024
|
+
});
|
|
2025
|
+
this.bufferReliableSessionMessage({ encrypted, type: `acp:${provider}:${eventType}` });
|
|
2026
|
+
} else {
|
|
2027
|
+
logger.debug("[API] Socket not connected, dropping non-critical ACP message:", {
|
|
2028
|
+
provider,
|
|
2029
|
+
type: eventType
|
|
2030
|
+
});
|
|
2031
|
+
}
|
|
2032
|
+
return;
|
|
2033
|
+
}
|
|
2034
|
+
this.emitEncryptedSessionMessage(encrypted);
|
|
2024
2035
|
}
|
|
2025
2036
|
sendSessionEvent(event, id) {
|
|
2026
2037
|
let content = {
|
|
@@ -2032,10 +2043,16 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2032
2043
|
}
|
|
2033
2044
|
};
|
|
2034
2045
|
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
2035
|
-
this.socket.
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2046
|
+
if (!this.socket.connected) {
|
|
2047
|
+
if (this.shouldBufferReliableSessionEvent(event)) {
|
|
2048
|
+
logger.debug("[API] Socket not connected, buffering session event:", { type: event.type });
|
|
2049
|
+
this.bufferReliableSessionMessage({ encrypted, type: `event:${event.type}` });
|
|
2050
|
+
} else {
|
|
2051
|
+
logger.debug("[API] Socket not connected, dropping session event:", { type: event.type });
|
|
2052
|
+
}
|
|
2053
|
+
return;
|
|
2054
|
+
}
|
|
2055
|
+
this.emitEncryptedSessionMessage(encrypted);
|
|
2039
2056
|
}
|
|
2040
2057
|
/**
|
|
2041
2058
|
* Send a ping message to keep the connection alive
|
|
@@ -2089,7 +2106,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2089
2106
|
* @param handler - Handler function that returns the updated metadata
|
|
2090
2107
|
*/
|
|
2091
2108
|
updateMetadata(handler) {
|
|
2092
|
-
this.metadataLock.inLock(async () => {
|
|
2109
|
+
void this.metadataLock.inLock(async () => {
|
|
2093
2110
|
await backoff(async () => {
|
|
2094
2111
|
let updated = handler(this.metadata);
|
|
2095
2112
|
const sessionIndex = buildSessionRuntimeIndex(updated);
|
|
@@ -2112,6 +2129,8 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2112
2129
|
throw new Error("Metadata version mismatch");
|
|
2113
2130
|
} else if (answer.result === "error") ;
|
|
2114
2131
|
});
|
|
2132
|
+
}).catch((error) => {
|
|
2133
|
+
logger.debug("[API] Metadata update failed unexpectedly", error);
|
|
2115
2134
|
});
|
|
2116
2135
|
}
|
|
2117
2136
|
/**
|
|
@@ -2120,7 +2139,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2120
2139
|
*/
|
|
2121
2140
|
updateAgentState(handler) {
|
|
2122
2141
|
logger.debugLargeJson("Updating agent state", this.agentState);
|
|
2123
|
-
this.agentStateLock.inLock(async () => {
|
|
2142
|
+
void this.agentStateLock.inLock(async () => {
|
|
2124
2143
|
await backoff(async () => {
|
|
2125
2144
|
let updated = handler(this.agentState || {});
|
|
2126
2145
|
const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) : null });
|
|
@@ -2138,6 +2157,8 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2138
2157
|
throw new Error("Agent state version mismatch");
|
|
2139
2158
|
} else if (answer.result === "error") ;
|
|
2140
2159
|
});
|
|
2160
|
+
}).catch((error) => {
|
|
2161
|
+
logger.debug("[API] Agent state update failed unexpectedly", error);
|
|
2141
2162
|
});
|
|
2142
2163
|
}
|
|
2143
2164
|
/**
|
|
@@ -2439,13 +2460,18 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2439
2460
|
message: encrypted
|
|
2440
2461
|
});
|
|
2441
2462
|
}
|
|
2442
|
-
|
|
2443
|
-
|
|
2463
|
+
bufferReliableSessionMessage(message) {
|
|
2464
|
+
this.pendingReliableSessionMessages.push(message);
|
|
2465
|
+
this.pendingReliableSessionMessageBytes += message.encrypted.length;
|
|
2466
|
+
this.trimPendingReliableSessionMessages();
|
|
2467
|
+
}
|
|
2468
|
+
flushReliableSessionMessages() {
|
|
2469
|
+
if (!this.socket.connected || this.pendingReliableSessionMessages.length === 0) {
|
|
2444
2470
|
return;
|
|
2445
2471
|
}
|
|
2446
|
-
const buffered = this.
|
|
2447
|
-
this.
|
|
2448
|
-
logger.debug("[API] Flushing buffered
|
|
2472
|
+
const buffered = this.pendingReliableSessionMessages.splice(0, this.pendingReliableSessionMessages.length);
|
|
2473
|
+
this.pendingReliableSessionMessageBytes = 0;
|
|
2474
|
+
logger.debug("[API] Flushing buffered session messages after reconnect", {
|
|
2449
2475
|
count: buffered.length,
|
|
2450
2476
|
types: buffered.map((message) => message.type)
|
|
2451
2477
|
});
|
|
@@ -2469,21 +2495,49 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2469
2495
|
return false;
|
|
2470
2496
|
}
|
|
2471
2497
|
}
|
|
2472
|
-
|
|
2498
|
+
shouldBufferReliableAcpMessage(body) {
|
|
2499
|
+
switch (body?.type) {
|
|
2500
|
+
case "message":
|
|
2501
|
+
case "tool-call":
|
|
2502
|
+
case "tool-result":
|
|
2503
|
+
case "file-edit":
|
|
2504
|
+
case "terminal-output":
|
|
2505
|
+
case "task_started":
|
|
2506
|
+
case "task_complete":
|
|
2507
|
+
case "turn_aborted":
|
|
2508
|
+
case "turn-report":
|
|
2509
|
+
case "permission-request":
|
|
2510
|
+
return true;
|
|
2511
|
+
default:
|
|
2512
|
+
return false;
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
shouldBufferReliableSessionEvent(event) {
|
|
2516
|
+
switch (event.type) {
|
|
2517
|
+
case "switch":
|
|
2518
|
+
case "message":
|
|
2519
|
+
case "permission-mode-changed":
|
|
2520
|
+
case "ready":
|
|
2521
|
+
return true;
|
|
2522
|
+
default:
|
|
2523
|
+
return false;
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
trimPendingReliableSessionMessages() {
|
|
2473
2527
|
let dropped = 0;
|
|
2474
|
-
while (this.
|
|
2475
|
-
const removed = this.
|
|
2528
|
+
while (this.pendingReliableSessionMessages.length > MAX_PENDING_RELIABLE_SESSION_MESSAGES || this.pendingReliableSessionMessageBytes > MAX_PENDING_RELIABLE_SESSION_MESSAGE_BYTES) {
|
|
2529
|
+
const removed = this.pendingReliableSessionMessages.shift();
|
|
2476
2530
|
if (!removed) {
|
|
2477
2531
|
break;
|
|
2478
2532
|
}
|
|
2479
|
-
this.
|
|
2533
|
+
this.pendingReliableSessionMessageBytes -= removed.encrypted.length;
|
|
2480
2534
|
dropped += 1;
|
|
2481
2535
|
}
|
|
2482
2536
|
if (dropped > 0) {
|
|
2483
|
-
logger.debug("[API] Dropped oldest buffered
|
|
2537
|
+
logger.debug("[API] Dropped oldest buffered session messages to cap reconnect memory usage", {
|
|
2484
2538
|
dropped,
|
|
2485
|
-
remaining: this.
|
|
2486
|
-
bytes: this.
|
|
2539
|
+
remaining: this.pendingReliableSessionMessages.length,
|
|
2540
|
+
bytes: this.pendingReliableSessionMessageBytes
|
|
2487
2541
|
});
|
|
2488
2542
|
}
|
|
2489
2543
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-D68EOBHW.cjs');
|
|
4
4
|
require('chalk');
|
|
5
|
-
require('./api-
|
|
5
|
+
require('./api-CeIpGPqs.cjs');
|
|
6
6
|
require('axios');
|
|
7
7
|
require('fs');
|
|
8
8
|
require('node:fs');
|
|
@@ -18,7 +18,7 @@ require('crypto');
|
|
|
18
18
|
require('path');
|
|
19
19
|
require('node:child_process');
|
|
20
20
|
require('expo-server-sdk');
|
|
21
|
-
require('./persistence-
|
|
21
|
+
require('./persistence-Czyd-Uei.cjs');
|
|
22
22
|
require('node:fs/promises');
|
|
23
23
|
require('os');
|
|
24
24
|
require('tmp');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createDefaultRuntimeShell } from './index-
|
|
1
|
+
import { c as createDefaultRuntimeShell } from './index-C4S85XB7.mjs';
|
|
2
2
|
import 'chalk';
|
|
3
|
-
import './api-
|
|
3
|
+
import './api-DRdn4-dL.mjs';
|
|
4
4
|
import 'axios';
|
|
5
5
|
import 'fs';
|
|
6
6
|
import 'node:fs';
|
|
@@ -16,7 +16,7 @@ import 'crypto';
|
|
|
16
16
|
import 'path';
|
|
17
17
|
import 'node:child_process';
|
|
18
18
|
import 'expo-server-sdk';
|
|
19
|
-
import './persistence-
|
|
19
|
+
import './persistence-DgpGouOO.mjs';
|
|
20
20
|
import 'node:fs/promises';
|
|
21
21
|
import 'os';
|
|
22
22
|
import 'tmp';
|