happy-imou-cloud 2.1.42 → 2.1.43
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/{BaseReasoningProcessor-Bq2Eh351.mjs → BaseReasoningProcessor-CWCPAVJ3.mjs} +4 -2
- package/dist/{BaseReasoningProcessor-BwuoSz2l.cjs → BaseReasoningProcessor-D6itItnT.cjs} +4 -2
- package/dist/{ProviderSelectionHandler-BpBO_5F5.cjs → ProviderSelectionHandler-CXwqOJpC.cjs} +2 -2
- package/dist/{ProviderSelectionHandler-Dz9bzO6r.mjs → ProviderSelectionHandler-CYUH1U8F.mjs} +2 -2
- package/dist/{api-DHHrvH1L.mjs → api-B89O-SC-.mjs} +261 -38
- package/dist/{api-Btcmobjm.cjs → api-zMic8QXq.cjs} +261 -37
- package/dist/{command-CZh0T9p1.mjs → command-W01qXC9C.mjs} +2 -2
- package/dist/{command-MtPPL26Y.cjs → command-_qNFoJ-l.cjs} +2 -2
- package/dist/{index-CKuJSLuU.mjs → index-CiHiCC31.mjs} +25 -16
- package/dist/{index-CCsk2Klg.cjs → index-DVVbyQGZ.cjs} +28 -19
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +827 -0
- package/dist/lib.d.mts +827 -0
- package/dist/lib.mjs +1 -1
- package/dist/{registerKillSessionHandler-CStAJszS.mjs → registerKillSessionHandler-BnS3ozFX.mjs} +270 -99
- package/dist/{registerKillSessionHandler-DdJrfRVO.cjs → registerKillSessionHandler-CDYAY5Ev.cjs} +270 -99
- package/dist/{runClaude-DxeIMKax.mjs → runClaude-0U7kV07_.mjs} +13 -4
- package/dist/{runClaude-ge-0Ex7x.cjs → runClaude-C1xfptKt.cjs} +14 -5
- package/dist/{runCodex-DBAVYSvY.cjs → runCodex-BBgKpYLO.cjs} +20 -6
- package/dist/{runCodex-tXxg-NBv.mjs → runCodex-DnDmHm7E.mjs} +19 -5
- package/dist/{runGemini-CF8Pq4xx.cjs → runGemini-CUwQHJ9y.cjs} +21 -5
- package/dist/{runGemini-BLWj_J4D.mjs → runGemini-DcsIBQSc.mjs} +20 -4
- package/package.json +1 -1
|
@@ -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-CiHiCC31.mjs';
|
|
2
|
+
import { s as startOfflineReconnection, c as configuration, i as isAuthenticationRequiredError, l as logger } from './api-B89O-SC-.mjs';
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
|
|
@@ -42,6 +42,8 @@ function createOfflineSessionStub(sessionTag) {
|
|
|
42
42
|
waitForMetadataUpdate: async () => metadata,
|
|
43
43
|
onUserMessage: () => {
|
|
44
44
|
},
|
|
45
|
+
onSessionMessage: () => {
|
|
46
|
+
},
|
|
45
47
|
configureProtocolV3Sync: () => {
|
|
46
48
|
},
|
|
47
49
|
rpcHandlerManager: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
4
|
-
var persistence = require('./api-
|
|
3
|
+
var index = require('./index-DVVbyQGZ.cjs');
|
|
4
|
+
var persistence = require('./api-zMic8QXq.cjs');
|
|
5
5
|
var node_events = require('node:events');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
7
|
|
|
@@ -44,6 +44,8 @@ function createOfflineSessionStub(sessionTag) {
|
|
|
44
44
|
waitForMetadataUpdate: async () => metadata,
|
|
45
45
|
onUserMessage: () => {
|
|
46
46
|
},
|
|
47
|
+
onSessionMessage: () => {
|
|
48
|
+
},
|
|
47
49
|
configureProtocolV3Sync: () => {
|
|
48
50
|
},
|
|
49
51
|
rpcHandlerManager: {
|
package/dist/{ProviderSelectionHandler-BpBO_5F5.cjs → ProviderSelectionHandler-CXwqOJpC.cjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var persistence = require('./api-
|
|
4
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
3
|
+
var persistence = require('./api-zMic8QXq.cjs');
|
|
4
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-CDYAY5Ev.cjs');
|
|
5
5
|
|
|
6
6
|
async function runModeLoop(opts) {
|
|
7
7
|
let currentMode = opts.startingMode;
|
package/dist/{ProviderSelectionHandler-Dz9bzO6r.mjs → ProviderSelectionHandler-CYUH1U8F.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-B89O-SC-.mjs';
|
|
2
|
+
import { g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, a as INTERACTION_TIMED_OUT_ERROR } from './registerKillSessionHandler-BnS3ozFX.mjs';
|
|
3
3
|
|
|
4
4
|
async function runModeLoop(opts) {
|
|
5
5
|
let currentMode = opts.startingMode;
|
|
@@ -18,7 +18,7 @@ import { spawn } from 'node:child_process';
|
|
|
18
18
|
import { Expo } from 'expo-server-sdk';
|
|
19
19
|
|
|
20
20
|
var name = "happy-imou-cloud";
|
|
21
|
-
var version = "2.1.
|
|
21
|
+
var version = "2.1.43";
|
|
22
22
|
var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
|
|
23
23
|
var author = "long.zhu";
|
|
24
24
|
var license = "MIT";
|
|
@@ -1657,12 +1657,29 @@ const UserMessageSchema = z$1.object({
|
|
|
1657
1657
|
// Mobile messages include this
|
|
1658
1658
|
meta: MessageMetaSchema.optional()
|
|
1659
1659
|
});
|
|
1660
|
+
const AgentProviderSchema = z$1.enum(["gemini", "codex", "claude", "opencode"]);
|
|
1660
1661
|
const AgentMessageSchema = z$1.object({
|
|
1661
1662
|
role: z$1.literal("agent"),
|
|
1662
|
-
content: z$1.
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1663
|
+
content: z$1.union([
|
|
1664
|
+
z$1.object({
|
|
1665
|
+
type: z$1.literal("output"),
|
|
1666
|
+
data: z$1.unknown()
|
|
1667
|
+
}),
|
|
1668
|
+
z$1.object({
|
|
1669
|
+
type: z$1.literal("codex"),
|
|
1670
|
+
data: z$1.unknown()
|
|
1671
|
+
}),
|
|
1672
|
+
z$1.object({
|
|
1673
|
+
type: z$1.literal("acp"),
|
|
1674
|
+
provider: AgentProviderSchema,
|
|
1675
|
+
data: z$1.unknown()
|
|
1676
|
+
}),
|
|
1677
|
+
z$1.object({
|
|
1678
|
+
type: z$1.literal("event"),
|
|
1679
|
+
id: z$1.string().optional(),
|
|
1680
|
+
data: z$1.unknown()
|
|
1681
|
+
})
|
|
1682
|
+
]),
|
|
1666
1683
|
meta: MessageMetaSchema.optional()
|
|
1667
1684
|
});
|
|
1668
1685
|
const MessageContentSchema = z$1.union([UserMessageSchema, AgentMessageSchema]);
|
|
@@ -3647,6 +3664,12 @@ async function runShellCommand(opts) {
|
|
|
3647
3664
|
});
|
|
3648
3665
|
}
|
|
3649
3666
|
|
|
3667
|
+
function quoteShellArgument(value) {
|
|
3668
|
+
if (value.length === 0) {
|
|
3669
|
+
return "''";
|
|
3670
|
+
}
|
|
3671
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
3672
|
+
}
|
|
3650
3673
|
function registerCommonHandlers(rpcHandlerManager, workingDirectory) {
|
|
3651
3674
|
rpcHandlerManager.registerHandler("bash", async (data) => {
|
|
3652
3675
|
logger.debug("Shell command request:", data.command);
|
|
@@ -3692,6 +3715,52 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory) {
|
|
|
3692
3715
|
return result;
|
|
3693
3716
|
}
|
|
3694
3717
|
});
|
|
3718
|
+
rpcHandlerManager.registerHandler("ripgrep", async (data) => {
|
|
3719
|
+
logger.debug("Ripgrep request:", data.args);
|
|
3720
|
+
if (data.cwd) {
|
|
3721
|
+
const validation = validatePath(data.cwd, workingDirectory);
|
|
3722
|
+
if (!validation.valid) {
|
|
3723
|
+
return { success: false, error: validation.error };
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
try {
|
|
3727
|
+
const cwd = data.cwd || workingDirectory;
|
|
3728
|
+
const command = ["rg", ...data.args.map(quoteShellArgument)].join(" ");
|
|
3729
|
+
logger.debug("Ripgrep executing...", {
|
|
3730
|
+
cwd,
|
|
3731
|
+
timeout: data.timeout || 3e4,
|
|
3732
|
+
args: data.args
|
|
3733
|
+
});
|
|
3734
|
+
const result = await runShellCommand({
|
|
3735
|
+
command,
|
|
3736
|
+
cwd,
|
|
3737
|
+
timeoutMs: data.timeout || 3e4
|
|
3738
|
+
});
|
|
3739
|
+
logger.debug("Ripgrep finished:", {
|
|
3740
|
+
success: result.success,
|
|
3741
|
+
exitCode: result.exitCode,
|
|
3742
|
+
error: result.error,
|
|
3743
|
+
stdoutLen: result.stdout.length,
|
|
3744
|
+
stderrLen: result.stderr.length
|
|
3745
|
+
});
|
|
3746
|
+
return result;
|
|
3747
|
+
} catch (error) {
|
|
3748
|
+
const result = {
|
|
3749
|
+
success: false,
|
|
3750
|
+
stdout: "",
|
|
3751
|
+
stderr: "",
|
|
3752
|
+
exitCode: 1,
|
|
3753
|
+
error: error instanceof Error ? error.message : "Ripgrep failed"
|
|
3754
|
+
};
|
|
3755
|
+
logger.debug("Ripgrep failed before execution completed:", {
|
|
3756
|
+
cwd: data.cwd || workingDirectory,
|
|
3757
|
+
success: false,
|
|
3758
|
+
exitCode: result.exitCode,
|
|
3759
|
+
error: result.error
|
|
3760
|
+
});
|
|
3761
|
+
return result;
|
|
3762
|
+
}
|
|
3763
|
+
});
|
|
3695
3764
|
rpcHandlerManager.registerHandler("readFile", async (data) => {
|
|
3696
3765
|
logger.debug("Read file request:", data.path);
|
|
3697
3766
|
const validation = validatePath(data.path, workingDirectory);
|
|
@@ -4254,9 +4323,95 @@ function isTransientMessageStreamDelta(body) {
|
|
|
4254
4323
|
return record.type === "message" && record.phase === "delta";
|
|
4255
4324
|
}
|
|
4256
4325
|
|
|
4326
|
+
function deterministicStringify(obj, options = {}) {
|
|
4327
|
+
const {
|
|
4328
|
+
undefinedBehavior = "omit",
|
|
4329
|
+
sortArrays = false,
|
|
4330
|
+
replacer,
|
|
4331
|
+
includeSymbols = false
|
|
4332
|
+
} = options;
|
|
4333
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
4334
|
+
function processValue(value, key) {
|
|
4335
|
+
if (replacer && key !== void 0) {
|
|
4336
|
+
value = replacer(key, value);
|
|
4337
|
+
}
|
|
4338
|
+
if (value === null) return null;
|
|
4339
|
+
if (value === void 0) {
|
|
4340
|
+
switch (undefinedBehavior) {
|
|
4341
|
+
case "omit":
|
|
4342
|
+
return void 0;
|
|
4343
|
+
case "null":
|
|
4344
|
+
return null;
|
|
4345
|
+
case "throw":
|
|
4346
|
+
throw new Error(`Undefined value at key: ${key}`);
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
4349
|
+
if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
4350
|
+
return value;
|
|
4351
|
+
}
|
|
4352
|
+
if (value instanceof Date) {
|
|
4353
|
+
return value.toISOString();
|
|
4354
|
+
}
|
|
4355
|
+
if (value instanceof RegExp) {
|
|
4356
|
+
return value.toString();
|
|
4357
|
+
}
|
|
4358
|
+
if (typeof value === "function") {
|
|
4359
|
+
return void 0;
|
|
4360
|
+
}
|
|
4361
|
+
if (typeof value === "symbol") {
|
|
4362
|
+
return includeSymbols ? value.toString() : void 0;
|
|
4363
|
+
}
|
|
4364
|
+
if (typeof value === "bigint") {
|
|
4365
|
+
return value.toString() + "n";
|
|
4366
|
+
}
|
|
4367
|
+
if (seen.has(value)) {
|
|
4368
|
+
throw new Error("Circular reference detected");
|
|
4369
|
+
}
|
|
4370
|
+
seen.add(value);
|
|
4371
|
+
if (Array.isArray(value)) {
|
|
4372
|
+
const processed2 = value.map((item, index) => processValue(item, String(index))).filter((item) => item !== void 0);
|
|
4373
|
+
if (sortArrays) {
|
|
4374
|
+
processed2.sort((a, b) => {
|
|
4375
|
+
const aStr = JSON.stringify(processValue(a));
|
|
4376
|
+
const bStr = JSON.stringify(processValue(b));
|
|
4377
|
+
return aStr.localeCompare(bStr);
|
|
4378
|
+
});
|
|
4379
|
+
}
|
|
4380
|
+
seen.delete(value);
|
|
4381
|
+
return processed2;
|
|
4382
|
+
}
|
|
4383
|
+
if (value.constructor === Object || value.constructor === void 0) {
|
|
4384
|
+
const processed2 = {};
|
|
4385
|
+
const keys = Object.keys(value).sort();
|
|
4386
|
+
for (const k of keys) {
|
|
4387
|
+
const processedValue = processValue(value[k], k);
|
|
4388
|
+
if (processedValue !== void 0) {
|
|
4389
|
+
processed2[k] = processedValue;
|
|
4390
|
+
}
|
|
4391
|
+
}
|
|
4392
|
+
seen.delete(value);
|
|
4393
|
+
return processed2;
|
|
4394
|
+
}
|
|
4395
|
+
try {
|
|
4396
|
+
const plain = { ...value };
|
|
4397
|
+
seen.delete(value);
|
|
4398
|
+
return processValue(plain, key);
|
|
4399
|
+
} catch {
|
|
4400
|
+
seen.delete(value);
|
|
4401
|
+
return String(value);
|
|
4402
|
+
}
|
|
4403
|
+
}
|
|
4404
|
+
const processed = processValue(obj);
|
|
4405
|
+
return JSON.stringify(processed);
|
|
4406
|
+
}
|
|
4407
|
+
function hashObject(obj, options, encoding = "hex") {
|
|
4408
|
+
const jsonString = deterministicStringify(obj, options);
|
|
4409
|
+
return createHash("sha256").update(jsonString).digest(encoding);
|
|
4410
|
+
}
|
|
4411
|
+
|
|
4257
4412
|
const MAX_PENDING_RELIABLE_SESSION_MESSAGES = 200;
|
|
4258
4413
|
const MAX_PENDING_RELIABLE_SESSION_MESSAGE_BYTES = 512 * 1024;
|
|
4259
|
-
const PROTOCOL_V3_INITIAL_SNAPSHOT_LIMIT =
|
|
4414
|
+
const PROTOCOL_V3_INITIAL_SNAPSHOT_LIMIT = 300;
|
|
4260
4415
|
const PROTOCOL_V3_CHANGES_PAGE_LIMIT = 200;
|
|
4261
4416
|
const PROTOCOL_V3_CAPABILITIES_WAIT_MS = 250;
|
|
4262
4417
|
const COMMITTED_SESSION_WRITE_ACK_TIMEOUT_MS = 5e3;
|
|
@@ -4389,8 +4544,11 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4389
4544
|
agentState;
|
|
4390
4545
|
agentStateVersion;
|
|
4391
4546
|
socket;
|
|
4547
|
+
initialSessionSeq;
|
|
4392
4548
|
pendingMessages = [];
|
|
4393
4549
|
pendingMessageCallback = null;
|
|
4550
|
+
pendingSessionMessages = [];
|
|
4551
|
+
pendingSessionMessageCallback = null;
|
|
4394
4552
|
rpcHandlerManager;
|
|
4395
4553
|
agentStateLock = new AsyncLock();
|
|
4396
4554
|
metadataLock = new AsyncLock();
|
|
@@ -4430,6 +4588,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4430
4588
|
this.agentStateVersion = session.agentStateVersion;
|
|
4431
4589
|
this.encryptionKey = session.encryptionKey;
|
|
4432
4590
|
this.encryptionVariant = session.encryptionVariant;
|
|
4591
|
+
this.initialSessionSeq = session.seq;
|
|
4433
4592
|
this.lastChangeSeq = session.seq;
|
|
4434
4593
|
this.committedSessionWriteAckMode = this.credentials.signing ? "unknown" : "unsupported";
|
|
4435
4594
|
for (const [dispatchId, ack] of Object.entries(session.metadata?.happyOrg?.dispatchAcks ?? {})) {
|
|
@@ -4544,6 +4703,12 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4544
4703
|
callback(this.pendingMessages.shift());
|
|
4545
4704
|
}
|
|
4546
4705
|
}
|
|
4706
|
+
onSessionMessage(callback) {
|
|
4707
|
+
this.pendingSessionMessageCallback = callback;
|
|
4708
|
+
while (this.pendingSessionMessages.length > 0) {
|
|
4709
|
+
callback(this.pendingSessionMessages.shift());
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4547
4712
|
configureProtocolV3Sync(options) {
|
|
4548
4713
|
this.invalidateProtocolV3SessionSync();
|
|
4549
4714
|
this.protocolV3SessionSync = options;
|
|
@@ -4570,6 +4735,13 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4570
4735
|
}
|
|
4571
4736
|
return preserveSessionRuntimeMetadata(this.metadata, next);
|
|
4572
4737
|
}
|
|
4738
|
+
didSessionValueChange(current, next) {
|
|
4739
|
+
try {
|
|
4740
|
+
return deterministicStringify(current ?? null) !== deterministicStringify(next ?? null);
|
|
4741
|
+
} catch {
|
|
4742
|
+
return true;
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4573
4745
|
async waitForMetadataUpdate(signal) {
|
|
4574
4746
|
if (signal?.aborted) {
|
|
4575
4747
|
throw createAbortError();
|
|
@@ -4822,7 +4994,10 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4822
4994
|
updateMetadata(handler) {
|
|
4823
4995
|
this.trackPendingBackgroundTask(this.metadataLock.inLock(async () => {
|
|
4824
4996
|
await backoff(async () => {
|
|
4825
|
-
|
|
4997
|
+
const updated = this.mergeRuntimeMetadata(handler(this.metadata));
|
|
4998
|
+
if (!this.didSessionValueChange(this.metadata, updated)) {
|
|
4999
|
+
return;
|
|
5000
|
+
}
|
|
4826
5001
|
const sessionIndex = buildSessionRuntimeIndex(updated);
|
|
4827
5002
|
const answer = await this.socket.emitWithAck("update-metadata", {
|
|
4828
5003
|
sid: this.sessionId,
|
|
@@ -4868,7 +5043,10 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4868
5043
|
logger.debugLargeJson("Updating agent state", this.agentState);
|
|
4869
5044
|
this.trackPendingBackgroundTask(this.agentStateLock.inLock(async () => {
|
|
4870
5045
|
await backoff(async () => {
|
|
4871
|
-
|
|
5046
|
+
const updated = handler(this.agentState || {});
|
|
5047
|
+
if (!this.didSessionValueChange(this.agentState, updated)) {
|
|
5048
|
+
return;
|
|
5049
|
+
}
|
|
4872
5050
|
const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) : null });
|
|
4873
5051
|
if (answer.result === "success") {
|
|
4874
5052
|
this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
|
|
@@ -4950,7 +5128,10 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4950
5128
|
if (messageSeq !== null && messageSeq <= this.lastChangeSeq) {
|
|
4951
5129
|
return;
|
|
4952
5130
|
}
|
|
4953
|
-
this.dispatchPlaintextSessionMessage(data.body.message.content.p
|
|
5131
|
+
this.dispatchPlaintextSessionMessage(data.body.message.content.p, {
|
|
5132
|
+
source: "live",
|
|
5133
|
+
seq: messageSeq
|
|
5134
|
+
});
|
|
4954
5135
|
if (messageSeq !== null) {
|
|
4955
5136
|
this.lastChangeSeq = Math.max(this.lastChangeSeq, messageSeq);
|
|
4956
5137
|
}
|
|
@@ -4961,7 +5142,10 @@ class ApiSessionClient extends EventEmitter {
|
|
|
4961
5142
|
if (messageSeq !== null && messageSeq <= this.lastChangeSeq) {
|
|
4962
5143
|
return;
|
|
4963
5144
|
}
|
|
4964
|
-
this.dispatchEncryptedSessionMessage(data.body.message.content.c
|
|
5145
|
+
this.dispatchEncryptedSessionMessage(data.body.message.content.c, {
|
|
5146
|
+
source: "live",
|
|
5147
|
+
seq: messageSeq
|
|
5148
|
+
});
|
|
4965
5149
|
if (messageSeq !== null) {
|
|
4966
5150
|
this.lastChangeSeq = Math.max(this.lastChangeSeq, messageSeq);
|
|
4967
5151
|
}
|
|
@@ -5006,18 +5190,25 @@ class ApiSessionClient extends EventEmitter {
|
|
|
5006
5190
|
}
|
|
5007
5191
|
this.emit("message", data.body);
|
|
5008
5192
|
}
|
|
5009
|
-
dispatchEncryptedSessionMessage(encryptedMessage) {
|
|
5193
|
+
dispatchEncryptedSessionMessage(encryptedMessage, options) {
|
|
5010
5194
|
const body = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(encryptedMessage));
|
|
5011
5195
|
logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", body);
|
|
5012
5196
|
const parsedBody = body ?? buildHappyOrgFallbackUserMessage(encryptedMessage);
|
|
5013
|
-
const
|
|
5014
|
-
if (
|
|
5015
|
-
this.
|
|
5016
|
-
if (
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5197
|
+
const messageResult = MessageContentSchema.safeParse(parsedBody);
|
|
5198
|
+
if (messageResult.success) {
|
|
5199
|
+
const queuesPendingInput = this.dispatchSessionTranscriptMessage(messageResult.data, options);
|
|
5200
|
+
if (messageResult.data.role === "user") {
|
|
5201
|
+
if (queuesPendingInput) {
|
|
5202
|
+
this.maybeAutoAcknowledgeHappyOrgDispatch(messageResult.data);
|
|
5203
|
+
if (this.pendingMessageCallback) {
|
|
5204
|
+
this.pendingMessageCallback(messageResult.data);
|
|
5205
|
+
} else {
|
|
5206
|
+
this.pendingMessages.push(messageResult.data);
|
|
5207
|
+
}
|
|
5208
|
+
}
|
|
5209
|
+
return;
|
|
5020
5210
|
}
|
|
5211
|
+
this.emit("message", messageResult.data);
|
|
5021
5212
|
return;
|
|
5022
5213
|
}
|
|
5023
5214
|
this.emit("message", parsedBody);
|
|
@@ -5026,7 +5217,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
5026
5217
|
* Dispatch a plaintext session message (AES mode: server already decrypted).
|
|
5027
5218
|
* The plaintext JSON is parsed and validated as a UserMessage.
|
|
5028
5219
|
*/
|
|
5029
|
-
dispatchPlaintextSessionMessage(plaintextJson) {
|
|
5220
|
+
dispatchPlaintextSessionMessage(plaintextJson, options) {
|
|
5030
5221
|
logger.debug("[SOCKET] [UPDATE] [PLAINTEXT] Received plaintext message");
|
|
5031
5222
|
let parsedBody = null;
|
|
5032
5223
|
try {
|
|
@@ -5035,19 +5226,41 @@ class ApiSessionClient extends EventEmitter {
|
|
|
5035
5226
|
logger.debug("[SOCKET] [UPDATE] [PLAINTEXT] Failed to parse plaintext JSON, ignoring");
|
|
5036
5227
|
return;
|
|
5037
5228
|
}
|
|
5038
|
-
const
|
|
5039
|
-
if (
|
|
5040
|
-
this.
|
|
5041
|
-
if (
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5229
|
+
const messageResult = MessageContentSchema.safeParse(parsedBody);
|
|
5230
|
+
if (messageResult.success) {
|
|
5231
|
+
const queuesPendingInput = this.dispatchSessionTranscriptMessage(messageResult.data, options);
|
|
5232
|
+
if (messageResult.data.role === "user") {
|
|
5233
|
+
if (queuesPendingInput) {
|
|
5234
|
+
this.maybeAutoAcknowledgeHappyOrgDispatch(messageResult.data);
|
|
5235
|
+
if (this.pendingMessageCallback) {
|
|
5236
|
+
this.pendingMessageCallback(messageResult.data);
|
|
5237
|
+
} else {
|
|
5238
|
+
this.pendingMessages.push(messageResult.data);
|
|
5239
|
+
}
|
|
5240
|
+
}
|
|
5241
|
+
return;
|
|
5045
5242
|
}
|
|
5243
|
+
this.emit("message", messageResult.data);
|
|
5046
5244
|
return;
|
|
5047
5245
|
}
|
|
5048
|
-
logger.debug("[SOCKET] [UPDATE] [PLAINTEXT] Message did not match
|
|
5246
|
+
logger.debug("[SOCKET] [UPDATE] [PLAINTEXT] Message did not match MessageContentSchema, emitting generic event");
|
|
5049
5247
|
this.emit("message", parsedBody);
|
|
5050
5248
|
}
|
|
5249
|
+
dispatchSessionTranscriptMessage(message, options) {
|
|
5250
|
+
const queuesPendingInput = message.role === "user" && (options.source === "live" || this.initialSessionSeq === 0);
|
|
5251
|
+
const transcriptMessage = {
|
|
5252
|
+
source: options.source,
|
|
5253
|
+
seq: typeof options.seq === "number" ? options.seq : null,
|
|
5254
|
+
message,
|
|
5255
|
+
queuesPendingInput
|
|
5256
|
+
};
|
|
5257
|
+
if (this.pendingSessionMessageCallback) {
|
|
5258
|
+
this.pendingSessionMessageCallback(transcriptMessage);
|
|
5259
|
+
} else {
|
|
5260
|
+
this.pendingSessionMessages.push(transcriptMessage);
|
|
5261
|
+
}
|
|
5262
|
+
return queuesPendingInput;
|
|
5263
|
+
}
|
|
5051
5264
|
maybeAutoAcknowledgeHappyOrgDispatch(message) {
|
|
5052
5265
|
const candidate = this.resolveHappyOrgDispatchBusinessAckCandidate(message);
|
|
5053
5266
|
if (!candidate) {
|
|
@@ -5352,7 +5565,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
5352
5565
|
sessionId: this.sessionId,
|
|
5353
5566
|
lastChangeSeq: this.lastChangeSeq
|
|
5354
5567
|
});
|
|
5355
|
-
if (!this.initialProtocolV3SnapshotComplete &&
|
|
5568
|
+
if (!this.initialProtocolV3SnapshotComplete && (!this.protocolV3Descriptor || this.supportsKnownProtocolCapability("session_snapshot_v3"))) {
|
|
5356
5569
|
const snapshot = await this.protocolV3SessionSync.getSessionSnapshot(
|
|
5357
5570
|
this.sessionId,
|
|
5358
5571
|
this.protocolV3SessionSync.snapshotLimit ?? PROTOCOL_V3_INITIAL_SNAPSHOT_LIMIT
|
|
@@ -5409,13 +5622,16 @@ class ApiSessionClient extends EventEmitter {
|
|
|
5409
5622
|
applyProtocolV3Snapshot(snapshot) {
|
|
5410
5623
|
this.applyProtocolV3SessionOverlay(snapshot.session);
|
|
5411
5624
|
for (const message of snapshot.snapshot.messages) {
|
|
5412
|
-
if (message.seq <= this.lastChangeSeq) {
|
|
5413
|
-
continue;
|
|
5414
|
-
}
|
|
5415
5625
|
if (message.content.t === "plaintext") {
|
|
5416
|
-
this.dispatchPlaintextSessionMessage(message.content.p
|
|
5626
|
+
this.dispatchPlaintextSessionMessage(message.content.p, {
|
|
5627
|
+
source: "snapshot",
|
|
5628
|
+
seq: message.seq
|
|
5629
|
+
});
|
|
5417
5630
|
} else if (message.content.t === "encrypted") {
|
|
5418
|
-
this.dispatchEncryptedSessionMessage(message.content.c
|
|
5631
|
+
this.dispatchEncryptedSessionMessage(message.content.c, {
|
|
5632
|
+
source: "snapshot",
|
|
5633
|
+
seq: message.seq
|
|
5634
|
+
});
|
|
5419
5635
|
}
|
|
5420
5636
|
this.lastChangeSeq = Math.max(this.lastChangeSeq, message.seq);
|
|
5421
5637
|
}
|
|
@@ -5444,11 +5660,18 @@ class ApiSessionClient extends EventEmitter {
|
|
|
5444
5660
|
case "message.created": {
|
|
5445
5661
|
const message = payload.message;
|
|
5446
5662
|
if (message && typeof message === "object") {
|
|
5663
|
+
const messageSeq = typeof message.seq === "number" ? message.seq : null;
|
|
5447
5664
|
const content = message.content;
|
|
5448
5665
|
if (content && typeof content === "object" && content.t === "plaintext" && typeof content.p === "string") {
|
|
5449
|
-
this.dispatchPlaintextSessionMessage(content.p
|
|
5666
|
+
this.dispatchPlaintextSessionMessage(content.p, {
|
|
5667
|
+
source: "live",
|
|
5668
|
+
seq: messageSeq ?? change.changeSeq
|
|
5669
|
+
});
|
|
5450
5670
|
} else if (content && typeof content === "object" && content.t === "encrypted" && typeof content.c === "string") {
|
|
5451
|
-
this.dispatchEncryptedSessionMessage(content.c
|
|
5671
|
+
this.dispatchEncryptedSessionMessage(content.c, {
|
|
5672
|
+
source: "live",
|
|
5673
|
+
seq: messageSeq ?? change.changeSeq
|
|
5674
|
+
});
|
|
5452
5675
|
}
|
|
5453
5676
|
}
|
|
5454
5677
|
break;
|
|
@@ -5869,12 +6092,12 @@ class ApiMachineClient {
|
|
|
5869
6092
|
requestShutdown
|
|
5870
6093
|
}) {
|
|
5871
6094
|
this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
|
|
5872
|
-
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, environmentVariables } = params || {};
|
|
6095
|
+
const { directory, sessionId, machineId, managedSessionTag, approvedNewDirectoryCreation, agent, token, resume, environmentVariables } = params || {};
|
|
5873
6096
|
logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
|
|
5874
6097
|
if (!directory) {
|
|
5875
6098
|
throw new Error("Directory is required");
|
|
5876
6099
|
}
|
|
5877
|
-
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, environmentVariables });
|
|
6100
|
+
const result = await spawnSession({ directory, sessionId, machineId, managedSessionTag, approvedNewDirectoryCreation, agent, token, resume, environmentVariables });
|
|
5878
6101
|
switch (result.type) {
|
|
5879
6102
|
case "success":
|
|
5880
6103
|
logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
|
|
@@ -7050,4 +7273,4 @@ var api = /*#__PURE__*/Object.freeze({
|
|
|
7050
7273
|
ApiClient: ApiClient
|
|
7051
7274
|
});
|
|
7052
7275
|
|
|
7053
|
-
export { ApiClient as A,
|
|
7276
|
+
export { ApiClient as A, writeCredentialsDataKey as B, readDaemonState as C, HAPPY_CLOUD_DAEMON_PORT as D, clearDaemonState as E, packageJson as F, acquireDaemonLock as G, HeadTailPreviewBuffer as H, writeDaemonState as I, releaseDaemonLock as J, validateProfileForAgent as K, getProfileEnvironmentVariables as L, clearCredentials as M, clearMachineId as N, readHappyOrgDispatchTruthSnapshot as O, processHappyOrgRepoRequests as P, readHappyOrgRepoTaskBoard as Q, HappyOrgTurnReportSchema as R, recordHappyOrgTurnReport as S, MessageContentSchema as T, buildSocketAuth as U, encrypt as V, getLatestDaemonLog as W, persistence as X, api as Y, ApiSessionClient as a, connectionState as b, configuration as c, AssistantMessageStream as d, HAPPY_ORG_REPLY_ACK_VERSION as e, HAPPY_ORG_TURN_REPORT_TAG as f, HAPPY_ORG_SUMMARY_MAX_LENGTH as g, hashObject as h, isAuthenticationRequiredError as i, HAPPY_ORG_REPEAT_THRESHOLD as j, backoff as k, logger as l, delay as m, normalizePreviewableArtifactTarget as n, AsyncLock as o, preserveSessionRuntimeMetadata as p, encodeBase64 as q, readSettings as r, startOfflineReconnection as s, readCredentials as t, ensureSigningCredentials as u, updateSettings as v, encodeBase64Url as w, buildClientHeaders as x, decodeBase64 as y, writeCredentialsLegacy as z };
|