@modelprofile.com/mcp-crossharness 5.0.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.
@@ -0,0 +1,941 @@
1
+ import * as plugins from './plugins.js';
2
+ import * as helpers from './helpers.js';
3
+ import { commitinfo } from './00_commitinfo_data.js';
4
+ const appServerVersion = '0.146.0';
5
+ const maxSocketMessageBytes = 4 * 1024 * 1024;
6
+ const maxSocketBufferedBytes = 4 * 1024 * 1024;
7
+ const maxTurnTextChars = 1024 * 1024;
8
+ const maxTurnDeltaChunks = 4096;
9
+ const maxEarlyNotifications = 100;
10
+ const maxQueuedSends = 100;
11
+ const maxQueuedSendsPerThread = 10;
12
+ export class CodexConnection {
13
+ connectionId;
14
+ serverUrl;
15
+ directory;
16
+ onClosing;
17
+ onClosed;
18
+ harness = 'codex';
19
+ state = 'connecting';
20
+ connectedAt = new Date().toISOString();
21
+ serverVersion;
22
+ socket;
23
+ requestCounter = 0;
24
+ pendingRequests = new Map();
25
+ pendingTurns = new Set();
26
+ threadQueues = new Map();
27
+ activeThreads = new Set();
28
+ queuedSends = 0;
29
+ queuedSendsByThread = new Map();
30
+ connectStarted = false;
31
+ constructor(connectionId, serverUrl, directory, onClosing, onClosed) {
32
+ this.connectionId = connectionId;
33
+ this.serverUrl = serverUrl;
34
+ this.directory = directory;
35
+ this.onClosing = onClosing;
36
+ this.onClosed = onClosed;
37
+ }
38
+ async connect() {
39
+ if (this.connectStarted) {
40
+ throw new Error(`Codex connection ${this.connectionId} has already been started`);
41
+ }
42
+ this.connectStarted = true;
43
+ const headers = {};
44
+ const token = process.env.CODEX_REMOTE_TOKEN;
45
+ if (token)
46
+ headers.authorization = `Bearer ${token}`;
47
+ const socket = new plugins.WsWebSocket(this.serverUrl, {
48
+ perMessageDeflate: false,
49
+ headers,
50
+ followRedirects: false,
51
+ maxPayload: maxSocketMessageBytes,
52
+ });
53
+ this.socket = socket;
54
+ socket.on('message', (data) => this.handleMessage(data.toString()));
55
+ socket.on('error', (error) => this.handleSocketFailure(error));
56
+ socket.on('close', () => this.handleSocketClose());
57
+ await new Promise((resolve, reject) => {
58
+ const cleanup = () => {
59
+ clearTimeout(timer);
60
+ socket.off('open', handleOpen);
61
+ socket.off('error', handleError);
62
+ socket.off('close', handleClose);
63
+ };
64
+ const handleOpen = () => {
65
+ cleanup();
66
+ resolve();
67
+ };
68
+ const handleError = (errorArg) => {
69
+ cleanup();
70
+ reject(errorArg);
71
+ };
72
+ const handleClose = () => {
73
+ cleanup();
74
+ reject(new Error('Codex server WebSocket closed during handshake'));
75
+ };
76
+ const timer = setTimeout(() => {
77
+ cleanup();
78
+ socket.terminate();
79
+ reject(new Error('Codex server WebSocket handshake timed out'));
80
+ }, 5000);
81
+ socket.once('open', handleOpen);
82
+ socket.once('error', handleError);
83
+ socket.once('close', handleClose);
84
+ });
85
+ try {
86
+ const initialized = await this.request('initialize', {
87
+ clientInfo: {
88
+ name: 'mcp-crossharness',
89
+ title: 'mcp-crossharness',
90
+ version: commitinfo.version,
91
+ },
92
+ capabilities: {
93
+ experimentalApi: false,
94
+ requestAttestation: false,
95
+ },
96
+ }, 5000, true);
97
+ if (!helpers.isRecord(initialized) || typeof initialized.userAgent !== 'string') {
98
+ throw new Error(`Codex server returned an invalid initialize response (expected app-server ${appServerVersion})`);
99
+ }
100
+ this.serverVersion = initialized.userAgent.match(/\/(\d+\.\d+\.\d+[^\s]*)/)?.[1];
101
+ if (this.state !== 'connecting' || socket.readyState !== plugins.WsWebSocket.OPEN) {
102
+ throw new Error('Codex server connection closed during initialization');
103
+ }
104
+ this.sendNotification('initialized');
105
+ this.state = 'connected';
106
+ }
107
+ catch (error) {
108
+ socket.terminate();
109
+ throw error;
110
+ }
111
+ }
112
+ getInfo() {
113
+ return {
114
+ connectionId: this.connectionId,
115
+ harness: this.harness,
116
+ serverUrl: this.serverUrl,
117
+ directory: this.directory,
118
+ state: this.state,
119
+ connectedAt: this.connectedAt,
120
+ serverVersion: this.serverVersion,
121
+ };
122
+ }
123
+ async getStatus() {
124
+ if (this.state !== 'connected') {
125
+ return { ...this.getInfo(), healthy: false, detail: `connection is ${this.state}` };
126
+ }
127
+ try {
128
+ const response = await this.request('thread/loaded/list', {}, 5000);
129
+ const healthy = helpers.isRecord(response) && Array.isArray(response.data);
130
+ return {
131
+ ...this.getInfo(),
132
+ healthy,
133
+ detail: healthy ? 'Codex app-server answered thread/loaded/list' : 'invalid health response',
134
+ };
135
+ }
136
+ catch (error) {
137
+ return { ...this.getInfo(), healthy: false, detail: helpers.errorMessage(error) };
138
+ }
139
+ }
140
+ async listChats(limitArg) {
141
+ const payload = await this.request('thread/list', {
142
+ limit: limitArg,
143
+ sortKey: 'updated_at',
144
+ sortDirection: 'desc',
145
+ archived: false,
146
+ cwd: this.directory,
147
+ });
148
+ if (!helpers.isRecord(payload) || !Array.isArray(payload.data)) {
149
+ throw new Error('Codex server returned an invalid thread list');
150
+ }
151
+ return payload.data.map((entry) => {
152
+ const thread = this.parseThread(entry);
153
+ this.assertThreadIdentity(thread, thread.id);
154
+ return {
155
+ harness: this.harness,
156
+ chatId: thread.id,
157
+ title: thread.name ?? thread.preview ?? '(untitled)',
158
+ directory: thread.cwd,
159
+ updatedAt: new Date(thread.updatedAt * 1000).toISOString(),
160
+ isActive: helpers.isRecord(thread.status) && thread.status.type === 'active',
161
+ meta: thread.modelProvider ? { modelProvider: thread.modelProvider } : undefined,
162
+ };
163
+ });
164
+ }
165
+ async readChat(chatIdArg, limitArg, maxCharsArg) {
166
+ this.assertChatId(chatIdArg);
167
+ const thread = await this.readThread(chatIdArg, true);
168
+ const messages = [];
169
+ for (const turn of thread.turns) {
170
+ if (!helpers.isRecord(turn) || !Array.isArray(turn.items))
171
+ continue;
172
+ for (const item of turn.items) {
173
+ if (!helpers.isRecord(item) || typeof item.type !== 'string')
174
+ continue;
175
+ if (item.type === 'userMessage' && Array.isArray(item.content)) {
176
+ const text = item.content
177
+ .filter((content) => helpers.isRecord(content) && content.type === 'text')
178
+ .map((content) => String(content.text ?? ''))
179
+ .join('\n')
180
+ .trim();
181
+ if (text)
182
+ messages.push({ role: 'user', text: helpers.truncateText(text, maxCharsArg) });
183
+ }
184
+ else if (item.type === 'agentMessage' && typeof item.text === 'string') {
185
+ messages.push({ role: 'assistant', text: helpers.truncateText(item.text, maxCharsArg) });
186
+ }
187
+ }
188
+ }
189
+ const limited = messages.slice(-limitArg);
190
+ return {
191
+ harness: this.harness,
192
+ chatId: chatIdArg,
193
+ title: thread.name ?? thread.preview ?? '(untitled)',
194
+ directory: thread.cwd,
195
+ totalMessages: messages.length,
196
+ messages: limited,
197
+ };
198
+ }
199
+ async sendMessage(chatIdArg, messageArg, timeoutSecondsArg, signalArg) {
200
+ this.assertChatId(chatIdArg);
201
+ if (messageArg.length > maxTurnTextChars) {
202
+ throw new Error('Codex message exceeds the 1 MiB character limit');
203
+ }
204
+ const threadQueueSize = this.queuedSendsByThread.get(chatIdArg) ?? 0;
205
+ if (this.queuedSends >= maxQueuedSends || threadQueueSize >= maxQueuedSendsPerThread) {
206
+ throw new Error('Codex send queue is full');
207
+ }
208
+ this.queuedSends++;
209
+ this.queuedSendsByThread.set(chatIdArg, threadQueueSize + 1);
210
+ const deadline = Date.now() + timeoutSecondsArg * 1000;
211
+ try {
212
+ return await this.enqueueThreadSend(chatIdArg, deadline, timeoutSecondsArg, signalArg, () => this.sendMessageInner(chatIdArg, messageArg, deadline, timeoutSecondsArg, signalArg));
213
+ }
214
+ finally {
215
+ this.queuedSends--;
216
+ const remainingForThread = (this.queuedSendsByThread.get(chatIdArg) ?? 1) - 1;
217
+ if (remainingForThread > 0)
218
+ this.queuedSendsByThread.set(chatIdArg, remainingForThread);
219
+ else
220
+ this.queuedSendsByThread.delete(chatIdArg);
221
+ }
222
+ }
223
+ async sendMessageInner(chatIdArg, messageArg, deadlineArg, timeoutSecondsArg, signalArg) {
224
+ await this.readThread(chatIdArg, false, this.remainingSendMs(deadlineArg, timeoutSecondsArg), signalArg);
225
+ const resumed = await this.request('thread/resume', { threadId: chatIdArg }, this.remainingSendMs(deadlineArg, timeoutSecondsArg), false, signalArg);
226
+ if (!helpers.isRecord(resumed) ||
227
+ !helpers.isRecord(resumed.thread) ||
228
+ typeof resumed.cwd !== 'string') {
229
+ throw new Error('Codex server returned an invalid thread/resume response');
230
+ }
231
+ const resumedThread = this.parseThread(resumed.thread);
232
+ this.assertThreadIdentity(resumedThread, chatIdArg);
233
+ if (resumed.cwd !== this.directory) {
234
+ throw new Error(`Codex thread ${chatIdArg} resumed outside the connection directory`);
235
+ }
236
+ const turnTimeoutMs = this.remainingSendMs(deadlineArg, timeoutSecondsArg);
237
+ if (signalArg?.aborted)
238
+ throw this.abortError(signalArg.reason);
239
+ return new Promise((resolve, reject) => {
240
+ const turn = {
241
+ threadId: chatIdArg,
242
+ agentText: '',
243
+ deltaChunks: [],
244
+ deltaChars: 0,
245
+ earlyNotifications: new Map(),
246
+ earlyNotificationCount: 0,
247
+ earlyNotificationChars: 0,
248
+ resolve,
249
+ reject,
250
+ timer: setTimeout(() => void this.timeoutTurn(turn, timeoutSecondsArg), turnTimeoutMs),
251
+ };
252
+ this.pendingTurns.add(turn);
253
+ void this.request('turn/start', {
254
+ threadId: chatIdArg,
255
+ clientUserMessageId: plugins.crypto.randomUUID(),
256
+ input: [{ type: 'text', text: messageArg, text_elements: [] }],
257
+ cwd: this.directory,
258
+ }, turnTimeoutMs)
259
+ .then((result) => {
260
+ if (!this.pendingTurns.has(turn))
261
+ return;
262
+ let turnId;
263
+ try {
264
+ turnId = this.extractTurnId(result);
265
+ }
266
+ catch (error) {
267
+ this.failUncertainTurnStart(turn, error);
268
+ return;
269
+ }
270
+ this.bindTurnId(turn, turnId);
271
+ })
272
+ .catch((error) => this.failUncertainTurnStart(turn, error));
273
+ });
274
+ }
275
+ enqueueThreadSend(threadIdArg, deadlineArg, timeoutSecondsArg, signalArg, taskArg) {
276
+ return new Promise((resolve, reject) => {
277
+ const entry = {
278
+ deadline: deadlineArg,
279
+ timeoutSeconds: timeoutSecondsArg,
280
+ task: taskArg,
281
+ resolve,
282
+ reject,
283
+ signal: signalArg,
284
+ };
285
+ if (signalArg?.aborted) {
286
+ reject(this.abortError(signalArg.reason));
287
+ return;
288
+ }
289
+ const queue = this.threadQueues.get(threadIdArg) ?? [];
290
+ queue.push(entry);
291
+ this.threadQueues.set(threadIdArg, queue);
292
+ entry.timer = setTimeout(() => this.timeoutQueuedSend(threadIdArg, entry), Math.max(0, deadlineArg - Date.now()));
293
+ if (signalArg) {
294
+ entry.abortHandler = () => this.cancelThreadSend(threadIdArg, entry);
295
+ signalArg.addEventListener('abort', entry.abortHandler, { once: true });
296
+ }
297
+ this.drainThreadQueue(threadIdArg);
298
+ });
299
+ }
300
+ async close(reasonArg = 'connection disconnected') {
301
+ if (this.state === 'closed')
302
+ return;
303
+ if (this.state !== 'closing') {
304
+ this.state = 'closing';
305
+ this.rejectAll(new Error(reasonArg));
306
+ this.onClosing?.();
307
+ this.onClosing = undefined;
308
+ }
309
+ await this.closeSocket();
310
+ this.finishClosed();
311
+ }
312
+ async readThread(chatIdArg, includeTurnsArg, timeoutMsArg = 30000, signalArg) {
313
+ const payload = await this.request('thread/read', {
314
+ threadId: chatIdArg,
315
+ includeTurns: includeTurnsArg,
316
+ }, timeoutMsArg, false, signalArg);
317
+ if (!helpers.isRecord(payload) || !helpers.isRecord(payload.thread)) {
318
+ throw new Error('Codex server returned an invalid thread');
319
+ }
320
+ const thread = this.parseThread(payload.thread);
321
+ this.assertThreadIdentity(thread, chatIdArg);
322
+ return thread;
323
+ }
324
+ parseThread(valueArg) {
325
+ if (!helpers.isRecord(valueArg) ||
326
+ typeof valueArg.id !== 'string' ||
327
+ typeof valueArg.cwd !== 'string' ||
328
+ typeof valueArg.updatedAt !== 'number' ||
329
+ !Array.isArray(valueArg.turns)) {
330
+ throw new Error('Codex server returned an invalid thread');
331
+ }
332
+ return {
333
+ id: valueArg.id,
334
+ cwd: valueArg.cwd,
335
+ updatedAt: valueArg.updatedAt,
336
+ turns: valueArg.turns,
337
+ preview: typeof valueArg.preview === 'string' ? valueArg.preview : undefined,
338
+ name: typeof valueArg.name === 'string' || valueArg.name === null ? valueArg.name : undefined,
339
+ modelProvider: typeof valueArg.modelProvider === 'string' ? valueArg.modelProvider : undefined,
340
+ status: valueArg.status,
341
+ };
342
+ }
343
+ assertThreadIdentity(threadArg, chatIdArg) {
344
+ if (threadArg.id !== chatIdArg) {
345
+ throw new Error(`Codex server returned a different thread for ${chatIdArg}`);
346
+ }
347
+ if (threadArg.cwd !== this.directory) {
348
+ throw new Error(`Codex thread ${chatIdArg} is outside the connection directory`);
349
+ }
350
+ }
351
+ request(methodArg, paramsArg, timeoutMsArg = 30000, allowConnectingArg = false, signalArg) {
352
+ if (!allowConnectingArg && this.state !== 'connected') {
353
+ return Promise.reject(new Error(`Codex connection ${this.connectionId} is ${this.state}`));
354
+ }
355
+ const socket = this.socket;
356
+ if (!socket || socket.readyState !== plugins.WsWebSocket.OPEN) {
357
+ return Promise.reject(new Error('Codex server WebSocket is not open'));
358
+ }
359
+ if (this.pendingRequests.size >= 256) {
360
+ return Promise.reject(new Error('Codex connection has too many active requests'));
361
+ }
362
+ if (signalArg?.aborted)
363
+ return Promise.reject(this.abortError(signalArg.reason));
364
+ return new Promise((resolve, reject) => {
365
+ const id = ++this.requestCounter;
366
+ const timer = setTimeout(() => {
367
+ const pending = this.pendingRequests.get(id);
368
+ if (!pending)
369
+ return;
370
+ this.pendingRequests.delete(id);
371
+ this.clearPendingRequestResources(pending);
372
+ reject(new Error(`Codex request timed out: ${methodArg}`));
373
+ }, timeoutMsArg);
374
+ const pending = { resolve, reject, timer, signal: signalArg };
375
+ if (signalArg) {
376
+ pending.abortHandler = () => {
377
+ if (!this.pendingRequests.delete(id))
378
+ return;
379
+ this.clearPendingRequestResources(pending);
380
+ reject(this.abortError(signalArg.reason));
381
+ };
382
+ signalArg.addEventListener('abort', pending.abortHandler, { once: true });
383
+ }
384
+ this.pendingRequests.set(id, pending);
385
+ const failSend = (errorArg) => {
386
+ const current = this.pendingRequests.get(id);
387
+ if (!current)
388
+ return;
389
+ this.pendingRequests.delete(id);
390
+ this.clearPendingRequestResources(current);
391
+ current.reject(errorArg);
392
+ };
393
+ try {
394
+ this.sendFrame({ id, method: methodArg, params: paramsArg });
395
+ }
396
+ catch (error) {
397
+ failSend(error instanceof Error ? error : new Error(String(error)));
398
+ }
399
+ });
400
+ }
401
+ sendNotification(methodArg, paramsArg) {
402
+ this.sendFrame(paramsArg === undefined
403
+ ? { method: methodArg }
404
+ : { method: methodArg, params: paramsArg });
405
+ }
406
+ sendFrame(frameArg) {
407
+ const socket = this.socket;
408
+ const payload = JSON.stringify(frameArg);
409
+ const payloadBytes = Buffer.byteLength(payload, 'utf8');
410
+ if (!socket || socket.readyState !== plugins.WsWebSocket.OPEN) {
411
+ const error = new Error('Codex server WebSocket is not open');
412
+ this.handleSocketFailure(error);
413
+ throw error;
414
+ }
415
+ if (socket.bufferedAmount + payloadBytes > maxSocketBufferedBytes) {
416
+ const error = new Error('Codex WebSocket send buffer exceeded the 4 MiB limit');
417
+ this.handleSocketFailure(error);
418
+ throw error;
419
+ }
420
+ try {
421
+ socket.send(payload, (error) => {
422
+ if (error)
423
+ this.handleSocketFailure(error);
424
+ });
425
+ }
426
+ catch (error) {
427
+ const sendError = error instanceof Error ? error : new Error(String(error));
428
+ this.handleSocketFailure(sendError);
429
+ throw sendError;
430
+ }
431
+ }
432
+ handleMessage(rawArg) {
433
+ const message = helpers.parseJson(rawArg);
434
+ if (!helpers.isRecord(message))
435
+ return;
436
+ if (message.id !== undefined && typeof message.method === 'string') {
437
+ this.respondToServerRequest(message);
438
+ return;
439
+ }
440
+ if (typeof message.id === 'number' && this.pendingRequests.has(message.id)) {
441
+ const pending = this.pendingRequests.get(message.id);
442
+ this.pendingRequests.delete(message.id);
443
+ this.clearPendingRequestResources(pending);
444
+ if (message.error !== undefined) {
445
+ pending.reject(new Error(`Codex server rejected request: ${JSON.stringify(message.error).slice(0, 4000)}`));
446
+ }
447
+ else {
448
+ pending.resolve(message.result);
449
+ }
450
+ return;
451
+ }
452
+ if (typeof message.method === 'string') {
453
+ if (!helpers.isRecord(message.params)) {
454
+ if (message.method === 'turn/completed') {
455
+ this.handleSocketFailure(new Error('Codex returned malformed turn/completed params'));
456
+ }
457
+ return;
458
+ }
459
+ this.handleNotification(message.method, message.params);
460
+ }
461
+ }
462
+ handleNotification(methodArg, paramsArg) {
463
+ if (methodArg === 'turn/completed') {
464
+ if (!helpers.isRecord(paramsArg.turn) ||
465
+ typeof paramsArg.turn.id !== 'string' ||
466
+ (paramsArg.turnId !== undefined && paramsArg.turnId !== paramsArg.turn.id)) {
467
+ this.handleSocketFailure(new Error('Codex returned malformed turn/completed identity'));
468
+ return;
469
+ }
470
+ }
471
+ const threadId = typeof paramsArg.threadId === 'string' ? paramsArg.threadId : undefined;
472
+ const turnId = typeof paramsArg.turnId === 'string'
473
+ ? paramsArg.turnId
474
+ : helpers.isRecord(paramsArg.turn) && typeof paramsArg.turn.id === 'string'
475
+ ? paramsArg.turn.id
476
+ : undefined;
477
+ if (!threadId || !turnId) {
478
+ if (methodArg === 'turn/completed') {
479
+ this.handleSocketFailure(new Error('Codex returned malformed turn/completed identity'));
480
+ }
481
+ return;
482
+ }
483
+ const turn = [...this.pendingTurns].find((candidate) => candidate.threadId === threadId && candidate.turnId === turnId);
484
+ if (!turn) {
485
+ const unbound = [...this.pendingTurns].filter((candidate) => candidate.threadId === threadId && !candidate.turnId);
486
+ if (unbound.length === 1)
487
+ this.bufferEarlyNotification(unbound[0], turnId, methodArg, paramsArg);
488
+ return;
489
+ }
490
+ this.handleTurnNotification(turn, methodArg, paramsArg);
491
+ }
492
+ handleTurnNotification(turnArg, methodArg, paramsArg) {
493
+ if (methodArg === 'turn/completed' && !helpers.isRecord(paramsArg.turn)) {
494
+ this.handleSocketFailure(new Error('Codex returned malformed turn/completed payload'));
495
+ return;
496
+ }
497
+ if (methodArg === 'item/agentMessage/delta' && typeof paramsArg.delta === 'string') {
498
+ this.appendTurnDelta(turnArg, paramsArg.delta);
499
+ }
500
+ else if (methodArg === 'item/completed' && helpers.isRecord(paramsArg.item)) {
501
+ if (paramsArg.item.type === 'agentMessage' && typeof paramsArg.item.text === 'string') {
502
+ if (paramsArg.item.text.length > maxTurnTextChars) {
503
+ this.handleSocketFailure(new Error('Codex turn output exceeded the response limit'));
504
+ return;
505
+ }
506
+ turnArg.agentText = paramsArg.item.text;
507
+ }
508
+ }
509
+ else if (methodArg === 'turn/completed' && helpers.isRecord(paramsArg.turn)) {
510
+ const status = paramsArg.turn.status;
511
+ if (turnArg.timeoutError) {
512
+ if (status !== 'completed' && status !== 'interrupted' && status !== 'failed') {
513
+ this.handleSocketFailure(new Error('Codex returned a non-terminal status in turn/completed'));
514
+ return;
515
+ }
516
+ turnArg.terminalObserved = true;
517
+ this.rejectTimedOutTurnIfSafe(turnArg);
518
+ return;
519
+ }
520
+ if (status === 'completed') {
521
+ this.completeTurn(turnArg);
522
+ }
523
+ else if (status === 'interrupted' || status === 'failed') {
524
+ const turnError = helpers.isRecord(paramsArg.turn.error)
525
+ ? String(paramsArg.turn.error.message ?? status)
526
+ : String(status);
527
+ this.failTurn(turnArg, new Error(`Codex turn ${status}: ${turnError}`));
528
+ }
529
+ else {
530
+ this.handleSocketFailure(new Error('Codex returned a non-terminal status in turn/completed'));
531
+ }
532
+ }
533
+ }
534
+ bindTurnId(turnArg, turnIdArg) {
535
+ if (!this.pendingTurns.has(turnArg))
536
+ return;
537
+ if (turnArg.turnId && turnArg.turnId !== turnIdArg) {
538
+ this.failTurn(turnArg, new Error('Codex turn identity changed during dispatch'));
539
+ return;
540
+ }
541
+ const collision = [...this.pendingTurns].find((candidate) => candidate !== turnArg && candidate.turnId === turnIdArg);
542
+ if (collision) {
543
+ this.handleSocketFailure(new Error('Codex reused a turn id across concurrent sends'));
544
+ return;
545
+ }
546
+ turnArg.turnId = turnIdArg;
547
+ const buffered = turnArg.earlyNotifications.get(turnIdArg) ?? [];
548
+ turnArg.earlyNotifications.clear();
549
+ turnArg.earlyNotificationCount = 0;
550
+ turnArg.earlyNotificationChars = 0;
551
+ for (const notification of buffered) {
552
+ if (!this.pendingTurns.has(turnArg))
553
+ break;
554
+ this.handleTurnNotification(turnArg, notification.method, notification.params);
555
+ }
556
+ }
557
+ extractTurnId(valueArg) {
558
+ if (!helpers.isRecord(valueArg) || !helpers.isRecord(valueArg.turn) || typeof valueArg.turn.id !== 'string') {
559
+ throw new Error('Codex server returned an invalid turn/start response');
560
+ }
561
+ return valueArg.turn.id;
562
+ }
563
+ completeTurn(turnArg) {
564
+ if (!this.settleTurn(turnArg))
565
+ return;
566
+ const reply = (turnArg.agentText || turnArg.deltaChunks.join('')).trim();
567
+ if (!reply) {
568
+ turnArg.reject(new Error('Codex turn completed without assistant text'));
569
+ return;
570
+ }
571
+ turnArg.resolve({
572
+ harness: this.harness,
573
+ chatId: turnArg.threadId,
574
+ reply,
575
+ via: `ws:${this.serverUrl}`,
576
+ });
577
+ }
578
+ failTurn(turnArg, errorArg) {
579
+ if (!this.settleTurn(turnArg))
580
+ return;
581
+ turnArg.reject(errorArg instanceof Error ? errorArg : new Error(String(errorArg)));
582
+ }
583
+ async timeoutTurn(turnArg, timeoutSecondsArg) {
584
+ if (!this.pendingTurns.has(turnArg) || turnArg.timeoutError)
585
+ return;
586
+ const timeoutError = new Error(`Codex turn timed out after ${timeoutSecondsArg}s; Crossharness did not retry`);
587
+ turnArg.timeoutError = timeoutError;
588
+ const turnId = turnArg.turnId;
589
+ if (!turnId) {
590
+ const fatalError = new Error(`${timeoutError.message}; no turn id was available to interrupt safely, so the connection was closed`);
591
+ this.handleSocketFailure(fatalError);
592
+ return;
593
+ }
594
+ try {
595
+ await this.request('turn/interrupt', { threadId: turnArg.threadId, turnId }, 3000);
596
+ if (!this.pendingTurns.has(turnArg))
597
+ return;
598
+ turnArg.interruptAcknowledged = true;
599
+ if (turnArg.terminalObserved) {
600
+ this.rejectTimedOutTurnIfSafe(turnArg);
601
+ return;
602
+ }
603
+ turnArg.terminalTimer = setTimeout(() => {
604
+ if (!this.pendingTurns.has(turnArg))
605
+ return;
606
+ this.handleSocketFailure(new Error(`${timeoutError.message}; the interrupted turn did not report terminal completion, so the connection was closed`));
607
+ }, 3000);
608
+ turnArg.terminalTimer.unref();
609
+ }
610
+ catch (error) {
611
+ const fatalError = new Error(`${timeoutError.message}; turn/interrupt was not acknowledged, so the connection was closed: ${helpers.errorMessage(error)}`, { cause: error });
612
+ this.handleSocketFailure(fatalError);
613
+ }
614
+ }
615
+ async cancelActiveTurn(turnArg, errorArg) {
616
+ if (!this.pendingTurns.has(turnArg) || turnArg.timeoutError)
617
+ return;
618
+ turnArg.timeoutError = errorArg;
619
+ const turnId = turnArg.turnId;
620
+ if (!turnId) {
621
+ this.handleSocketFailure(new Error(`${errorArg.message}; no turn id was available to interrupt safely, so the connection was closed`));
622
+ return;
623
+ }
624
+ try {
625
+ await this.request('turn/interrupt', { threadId: turnArg.threadId, turnId }, 3000);
626
+ if (!this.pendingTurns.has(turnArg))
627
+ return;
628
+ turnArg.interruptAcknowledged = true;
629
+ if (turnArg.terminalObserved) {
630
+ this.rejectTimedOutTurnIfSafe(turnArg);
631
+ return;
632
+ }
633
+ turnArg.terminalTimer = setTimeout(() => {
634
+ if (!this.pendingTurns.has(turnArg))
635
+ return;
636
+ this.handleSocketFailure(new Error(`${errorArg.message}; the interrupted turn did not report terminal completion, so the connection was closed`));
637
+ }, 3000);
638
+ turnArg.terminalTimer.unref();
639
+ }
640
+ catch (error) {
641
+ this.handleSocketFailure(new Error(`${errorArg.message}; turn/interrupt was not acknowledged, so the connection was closed: ${helpers.errorMessage(error)}`, { cause: error }));
642
+ }
643
+ }
644
+ timeoutQueuedSend(threadIdArg, entryArg) {
645
+ if (this.activeThreads.has(threadIdArg)) {
646
+ const queue = this.threadQueues.get(threadIdArg);
647
+ if (queue?.[0] === entryArg)
648
+ return;
649
+ }
650
+ const queue = this.threadQueues.get(threadIdArg);
651
+ if (!queue)
652
+ return;
653
+ const index = queue.indexOf(entryArg);
654
+ if (index < 0)
655
+ return;
656
+ queue.splice(index, 1);
657
+ this.clearQueueEntryResources(entryArg);
658
+ entryArg.reject(new Error(`Codex send timed out after ${entryArg.timeoutSeconds}s while queued; no message was delivered`));
659
+ if (queue.length === 0 && !this.activeThreads.has(threadIdArg)) {
660
+ this.threadQueues.delete(threadIdArg);
661
+ }
662
+ }
663
+ cancelThreadSend(threadIdArg, entryArg) {
664
+ const queue = this.threadQueues.get(threadIdArg);
665
+ if (!queue)
666
+ return;
667
+ const index = queue.indexOf(entryArg);
668
+ if (index < 0)
669
+ return;
670
+ if (index === 0 && this.activeThreads.has(threadIdArg)) {
671
+ const turn = [...this.pendingTurns].find((candidate) => candidate.threadId === threadIdArg);
672
+ if (turn)
673
+ void this.cancelActiveTurn(turn, this.abortError(entryArg.signal?.reason));
674
+ return;
675
+ }
676
+ queue.splice(index, 1);
677
+ this.clearQueueEntryResources(entryArg);
678
+ entryArg.reject(this.abortError(entryArg.signal?.reason));
679
+ if (queue.length === 0 && !this.activeThreads.has(threadIdArg)) {
680
+ this.threadQueues.delete(threadIdArg);
681
+ }
682
+ }
683
+ drainThreadQueue(threadIdArg) {
684
+ if (this.activeThreads.has(threadIdArg))
685
+ return;
686
+ const queue = this.threadQueues.get(threadIdArg);
687
+ const entry = queue?.[0];
688
+ if (!queue || !entry) {
689
+ this.threadQueues.delete(threadIdArg);
690
+ return;
691
+ }
692
+ if (entry.deadline <= Date.now()) {
693
+ this.timeoutQueuedSend(threadIdArg, entry);
694
+ this.drainThreadQueue(threadIdArg);
695
+ return;
696
+ }
697
+ this.activeThreads.add(threadIdArg);
698
+ if (entry.timer)
699
+ clearTimeout(entry.timer);
700
+ void entry.task().then(entry.resolve, entry.reject).finally(() => {
701
+ this.clearQueueEntryResources(entry);
702
+ this.activeThreads.delete(threadIdArg);
703
+ const currentQueue = this.threadQueues.get(threadIdArg);
704
+ if (currentQueue?.[0] === entry)
705
+ currentQueue.shift();
706
+ if (currentQueue?.length === 0)
707
+ this.threadQueues.delete(threadIdArg);
708
+ this.drainThreadQueue(threadIdArg);
709
+ });
710
+ }
711
+ appendTurnDelta(turnArg, deltaArg) {
712
+ if (turnArg.deltaChunks.length >= maxTurnDeltaChunks) {
713
+ this.handleSocketFailure(new Error('Codex turn output exceeded the delta chunk limit'));
714
+ return;
715
+ }
716
+ if (turnArg.deltaChars + deltaArg.length > maxTurnTextChars) {
717
+ this.handleSocketFailure(new Error('Codex turn output exceeded the response limit'));
718
+ return;
719
+ }
720
+ turnArg.deltaChunks.push(deltaArg);
721
+ turnArg.deltaChars += deltaArg.length;
722
+ }
723
+ remainingSendMs(deadlineArg, timeoutSecondsArg) {
724
+ const remainingMs = deadlineArg - Date.now();
725
+ if (remainingMs <= 0) {
726
+ throw new Error(`Codex send timed out after ${timeoutSecondsArg}s before turn/start; no message was delivered`);
727
+ }
728
+ return remainingMs;
729
+ }
730
+ clearQueueEntryResources(entryArg) {
731
+ if (entryArg.timer)
732
+ clearTimeout(entryArg.timer);
733
+ if (entryArg.abortHandler) {
734
+ entryArg.signal?.removeEventListener('abort', entryArg.abortHandler);
735
+ }
736
+ }
737
+ clearPendingRequestResources(pendingArg) {
738
+ clearTimeout(pendingArg.timer);
739
+ if (pendingArg.abortHandler) {
740
+ pendingArg.signal?.removeEventListener('abort', pendingArg.abortHandler);
741
+ }
742
+ }
743
+ abortError(reasonArg) {
744
+ return reasonArg instanceof Error ? reasonArg : new Error('operation cancelled');
745
+ }
746
+ assertChatId(chatIdArg) {
747
+ if (!chatIdArg || chatIdArg.length > 1024) {
748
+ throw new Error('Codex chatId must contain 1-1024 characters');
749
+ }
750
+ }
751
+ bufferEarlyNotification(turnArg, turnIdArg, methodArg, paramsArg) {
752
+ const notification = this.normalizeEarlyNotification(methodArg, paramsArg);
753
+ if (!notification)
754
+ return;
755
+ turnArg.earlyNotificationCount++;
756
+ if (turnArg.earlyNotificationCount > maxEarlyNotifications) {
757
+ this.handleSocketFailure(new Error('Codex sent too many turn notifications before acknowledging turn/start'));
758
+ return;
759
+ }
760
+ const notificationChars = JSON.stringify(notification).length;
761
+ turnArg.earlyNotificationChars += notificationChars;
762
+ if (turnArg.earlyNotificationChars > maxTurnTextChars) {
763
+ this.handleSocketFailure(new Error('Codex buffered turn notifications exceeded the response limit'));
764
+ return;
765
+ }
766
+ const notifications = turnArg.earlyNotifications.get(turnIdArg) ?? [];
767
+ notifications.push(notification);
768
+ turnArg.earlyNotifications.set(turnIdArg, notifications);
769
+ }
770
+ normalizeEarlyNotification(methodArg, paramsArg) {
771
+ if (methodArg === 'item/agentMessage/delta' && typeof paramsArg.delta === 'string') {
772
+ return { method: methodArg, params: { delta: paramsArg.delta } };
773
+ }
774
+ if (methodArg === 'item/completed' && helpers.isRecord(paramsArg.item)) {
775
+ const item = paramsArg.item;
776
+ if (item.type === 'agentMessage' && typeof item.text === 'string') {
777
+ return { method: methodArg, params: { item: { type: item.type, text: item.text } } };
778
+ }
779
+ return undefined;
780
+ }
781
+ if (methodArg === 'turn/completed' && helpers.isRecord(paramsArg.turn)) {
782
+ const turn = paramsArg.turn;
783
+ return {
784
+ method: methodArg,
785
+ params: {
786
+ turn: {
787
+ status: turn.status,
788
+ error: helpers.isRecord(turn.error) ? { message: turn.error.message } : turn.error,
789
+ },
790
+ },
791
+ };
792
+ }
793
+ return undefined;
794
+ }
795
+ failUncertainTurnStart(turnArg, errorArg) {
796
+ if (!this.pendingTurns.has(turnArg))
797
+ return;
798
+ const fatalError = new Error(`Codex turn/start outcome is uncertain, so the connection was closed: ${helpers.errorMessage(errorArg)}`, { cause: errorArg });
799
+ this.handleSocketFailure(fatalError);
800
+ }
801
+ rejectTimedOutTurnIfSafe(turnArg) {
802
+ const error = turnArg.timeoutError;
803
+ if (!error ||
804
+ !turnArg.interruptAcknowledged ||
805
+ !turnArg.terminalObserved ||
806
+ !this.settleTurn(turnArg)) {
807
+ return;
808
+ }
809
+ turnArg.reject(error);
810
+ }
811
+ settleTurn(turnArg) {
812
+ if (!this.pendingTurns.delete(turnArg))
813
+ return false;
814
+ clearTimeout(turnArg.timer);
815
+ if (turnArg.terminalTimer)
816
+ clearTimeout(turnArg.terminalTimer);
817
+ turnArg.earlyNotifications.clear();
818
+ return true;
819
+ }
820
+ respondToServerRequest(messageArg) {
821
+ const method = String(messageArg.method);
822
+ let result;
823
+ switch (method) {
824
+ case 'item/commandExecution/requestApproval':
825
+ case 'item/fileChange/requestApproval':
826
+ result = { decision: 'decline' };
827
+ break;
828
+ case 'item/tool/requestUserInput':
829
+ result = { answers: {} };
830
+ break;
831
+ case 'mcpServer/elicitation/request':
832
+ result = { action: 'decline', content: null, _meta: null };
833
+ break;
834
+ case 'item/permissions/requestApproval':
835
+ result = { permissions: {}, scope: 'turn' };
836
+ break;
837
+ case 'applyPatchApproval':
838
+ case 'execCommandApproval':
839
+ result = { decision: 'abort' };
840
+ break;
841
+ default:
842
+ try {
843
+ this.sendFrame({
844
+ id: messageArg.id,
845
+ error: { code: -32601, message: `Crossharness does not implement ${method}` },
846
+ });
847
+ }
848
+ catch { }
849
+ return;
850
+ }
851
+ try {
852
+ this.sendFrame({ id: messageArg.id, result });
853
+ }
854
+ catch { }
855
+ }
856
+ handleSocketFailure(errorArg) {
857
+ if (this.state === 'closed')
858
+ return;
859
+ if (this.state !== 'closing') {
860
+ this.state = 'closing';
861
+ this.rejectAll(errorArg);
862
+ this.onClosing?.();
863
+ this.onClosing = undefined;
864
+ }
865
+ const socket = this.socket;
866
+ if (socket && socket.readyState !== plugins.WsWebSocket.CLOSED) {
867
+ socket.terminate();
868
+ }
869
+ else {
870
+ this.finishClosed();
871
+ }
872
+ }
873
+ handleSocketClose() {
874
+ if (this.state !== 'closing' && this.state !== 'closed') {
875
+ this.state = 'closing';
876
+ this.rejectAll(new Error('Codex server connection closed'));
877
+ this.onClosing?.();
878
+ this.onClosing = undefined;
879
+ }
880
+ this.finishClosed();
881
+ }
882
+ finishClosed() {
883
+ if (this.state === 'closed')
884
+ return;
885
+ this.state = 'closed';
886
+ this.onClosed?.();
887
+ this.onClosing = undefined;
888
+ this.onClosed = undefined;
889
+ }
890
+ rejectAll(errorArg) {
891
+ for (const pending of this.pendingRequests.values()) {
892
+ this.clearPendingRequestResources(pending);
893
+ pending.reject(errorArg);
894
+ }
895
+ this.pendingRequests.clear();
896
+ for (const turn of [...this.pendingTurns])
897
+ this.failTurn(turn, errorArg);
898
+ for (const [threadId, queue] of this.threadQueues) {
899
+ const activeOffset = this.activeThreads.has(threadId) ? 1 : 0;
900
+ for (const entry of queue.slice(activeOffset)) {
901
+ this.clearQueueEntryResources(entry);
902
+ entry.reject(errorArg);
903
+ }
904
+ }
905
+ this.threadQueues.clear();
906
+ }
907
+ async closeSocket() {
908
+ const socket = this.socket;
909
+ if (!socket || socket.readyState === plugins.WsWebSocket.CLOSED)
910
+ return;
911
+ await new Promise((resolve) => {
912
+ let settled = false;
913
+ const finish = () => {
914
+ if (settled)
915
+ return;
916
+ settled = true;
917
+ clearTimeout(timer);
918
+ socket.off('close', finish);
919
+ resolve();
920
+ };
921
+ const timer = setTimeout(() => {
922
+ socket.terminate();
923
+ finish();
924
+ }, 1000);
925
+ socket.once('close', finish);
926
+ try {
927
+ if (socket.readyState === plugins.WsWebSocket.CONNECTING) {
928
+ socket.terminate();
929
+ }
930
+ else {
931
+ socket.close();
932
+ }
933
+ }
934
+ catch {
935
+ socket.terminate();
936
+ finish();
937
+ }
938
+ });
939
+ }
940
+ }
941
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb25uZWN0aW9uLmNvZGV4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5jb25uZWN0aW9uLmNvZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUdyRCxNQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQztBQUNuQyxNQUFNLHFCQUFxQixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQzlDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDL0MsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3JDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0scUJBQXFCLEdBQUcsR0FBRyxDQUFDO0FBQ2xDLE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQztBQUMzQixNQUFNLHVCQUF1QixHQUFHLEVBQUUsQ0FBQztBQXVEbkMsTUFBTSxPQUFPLGVBQWU7SUFnQlI7SUFDQTtJQUNBO0lBQ1I7SUFDQTtJQW5CTSxPQUFPLEdBQUcsT0FBZ0IsQ0FBQztJQUNwQyxLQUFLLEdBQWdDLFlBQVksQ0FBQztJQUNqRCxXQUFXLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN2QyxhQUFhLENBQXFCO0lBQ2xDLE1BQU0sQ0FBdUQ7SUFDN0QsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNuQixlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQTJCLENBQUM7SUFDckQsWUFBWSxHQUFHLElBQUksR0FBRyxFQUFnQixDQUFDO0lBQ3ZDLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBK0IsQ0FBQztJQUN0RCxhQUFhLEdB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