acpx 0.4.1 → 0.5.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/agent-registry-DGw0-3Tc.js +54 -0
- package/dist/agent-registry-DGw0-3Tc.js.map +1 -0
- package/dist/{cli-idpWyCOs.js → cli-CLRrs6eQ.js} +8 -12
- package/dist/cli-CLRrs6eQ.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1018 -1009
- package/dist/cli.js.map +1 -1
- package/dist/client-DLTWuu4w.d.ts +116 -0
- package/dist/client-DLTWuu4w.d.ts.map +1 -0
- package/dist/{flags-CCcX9fZj.js → flags-BmubjvOw.js} +5 -55
- package/dist/flags-BmubjvOw.js.map +1 -0
- package/dist/{flows-BL1tSvZT.js → flows-CR7xCmkR.js} +471 -281
- package/dist/flows-CR7xCmkR.js.map +1 -0
- package/dist/flows.d.ts +5 -9
- package/dist/flows.d.ts.map +1 -1
- package/dist/flows.js +1 -1
- package/dist/{queue-ipc-CE8_QGX3.js → ipc-DN6M4Ui9.js} +12 -571
- package/dist/ipc-DN6M4Ui9.js.map +1 -0
- package/dist/{acp-jsonrpc-BbBgC5gO.js → jsonrpc-M3y-qzy8.js} +2 -2
- package/dist/jsonrpc-M3y-qzy8.js.map +1 -0
- package/dist/{output-Du3m6oPQ.js → output-Di0M9Et8.js} +6 -6
- package/dist/output-Di0M9Et8.js.map +1 -0
- package/dist/perf-metrics-D9QC81lB.js +568 -0
- package/dist/perf-metrics-D9QC81lB.js.map +1 -0
- package/dist/{session-RO_LZUnv.js → prompt-turn-Bt8T3SRR.js} +2304 -3632
- package/dist/prompt-turn-Bt8T3SRR.js.map +1 -0
- package/dist/{output-render-Bz58qaQn.js → render-BL5ynRkN.js} +7 -6
- package/dist/render-BL5ynRkN.js.map +1 -0
- package/dist/runtime.d.ts +266 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +984 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session-BbN0SBgf.js +1488 -0
- package/dist/session-BbN0SBgf.js.map +1 -0
- package/dist/{types-CeRKmEQ1.d.ts → types-DXxLBQc3.d.ts} +40 -3
- package/dist/types-DXxLBQc3.d.ts.map +1 -0
- package/package.json +5 -3
- package/dist/acp-jsonrpc-BbBgC5gO.js.map +0 -1
- package/dist/cli-idpWyCOs.js.map +0 -1
- package/dist/flags-CCcX9fZj.js.map +0 -1
- package/dist/flows-BL1tSvZT.js.map +0 -1
- package/dist/output-Du3m6oPQ.js.map +0 -1
- package/dist/output-render-Bz58qaQn.js.map +0 -1
- package/dist/queue-ipc-CE8_QGX3.js.map +0 -1
- package/dist/session-RO_LZUnv.js.map +0 -1
- package/dist/types-CeRKmEQ1.d.ts.map +0 -1
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
var AcpxOperationalError = class extends Error {
|
|
3
|
+
outputCode;
|
|
4
|
+
detailCode;
|
|
5
|
+
origin;
|
|
6
|
+
retryable;
|
|
7
|
+
acp;
|
|
8
|
+
outputAlreadyEmitted;
|
|
9
|
+
constructor(message, options) {
|
|
10
|
+
super(message, options);
|
|
11
|
+
this.name = new.target.name;
|
|
12
|
+
this.outputCode = options?.outputCode;
|
|
13
|
+
this.detailCode = options?.detailCode;
|
|
14
|
+
this.origin = options?.origin;
|
|
15
|
+
this.retryable = options?.retryable;
|
|
16
|
+
this.acp = options?.acp;
|
|
17
|
+
this.outputAlreadyEmitted = options?.outputAlreadyEmitted;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var SessionNotFoundError = class extends AcpxOperationalError {
|
|
21
|
+
sessionId;
|
|
22
|
+
constructor(sessionId) {
|
|
23
|
+
super(`Session not found: ${sessionId}`);
|
|
24
|
+
this.sessionId = sessionId;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var SessionResolutionError = class extends AcpxOperationalError {};
|
|
28
|
+
var AgentSpawnError = class extends AcpxOperationalError {
|
|
29
|
+
agentCommand;
|
|
30
|
+
constructor(agentCommand, cause) {
|
|
31
|
+
super(`Failed to spawn agent command: ${agentCommand}`, { cause: cause instanceof Error ? cause : void 0 });
|
|
32
|
+
this.agentCommand = agentCommand;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var AgentDisconnectedError = class extends AcpxOperationalError {
|
|
36
|
+
reason;
|
|
37
|
+
exitCode;
|
|
38
|
+
signal;
|
|
39
|
+
constructor(reason, exitCode, signal, options) {
|
|
40
|
+
super(`ACP agent disconnected during request (${reason}, exit=${exitCode ?? "null"}, signal=${signal ?? "null"})`, {
|
|
41
|
+
outputCode: "RUNTIME",
|
|
42
|
+
detailCode: "AGENT_DISCONNECTED",
|
|
43
|
+
origin: "acp",
|
|
44
|
+
...options
|
|
45
|
+
});
|
|
46
|
+
this.reason = reason;
|
|
47
|
+
this.exitCode = exitCode;
|
|
48
|
+
this.signal = signal;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var SessionResumeRequiredError = class extends AcpxOperationalError {
|
|
52
|
+
constructor(message, options) {
|
|
53
|
+
super(message, {
|
|
54
|
+
outputCode: "RUNTIME",
|
|
55
|
+
detailCode: "SESSION_RESUME_REQUIRED",
|
|
56
|
+
origin: "acp",
|
|
57
|
+
retryable: true,
|
|
58
|
+
...options
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var GeminiAcpStartupTimeoutError = class extends AcpxOperationalError {
|
|
63
|
+
constructor(message, options) {
|
|
64
|
+
super(message, {
|
|
65
|
+
outputCode: "TIMEOUT",
|
|
66
|
+
detailCode: "GEMINI_ACP_STARTUP_TIMEOUT",
|
|
67
|
+
origin: "acp",
|
|
68
|
+
...options
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var SessionModeReplayError = class extends AcpxOperationalError {
|
|
73
|
+
constructor(message, options) {
|
|
74
|
+
super(message, {
|
|
75
|
+
outputCode: "RUNTIME",
|
|
76
|
+
detailCode: "SESSION_MODE_REPLAY_FAILED",
|
|
77
|
+
origin: "acp",
|
|
78
|
+
...options
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
var SessionModelReplayError = class extends AcpxOperationalError {
|
|
83
|
+
constructor(message, options) {
|
|
84
|
+
super(message, {
|
|
85
|
+
outputCode: "RUNTIME",
|
|
86
|
+
detailCode: "SESSION_MODEL_REPLAY_FAILED",
|
|
87
|
+
origin: "acp",
|
|
88
|
+
...options
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var ClaudeAcpSessionCreateTimeoutError = class extends AcpxOperationalError {
|
|
93
|
+
constructor(message, options) {
|
|
94
|
+
super(message, {
|
|
95
|
+
outputCode: "TIMEOUT",
|
|
96
|
+
detailCode: "CLAUDE_ACP_SESSION_CREATE_TIMEOUT",
|
|
97
|
+
origin: "acp",
|
|
98
|
+
...options
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
var CopilotAcpUnsupportedError = class extends AcpxOperationalError {
|
|
103
|
+
constructor(message, options) {
|
|
104
|
+
super(message, {
|
|
105
|
+
outputCode: "RUNTIME",
|
|
106
|
+
detailCode: "COPILOT_ACP_UNSUPPORTED",
|
|
107
|
+
origin: "acp",
|
|
108
|
+
...options
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
var AuthPolicyError = class extends AcpxOperationalError {
|
|
113
|
+
constructor(message, options) {
|
|
114
|
+
super(message, {
|
|
115
|
+
outputCode: "RUNTIME",
|
|
116
|
+
detailCode: "AUTH_REQUIRED",
|
|
117
|
+
origin: "acp",
|
|
118
|
+
...options
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var QueueConnectionError = class extends AcpxOperationalError {};
|
|
123
|
+
var QueueProtocolError = class extends AcpxOperationalError {};
|
|
124
|
+
var PermissionDeniedError = class extends AcpxOperationalError {};
|
|
125
|
+
var PermissionPromptUnavailableError = class extends AcpxOperationalError {
|
|
126
|
+
constructor() {
|
|
127
|
+
super("Permission prompt unavailable in non-interactive mode");
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/types.ts
|
|
132
|
+
const EXIT_CODES = {
|
|
133
|
+
SUCCESS: 0,
|
|
134
|
+
ERROR: 1,
|
|
135
|
+
USAGE: 2,
|
|
136
|
+
TIMEOUT: 3,
|
|
137
|
+
NO_SESSION: 4,
|
|
138
|
+
PERMISSION_DENIED: 5,
|
|
139
|
+
INTERRUPTED: 130
|
|
140
|
+
};
|
|
141
|
+
const OUTPUT_FORMATS = [
|
|
142
|
+
"text",
|
|
143
|
+
"json",
|
|
144
|
+
"quiet"
|
|
145
|
+
];
|
|
146
|
+
const PERMISSION_MODES = [
|
|
147
|
+
"approve-all",
|
|
148
|
+
"approve-reads",
|
|
149
|
+
"deny-all"
|
|
150
|
+
];
|
|
151
|
+
const AUTH_POLICIES = ["skip", "fail"];
|
|
152
|
+
const NON_INTERACTIVE_PERMISSION_POLICIES = ["deny", "fail"];
|
|
153
|
+
const OUTPUT_ERROR_CODES = [
|
|
154
|
+
"NO_SESSION",
|
|
155
|
+
"TIMEOUT",
|
|
156
|
+
"PERMISSION_DENIED",
|
|
157
|
+
"PERMISSION_PROMPT_UNAVAILABLE",
|
|
158
|
+
"RUNTIME",
|
|
159
|
+
"USAGE"
|
|
160
|
+
];
|
|
161
|
+
const OUTPUT_ERROR_ORIGINS = [
|
|
162
|
+
"cli",
|
|
163
|
+
"runtime",
|
|
164
|
+
"queue",
|
|
165
|
+
"acp"
|
|
166
|
+
];
|
|
167
|
+
const SESSION_RECORD_SCHEMA = "acpx.session.v1";
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/acp/error-shapes.ts
|
|
170
|
+
const RESOURCE_NOT_FOUND_ACP_CODES = new Set([-32001, -32002]);
|
|
171
|
+
function asRecord$2(value) {
|
|
172
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
173
|
+
return value;
|
|
174
|
+
}
|
|
175
|
+
function toAcpErrorPayload(value) {
|
|
176
|
+
const record = asRecord$2(value);
|
|
177
|
+
if (!record) return;
|
|
178
|
+
if (typeof record.code !== "number" || !Number.isFinite(record.code)) return;
|
|
179
|
+
if (typeof record.message !== "string" || record.message.length === 0) return;
|
|
180
|
+
return {
|
|
181
|
+
code: record.code,
|
|
182
|
+
message: record.message,
|
|
183
|
+
data: record.data
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function extractAcpErrorInternal(value, depth) {
|
|
187
|
+
if (depth > 5) return;
|
|
188
|
+
const direct = toAcpErrorPayload(value);
|
|
189
|
+
if (direct) return direct;
|
|
190
|
+
const record = asRecord$2(value);
|
|
191
|
+
if (!record) return;
|
|
192
|
+
if ("error" in record) {
|
|
193
|
+
const nested = extractAcpErrorInternal(record.error, depth + 1);
|
|
194
|
+
if (nested) return nested;
|
|
195
|
+
}
|
|
196
|
+
if ("acp" in record) {
|
|
197
|
+
const nested = extractAcpErrorInternal(record.acp, depth + 1);
|
|
198
|
+
if (nested) return nested;
|
|
199
|
+
}
|
|
200
|
+
if ("cause" in record) {
|
|
201
|
+
const nested = extractAcpErrorInternal(record.cause, depth + 1);
|
|
202
|
+
if (nested) return nested;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function formatUnknownErrorMessage(error) {
|
|
206
|
+
if (error instanceof Error) return error.message;
|
|
207
|
+
if (error && typeof error === "object") {
|
|
208
|
+
const maybeMessage = error.message;
|
|
209
|
+
if (typeof maybeMessage === "string" && maybeMessage.length > 0) return maybeMessage;
|
|
210
|
+
try {
|
|
211
|
+
return JSON.stringify(error);
|
|
212
|
+
} catch {}
|
|
213
|
+
}
|
|
214
|
+
return String(error);
|
|
215
|
+
}
|
|
216
|
+
const SESSION_NOT_FOUND_PATTERN = /session\s+["'\w-]+\s+not found/i;
|
|
217
|
+
function isSessionNotFoundText(value) {
|
|
218
|
+
if (typeof value !== "string") return false;
|
|
219
|
+
const normalized = value.toLowerCase();
|
|
220
|
+
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") || SESSION_NOT_FOUND_PATTERN.test(value);
|
|
221
|
+
}
|
|
222
|
+
function hasSessionNotFoundHint(value, depth = 0) {
|
|
223
|
+
if (depth > 4) return false;
|
|
224
|
+
if (isSessionNotFoundText(value)) return true;
|
|
225
|
+
if (Array.isArray(value)) return value.some((entry) => hasSessionNotFoundHint(entry, depth + 1));
|
|
226
|
+
const record = asRecord$2(value);
|
|
227
|
+
if (!record) return false;
|
|
228
|
+
return Object.values(record).some((entry) => hasSessionNotFoundHint(entry, depth + 1));
|
|
229
|
+
}
|
|
230
|
+
function extractAcpError(error) {
|
|
231
|
+
return extractAcpErrorInternal(error, 0);
|
|
232
|
+
}
|
|
233
|
+
function isAcpResourceNotFoundError(error) {
|
|
234
|
+
const acp = extractAcpError(error);
|
|
235
|
+
if (acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code)) return true;
|
|
236
|
+
if (acp) {
|
|
237
|
+
if (isSessionNotFoundText(acp.message)) return true;
|
|
238
|
+
if (hasSessionNotFoundHint(acp.data)) return true;
|
|
239
|
+
}
|
|
240
|
+
return isSessionNotFoundText(formatUnknownErrorMessage(error));
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/acp/error-normalization.ts
|
|
244
|
+
const AUTH_REQUIRED_ACP_CODES = new Set([-32e3]);
|
|
245
|
+
const QUERY_CLOSED_BEFORE_RESPONSE_DETAIL = "query closed before response received";
|
|
246
|
+
function asRecord$1(value) {
|
|
247
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
248
|
+
return value;
|
|
249
|
+
}
|
|
250
|
+
function isAuthRequiredMessage(value) {
|
|
251
|
+
if (!value) return false;
|
|
252
|
+
const normalized = value.toLowerCase();
|
|
253
|
+
return normalized.includes("auth required") || normalized.includes("authentication required") || normalized.includes("authorization required") || normalized.includes("credential required") || normalized.includes("credentials required") || normalized.includes("token required") || normalized.includes("login required");
|
|
254
|
+
}
|
|
255
|
+
function isAcpAuthRequiredPayload(acp) {
|
|
256
|
+
if (!acp) return false;
|
|
257
|
+
if (!AUTH_REQUIRED_ACP_CODES.has(acp.code)) return false;
|
|
258
|
+
if (isAuthRequiredMessage(acp.message)) return true;
|
|
259
|
+
const data = asRecord$1(acp.data);
|
|
260
|
+
if (!data) return false;
|
|
261
|
+
if (data.authRequired === true) return true;
|
|
262
|
+
const methodId = data.methodId;
|
|
263
|
+
if (typeof methodId === "string" && methodId.trim().length > 0) return true;
|
|
264
|
+
const methods = data.methods;
|
|
265
|
+
if (Array.isArray(methods) && methods.length > 0) return true;
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
function isOutputErrorCode(value) {
|
|
269
|
+
return typeof value === "string" && OUTPUT_ERROR_CODES.includes(value);
|
|
270
|
+
}
|
|
271
|
+
function isOutputErrorOrigin(value) {
|
|
272
|
+
return typeof value === "string" && OUTPUT_ERROR_ORIGINS.includes(value);
|
|
273
|
+
}
|
|
274
|
+
function readOutputErrorMeta(error) {
|
|
275
|
+
const record = asRecord$1(error);
|
|
276
|
+
if (!record) return {};
|
|
277
|
+
return {
|
|
278
|
+
outputCode: isOutputErrorCode(record.outputCode) ? record.outputCode : void 0,
|
|
279
|
+
detailCode: typeof record.detailCode === "string" && record.detailCode.trim().length > 0 ? record.detailCode : void 0,
|
|
280
|
+
origin: isOutputErrorOrigin(record.origin) ? record.origin : void 0,
|
|
281
|
+
retryable: typeof record.retryable === "boolean" ? record.retryable : void 0,
|
|
282
|
+
acp: extractAcpError(record.acp)
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function isTimeoutLike(error) {
|
|
286
|
+
return error instanceof Error && error.name === "TimeoutError";
|
|
287
|
+
}
|
|
288
|
+
function isNoSessionLike(error) {
|
|
289
|
+
return error instanceof Error && error.name === "NoSessionError";
|
|
290
|
+
}
|
|
291
|
+
function isUsageLike(error) {
|
|
292
|
+
if (!(error instanceof Error)) return false;
|
|
293
|
+
return error.name === "CommanderError" || error.name === "InvalidArgumentError" || asRecord$1(error)?.code === "commander.invalidArgument";
|
|
294
|
+
}
|
|
295
|
+
function formatErrorMessage(error) {
|
|
296
|
+
return formatUnknownErrorMessage(error);
|
|
297
|
+
}
|
|
298
|
+
function isAcpQueryClosedBeforeResponseError(error) {
|
|
299
|
+
const acp = extractAcpError(error);
|
|
300
|
+
if (!acp || acp.code !== -32603) return false;
|
|
301
|
+
const details = asRecord$1(acp.data)?.details;
|
|
302
|
+
if (typeof details !== "string") return false;
|
|
303
|
+
return details.toLowerCase().includes(QUERY_CLOSED_BEFORE_RESPONSE_DETAIL);
|
|
304
|
+
}
|
|
305
|
+
function mapErrorCode(error) {
|
|
306
|
+
if (error instanceof PermissionPromptUnavailableError) return "PERMISSION_PROMPT_UNAVAILABLE";
|
|
307
|
+
if (error instanceof PermissionDeniedError) return "PERMISSION_DENIED";
|
|
308
|
+
if (isTimeoutLike(error)) return "TIMEOUT";
|
|
309
|
+
if (isNoSessionLike(error) || isAcpResourceNotFoundError(error)) return "NO_SESSION";
|
|
310
|
+
if (isUsageLike(error)) return "USAGE";
|
|
311
|
+
}
|
|
312
|
+
function normalizeOutputError(error, options = {}) {
|
|
313
|
+
const meta = readOutputErrorMeta(error);
|
|
314
|
+
let code = mapErrorCode(error) ?? options.defaultCode ?? "RUNTIME";
|
|
315
|
+
if (meta.outputCode) code = meta.outputCode;
|
|
316
|
+
if (code === "RUNTIME" && isAcpResourceNotFoundError(error)) code = "NO_SESSION";
|
|
317
|
+
const acp = options.acp ?? meta.acp ?? extractAcpError(error);
|
|
318
|
+
const detailCode = meta.detailCode ?? options.detailCode ?? (error instanceof AuthPolicyError || isAcpAuthRequiredPayload(acp) ? "AUTH_REQUIRED" : void 0);
|
|
319
|
+
return {
|
|
320
|
+
code,
|
|
321
|
+
message: formatErrorMessage(error),
|
|
322
|
+
detailCode,
|
|
323
|
+
origin: meta.origin ?? options.origin,
|
|
324
|
+
retryable: meta.retryable ?? options.retryable,
|
|
325
|
+
acp
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Returns true when an error from `client.prompt()` looks transient and
|
|
330
|
+
* can reasonably be retried (e.g. model-API 400/500, network hiccups that
|
|
331
|
+
* surface as ACP internal errors).
|
|
332
|
+
*
|
|
333
|
+
* Errors that are definitively non-recoverable (auth, missing session,
|
|
334
|
+
* invalid params, timeout, permission) return false.
|
|
335
|
+
*/
|
|
336
|
+
function isRetryablePromptError(error) {
|
|
337
|
+
if (error instanceof PermissionDeniedError || error instanceof PermissionPromptUnavailableError) return false;
|
|
338
|
+
if (isTimeoutLike(error) || isNoSessionLike(error) || isUsageLike(error)) return false;
|
|
339
|
+
const acp = extractAcpError(error);
|
|
340
|
+
if (!acp) return false;
|
|
341
|
+
if (acp.code === -32001 || acp.code === -32002) return false;
|
|
342
|
+
if (isAcpAuthRequiredPayload(acp)) return false;
|
|
343
|
+
if (acp.code === -32601 || acp.code === -32602) return false;
|
|
344
|
+
return acp.code === -32603 || acp.code === -32700;
|
|
345
|
+
}
|
|
346
|
+
function exitCodeForOutputErrorCode(code) {
|
|
347
|
+
switch (code) {
|
|
348
|
+
case "USAGE": return EXIT_CODES.USAGE;
|
|
349
|
+
case "TIMEOUT": return EXIT_CODES.TIMEOUT;
|
|
350
|
+
case "NO_SESSION": return EXIT_CODES.NO_SESSION;
|
|
351
|
+
case "PERMISSION_DENIED":
|
|
352
|
+
case "PERMISSION_PROMPT_UNAVAILABLE": return EXIT_CODES.PERMISSION_DENIED;
|
|
353
|
+
default: return EXIT_CODES.ERROR;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/prompt-content.ts
|
|
358
|
+
var PromptInputValidationError = class extends Error {
|
|
359
|
+
constructor(message) {
|
|
360
|
+
super(message);
|
|
361
|
+
this.name = "PromptInputValidationError";
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
function asRecord(value) {
|
|
365
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
366
|
+
return value;
|
|
367
|
+
}
|
|
368
|
+
function isNonEmptyString(value) {
|
|
369
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
370
|
+
}
|
|
371
|
+
function isBase64Data(value) {
|
|
372
|
+
if (value.length === 0 || value.length % 4 !== 0) return false;
|
|
373
|
+
return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value);
|
|
374
|
+
}
|
|
375
|
+
function isImageMimeType(value) {
|
|
376
|
+
return /^image\/[A-Za-z0-9.+-]+$/i.test(value);
|
|
377
|
+
}
|
|
378
|
+
function isTextBlock(value) {
|
|
379
|
+
const record = asRecord(value);
|
|
380
|
+
return record?.type === "text" && typeof record.text === "string";
|
|
381
|
+
}
|
|
382
|
+
function isImageBlock(value) {
|
|
383
|
+
const record = asRecord(value);
|
|
384
|
+
return record?.type === "image" && isNonEmptyString(record.mimeType) && isImageMimeType(record.mimeType) && typeof record.data === "string" && isBase64Data(record.data);
|
|
385
|
+
}
|
|
386
|
+
function isResourceLinkBlock(value) {
|
|
387
|
+
const record = asRecord(value);
|
|
388
|
+
return record?.type === "resource_link" && isNonEmptyString(record.uri) && (record.title === void 0 || typeof record.title === "string") && (record.name === void 0 || typeof record.name === "string");
|
|
389
|
+
}
|
|
390
|
+
function isResourcePayload(value) {
|
|
391
|
+
const record = asRecord(value);
|
|
392
|
+
if (!record || !isNonEmptyString(record.uri)) return false;
|
|
393
|
+
return record.text === void 0 || typeof record.text === "string";
|
|
394
|
+
}
|
|
395
|
+
function isResourceBlock(value) {
|
|
396
|
+
const record = asRecord(value);
|
|
397
|
+
return record?.type === "resource" && isResourcePayload(record.resource);
|
|
398
|
+
}
|
|
399
|
+
function isContentBlock(value) {
|
|
400
|
+
return isTextBlock(value) || isImageBlock(value) || isResourceLinkBlock(value) || isResourceBlock(value);
|
|
401
|
+
}
|
|
402
|
+
function getContentBlockValidationError(value, index) {
|
|
403
|
+
const record = asRecord(value);
|
|
404
|
+
if (!record || typeof record.type !== "string") return `prompt[${index}] must be an ACP content block object`;
|
|
405
|
+
switch (record.type) {
|
|
406
|
+
case "text": return typeof record.text === "string" ? void 0 : `prompt[${index}] text block must include a string text field`;
|
|
407
|
+
case "image":
|
|
408
|
+
if (!isNonEmptyString(record.mimeType)) return `prompt[${index}] image block must include a non-empty mimeType`;
|
|
409
|
+
if (!isImageMimeType(record.mimeType)) return `prompt[${index}] image block mimeType must start with image/`;
|
|
410
|
+
if (typeof record.data !== "string" || record.data.length === 0) return `prompt[${index}] image block must include non-empty base64 data`;
|
|
411
|
+
if (!isBase64Data(record.data)) return `prompt[${index}] image block data must be valid base64`;
|
|
412
|
+
return;
|
|
413
|
+
case "resource_link":
|
|
414
|
+
if (!isNonEmptyString(record.uri)) return `prompt[${index}] resource_link block must include a non-empty uri`;
|
|
415
|
+
if (record.title !== void 0 && typeof record.title !== "string") return `prompt[${index}] resource_link block title must be a string when present`;
|
|
416
|
+
if (record.name !== void 0 && typeof record.name !== "string") return `prompt[${index}] resource_link block name must be a string when present`;
|
|
417
|
+
return;
|
|
418
|
+
case "resource":
|
|
419
|
+
if (!asRecord(record.resource)) return `prompt[${index}] resource block must include a resource object`;
|
|
420
|
+
if (!isResourcePayload(record.resource)) return `prompt[${index}] resource block resource must include a non-empty uri and optional text`;
|
|
421
|
+
return;
|
|
422
|
+
default: return `prompt[${index}] has unsupported content block type ${JSON.stringify(record.type)}`;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function isPromptInput(value) {
|
|
426
|
+
return Array.isArray(value) && value.every((entry) => isContentBlock(entry));
|
|
427
|
+
}
|
|
428
|
+
function textPrompt(text) {
|
|
429
|
+
return [{
|
|
430
|
+
type: "text",
|
|
431
|
+
text
|
|
432
|
+
}];
|
|
433
|
+
}
|
|
434
|
+
function parseStructuredPrompt(source) {
|
|
435
|
+
if (!source.startsWith("[")) return;
|
|
436
|
+
try {
|
|
437
|
+
const parsed = JSON.parse(source);
|
|
438
|
+
if (isPromptInput(parsed)) return parsed;
|
|
439
|
+
if (Array.isArray(parsed)) throw new PromptInputValidationError(parsed.map((entry, index) => getContentBlockValidationError(entry, index)).find((message) => message !== void 0) ?? "Structured prompt JSON must be an array of valid ACP content blocks");
|
|
440
|
+
return;
|
|
441
|
+
} catch (error) {
|
|
442
|
+
if (error instanceof PromptInputValidationError) throw error;
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function parsePromptSource(source) {
|
|
447
|
+
const trimmed = source.trim();
|
|
448
|
+
const structured = parseStructuredPrompt(trimmed);
|
|
449
|
+
if (structured) return structured;
|
|
450
|
+
if (!trimmed) return [];
|
|
451
|
+
return textPrompt(trimmed);
|
|
452
|
+
}
|
|
453
|
+
function mergePromptSourceWithText(source, suffixText) {
|
|
454
|
+
const prompt = parsePromptSource(source);
|
|
455
|
+
const appended = suffixText.trim();
|
|
456
|
+
if (!appended) return prompt;
|
|
457
|
+
if (prompt.length === 0) return textPrompt(appended);
|
|
458
|
+
return [...prompt, ...textPrompt(appended)];
|
|
459
|
+
}
|
|
460
|
+
function promptToDisplayText(prompt) {
|
|
461
|
+
return prompt.map((block) => {
|
|
462
|
+
switch (block.type) {
|
|
463
|
+
case "text": return block.text;
|
|
464
|
+
case "resource_link": return block.title ?? block.name ?? block.uri;
|
|
465
|
+
case "resource": return "text" in block.resource && typeof block.resource.text === "string" ? block.resource.text : block.resource.uri;
|
|
466
|
+
case "image": return `[image] ${block.mimeType}`;
|
|
467
|
+
default: return "";
|
|
468
|
+
}
|
|
469
|
+
}).filter((entry) => entry.trim().length > 0).join("\n\n").trim();
|
|
470
|
+
}
|
|
471
|
+
//#endregion
|
|
472
|
+
//#region src/acp/agent-session-id.ts
|
|
473
|
+
const AGENT_SESSION_ID_META_KEYS = ["agentSessionId", "sessionId"];
|
|
474
|
+
function normalizeAgentSessionId(value) {
|
|
475
|
+
if (typeof value !== "string") return;
|
|
476
|
+
const trimmed = value.trim();
|
|
477
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
478
|
+
}
|
|
479
|
+
function asMetaRecord(meta) {
|
|
480
|
+
if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
|
|
481
|
+
return meta;
|
|
482
|
+
}
|
|
483
|
+
function extractAgentSessionId(meta) {
|
|
484
|
+
const record = asMetaRecord(meta);
|
|
485
|
+
if (!record) return;
|
|
486
|
+
for (const key of AGENT_SESSION_ID_META_KEYS) {
|
|
487
|
+
const normalized = normalizeAgentSessionId(record[key]);
|
|
488
|
+
if (normalized) return normalized;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region src/session/runtime-session-id.ts
|
|
493
|
+
function normalizeRuntimeSessionId(value) {
|
|
494
|
+
return normalizeAgentSessionId(value);
|
|
495
|
+
}
|
|
496
|
+
function extractRuntimeSessionId(meta) {
|
|
497
|
+
return extractAgentSessionId(meta);
|
|
498
|
+
}
|
|
499
|
+
//#endregion
|
|
500
|
+
//#region src/perf-metrics.ts
|
|
501
|
+
const counters = /* @__PURE__ */ new Map();
|
|
502
|
+
const gauges = /* @__PURE__ */ new Map();
|
|
503
|
+
const timings = /* @__PURE__ */ new Map();
|
|
504
|
+
function hrNow() {
|
|
505
|
+
return process.hrtime.bigint();
|
|
506
|
+
}
|
|
507
|
+
function durationMs(start) {
|
|
508
|
+
return Number(process.hrtime.bigint() - start) / 1e6;
|
|
509
|
+
}
|
|
510
|
+
function roundMetric(value) {
|
|
511
|
+
return Number(value.toFixed(3));
|
|
512
|
+
}
|
|
513
|
+
function incrementPerfCounter(name, delta = 1) {
|
|
514
|
+
counters.set(name, (counters.get(name) ?? 0) + delta);
|
|
515
|
+
}
|
|
516
|
+
function setPerfGauge(name, value) {
|
|
517
|
+
gauges.set(name, value);
|
|
518
|
+
}
|
|
519
|
+
function recordPerfDuration(name, durationMsValue) {
|
|
520
|
+
const next = timings.get(name) ?? {
|
|
521
|
+
count: 0,
|
|
522
|
+
totalMs: 0,
|
|
523
|
+
maxMs: 0
|
|
524
|
+
};
|
|
525
|
+
next.count += 1;
|
|
526
|
+
next.totalMs += durationMsValue;
|
|
527
|
+
next.maxMs = Math.max(next.maxMs, durationMsValue);
|
|
528
|
+
timings.set(name, next);
|
|
529
|
+
}
|
|
530
|
+
async function measurePerf(name, run) {
|
|
531
|
+
const startedAt = hrNow();
|
|
532
|
+
try {
|
|
533
|
+
return await run();
|
|
534
|
+
} finally {
|
|
535
|
+
recordPerfDuration(name, durationMs(startedAt));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
function startPerfTimer(name) {
|
|
539
|
+
const startedAt = hrNow();
|
|
540
|
+
return () => {
|
|
541
|
+
const elapsedMs = durationMs(startedAt);
|
|
542
|
+
recordPerfDuration(name, elapsedMs);
|
|
543
|
+
return elapsedMs;
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
function getPerfMetricsSnapshot() {
|
|
547
|
+
return {
|
|
548
|
+
counters: Object.fromEntries(counters.entries()),
|
|
549
|
+
gauges: Object.fromEntries(gauges.entries()),
|
|
550
|
+
timings: Object.fromEntries([...timings.entries()].map(([name, bucket]) => [name, {
|
|
551
|
+
count: bucket.count,
|
|
552
|
+
totalMs: roundMetric(bucket.totalMs),
|
|
553
|
+
maxMs: roundMetric(bucket.maxMs)
|
|
554
|
+
}]))
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
function resetPerfMetrics() {
|
|
558
|
+
counters.clear();
|
|
559
|
+
gauges.clear();
|
|
560
|
+
timings.clear();
|
|
561
|
+
}
|
|
562
|
+
function formatPerfMetric(name, durationMsValue) {
|
|
563
|
+
return `${name}=${roundMetric(durationMsValue)}ms`;
|
|
564
|
+
}
|
|
565
|
+
//#endregion
|
|
566
|
+
export { PERMISSION_MODES as A, QueueConnectionError as B, isAcpResourceNotFoundError as C, OUTPUT_ERROR_CODES as D, NON_INTERACTIVE_PERMISSION_POLICIES as E, ClaudeAcpSessionCreateTimeoutError as F, SessionResolutionError as G, SessionModeReplayError as H, CopilotAcpUnsupportedError as I, SessionResumeRequiredError as K, GeminiAcpStartupTimeoutError as L, AgentDisconnectedError as M, AgentSpawnError as N, OUTPUT_ERROR_ORIGINS as O, AuthPolicyError as P, PermissionDeniedError as R, extractAcpError as S, EXIT_CODES as T, SessionModelReplayError as U, QueueProtocolError as V, SessionNotFoundError as W, exitCodeForOutputErrorCode as _, recordPerfDuration as a, isRetryablePromptError as b, startPerfTimer as c, PromptInputValidationError as d, isPromptInput as f, textPrompt as g, promptToDisplayText as h, measurePerf as i, SESSION_RECORD_SCHEMA as j, OUTPUT_FORMATS as k, extractRuntimeSessionId as l, parsePromptSource as m, getPerfMetricsSnapshot as n, resetPerfMetrics as o, mergePromptSourceWithText as p, incrementPerfCounter as r, setPerfGauge as s, formatPerfMetric as t, normalizeRuntimeSessionId as u, formatErrorMessage as v, AUTH_POLICIES as w, normalizeOutputError as x, isAcpQueryClosedBeforeResponseError as y, PermissionPromptUnavailableError as z };
|
|
567
|
+
|
|
568
|
+
//# sourceMappingURL=perf-metrics-D9QC81lB.js.map
|