acpx 0.1.16 → 0.2.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -13
- package/dist/cli.js.map +1 -1
- package/dist/{output-render-C_rsjEYP.js → output-render-Cvz0eKSb.js} +2 -2
- package/dist/{output-render-C_rsjEYP.js.map → output-render-Cvz0eKSb.js.map} +1 -1
- package/dist/{queue-ipc-CEetz4_7.js → queue-ipc-C8StWiZt.js} +306 -254
- package/dist/queue-ipc-C8StWiZt.js.map +1 -0
- package/dist/{session-BARXiu6-.js → session-C6nyqSfk.js} +16 -15
- package/dist/session-C6nyqSfk.js.map +1 -0
- package/package.json +1 -4
- package/dist/queue-ipc-CEetz4_7.js.map +0 -1
- package/dist/session-BARXiu6-.js.map +0 -1
|
@@ -99,6 +99,150 @@ var PermissionPromptUnavailableError = class extends AcpxOperationalError {
|
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/prompt-content.ts
|
|
104
|
+
function asRecord$3(value) {
|
|
105
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
function isTextBlock(value) {
|
|
109
|
+
const record = asRecord$3(value);
|
|
110
|
+
return record?.type === "text" && typeof record.text === "string";
|
|
111
|
+
}
|
|
112
|
+
function isImageBlock(value) {
|
|
113
|
+
const record = asRecord$3(value);
|
|
114
|
+
return record?.type === "image" && typeof record.mimeType === "string" && typeof record.data === "string";
|
|
115
|
+
}
|
|
116
|
+
function isResourceLinkBlock(value) {
|
|
117
|
+
const record = asRecord$3(value);
|
|
118
|
+
return record?.type === "resource_link" && typeof record.uri === "string" && (record.title === void 0 || typeof record.title === "string") && (record.name === void 0 || typeof record.name === "string");
|
|
119
|
+
}
|
|
120
|
+
function isResourcePayload(value) {
|
|
121
|
+
const record = asRecord$3(value);
|
|
122
|
+
if (!record || typeof record.uri !== "string") return false;
|
|
123
|
+
return record.text === void 0 || typeof record.text === "string";
|
|
124
|
+
}
|
|
125
|
+
function isResourceBlock(value) {
|
|
126
|
+
const record = asRecord$3(value);
|
|
127
|
+
return record?.type === "resource" && isResourcePayload(record.resource);
|
|
128
|
+
}
|
|
129
|
+
function isContentBlock(value) {
|
|
130
|
+
return isTextBlock(value) || isImageBlock(value) || isResourceLinkBlock(value) || isResourceBlock(value);
|
|
131
|
+
}
|
|
132
|
+
function isPromptInput(value) {
|
|
133
|
+
return Array.isArray(value) && value.every((entry) => isContentBlock(entry));
|
|
134
|
+
}
|
|
135
|
+
function textPrompt(text) {
|
|
136
|
+
return [{
|
|
137
|
+
type: "text",
|
|
138
|
+
text
|
|
139
|
+
}];
|
|
140
|
+
}
|
|
141
|
+
function parseStructuredPrompt(source) {
|
|
142
|
+
if (!source.startsWith("[")) return;
|
|
143
|
+
try {
|
|
144
|
+
const parsed = JSON.parse(source);
|
|
145
|
+
return isPromptInput(parsed) ? parsed : void 0;
|
|
146
|
+
} catch {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function parsePromptSource(source) {
|
|
151
|
+
const trimmed = source.trim();
|
|
152
|
+
const structured = parseStructuredPrompt(trimmed);
|
|
153
|
+
if (structured) return structured;
|
|
154
|
+
if (!trimmed) return [];
|
|
155
|
+
return textPrompt(trimmed);
|
|
156
|
+
}
|
|
157
|
+
function mergePromptSourceWithText(source, suffixText) {
|
|
158
|
+
const prompt = parsePromptSource(source);
|
|
159
|
+
const appended = suffixText.trim();
|
|
160
|
+
if (!appended) return prompt;
|
|
161
|
+
if (prompt.length === 0) return textPrompt(appended);
|
|
162
|
+
return [...prompt, ...textPrompt(appended)];
|
|
163
|
+
}
|
|
164
|
+
function promptToDisplayText(prompt) {
|
|
165
|
+
return prompt.map((block) => {
|
|
166
|
+
switch (block.type) {
|
|
167
|
+
case "text": return block.text;
|
|
168
|
+
case "resource_link": return block.title ?? block.name ?? block.uri;
|
|
169
|
+
case "resource": return "text" in block.resource && typeof block.resource.text === "string" ? block.resource.text : block.resource.uri;
|
|
170
|
+
case "image": return `[image] ${block.mimeType}`;
|
|
171
|
+
default: return "";
|
|
172
|
+
}
|
|
173
|
+
}).filter((entry) => entry.trim().length > 0).join("\n\n").trim();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/acp-error-shapes.ts
|
|
178
|
+
const RESOURCE_NOT_FOUND_ACP_CODES = new Set([-32001, -32002]);
|
|
179
|
+
function asRecord$2(value) {
|
|
180
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
183
|
+
function toAcpErrorPayload(value) {
|
|
184
|
+
const record = asRecord$2(value);
|
|
185
|
+
if (!record) return;
|
|
186
|
+
if (typeof record.code !== "number" || !Number.isFinite(record.code)) return;
|
|
187
|
+
if (typeof record.message !== "string" || record.message.length === 0) return;
|
|
188
|
+
return {
|
|
189
|
+
code: record.code,
|
|
190
|
+
message: record.message,
|
|
191
|
+
data: record.data
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function extractAcpErrorInternal(value, depth) {
|
|
195
|
+
if (depth > 5) return;
|
|
196
|
+
const direct = toAcpErrorPayload(value);
|
|
197
|
+
if (direct) return direct;
|
|
198
|
+
const record = asRecord$2(value);
|
|
199
|
+
if (!record) return;
|
|
200
|
+
if ("error" in record) {
|
|
201
|
+
const nested = extractAcpErrorInternal(record.error, depth + 1);
|
|
202
|
+
if (nested) return nested;
|
|
203
|
+
}
|
|
204
|
+
if ("cause" in record) {
|
|
205
|
+
const nested = extractAcpErrorInternal(record.cause, depth + 1);
|
|
206
|
+
if (nested) return nested;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function formatUnknownErrorMessage(error) {
|
|
210
|
+
if (error instanceof Error) return error.message;
|
|
211
|
+
if (error && typeof error === "object") {
|
|
212
|
+
const maybeMessage = error.message;
|
|
213
|
+
if (typeof maybeMessage === "string" && maybeMessage.length > 0) return maybeMessage;
|
|
214
|
+
try {
|
|
215
|
+
return JSON.stringify(error);
|
|
216
|
+
} catch {}
|
|
217
|
+
}
|
|
218
|
+
return String(error);
|
|
219
|
+
}
|
|
220
|
+
function isSessionNotFoundText(value) {
|
|
221
|
+
if (typeof value !== "string") return false;
|
|
222
|
+
const normalized = value.toLowerCase();
|
|
223
|
+
return normalized.includes("resource_not_found") || normalized.includes("resource not found") || normalized.includes("session not found") || normalized.includes("unknown session") || normalized.includes("invalid session identifier");
|
|
224
|
+
}
|
|
225
|
+
function hasSessionNotFoundHint(value, depth = 0) {
|
|
226
|
+
if (depth > 4) return false;
|
|
227
|
+
if (isSessionNotFoundText(value)) return true;
|
|
228
|
+
if (Array.isArray(value)) return value.some((entry) => hasSessionNotFoundHint(entry, depth + 1));
|
|
229
|
+
const record = asRecord$2(value);
|
|
230
|
+
if (!record) return false;
|
|
231
|
+
return Object.values(record).some((entry) => hasSessionNotFoundHint(entry, depth + 1));
|
|
232
|
+
}
|
|
233
|
+
function extractAcpError(error) {
|
|
234
|
+
return extractAcpErrorInternal(error, 0);
|
|
235
|
+
}
|
|
236
|
+
function isAcpResourceNotFoundError(error) {
|
|
237
|
+
const acp = extractAcpError(error);
|
|
238
|
+
if (acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code)) return true;
|
|
239
|
+
if (acp) {
|
|
240
|
+
if (isSessionNotFoundText(acp.message)) return true;
|
|
241
|
+
if (hasSessionNotFoundHint(acp.data)) return true;
|
|
242
|
+
}
|
|
243
|
+
return isSessionNotFoundText(formatUnknownErrorMessage(error));
|
|
244
|
+
}
|
|
245
|
+
|
|
102
246
|
//#endregion
|
|
103
247
|
//#region src/types.ts
|
|
104
248
|
const EXIT_CODES = {
|
|
@@ -135,7 +279,6 @@ const SESSION_RECORD_SCHEMA = "acpx.session.v1";
|
|
|
135
279
|
|
|
136
280
|
//#endregion
|
|
137
281
|
//#region src/error-normalization.ts
|
|
138
|
-
const RESOURCE_NOT_FOUND_ACP_CODES = new Set([-32002]);
|
|
139
282
|
const AUTH_REQUIRED_ACP_CODES = new Set([-32e3]);
|
|
140
283
|
const QUERY_CLOSED_BEFORE_RESPONSE_DETAIL = "query closed before response received";
|
|
141
284
|
function asRecord$1(value) {
|
|
@@ -174,35 +317,9 @@ function readOutputErrorMeta(error) {
|
|
|
174
317
|
detailCode: typeof record.detailCode === "string" && record.detailCode.trim().length > 0 ? record.detailCode : void 0,
|
|
175
318
|
origin: isOutputErrorOrigin$1(record.origin) ? record.origin : void 0,
|
|
176
319
|
retryable: typeof record.retryable === "boolean" ? record.retryable : void 0,
|
|
177
|
-
acp:
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
function toAcpErrorPayload(value) {
|
|
181
|
-
const record = asRecord$1(value);
|
|
182
|
-
if (!record) return;
|
|
183
|
-
if (typeof record.code !== "number" || !Number.isFinite(record.code)) return;
|
|
184
|
-
if (typeof record.message !== "string" || record.message.length === 0) return;
|
|
185
|
-
return {
|
|
186
|
-
code: record.code,
|
|
187
|
-
message: record.message,
|
|
188
|
-
data: record.data
|
|
320
|
+
acp: extractAcpError(record.acp)
|
|
189
321
|
};
|
|
190
322
|
}
|
|
191
|
-
function extractAcpErrorInternal(value, depth) {
|
|
192
|
-
if (depth > 5) return;
|
|
193
|
-
const direct = toAcpErrorPayload(value);
|
|
194
|
-
if (direct) return direct;
|
|
195
|
-
const record = asRecord$1(value);
|
|
196
|
-
if (!record) return;
|
|
197
|
-
if ("error" in record) {
|
|
198
|
-
const nested = extractAcpErrorInternal(record.error, depth + 1);
|
|
199
|
-
if (nested) return nested;
|
|
200
|
-
}
|
|
201
|
-
if ("cause" in record) {
|
|
202
|
-
const nested = extractAcpErrorInternal(record.cause, depth + 1);
|
|
203
|
-
if (nested) return nested;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
323
|
function isTimeoutLike(error) {
|
|
207
324
|
return error instanceof Error && error.name === "TimeoutError";
|
|
208
325
|
}
|
|
@@ -214,22 +331,7 @@ function isUsageLike(error) {
|
|
|
214
331
|
return error.name === "CommanderError" || error.name === "InvalidArgumentError" || asRecord$1(error)?.code === "commander.invalidArgument";
|
|
215
332
|
}
|
|
216
333
|
function formatErrorMessage(error) {
|
|
217
|
-
|
|
218
|
-
if (error && typeof error === "object") {
|
|
219
|
-
const maybeMessage = error.message;
|
|
220
|
-
if (typeof maybeMessage === "string" && maybeMessage.length > 0) return maybeMessage;
|
|
221
|
-
try {
|
|
222
|
-
return JSON.stringify(error);
|
|
223
|
-
} catch {}
|
|
224
|
-
}
|
|
225
|
-
return String(error);
|
|
226
|
-
}
|
|
227
|
-
function extractAcpError(error) {
|
|
228
|
-
return extractAcpErrorInternal(error, 0);
|
|
229
|
-
}
|
|
230
|
-
function isAcpResourceNotFoundError(error) {
|
|
231
|
-
const acp = extractAcpError(error);
|
|
232
|
-
return Boolean(acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code));
|
|
334
|
+
return formatUnknownErrorMessage(error);
|
|
233
335
|
}
|
|
234
336
|
function isAcpQueryClosedBeforeResponseError(error) {
|
|
235
337
|
const acp = extractAcpError(error);
|
|
@@ -595,12 +697,14 @@ function parseQueueRequest(raw) {
|
|
|
595
697
|
if (request.type === "submit_prompt") {
|
|
596
698
|
const nonInteractivePermissions = request.nonInteractivePermissions == null ? void 0 : isNonInteractivePermissionPolicy(request.nonInteractivePermissions) ? request.nonInteractivePermissions : null;
|
|
597
699
|
const suppressSdkConsoleErrors = request.suppressSdkConsoleErrors == null ? void 0 : typeof request.suppressSdkConsoleErrors === "boolean" ? request.suppressSdkConsoleErrors : null;
|
|
598
|
-
|
|
700
|
+
const prompt = request.prompt == null ? void 0 : isPromptInput(request.prompt) ? request.prompt : null;
|
|
701
|
+
if (typeof request.message !== "string" || !isPermissionMode(request.permissionMode) || prompt === null || nonInteractivePermissions === null || suppressSdkConsoleErrors === null || typeof request.waitForCompletion !== "boolean") return null;
|
|
599
702
|
return {
|
|
600
703
|
type: "submit_prompt",
|
|
601
704
|
requestId: request.requestId,
|
|
602
705
|
ownerGeneration,
|
|
603
706
|
message: request.message,
|
|
707
|
+
prompt: prompt ?? textPrompt(request.message),
|
|
604
708
|
permissionMode: request.permissionMode,
|
|
605
709
|
nonInteractivePermissions,
|
|
606
710
|
timeoutMs,
|
|
@@ -862,6 +966,26 @@ var SessionQueueOwner = class SessionQueueOwner {
|
|
|
862
966
|
this.pending.push(task);
|
|
863
967
|
this.emitQueueDepth();
|
|
864
968
|
}
|
|
969
|
+
handleControlRequest(options) {
|
|
970
|
+
writeQueueMessage(options.socket, {
|
|
971
|
+
type: "accepted",
|
|
972
|
+
requestId: options.requestId,
|
|
973
|
+
ownerGeneration: this.ownerGeneration
|
|
974
|
+
});
|
|
975
|
+
options.run().then((message) => {
|
|
976
|
+
writeQueueMessage(options.socket, {
|
|
977
|
+
...message,
|
|
978
|
+
ownerGeneration: this.ownerGeneration
|
|
979
|
+
});
|
|
980
|
+
}).catch((error) => {
|
|
981
|
+
writeQueueMessage(options.socket, {
|
|
982
|
+
...makeQueueOwnerErrorFromUnknown(options.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
|
|
983
|
+
ownerGeneration: this.ownerGeneration
|
|
984
|
+
});
|
|
985
|
+
}).finally(() => {
|
|
986
|
+
if (!options.socket.destroyed) options.socket.end();
|
|
987
|
+
});
|
|
988
|
+
}
|
|
865
989
|
handleConnection(socket) {
|
|
866
990
|
socket.setEncoding("utf8");
|
|
867
991
|
if (this.closed) {
|
|
@@ -898,77 +1022,48 @@ var SessionQueueOwner = class SessionQueueOwner {
|
|
|
898
1022
|
return;
|
|
899
1023
|
}
|
|
900
1024
|
if (request.type === "cancel_prompt") {
|
|
901
|
-
|
|
902
|
-
|
|
1025
|
+
this.handleControlRequest({
|
|
1026
|
+
socket,
|
|
903
1027
|
requestId: request.requestId,
|
|
904
|
-
|
|
905
|
-
});
|
|
906
|
-
this.controlHandlers.cancelPrompt().then((cancelled) => {
|
|
907
|
-
writeQueueMessage(socket, {
|
|
1028
|
+
run: async () => ({
|
|
908
1029
|
type: "cancel_result",
|
|
909
1030
|
requestId: request.requestId,
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
});
|
|
913
|
-
}).catch((error) => {
|
|
914
|
-
writeQueueMessage(socket, {
|
|
915
|
-
...makeQueueOwnerErrorFromUnknown(request.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
|
|
916
|
-
ownerGeneration: this.ownerGeneration
|
|
917
|
-
});
|
|
918
|
-
}).finally(() => {
|
|
919
|
-
if (!socket.destroyed) socket.end();
|
|
1031
|
+
cancelled: await this.controlHandlers.cancelPrompt()
|
|
1032
|
+
})
|
|
920
1033
|
});
|
|
921
1034
|
return;
|
|
922
1035
|
}
|
|
923
1036
|
if (request.type === "set_mode") {
|
|
924
|
-
|
|
925
|
-
|
|
1037
|
+
this.handleControlRequest({
|
|
1038
|
+
socket,
|
|
926
1039
|
requestId: request.requestId,
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
});
|
|
936
|
-
}).catch((error) => {
|
|
937
|
-
writeQueueMessage(socket, {
|
|
938
|
-
...makeQueueOwnerErrorFromUnknown(request.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
|
|
939
|
-
ownerGeneration: this.ownerGeneration
|
|
940
|
-
});
|
|
941
|
-
}).finally(() => {
|
|
942
|
-
if (!socket.destroyed) socket.end();
|
|
1040
|
+
run: async () => {
|
|
1041
|
+
await this.controlHandlers.setSessionMode(request.modeId, request.timeoutMs);
|
|
1042
|
+
return {
|
|
1043
|
+
type: "set_mode_result",
|
|
1044
|
+
requestId: request.requestId,
|
|
1045
|
+
modeId: request.modeId
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
943
1048
|
});
|
|
944
1049
|
return;
|
|
945
1050
|
}
|
|
946
1051
|
if (request.type === "set_config_option") {
|
|
947
|
-
|
|
948
|
-
|
|
1052
|
+
this.handleControlRequest({
|
|
1053
|
+
socket,
|
|
949
1054
|
requestId: request.requestId,
|
|
950
|
-
|
|
951
|
-
});
|
|
952
|
-
this.controlHandlers.setSessionConfigOption(request.configId, request.value, request.timeoutMs).then((response) => {
|
|
953
|
-
writeQueueMessage(socket, {
|
|
1055
|
+
run: async () => ({
|
|
954
1056
|
type: "set_config_option_result",
|
|
955
1057
|
requestId: request.requestId,
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
});
|
|
959
|
-
}).catch((error) => {
|
|
960
|
-
writeQueueMessage(socket, {
|
|
961
|
-
...makeQueueOwnerErrorFromUnknown(request.requestId, error, "QUEUE_CONTROL_REQUEST_FAILED"),
|
|
962
|
-
ownerGeneration: this.ownerGeneration
|
|
963
|
-
});
|
|
964
|
-
}).finally(() => {
|
|
965
|
-
if (!socket.destroyed) socket.end();
|
|
1058
|
+
response: await this.controlHandlers.setSessionConfigOption(request.configId, request.value, request.timeoutMs)
|
|
1059
|
+
})
|
|
966
1060
|
});
|
|
967
1061
|
return;
|
|
968
1062
|
}
|
|
969
1063
|
const task = {
|
|
970
1064
|
requestId: request.requestId,
|
|
971
1065
|
message: request.message,
|
|
1066
|
+
prompt: request.prompt ?? textPrompt(request.message),
|
|
972
1067
|
permissionMode: request.permissionMode,
|
|
973
1068
|
nonInteractivePermissions: request.nonInteractivePermissions,
|
|
974
1069
|
timeoutMs: request.timeoutMs,
|
|
@@ -1115,27 +1210,38 @@ function assertOwnerGeneration(owner, message) {
|
|
|
1115
1210
|
});
|
|
1116
1211
|
return message;
|
|
1117
1212
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1213
|
+
function makeMalformedQueueMessageError() {
|
|
1214
|
+
return new QueueProtocolError("Queue owner sent malformed message", {
|
|
1215
|
+
detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
|
|
1216
|
+
origin: "queue",
|
|
1217
|
+
retryable: true
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
function parseQueueOwnerResponseLine(owner, requestId, line) {
|
|
1221
|
+
let parsed;
|
|
1222
|
+
try {
|
|
1223
|
+
parsed = JSON.parse(line);
|
|
1224
|
+
} catch {
|
|
1225
|
+
throw new QueueProtocolError("Queue owner sent invalid JSON payload", {
|
|
1226
|
+
detailCode: "QUEUE_PROTOCOL_INVALID_JSON",
|
|
1227
|
+
origin: "queue",
|
|
1228
|
+
retryable: true
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
const parsedMessage = parseQueueOwnerMessage(parsed);
|
|
1232
|
+
if (!parsedMessage) throw makeMalformedQueueMessageError();
|
|
1233
|
+
const message = assertOwnerGeneration(owner, parsedMessage);
|
|
1234
|
+
if (message.requestId !== requestId) throw makeMalformedQueueMessageError();
|
|
1235
|
+
return message;
|
|
1236
|
+
}
|
|
1237
|
+
async function runQueueOwnerRequest(options) {
|
|
1238
|
+
const socket = await connectToQueueOwner(options.owner);
|
|
1120
1239
|
if (!socket) return;
|
|
1121
1240
|
socket.setEncoding("utf8");
|
|
1122
|
-
const requestId = randomUUID();
|
|
1123
|
-
const request = {
|
|
1124
|
-
type: "submit_prompt",
|
|
1125
|
-
requestId,
|
|
1126
|
-
ownerGeneration: owner.ownerGeneration,
|
|
1127
|
-
message: options.message,
|
|
1128
|
-
permissionMode: options.permissionMode,
|
|
1129
|
-
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
1130
|
-
timeoutMs: options.timeoutMs,
|
|
1131
|
-
suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,
|
|
1132
|
-
waitForCompletion: options.waitForCompletion
|
|
1133
|
-
};
|
|
1134
|
-
options.outputFormatter.setContext({ sessionId: options.sessionId });
|
|
1135
1241
|
return await new Promise((resolve, reject) => {
|
|
1136
1242
|
let settled = false;
|
|
1137
|
-
let acknowledged = false;
|
|
1138
1243
|
let buffer = "";
|
|
1244
|
+
const state = { acknowledged: false };
|
|
1139
1245
|
const finishResolve = (result) => {
|
|
1140
1246
|
if (settled) return;
|
|
1141
1247
|
settled = true;
|
|
@@ -1150,46 +1256,73 @@ async function submitToQueueOwner(owner, options) {
|
|
|
1150
1256
|
if (!socket.destroyed) socket.destroy();
|
|
1151
1257
|
reject(error);
|
|
1152
1258
|
};
|
|
1259
|
+
const controls = {
|
|
1260
|
+
state,
|
|
1261
|
+
resolve: finishResolve,
|
|
1262
|
+
reject: finishReject
|
|
1263
|
+
};
|
|
1153
1264
|
const processLine = (line) => {
|
|
1154
|
-
let
|
|
1265
|
+
let message;
|
|
1155
1266
|
try {
|
|
1156
|
-
|
|
1157
|
-
} catch {
|
|
1158
|
-
finishReject(
|
|
1159
|
-
detailCode: "QUEUE_PROTOCOL_INVALID_JSON",
|
|
1160
|
-
origin: "queue",
|
|
1161
|
-
retryable: true
|
|
1162
|
-
}));
|
|
1163
|
-
return;
|
|
1164
|
-
}
|
|
1165
|
-
const parsedMessage = parseQueueOwnerMessage(parsed);
|
|
1166
|
-
if (!parsedMessage) {
|
|
1167
|
-
finishReject(new QueueProtocolError("Queue owner sent malformed message", {
|
|
1168
|
-
detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
|
|
1169
|
-
origin: "queue",
|
|
1170
|
-
retryable: true
|
|
1171
|
-
}));
|
|
1172
|
-
return;
|
|
1173
|
-
}
|
|
1174
|
-
const message = assertOwnerGeneration(owner, parsedMessage);
|
|
1175
|
-
if (message.requestId !== requestId) {
|
|
1176
|
-
finishReject(new QueueProtocolError("Queue owner sent malformed message", {
|
|
1177
|
-
detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
|
|
1178
|
-
origin: "queue",
|
|
1179
|
-
retryable: true
|
|
1180
|
-
}));
|
|
1267
|
+
message = parseQueueOwnerResponseLine(options.owner, options.request.requestId, line);
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
finishReject(error);
|
|
1181
1270
|
return;
|
|
1182
1271
|
}
|
|
1183
1272
|
if (message.type === "accepted") {
|
|
1184
|
-
acknowledged = true;
|
|
1185
|
-
options.
|
|
1186
|
-
if (!options.waitForCompletion) finishResolve({
|
|
1187
|
-
queued: true,
|
|
1188
|
-
sessionId: options.sessionId,
|
|
1189
|
-
requestId
|
|
1190
|
-
});
|
|
1273
|
+
state.acknowledged = true;
|
|
1274
|
+
options.onAccepted?.(controls);
|
|
1191
1275
|
return;
|
|
1192
1276
|
}
|
|
1277
|
+
options.onMessage(message, controls);
|
|
1278
|
+
};
|
|
1279
|
+
socket.on("data", (chunk) => {
|
|
1280
|
+
buffer += chunk;
|
|
1281
|
+
let index = buffer.indexOf("\n");
|
|
1282
|
+
while (index >= 0) {
|
|
1283
|
+
const line = buffer.slice(0, index).trim();
|
|
1284
|
+
buffer = buffer.slice(index + 1);
|
|
1285
|
+
if (line.length > 0) processLine(line);
|
|
1286
|
+
index = buffer.indexOf("\n");
|
|
1287
|
+
}
|
|
1288
|
+
});
|
|
1289
|
+
socket.once("error", (error) => {
|
|
1290
|
+
finishReject(error);
|
|
1291
|
+
});
|
|
1292
|
+
socket.once("close", () => {
|
|
1293
|
+
if (settled) return;
|
|
1294
|
+
options.onClose(controls);
|
|
1295
|
+
});
|
|
1296
|
+
socket.write(`${JSON.stringify(options.request)}\n`);
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
async function submitToQueueOwner(owner, options) {
|
|
1300
|
+
const requestId = randomUUID();
|
|
1301
|
+
const request = {
|
|
1302
|
+
type: "submit_prompt",
|
|
1303
|
+
requestId,
|
|
1304
|
+
ownerGeneration: owner.ownerGeneration,
|
|
1305
|
+
message: options.message,
|
|
1306
|
+
prompt: options.prompt,
|
|
1307
|
+
permissionMode: options.permissionMode,
|
|
1308
|
+
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
1309
|
+
timeoutMs: options.timeoutMs,
|
|
1310
|
+
suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,
|
|
1311
|
+
waitForCompletion: options.waitForCompletion
|
|
1312
|
+
};
|
|
1313
|
+
options.outputFormatter.setContext({ sessionId: options.sessionId });
|
|
1314
|
+
return await runQueueOwnerRequest({
|
|
1315
|
+
owner,
|
|
1316
|
+
request,
|
|
1317
|
+
onAccepted: ({ resolve }) => {
|
|
1318
|
+
options.outputFormatter.setContext({ sessionId: options.sessionId });
|
|
1319
|
+
if (!options.waitForCompletion) resolve({
|
|
1320
|
+
queued: true,
|
|
1321
|
+
sessionId: options.sessionId,
|
|
1322
|
+
requestId
|
|
1323
|
+
});
|
|
1324
|
+
},
|
|
1325
|
+
onMessage: (message, { state, resolve, reject }) => {
|
|
1193
1326
|
if (message.type === "error") {
|
|
1194
1327
|
options.outputFormatter.setContext({ sessionId: options.sessionId });
|
|
1195
1328
|
const queueErrorAlreadyEmitted = options.errorEmissionPolicy?.queueErrorAlreadyEmitted ?? true;
|
|
@@ -1204,7 +1337,7 @@ async function submitToQueueOwner(owner, options) {
|
|
|
1204
1337
|
});
|
|
1205
1338
|
options.outputFormatter.flush();
|
|
1206
1339
|
}
|
|
1207
|
-
|
|
1340
|
+
reject(new QueueConnectionError(message.message, {
|
|
1208
1341
|
outputCode: message.code,
|
|
1209
1342
|
detailCode: message.detailCode,
|
|
1210
1343
|
origin: message.origin ?? "queue",
|
|
@@ -1214,8 +1347,8 @@ async function submitToQueueOwner(owner, options) {
|
|
|
1214
1347
|
}));
|
|
1215
1348
|
return;
|
|
1216
1349
|
}
|
|
1217
|
-
if (!acknowledged) {
|
|
1218
|
-
|
|
1350
|
+
if (!state.acknowledged) {
|
|
1351
|
+
reject(new QueueConnectionError("Queue owner did not acknowledge request", {
|
|
1219
1352
|
detailCode: "QUEUE_ACK_MISSING",
|
|
1220
1353
|
origin: "queue",
|
|
1221
1354
|
retryable: true
|
|
@@ -1228,32 +1361,18 @@ async function submitToQueueOwner(owner, options) {
|
|
|
1228
1361
|
}
|
|
1229
1362
|
if (message.type === "result") {
|
|
1230
1363
|
options.outputFormatter.flush();
|
|
1231
|
-
|
|
1364
|
+
resolve(message.result);
|
|
1232
1365
|
return;
|
|
1233
1366
|
}
|
|
1234
|
-
|
|
1367
|
+
reject(new QueueProtocolError("Queue owner returned unexpected response", {
|
|
1235
1368
|
detailCode: "QUEUE_PROTOCOL_UNEXPECTED_RESPONSE",
|
|
1236
1369
|
origin: "queue",
|
|
1237
1370
|
retryable: true
|
|
1238
1371
|
}));
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
while (index >= 0) {
|
|
1244
|
-
const line = buffer.slice(0, index).trim();
|
|
1245
|
-
buffer = buffer.slice(index + 1);
|
|
1246
|
-
if (line.length > 0) processLine(line);
|
|
1247
|
-
index = buffer.indexOf("\n");
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
1250
|
-
socket.once("error", (error) => {
|
|
1251
|
-
finishReject(error);
|
|
1252
|
-
});
|
|
1253
|
-
socket.once("close", () => {
|
|
1254
|
-
if (settled) return;
|
|
1255
|
-
if (!acknowledged) {
|
|
1256
|
-
finishReject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
|
|
1372
|
+
},
|
|
1373
|
+
onClose: ({ state, resolve, reject }) => {
|
|
1374
|
+
if (!state.acknowledged) {
|
|
1375
|
+
reject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
|
|
1257
1376
|
detailCode: "QUEUE_DISCONNECTED_BEFORE_ACK",
|
|
1258
1377
|
origin: "queue",
|
|
1259
1378
|
retryable: true
|
|
@@ -1261,80 +1380,28 @@ async function submitToQueueOwner(owner, options) {
|
|
|
1261
1380
|
return;
|
|
1262
1381
|
}
|
|
1263
1382
|
if (!options.waitForCompletion) {
|
|
1264
|
-
|
|
1383
|
+
resolve({
|
|
1265
1384
|
queued: true,
|
|
1266
1385
|
sessionId: options.sessionId,
|
|
1267
1386
|
requestId
|
|
1268
1387
|
});
|
|
1269
1388
|
return;
|
|
1270
1389
|
}
|
|
1271
|
-
|
|
1390
|
+
reject(new QueueConnectionError("Queue owner disconnected before prompt completion", {
|
|
1272
1391
|
detailCode: "QUEUE_DISCONNECTED_BEFORE_COMPLETION",
|
|
1273
1392
|
origin: "queue",
|
|
1274
1393
|
retryable: true
|
|
1275
1394
|
}));
|
|
1276
|
-
}
|
|
1277
|
-
socket.write(`${JSON.stringify(request)}\n`);
|
|
1395
|
+
}
|
|
1278
1396
|
});
|
|
1279
1397
|
}
|
|
1280
1398
|
async function submitControlToQueueOwner(owner, request, isExpectedResponse) {
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
let settled = false;
|
|
1286
|
-
let acknowledged = false;
|
|
1287
|
-
let buffer = "";
|
|
1288
|
-
const finishResolve = (result) => {
|
|
1289
|
-
if (settled) return;
|
|
1290
|
-
settled = true;
|
|
1291
|
-
socket.removeAllListeners();
|
|
1292
|
-
if (!socket.destroyed) socket.end();
|
|
1293
|
-
resolve(result);
|
|
1294
|
-
};
|
|
1295
|
-
const finishReject = (error) => {
|
|
1296
|
-
if (settled) return;
|
|
1297
|
-
settled = true;
|
|
1298
|
-
socket.removeAllListeners();
|
|
1299
|
-
if (!socket.destroyed) socket.destroy();
|
|
1300
|
-
reject(error);
|
|
1301
|
-
};
|
|
1302
|
-
const processLine = (line) => {
|
|
1303
|
-
let parsed;
|
|
1304
|
-
try {
|
|
1305
|
-
parsed = JSON.parse(line);
|
|
1306
|
-
} catch {
|
|
1307
|
-
finishReject(new QueueProtocolError("Queue owner sent invalid JSON payload", {
|
|
1308
|
-
detailCode: "QUEUE_PROTOCOL_INVALID_JSON",
|
|
1309
|
-
origin: "queue",
|
|
1310
|
-
retryable: true
|
|
1311
|
-
}));
|
|
1312
|
-
return;
|
|
1313
|
-
}
|
|
1314
|
-
const parsedMessage = parseQueueOwnerMessage(parsed);
|
|
1315
|
-
if (!parsedMessage) {
|
|
1316
|
-
finishReject(new QueueProtocolError("Queue owner sent malformed message", {
|
|
1317
|
-
detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
|
|
1318
|
-
origin: "queue",
|
|
1319
|
-
retryable: true
|
|
1320
|
-
}));
|
|
1321
|
-
return;
|
|
1322
|
-
}
|
|
1323
|
-
const message = assertOwnerGeneration(owner, parsedMessage);
|
|
1324
|
-
if (message.requestId !== request.requestId) {
|
|
1325
|
-
finishReject(new QueueProtocolError("Queue owner sent malformed message", {
|
|
1326
|
-
detailCode: "QUEUE_PROTOCOL_MALFORMED_MESSAGE",
|
|
1327
|
-
origin: "queue",
|
|
1328
|
-
retryable: true
|
|
1329
|
-
}));
|
|
1330
|
-
return;
|
|
1331
|
-
}
|
|
1332
|
-
if (message.type === "accepted") {
|
|
1333
|
-
acknowledged = true;
|
|
1334
|
-
return;
|
|
1335
|
-
}
|
|
1399
|
+
return await runQueueOwnerRequest({
|
|
1400
|
+
owner,
|
|
1401
|
+
request,
|
|
1402
|
+
onMessage: (message, { state, resolve, reject }) => {
|
|
1336
1403
|
if (message.type === "error") {
|
|
1337
|
-
|
|
1404
|
+
reject(new QueueConnectionError(message.message, {
|
|
1338
1405
|
outputCode: message.code,
|
|
1339
1406
|
detailCode: message.detailCode,
|
|
1340
1407
|
origin: message.origin ?? "queue",
|
|
@@ -1343,8 +1410,8 @@ async function submitControlToQueueOwner(owner, request, isExpectedResponse) {
|
|
|
1343
1410
|
}));
|
|
1344
1411
|
return;
|
|
1345
1412
|
}
|
|
1346
|
-
if (!acknowledged) {
|
|
1347
|
-
|
|
1413
|
+
if (!state.acknowledged) {
|
|
1414
|
+
reject(new QueueConnectionError("Queue owner did not acknowledge request", {
|
|
1348
1415
|
detailCode: "QUEUE_ACK_MISSING",
|
|
1349
1416
|
origin: "queue",
|
|
1350
1417
|
retryable: true
|
|
@@ -1352,45 +1419,30 @@ async function submitControlToQueueOwner(owner, request, isExpectedResponse) {
|
|
|
1352
1419
|
return;
|
|
1353
1420
|
}
|
|
1354
1421
|
if (!isExpectedResponse(message)) {
|
|
1355
|
-
|
|
1422
|
+
reject(new QueueProtocolError("Queue owner returned unexpected response", {
|
|
1356
1423
|
detailCode: "QUEUE_PROTOCOL_UNEXPECTED_RESPONSE",
|
|
1357
1424
|
origin: "queue",
|
|
1358
1425
|
retryable: true
|
|
1359
1426
|
}));
|
|
1360
1427
|
return;
|
|
1361
1428
|
}
|
|
1362
|
-
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
while (index >= 0) {
|
|
1368
|
-
const line = buffer.slice(0, index).trim();
|
|
1369
|
-
buffer = buffer.slice(index + 1);
|
|
1370
|
-
if (line.length > 0) processLine(line);
|
|
1371
|
-
index = buffer.indexOf("\n");
|
|
1372
|
-
}
|
|
1373
|
-
});
|
|
1374
|
-
socket.once("error", (error) => {
|
|
1375
|
-
finishReject(error);
|
|
1376
|
-
});
|
|
1377
|
-
socket.once("close", () => {
|
|
1378
|
-
if (settled) return;
|
|
1379
|
-
if (!acknowledged) {
|
|
1380
|
-
finishReject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
|
|
1429
|
+
resolve(message);
|
|
1430
|
+
},
|
|
1431
|
+
onClose: ({ state, reject }) => {
|
|
1432
|
+
if (!state.acknowledged) {
|
|
1433
|
+
reject(new QueueConnectionError("Queue owner disconnected before acknowledging request", {
|
|
1381
1434
|
detailCode: "QUEUE_DISCONNECTED_BEFORE_ACK",
|
|
1382
1435
|
origin: "queue",
|
|
1383
1436
|
retryable: true
|
|
1384
1437
|
}));
|
|
1385
1438
|
return;
|
|
1386
1439
|
}
|
|
1387
|
-
|
|
1440
|
+
reject(new QueueConnectionError("Queue owner disconnected before responding", {
|
|
1388
1441
|
detailCode: "QUEUE_DISCONNECTED_BEFORE_COMPLETION",
|
|
1389
1442
|
origin: "queue",
|
|
1390
1443
|
retryable: true
|
|
1391
1444
|
}));
|
|
1392
|
-
}
|
|
1393
|
-
socket.write(`${JSON.stringify(request)}\n`);
|
|
1445
|
+
}
|
|
1394
1446
|
});
|
|
1395
1447
|
}
|
|
1396
1448
|
async function submitCancelToQueueOwner(owner) {
|
|
@@ -1515,5 +1567,5 @@ async function trySetConfigOptionOnRunningOwner(sessionId, configId, value, time
|
|
|
1515
1567
|
}
|
|
1516
1568
|
|
|
1517
1569
|
//#endregion
|
|
1518
|
-
export {
|
|
1519
|
-
//# sourceMappingURL=queue-ipc-
|
|
1570
|
+
export { OUTPUT_FORMATS as A, ClaudeAcpSessionCreateTimeoutError as B, exitCodeForOutputErrorCode as C, AUTH_POLICIES as D, normalizeOutputError as E, parsePromptSource as F, QueueConnectionError as G, GeminiAcpStartupTimeoutError as H, promptToDisplayText as I, SessionResolutionError as J, SessionModeReplayError as K, textPrompt as L, extractAcpError as M, isAcpResourceNotFoundError as N, EXIT_CODES as O, mergePromptSourceWithText as P, AgentSpawnError as R, startPerfTimer as S, isAcpQueryClosedBeforeResponseError as T, PermissionDeniedError as U, CopilotAcpUnsupportedError as V, PermissionPromptUnavailableError as W, getPerfMetricsSnapshot as _, trySetConfigOptionOnRunningOwner as a, resetPerfMetrics as b, SessionQueueOwner as c, releaseQueueOwnerLease as d, terminateProcess as f, formatPerfMetric as g, waitMs as h, tryCancelOnRunningOwner as i, SESSION_RECORD_SCHEMA as j, NON_INTERACTIVE_PERMISSION_POLICIES as k, isProcessAlive as l, tryAcquireQueueOwnerLease as m, probeQueueOwnerHealth as n, trySetModeOnRunningOwner as o, terminateQueueOwnerForSession as p, SessionNotFoundError as q, queue_ipc_exports as r, trySubmitToRunningOwner as s, QUEUE_CONNECT_RETRY_MS as t, refreshQueueOwnerLease as u, incrementPerfCounter as v, formatErrorMessage as w, setPerfGauge as x, measurePerf as y, AuthPolicyError as z };
|
|
1571
|
+
//# sourceMappingURL=queue-ipc-C8StWiZt.js.map
|