happy-imou-cloud 2.0.10 → 2.0.11
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/BaseReasoningProcessor-5ACv9gKu.mjs +320 -0
- package/dist/BaseReasoningProcessor-COrRWyn0.cjs +323 -0
- package/dist/ProviderSelectionHandler-BljOLMQn.mjs +261 -0
- package/dist/ProviderSelectionHandler-DBGobhGZ.cjs +265 -0
- package/dist/{api-BjxmW-0W.mjs → api-BcWf5v4i.mjs} +174 -46
- package/dist/{api-DUE5TJBE.cjs → api-Ye-rPX6s.cjs} +174 -46
- package/dist/{command-Df7u5eAT.cjs → command-BK93nizl.cjs} +6 -6
- package/dist/{command-ComOeFLY.mjs → command-nOI80Mnm.mjs} +6 -6
- package/dist/{index-CzvgPwr1.mjs → index-DnsqY6I_.mjs} +189 -60
- package/dist/{index-Cuvfa15L.cjs → index-J7QKJ8lc.cjs} +194 -61
- package/dist/index.cjs +8 -8
- package/dist/index.mjs +8 -8
- package/dist/lib.cjs +2 -3
- package/dist/lib.d.cts +2 -0
- package/dist/lib.d.mts +2 -0
- package/dist/lib.mjs +2 -3
- package/dist/{persistence-BxP6Jw1f.mjs → persistence-BMa6cyw9.mjs} +2 -3
- package/dist/{persistence-D7JtnrYA.cjs → persistence-xK5CKhbn.cjs} +2 -3
- package/dist/registerKillSessionHandler-CH6yN0eG.cjs +1198 -0
- package/dist/registerKillSessionHandler-Dxwg4L4J.mjs +1179 -0
- package/dist/{runClaude-C1W_Nw0C.cjs → runClaude-BMHlBny_.cjs} +884 -398
- package/dist/{runClaude-B_fTMxc4.mjs → runClaude-cQ-UT0Ke.mjs} +882 -396
- package/dist/{runCodex-CUgOiIEz.mjs → runCodex-AnJUPIhX.mjs} +155 -578
- package/dist/{runCodex-D2VCWVEK.cjs → runCodex-roOSOWWL.cjs} +158 -583
- package/dist/{runGemini-2_FEtJYa.mjs → runGemini-BGo_0mzA.mjs} +142 -387
- package/dist/{runGemini-CiGnjflq.cjs → runGemini-Cg6Zbqlz.cjs} +145 -390
- package/package.json +9 -8
- package/scripts/e2e/fake-codex-acp-agent.mjs +139 -0
- package/scripts/e2e/local-server-session-roundtrip.mjs +1063 -0
- package/scripts/release-smoke.mjs +23 -6
- package/dist/names-CicSgRNg.mjs +0 -625
- package/dist/names-yJNZoTv_.cjs +0 -636
- package/dist/registerKillSessionHandler-ARQrPvnT.mjs +0 -454
- package/dist/registerKillSessionHandler-DCMFiXyA.cjs +0 -459
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { l as logger, b as connectionState, A as ApiClient
|
|
3
|
-
import {
|
|
4
|
-
import { f as formatDisplayMessage, v as validateCodexAcpSpawn,
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
9
|
-
import 'axios';
|
|
10
|
-
import 'chalk';
|
|
2
|
+
import { l as logger, b as connectionState, A as ApiClient } from './api-BcWf5v4i.mjs';
|
|
3
|
+
import { B as BasePermissionHandler, h as hashObject, d as MessageBuffer, C as ConversationHistory$1, w as waitForResponseCompleteWithAbort, r as registerKillSessionHandler, l as launchRuntimeHandleWithFactoryResult, i as inferToolResultError, j as forwardAgentMessageToProviderSession, f as closeProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, s as syncControlledByUserState } from './registerKillSessionHandler-Dxwg4L4J.mjs';
|
|
4
|
+
import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate } from './index-DnsqY6I_.mjs';
|
|
5
|
+
import 'cross-spawn';
|
|
6
|
+
import '@agentclientprotocol/sdk';
|
|
7
|
+
import 'ps-list';
|
|
11
8
|
import 'fs';
|
|
9
|
+
import 'path';
|
|
10
|
+
import 'os';
|
|
11
|
+
import 'child_process';
|
|
12
12
|
import 'node:fs';
|
|
13
|
-
import 'node:os';
|
|
14
13
|
import 'node:path';
|
|
14
|
+
import 'node:os';
|
|
15
|
+
import './persistence-BMa6cyw9.mjs';
|
|
16
|
+
import 'node:fs/promises';
|
|
17
|
+
import 'fs/promises';
|
|
18
|
+
import 'crypto';
|
|
19
|
+
import 'node:child_process';
|
|
20
|
+
import 'chalk';
|
|
15
21
|
import 'node:events';
|
|
22
|
+
import 'axios';
|
|
23
|
+
import 'tweetnacl';
|
|
24
|
+
import 'open';
|
|
25
|
+
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
26
|
+
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
27
|
+
import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-BljOLMQn.mjs';
|
|
28
|
+
import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-5ACv9gKu.mjs';
|
|
16
29
|
import 'socket.io-client';
|
|
17
30
|
import 'zod';
|
|
18
|
-
import 'tweetnacl';
|
|
19
|
-
import 'child_process';
|
|
20
|
-
import 'util';
|
|
21
|
-
import 'fs/promises';
|
|
22
|
-
import 'crypto';
|
|
23
|
-
import 'path';
|
|
24
31
|
import 'expo-server-sdk';
|
|
25
|
-
import '
|
|
26
|
-
import 'os';
|
|
32
|
+
import './types-CiliQpqS.mjs';
|
|
27
33
|
import 'tmp';
|
|
28
34
|
import 'qrcode-terminal';
|
|
29
35
|
import 'node:module';
|
|
30
|
-
import 'open';
|
|
31
36
|
import 'url';
|
|
32
|
-
import 'node:child_process';
|
|
33
|
-
import 'ps-list';
|
|
34
|
-
import 'cross-spawn';
|
|
35
37
|
import 'fastify';
|
|
36
38
|
import 'fastify-type-provider-zod';
|
|
37
39
|
import 'node:readline';
|
|
38
40
|
import 'http';
|
|
39
|
-
import '
|
|
40
|
-
import './types-CiliQpqS.mjs';
|
|
41
|
+
import 'util';
|
|
41
42
|
|
|
42
43
|
const DEFAULT_CAPABILITIES = {
|
|
43
44
|
committedMessageAcks: false,
|
|
@@ -127,7 +128,7 @@ class CodexSession {
|
|
|
127
128
|
sessionId;
|
|
128
129
|
mode;
|
|
129
130
|
thinking = false;
|
|
130
|
-
|
|
131
|
+
keepAliveController;
|
|
131
132
|
onModeChangeCallback;
|
|
132
133
|
clientSwapCallbacks = [];
|
|
133
134
|
constructor(opts) {
|
|
@@ -143,13 +144,16 @@ class CodexSession {
|
|
|
143
144
|
this.queue = opts.messageQueue;
|
|
144
145
|
this.codexArgs = opts.codexArgs;
|
|
145
146
|
this.onModeChangeCallback = opts.onModeChange;
|
|
146
|
-
this.
|
|
147
|
-
|
|
148
|
-
this.
|
|
149
|
-
|
|
147
|
+
this.keepAliveController = createKeepAliveController({
|
|
148
|
+
initialMode: this.mode,
|
|
149
|
+
initialThinking: this.thinking,
|
|
150
|
+
send: (thinking, mode) => {
|
|
151
|
+
this.client.keepAlive(thinking, mode);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
150
154
|
}
|
|
151
155
|
cleanup() {
|
|
152
|
-
|
|
156
|
+
this.keepAliveController.dispose();
|
|
153
157
|
logger.debug("[CodexSession] Cleaned up resources");
|
|
154
158
|
}
|
|
155
159
|
updateClient = (client) => {
|
|
@@ -172,11 +176,11 @@ class CodexSession {
|
|
|
172
176
|
};
|
|
173
177
|
onThinkingChange = (thinking) => {
|
|
174
178
|
this.thinking = thinking;
|
|
175
|
-
this.
|
|
179
|
+
this.keepAliveController.setThinking(thinking);
|
|
176
180
|
};
|
|
177
181
|
onModeChange = async (mode) => {
|
|
178
182
|
this.mode = mode;
|
|
179
|
-
this.
|
|
183
|
+
this.keepAliveController.setMode(mode);
|
|
180
184
|
await this.onModeChangeCallback(mode);
|
|
181
185
|
};
|
|
182
186
|
onSessionFound = (sessionId) => {
|
|
@@ -329,208 +333,9 @@ class CodexPermissionHandler extends BasePermissionHandler {
|
|
|
329
333
|
}
|
|
330
334
|
}
|
|
331
335
|
|
|
332
|
-
class CodexSelectionHandler {
|
|
333
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
334
|
-
session;
|
|
336
|
+
class CodexSelectionHandler extends ProviderSelectionHandler {
|
|
335
337
|
constructor(session) {
|
|
336
|
-
|
|
337
|
-
this.setupRpcHandler();
|
|
338
|
-
}
|
|
339
|
-
updateSession(newSession) {
|
|
340
|
-
this.session = newSession;
|
|
341
|
-
this.setupRpcHandler();
|
|
342
|
-
}
|
|
343
|
-
async requestSelection(request) {
|
|
344
|
-
return new Promise((resolve, reject) => {
|
|
345
|
-
const pending = {
|
|
346
|
-
resolve,
|
|
347
|
-
reject,
|
|
348
|
-
request
|
|
349
|
-
};
|
|
350
|
-
pending.timeoutHandle = setTimeout(() => {
|
|
351
|
-
this.handleSelectionTimeout(request.id, pending);
|
|
352
|
-
}, getPendingInteractionTimeoutMs());
|
|
353
|
-
this.pendingRequests.set(request.id, pending);
|
|
354
|
-
this.session.updateAgentState((currentState) => ({
|
|
355
|
-
...currentState,
|
|
356
|
-
requests: {
|
|
357
|
-
...currentState.requests,
|
|
358
|
-
[request.id]: {
|
|
359
|
-
tool: "AskUserQuestion",
|
|
360
|
-
arguments: {
|
|
361
|
-
requestKind: "selection",
|
|
362
|
-
questions: [
|
|
363
|
-
{
|
|
364
|
-
header: "Codex",
|
|
365
|
-
question: request.message,
|
|
366
|
-
multiSelect: false,
|
|
367
|
-
options: request.options.map((option) => ({
|
|
368
|
-
label: option.label,
|
|
369
|
-
description: option.description || option.optionId,
|
|
370
|
-
optionId: option.optionId
|
|
371
|
-
}))
|
|
372
|
-
}
|
|
373
|
-
]
|
|
374
|
-
},
|
|
375
|
-
createdAt: Date.now(),
|
|
376
|
-
requestKind: "selection",
|
|
377
|
-
options: request.options,
|
|
378
|
-
defaultOptionId: request.defaultOptionId
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}));
|
|
382
|
-
logger.debug(`[Codex] Selection request sent (${request.id}) with ${request.options.length} options`);
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
hasPendingRequests() {
|
|
386
|
-
return this.pendingRequests.size > 0;
|
|
387
|
-
}
|
|
388
|
-
supersedePendingRequests(reason = INTERACTION_SUPERSEDED_ERROR) {
|
|
389
|
-
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
390
|
-
if (pendingSnapshot.length === 0) {
|
|
391
|
-
return 0;
|
|
392
|
-
}
|
|
393
|
-
this.pendingRequests.clear();
|
|
394
|
-
const completedAt = Date.now();
|
|
395
|
-
for (const [, pending] of pendingSnapshot) {
|
|
396
|
-
this.clearPendingRequestTimeout(pending);
|
|
397
|
-
pending.reject(new Error(reason));
|
|
398
|
-
}
|
|
399
|
-
this.session.updateAgentState((currentState) => {
|
|
400
|
-
const requests = { ...currentState.requests || {} };
|
|
401
|
-
const completedRequests = { ...currentState.completedRequests || {} };
|
|
402
|
-
for (const [id, request] of Object.entries(requests)) {
|
|
403
|
-
if (request.requestKind !== "selection") {
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
completedRequests[id] = {
|
|
407
|
-
...request,
|
|
408
|
-
completedAt,
|
|
409
|
-
status: "canceled",
|
|
410
|
-
reason,
|
|
411
|
-
requestKind: "selection"
|
|
412
|
-
};
|
|
413
|
-
delete requests[id];
|
|
414
|
-
}
|
|
415
|
-
return {
|
|
416
|
-
...currentState,
|
|
417
|
-
requests,
|
|
418
|
-
completedRequests
|
|
419
|
-
};
|
|
420
|
-
});
|
|
421
|
-
logger.debug(`[Codex] Superseded ${pendingSnapshot.length} pending selection request(s)`);
|
|
422
|
-
return pendingSnapshot.length;
|
|
423
|
-
}
|
|
424
|
-
reset(reason = "Session reset") {
|
|
425
|
-
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
426
|
-
this.pendingRequests.clear();
|
|
427
|
-
for (const [, pending] of pendingSnapshot) {
|
|
428
|
-
this.clearPendingRequestTimeout(pending);
|
|
429
|
-
pending.reject(new Error(reason));
|
|
430
|
-
}
|
|
431
|
-
this.session.updateAgentState((currentState) => {
|
|
432
|
-
const requests = { ...currentState.requests || {} };
|
|
433
|
-
const completedRequests = { ...currentState.completedRequests || {} };
|
|
434
|
-
for (const [id, request] of Object.entries(requests)) {
|
|
435
|
-
if (request.requestKind !== "selection") {
|
|
436
|
-
continue;
|
|
437
|
-
}
|
|
438
|
-
completedRequests[id] = {
|
|
439
|
-
...request,
|
|
440
|
-
completedAt: Date.now(),
|
|
441
|
-
status: "canceled",
|
|
442
|
-
reason,
|
|
443
|
-
requestKind: "selection"
|
|
444
|
-
};
|
|
445
|
-
delete requests[id];
|
|
446
|
-
}
|
|
447
|
-
return {
|
|
448
|
-
...currentState,
|
|
449
|
-
requests,
|
|
450
|
-
completedRequests
|
|
451
|
-
};
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
setupRpcHandler() {
|
|
455
|
-
this.session.rpcHandlerManager.registerHandler("selection", async (response) => {
|
|
456
|
-
const pending = this.pendingRequests.get(response.id);
|
|
457
|
-
if (!pending) {
|
|
458
|
-
logger.debug("[Codex] Selection request not found or already resolved");
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
this.pendingRequests.delete(response.id);
|
|
462
|
-
this.clearPendingRequestTimeout(pending);
|
|
463
|
-
pending.resolve(response);
|
|
464
|
-
this.session.updateAgentState((currentState) => {
|
|
465
|
-
const request = currentState.requests?.[response.id];
|
|
466
|
-
if (!request) {
|
|
467
|
-
return currentState;
|
|
468
|
-
}
|
|
469
|
-
const { [response.id]: _, ...remainingRequests } = currentState.requests || {};
|
|
470
|
-
return {
|
|
471
|
-
...currentState,
|
|
472
|
-
requests: remainingRequests,
|
|
473
|
-
completedRequests: {
|
|
474
|
-
...currentState.completedRequests,
|
|
475
|
-
[response.id]: {
|
|
476
|
-
...request,
|
|
477
|
-
completedAt: Date.now(),
|
|
478
|
-
status: "approved",
|
|
479
|
-
requestKind: "selection",
|
|
480
|
-
selectedOptionId: response.optionId
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
};
|
|
484
|
-
});
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
clearPendingRequestTimeout(pending) {
|
|
488
|
-
if (pending?.timeoutHandle) {
|
|
489
|
-
clearTimeout(pending.timeoutHandle);
|
|
490
|
-
pending.timeoutHandle = void 0;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
handleSelectionTimeout(requestId, pending) {
|
|
494
|
-
const active = this.pendingRequests.get(requestId);
|
|
495
|
-
if (!active || active !== pending) {
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
this.pendingRequests.delete(requestId);
|
|
499
|
-
this.clearPendingRequestTimeout(active);
|
|
500
|
-
active.reject(new Error(INTERACTION_TIMED_OUT_ERROR));
|
|
501
|
-
this.session.updateAgentState((currentState) => {
|
|
502
|
-
const request = currentState.requests?.[requestId] || {
|
|
503
|
-
tool: "AskUserQuestion",
|
|
504
|
-
arguments: {
|
|
505
|
-
requestKind: "selection",
|
|
506
|
-
questions: []
|
|
507
|
-
},
|
|
508
|
-
createdAt: Date.now(),
|
|
509
|
-
requestKind: "selection",
|
|
510
|
-
options: active.request.options,
|
|
511
|
-
defaultOptionId: active.request.defaultOptionId
|
|
512
|
-
};
|
|
513
|
-
const { [requestId]: _, ...remainingRequests } = currentState.requests || {};
|
|
514
|
-
return {
|
|
515
|
-
...currentState,
|
|
516
|
-
requests: remainingRequests,
|
|
517
|
-
completedRequests: {
|
|
518
|
-
...currentState.completedRequests,
|
|
519
|
-
[requestId]: {
|
|
520
|
-
...request,
|
|
521
|
-
completedAt: Date.now(),
|
|
522
|
-
status: "canceled",
|
|
523
|
-
reason: INTERACTION_TIMED_OUT_ERROR,
|
|
524
|
-
requestKind: "selection"
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
});
|
|
529
|
-
this.session.sendSessionEvent({
|
|
530
|
-
type: "message",
|
|
531
|
-
message: "Pending interaction timed out waiting for a response. Send a new message to continue."
|
|
532
|
-
});
|
|
533
|
-
logger.debug(`[Codex] Selection request timed out (${requestId})`);
|
|
338
|
+
super(session, "Codex");
|
|
534
339
|
}
|
|
535
340
|
}
|
|
536
341
|
|
|
@@ -558,101 +363,6 @@ class ReasoningProcessor extends BaseReasoningProcessor {
|
|
|
558
363
|
}
|
|
559
364
|
}
|
|
560
365
|
|
|
561
|
-
class ConversationHistory {
|
|
562
|
-
messages = [];
|
|
563
|
-
maxMessages;
|
|
564
|
-
maxCharacters;
|
|
565
|
-
constructor(options = {}) {
|
|
566
|
-
this.maxMessages = options.maxMessages ?? 20;
|
|
567
|
-
this.maxCharacters = options.maxCharacters ?? 5e4;
|
|
568
|
-
}
|
|
569
|
-
isDuplicate(role, content) {
|
|
570
|
-
if (this.messages.length === 0) {
|
|
571
|
-
return false;
|
|
572
|
-
}
|
|
573
|
-
for (let index = this.messages.length - 1; index >= 0; index -= 1) {
|
|
574
|
-
const message = this.messages[index];
|
|
575
|
-
if (message.role !== role) {
|
|
576
|
-
continue;
|
|
577
|
-
}
|
|
578
|
-
const normalizedIncoming = content.trim().replace(/\s+/g, " ");
|
|
579
|
-
const normalizedExisting = message.content.replace(/\s+/g, " ");
|
|
580
|
-
return normalizedIncoming === normalizedExisting;
|
|
581
|
-
}
|
|
582
|
-
return false;
|
|
583
|
-
}
|
|
584
|
-
addUserMessage(content) {
|
|
585
|
-
this.addMessage("user", content);
|
|
586
|
-
}
|
|
587
|
-
addAssistantMessage(content) {
|
|
588
|
-
this.addMessage("assistant", content);
|
|
589
|
-
}
|
|
590
|
-
hasHistory() {
|
|
591
|
-
return this.messages.length > 0;
|
|
592
|
-
}
|
|
593
|
-
size() {
|
|
594
|
-
return this.messages.length;
|
|
595
|
-
}
|
|
596
|
-
clear() {
|
|
597
|
-
this.messages = [];
|
|
598
|
-
logger.debug("[CodexConversationHistory] History cleared");
|
|
599
|
-
}
|
|
600
|
-
getContextForNewSession() {
|
|
601
|
-
if (this.messages.length === 0) {
|
|
602
|
-
return "";
|
|
603
|
-
}
|
|
604
|
-
const formattedMessages = this.messages.map((message) => {
|
|
605
|
-
const role = message.role === "user" ? "User" : "Assistant";
|
|
606
|
-
const content = message.content.length > 2e3 ? `${message.content.slice(0, 2e3)}... [truncated]` : message.content;
|
|
607
|
-
return `${role}: ${content}`;
|
|
608
|
-
}).join("\n\n");
|
|
609
|
-
return [
|
|
610
|
-
"[PREVIOUS CONVERSATION CONTEXT]",
|
|
611
|
-
"Continue from the prior Codex session using the conversation below as context.",
|
|
612
|
-
"",
|
|
613
|
-
formattedMessages,
|
|
614
|
-
"",
|
|
615
|
-
"[END OF PREVIOUS CONTEXT]",
|
|
616
|
-
""
|
|
617
|
-
].join("\n");
|
|
618
|
-
}
|
|
619
|
-
getSummary() {
|
|
620
|
-
const totalChars = this.messages.reduce((sum, message) => sum + message.content.length, 0);
|
|
621
|
-
const userCount = this.messages.filter((message) => message.role === "user").length;
|
|
622
|
-
const assistantCount = this.messages.filter((message) => message.role === "assistant").length;
|
|
623
|
-
return `${this.messages.length} messages (${userCount} user, ${assistantCount} assistant), ${totalChars} chars`;
|
|
624
|
-
}
|
|
625
|
-
addMessage(role, content) {
|
|
626
|
-
const trimmedContent = content.trim();
|
|
627
|
-
if (!trimmedContent) {
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
if (this.isDuplicate(role, trimmedContent)) {
|
|
631
|
-
logger.debug(`[CodexConversationHistory] Skipping duplicate ${role} message (${trimmedContent.length} chars)`);
|
|
632
|
-
return;
|
|
633
|
-
}
|
|
634
|
-
this.messages.push({
|
|
635
|
-
role,
|
|
636
|
-
content: trimmedContent,
|
|
637
|
-
timestamp: Date.now()
|
|
638
|
-
});
|
|
639
|
-
this.trimHistory();
|
|
640
|
-
logger.debug(`[CodexConversationHistory] Added ${role} message (${trimmedContent.length} chars), total: ${this.messages.length}`);
|
|
641
|
-
}
|
|
642
|
-
trimHistory() {
|
|
643
|
-
while (this.messages.length > this.maxMessages) {
|
|
644
|
-
this.messages.shift();
|
|
645
|
-
}
|
|
646
|
-
let totalChars = this.messages.reduce((sum, message) => sum + message.content.length, 0);
|
|
647
|
-
while (totalChars > this.maxCharacters && this.messages.length > 1) {
|
|
648
|
-
const removed = this.messages.shift();
|
|
649
|
-
if (removed) {
|
|
650
|
-
totalChars -= removed.content.length;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
|
|
656
366
|
function resolveCodexAcpExecutionMode(mode) {
|
|
657
367
|
const approvalPolicy = (() => {
|
|
658
368
|
switch (mode.permissionMode) {
|
|
@@ -704,26 +414,6 @@ function getCodexExecutionFingerprint(mode) {
|
|
|
704
414
|
return hashObject(resolveCodexAcpExecutionMode(mode));
|
|
705
415
|
}
|
|
706
416
|
|
|
707
|
-
function createAbortError() {
|
|
708
|
-
const error = new Error("Operation aborted");
|
|
709
|
-
error.name = "AbortError";
|
|
710
|
-
return error;
|
|
711
|
-
}
|
|
712
|
-
async function waitForResponseCompleteWithAbort(backend, signal, timeoutMs = 12e4) {
|
|
713
|
-
if (!backend.waitForResponseComplete) {
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
|
-
if (signal.aborted) {
|
|
717
|
-
throw createAbortError();
|
|
718
|
-
}
|
|
719
|
-
await new Promise((resolve, reject) => {
|
|
720
|
-
const onAbort = () => reject(createAbortError());
|
|
721
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
722
|
-
backend.waitForResponseComplete(timeoutMs).then(resolve).catch(reject).finally(() => {
|
|
723
|
-
signal.removeEventListener("abort", onAbort);
|
|
724
|
-
});
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
417
|
function normalizeCodexBackendError(error) {
|
|
728
418
|
const record = typeof error === "object" && error !== null ? error : null;
|
|
729
419
|
const text = formatDisplayMessage(error).trim();
|
|
@@ -780,15 +470,14 @@ function registerCodexRemoteRpcHandlers(clientSession, handlers) {
|
|
|
780
470
|
registerKillSessionHandler(clientSession.rpcHandlerManager, handlers.handleKillSession);
|
|
781
471
|
}
|
|
782
472
|
async function codexRemoteLauncher(session) {
|
|
783
|
-
const messageBuffer = new MessageBuffer();
|
|
784
473
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
474
|
+
const messageBuffer = new MessageBuffer({ enabled: hasTTY });
|
|
785
475
|
let inkInstance = null;
|
|
786
476
|
let shouldExit = false;
|
|
787
477
|
let abortController = new AbortController();
|
|
788
478
|
let turnInFlight = false;
|
|
789
|
-
let
|
|
790
|
-
let
|
|
791
|
-
let wasSessionCreated = false;
|
|
479
|
+
let runtimeHandle = null;
|
|
480
|
+
let unsubscribeRuntimeMessages = null;
|
|
792
481
|
let currentModeHash = null;
|
|
793
482
|
let pending = null;
|
|
794
483
|
let readyAlreadySent = false;
|
|
@@ -801,7 +490,7 @@ async function codexRemoteLauncher(session) {
|
|
|
801
490
|
let currentThinkingMessageId = null;
|
|
802
491
|
const permissionHandler = new CodexPermissionHandler(session.client);
|
|
803
492
|
const selectionHandler = new CodexSelectionHandler(session.client);
|
|
804
|
-
const conversationHistory = new ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
|
|
493
|
+
const conversationHistory = new ConversationHistory$1({ maxMessages: 20, maxCharacters: 5e4 });
|
|
805
494
|
const reasoningProcessor = new ReasoningProcessor((message) => {
|
|
806
495
|
session.runtimeSession.sendCodexMessage(message);
|
|
807
496
|
});
|
|
@@ -837,22 +526,22 @@ async function codexRemoteLauncher(session) {
|
|
|
837
526
|
activeController.abort();
|
|
838
527
|
reasoningProcessor.abort();
|
|
839
528
|
session.onThinkingChange(false);
|
|
840
|
-
if (
|
|
841
|
-
void
|
|
529
|
+
if (runtimeHandle) {
|
|
530
|
+
void runtimeHandle.cancel().catch((error) => {
|
|
842
531
|
logger.debug("[Codex] Error cancelling ACP session:", error);
|
|
843
532
|
});
|
|
844
533
|
}
|
|
845
534
|
};
|
|
846
|
-
const
|
|
847
|
-
if (!
|
|
535
|
+
const disposeRuntimeHandle = async () => {
|
|
536
|
+
if (!runtimeHandle) {
|
|
848
537
|
return;
|
|
849
538
|
}
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
539
|
+
const activeRuntimeHandle = runtimeHandle;
|
|
540
|
+
runtimeHandle = null;
|
|
541
|
+
unsubscribeRuntimeMessages?.();
|
|
542
|
+
unsubscribeRuntimeMessages = null;
|
|
854
543
|
try {
|
|
855
|
-
await
|
|
544
|
+
await activeRuntimeHandle.dispose();
|
|
856
545
|
} catch (error) {
|
|
857
546
|
logger.debug("[Codex] Error disposing ACP backend:", error);
|
|
858
547
|
}
|
|
@@ -893,8 +582,16 @@ async function codexRemoteLauncher(session) {
|
|
|
893
582
|
accumulatedResponse = "";
|
|
894
583
|
isResponseInProgress = false;
|
|
895
584
|
};
|
|
896
|
-
const
|
|
897
|
-
|
|
585
|
+
const setupRuntimeMessageHandler = (activeRuntimeHandle) => {
|
|
586
|
+
const forwardAgentMessage = (agentMessage) => {
|
|
587
|
+
forwardAgentMessageToProviderSession(agentMessage, {
|
|
588
|
+
provider: "codex",
|
|
589
|
+
send: (body) => session.runtimeSession.sendCodexMessage(body),
|
|
590
|
+
toolResultType: "tool-call-result"
|
|
591
|
+
});
|
|
592
|
+
};
|
|
593
|
+
unsubscribeRuntimeMessages?.();
|
|
594
|
+
unsubscribeRuntimeMessages = activeRuntimeHandle.onMessage((msg) => {
|
|
898
595
|
switch (msg.type) {
|
|
899
596
|
case "model-output": {
|
|
900
597
|
const text = msg.textDelta ?? msg.fullText ?? "";
|
|
@@ -945,24 +642,11 @@ async function codexRemoteLauncher(session) {
|
|
|
945
642
|
}
|
|
946
643
|
case "tool-call": {
|
|
947
644
|
const toolArgs = msg.args ? truncateDisplayMessage(msg.args, 100) : "";
|
|
948
|
-
const canonicalToolName = resolveCanonicalToolNameV2(msg.toolName);
|
|
949
645
|
messageBuffer.addMessage(
|
|
950
646
|
`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}` : ""}`,
|
|
951
647
|
"tool"
|
|
952
648
|
);
|
|
953
|
-
|
|
954
|
-
type: "tool-call",
|
|
955
|
-
name: canonicalToolName,
|
|
956
|
-
callId: msg.callId,
|
|
957
|
-
input: attachToolHappierMetaV2(msg.args, {
|
|
958
|
-
v: 2,
|
|
959
|
-
protocol: "acp",
|
|
960
|
-
provider: "codex",
|
|
961
|
-
rawToolName: msg.toolName,
|
|
962
|
-
canonicalToolName
|
|
963
|
-
}),
|
|
964
|
-
id: randomUUID()
|
|
965
|
-
});
|
|
649
|
+
forwardAgentMessage(msg);
|
|
966
650
|
return;
|
|
967
651
|
}
|
|
968
652
|
case "tool-result": {
|
|
@@ -972,95 +656,37 @@ async function codexRemoteLauncher(session) {
|
|
|
972
656
|
`${isError ? "Error:" : "Result:"} ${resultText}`.trim(),
|
|
973
657
|
"result"
|
|
974
658
|
);
|
|
975
|
-
|
|
976
|
-
type: "tool-call-result",
|
|
977
|
-
callId: msg.callId,
|
|
978
|
-
output: attachToolHappierMetaV2(msg.result, {
|
|
979
|
-
v: 2,
|
|
980
|
-
protocol: "acp",
|
|
981
|
-
provider: "codex",
|
|
982
|
-
rawToolName: msg.toolName,
|
|
983
|
-
canonicalToolName: resolveCanonicalToolNameV2(msg.toolName)
|
|
984
|
-
}),
|
|
985
|
-
id: randomUUID(),
|
|
986
|
-
isError
|
|
987
|
-
});
|
|
659
|
+
forwardAgentMessage(msg);
|
|
988
660
|
return;
|
|
989
661
|
}
|
|
990
662
|
case "fs-edit": {
|
|
991
663
|
messageBuffer.addMessage(`File edit: ${msg.description}`, "tool");
|
|
992
|
-
|
|
993
|
-
type: "file-edit",
|
|
994
|
-
description: msg.description,
|
|
995
|
-
filePath: msg.path || "unknown",
|
|
996
|
-
diff: msg.diff,
|
|
997
|
-
id: randomUUID()
|
|
998
|
-
});
|
|
664
|
+
forwardAgentMessage(msg);
|
|
999
665
|
return;
|
|
1000
666
|
}
|
|
1001
667
|
case "terminal-output": {
|
|
1002
668
|
const terminalOutput = formatDisplayMessage(msg.data);
|
|
1003
669
|
messageBuffer.addMessage(terminalOutput, "result");
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
data: terminalOutput
|
|
1007
|
-
callId: msg.callId ?? randomUUID()
|
|
670
|
+
forwardAgentMessage({
|
|
671
|
+
...msg,
|
|
672
|
+
data: terminalOutput
|
|
1008
673
|
});
|
|
1009
674
|
return;
|
|
1010
675
|
}
|
|
1011
676
|
case "permission-request": {
|
|
1012
|
-
|
|
1013
|
-
session.runtimeSession.sendCodexMessage({
|
|
1014
|
-
type: "permission-request",
|
|
1015
|
-
permissionId: msg.id,
|
|
1016
|
-
toolName: typeof payload.toolName === "string" ? payload.toolName : msg.reason,
|
|
1017
|
-
description: msg.reason,
|
|
1018
|
-
options: payload
|
|
1019
|
-
});
|
|
677
|
+
forwardAgentMessage(msg);
|
|
1020
678
|
return;
|
|
1021
679
|
}
|
|
1022
680
|
case "exec-approval-request": {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
const rawToolName = "CodexBash";
|
|
1026
|
-
const canonicalToolName = resolveCanonicalToolNameV2(rawToolName);
|
|
1027
|
-
session.runtimeSession.sendCodexMessage({
|
|
1028
|
-
type: "tool-call",
|
|
1029
|
-
name: canonicalToolName,
|
|
1030
|
-
callId: call_id,
|
|
1031
|
-
input: attachToolHappierMetaV2(inputs, {
|
|
1032
|
-
v: 2,
|
|
1033
|
-
protocol: "acp",
|
|
1034
|
-
provider: "codex",
|
|
1035
|
-
rawToolName,
|
|
1036
|
-
canonicalToolName
|
|
1037
|
-
}),
|
|
1038
|
-
id: randomUUID()
|
|
1039
|
-
});
|
|
681
|
+
messageBuffer.addMessage(`Exec approval requested: ${msg.call_id}`, "tool");
|
|
682
|
+
forwardAgentMessage(msg);
|
|
1040
683
|
return;
|
|
1041
684
|
}
|
|
1042
685
|
case "patch-apply-begin": {
|
|
1043
686
|
const changeCount = Object.keys(msg.changes || {}).length;
|
|
1044
687
|
const filesMsg = changeCount === 1 ? "1 file" : `${changeCount} files`;
|
|
1045
688
|
messageBuffer.addMessage(`Modifying ${filesMsg}...`, "tool");
|
|
1046
|
-
|
|
1047
|
-
const canonicalToolName = resolveCanonicalToolNameV2(rawToolName);
|
|
1048
|
-
session.runtimeSession.sendCodexMessage({
|
|
1049
|
-
type: "tool-call",
|
|
1050
|
-
name: canonicalToolName,
|
|
1051
|
-
callId: msg.call_id,
|
|
1052
|
-
input: attachToolHappierMetaV2({
|
|
1053
|
-
auto_approved: msg.auto_approved,
|
|
1054
|
-
changes: msg.changes
|
|
1055
|
-
}, {
|
|
1056
|
-
v: 2,
|
|
1057
|
-
protocol: "acp",
|
|
1058
|
-
provider: "codex",
|
|
1059
|
-
rawToolName,
|
|
1060
|
-
canonicalToolName
|
|
1061
|
-
}),
|
|
1062
|
-
id: randomUUID()
|
|
1063
|
-
});
|
|
689
|
+
forwardAgentMessage(msg);
|
|
1064
690
|
return;
|
|
1065
691
|
}
|
|
1066
692
|
case "patch-apply-end": {
|
|
@@ -1069,30 +695,11 @@ async function codexRemoteLauncher(session) {
|
|
|
1069
695
|
} else {
|
|
1070
696
|
messageBuffer.addMessage(`Error: ${truncateDisplayMessage(msg.stderr || "Failed to modify files", 200)}`, "result");
|
|
1071
697
|
}
|
|
1072
|
-
|
|
1073
|
-
type: "tool-call-result",
|
|
1074
|
-
callId: msg.call_id,
|
|
1075
|
-
output: attachToolHappierMetaV2({
|
|
1076
|
-
stdout: msg.stdout,
|
|
1077
|
-
stderr: msg.stderr,
|
|
1078
|
-
success: msg.success
|
|
1079
|
-
}, {
|
|
1080
|
-
v: 2,
|
|
1081
|
-
protocol: "acp",
|
|
1082
|
-
provider: "codex",
|
|
1083
|
-
rawToolName: "CodexPatch",
|
|
1084
|
-
canonicalToolName: resolveCanonicalToolNameV2("CodexPatch")
|
|
1085
|
-
}),
|
|
1086
|
-
id: randomUUID(),
|
|
1087
|
-
isError: !msg.success
|
|
1088
|
-
});
|
|
698
|
+
forwardAgentMessage(msg);
|
|
1089
699
|
return;
|
|
1090
700
|
}
|
|
1091
701
|
case "token-count": {
|
|
1092
|
-
|
|
1093
|
-
...msg,
|
|
1094
|
-
id: randomUUID()
|
|
1095
|
-
});
|
|
702
|
+
forwardAgentMessage(msg);
|
|
1096
703
|
return;
|
|
1097
704
|
}
|
|
1098
705
|
case "event": {
|
|
@@ -1118,7 +725,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1118
725
|
}
|
|
1119
726
|
});
|
|
1120
727
|
};
|
|
1121
|
-
const
|
|
728
|
+
const createRuntimeHandle = async (mode) => {
|
|
1122
729
|
const executionMode = resolveCodexAcpExecutionMode(mode);
|
|
1123
730
|
const validation = validateCodexAcpSpawn({
|
|
1124
731
|
command: process.env.HAPPY_CODEX_ACP_COMMAND,
|
|
@@ -1130,20 +737,25 @@ async function codexRemoteLauncher(session) {
|
|
|
1130
737
|
if (!validation.ok) {
|
|
1131
738
|
throw new Error(validation.errorMessage);
|
|
1132
739
|
}
|
|
1133
|
-
const
|
|
740
|
+
const { session: nextRuntimeHandle } = await launchRuntimeHandleWithFactoryResult({
|
|
741
|
+
provider: "codex",
|
|
1134
742
|
cwd: session.path,
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
743
|
+
createBackendResult: (opts) => createCodexBackend({
|
|
744
|
+
...opts,
|
|
745
|
+
baseArgs: session.codexArgs,
|
|
746
|
+
model: executionMode.model,
|
|
747
|
+
sandbox: executionMode.sandbox,
|
|
748
|
+
approvalPolicy: executionMode.approvalPolicy,
|
|
749
|
+
permissionHandler,
|
|
750
|
+
selectionHandler: {
|
|
751
|
+
handleSelection: (request) => selectionHandler.requestSelection(request)
|
|
752
|
+
}
|
|
753
|
+
})
|
|
1143
754
|
});
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
755
|
+
runtimeHandle = nextRuntimeHandle;
|
|
756
|
+
setupRuntimeMessageHandler(nextRuntimeHandle);
|
|
757
|
+
session.onSessionFound(nextRuntimeHandle.sessionId);
|
|
758
|
+
return nextRuntimeHandle;
|
|
1147
759
|
};
|
|
1148
760
|
const handleSwitchToLocal = async () => {
|
|
1149
761
|
const message = getCodexLegacySwitchIgnoredMessage();
|
|
@@ -1162,17 +774,10 @@ async function codexRemoteLauncher(session) {
|
|
|
1162
774
|
logger.debug("[Codex] Kill session requested - terminating process");
|
|
1163
775
|
await handleAbort();
|
|
1164
776
|
try {
|
|
1165
|
-
session.runtimeSession
|
|
1166
|
-
...currentMetadata,
|
|
1167
|
-
lifecycleState: "archived",
|
|
1168
|
-
lifecycleStateSince: Date.now(),
|
|
1169
|
-
archivedBy: "cli",
|
|
777
|
+
await closeProviderSession(session.runtimeSession, {
|
|
1170
778
|
archiveReason: "User terminated"
|
|
1171
|
-
})
|
|
1172
|
-
|
|
1173
|
-
await session.runtimeSession.flush();
|
|
1174
|
-
await session.runtimeSession.close();
|
|
1175
|
-
await disposeBackend();
|
|
779
|
+
});
|
|
780
|
+
await disposeRuntimeHandle();
|
|
1176
781
|
stopCaffeinate();
|
|
1177
782
|
process.exit(0);
|
|
1178
783
|
} catch (error) {
|
|
@@ -1236,9 +841,9 @@ async function codexRemoteLauncher(session) {
|
|
|
1236
841
|
if (!message) {
|
|
1237
842
|
break;
|
|
1238
843
|
}
|
|
1239
|
-
if (
|
|
844
|
+
if (runtimeHandle && currentModeHash && message.hash !== currentModeHash) {
|
|
1240
845
|
queueHistoryInjectionForRestart("Starting new Codex session (execution settings changed)...");
|
|
1241
|
-
await
|
|
846
|
+
await disposeRuntimeHandle();
|
|
1242
847
|
session.clearSessionId();
|
|
1243
848
|
currentModeHash = null;
|
|
1244
849
|
pending = message;
|
|
@@ -1254,16 +859,10 @@ async function codexRemoteLauncher(session) {
|
|
|
1254
859
|
try {
|
|
1255
860
|
turnInFlight = true;
|
|
1256
861
|
shouldCommitAccumulatedResponse = false;
|
|
1257
|
-
const
|
|
1258
|
-
if (!
|
|
862
|
+
const activeRuntimeHandle = runtimeHandle ?? await createRuntimeHandle(message.mode);
|
|
863
|
+
if (!activeRuntimeHandle) {
|
|
1259
864
|
throw new Error("Failed to create Codex ACP backend");
|
|
1260
865
|
}
|
|
1261
|
-
if (!acpSessionId) {
|
|
1262
|
-
const { sessionId } = await activeBackend.startSession();
|
|
1263
|
-
acpSessionId = sessionId;
|
|
1264
|
-
wasSessionCreated = true;
|
|
1265
|
-
session.onSessionFound(sessionId);
|
|
1266
|
-
}
|
|
1267
866
|
session.onThinkingChange(true);
|
|
1268
867
|
let promptToSend = message.message;
|
|
1269
868
|
if (shouldInjectHistoryOnNextSession && conversationHistory.hasHistory()) {
|
|
@@ -1272,8 +871,8 @@ async function codexRemoteLauncher(session) {
|
|
|
1272
871
|
logger.debug(`[Codex] Injected conversation history context (${historyContext.length} chars)`);
|
|
1273
872
|
}
|
|
1274
873
|
conversationHistory.addUserMessage(message.message);
|
|
1275
|
-
await
|
|
1276
|
-
await waitForResponseCompleteWithAbort(
|
|
874
|
+
await activeRuntimeHandle.sendPrompt(promptToSend);
|
|
875
|
+
await waitForResponseCompleteWithAbort(activeRuntimeHandle.backend, turnSignal);
|
|
1277
876
|
reasoningProcessor.completeCurrent();
|
|
1278
877
|
shouldCommitAccumulatedResponse = true;
|
|
1279
878
|
shouldInjectHistoryOnNextSession = false;
|
|
@@ -1293,7 +892,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1293
892
|
if (conversationHistory.hasHistory()) {
|
|
1294
893
|
shouldInjectHistoryOnNextSession = true;
|
|
1295
894
|
}
|
|
1296
|
-
await
|
|
895
|
+
await disposeRuntimeHandle();
|
|
1297
896
|
session.clearSessionId();
|
|
1298
897
|
}
|
|
1299
898
|
} finally {
|
|
@@ -1322,7 +921,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1322
921
|
}
|
|
1323
922
|
}
|
|
1324
923
|
} finally {
|
|
1325
|
-
await
|
|
924
|
+
await disposeRuntimeHandle();
|
|
1326
925
|
permissionHandler.reset();
|
|
1327
926
|
selectionHandler.reset();
|
|
1328
927
|
session.removeClientSwapCallback(handleClientSwap);
|
|
@@ -1353,49 +952,24 @@ async function codexRemoteLauncher(session) {
|
|
|
1353
952
|
|
|
1354
953
|
async function codexLoop(opts) {
|
|
1355
954
|
const displayMode = opts.startingMode ?? "local";
|
|
1356
|
-
await opts.session.onModeChange(displayMode);
|
|
1357
955
|
logger.debug(`[codex-loop] Starting ACP-only Codex launcher with display mode: ${displayMode}`);
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
async
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
}
|
|
1373
|
-
await new Promise((resolve) => {
|
|
1374
|
-
let settled = false;
|
|
1375
|
-
const handleUpdated = () => {
|
|
1376
|
-
if (settled) {
|
|
1377
|
-
return;
|
|
1378
|
-
}
|
|
1379
|
-
settled = true;
|
|
1380
|
-
clearTimeout(timeout);
|
|
1381
|
-
sessionClient.off("agent-state-updated", handleUpdated);
|
|
1382
|
-
resolve();
|
|
1383
|
-
};
|
|
1384
|
-
const timeout = setTimeout(() => {
|
|
1385
|
-
if (settled) {
|
|
1386
|
-
return;
|
|
1387
|
-
}
|
|
1388
|
-
settled = true;
|
|
1389
|
-
sessionClient.off("agent-state-updated", handleUpdated);
|
|
1390
|
-
resolve();
|
|
1391
|
-
}, 1500);
|
|
1392
|
-
sessionClient.once("agent-state-updated", handleUpdated);
|
|
1393
|
-
sessionClient.updateAgentState((currentState) => ({
|
|
1394
|
-
...currentState,
|
|
1395
|
-
controlledByUser
|
|
1396
|
-
}));
|
|
956
|
+
const launchCurrentMode = async () => {
|
|
957
|
+
await codexRemoteLauncher(opts.session);
|
|
958
|
+
return { type: "exit", value: 0 };
|
|
959
|
+
};
|
|
960
|
+
return await runModeLoop({
|
|
961
|
+
startingMode: displayMode,
|
|
962
|
+
notifyInitialMode: true,
|
|
963
|
+
onModeChange: async (mode) => {
|
|
964
|
+
await opts.session.onModeChange(mode);
|
|
965
|
+
},
|
|
966
|
+
launchers: {
|
|
967
|
+
local: launchCurrentMode,
|
|
968
|
+
remote: launchCurrentMode
|
|
969
|
+
}
|
|
1397
970
|
});
|
|
1398
971
|
}
|
|
972
|
+
|
|
1399
973
|
function resolveInitialCodexPermissionMode(opts) {
|
|
1400
974
|
if (opts.permissionMode) {
|
|
1401
975
|
return opts.permissionMode;
|
|
@@ -1434,48 +1008,38 @@ async function runCodex(opts) {
|
|
|
1434
1008
|
}
|
|
1435
1009
|
const api = await ApiClient.create(opts.credentials);
|
|
1436
1010
|
logger.debug(`[codex] Starting with options: startedBy=${opts.startedBy || "terminal"}, requestedStartingMode=${requestedStartingMode}, executionMode=acp-only`);
|
|
1437
|
-
|
|
1438
|
-
const machineId = settings?.machineId;
|
|
1439
|
-
if (!machineId) {
|
|
1440
|
-
console.error("[START] No machine ID found in settings.");
|
|
1441
|
-
process.exit(1);
|
|
1442
|
-
}
|
|
1443
|
-
await api.getOrCreateMachine({
|
|
1444
|
-
machineId,
|
|
1445
|
-
metadata: initialMachineMetadata
|
|
1446
|
-
});
|
|
1447
|
-
const { state, metadata } = createSessionMetadata({
|
|
1448
|
-
flavor: "codex",
|
|
1449
|
-
machineId,
|
|
1450
|
-
startedBy: opts.startedBy
|
|
1451
|
-
});
|
|
1452
|
-
let response = null;
|
|
1011
|
+
let machineId;
|
|
1453
1012
|
try {
|
|
1454
|
-
|
|
1013
|
+
machineId = await ensureManagedProviderMachine({
|
|
1014
|
+
api,
|
|
1015
|
+
missingMachineIdMessage: "[START] No machine ID found in settings."
|
|
1016
|
+
});
|
|
1455
1017
|
} catch (error) {
|
|
1456
|
-
if (
|
|
1457
|
-
|
|
1018
|
+
if (error instanceof MissingMachineIdError) {
|
|
1019
|
+
console.error(error.message);
|
|
1020
|
+
process.exit(1);
|
|
1458
1021
|
}
|
|
1459
|
-
|
|
1022
|
+
throw error;
|
|
1460
1023
|
}
|
|
1461
1024
|
let sessionClient;
|
|
1462
1025
|
let codexSession = null;
|
|
1463
|
-
const { session: initialSession, reconnectionHandle } =
|
|
1026
|
+
const { metadata, session: initialSession, reconnectionHandle } = await bootstrapManagedProviderSession({
|
|
1464
1027
|
api,
|
|
1465
1028
|
sessionTag,
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1029
|
+
flavor: "codex",
|
|
1030
|
+
machineId,
|
|
1031
|
+
startedBy: opts.startedBy,
|
|
1032
|
+
authFallbackLogMessage: "[codex] Falling back to offline session stub after authentication failure",
|
|
1469
1033
|
onSessionSwap: (newSession) => {
|
|
1470
1034
|
sessionClient = newSession;
|
|
1471
1035
|
codexSession?.updateClient(newSession);
|
|
1472
|
-
void
|
|
1036
|
+
void syncControlledByUserState(
|
|
1037
|
+
newSession,
|
|
1038
|
+
(codexSession?.mode ?? requestedStartingMode) === "local"
|
|
1039
|
+
);
|
|
1473
1040
|
}
|
|
1474
1041
|
});
|
|
1475
1042
|
sessionClient = initialSession;
|
|
1476
|
-
if (response) {
|
|
1477
|
-
await publishSessionRegistration(response.id, metadata);
|
|
1478
|
-
}
|
|
1479
1043
|
const messageQueue = new MessageQueue2(getCodexExecutionFingerprint);
|
|
1480
1044
|
let currentPermissionMode = initialPermissionMode;
|
|
1481
1045
|
let currentModel;
|
|
@@ -1515,20 +1079,33 @@ async function runCodex(opts) {
|
|
|
1515
1079
|
await syncControlledByUserState(sessionClient, mode === "local");
|
|
1516
1080
|
}
|
|
1517
1081
|
});
|
|
1082
|
+
let exitCode = null;
|
|
1083
|
+
let loopError;
|
|
1084
|
+
let closeError;
|
|
1518
1085
|
try {
|
|
1519
|
-
|
|
1086
|
+
exitCode = await codexLoop({
|
|
1520
1087
|
session: codexSession,
|
|
1521
1088
|
startingMode: requestedStartingMode
|
|
1522
1089
|
});
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
await sessionClient.close();
|
|
1526
|
-
stopCaffeinate();
|
|
1527
|
-
process.exit(exitCode);
|
|
1090
|
+
} catch (error) {
|
|
1091
|
+
loopError = error;
|
|
1528
1092
|
} finally {
|
|
1093
|
+
try {
|
|
1094
|
+
await closeProviderSession(sessionClient);
|
|
1095
|
+
} catch (error) {
|
|
1096
|
+
closeError = error;
|
|
1097
|
+
}
|
|
1098
|
+
stopCaffeinate();
|
|
1529
1099
|
reconnectionHandle?.cancel();
|
|
1530
1100
|
codexSession.cleanup();
|
|
1531
1101
|
}
|
|
1102
|
+
if (loopError !== void 0) {
|
|
1103
|
+
throw loopError;
|
|
1104
|
+
}
|
|
1105
|
+
if (closeError !== void 0) {
|
|
1106
|
+
throw closeError;
|
|
1107
|
+
}
|
|
1108
|
+
process.exit(exitCode ?? 1);
|
|
1532
1109
|
}
|
|
1533
1110
|
|
|
1534
|
-
export { resolveIncomingCodexPermissionMode, resolveInitialCodexPermissionMode, resolveQueuedCodexPermissionMode, runCodex
|
|
1111
|
+
export { resolveIncomingCodexPermissionMode, resolveInitialCodexPermissionMode, resolveQueuedCodexPermissionMode, runCodex };
|