acpx 0.16.0 → 0.17.0
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 +2 -0
- package/dist/{cli-BkYIxj_N.js → cli-CiyfEC7L.js} +5 -4
- package/dist/{cli-BkYIxj_N.js.map → cli-CiyfEC7L.js.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +33 -26
- package/dist/cli.js.map +1 -1
- package/dist/{client-5levcBIs.d.ts → client-C6NUFqr-.d.ts} +12 -6
- package/dist/client-C6NUFqr-.d.ts.map +1 -0
- package/dist/{flows-Bxs4udrs.js → flows-CTOdIk-m.js} +6 -5
- package/dist/{flows-Bxs4udrs.js.map → flows-CTOdIk-m.js.map} +1 -1
- package/dist/flows.d.ts +2 -2
- package/dist/flows.js +1 -1
- package/dist/{invocation-options-BY4lxkn3.js → invocation-options-DbCcOAzM.js} +4 -3
- package/dist/{invocation-options-BY4lxkn3.js.map → invocation-options-DbCcOAzM.js.map} +1 -1
- package/dist/ipc-D3akHMEq.js +3350 -0
- package/dist/ipc-D3akHMEq.js.map +1 -0
- package/dist/output-BPPjvJTI.js +980 -0
- package/dist/output-BPPjvJTI.js.map +1 -0
- package/dist/{live-checkpoint-BEfxBKCh.js → queue-owner-runtime--IbbndGz.js} +3052 -1852
- package/dist/queue-owner-runtime--IbbndGz.js.map +1 -0
- package/dist/runtime.d.ts +99 -12
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +308 -69
- package/dist/runtime.js.map +1 -1
- package/dist/{session-options-t3d-F4dn.d.ts → session-options-Dp6mzNSy.d.ts} +2 -2
- package/dist/{session-options-t3d-F4dn.d.ts.map → session-options-Dp6mzNSy.d.ts.map} +1 -1
- package/dist/session-watch--UX5dh00.js +76 -0
- package/dist/session-watch--UX5dh00.js.map +1 -0
- package/dist/watch-BbBxO-kb.js +32 -0
- package/dist/watch-BbBxO-kb.js.map +1 -0
- package/package.json +1 -1
- package/skills/acpx/SKILL.md +5 -2
- package/dist/client-5levcBIs.d.ts.map +0 -1
- package/dist/live-checkpoint-BEfxBKCh.js.map +0 -1
- package/dist/output-uo5a27KB.js +0 -4711
- package/dist/output-uo5a27KB.js.map +0 -1
package/dist/runtime.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as textPrompt, D as findSession, F as resolveSessionRecord, L as assertPersistedKeyPolicy, P as readSessionRecord, R as parseSessionRecord, gt as extractAcpError, mt as writePrivateJsonFile, t as tryCancelOnRunningOwner, vt as isAcpResourceNotFoundError, z as serializeSessionRecordForDisk } from "./ipc-D3akHMEq.js";
|
|
2
|
+
import { A as setDesiredModeId, B as recordClientOperation, C as withConnectedSession, D as applyInitialModelSelection, E as applyConfigOptionsToRecord, F as createInitialSessionRecord, G as AcpClient, H as recordSessionUpdate, I as reconcileAgentSessionId, J as RequestedModelUnsupportedError, K as REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE, L as cloneSessionAcpxState, M as sessionOptionsFromRecord, N as applyConversation, O as applyModelSelection, P as applyLifecycleSnapshotToRecord, R as cloneSessionConversation, T as applyConfigOptionSelection, U as trimConversationForRuntime, V as recordPromptSubmission, W as advertisedModelState, Y as isRequestedModelUnsupportedError, _ as cancelSessionPrompt, c as LiveSessionCheckpoint, ct as normalizeOutputError, h as ensureSession, it as assertControlAuthority, j as persistSessionOptions, k as applyRequestedModelIfAdvertised, l as runPromptTurn, ot as withTimeout, q as REQUESTED_MODEL_UNSUPPORTED_REASONS, r as sendSession, s as DISCARD_OUTPUT_FORMATTER, v as closeSession, w as connectAndLoadSession } from "./queue-owner-runtime--IbbndGz.js";
|
|
2
3
|
import { D as normalizeAgentCommandInput, a as createAgentRegistry, i as DEFAULT_AGENT_NAME } from "./agent-registry-DU6mhZBL.js";
|
|
4
|
+
import { t as watchSession } from "./watch-BbBxO-kb.js";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
3
6
|
import path from "node:path";
|
|
4
7
|
import fs from "node:fs/promises";
|
|
5
8
|
import { randomUUID } from "node:crypto";
|
|
@@ -733,7 +736,7 @@ function commandRecord(value) {
|
|
|
733
736
|
return value;
|
|
734
737
|
}
|
|
735
738
|
//#endregion
|
|
736
|
-
//#region src/runtime/engine/
|
|
739
|
+
//#region src/runtime/engine/turn.ts
|
|
737
740
|
function createDeferred() {
|
|
738
741
|
let resolve;
|
|
739
742
|
let reject;
|
|
@@ -746,22 +749,6 @@ function createDeferred() {
|
|
|
746
749
|
reject
|
|
747
750
|
};
|
|
748
751
|
}
|
|
749
|
-
async function settleAttempt(run) {
|
|
750
|
-
try {
|
|
751
|
-
return {
|
|
752
|
-
ok: true,
|
|
753
|
-
value: await run()
|
|
754
|
-
};
|
|
755
|
-
} catch (error) {
|
|
756
|
-
return {
|
|
757
|
-
ok: false,
|
|
758
|
-
error
|
|
759
|
-
};
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
function firstFailedAttempt(attempts) {
|
|
763
|
-
return attempts.find((attempt) => !attempt.ok);
|
|
764
|
-
}
|
|
765
752
|
var AsyncEventQueue = class {
|
|
766
753
|
items = [];
|
|
767
754
|
waits = [];
|
|
@@ -798,17 +785,6 @@ var AsyncEventQueue = class {
|
|
|
798
785
|
}
|
|
799
786
|
}
|
|
800
787
|
};
|
|
801
|
-
function isoNow() {
|
|
802
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
803
|
-
}
|
|
804
|
-
function isUnsupportedSessionCloseError(error) {
|
|
805
|
-
const acp = extractAcpError(error);
|
|
806
|
-
if (!acp) return false;
|
|
807
|
-
if (acp.code === -32601 || acp.code === -32602) return true;
|
|
808
|
-
if (acp.code !== -32603 || !acp.data || typeof acp.data !== "object") return false;
|
|
809
|
-
const details = acp.data.details;
|
|
810
|
-
return typeof details === "string" && details.toLowerCase().includes("invalid params");
|
|
811
|
-
}
|
|
812
788
|
function toPromptInput(text, attachments) {
|
|
813
789
|
if (!attachments || attachments.length === 0) return text;
|
|
814
790
|
const blocks = [];
|
|
@@ -837,13 +813,6 @@ function toPromptInput(text, attachments) {
|
|
|
837
813
|
}
|
|
838
814
|
return blocks.length > 0 ? blocks : textPrompt(text);
|
|
839
815
|
}
|
|
840
|
-
function createRecordId(sessionKey, mode) {
|
|
841
|
-
if (mode === "persistent") return sessionKey;
|
|
842
|
-
return `${sessionKey}:oneshot:${randomUUID()}`;
|
|
843
|
-
}
|
|
844
|
-
function resumePolicyForSessionMode(mode) {
|
|
845
|
-
return mode === "persistent" ? "same-session-only" : "allow-new";
|
|
846
|
-
}
|
|
847
816
|
function legacyTerminalEventFromTurnResult(result) {
|
|
848
817
|
if (result.status === "failed") return {
|
|
849
818
|
type: "error",
|
|
@@ -858,6 +827,42 @@ function legacyTerminalEventFromTurnResult(result) {
|
|
|
858
827
|
...result._meta === void 0 ? {} : { _meta: result._meta }
|
|
859
828
|
};
|
|
860
829
|
}
|
|
830
|
+
//#endregion
|
|
831
|
+
//#region src/runtime/engine/manager.ts
|
|
832
|
+
async function settleAttempt(run) {
|
|
833
|
+
try {
|
|
834
|
+
return {
|
|
835
|
+
ok: true,
|
|
836
|
+
value: await run()
|
|
837
|
+
};
|
|
838
|
+
} catch (error) {
|
|
839
|
+
return {
|
|
840
|
+
ok: false,
|
|
841
|
+
error
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
function firstFailedAttempt(attempts) {
|
|
846
|
+
return attempts.find((attempt) => !attempt.ok);
|
|
847
|
+
}
|
|
848
|
+
function isoNow() {
|
|
849
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
850
|
+
}
|
|
851
|
+
function isUnsupportedSessionCloseError(error) {
|
|
852
|
+
const acp = extractAcpError(error);
|
|
853
|
+
if (!acp) return false;
|
|
854
|
+
if (acp.code === -32601 || acp.code === -32602) return true;
|
|
855
|
+
if (acp.code !== -32603 || !acp.data || typeof acp.data !== "object") return false;
|
|
856
|
+
const details = acp.data.details;
|
|
857
|
+
return typeof details === "string" && details.toLowerCase().includes("invalid params");
|
|
858
|
+
}
|
|
859
|
+
function createRecordId(sessionKey, mode) {
|
|
860
|
+
if (mode === "persistent") return sessionKey;
|
|
861
|
+
return `${sessionKey}:oneshot:${randomUUID()}`;
|
|
862
|
+
}
|
|
863
|
+
function resumePolicyForSessionMode(mode) {
|
|
864
|
+
return mode === "persistent" ? "same-session-only" : "allow-new";
|
|
865
|
+
}
|
|
861
866
|
function advertisedConfigOptionIds(record) {
|
|
862
867
|
const configOptions = record.acpx?.config_options;
|
|
863
868
|
if (!configOptions) return;
|
|
@@ -1179,9 +1184,11 @@ var AcpRuntimeManager = class {
|
|
|
1179
1184
|
agentArgv: agentArgv ? [...agentArgv] : void 0
|
|
1180
1185
|
}) : servers ?? []];
|
|
1181
1186
|
}
|
|
1182
|
-
async withRuntimeControlSession(record, sessionMode, run, replacingConfigOption) {
|
|
1187
|
+
async withRuntimeControlSession(record, sessionMode, run, replacingConfigOption, authority) {
|
|
1183
1188
|
await this.retrySessionCleanup(record.acpxRecordId);
|
|
1189
|
+
assertControlAuthority(authority);
|
|
1184
1190
|
const owner = await this.readRetainedSessionOwner(record, { consume: false });
|
|
1191
|
+
assertControlAuthority(authority);
|
|
1185
1192
|
if (owner) {
|
|
1186
1193
|
const ownedRecord = owner.projection?.record ?? record;
|
|
1187
1194
|
try {
|
|
@@ -1226,6 +1233,7 @@ var AcpRuntimeManager = class {
|
|
|
1226
1233
|
timeoutMs: this.options.timeoutMs,
|
|
1227
1234
|
resumePolicy: resumePolicyForSessionMode(sessionMode),
|
|
1228
1235
|
replacingConfigOption,
|
|
1236
|
+
authority,
|
|
1229
1237
|
run
|
|
1230
1238
|
});
|
|
1231
1239
|
return {
|
|
@@ -1251,8 +1259,9 @@ var AcpRuntimeManager = class {
|
|
|
1251
1259
|
const key = `${input.mode}\0${input.sessionKey}`;
|
|
1252
1260
|
return await this.withManagerLock(this.ensureSessionLocks, key, run);
|
|
1253
1261
|
}
|
|
1254
|
-
async withManagerLock(locks, key, run) {
|
|
1262
|
+
async withManagerLock(locks, key, run, authority) {
|
|
1255
1263
|
this.assertOpen();
|
|
1264
|
+
assertControlAuthority(authority);
|
|
1256
1265
|
const previous = locks.get(key) ?? Promise.resolve();
|
|
1257
1266
|
let release;
|
|
1258
1267
|
const gate = new Promise((resolve) => {
|
|
@@ -1263,6 +1272,7 @@ var AcpRuntimeManager = class {
|
|
|
1263
1272
|
await previous;
|
|
1264
1273
|
try {
|
|
1265
1274
|
this.assertOpen();
|
|
1275
|
+
assertControlAuthority(authority);
|
|
1266
1276
|
return await run();
|
|
1267
1277
|
} finally {
|
|
1268
1278
|
release();
|
|
@@ -1685,24 +1695,24 @@ var AcpRuntimeManager = class {
|
|
|
1685
1695
|
return {
|
|
1686
1696
|
hasActivePrompt: () => turn.client.hasActivePrompt(),
|
|
1687
1697
|
requestCancelActivePrompt: async () => await this.requestRuntimeTurnCancel(task, turn),
|
|
1688
|
-
setSessionMode: async (modeId) => {
|
|
1698
|
+
setSessionMode: async (modeId, authority) => {
|
|
1689
1699
|
await this.waitForRuntimeControlSession(task, turn);
|
|
1690
|
-
await turn.client.setSessionMode(turn.activeSessionId, modeId);
|
|
1700
|
+
await turn.client.setSessionMode(turn.activeSessionId, modeId, authority);
|
|
1691
1701
|
const nextState = cloneSessionAcpxState(turn.acpxState) ?? {};
|
|
1692
1702
|
nextState.desired_mode_id = modeId;
|
|
1693
1703
|
turn.acpxState = nextState;
|
|
1694
1704
|
},
|
|
1695
|
-
setSessionModel: async (modelId) => {
|
|
1705
|
+
setSessionModel: async (modelId, authority) => {
|
|
1696
1706
|
await this.waitForRuntimeControlSession(task, turn);
|
|
1697
1707
|
const models = advertisedModelState(turn.acpxState);
|
|
1698
|
-
const response = await turn.client.setSessionModel(turn.activeSessionId, modelId, models);
|
|
1708
|
+
const response = await turn.client.setSessionModel(turn.activeSessionId, modelId, models, authority);
|
|
1699
1709
|
turn.acpxState = applyModelSelection(turn.acpxState, modelId, response);
|
|
1700
1710
|
return response;
|
|
1701
1711
|
},
|
|
1702
|
-
setSessionConfigOption: async (configId, value) => {
|
|
1703
|
-
return (await task.state.activeController.setResolvedSessionConfigOption(configId, value)).response;
|
|
1712
|
+
setSessionConfigOption: async (configId, value, authority) => {
|
|
1713
|
+
return (await task.state.activeController.setResolvedSessionConfigOption(configId, value, authority)).response;
|
|
1704
1714
|
},
|
|
1705
|
-
setResolvedSessionConfigOption: async (configId, value) => await this.setRuntimeResolvedSessionConfigOption(task, turn, configId, value)
|
|
1715
|
+
setResolvedSessionConfigOption: async (configId, value, authority) => await this.setRuntimeResolvedSessionConfigOption(task, turn, configId, value, authority)
|
|
1706
1716
|
};
|
|
1707
1717
|
}
|
|
1708
1718
|
async waitForRuntimeControlSession(task, turn) {
|
|
@@ -1715,14 +1725,14 @@ var AcpRuntimeManager = class {
|
|
|
1715
1725
|
task.state.pendingCancel = true;
|
|
1716
1726
|
return true;
|
|
1717
1727
|
}
|
|
1718
|
-
async setRuntimeResolvedSessionConfigOption(task, turn, configId, value) {
|
|
1728
|
+
async setRuntimeResolvedSessionConfigOption(task, turn, configId, value, authority) {
|
|
1719
1729
|
await this.waitForRuntimeControlSession(task, turn);
|
|
1720
1730
|
const resolvedConfigId = resolveSupportedConfigOptionId({
|
|
1721
1731
|
...turn.record,
|
|
1722
1732
|
acpx: turn.acpxState ?? void 0
|
|
1723
1733
|
}, configId);
|
|
1724
1734
|
const modelConfigId = advertisedModelState(turn.acpxState)?.configId;
|
|
1725
|
-
const response = await turn.client.setSessionConfigOption(turn.activeSessionId, resolvedConfigId, value);
|
|
1735
|
+
const response = await turn.client.setSessionConfigOption(turn.activeSessionId, resolvedConfigId, value, authority);
|
|
1726
1736
|
turn.acpxState = applyConfigOptionSelection(turn.acpxState, resolvedConfigId, value, response, modelConfigId);
|
|
1727
1737
|
return {
|
|
1728
1738
|
configId: resolvedConfigId,
|
|
@@ -1879,49 +1889,52 @@ var AcpRuntimeManager = class {
|
|
|
1879
1889
|
if (owner) await this.flushSessionOwner(owner);
|
|
1880
1890
|
return runtimeStatusFromRecord(await this.requireRecord(recordId));
|
|
1881
1891
|
}
|
|
1882
|
-
async setMode(handle, mode, sessionMode = "persistent") {
|
|
1892
|
+
async setMode(handle, mode, sessionMode = "persistent", authority) {
|
|
1883
1893
|
const recordId = handle.acpxRecordId ?? handle.sessionKey;
|
|
1884
|
-
await this.withManagerLock(this.runtimeOperationLocks, recordId, async () => this.setModeWithOwnership(handle, mode, sessionMode));
|
|
1894
|
+
await this.withManagerLock(this.runtimeOperationLocks, recordId, async () => this.setModeWithOwnership(handle, mode, sessionMode, authority), authority);
|
|
1885
1895
|
}
|
|
1886
|
-
async setModeWithOwnership(handle, mode, sessionMode) {
|
|
1896
|
+
async setModeWithOwnership(handle, mode, sessionMode, authority) {
|
|
1887
1897
|
const record = await this.requireRecord(handle.acpxRecordId ?? handle.sessionKey);
|
|
1898
|
+
assertControlAuthority(authority);
|
|
1888
1899
|
const controller = this.activeControllers.get(record.acpxRecordId);
|
|
1889
1900
|
let targetRecord = record;
|
|
1890
|
-
if (controller) await controller.setSessionMode(mode);
|
|
1901
|
+
if (controller) await controller.setSessionMode(mode, authority);
|
|
1891
1902
|
else targetRecord = (await this.withRuntimeControlSession(record, sessionMode, async ({ client, sessionId }) => {
|
|
1892
|
-
await client.setSessionMode(sessionId, mode);
|
|
1893
|
-
})).record;
|
|
1903
|
+
await client.setSessionMode(sessionId, mode, authority);
|
|
1904
|
+
}, void 0, authority)).record;
|
|
1894
1905
|
setDesiredModeId(targetRecord, mode);
|
|
1895
1906
|
await this.options.sessionStore.save(targetRecord);
|
|
1896
1907
|
}
|
|
1897
|
-
async setModel(handle, model, sessionMode = "persistent") {
|
|
1908
|
+
async setModel(handle, model, sessionMode = "persistent", authority) {
|
|
1898
1909
|
const recordId = handle.acpxRecordId ?? handle.sessionKey;
|
|
1899
|
-
await this.withManagerLock(this.runtimeOperationLocks, recordId, async () => this.setModelWithOwnership(handle, model, sessionMode));
|
|
1910
|
+
await this.withManagerLock(this.runtimeOperationLocks, recordId, async () => this.setModelWithOwnership(handle, model, sessionMode, authority), authority);
|
|
1900
1911
|
}
|
|
1901
|
-
async setModelWithOwnership(handle, model, sessionMode) {
|
|
1912
|
+
async setModelWithOwnership(handle, model, sessionMode, authority) {
|
|
1902
1913
|
const record = await this.requireRecord(handle.acpxRecordId ?? handle.sessionKey);
|
|
1914
|
+
assertControlAuthority(authority);
|
|
1903
1915
|
const controller = this.activeControllers.get(record.acpxRecordId);
|
|
1904
1916
|
if (controller) {
|
|
1905
|
-
const response = await controller.setSessionModel(model);
|
|
1917
|
+
const response = await controller.setSessionModel(model, authority);
|
|
1906
1918
|
record.acpx = applyModelSelection(record.acpx, model, response);
|
|
1907
1919
|
await this.options.sessionStore.save(record);
|
|
1908
1920
|
return;
|
|
1909
1921
|
}
|
|
1910
1922
|
const result = await this.withRuntimeControlSession(record, sessionMode, async ({ client, sessionId, record: connectedRecord }) => {
|
|
1911
|
-
const response = await client.setSessionModel(sessionId, model, advertisedModelState(connectedRecord.acpx));
|
|
1923
|
+
const response = await client.setSessionModel(sessionId, model, advertisedModelState(connectedRecord.acpx), authority);
|
|
1912
1924
|
connectedRecord.acpx = applyModelSelection(connectedRecord.acpx, model, response);
|
|
1913
|
-
}, { key: "model" });
|
|
1925
|
+
}, { key: "model" }, authority);
|
|
1914
1926
|
await this.options.sessionStore.save(result.record);
|
|
1915
1927
|
}
|
|
1916
|
-
async setConfigOption(handle, key, value, sessionMode = "persistent") {
|
|
1928
|
+
async setConfigOption(handle, key, value, sessionMode = "persistent", authority) {
|
|
1917
1929
|
const recordId = handle.acpxRecordId ?? handle.sessionKey;
|
|
1918
|
-
return await this.withManagerLock(this.runtimeOperationLocks, recordId, async () => this.setConfigOptionWithOwnership(handle, key, value, sessionMode));
|
|
1930
|
+
return await this.withManagerLock(this.runtimeOperationLocks, recordId, async () => this.setConfigOptionWithOwnership(handle, key, value, sessionMode, authority), authority);
|
|
1919
1931
|
}
|
|
1920
|
-
async setConfigOptionWithOwnership(handle, key, value, sessionMode) {
|
|
1932
|
+
async setConfigOptionWithOwnership(handle, key, value, sessionMode, authority) {
|
|
1921
1933
|
const record = await this.requireRecord(handle.acpxRecordId ?? handle.sessionKey);
|
|
1934
|
+
assertControlAuthority(authority);
|
|
1922
1935
|
const controller = this.activeControllers.get(record.acpxRecordId);
|
|
1923
1936
|
if (controller) {
|
|
1924
|
-
const { configId, response } = await controller.setResolvedSessionConfigOption(key, value);
|
|
1937
|
+
const { configId, response } = await controller.setResolvedSessionConfigOption(key, value, authority);
|
|
1925
1938
|
record.acpx = applyConfigOptionSelection(record.acpx, configId, value, response);
|
|
1926
1939
|
await this.options.sessionStore.save(record);
|
|
1927
1940
|
return response;
|
|
@@ -1929,13 +1942,13 @@ var AcpRuntimeManager = class {
|
|
|
1929
1942
|
const result = await this.withRuntimeControlSession(record, sessionMode, async ({ client, sessionId, record: connectedRecord }) => {
|
|
1930
1943
|
const configId = resolveSupportedConfigOptionId(connectedRecord, key);
|
|
1931
1944
|
const modelConfigId = advertisedModelState(connectedRecord.acpx)?.configId;
|
|
1932
|
-
const response = await client.setSessionConfigOption(sessionId, configId, value);
|
|
1945
|
+
const response = await client.setSessionConfigOption(sessionId, configId, value, authority);
|
|
1933
1946
|
connectedRecord.acpx = applyConfigOptionSelection(connectedRecord.acpx, configId, value, response, modelConfigId);
|
|
1934
1947
|
return response;
|
|
1935
1948
|
}, {
|
|
1936
1949
|
key,
|
|
1937
1950
|
resolve: (connectedRecord) => resolveSupportedConfigOptionId(connectedRecord, key)
|
|
1938
|
-
});
|
|
1951
|
+
}, authority);
|
|
1939
1952
|
await this.options.sessionStore.save(result.record);
|
|
1940
1953
|
return result.value;
|
|
1941
1954
|
}
|
|
@@ -2125,6 +2138,232 @@ function writeHandleState(handle, state) {
|
|
|
2125
2138
|
handle.agentSessionId = state.agentSessionId;
|
|
2126
2139
|
}
|
|
2127
2140
|
//#endregion
|
|
2141
|
+
//#region src/runtime/shared.ts
|
|
2142
|
+
const SHARED_BACKEND = "acpx-shared";
|
|
2143
|
+
function invalidOption(message) {
|
|
2144
|
+
throw new AcpRuntimeError("ACP_INVALID_RUNTIME_OPTION", message);
|
|
2145
|
+
}
|
|
2146
|
+
function sharedHandle(record) {
|
|
2147
|
+
return {
|
|
2148
|
+
backend: SHARED_BACKEND,
|
|
2149
|
+
sessionKey: record.name ?? "",
|
|
2150
|
+
runtimeSessionName: record.acpxRecordId,
|
|
2151
|
+
acpxRecordId: record.acpxRecordId,
|
|
2152
|
+
backendSessionId: record.acpSessionId,
|
|
2153
|
+
agentSessionId: record.agentSessionId,
|
|
2154
|
+
cwd: record.cwd
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
2157
|
+
function sharedRecordId(handle) {
|
|
2158
|
+
if (handle.backend !== SHARED_BACKEND || !handle.acpxRecordId) return invalidOption("A shared runtime requires a handle from a shared session.");
|
|
2159
|
+
return handle.acpxRecordId;
|
|
2160
|
+
}
|
|
2161
|
+
function turnFailure(error) {
|
|
2162
|
+
const normalized = normalizeOutputError(error, {
|
|
2163
|
+
defaultCode: "RUNTIME",
|
|
2164
|
+
origin: "queue"
|
|
2165
|
+
});
|
|
2166
|
+
if (normalized.detailCode === "QUEUE_REQUEST_CANCELLED") return {
|
|
2167
|
+
status: "cancelled",
|
|
2168
|
+
stopReason: "cancelled"
|
|
2169
|
+
};
|
|
2170
|
+
return {
|
|
2171
|
+
status: "failed",
|
|
2172
|
+
error: {
|
|
2173
|
+
message: normalized.message,
|
|
2174
|
+
code: normalized.code,
|
|
2175
|
+
detailCode: normalized.detailCode,
|
|
2176
|
+
retryable: normalized.retryable
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
2179
|
+
}
|
|
2180
|
+
/** A client of the CLI's local session owner. Shutdown detaches this client. */
|
|
2181
|
+
var SharedAcpRuntime = class {
|
|
2182
|
+
registry;
|
|
2183
|
+
options;
|
|
2184
|
+
disconnect = new AbortController();
|
|
2185
|
+
pending = /* @__PURE__ */ new Set();
|
|
2186
|
+
constructor(options) {
|
|
2187
|
+
for (const name of [
|
|
2188
|
+
"sessionStore",
|
|
2189
|
+
"agentProcessEnv",
|
|
2190
|
+
"mcpServers",
|
|
2191
|
+
"processLifecycle",
|
|
2192
|
+
"onPermissionRequest",
|
|
2193
|
+
"elicitationModes"
|
|
2194
|
+
]) if (Object.hasOwn(options, name)) invalidOption(`${name} belongs to the in-process runtime and is not supported by shared sessions.`);
|
|
2195
|
+
this.options = {
|
|
2196
|
+
...options,
|
|
2197
|
+
cwd: path.resolve(options.cwd),
|
|
2198
|
+
authCredentials: options.authCredentials ? { ...options.authCredentials } : void 0
|
|
2199
|
+
};
|
|
2200
|
+
this.registry = options.agentRegistry ?? createAgentRegistry();
|
|
2201
|
+
}
|
|
2202
|
+
assertOpen() {
|
|
2203
|
+
if (this.disconnect.signal.aborted) throw new AcpRuntimeError("ACP_BACKEND_UNAVAILABLE", "Shared ACP runtime is shut down.");
|
|
2204
|
+
}
|
|
2205
|
+
track(task) {
|
|
2206
|
+
this.pending.add(task);
|
|
2207
|
+
task.then(() => this.pending.delete(task), () => this.pending.delete(task));
|
|
2208
|
+
return task;
|
|
2209
|
+
}
|
|
2210
|
+
sessionOptions(input) {
|
|
2211
|
+
if (!input.agent.trim()) invalidOption("ACP agent id is required.");
|
|
2212
|
+
return {
|
|
2213
|
+
...normalizeAgentCommandInput(this.registry.resolve(input.agent)),
|
|
2214
|
+
cwd: path.resolve(input.cwd ?? this.options.cwd),
|
|
2215
|
+
name: input.sessionKey.trim() || void 0
|
|
2216
|
+
};
|
|
2217
|
+
}
|
|
2218
|
+
async findSession(input) {
|
|
2219
|
+
this.assertOpen();
|
|
2220
|
+
const record = await findSession(this.sessionOptions(input));
|
|
2221
|
+
return record ? sharedHandle(record) : void 0;
|
|
2222
|
+
}
|
|
2223
|
+
ensureSession(input) {
|
|
2224
|
+
this.assertOpen();
|
|
2225
|
+
if (input.mode !== "persistent") invalidOption("Shared sessions require persistent mode; use the in-process runtime for oneshot sessions.");
|
|
2226
|
+
const session = this.sessionOptions(input);
|
|
2227
|
+
return this.track(ensureSession({
|
|
2228
|
+
...this.options,
|
|
2229
|
+
...session,
|
|
2230
|
+
walkBoundary: session.cwd,
|
|
2231
|
+
sessionOptions: input.sessionOptions,
|
|
2232
|
+
resumeSessionId: input.resumeSessionId,
|
|
2233
|
+
handleProcessInterrupts: false,
|
|
2234
|
+
signal: this.disconnect.signal
|
|
2235
|
+
}).then(({ record }) => {
|
|
2236
|
+
this.assertOpen();
|
|
2237
|
+
return sharedHandle(record);
|
|
2238
|
+
}));
|
|
2239
|
+
}
|
|
2240
|
+
startTurn(input) {
|
|
2241
|
+
this.assertOpen();
|
|
2242
|
+
if (input.mode !== "prompt" || input.onPermissionRequest || input.onElicitation) invalidOption("Shared turns support prompt mode and the client's static permission policy; in-process callbacks and steering are unsupported.");
|
|
2243
|
+
if (!input.requestId.trim()) invalidOption("A shared turn requires a requestId.");
|
|
2244
|
+
const sessionId = sharedRecordId(input.handle);
|
|
2245
|
+
const prompt = toPromptInput(input.text, input.attachments);
|
|
2246
|
+
const events = new AsyncEventQueue();
|
|
2247
|
+
const promptStarted = createDeferred();
|
|
2248
|
+
promptStarted.promise.catch(() => {});
|
|
2249
|
+
let accepted = false;
|
|
2250
|
+
let settled = false;
|
|
2251
|
+
let cancelRequested = input.signal?.aborted === true;
|
|
2252
|
+
let cancellation;
|
|
2253
|
+
const cancel = async () => {
|
|
2254
|
+
cancelRequested = true;
|
|
2255
|
+
if (!accepted || settled) return;
|
|
2256
|
+
cancellation ??= tryCancelOnRunningOwner({
|
|
2257
|
+
sessionId,
|
|
2258
|
+
targetRequestId: input.requestId
|
|
2259
|
+
}).then(() => {});
|
|
2260
|
+
await cancellation;
|
|
2261
|
+
};
|
|
2262
|
+
const onAbort = () => {
|
|
2263
|
+
cancel().catch(() => {});
|
|
2264
|
+
};
|
|
2265
|
+
input.signal?.addEventListener("abort", onAbort, { once: true });
|
|
2266
|
+
const run = async () => {
|
|
2267
|
+
if (cancelRequested) return {
|
|
2268
|
+
status: "cancelled",
|
|
2269
|
+
stopReason: "cancelled"
|
|
2270
|
+
};
|
|
2271
|
+
if ((await resolveSessionRecord(sessionId)).closed) throw new AcpRuntimeError("ACP_SESSION_INIT_FAILED", "Shared session is closed; ensure it again before submitting a turn.");
|
|
2272
|
+
if (cancelRequested) return {
|
|
2273
|
+
status: "cancelled",
|
|
2274
|
+
stopReason: "cancelled"
|
|
2275
|
+
};
|
|
2276
|
+
const result = await sendSession({
|
|
2277
|
+
...this.options,
|
|
2278
|
+
sessionId,
|
|
2279
|
+
requestId: input.requestId,
|
|
2280
|
+
prompt: typeof prompt === "string" ? textPrompt(prompt) : prompt,
|
|
2281
|
+
resumePolicy: "same-session-only",
|
|
2282
|
+
requireSharedRuntime: true,
|
|
2283
|
+
signal: this.disconnect.signal,
|
|
2284
|
+
timeoutMs: input.timeoutMs ?? this.options.timeoutMs,
|
|
2285
|
+
queueOwnerArgs: [fileURLToPath(import.meta.resolve("acpx/dist/cli.js")), "__queue-owner"],
|
|
2286
|
+
onQueueAccepted: () => {
|
|
2287
|
+
accepted = true;
|
|
2288
|
+
if (cancelRequested) cancel().catch(() => {});
|
|
2289
|
+
},
|
|
2290
|
+
onPromptStarted: () => promptStarted.resolve(),
|
|
2291
|
+
outputFormatter: {
|
|
2292
|
+
...DISCARD_OUTPUT_FORMATTER,
|
|
2293
|
+
onAcpMessage: (message) => {
|
|
2294
|
+
const event = parsePromptEventLine(JSON.stringify(message));
|
|
2295
|
+
if (event) events.push(event);
|
|
2296
|
+
}
|
|
2297
|
+
},
|
|
2298
|
+
errorEmissionPolicy: { queueErrorAlreadyEmitted: false },
|
|
2299
|
+
waitForCompletion: true
|
|
2300
|
+
});
|
|
2301
|
+
if ("queued" in result) throw new AcpRuntimeError("ACP_TURN_FAILED", "Shared turn ended without a completion result.");
|
|
2302
|
+
return {
|
|
2303
|
+
status: result.stopReason === "cancelled" ? "cancelled" : "completed",
|
|
2304
|
+
stopReason: result.stopReason,
|
|
2305
|
+
_meta: result._meta
|
|
2306
|
+
};
|
|
2307
|
+
};
|
|
2308
|
+
const result = this.track(run().catch(turnFailure).finally(() => {
|
|
2309
|
+
settled = true;
|
|
2310
|
+
promptStarted.reject(new AcpRuntimeError("ACP_TURN_FAILED", "Turn settled before its prompt was written."));
|
|
2311
|
+
input.signal?.removeEventListener("abort", onAbort);
|
|
2312
|
+
events.close();
|
|
2313
|
+
}));
|
|
2314
|
+
return {
|
|
2315
|
+
requestId: input.requestId,
|
|
2316
|
+
promptStarted: promptStarted.promise,
|
|
2317
|
+
events: events.iterate(),
|
|
2318
|
+
result,
|
|
2319
|
+
cancel,
|
|
2320
|
+
closeStream: async () => {
|
|
2321
|
+
events.clear();
|
|
2322
|
+
events.close();
|
|
2323
|
+
}
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
async *runTurn(input) {
|
|
2327
|
+
const turn = this.startTurn(input);
|
|
2328
|
+
yield* turn.events;
|
|
2329
|
+
yield legacyTerminalEventFromTurnResult(await turn.result);
|
|
2330
|
+
}
|
|
2331
|
+
async getStatus(input) {
|
|
2332
|
+
this.assertOpen();
|
|
2333
|
+
return runtimeStatusFromRecord(await resolveSessionRecord(sharedRecordId(input.handle)));
|
|
2334
|
+
}
|
|
2335
|
+
watchSession(input) {
|
|
2336
|
+
this.assertOpen();
|
|
2337
|
+
const signal = input.signal ? AbortSignal.any([input.signal, this.disconnect.signal]) : this.disconnect.signal;
|
|
2338
|
+
const recordId = sharedRecordId(input.handle);
|
|
2339
|
+
const record = readSessionRecord(recordId).then((value) => {
|
|
2340
|
+
if (!value || value.acpxRecordId !== recordId) throw new AcpRuntimeError("ACP_SESSION_INIT_FAILED", "Shared session record is unavailable.");
|
|
2341
|
+
return value;
|
|
2342
|
+
});
|
|
2343
|
+
record.catch(() => {});
|
|
2344
|
+
return watchSession({
|
|
2345
|
+
record,
|
|
2346
|
+
cursor: input.cursor,
|
|
2347
|
+
signal
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
async cancel(input) {
|
|
2351
|
+
this.assertOpen();
|
|
2352
|
+
await this.track(cancelSessionPrompt({ sessionId: sharedRecordId(input.handle) }));
|
|
2353
|
+
}
|
|
2354
|
+
async close(input) {
|
|
2355
|
+
this.assertOpen();
|
|
2356
|
+
await this.track(closeSession(sharedRecordId(input.handle)));
|
|
2357
|
+
}
|
|
2358
|
+
async shutdown() {
|
|
2359
|
+
this.disconnect.abort(new AcpRuntimeError("ACP_BACKEND_UNAVAILABLE", "Shared client detached; submitted work may still be running."));
|
|
2360
|
+
await Promise.allSettled(this.pending);
|
|
2361
|
+
}
|
|
2362
|
+
};
|
|
2363
|
+
function createSharedAcpRuntime(options) {
|
|
2364
|
+
return new SharedAcpRuntime(options);
|
|
2365
|
+
}
|
|
2366
|
+
//#endregion
|
|
2128
2367
|
//#region src/runtime.ts
|
|
2129
2368
|
const ACPX_BACKEND_ID = "acpx";
|
|
2130
2369
|
const ACPX_CAPABILITIES = { controls: [
|
|
@@ -2286,15 +2525,15 @@ var AcpxRuntime = class {
|
|
|
2286
2525
|
}
|
|
2287
2526
|
async setMode(input) {
|
|
2288
2527
|
const { handle, state } = this.resolveManagerHandle(input.handle);
|
|
2289
|
-
await (await this.getManager()).setMode(handle, input.mode, state.mode);
|
|
2528
|
+
await (await this.getManager()).setMode(handle, input.mode, state.mode, input);
|
|
2290
2529
|
}
|
|
2291
2530
|
async setModel(input) {
|
|
2292
2531
|
const { handle, state } = this.resolveManagerHandle(input.handle);
|
|
2293
|
-
await (await this.getManager()).setModel(handle, input.model, state.mode);
|
|
2532
|
+
await (await this.getManager()).setModel(handle, input.model, state.mode, input);
|
|
2294
2533
|
}
|
|
2295
2534
|
async setConfigOption(input) {
|
|
2296
2535
|
const { handle, state } = this.resolveManagerHandle(input.handle);
|
|
2297
|
-
return await (await this.getManager()).setConfigOption(handle, input.key, input.value, state.mode);
|
|
2536
|
+
return await (await this.getManager()).setConfigOption(handle, input.key, input.value, state.mode, input);
|
|
2298
2537
|
}
|
|
2299
2538
|
async cancel(input) {
|
|
2300
2539
|
const { handle } = this.resolveManagerHandle(input.handle);
|
|
@@ -2377,6 +2616,6 @@ function createRuntimeStore(options) {
|
|
|
2377
2616
|
return createFileSessionStore(options);
|
|
2378
2617
|
}
|
|
2379
2618
|
//#endregion
|
|
2380
|
-
export { ACPX_BACKEND_ID, AcpRuntimeError, AcpxRuntime, DEFAULT_AGENT_NAME, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE, REQUESTED_MODEL_UNSUPPORTED_REASONS, RequestedModelUnsupportedError, createAcpRuntime, createAgentRegistry, createFileSessionStore, createRuntimeStore, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState, isAcpRuntimeError, isRequestedModelUnsupportedError };
|
|
2619
|
+
export { ACPX_BACKEND_ID, AcpRuntimeError, AcpxRuntime, DEFAULT_AGENT_NAME, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE, REQUESTED_MODEL_UNSUPPORTED_REASONS, RequestedModelUnsupportedError, SharedAcpRuntime, createAcpRuntime, createAgentRegistry, createFileSessionStore, createRuntimeStore, createSharedAcpRuntime, decodeAcpxRuntimeHandleState, encodeAcpxRuntimeHandleState, isAcpRuntimeError, isRequestedModelUnsupportedError };
|
|
2381
2620
|
|
|
2382
2621
|
//# sourceMappingURL=runtime.js.map
|