@moxt-ai/mobius 0.0.317 → 0.0.319

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.
Files changed (80) hide show
  1. package/dist/acp/adapter/agent-initialization.d.ts.map +1 -1
  2. package/dist/acp/adapter/agent-initialization.js +7 -12
  3. package/dist/acp/adapter/agent-initialization.js.map +1 -1
  4. package/dist/acp/adapter/claude/agent-connection.d.ts +6 -0
  5. package/dist/acp/adapter/claude/agent-connection.d.ts.map +1 -0
  6. package/dist/acp/adapter/claude/agent-connection.js +15 -0
  7. package/dist/acp/adapter/claude/agent-connection.js.map +1 -0
  8. package/dist/acp/adapter/codex/agent-connection.d.ts +6 -0
  9. package/dist/acp/adapter/codex/agent-connection.d.ts.map +1 -0
  10. package/dist/acp/adapter/codex/agent-connection.js +15 -0
  11. package/dist/acp/adapter/codex/agent-connection.js.map +1 -0
  12. package/dist/acp/adapter/pi/agent-connection.d.ts +6 -0
  13. package/dist/acp/adapter/pi/agent-connection.d.ts.map +1 -0
  14. package/dist/acp/adapter/pi/agent-connection.js +15 -0
  15. package/dist/acp/adapter/pi/agent-connection.js.map +1 -0
  16. package/dist/acp/adapter/session-events.d.ts +1 -1
  17. package/dist/acp/adapter/session-events.d.ts.map +1 -1
  18. package/dist/acp/adapter/session-events.js +12 -11
  19. package/dist/acp/adapter/session-events.js.map +1 -1
  20. package/dist/acp/agent/agent-definition.d.ts +9 -21
  21. package/dist/acp/agent/agent-definition.d.ts.map +1 -1
  22. package/dist/acp/agent/agent-definition.js +11 -31
  23. package/dist/acp/agent/agent-definition.js.map +1 -1
  24. package/dist/acp/connection/agent-connection.d.ts +18 -10
  25. package/dist/acp/connection/agent-connection.d.ts.map +1 -1
  26. package/dist/acp/connection/agent-connection.js +1 -231
  27. package/dist/acp/connection/agent-connection.js.map +1 -1
  28. package/dist/acp/connection/agent-operation.d.ts +4 -0
  29. package/dist/acp/connection/agent-operation.d.ts.map +1 -0
  30. package/dist/acp/connection/agent-operation.js +57 -0
  31. package/dist/acp/connection/agent-operation.js.map +1 -0
  32. package/dist/acp/connection/endpoint-agent-connection.d.ts +28 -0
  33. package/dist/acp/connection/endpoint-agent-connection.d.ts.map +1 -0
  34. package/dist/acp/connection/endpoint-agent-connection.js +31 -0
  35. package/dist/acp/connection/endpoint-agent-connection.js.map +1 -0
  36. package/dist/agent/discovery/acp-readiness-probe.d.ts +1 -0
  37. package/dist/agent/discovery/acp-readiness-probe.d.ts.map +1 -1
  38. package/dist/agent/discovery/acp-readiness-probe.js +29 -188
  39. package/dist/agent/discovery/acp-readiness-probe.js.map +1 -1
  40. package/dist/agent/discovery/discover-agent.d.ts.map +1 -1
  41. package/dist/agent/discovery/discover-agent.js +4 -6
  42. package/dist/agent/discovery/discover-agent.js.map +1 -1
  43. package/dist/agent/discovery/executable-discovery.d.ts +1 -1
  44. package/dist/agent/discovery/executable-discovery.d.ts.map +1 -1
  45. package/dist/agent/discovery/executable-discovery.js +1 -6
  46. package/dist/agent/discovery/executable-discovery.js.map +1 -1
  47. package/dist/agent/specification/agent-specification.d.ts +3 -9
  48. package/dist/agent/specification/agent-specification.d.ts.map +1 -1
  49. package/dist/agent/specification/agent-specification.js +1 -12
  50. package/dist/agent/specification/agent-specification.js.map +1 -1
  51. package/dist/agent/specification/vendors/claude-code-agent.d.ts +2 -2
  52. package/dist/agent/specification/vendors/claude-code-agent.d.ts.map +1 -1
  53. package/dist/agent/specification/vendors/claude-code-agent.js +2 -2
  54. package/dist/agent/specification/vendors/claude-code-agent.js.map +1 -1
  55. package/dist/agent/specification/vendors/codex-agent.d.ts +2 -2
  56. package/dist/agent/specification/vendors/codex-agent.d.ts.map +1 -1
  57. package/dist/agent/specification/vendors/codex-agent.js +2 -2
  58. package/dist/agent/specification/vendors/codex-agent.js.map +1 -1
  59. package/dist/agent/specification/vendors/pi-agent.d.ts +2 -2
  60. package/dist/agent/specification/vendors/pi-agent.d.ts.map +1 -1
  61. package/dist/agent/specification/vendors/pi-agent.js +2 -2
  62. package/dist/agent/specification/vendors/pi-agent.js.map +1 -1
  63. package/dist/cli/handler/agents/logic/agent-diagnostics.d.ts.map +1 -1
  64. package/dist/cli/handler/agents/logic/agent-diagnostics.js +1 -4
  65. package/dist/cli/handler/agents/logic/agent-diagnostics.js.map +1 -1
  66. package/dist/cli.js +584 -862
  67. package/dist/cli.js.map +4 -4
  68. package/dist/runtime/catalog/resolve-catalog-agent.js +6 -3
  69. package/dist/runtime/catalog/resolve-catalog-agent.js.map +1 -1
  70. package/dist/runtime.d.ts +3 -2
  71. package/dist/runtime.d.ts.map +1 -1
  72. package/dist/runtime.js +308 -611
  73. package/dist/runtime.js.map +4 -4
  74. package/dist/session/settings/discover-agent-settings.js +1 -1
  75. package/dist/session/settings/discover-agent-settings.js.map +1 -1
  76. package/dist/session/turn/session-turns.d.ts +7 -0
  77. package/dist/session/turn/session-turns.d.ts.map +1 -1
  78. package/dist/session/turn/session-turns.js +1 -0
  79. package/dist/session/turn/session-turns.js.map +1 -1
  80. package/package.json +2 -2
package/dist/runtime.js CHANGED
@@ -1017,92 +1017,46 @@ function restrictAcpSessionCapabilities(capabilities, response) {
1017
1017
  }
1018
1018
 
1019
1019
  // src/acp/agent/agent-definition.ts
