@openacp/cli 2026.330.2 → 2026.331.1
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/README.md +17 -0
- package/dist/adapter-ELG3VRZ3.js +14 -0
- package/dist/{agent-catalog-SZQQERV7.js → agent-catalog-UYD26QDK.js} +3 -3
- package/dist/{api-client-XTLRRFPX.js → api-client-PEMHYL5U.js} +2 -2
- package/dist/{api-server-JLBDKCU4.js → api-server-DATG2KBR.js} +3 -3
- package/dist/api-server-L5Z7XACW.js +7 -0
- package/dist/chunk-23SRIVG4.js +50 -0
- package/dist/chunk-23SRIVG4.js.map +1 -0
- package/dist/{chunk-YIGBJFJL.js → chunk-7GXEMMEV.js} +15 -15
- package/dist/{chunk-QWVHCTCA.js → chunk-7U6IZIJP.js} +37 -23
- package/dist/chunk-7U6IZIJP.js.map +1 -0
- package/dist/{chunk-FCTC7KDT.js → chunk-7YIKTRSM.js} +14 -10
- package/dist/chunk-7YIKTRSM.js.map +1 -0
- package/dist/{chunk-MITTQMGZ.js → chunk-BYCJQPMN.js} +5 -5
- package/dist/chunk-BYCJQPMN.js.map +1 -0
- package/dist/{chunk-5ZNBNIK3.js → chunk-EWVXSTQK.js} +193 -53
- package/dist/chunk-EWVXSTQK.js.map +1 -0
- package/dist/{chunk-UWH7KIAA.js → chunk-FPKQYCQS.js} +88 -13
- package/dist/chunk-FPKQYCQS.js.map +1 -0
- package/dist/{chunk-GEOXPGCO.js → chunk-K6UY5M75.js} +12 -9
- package/dist/chunk-K6UY5M75.js.map +1 -0
- package/dist/{chunk-KDU3ZEWT.js → chunk-KGAQW6F4.js} +12 -3
- package/dist/chunk-KGAQW6F4.js.map +1 -0
- package/dist/{chunk-7RKPIM3E.js → chunk-LRV56K2M.js} +205 -16
- package/dist/chunk-LRV56K2M.js.map +1 -0
- package/dist/{chunk-V2YZWYXT.js → chunk-MDJHCCFS.js} +18 -17
- package/dist/chunk-MDJHCCFS.js.map +1 -0
- package/dist/chunk-NHD5XDD2.js +686 -0
- package/dist/chunk-NHD5XDD2.js.map +1 -0
- package/dist/{chunk-APS6UEFU.js → chunk-NJX75BLK.js} +1 -1
- package/dist/chunk-NJX75BLK.js.map +1 -0
- package/dist/{chunk-5HKQCYOI.js → chunk-NOEAJNTK.js} +14 -3
- package/dist/chunk-NOEAJNTK.js.map +1 -0
- package/dist/chunk-ON7HB5O7.js +58 -0
- package/dist/chunk-ON7HB5O7.js.map +1 -0
- package/dist/{chunk-5OCGO27U.js → chunk-OSBZXY2W.js} +2 -1
- package/dist/chunk-OSBZXY2W.js.map +1 -0
- package/dist/{chunk-PA6MNBG4.js → chunk-P3HHJANC.js} +32 -13
- package/dist/chunk-P3HHJANC.js.map +1 -0
- package/dist/{chunk-BTJHGSLM.js → chunk-R2YLDQLI.js} +9 -10
- package/dist/chunk-R2YLDQLI.js.map +1 -0
- package/dist/{chunk-CFUJGWOP.js → chunk-SSLVNCEA.js} +27 -3
- package/dist/chunk-SSLVNCEA.js.map +1 -0
- package/dist/{chunk-MPGEHTGE.js → chunk-TGP34LQN.js} +9 -7
- package/dist/chunk-TGP34LQN.js.map +1 -0
- package/dist/{chunk-TMVTSWVH.js → chunk-VUSCVRJL.js} +2 -1
- package/dist/chunk-VUSCVRJL.js.map +1 -0
- package/dist/chunk-XRJUS6FE.js +53 -0
- package/dist/chunk-XRJUS6FE.js.map +1 -0
- package/dist/{chunk-W4LK6WJP.js → chunk-YZCKSNRN.js} +24 -17
- package/dist/chunk-YZCKSNRN.js.map +1 -0
- package/dist/{chunk-3NAFXVQM.js → chunk-ZIRH6QWW.js} +7 -5
- package/dist/chunk-ZIRH6QWW.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +334 -140
- package/dist/cli.js.map +1 -1
- package/dist/config-X4UP7H6R.js +13 -0
- package/dist/config-editor-7BENRVG5.js +11 -0
- package/dist/{config-registry-ZXAIJNYB.js → config-registry-M3FFWEVM.js} +3 -2
- package/dist/context-FVGCU5TI.js +9 -0
- package/dist/core-plugins-JSY2I44L.js +25 -0
- package/dist/{daemon-XFEMMJSZ.js → daemon-UOSRDEXW.js} +8 -3
- package/dist/doctor-6DLACBR4.js +10 -0
- package/dist/{file-service-HHB3JQIO.js → file-service-FQQYME7M.js} +2 -2
- package/dist/index.d.ts +265 -32
- package/dist/index.js +44 -33
- package/dist/index.js.map +1 -1
- package/dist/{install-cloudflared-JRJ4BSOM.js → install-cloudflared-LNS5L5FR.js} +5 -4
- package/dist/install-cloudflared-LNS5L5FR.js.map +1 -0
- package/dist/{install-context-EHYV5WRY.js → install-context-KZO5FR4D.js} +4 -3
- package/dist/install-context-KZO5FR4D.js.map +1 -0
- package/dist/{install-jq-ISTGT263.js → install-jq-SN4IA5K4.js} +3 -3
- package/dist/instance-context-FLCE7VZ4.js +13 -0
- package/dist/instance-registry-SW5FWKHO.js +7 -0
- package/dist/{main-L2M4NTJY.js → main-D7M2AKRM.js} +91 -48
- package/dist/main-D7M2AKRM.js.map +1 -0
- package/dist/{plugin-create-EHL76ZZG.js → plugin-create-HFKS23JY.js} +4 -2
- package/dist/{plugin-create-EHL76ZZG.js.map → plugin-create-HFKS23JY.js.map} +1 -1
- package/dist/{post-upgrade-Y26S2ZQ7.js → post-upgrade-F4YPMTUT.js} +6 -6
- package/dist/{security-2BA265LN.js → security-O4XGN2CM.js} +2 -2
- package/dist/{setup-E6BNEYCS.js → setup-44WLBIOT.js} +209 -22
- package/dist/setup-44WLBIOT.js.map +1 -0
- package/dist/{speech-SG62JYIF.js → speech-GHTSWDAN.js} +2 -2
- package/dist/telegram-D7ASLVEB.js +7 -0
- package/dist/telegram-D7ASLVEB.js.map +1 -0
- package/dist/tunnel-ALJDPFDQ.js +10 -0
- package/dist/tunnel-ALJDPFDQ.js.map +1 -0
- package/dist/{tunnel-service-ZMO4THKE.js → tunnel-service-TBAHDXMF.js} +41 -547
- package/dist/tunnel-service-TBAHDXMF.js.map +1 -0
- package/package.json +1 -1
- package/dist/adapter-4U6MC5ZS.js +0 -13
- package/dist/api-server-5VNYFWJE.js +0 -7
- package/dist/chunk-3NAFXVQM.js.map +0 -1
- package/dist/chunk-4WXALZA3.js +0 -45
- package/dist/chunk-4WXALZA3.js.map +0 -1
- package/dist/chunk-5HKQCYOI.js.map +0 -1
- package/dist/chunk-5OCGO27U.js.map +0 -1
- package/dist/chunk-5ZNBNIK3.js.map +0 -1
- package/dist/chunk-7RKPIM3E.js.map +0 -1
- package/dist/chunk-APS6UEFU.js.map +0 -1
- package/dist/chunk-BTJHGSLM.js.map +0 -1
- package/dist/chunk-CFUJGWOP.js.map +0 -1
- package/dist/chunk-FCTC7KDT.js.map +0 -1
- package/dist/chunk-GEOXPGCO.js.map +0 -1
- package/dist/chunk-KDU3ZEWT.js.map +0 -1
- package/dist/chunk-MITTQMGZ.js.map +0 -1
- package/dist/chunk-MPGEHTGE.js.map +0 -1
- package/dist/chunk-PA6MNBG4.js.map +0 -1
- package/dist/chunk-QWVHCTCA.js.map +0 -1
- package/dist/chunk-TMVTSWVH.js.map +0 -1
- package/dist/chunk-UWH7KIAA.js.map +0 -1
- package/dist/chunk-V2YZWYXT.js.map +0 -1
- package/dist/chunk-W4LK6WJP.js.map +0 -1
- package/dist/config-KN6NKKPF.js +0 -20
- package/dist/config-editor-76RVZS4B.js +0 -10
- package/dist/context-NXXW62NJ.js +0 -9
- package/dist/core-plugins-OCHKGCIZ.js +0 -22
- package/dist/doctor-AV6AUO22.js +0 -9
- package/dist/install-cloudflared-JRJ4BSOM.js.map +0 -1
- package/dist/install-context-EHYV5WRY.js.map +0 -1
- package/dist/main-L2M4NTJY.js.map +0 -1
- package/dist/setup-E6BNEYCS.js.map +0 -1
- package/dist/telegram-EAVRDNFU.js +0 -7
- package/dist/tunnel-HWJ27WDH.js +0 -7
- package/dist/tunnel-service-ZMO4THKE.js.map +0 -1
- /package/dist/{adapter-4U6MC5ZS.js.map → adapter-ELG3VRZ3.js.map} +0 -0
- /package/dist/{agent-catalog-SZQQERV7.js.map → agent-catalog-UYD26QDK.js.map} +0 -0
- /package/dist/{api-client-XTLRRFPX.js.map → api-client-PEMHYL5U.js.map} +0 -0
- /package/dist/{api-server-5VNYFWJE.js.map → api-server-DATG2KBR.js.map} +0 -0
- /package/dist/{api-server-JLBDKCU4.js.map → api-server-L5Z7XACW.js.map} +0 -0
- /package/dist/{chunk-YIGBJFJL.js.map → chunk-7GXEMMEV.js.map} +0 -0
- /package/dist/{config-KN6NKKPF.js.map → config-X4UP7H6R.js.map} +0 -0
- /package/dist/{config-editor-76RVZS4B.js.map → config-editor-7BENRVG5.js.map} +0 -0
- /package/dist/{config-registry-ZXAIJNYB.js.map → config-registry-M3FFWEVM.js.map} +0 -0
- /package/dist/{context-NXXW62NJ.js.map → context-FVGCU5TI.js.map} +0 -0
- /package/dist/{core-plugins-OCHKGCIZ.js.map → core-plugins-JSY2I44L.js.map} +0 -0
- /package/dist/{daemon-XFEMMJSZ.js.map → daemon-UOSRDEXW.js.map} +0 -0
- /package/dist/{doctor-AV6AUO22.js.map → doctor-6DLACBR4.js.map} +0 -0
- /package/dist/{file-service-HHB3JQIO.js.map → file-service-FQQYME7M.js.map} +0 -0
- /package/dist/{install-jq-ISTGT263.js.map → install-jq-SN4IA5K4.js.map} +0 -0
- /package/dist/{security-2BA265LN.js.map → instance-context-FLCE7VZ4.js.map} +0 -0
- /package/dist/{speech-SG62JYIF.js.map → instance-registry-SW5FWKHO.js.map} +0 -0
- /package/dist/{post-upgrade-Y26S2ZQ7.js.map → post-upgrade-F4YPMTUT.js.map} +0 -0
- /package/dist/{telegram-EAVRDNFU.js.map → security-O4XGN2CM.js.map} +0 -0
- /package/dist/{tunnel-HWJ27WDH.js.map → speech-GHTSWDAN.js.map} +0 -0
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentCatalog
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import {
|
|
5
|
-
getAgentCapabilities
|
|
6
|
-
} from "./chunk-ZSLHHQPQ.js";
|
|
3
|
+
} from "./chunk-MDJHCCFS.js";
|
|
7
4
|
import {
|
|
8
5
|
readTextFileWithRange
|
|
9
6
|
} from "./chunk-OYSAN7UX.js";
|
|
@@ -12,6 +9,9 @@ import {
|
|
|
12
9
|
createChildLogger,
|
|
13
10
|
createSessionLogger
|
|
14
11
|
} from "./chunk-R6KZYF7D.js";
|
|
12
|
+
import {
|
|
13
|
+
getAgentCapabilities
|
|
14
|
+
} from "./chunk-ZSLHHQPQ.js";
|
|
15
15
|
|
|
16
16
|
// src/core/utils/streams.ts
|
|
17
17
|
function nodeToWebWritable(nodeStream) {
|
|
@@ -1084,6 +1084,8 @@ var Session = class extends TypedEmitter {
|
|
|
1084
1084
|
agentCapabilities;
|
|
1085
1085
|
archiving = false;
|
|
1086
1086
|
promptCount = 0;
|
|
1087
|
+
firstAgent;
|
|
1088
|
+
agentSwitchHistory = [];
|
|
1087
1089
|
log;
|
|
1088
1090
|
middlewareChain;
|
|
1089
1091
|
permissionGate = new PermissionGate();
|
|
@@ -1095,6 +1097,7 @@ var Session = class extends TypedEmitter {
|
|
|
1095
1097
|
this.id = opts.id || nanoid(12);
|
|
1096
1098
|
this.channelId = opts.channelId;
|
|
1097
1099
|
this.agentName = opts.agentName;
|
|
1100
|
+
this.firstAgent = opts.agentName;
|
|
1098
1101
|
this.workingDirectory = opts.workingDirectory;
|
|
1099
1102
|
this.agentInstance = opts.agentInstance;
|
|
1100
1103
|
this.speechService = opts.speechService;
|
|
@@ -1176,6 +1179,7 @@ var Session = class extends TypedEmitter {
|
|
|
1176
1179
|
}
|
|
1177
1180
|
if (this._status === "finished") return;
|
|
1178
1181
|
this.promptCount++;
|
|
1182
|
+
this.emit("prompt_count_changed", this.promptCount);
|
|
1179
1183
|
if (this._status === "initializing" || this._status === "cancelled" || this._status === "error") {
|
|
1180
1184
|
this.activate();
|
|
1181
1185
|
}
|
|
@@ -1422,6 +1426,44 @@ ${result.text}` : result.text;
|
|
|
1422
1426
|
this.log.info("Prompt aborted");
|
|
1423
1427
|
await this.agentInstance.cancel();
|
|
1424
1428
|
}
|
|
1429
|
+
/** Search backward through agentSwitchHistory for the last entry matching agentName */
|
|
1430
|
+
findLastSwitchEntry(agentName) {
|
|
1431
|
+
for (let i = this.agentSwitchHistory.length - 1; i >= 0; i--) {
|
|
1432
|
+
if (this.agentSwitchHistory[i].agentName === agentName) {
|
|
1433
|
+
return this.agentSwitchHistory[i];
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
return void 0;
|
|
1437
|
+
}
|
|
1438
|
+
/** Switch the agent instance in-place, preserving session identity */
|
|
1439
|
+
async switchAgent(agentName, createAgent) {
|
|
1440
|
+
if (agentName === this.agentName) {
|
|
1441
|
+
throw new Error(`Already using ${agentName}`);
|
|
1442
|
+
}
|
|
1443
|
+
this.agentSwitchHistory.push({
|
|
1444
|
+
agentName: this.agentName,
|
|
1445
|
+
agentSessionId: this.agentSessionId,
|
|
1446
|
+
switchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1447
|
+
promptCount: this.promptCount
|
|
1448
|
+
});
|
|
1449
|
+
this.queue.clear();
|
|
1450
|
+
if (this.permissionGate.isPending) {
|
|
1451
|
+
this.permissionGate.reject("Agent switched");
|
|
1452
|
+
}
|
|
1453
|
+
await this.agentInstance.destroy();
|
|
1454
|
+
const newAgent = await createAgent();
|
|
1455
|
+
this.agentInstance = newAgent;
|
|
1456
|
+
this.agentName = agentName;
|
|
1457
|
+
this.agentSessionId = newAgent.sessionId;
|
|
1458
|
+
this.promptCount = 0;
|
|
1459
|
+
this.agentCapabilities = void 0;
|
|
1460
|
+
this.currentMode = void 0;
|
|
1461
|
+
this.availableModes = [];
|
|
1462
|
+
this.currentModel = void 0;
|
|
1463
|
+
this.availableModels = [];
|
|
1464
|
+
this.configOptions = [];
|
|
1465
|
+
this.log.info({ from: this.agentSwitchHistory.at(-1).agentName, to: agentName }, "Agent switched");
|
|
1466
|
+
}
|
|
1425
1467
|
async destroy() {
|
|
1426
1468
|
this.log.info("Session destroyed");
|
|
1427
1469
|
if (this.permissionGate.isPending) {
|
|
@@ -1609,6 +1651,7 @@ var SessionBridge = class {
|
|
|
1609
1651
|
sessionEventHandler;
|
|
1610
1652
|
statusChangeHandler;
|
|
1611
1653
|
namedHandler;
|
|
1654
|
+
promptCountHandler;
|
|
1612
1655
|
get tracer() {
|
|
1613
1656
|
return this.session.agentInstance.debugTracer ?? null;
|
|
1614
1657
|
}
|
|
@@ -1657,6 +1700,9 @@ var SessionBridge = class {
|
|
|
1657
1700
|
if (this.namedHandler) {
|
|
1658
1701
|
this.session.off("named", this.namedHandler);
|
|
1659
1702
|
}
|
|
1703
|
+
if (this.promptCountHandler) {
|
|
1704
|
+
this.session.off("prompt_count_changed", this.promptCountHandler);
|
|
1705
|
+
}
|
|
1660
1706
|
this.session.agentInstance.onPermissionRequest = async () => "";
|
|
1661
1707
|
}
|
|
1662
1708
|
wireAgentToSession() {
|
|
@@ -1941,6 +1987,10 @@ var SessionBridge = class {
|
|
|
1941
1987
|
this.adapter.renameSessionThread(this.session.id, name);
|
|
1942
1988
|
};
|
|
1943
1989
|
this.session.on("named", this.namedHandler);
|
|
1990
|
+
this.promptCountHandler = (count) => {
|
|
1991
|
+
this.deps.sessionManager.patchRecord(this.session.id, { currentPromptCount: count });
|
|
1992
|
+
};
|
|
1993
|
+
this.session.on("prompt_count_changed", this.promptCountHandler);
|
|
1944
1994
|
}
|
|
1945
1995
|
};
|
|
1946
1996
|
|
|
@@ -2422,8 +2472,8 @@ var EventBus = class extends TypedEmitter {
|
|
|
2422
2472
|
};
|
|
2423
2473
|
|
|
2424
2474
|
// src/core/core.ts
|
|
2425
|
-
import
|
|
2426
|
-
import
|
|
2475
|
+
import path6 from "path";
|
|
2476
|
+
import os2 from "os";
|
|
2427
2477
|
|
|
2428
2478
|
// src/core/sessions/session-store.ts
|
|
2429
2479
|
import fs4 from "fs";
|
|
@@ -2467,9 +2517,15 @@ var JsonFileSessionStore = class {
|
|
|
2467
2517
|
return void 0;
|
|
2468
2518
|
}
|
|
2469
2519
|
findByAgentSessionId(agentSessionId) {
|
|
2470
|
-
|
|
2471
|
-
(
|
|
2472
|
-
|
|
2520
|
+
for (const record of this.records.values()) {
|
|
2521
|
+
if (record.agentSessionId === agentSessionId || record.originalAgentSessionId === agentSessionId) {
|
|
2522
|
+
return record;
|
|
2523
|
+
}
|
|
2524
|
+
if (record.agentSwitchHistory?.some((e) => e.agentSessionId === agentSessionId)) {
|
|
2525
|
+
return record;
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
return void 0;
|
|
2473
2529
|
}
|
|
2474
2530
|
list(channelId) {
|
|
2475
2531
|
const all = [...this.records.values()];
|
|
@@ -2796,6 +2852,10 @@ var ErrorTracker = class {
|
|
|
2796
2852
|
}
|
|
2797
2853
|
};
|
|
2798
2854
|
|
|
2855
|
+
// src/core/plugin/plugin-context.ts
|
|
2856
|
+
import path5 from "path";
|
|
2857
|
+
import os from "os";
|
|
2858
|
+
|
|
2799
2859
|
// src/core/plugin/plugin-storage.ts
|
|
2800
2860
|
import fs5 from "fs";
|
|
2801
2861
|
import path4 from "path";
|
|
@@ -2867,6 +2927,7 @@ function createPluginContext(opts) {
|
|
|
2867
2927
|
config,
|
|
2868
2928
|
core
|
|
2869
2929
|
} = opts;
|
|
2930
|
+
const instanceRoot = opts.instanceRoot ?? path5.join(os.homedir(), ".openacp");
|
|
2870
2931
|
const registeredListeners = [];
|
|
2871
2932
|
const registeredCommands = [];
|
|
2872
2933
|
const noopLog = {
|
|
@@ -2975,6 +3036,7 @@ function createPluginContext(opts) {
|
|
|
2975
3036
|
requirePermission(permissions, "kernel:access", "core");
|
|
2976
3037
|
return core;
|
|
2977
3038
|
},
|
|
3039
|
+
instanceRoot,
|
|
2978
3040
|
cleanup() {
|
|
2979
3041
|
for (const { event, handler } of registeredListeners) {
|
|
2980
3042
|
eventBus.off(event, handler);
|
|
@@ -3049,6 +3111,7 @@ var LifecycleManager = class {
|
|
|
3049
3111
|
log;
|
|
3050
3112
|
settingsManager;
|
|
3051
3113
|
pluginRegistry;
|
|
3114
|
+
instanceRoot;
|
|
3052
3115
|
contexts = /* @__PURE__ */ new Map();
|
|
3053
3116
|
loadOrder = [];
|
|
3054
3117
|
_loaded = /* @__PURE__ */ new Set();
|
|
@@ -3081,6 +3144,7 @@ var LifecycleManager = class {
|
|
|
3081
3144
|
this.log = opts?.log;
|
|
3082
3145
|
this.settingsManager = opts?.settingsManager;
|
|
3083
3146
|
this.pluginRegistry = opts?.pluginRegistry;
|
|
3147
|
+
this.instanceRoot = opts?.instanceRoot;
|
|
3084
3148
|
}
|
|
3085
3149
|
getPluginLogger(pluginName) {
|
|
3086
3150
|
if (this.log && typeof this.log.child === "function") {
|
|
@@ -3190,7 +3254,8 @@ var LifecycleManager = class {
|
|
|
3190
3254
|
sessions: this.sessions,
|
|
3191
3255
|
config: this.config,
|
|
3192
3256
|
core: this.core,
|
|
3193
|
-
log: this.log
|
|
3257
|
+
log: this.log,
|
|
3258
|
+
instanceRoot: this.instanceRoot
|
|
3194
3259
|
});
|
|
3195
3260
|
try {
|
|
3196
3261
|
await withTimeout(plugin.setup(ctx), SETUP_TIMEOUT_MS, `${plugin.name}.setup()`);
|
|
@@ -3255,14 +3320,18 @@ var OpenACPCore = class {
|
|
|
3255
3320
|
sessionManager;
|
|
3256
3321
|
messageTransformer;
|
|
3257
3322
|
adapters = /* @__PURE__ */ new Map();
|
|
3323
|
+
/** sessionId → SessionBridge — tracks active bridges for disconnect/reconnect during agent switch */
|
|
3324
|
+
bridges = /* @__PURE__ */ new Map();
|
|
3258
3325
|
/** Set by main.ts — triggers graceful shutdown with restart exit code */
|
|
3259
3326
|
requestRestart = null;
|
|
3260
3327
|
_tunnelService;
|
|
3261
3328
|
sessionStore = null;
|
|
3262
3329
|
resumeLocks = /* @__PURE__ */ new Map();
|
|
3330
|
+
switchingLocks = /* @__PURE__ */ new Set();
|
|
3263
3331
|
eventBus;
|
|
3264
3332
|
sessionFactory;
|
|
3265
3333
|
lifecycleManager;
|
|
3334
|
+
instanceContext;
|
|
3266
3335
|
// --- Lazy getters: resolve from ServiceRegistry (populated by plugins during boot) ---
|
|
3267
3336
|
getService(name) {
|
|
3268
3337
|
const svc = this.lifecycleManager.serviceRegistry.get(name);
|
|
@@ -3284,13 +3353,14 @@ var OpenACPCore = class {
|
|
|
3284
3353
|
get contextManager() {
|
|
3285
3354
|
return this.getService("context");
|
|
3286
3355
|
}
|
|
3287
|
-
constructor(configManager) {
|
|
3356
|
+
constructor(configManager, ctx) {
|
|
3288
3357
|
this.configManager = configManager;
|
|
3358
|
+
this.instanceContext = ctx;
|
|
3289
3359
|
const config = configManager.get();
|
|
3290
3360
|
this.agentCatalog = new AgentCatalog();
|
|
3291
3361
|
this.agentCatalog.load();
|
|
3292
3362
|
this.agentManager = new AgentManager(this.agentCatalog);
|
|
3293
|
-
const storePath =
|
|
3363
|
+
const storePath = ctx?.paths.sessions ?? path6.join(os2.homedir(), ".openacp", "sessions.json");
|
|
3294
3364
|
this.sessionStore = new JsonFileSessionStore(
|
|
3295
3365
|
storePath,
|
|
3296
3366
|
config.sessionStore.ttlDays
|
|
@@ -3313,7 +3383,7 @@ var OpenACPCore = class {
|
|
|
3313
3383
|
sessions: this.sessionManager,
|
|
3314
3384
|
config: this.configManager,
|
|
3315
3385
|
core: this,
|
|
3316
|
-
storagePath:
|
|
3386
|
+
storagePath: ctx?.paths.pluginsData ?? path6.join(os2.homedir(), ".openacp", "plugins", "data"),
|
|
3317
3387
|
log: createChildLogger({ module: "plugin" })
|
|
3318
3388
|
});
|
|
3319
3389
|
this.sessionFactory.middlewareChain = this.lifecycleManager.middlewareChain;
|
|
@@ -3502,7 +3572,10 @@ var OpenACPCore = class {
|
|
|
3502
3572
|
createdAt: session.createdAt.toISOString(),
|
|
3503
3573
|
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3504
3574
|
name: session.name,
|
|
3505
|
-
platform
|
|
3575
|
+
platform,
|
|
3576
|
+
firstAgent: session.firstAgent,
|
|
3577
|
+
currentPromptCount: session.promptCount,
|
|
3578
|
+
agentSwitchHistory: session.agentSwitchHistory
|
|
3506
3579
|
});
|
|
3507
3580
|
log6.info(
|
|
3508
3581
|
{ sessionId: session.id, agentName: params.agentName },
|
|
@@ -3675,6 +3748,117 @@ var OpenACPCore = class {
|
|
|
3675
3748
|
}
|
|
3676
3749
|
return { session, contextResult };
|
|
3677
3750
|
}
|
|
3751
|
+
// --- Agent Switch ---
|
|
3752
|
+
async switchSessionAgent(sessionId, toAgent) {
|
|
3753
|
+
if (this.switchingLocks.has(sessionId)) {
|
|
3754
|
+
throw new Error("Switch already in progress");
|
|
3755
|
+
}
|
|
3756
|
+
this.switchingLocks.add(sessionId);
|
|
3757
|
+
try {
|
|
3758
|
+
return await this._doSwitchSessionAgent(sessionId, toAgent);
|
|
3759
|
+
} finally {
|
|
3760
|
+
this.switchingLocks.delete(sessionId);
|
|
3761
|
+
}
|
|
3762
|
+
}
|
|
3763
|
+
async _doSwitchSessionAgent(sessionId, toAgent) {
|
|
3764
|
+
const session = this.sessionManager.getSession(sessionId);
|
|
3765
|
+
if (!session) throw new Error(`Session ${sessionId} not found`);
|
|
3766
|
+
const agentDef = this.agentManager.getAgent(toAgent);
|
|
3767
|
+
if (!agentDef) throw new Error(`Agent "${toAgent}" is not installed`);
|
|
3768
|
+
const fromAgent = session.agentName;
|
|
3769
|
+
const middlewareChain = this.lifecycleManager.middlewareChain;
|
|
3770
|
+
const result = await middlewareChain.execute("agent:beforeSwitch", {
|
|
3771
|
+
sessionId,
|
|
3772
|
+
fromAgent,
|
|
3773
|
+
toAgent
|
|
3774
|
+
}, async (payload) => payload);
|
|
3775
|
+
if (!result) throw new Error("Agent switch blocked by middleware");
|
|
3776
|
+
const lastEntry = session.findLastSwitchEntry(toAgent);
|
|
3777
|
+
const caps = getAgentCapabilities(toAgent);
|
|
3778
|
+
const canResume = !!(lastEntry && caps.supportsResume && lastEntry.promptCount === 0);
|
|
3779
|
+
const resumed = canResume;
|
|
3780
|
+
const bridge = this.bridges.get(sessionId);
|
|
3781
|
+
if (bridge) bridge.disconnect();
|
|
3782
|
+
const switchAdapter = this.adapters.get(session.channelId);
|
|
3783
|
+
if (switchAdapter?.sendSkillCommands) {
|
|
3784
|
+
await switchAdapter.sendSkillCommands(session.id, []);
|
|
3785
|
+
}
|
|
3786
|
+
if (switchAdapter?.cleanupSessionState) {
|
|
3787
|
+
await switchAdapter.cleanupSessionState(session.id);
|
|
3788
|
+
}
|
|
3789
|
+
const fromAgentSessionId = session.agentSessionId;
|
|
3790
|
+
try {
|
|
3791
|
+
await session.switchAgent(toAgent, async () => {
|
|
3792
|
+
if (canResume) {
|
|
3793
|
+
return this.agentManager.resume(toAgent, session.workingDirectory, lastEntry.agentSessionId);
|
|
3794
|
+
} else {
|
|
3795
|
+
const instance = await this.agentManager.spawn(toAgent, session.workingDirectory);
|
|
3796
|
+
try {
|
|
3797
|
+
const contextService = this.lifecycleManager.serviceRegistry.get("context");
|
|
3798
|
+
if (contextService) {
|
|
3799
|
+
const config = this.configManager.get();
|
|
3800
|
+
const labelAgent = config.agentSwitch?.labelHistory ?? true;
|
|
3801
|
+
const contextResult = await contextService.buildContext(
|
|
3802
|
+
{ type: "session", value: sessionId, repoPath: session.workingDirectory },
|
|
3803
|
+
{ labelAgent }
|
|
3804
|
+
);
|
|
3805
|
+
if (contextResult?.markdown) {
|
|
3806
|
+
session.setContext(contextResult.markdown);
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
} catch {
|
|
3810
|
+
}
|
|
3811
|
+
return instance;
|
|
3812
|
+
}
|
|
3813
|
+
});
|
|
3814
|
+
} catch (err) {
|
|
3815
|
+
try {
|
|
3816
|
+
let rollbackInstance;
|
|
3817
|
+
try {
|
|
3818
|
+
rollbackInstance = await this.agentManager.resume(fromAgent, session.workingDirectory, fromAgentSessionId);
|
|
3819
|
+
} catch {
|
|
3820
|
+
rollbackInstance = await this.agentManager.spawn(fromAgent, session.workingDirectory);
|
|
3821
|
+
}
|
|
3822
|
+
const oldInstance = rollbackInstance;
|
|
3823
|
+
session.agentSwitchHistory.pop();
|
|
3824
|
+
session.agentInstance = oldInstance;
|
|
3825
|
+
session.agentName = fromAgent;
|
|
3826
|
+
session.agentSessionId = oldInstance.sessionId;
|
|
3827
|
+
const adapter = this.adapters.get(session.channelId);
|
|
3828
|
+
if (adapter) {
|
|
3829
|
+
const rollbackBridge = this.createBridge(session, adapter);
|
|
3830
|
+
rollbackBridge.connect();
|
|
3831
|
+
}
|
|
3832
|
+
log6.warn({ sessionId, fromAgent, toAgent, err }, "Agent switch failed, rolled back to previous agent");
|
|
3833
|
+
} catch (rollbackErr) {
|
|
3834
|
+
session.fail(`Switch failed and rollback failed: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);
|
|
3835
|
+
log6.error({ sessionId, fromAgent, toAgent, err, rollbackErr }, "Agent switch failed and rollback also failed");
|
|
3836
|
+
}
|
|
3837
|
+
throw err;
|
|
3838
|
+
}
|
|
3839
|
+
if (bridge) {
|
|
3840
|
+
const adapter = this.adapters.get(session.channelId);
|
|
3841
|
+
if (adapter) {
|
|
3842
|
+
const newBridge = this.createBridge(session, adapter);
|
|
3843
|
+
newBridge.connect();
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
await this.sessionManager.patchRecord(sessionId, {
|
|
3847
|
+
agentName: toAgent,
|
|
3848
|
+
agentSessionId: session.agentSessionId,
|
|
3849
|
+
firstAgent: session.firstAgent,
|
|
3850
|
+
currentPromptCount: 0,
|
|
3851
|
+
agentSwitchHistory: session.agentSwitchHistory
|
|
3852
|
+
});
|
|
3853
|
+
middlewareChain.execute("agent:afterSwitch", {
|
|
3854
|
+
sessionId,
|
|
3855
|
+
fromAgent,
|
|
3856
|
+
toAgent,
|
|
3857
|
+
resumed
|
|
3858
|
+
}, async (p) => p).catch(() => {
|
|
3859
|
+
});
|
|
3860
|
+
return { resumed };
|
|
3861
|
+
}
|
|
3678
3862
|
// --- Lazy Resume ---
|
|
3679
3863
|
/**
|
|
3680
3864
|
* Get active session by thread, or attempt lazy resume from store.
|
|
@@ -3734,6 +3918,9 @@ var OpenACPCore = class {
|
|
|
3734
3918
|
});
|
|
3735
3919
|
session.activate();
|
|
3736
3920
|
session.dangerousMode = record.dangerousMode ?? false;
|
|
3921
|
+
if (record.firstAgent) session.firstAgent = record.firstAgent;
|
|
3922
|
+
if (record.agentSwitchHistory) session.agentSwitchHistory = record.agentSwitchHistory;
|
|
3923
|
+
if (record.currentPromptCount != null) session.promptCount = record.currentPromptCount;
|
|
3737
3924
|
log6.info(
|
|
3738
3925
|
{ sessionId: session.id, threadId: message.threadId },
|
|
3739
3926
|
"Lazy resume successful"
|
|
@@ -3762,7 +3949,7 @@ var OpenACPCore = class {
|
|
|
3762
3949
|
// --- Event Wiring ---
|
|
3763
3950
|
/** Create a SessionBridge for the given session and adapter */
|
|
3764
3951
|
createBridge(session, adapter) {
|
|
3765
|
-
|
|
3952
|
+
const bridge = new SessionBridge(session, adapter, {
|
|
3766
3953
|
messageTransformer: this.messageTransformer,
|
|
3767
3954
|
notificationManager: this.notificationManager,
|
|
3768
3955
|
sessionManager: this.sessionManager,
|
|
@@ -3770,6 +3957,8 @@ var OpenACPCore = class {
|
|
|
3770
3957
|
fileService: this.fileService,
|
|
3771
3958
|
middlewareChain: this.lifecycleManager?.middlewareChain
|
|
3772
3959
|
});
|
|
3960
|
+
this.bridges.set(session.id, bridge);
|
|
3961
|
+
return bridge;
|
|
3773
3962
|
}
|
|
3774
3963
|
};
|
|
3775
3964
|
|
|
@@ -3914,4 +4103,4 @@ export {
|
|
|
3914
4103
|
OpenACPCore,
|
|
3915
4104
|
CommandRegistry
|
|
3916
4105
|
};
|
|
3917
|
-
//# sourceMappingURL=chunk-
|
|
4106
|
+
//# sourceMappingURL=chunk-LRV56K2M.js.map
|