1020
- var AgentDefinition = class {
1020
+ var AcpAgentDefinition = class _AcpAgentDefinition {
1021
1021
  agentIdentity;
1022
1022
  agentVersion;
1023
+ adapterVersion;
1023
1024
  capabilities;
1024
1025
  command;
1025
1026
  environment;
1026
1027
  id;
1027
1028
  label;
1028
- constructor(id, label, _command, environment, agentVersion, agentIdentity, capabilities) {
1029
+ runtimeExecutables;
1030
+ #connectionFactory;
1031
+ constructor(id, label, command, createConnection, environment = {}, agentVersion = "", agentIdentity = readExecutableIdentity(command), capabilities = unsupportedSessionCapabilities(), adapterVersion = agentVersion, runtimeExecutables = [agentIdentity]) {
1029
1032
  this.agentIdentity = agentIdentity;
1030
1033
  this.agentVersion = agentVersion;
1034
+ this.adapterVersion = adapterVersion;
1031
1035
  this.capabilities = Object.freeze({ ...capabilities });
1032
1036
  this.command = agentIdentity.realPath;
1033
1037
  this.environment = Object.freeze({ ...environment });
1034
1038
  this.id = id;
1035
1039
  this.label = label;
1040
+ this.runtimeExecutables = Object.freeze([.../* @__PURE__ */ new Set([agentIdentity, ...runtimeExecutables])]);
1041
+ this.#connectionFactory = createConnection;
1036
1042
  }
1037
- };
1038
- var LocalAgentDefinition = class _LocalAgentDefinition extends AgentDefinition {
1039
- kind = "acp-adapter-process";
1040
- adapterIdentity;
1041
- adapterPath;
1042
- adapterVersion;
1043
- arguments;
1044
- constructor(id, label, command, arguments_, environment = {}, adapterVersion = "", agentVersion = "", adapterIdentity = readExecutableIdentity(command), agentIdentity = adapterIdentity, capabilities = unsupportedSessionCapabilities()) {
1045
- super(id, label, command, environment, agentVersion, agentIdentity, capabilities);
1046
- this.adapterIdentity = adapterIdentity;
1047
- this.adapterPath = adapterIdentity.realPath;
1048
- this.adapterVersion = adapterVersion;
1049
- this.arguments = Object.freeze([...arguments_]);
1050
- }
1051
- withEnvironment = (environment) => new _LocalAgentDefinition(
1043
+ createConnection = (options) => this.#connectionFactory({ ...options, command: this.command, environment: this.environment });
1044
+ withEnvironment = (environment) => new _AcpAgentDefinition(
1052
1045
  this.id,
1053
1046
  this.label,
1054
1047
  this.command,
1055
- this.arguments,
1048
+ this.#connectionFactory,
1056
1049
  environment,
1057
- this.adapterVersion,
1058
1050
  this.agentVersion,
1059
- this.adapterIdentity,
1060
1051
  this.agentIdentity,
1061
- this.capabilities
1062
- );
1063
- };
1064
- var InProcessAcpAgentDefinition = class _InProcessAcpAgentDefinition extends AgentDefinition {
1065
- kind = "in-process-acp";
1066
- createEndpoint;
1067
- constructor(id, label, command, createEndpoint, environment = {}, agentVersion = "", agentIdentity = readExecutableIdentity(command), capabilities = unsupportedSessionCapabilities()) {
1068
- super(id, label, command, environment, agentVersion, agentIdentity, capabilities);
1069
- this.createEndpoint = createEndpoint;
1070
- }
1071
- withEnvironment = (environment) => new _InProcessAcpAgentDefinition(
1072
- this.id,
1073
- this.label,
1074
- this.command,
1075
- this.createEndpoint,
1076
- environment,
1077
- this.agentVersion,
1078
- this.agentIdentity,
1079
- this.capabilities
1052
+ this.capabilities,
1053
+ this.adapterVersion,
1054
+ this.runtimeExecutables
1080
1055
  );
1081
1056
  };
1082
1057
 
1083
- // src/acp/adapter/adapter-registry.ts
1084
- var AdapterRegistry = class {
1085
- #resolve;
1086
- #dependencies;
1087
- #adapters = /* @__PURE__ */ new Map();
1088
- constructor(resolve19, dependencies) {
1089
- this.#resolve = resolve19;
1090
- this.#dependencies = dependencies;
1091
- }
1092
- resolve = (agent) => {
1093
- const existing = this.#adapters.get(agent.id);
1094
- if (existing !== void 0) {
1095
- return existing;
1096
- }
1097
- const adapter = this.#resolve(agent, this.#dependencies);
1098
- this.#adapters.set(agent.id, adapter);
1099
- return adapter;
1100
- };
1101
- close = async () => {
1102
- await Promise.all([...this.#adapters.values()].map((adapter) => adapter.close()));
1103
- this.#adapters.clear();
1104
- };
1105
- };
1058
+ // src/acp/connection/agent-operation.ts
1059
+ import { RequestError } from "@agentclientprotocol/sdk";
1106
1060
 
1107
1061
  // src/infra/operation-error.ts
1108
1062
  var OperationError = class extends Error {
@@ -1141,6 +1095,145 @@ var AcpConfigurationValueUnavailableError = class extends AcpExecutionError {
1141
1095
  }
1142
1096
  };
1143
1097
 
1098
+ // src/acp/agent/in-process-endpoint.ts
1099
+ function acpEndpointTerminationError(termination) {
1100
+ switch (termination.kind) {
1101
+ case "failed":
1102
+ return termination.error;
1103
+ case "closed":
1104
+ return new AcpExecutionError("The ACP endpoint is closed", {}, "acp_endpoint_closed");
1105
+ default: {
1106
+ const unreachable3 = termination;
1107
+ return unreachable3;
1108
+ }
1109
+ }
1110
+ }
1111
+
1112
+ // src/acp/connection/agent-operation.ts
1113
+ function requestErrorMessage(error62) {
1114
+ const fallback = truncate(error62.message, 500);
1115
+ if (error62.message !== "Internal error" || !isRecord(error62.data)) {
1116
+ return fallback;
1117
+ }
1118
+ const agentError = error62.data["error"];
1119
+ if (isRecord(agentError)) {
1120
+ const message = agentError["message"];
1121
+ if (typeof message === "string" && message.length > 0) {
1122
+ return truncate(message, 500);
1123
+ }
1124
+ }
1125
+ const details = error62.data["details"];
1126
+ return typeof details === "string" && details.length > 0 ? truncate(details, 500) : fallback;
1127
+ }
1128
+ async function raceAgentOperation(operation, termination, exitMessage, signal) {
1129
+ let removeAbortListener = () => {
1130
+ };
1131
+ const aborted2 = new Promise((_resolve, reject2) => {
1132
+ const rejectAbort = () => {
1133
+ reject2(signal.reason ?? new Error("ACP request was cancelled"));
1134
+ };
1135
+ signal.addEventListener("abort", rejectAbort, { once: true });
1136
+ removeAbortListener = () => signal.removeEventListener("abort", rejectAbort);
1137
+ if (signal.aborted) {
1138
+ rejectAbort();
1139
+ }
1140
+ });
1141
+ try {
1142
+ return await Promise.race([
1143
+ aborted2,
1144
+ operation,
1145
+ termination.then((result) => {
1146
+ const cause = acpEndpointTerminationError(result);
1147
+ throw new AcpExecutionError(exitMessage, { cause }, cause.code);
1148
+ })
1149
+ ]);
1150
+ } catch (error62) {
1151
+ signal.throwIfAborted();
1152
+ if (error62 instanceof RequestError && error62.code === -32e3) {
1153
+ throw new AcpExecutionError(
1154
+ "Agent authentication is required",
1155
+ { cause: error62 },
1156
+ "authentication_required"
1157
+ );
1158
+ }
1159
+ if (error62 instanceof RequestError) {
1160
+ throw new AcpExecutionError(requestErrorMessage(error62), { cause: error62 }, "acp_agent_error");
1161
+ }
1162
+ throw error62;
1163
+ } finally {
1164
+ removeAbortListener();
1165
+ }
1166
+ }
1167
+
1168
+ // src/acp/connection/create-client.ts
1169
+ import {
1170
+ client,
1171
+ methods
1172
+ } from "@agentclientprotocol/sdk";
1173
+ var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
1174
+ methods.client.session.requestPermission,
1175
+ async (context) => await handler.onPermission(context.params, context.signal)
1176
+ ).onRequest(
1177
+ methods.client.elicitation.create,
1178
+ async (context) => await handler.onElicitation(context.params, context.signal)
1179
+ ).onNotification(methods.client.session.update, async (context) => {
1180
+ await handler.onUpdate(context.params);
1181
+ }).onNotification(methods.client.elicitation.complete, async (context) => {
1182
+ await handler.onElicitationComplete(context.params);
1183
+ });
1184
+
1185
+ // src/acp/connection/endpoint-agent-connection.ts
1186
+ var EndpointAgentConnection = class {
1187
+ #endpoint;
1188
+ connection;
1189
+ termination;
1190
+ #closePromise = null;
1191
+ constructor(endpoint, client2) {
1192
+ this.#endpoint = endpoint;
1193
+ this.termination = endpoint.terminated;
1194
+ this.connection = createAcpClient(client2).connect(endpoint.app());
1195
+ }
1196
+ initialize = async (signal) => {
1197
+ await this.#endpoint.initialize(signal);
1198
+ };
1199
+ agentSettingsModelEffort = () => this.#endpoint.agentSettingsModelEffort?.() ?? null;
1200
+ closeProcess = () => {
1201
+ this.#closePromise ??= (async () => {
1202
+ try {
1203
+ await this.#endpoint.close();
1204
+ } finally {
1205
+ this.connection.close();
1206
+ }
1207
+ })();
1208
+ return this.#closePromise;
1209
+ };
1210
+ race = (operation, exitMessage, signal) => raceAgentOperation(operation, this.termination, exitMessage, signal);
1211
+ };
1212
+
1213
+ // src/acp/adapter/adapter-registry.ts
1214
+ var AdapterRegistry = class {
1215
+ #resolve;
1216
+ #dependencies;
1217
+ #adapters = /* @__PURE__ */ new Map();
1218
+ constructor(resolve19, dependencies) {
1219
+ this.#resolve = resolve19;
1220
+ this.#dependencies = dependencies;
1221
+ }
1222
+ resolve = (agent) => {
1223
+ const existing = this.#adapters.get(agent.id);
1224
+ if (existing !== void 0) {
1225
+ return existing;
1226
+ }
1227
+ const adapter = this.#resolve(agent, this.#dependencies);
1228
+ this.#adapters.set(agent.id, adapter);
1229
+ return adapter;
1230
+ };
1231
+ close = async () => {
1232
+ await Promise.all([...this.#adapters.values()].map((adapter) => adapter.close()));
1233
+ this.#adapters.clear();
1234
+ };
1235
+ };
1236
+
1144
1237
  // src/util/run-cleanup.ts
1145
1238
  async function runCleanup(...actions) {
1146
1239
  const [first, ...remaining] = actions;
@@ -21931,7 +22024,9 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
21931
22024
  external_exports.object({
21932
22025
  commandId: identifierStringSchema,
21933
22026
  prompt: external_exports.string().max(1e5),
21934
- images: external_exports.array(promptImageSchema).max(8).readonly()
22027
+ images: external_exports.array(promptImageSchema).max(8).readonly(),
22028
+ // Absent from daemons that predate it; a client then cannot restore the prompt's files.
22029
+ resources: external_exports.array(promptResourceSchema).max(16).readonly().optional()
21935
22030
  }).readonly()
21936
22031
  ).readonly(),
21937
22032
  turn: activeTurnSnapshotSchema.nullable()
@@ -22840,7 +22935,7 @@ var nativeSessionPageSchema = external_exports.object({
22840
22935
  }).readonly();
22841
22936
 
22842
22937
  // src/acp/protocol/session-config-protocol.ts
22843
- import { methods } from "@agentclientprotocol/sdk";
22938
+ import { methods as methods2 } from "@agentclientprotocol/sdk";
22844
22939
  var MAXIMUM_CONFIG_OPTIONS = 100;
22845
22940
  var SessionConfigProtocolError = class extends Error {
22846
22941
  code = "invalid_session_configuration_response";
@@ -23010,7 +23105,7 @@ var StandardSessionConfigProtocol = class {
23010
23105
  }
23011
23106
  if (existing.type === "select" && existing.category === "mode") {
23012
23107
  await transport.request(
23013
- methods.agent.session.setMode,
23108
+ methods2.agent.session.setMode,
23014
23109
  { modeId: change.value, sessionId: nativeSessionId },
23015
23110
  "ACP agent exited while setting the session mode",
23016
23111
  change.signal
@@ -23028,7 +23123,7 @@ var StandardSessionConfigProtocol = class {
23028
23123
  value: change.value
23029
23124
  };
23030
23125
  const response = await transport.request(
23031
- methods.agent.session.setConfigOption,
23126
+ methods2.agent.session.setConfigOption,
23032
23127
  params,
23033
23128
  "ACP agent exited while changing session configuration",
23034
23129
  change.signal
@@ -23049,266 +23144,6 @@ function sessionConfigProtocolForAgent(_agentId) {
23049
23144
  // src/acp/adapter/session-events.ts
23050
23145
  import { setImmediate as yieldToRuntime2 } from "node:timers/promises";
23051
23146
 
23052
- // src/acp/connection/agent-connection.ts
23053
- import { spawn as spawn2 } from "node:child_process";
23054
- import { ndJsonStream, RequestError } from "@agentclientprotocol/sdk";
23055
-
23056
- // src/acp/agent/in-process-endpoint.ts
23057
- function acpEndpointTerminationError(termination) {
23058
- switch (termination.kind) {
23059
- case "failed":
23060
- return termination.error;
23061
- case "closed":
23062
- return new AcpExecutionError("The ACP endpoint is closed", {}, "acp_endpoint_closed");
23063
- default: {
23064
- const unreachable3 = termination;
23065
- return unreachable3;
23066
- }
23067
- }
23068
- }
23069
-
23070
- // src/acp/connection/create-client.ts
23071
- import {
23072
- client,
23073
- methods as methods2
23074
- } from "@agentclientprotocol/sdk";
23075
- var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
23076
- methods2.client.session.requestPermission,
23077
- async (context) => await handler.onPermission(context.params, context.signal)
23078
- ).onRequest(
23079
- methods2.client.elicitation.create,
23080
- async (context) => await handler.onElicitation(context.params, context.signal)
23081
- ).onNotification(methods2.client.session.update, async (context) => {
23082
- await handler.onUpdate(context.params);
23083
- }).onNotification(methods2.client.elicitation.complete, async (context) => {
23084
- await handler.onElicitationComplete(context.params);
23085
- });
23086
-
23087
- // src/acp/connection/agent-connection.ts
23088
- function requestErrorMessage(error62) {
23089
- const fallback = truncate(error62.message, 500);
23090
- if (error62.message !== "Internal error" || !isRecord(error62.data)) {
23091
- return fallback;
23092
- }
23093
- const agentError = error62.data["error"];
23094
- if (isRecord(agentError)) {
23095
- const message = agentError["message"];
23096
- if (typeof message === "string" && message.length > 0) {
23097
- return truncate(message, 500);
23098
- }
23099
- }
23100
- const details = error62.data["details"];
23101
- return typeof details === "string" && details.length > 0 ? truncate(details, 500) : fallback;
23102
- }
23103
- function readableWebStream(input2) {
23104
- let streamOpen = true;
23105
- return new ReadableStream({
23106
- start(controller) {
23107
- input2.on("data", (chunk) => {
23108
- if (!streamOpen) {
23109
- return;
23110
- }
23111
- if (chunk instanceof Uint8Array) {
23112
- controller.enqueue(new Uint8Array(chunk));
23113
- return;
23114
- }
23115
- streamOpen = false;
23116
- controller.error(new Error("ACP process produced a non-binary chunk"));
23117
- });
23118
- input2.once("end", () => {
23119
- if (!streamOpen) {
23120
- return;
23121
- }
23122
- streamOpen = false;
23123
- controller.close();
23124
- });
23125
- input2.once("error", (error62) => {
23126
- if (!streamOpen) {
23127
- return;
23128
- }
23129
- streamOpen = false;
23130
- controller.error(error62);
23131
- });
23132
- },
23133
- cancel() {
23134
- streamOpen = false;
23135
- }
23136
- });
23137
- }
23138
- function createWritableAcpStream(output2) {
23139
- let outputFailure;
23140
- const pendingWriteFailures = /* @__PURE__ */ new Set();
23141
- const fail = (error62) => {
23142
- outputFailure = error62;
23143
- for (const reject2 of pendingWriteFailures) {
23144
- reject2(error62);
23145
- }
23146
- pendingWriteFailures.clear();
23147
- };
23148
- output2.on("error", fail);
23149
- output2.once("close", () => {
23150
- if (outputFailure === void 0) {
23151
- fail(new Error("ACP process input closed"));
23152
- }
23153
- });
23154
- return new WritableStream({
23155
- write(chunk) {
23156
- if (outputFailure !== void 0) {
23157
- return Promise.reject(outputFailure);
23158
- }
23159
- return new Promise((resolve19, reject2) => {
23160
- pendingWriteFailures.add(reject2);
23161
- output2.write(chunk, (error62) => {
23162
- pendingWriteFailures.delete(reject2);
23163
- if (error62) {
23164
- outputFailure = error62;
23165
- reject2(error62);
23166
- return;
23167
- }
23168
- if (outputFailure !== void 0) {
23169
- reject2(outputFailure);
23170
- return;
23171
- }
23172
- resolve19();
23173
- });
23174
- });
23175
- }
23176
- });
23177
- }
23178
- var AgentConnection = class {
23179
- connection;
23180
- termination;
23181
- #process;
23182
- constructor(agent, cwd, client2, onBackgroundActivity = () => {
23183
- }) {
23184
- if (agent.kind === "in-process-acp") {
23185
- const inProcess = agent.createEndpoint({
23186
- command: agent.command,
23187
- cwd,
23188
- environment: agent.environment,
23189
- onSessionUpdate: client2.onUpdate,
23190
- onBackgroundActivity
23191
- });
23192
- this.#process = { kind: "in-process", endpoint: inProcess };
23193
- this.termination = inProcess.terminated;
23194
- this.connection = createAcpClient(client2).connect(inProcess.app());
23195
- return;
23196
- }
23197
- const launch = executableLaunch2(agent.adapterPath, agent.arguments);
23198
- const child = spawn2(launch.command, [...launch.arguments], {
23199
- cwd,
23200
- ...platformSpawnOptions,
23201
- env: { ...process.env, ...agent.environment },
23202
- shell: false,
23203
- stdio: ["pipe", "pipe", "pipe"]
23204
- });
23205
- this.#process = { kind: "child", child };
23206
- const stdin = child.stdin;
23207
- const stdout = child.stdout;
23208
- const stderr = child.stderr;
23209
- if (stdin === null || stdout === null || stderr === null) {
23210
- child.kill("SIGKILL");
23211
- throw new AcpExecutionError("ACP process streams are unavailable");
23212
- }
23213
- stderr.setEncoding("utf8");
23214
- stderr.on("data", (chunk) => {
23215
- process.stderr.write(`[${agent.id}-acp] ${chunk}`);
23216
- });
23217
- this.termination = new Promise((resolve19) => {
23218
- child.once("error", (cause) => {
23219
- resolve19({ kind: "failed", error: new AcpExecutionError("The ACP process could not run", { cause }) });
23220
- });
23221
- child.once("exit", (code, signal) => {
23222
- resolve19({
23223
- kind: "failed",
23224
- error: new AcpExecutionError("The ACP process stopped", { cause: { code, signal } })
23225
- });
23226
- });
23227
- });
23228
- const stream = ndJsonStream(createWritableAcpStream(stdin), readableWebStream(stdout));
23229
- let pendingUpdates = 0;
23230
- this.connection = createAcpClient({
23231
- onElicitation: client2.onElicitation,
23232
- onElicitationComplete: client2.onElicitationComplete,
23233
- onPermission: client2.onPermission,
23234
- // ACP notifications acknowledge transport writes, not their consumption.
23235
- // Stop reading the child while updates from the current chunk drain;
23236
- // the OS pipe then backpressures history replay instead of filling our queue.
23237
- onUpdate: async (notification) => {
23238
- pendingUpdates += 1;
23239
- stdout.pause();
23240
- try {
23241
- await client2.onUpdate(notification);
23242
- } finally {
23243
- pendingUpdates -= 1;
23244
- if (pendingUpdates === 0) {
23245
- stdout.resume();
23246
- }
23247
- }
23248
- }
23249
- }).connect(stream);
23250
- }
23251
- get inProcessAgent() {
23252
- return this.#process.kind === "in-process" ? this.#process.endpoint : null;
23253
- }
23254
- closeProcess = async () => {
23255
- try {
23256
- if (this.#process.kind === "in-process") {
23257
- await this.#process.endpoint.close();
23258
- return;
23259
- }
23260
- await stopProcessTree(this.#process.child);
23261
- } finally {
23262
- this.connection.close();
23263
- }
23264
- };
23265
- race = async (operation, exitMessage, signal) => {
23266
- let removeAbortListener = () => {
23267
- };
23268
- const aborted2 = new Promise((_resolve, reject2) => {
23269
- const rejectAbort = () => {
23270
- reject2(signal.reason ?? new Error("ACP request was cancelled"));
23271
- };
23272
- signal.addEventListener("abort", rejectAbort, { once: true });
23273
- removeAbortListener = () => {
23274
- signal.removeEventListener("abort", rejectAbort);
23275
- };
23276
- if (signal.aborted) {
23277
- rejectAbort();
23278
- }
23279
- });
23280
- try {
23281
- try {
23282
- return await Promise.race([
23283
- // The caller has already started operation. Even when cancellation
23284
- // won before entry, observe its later rejection during endpoint cleanup.
23285
- aborted2,
23286
- operation,
23287
- this.termination.then((termination) => {
23288
- const cause = acpEndpointTerminationError(termination);
23289
- throw new AcpExecutionError(exitMessage, { cause }, cause.code);
23290
- })
23291
- ]);
23292
- } catch (error62) {
23293
- signal.throwIfAborted();
23294
- if (error62 instanceof RequestError && error62.code === -32e3) {
23295
- throw new AcpExecutionError(
23296
- "Agent authentication is required",
23297
- { cause: error62 },
23298
- "authentication_required"
23299
- );
23300
- }
23301
- if (error62 instanceof RequestError) {
23302
- throw new AcpExecutionError(requestErrorMessage(error62), { cause: error62 }, "acp_agent_error");
23303
- }
23304
- throw error62;
23305
- }
23306
- } finally {
23307
- removeAbortListener();
23308
- }
23309
- };
23310
- };
23311
-
23312
23147
  // src/acp/connection/agent-update-stream.ts
23313
23148
  import { setImmediate as yieldToRuntime } from "node:timers/promises";
23314
23149
  var MAX_PENDING_UPDATES = 100;
@@ -23537,21 +23372,23 @@ var AdapterSessionConnection = class {
23537
23372
  onElicitation: options.interactions.onElicitation,
23538
23373
  onElicitationComplete: options.interactions.onElicitationComplete
23539
23374
  };
23540
- this.#connection = new AgentConnection(options.agent, options.cwd, client2, (active) => {
23541
- if (this.#lifetime.signal.aborted) {
23542
- return;
23375
+ this.#connection = options.agent.createConnection({
23376
+ cwd: options.cwd,
23377
+ client: client2,
23378
+ onBackgroundActivity: (active) => {
23379
+ if (this.#lifetime.signal.aborted) {
23380
+ return;
23381
+ }
23382
+ this.#backgroundActivity = active;
23383
+ this.#onBackgroundActivity(active);
23543
23384
  }
23544
- this.#backgroundActivity = active;
23545
- this.#onBackgroundActivity(active);
23546
23385
  });
23547
23386
  }
23548
23387
  get connection() {
23549
23388
  return this.#connection.connection;
23550
23389
  }
23551
- get inProcessAgent() {
23552
- return this.#connection.inProcessAgent;
23553
- }
23554
- agentSettingsModelEffort = () => this.#connection.inProcessAgent?.agentSettingsModelEffort?.() ?? null;
23390
+ initialize = (signal) => this.#connection.initialize(signal);
23391
+ agentSettingsModelEffort = () => this.#connection.agentSettingsModelEffort();
23555
23392
  race = (operation, exitMessage, signal) => this.#connection.race(operation, exitMessage, signal);
23556
23393
  closeProcess = async () => {
23557
23394
  this.#lifetime.abort(new DOMException("The adapter event subscription closed", "AbortError"));
@@ -24609,10 +24446,7 @@ var RetryableAcpInitializationError = class extends AcpExecutionError {
24609
24446
  };
24610
24447
  async function validateAgentRuntime(agent, signal) {
24611
24448
  signal.throwIfAborted();
24612
- const unchanged = await Promise.all([
24613
- agent.kind === "acp-adapter-process" ? revalidateExecutable(agent.adapterIdentity) : Promise.resolve(true),
24614
- revalidateExecutable(agent.agentIdentity)
24615
- ]);
24449
+ const unchanged = await Promise.all(agent.runtimeExecutables.map((identity2) => revalidateExecutable(identity2)));
24616
24450
  signal.throwIfAborted();
24617
24451
  if (unchanged.some((result) => !result)) {
24618
24452
  throw new AcpExecutionError(
@@ -24623,16 +24457,10 @@ async function validateAgentRuntime(agent, signal) {
24623
24457
  }
24624
24458
  }
24625
24459
  async function initializeAgentConnection(connection, agentId, verifiedVersion, signal) {
24626
- if (connection.inProcessAgent !== null) {
24627
- await connection.race(
24628
- connection.inProcessAgent.initialize(signal),
24629
- "The Codex app-server exited during initialization",
24630
- signal
24631
- ).catch((cause) => {
24632
- signal.throwIfAborted();
24633
- throw new RetryableAcpInitializationError(cause);
24634
- });
24635
- }
24460
+ await connection.race(connection.initialize(signal), "The Agent runtime exited during initialization", signal).catch((cause) => {
24461
+ signal.throwIfAborted();
24462
+ throw new RetryableAcpInitializationError(cause);
24463
+ });
24636
24464
  const initialized = await connection.race(
24637
24465
  connection.connection.agent.request(
24638
24466
  methods4.agent.initialize,
@@ -24941,7 +24769,7 @@ var ClaudeAdapter = class {
24941
24769
  import { createHash as createHash3 } from "node:crypto";
24942
24770
 
24943
24771
  // src/acp/harness/codex/app-server-client.ts
24944
- import { spawn as spawn3 } from "node:child_process";
24772
+ import { spawn as spawn2 } from "node:child_process";
24945
24773
 
24946
24774
  // src/acp/harness/codex/app-server-protocol.ts
24947
24775
  import { isAbsolute as isAbsolute5 } from "node:path";
@@ -25261,7 +25089,7 @@ var CodexAppServerClient = class {
25261
25089
  constructor(options) {
25262
25090
  this.#handlers = options.handlers;
25263
25091
  const launch = executableLaunch2(options.command, ["app-server"]);
25264
- this.#child = spawn3(launch.command, [...launch.arguments], {
25092
+ this.#child = spawn2(launch.command, [...launch.arguments], {
25265
25093
  cwd: options.cwd,
25266
25094
  ...platformSpawnOptions,
25267
25095
  env: { ...process.env, ...options.environment },
@@ -25915,12 +25743,12 @@ function presentToolItem(item) {
25915
25743
  };
25916
25744
  }
25917
25745
  if (item.type === "collabAgentToolCall") {
25918
- const spawn8 = item.tool === "spawnAgent";
25746
+ const spawn6 = item.tool === "spawnAgent";
25919
25747
  return {
25920
25748
  content: [],
25921
25749
  kind: "other",
25922
25750
  locations: [],
25923
- rawInput: spawn8 ? {
25751
+ rawInput: spawn6 ? {
25924
25752
  model: item.model,
25925
25753
  prompt: item.prompt,
25926
25754
  reasoningEffort: item.reasoningEffort,
@@ -25928,10 +25756,10 @@ function presentToolItem(item) {
25928
25756
  } : { receiverThreadIds: item.receiverThreadIds, senderThreadId: item.senderThreadId },
25929
25757
  rawOutput: {
25930
25758
  agentsStates: item.agentsStates,
25931
- ...spawn8 ? { receiverThreadIds: item.receiverThreadIds } : {}
25759
+ ...spawn6 ? { receiverThreadIds: item.receiverThreadIds } : {}
25932
25760
  },
25933
25761
  status: collaborationStatus(item.status),
25934
- title: spawn8 ? "Dispatch subagent" : "Wait for subagent"
25762
+ title: spawn6 ? "Dispatch subagent" : "Wait for subagent"
25935
25763
  };
25936
25764
  }
25937
25765
  if (item.type === "subAgentActivity" && item.kind === "started") {
@@ -32453,7 +32281,7 @@ import { fetch as fetch3 } from "undici";
32453
32281
  // package.json
32454
32282
  var package_default = {
32455
32283
  name: "@moxt-ai/mobius",
32456
- version: "0.0.317",
32284
+ version: "0.0.319",
32457
32285
  description: "Mobius CLI for pairing and running local AI agent services.",
32458
32286
  type: "module",
32459
32287
  bin: {
@@ -32557,7 +32385,7 @@ var package_default = {
32557
32385
  };
32558
32386
 
32559
32387
  // src/acp/harness/claude/parent-lifeline.ts
32560
- import { spawn as spawn4 } from "node:child_process";
32388
+ import { spawn as spawn3 } from "node:child_process";
32561
32389
  import { Duplex } from "node:stream";
32562
32390
  var supervisor = `
32563
32391
  const { spawn, spawnSync } = require("node:child_process");
@@ -32586,7 +32414,7 @@ child.once("close", (code) => { exited = true; process.exitCode = code ?? 1; lif
32586
32414
  `;
32587
32415
  function spawnClaudeWithParentLifeline(options) {
32588
32416
  options.signal.throwIfAborted();
32589
- const child = spawn4(process.execPath, ["-e", supervisor, "--", options.command, ...options.args], {
32417
+ const child = spawn3(process.execPath, ["-e", supervisor, "--", options.command, ...options.args], {
32590
32418
  cwd: options.cwd,
32591
32419
  env: options.env,
32592
32420
  stdio: ["pipe", "pipe", "pipe", "pipe"],
@@ -32636,7 +32464,7 @@ import * as fs3 from "node:fs/promises";
32636
32464
  import * as os3 from "node:os";
32637
32465
  import * as path6 from "node:path";
32638
32466
  import { promisify as promisify2 } from "node:util";
32639
- import { agent as acpAgent, CreateElicitationResponse as CreateElicitationResponse2, methods as methods7, ndJsonStream as ndJsonStream2, RequestError as RequestError4 } from "@agentclientprotocol/sdk";
32467
+ import { agent as acpAgent, CreateElicitationResponse as CreateElicitationResponse2, methods as methods7, ndJsonStream, RequestError as RequestError4 } from "@agentclientprotocol/sdk";
32640
32468
 
32641
32469
  // ../../node_modules/.pnpm/@anthropic-ai+claude-agent-sdk@0.3.257_@anthropic-ai+sdk@0.122.0_zod@4.6.5__@modelconte_b0b90ed00d211c5955785f7de7f8dbf4/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
32642
32470
  import { createRequire as $ne } from "node:module";
@@ -73408,16 +73236,15 @@ var ClaudeAcpAgent = class {
73408
73236
  session.lastSessionState = message.state;
73409
73237
  if (message.state === "idle") {
73410
73238
  disarmResultWatchdog();
73239
+ const boundary = session.idleBoundary;
73240
+ const hadEarlierResult = boundary.kind === "accounted" && boundary.turn !== session.activeTurn;
73241
+ session.idleBoundary = { kind: "unaccounted" };
73411
73242
  if (session.cancelled && session.activeTurn && !session.activeTurn.settled) {
73412
73243
  settleActive(turnOutcome(session, "cancelled"));
73413
73244
  session.emittedAssistantText = false;
73414
73245
  } else if (isHeldOpen(session.activeTurn)) {
73415
- if (session.owedTrailingIdles > 0) {
73416
- session.owedTrailingIdles--;
73417
- }
73418
73246
  settleDeferredIfDrained();
73419
- } else if (session.owedTrailingIdles > 0) {
73420
- session.owedTrailingIdles--;
73247
+ } else if (hadEarlierResult) {
73421
73248
  } else if (isSteering(session.activeTurn)) {
73422
73249
  const steered = session.activeTurn;
73423
73250
  if (steered.steeredEchoes?.size === 0 && steered.steeredSettle !== void 0) {
@@ -73426,7 +73253,7 @@ var ClaudeAcpAgent = class {
73426
73253
  steered.steeredSettle = void 0;
73427
73254
  settleDeferredIfDrained();
73428
73255
  }
73429
- } else if (!session.cancelled && session.activeTurn && !session.activeTurn.settled) {
73256
+ } else if (boundary.kind === "unaccounted" && !session.cancelled && session.activeTurn && !session.activeTurn.settled) {
73430
73257
  this.logger.error(`Session ${params.sessionId}: SDK went idle without emitting a result for the active turn; failing the in-flight prompt (issue #825)`);
73431
73258
  failActive(RequestError4.internalError(errorKindData("no_result"), TURN_NO_RESULT_MESSAGE));
73432
73259
  }
@@ -73687,9 +73514,8 @@ ${message.api_refusal_explanation}` : "";
73687
73514
  }
73688
73515
  }
73689
73516
  const deliveredAssistantText = session.emittedAssistantText;
73690
- const owesTrailingIdle = isAutonomousResult || !isSteering(session.activeTurn);
73691
- if (owesTrailingIdle && (isAutonomousResult || !session.cancelled || !session.activeTurn)) {
73692
- session.owedTrailingIdles++;
73517
+ if (isAutonomousResult || !session.cancelled || !session.activeTurn) {
73518
+ session.idleBoundary = { kind: "accounted", turn: session.activeTurn ?? null };
73693
73519
  }
73694
73520
  if (!isAutonomousResult) {
73695
73521
  session.accumulatedUsage.inputTokens += message.usage.input_tokens;
@@ -73951,12 +73777,18 @@ ${message.api_refusal_explanation}` : "";
73951
73777
  if (session.activeTurn !== queued) {
73952
73778
  if (session.activeTurn) {
73953
73779
  if (session.cancelled) {
73954
- session.owedTrailingIdles++;
73780
+ session.idleBoundary = {
73781
+ kind: "accounted",
73782
+ turn: session.activeTurn ?? null
73783
+ };
73955
73784
  settleActive(turnOutcome(session, "cancelled"));
73956
73785
  } else if (isHeldOpen(session.activeTurn)) {
73957
73786
  settleActive(session.activeTurn.deferredSettle);
73958
73787
  } else if (isSteering(session.activeTurn) && session.activeTurn.steeredSettle !== void 0) {
73959
- session.owedTrailingIdles++;
73788
+ session.idleBoundary = {
73789
+ kind: "accounted",
73790
+ turn: session.activeTurn ?? null
73791
+ };
73960
73792
  settleActive(session.activeTurn.steeredSettle);
73961
73793
  } else {
73962
73794
  settleActive(turnOutcome(session, "end_turn"));
@@ -73967,8 +73799,8 @@ ${message.api_refusal_explanation}` : "";
73967
73799
  break;
73968
73800
  }
73969
73801
  if ("isReplay" in message && message.isReplay) {
73970
- if (isSteering(session.activeTurn)) {
73971
- session.activeTurn.steeredEchoes.delete(message.uuid);
73802
+ if (isSteering(session.activeTurn) && session.activeTurn.steeredEchoes.delete(message.uuid)) {
73803
+ session.activeTurn.steeredSettle = void 0;
73972
73804
  }
73973
73805
  break;
73974
73806
  }
@@ -74233,7 +74065,7 @@ ${message.api_refusal_explanation}` : "";
74233
74065
  session.activeTurn = null;
74234
74066
  session.emittedAssistantText = false;
74235
74067
  if (session.lastSessionState !== "idle") {
74236
- session.owedTrailingIdles++;
74068
+ session.idleBoundary = { kind: "accounted", turn: active };
74237
74069
  }
74238
74070
  active.resolve({
74239
74071
  stopReason: "cancelled",
@@ -74243,7 +74075,7 @@ ${message.api_refusal_explanation}` : "";
74243
74075
  }
74244
74076
  }
74245
74077
  if (isSteering(session.activeTurn) && session.activeTurn.steeredSettle !== void 0) {
74246
- session.owedTrailingIdles++;
74078
+ session.idleBoundary = { kind: "accounted", turn: session.activeTurn ?? null };
74247
74079
  }
74248
74080
  if (session.activeTurn && session.cancelController && !session.cancelController.signal.aborted && !session.forceCancelTimer) {
74249
74081
  const cancelController = session.cancelController;
@@ -75261,7 +75093,7 @@ ${message.api_refusal_explanation}` : "";
75261
75093
  emittedToolCalls: /* @__PURE__ */ new Set(),
75262
75094
  liveBackgroundTasks: /* @__PURE__ */ new Map(),
75263
75095
  emittedAssistantText: false,
75264
- owedTrailingIdles: 0,
75096
+ idleBoundary: { kind: "unaccounted" },
75265
75097
  messageIdToUuid: /* @__PURE__ */ new Map()
75266
75098
  };
75267
75099
  return {
@@ -76668,6 +76500,20 @@ var ClaudeAcpEndpoint = class {
76668
76500
  };
76669
76501
  };
76670
76502
 
76503
+ // src/acp/adapter/claude/agent-connection.ts
76504
+ var ClaudeAgentConnection = class extends EndpointAgentConnection {
76505
+ constructor(options) {
76506
+ const endpoint = new ClaudeAcpEndpoint({
76507
+ command: options.command,
76508
+ cwd: options.cwd,
76509
+ environment: options.environment,
76510
+ onSessionUpdate: options.client.onUpdate,
76511
+ onBackgroundActivity: (active) => options.onBackgroundActivity?.(active)
76512
+ });
76513
+ super(endpoint, options.client);
76514
+ }
76515
+ };
76516
+
76671
76517
  // src/agent/discovery/version-output.ts
76672
76518
  function normalizeVersionOutput(output2) {
76673
76519
  return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
@@ -76691,17 +76537,6 @@ var LocalAgentSpecification = class {
76691
76537
  resolveInstalledAgentExecutables = (_context) => Promise.resolve([]);
76692
76538
  verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
76693
76539
  };
76694
- var DirectAcpAgentSpecification = class extends LocalAgentSpecification {
76695
- adapterOverrideVariable;
76696
- agentOverrideVariable;
76697
- launchArguments;
76698
- constructor(executableOverrideVariable, launchArguments) {
76699
- super();
76700
- this.adapterOverrideVariable = executableOverrideVariable;
76701
- this.agentOverrideVariable = executableOverrideVariable;
76702
- this.launchArguments = Object.freeze([...launchArguments]);
76703
- }
76704
- };
76705
76540
  var InProcessAcpAgentSpecification = class extends LocalAgentSpecification {
76706
76541
  launchArguments = Object.freeze([]);
76707
76542
  adapterOverrideVariable;
@@ -76717,7 +76552,7 @@ var InProcessAcpAgentSpecification = class extends LocalAgentSpecification {
76717
76552
  // src/agent/specification/vendors/claude-code-agent.ts
76718
76553
  var ClaudeCodeAgentSpecification = class extends InProcessAcpAgentSpecification {
76719
76554
  agentExecutable = "claude";
76720
- createEndpoint = (options) => new ClaudeAcpEndpoint(options);
76555
+ createConnection = (options) => new ClaudeAgentConnection(options);
76721
76556
  id = "claude";
76722
76557
  label = "Claude Code";
76723
76558
  minimumSupportedAgentVersion = "2.1.273";
@@ -77723,11 +77558,25 @@ var CodexAcpAgent = class {
77723
77558
  };
77724
77559
  };
77725
77560
 
77561
+ // src/acp/adapter/codex/agent-connection.ts
77562
+ var CodexAgentConnection = class extends EndpointAgentConnection {
77563
+ constructor(options) {
77564
+ const endpoint = new CodexAcpAgent({
77565
+ command: options.command,
77566
+ cwd: options.cwd,
77567
+ environment: options.environment,
77568
+ onSessionUpdate: options.client.onUpdate,
77569
+ onBackgroundActivity: (active) => options.onBackgroundActivity?.(active)
77570
+ });
77571
+ super(endpoint, options.client);
77572
+ }
77573
+ };
77574
+
77726
77575
  // src/agent/specification/vendors/codex-agent.ts
77727
77576
  var CodexAgentSpecification = class extends InProcessAcpAgentSpecification {
77728
77577
  versionProbeTimeoutMilliseconds = 1e4;
77729
77578
  agentExecutable = "codex";
77730
- createEndpoint = (options) => new CodexAcpAgent(options);
77579
+ createConnection = (options) => new CodexAgentConnection(options);
77731
77580
  id = "codex";
77732
77581
  label = "Codex";
77733
77582
  minimumSupportedAgentVersion = "0.153.0";
@@ -77755,7 +77604,7 @@ import { basename as basename5, dirname as dirname8, isAbsolute as isAbsolute13,
77755
77604
  import { RequestError as RequestError8 } from "@agentclientprotocol/sdk";
77756
77605
 
77757
77606
  // src/acp/harness/pi/upstream/dist/pi-rpc/process.js
77758
- import { spawn as spawn6 } from "node:child_process";
77607
+ import { spawn as spawn5 } from "node:child_process";
77759
77608
  import * as readline from "node:readline";
77760
77609
 
77761
77610
  // src/acp/harness/pi/upstream/dist/pi-rpc/command.js
@@ -77872,7 +77721,7 @@ var PiRpcProcess = class _PiRpcProcess {
77872
77721
  args.push("--fork", params.origin.sessionPath);
77873
77722
  break;
77874
77723
  }
77875
- const child = spawn6(cmd, args, {
77724
+ const child = spawn5(cmd, args, {
77876
77725
  cwd: params.cwd,
77877
77726
  stdio: "pipe",
77878
77727
  env: params.environment,
@@ -81588,6 +81437,20 @@ function piAgentOrThrow(agent) {
81588
81437
  return agent;
81589
81438
  }
81590
81439
 
81440
+ // src/acp/adapter/pi/agent-connection.ts
81441
+ var PiAgentConnection = class extends EndpointAgentConnection {
81442
+ constructor(options) {
81443
+ const endpoint = new PiAcpEndpoint({
81444
+ command: options.command,
81445
+ cwd: options.cwd,
81446
+ environment: options.environment,
81447
+ onSessionUpdate: options.client.onUpdate,
81448
+ onBackgroundActivity: (active) => options.onBackgroundActivity?.(active)
81449
+ });
81450
+ super(endpoint, options.client);
81451
+ }
81452
+ };
81453
+
81591
81454
  // src/agent/discovery/agent-probe-error.ts
81592
81455
  var AgentProbeError = class extends Error {
81593
81456
  code;
@@ -81603,7 +81466,7 @@ var ACP_PROBE_TIMEOUT_MILLISECONDS2 = 3e4;
81603
81466
  var PiAgentSpecification = class extends InProcessAcpAgentSpecification {
81604
81467
  acpProbeTimeoutMilliseconds = ACP_PROBE_TIMEOUT_MILLISECONDS2;
81605
81468
  agentExecutable = "pi";
81606
- createEndpoint = (options) => new PiAcpEndpoint(options);
81469
+ createConnection = (options) => new PiAgentConnection(options);
81607
81470
  // The Pi ACP fork inlines embedded prompt resources into the turn message, so Mobius
81608
81471
  // keeps the adapter's opt-in capability flag enabled for every launch it owns.
81609
81472
  createLaunchEnvironment = async (_agent, context) => {
@@ -81791,14 +81654,10 @@ var LocalAgentInventory = class {
81791
81654
  };
81792
81655
 
81793
81656
  // src/agent/discovery/acp-readiness-probe.ts
81794
- import { spawn as spawn7 } from "node:child_process";
81795
81657
  import {
81796
81658
  methods as methods12,
81797
- ndJsonStream as ndJsonStream3,
81798
- PROTOCOL_VERSION as PROTOCOL_VERSION3,
81799
- RequestError as RequestError9
81659
+ PROTOCOL_VERSION as PROTOCOL_VERSION3
81800
81660
  } from "@agentclientprotocol/sdk";
81801
- var ACP_OUTPUT_LIMIT_BYTES = 1024 * 1024;
81802
81661
  var VerifiedAcpReadiness = class {
81803
81662
  adapterVersion;
81804
81663
  capabilities;
@@ -81813,76 +81672,38 @@ var DiscoveryAcpHandler = class {
81813
81672
  onPermission = (_request, _signal) => Promise.reject(new Error("ACP probe does not grant permissions"));
81814
81673
  onUpdate = (_notification) => Promise.resolve();
81815
81674
  };
81816
- function readableAcpStream(input2) {
81817
- let byteLength = 0;
81818
- let open6 = true;
81819
- return new ReadableStream({
81820
- start(controller) {
81821
- input2.on("data", (chunk) => {
81822
- if (!open6) {
81823
- return;
81824
- }
81825
- if (!(chunk instanceof Uint8Array)) {
81826
- open6 = false;
81827
- controller.error(new Error("ACP adapter produced invalid output"));
81828
- return;
81829
- }
81830
- byteLength += chunk.byteLength;
81831
- if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
81832
- open6 = false;
81833
- controller.error(new Error("ACP adapter output limit exceeded"));
81834
- return;
81835
- }
81836
- controller.enqueue(new Uint8Array(chunk));
81837
- });
81838
- input2.once("end", () => {
81839
- if (open6) {
81840
- open6 = false;
81841
- controller.close();
81842
- }
81843
- });
81844
- input2.once("error", (error62) => {
81845
- if (open6) {
81846
- open6 = false;
81847
- controller.error(error62);
81848
- }
81849
- });
81850
- },
81851
- cancel() {
81852
- open6 = false;
81853
- }
81854
- });
81855
- }
81856
- function writableAcpStream(output2) {
81857
- return new WritableStream({
81858
- write(chunk) {
81859
- return new Promise((resolveWrite, rejectWrite) => {
81860
- output2.write(chunk, (error62) => {
81861
- if (error62) {
81862
- rejectWrite(error62);
81863
- return;
81864
- }
81865
- resolveWrite();
81866
- });
81867
- });
81675
+ function filterEnvironment(environment) {
81676
+ const filtered = {};
81677
+ for (const [name2, value] of Object.entries(environment)) {
81678
+ if (typeof value === "string") {
81679
+ filtered[name2] = value;
81868
81680
  }
81869
- });
81681
+ }
81682
+ return filtered;
81870
81683
  }
81871
- async function probeInProcessReadiness(specification, agent, environment, defaultWorkspace, controller) {
81872
- const handler = new DiscoveryAcpHandler();
81873
- const inProcess = agent.createEndpoint({
81874
- command: agent.command,
81875
- cwd: defaultWorkspace,
81876
- environment: { ...filterEnvironment(environment), ...agent.environment },
81877
- onSessionUpdate: handler.onUpdate
81878
- });
81684
+ async function probeAcpReadiness(specification, agent, environment, defaultWorkspace, signal) {
81685
+ signal.throwIfAborted();
81686
+ const controller = new AbortController();
81687
+ let timedOut = false;
81688
+ const timeout = setTimeout(() => {
81689
+ timedOut = true;
81690
+ controller.abort(new Error("ACP probe timed out"));
81691
+ }, specification.acpProbeTimeoutMilliseconds);
81692
+ const abort = () => controller.abort(signal.reason);
81693
+ signal.addEventListener("abort", abort, { once: true });
81694
+ if (signal.aborted) {
81695
+ abort();
81696
+ }
81879
81697
  try {
81880
- const connection = createAcpClient(handler).connect(inProcess.app());
81698
+ const runtime = agent.withEnvironment({ ...filterEnvironment(environment), ...agent.environment }).createConnection({
81699
+ cwd: defaultWorkspace,
81700
+ client: new DiscoveryAcpHandler()
81701
+ });
81881
81702
  try {
81882
- return await Promise.race([
81703
+ return await runtime.race(
81883
81704
  (async () => {
81884
- await inProcess.initialize(controller.signal);
81885
- const initialized = await connection.agent.request(
81705
+ await runtime.initialize(controller.signal);
81706
+ const initialized = await runtime.connection.agent.request(
81886
81707
  methods12.agent.initialize,
81887
81708
  {
81888
81709
  clientCapabilities: {},
@@ -81897,148 +81718,33 @@ async function probeInProcessReadiness(specification, agent, environment, defaul
81897
81718
  "ACP agent selected an unsupported protocol version"
81898
81719
  );
81899
81720
  }
81900
- await specification.verifyAcp(connection, initialized, defaultWorkspace, controller.signal);
81721
+ await specification.verifyAcp(runtime.connection, initialized, defaultWorkspace, controller.signal);
81901
81722
  return new VerifiedAcpReadiness(
81902
81723
  normalizeVersionOutput(initialized.agentInfo?.version ?? ""),
81903
81724
  normalizeAcpCapabilities(initialized)
81904
81725
  );
81905
81726
  })(),
81906
- inProcess.terminated.then((termination) => {
81907
- throw new AgentProbeError("acp_incompatible", "The ACP endpoint stopped during initialization", {
81908
- cause: acpEndpointTerminationError(termination)
81909
- });
81910
- })
81911
- ]);
81912
- } finally {
81913
- connection.close();
81914
- }
81915
- } finally {
81916
- await inProcess.close();
81917
- }
81918
- }
81919
- function filterEnvironment(environment) {
81920
- const filtered = {};
81921
- for (const [name2, value] of Object.entries(environment)) {
81922
- if (typeof value === "string") {
81923
- filtered[name2] = value;
81924
- }
81925
- }
81926
- return filtered;
81927
- }
81928
- async function probeAcpReadiness(specification, agent, environment, defaultWorkspace, signal) {
81929
- signal.throwIfAborted();
81930
- const controller = new AbortController();
81931
- let timedOut = false;
81932
- const timeout = setTimeout(() => {
81933
- timedOut = true;
81934
- controller.abort(new Error("ACP probe timed out"));
81935
- }, specification.acpProbeTimeoutMilliseconds);
81936
- const abort = () => controller.abort(signal.reason);
81937
- signal.addEventListener("abort", abort, { once: true });
81938
- if (signal.aborted) {
81939
- abort();
81940
- }
81941
- if (agent.kind === "in-process-acp") {
81942
- try {
81943
- return await probeInProcessReadiness(specification, agent, environment, defaultWorkspace, controller);
81944
- } catch (error62) {
81945
- if (signal.aborted) {
81946
- signal.throwIfAborted();
81947
- }
81948
- if (timedOut) {
81949
- throw new AgentProbeError("adapter_probe_timeout", "ACP agent probe timed out", { cause: error62 });
81950
- }
81951
- if (error62 instanceof AgentProbeError) {
81952
- throw error62;
81953
- }
81954
- if (error62 instanceof RequestError9 && error62.code === -32e3 && specification.authenticationCommand().length > 0) {
81955
- throw new AgentProbeError("authentication_required", "Agent authentication is required", {
81956
- cause: error62
81957
- });
81958
- }
81959
- throw new AgentProbeError("acp_incompatible", "ACP agent initialization failed", { cause: error62 });
81727
+ "The ACP endpoint stopped during initialization",
81728
+ controller.signal
81729
+ );
81960
81730
  } finally {
81961
- clearTimeout(timeout);
81962
- signal.removeEventListener("abort", abort);
81963
- }
81964
- }
81965
- const launch = executableLaunch2(agent.adapterPath, agent.arguments);
81966
- const child = spawn7(launch.command, [...launch.arguments], {
81967
- cwd: defaultWorkspace,
81968
- ...platformSpawnOptions,
81969
- env: { ...environment, ...agent.environment },
81970
- shell: false,
81971
- stdio: ["pipe", "pipe", "pipe"]
81972
- });
81973
- const processExit = new Promise((_resolve, reject2) => {
81974
- const rejectExit = () => reject2(new Error("ACP adapter exited during initialization"));
81975
- child.once("error", reject2);
81976
- child.once("exit", rejectExit);
81977
- if (child.exitCode !== null || child.signalCode !== null) {
81978
- rejectExit();
81979
- }
81980
- });
81981
- const stdin = child.stdin;
81982
- const stdout = child.stdout;
81983
- const stderr = child.stderr;
81984
- if (stdin === null || stdout === null || stderr === null) {
81985
- await stopProcessTree(child);
81986
- throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
81987
- }
81988
- let stderrBytes = 0;
81989
- const consumeStderr = (chunk) => {
81990
- stderrBytes += chunk.byteLength;
81991
- if (stderrBytes > ACP_OUTPUT_LIMIT_BYTES) {
81992
- controller.abort(new Error("ACP adapter output limit exceeded"));
81993
- }
81994
- };
81995
- stderr.on("data", consumeStderr);
81996
- const connection = createAcpClient(new DiscoveryAcpHandler()).connect(
81997
- ndJsonStream3(writableAcpStream(stdin), readableAcpStream(stdout))
81998
- );
81999
- try {
82000
- const initialized = await Promise.race([
82001
- connection.agent.request(
82002
- methods12.agent.initialize,
82003
- {
82004
- clientCapabilities: {},
82005
- clientInfo: { name: "mobius", version: "0.0.3" },
82006
- protocolVersion: PROTOCOL_VERSION3
82007
- },
82008
- { cancellationSignal: controller.signal }
82009
- ),
82010
- processExit
82011
- ]);
82012
- if (initialized.protocolVersion !== PROTOCOL_VERSION3) {
82013
- throw new AgentProbeError("acp_incompatible", "ACP adapter selected an unsupported protocol version");
81731
+ await runtime.closeProcess();
82014
81732
  }
82015
- await specification.verifyAcp(connection, initialized, defaultWorkspace, controller.signal);
82016
- return new VerifiedAcpReadiness(
82017
- normalizeVersionOutput(initialized.agentInfo?.version ?? ""),
82018
- normalizeAcpCapabilities(initialized)
82019
- );
82020
81733
  } catch (error62) {
82021
- if (signal.aborted) {
82022
- signal.throwIfAborted();
82023
- }
81734
+ signal.throwIfAborted();
82024
81735
  if (timedOut) {
82025
- throw new AgentProbeError("adapter_probe_timeout", "ACP adapter probe timed out", { cause: error62 });
81736
+ throw new AgentProbeError("adapter_probe_timeout", "ACP agent probe timed out", { cause: error62 });
82026
81737
  }
82027
81738
  if (error62 instanceof AgentProbeError) {
82028
81739
  throw error62;
82029
81740
  }
82030
- if (error62 instanceof RequestError9 && error62.code === -32e3 && specification.authenticationCommand().length > 0) {
81741
+ if (error62 instanceof AcpExecutionError && error62.code === "authentication_required" && specification.authenticationCommand().length > 0) {
82031
81742
  throw new AgentProbeError("authentication_required", "Agent authentication is required", { cause: error62 });
82032
81743
  }
82033
- throw new AgentProbeError("acp_incompatible", "ACP adapter initialization failed", { cause: error62 });
81744
+ throw new AgentProbeError("acp_incompatible", "ACP agent initialization failed", { cause: error62 });
82034
81745
  } finally {
82035
81746
  clearTimeout(timeout);
82036
81747
  signal.removeEventListener("abort", abort);
82037
- const capturedProcesses = await captureProcessTree(child);
82038
- connection.close();
82039
- stdin.end();
82040
- stderr.removeListener("data", consumeStderr);
82041
- await stopProcessTree(child, capturedProcesses);
82042
81748
  }
82043
81749
  }
82044
81750
 
@@ -82133,10 +81839,7 @@ async function resolveAgentExecutables(specification, context) {
82133
81839
  );
82134
81840
  }
82135
81841
  async function resolveAdapterExecutables(specification, context) {
82136
- if (specification instanceof DirectAcpAgentSpecification || specification instanceof InProcessAcpAgentSpecification) {
82137
- return await resolveAgentExecutables(specification, context);
82138
- }
82139
- throw new Error("Unsupported local Agent execution topology");
81842
+ return await resolveAgentExecutables(specification, context);
82140
81843
  }
82141
81844
  async function probeVersion(executable, arguments_, environment, defaultWorkspace, signal, timeoutMilliseconds, normalize4 = normalizeVersionOutput) {
82142
81845
  const result = await runBoundedProcess({
@@ -82250,7 +81953,7 @@ async function discoverAgent(specification, context) {
82250
81953
  return new MissingAdapter(specification);
82251
81954
  }
82252
81955
  for (const adapter of adapters) {
82253
- if (specification instanceof DirectAcpAgentSpecification && adapter.path !== agent.path) {
81956
+ if (adapter.path !== agent.path) {
82254
81957
  continue;
82255
81958
  }
82256
81959
  let adapterVersion = "";
@@ -82281,26 +81984,16 @@ async function discoverAgent(specification, context) {
82281
81984
  lastFailure = integrationProbeFailure(specification, error62);
82282
81985
  continue;
82283
81986
  }
82284
- const buildDefinition = (verifiedAdapterVersion, capabilities) => specification instanceof InProcessAcpAgentSpecification ? new InProcessAcpAgentDefinition(
81987
+ const buildDefinition = (verifiedAdapterVersion, capabilities) => new AcpAgentDefinition(
82285
81988
  specification.id,
82286
81989
  specification.label,
82287
81990
  agent.path,
82288
- specification.createEndpoint,
81991
+ specification.createConnection,
82289
81992
  launchEnvironment,
82290
81993
  agentVersion.length > 0 ? agentVersion : verifiedAdapterVersion,
82291
81994
  agent.identity,
82292
- capabilities
82293
- ) : new LocalAgentDefinition(
82294
- specification.id,
82295
- specification.label,
82296
- adapter.path,
82297
- specification.launchArguments,
82298
- launchEnvironment,
82299
- verifiedAdapterVersion,
82300
- agentVersion,
82301
- adapter.identity,
82302
- agent.identity,
82303
- capabilities
81995
+ capabilities,
81996
+ specification instanceof InProcessAcpAgentSpecification ? agentVersion : verifiedAdapterVersion
82304
81997
  );
82305
81998
  try {
82306
81999
  const readiness = await probeWithRetry(
@@ -82688,11 +82381,14 @@ function createCatalogAgentResolver(discover, readConfig, publish) {
82688
82381
  };
82689
82382
  }
82690
82383
  async function unchangedIdentity(agent, signal) {
82691
- if (!await revalidateExecutable(agent.agentIdentity)) {
82692
- return false;
82384
+ for (const identity2 of agent.runtimeExecutables) {
82385
+ signal.throwIfAborted();
82386
+ if (!await revalidateExecutable(identity2)) {
82387
+ return false;
82388
+ }
82693
82389
  }
82694
82390
  signal.throwIfAborted();
82695
- return agent.kind !== "acp-adapter-process" || await revalidateExecutable(agent.adapterIdentity);
82391
+ return true;
82696
82392
  }
82697
82393
 
82698
82394
  // src/runtime/connection/runtime-installation-store.ts
@@ -87386,7 +87082,8 @@ var SessionTurns = class {
87386
87082
  queued.push({
87387
87083
  commandId: candidate.command.commandId,
87388
87084
  prompt: candidate.command.prompt,
87389
- images: candidate.command.images
87085
+ images: candidate.command.images,
87086
+ resources: candidate.command.resources
87390
87087
  });
87391
87088
  }
87392
87089
  return { turn: turnSnapshot ?? null, queued };
@@ -88979,7 +88676,7 @@ function settingsRevision(agent, reportedAgentVersion, settings, modelEffort) {
88979
88676
  };
88980
88677
  return createHash8("sha256").update(
88981
88678
  JSON.stringify({
88982
- adapterVersion: agent.kind === "acp-adapter-process" ? agent.adapterVersion : agent.agentVersion,
88679
+ adapterVersion: agent.adapterVersion,
88983
88680
  agentId: agent.id,
88984
88681
  agentVersion: agent.agentVersion,
88985
88682
  modelEffort: revisionModelEffort,
@@ -91735,8 +91432,8 @@ var MobiusRuntimeEngine = class {
91735
91432
  };
91736
91433
  };
91737
91434
  export {
91738
- InProcessAcpAgentDefinition,
91739
- LocalAgentDefinition,
91435
+ AcpAgentDefinition,
91436
+ EndpointAgentConnection,
91740
91437
  MobiusRuntimeConfigurationError,
91741
91438
  MobiusRuntimeEngine,
91742
91439
  OpaqueRuntimeReconnectTarget,