happy-imou-cloud 2.0.6 → 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/bin/happy-cloud.mjs +1 -1
  2. package/dist/{api-DccDghmF.cjs → api-CN-WqYd_.cjs} +3 -4
  3. package/dist/{api-Emo3rSZH.mjs → api-D-uiH_TF.mjs} +3 -4
  4. package/dist/{command-D8Zz6B4t.mjs → command-DGFsZx58.mjs} +3 -3
  5. package/dist/{command-C2v0VkPq.cjs → command-DjIfRZQS.cjs} +3 -3
  6. package/dist/{index-Buq7nurH.cjs → index-DM6z3aeG.cjs} +189 -27
  7. package/dist/{index-Dh8UTgm4.mjs → index-DhheEtRl.mjs} +187 -25
  8. package/dist/index.cjs +3 -3
  9. package/dist/index.mjs +3 -3
  10. package/dist/lib.cjs +1 -1
  11. package/dist/lib.mjs +1 -1
  12. package/dist/{BaseReasoningProcessor-1EzrE03x.mjs → names-BjEof0E2.mjs} +98 -3
  13. package/dist/{BaseReasoningProcessor-BMyfwx3p.cjs → names-BnV67N_O.cjs} +100 -2
  14. package/dist/{persistence-BrTyBuT7.cjs → persistence-DBGkO8gB.cjs} +110 -1
  15. package/dist/{persistence-Blm1hTQA.mjs → persistence-DiNg1DPF.mjs} +100 -4
  16. package/dist/{registerKillSessionHandler-EFAsOnR_.cjs → registerKillSessionHandler-CYc0SIjF.cjs} +26 -2
  17. package/dist/{registerKillSessionHandler-Bm7E-03E.mjs → registerKillSessionHandler-Cu9rHGsI.mjs} +26 -2
  18. package/dist/{runClaude-COy1pLhn.cjs → runClaude-CPhWaFrX.cjs} +5 -5
  19. package/dist/{runClaude-CwA5UCO-.mjs → runClaude-DAR_hw3C.mjs} +4 -4
  20. package/dist/{runCodex-BRMOT2dJ.cjs → runCodex--QLrOs8X.cjs} +53 -82
  21. package/dist/{runCodex-DTPmqCyS.mjs → runCodex-B4QAb-Go.mjs} +35 -63
  22. package/dist/{runGemini-BVPmTGxQ.cjs → runGemini-CDyhCucw.cjs} +20 -21
  23. package/dist/{runGemini-DDSR8BtO.mjs → runGemini-DqowSR2w.mjs} +5 -6
  24. package/package.json +3 -4
  25. package/scripts/build.mjs +66 -0
  26. package/scripts/release-smoke.mjs +166 -30
@@ -1,14 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var node_crypto = require('node:crypto');
4
- var api = require('./api-DccDghmF.cjs');
5
- var persistence = require('./persistence-BrTyBuT7.cjs');
6
- var index = require('./index-Buq7nurH.cjs');
7
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-BMyfwx3p.cjs');
8
- var registerKillSessionHandler = require('./registerKillSessionHandler-EFAsOnR_.cjs');
4
+ var api = require('./api-CN-WqYd_.cjs');
5
+ var persistence = require('./persistence-DBGkO8gB.cjs');
6
+ var index = require('./index-DM6z3aeG.cjs');
7
+ var names = require('./names-BnV67N_O.cjs');
8
+ var registerKillSessionHandler = require('./registerKillSessionHandler-CYc0SIjF.cjs');
9
9
  var React = require('react');
10
10
  var ink = require('ink');
11
- var happyProtocol = require('happy-protocol');
12
11
  require('axios');
13
12
  require('chalk');
14
13
  require('fs');
@@ -133,7 +132,6 @@ class CodexSession {
133
132
  keepAliveInterval;
134
133
  onModeChangeCallback;
135
134
  clientSwapCallbacks = [];
136
- supersedePendingInteractionsCallback = null;
137
135
  constructor(opts) {
138
136
  this.path = opts.path;
139
137
  this.api = opts.api;
@@ -174,12 +172,6 @@ class CodexSession {
174
172
  this.clientSwapCallbacks.splice(index, 1);
175
173
  }
176
174
  };
177
- setPendingInteractionSuperseder = (callback) => {
178
- this.supersedePendingInteractionsCallback = callback;
179
- };
180
- supersedePendingInteractions = (reason) => {
181
- return this.supersedePendingInteractionsCallback?.(reason) ?? false;
182
- };
183
175
  onThinkingChange = (thinking) => {
184
176
  this.thinking = thinking;
185
177
  this.client.keepAlive(thinking, this.mode);
@@ -320,7 +312,7 @@ const CodexDisplay = ({ messageBuffer, logPath, onExit, title }) => {
320
312
  ));
321
313
  };
322
314
 
323
- class CodexPermissionHandler extends BaseReasoningProcessor.BasePermissionHandler {
315
+ class CodexPermissionHandler extends names.BasePermissionHandler {
324
316
  constructor(session) {
325
317
  super(session);
326
318
  }
@@ -359,7 +351,7 @@ class CodexSelectionHandler {
359
351
  };
360
352
  pending.timeoutHandle = setTimeout(() => {
361
353
  this.handleSelectionTimeout(request.id, pending);
362
- }, BaseReasoningProcessor.getPendingInteractionTimeoutMs());
354
+ }, names.getPendingInteractionTimeoutMs());
363
355
  this.pendingRequests.set(request.id, pending);
364
356
  this.session.updateAgentState((currentState) => ({
365
357
  ...currentState,
@@ -395,7 +387,7 @@ class CodexSelectionHandler {
395
387
  hasPendingRequests() {
396
388
  return this.pendingRequests.size > 0;
397
389
  }
398
- supersedePendingRequests(reason = BaseReasoningProcessor.INTERACTION_SUPERSEDED_ERROR) {
390
+ supersedePendingRequests(reason = names.INTERACTION_SUPERSEDED_ERROR) {
399
391
  const pendingSnapshot = Array.from(this.pendingRequests.entries());
400
392
  if (pendingSnapshot.length === 0) {
401
393
  return 0;
@@ -507,7 +499,7 @@ class CodexSelectionHandler {
507
499
  }
508
500
  this.pendingRequests.delete(requestId);
509
501
  this.clearPendingRequestTimeout(active);
510
- active.reject(new Error(BaseReasoningProcessor.INTERACTION_TIMED_OUT_ERROR));
502
+ active.reject(new Error(names.INTERACTION_TIMED_OUT_ERROR));
511
503
  this.session.updateAgentState((currentState) => {
512
504
  const request = currentState.requests?.[requestId] || {
513
505
  tool: "AskUserQuestion",
@@ -530,7 +522,7 @@ class CodexSelectionHandler {
530
522
  ...request,
531
523
  completedAt: Date.now(),
532
524
  status: "canceled",
533
- reason: BaseReasoningProcessor.INTERACTION_TIMED_OUT_ERROR,
525
+ reason: names.INTERACTION_TIMED_OUT_ERROR,
534
526
  requestKind: "selection"
535
527
  }
536
528
  }
@@ -544,7 +536,7 @@ class CodexSelectionHandler {
544
536
  }
545
537
  }
546
538
 
547
- class ReasoningProcessor extends BaseReasoningProcessor.BaseReasoningProcessor {
539
+ class ReasoningProcessor extends names.BaseReasoningProcessor {
548
540
  getToolName() {
549
541
  return "CodexReasoning";
550
542
  }
@@ -784,21 +776,6 @@ function registerCodexRemoteRpcHandlers(clientSession, handlers) {
784
776
  clientSession.rpcHandlerManager.registerHandler("switch", handlers.handleSwitchToLocal);
785
777
  registerKillSessionHandler.registerKillSessionHandler(clientSession.rpcHandlerManager, handlers.handleKillSession);
786
778
  }
787
- function handleIncomingCodexMessageDuringRemoteTurn(opts) {
788
- const reason = opts.reason ?? BaseReasoningProcessor.INTERACTION_SUPERSEDED_ERROR;
789
- const supersededPermissions = opts.supersedePermissions(reason);
790
- const supersededSelections = opts.supersedeSelections(reason);
791
- const interruptedTurn = opts.turnInFlight;
792
- const total = supersededPermissions + supersededSelections;
793
- if (interruptedTurn) {
794
- opts.abortActiveTurn();
795
- }
796
- if (total > 0 || interruptedTurn) {
797
- const message = interruptedTurn ? "Current Codex task was canceled because a new user message arrived. Processing the latest message instead." : "Previous pending interaction was canceled because a new user message arrived. Processing the latest message instead.";
798
- opts.onInterrupted(message);
799
- }
800
- return total > 0 || interruptedTurn;
801
- }
802
779
  async function codexRemoteLauncher(session) {
803
780
  const messageBuffer = new registerKillSessionHandler.MessageBuffer();
804
781
  const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
@@ -816,6 +793,9 @@ async function codexRemoteLauncher(session) {
816
793
  let isResponseInProgress = false;
817
794
  let taskStartedSent = false;
818
795
  let shouldInjectHistoryOnNextSession = false;
796
+ let shouldCommitAccumulatedResponse = false;
797
+ let currentAssistantMessageId = null;
798
+ let currentThinkingMessageId = null;
819
799
  const permissionHandler = new CodexPermissionHandler(session.client);
820
800
  const selectionHandler = new CodexSelectionHandler(session.client);
821
801
  const conversationHistory = new ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
@@ -844,6 +824,9 @@ async function codexRemoteLauncher(session) {
844
824
  accumulatedResponse = "";
845
825
  isResponseInProgress = false;
846
826
  taskStartedSent = false;
827
+ shouldCommitAccumulatedResponse = false;
828
+ currentAssistantMessageId = null;
829
+ currentThinkingMessageId = null;
847
830
  session.onThinkingChange(false);
848
831
  };
849
832
  const abortActiveTurn = () => {
@@ -916,11 +899,17 @@ async function codexRemoteLauncher(session) {
916
899
  return;
917
900
  }
918
901
  if (!isResponseInProgress) {
919
- messageBuffer.removeLastMessage("system");
920
- messageBuffer.addMessage(text, "assistant");
902
+ if (currentThinkingMessageId) {
903
+ messageBuffer.removeMessage(currentThinkingMessageId);
904
+ currentThinkingMessageId = null;
905
+ }
906
+ currentAssistantMessageId = messageBuffer.addMessage(text, "assistant");
921
907
  isResponseInProgress = true;
922
908
  } else {
923
- messageBuffer.updateLastMessage(text, "assistant");
909
+ const updated = currentAssistantMessageId ? messageBuffer.updateMessage(currentAssistantMessageId, text) : false;
910
+ if (!updated) {
911
+ currentAssistantMessageId = messageBuffer.addMessage(text, "assistant");
912
+ }
924
913
  }
925
914
  accumulatedResponse += text;
926
915
  return;
@@ -935,8 +924,8 @@ async function codexRemoteLauncher(session) {
935
924
  });
936
925
  taskStartedSent = true;
937
926
  }
938
- if (!isResponseInProgress) {
939
- messageBuffer.addMessage("Thinking...", "system");
927
+ if (!isResponseInProgress && !currentThinkingMessageId) {
928
+ currentThinkingMessageId = messageBuffer.addMessage("Thinking...", "system");
940
929
  }
941
930
  return;
942
931
  }
@@ -953,7 +942,7 @@ async function codexRemoteLauncher(session) {
953
942
  }
954
943
  case "tool-call": {
955
944
  const toolArgs = msg.args ? index.truncateDisplayMessage(msg.args, 100) : "";
956
- const canonicalToolName = happyProtocol.resolveCanonicalToolNameV2(msg.toolName);
945
+ const canonicalToolName = names.resolveCanonicalToolNameV2(msg.toolName);
957
946
  messageBuffer.addMessage(
958
947
  `Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}` : ""}`,
959
948
  "tool"
@@ -962,7 +951,7 @@ async function codexRemoteLauncher(session) {
962
951
  type: "tool-call",
963
952
  name: canonicalToolName,
964
953
  callId: msg.callId,
965
- input: happyProtocol.attachToolHappierMetaV2(msg.args, {
954
+ input: names.attachToolHappierMetaV2(msg.args, {
966
955
  v: 2,
967
956
  protocol: "acp",
968
957
  provider: "codex",
@@ -974,7 +963,7 @@ async function codexRemoteLauncher(session) {
974
963
  return;
975
964
  }
976
965
  case "tool-result": {
977
- const isError = happyProtocol.inferToolResultError(msg.result);
966
+ const isError = names.inferToolResultError(msg.result);
978
967
  const resultText = index.truncateDisplayMessage(msg.result, 200) || (isError ? "Unknown error" : "");
979
968
  messageBuffer.addMessage(
980
969
  `${isError ? "Error:" : "Result:"} ${resultText}`.trim(),
@@ -983,12 +972,12 @@ async function codexRemoteLauncher(session) {
983
972
  session.runtimeSession.sendCodexMessage({
984
973
  type: "tool-call-result",
985
974
  callId: msg.callId,
986
- output: happyProtocol.attachToolHappierMetaV2(msg.result, {
975
+ output: names.attachToolHappierMetaV2(msg.result, {
987
976
  v: 2,
988
977
  protocol: "acp",
989
978
  provider: "codex",
990
979
  rawToolName: msg.toolName,
991
- canonicalToolName: happyProtocol.resolveCanonicalToolNameV2(msg.toolName)
980
+ canonicalToolName: names.resolveCanonicalToolNameV2(msg.toolName)
992
981
  }),
993
982
  id: node_crypto.randomUUID(),
994
983
  isError
@@ -1031,12 +1020,12 @@ async function codexRemoteLauncher(session) {
1031
1020
  const { call_id, type, ...inputs } = msg;
1032
1021
  messageBuffer.addMessage(`Exec approval requested: ${call_id}`, "tool");
1033
1022
  const rawToolName = "CodexBash";
1034
- const canonicalToolName = happyProtocol.resolveCanonicalToolNameV2(rawToolName);
1023
+ const canonicalToolName = names.resolveCanonicalToolNameV2(rawToolName);
1035
1024
  session.runtimeSession.sendCodexMessage({
1036
1025
  type: "tool-call",
1037
1026
  name: canonicalToolName,
1038
1027
  callId: call_id,
1039
- input: happyProtocol.attachToolHappierMetaV2(inputs, {
1028
+ input: names.attachToolHappierMetaV2(inputs, {
1040
1029
  v: 2,
1041
1030
  protocol: "acp",
1042
1031
  provider: "codex",
@@ -1052,12 +1041,12 @@ async function codexRemoteLauncher(session) {
1052
1041
  const filesMsg = changeCount === 1 ? "1 file" : `${changeCount} files`;
1053
1042
  messageBuffer.addMessage(`Modifying ${filesMsg}...`, "tool");
1054
1043
  const rawToolName = "CodexPatch";
1055
- const canonicalToolName = happyProtocol.resolveCanonicalToolNameV2(rawToolName);
1044
+ const canonicalToolName = names.resolveCanonicalToolNameV2(rawToolName);
1056
1045
  session.runtimeSession.sendCodexMessage({
1057
1046
  type: "tool-call",
1058
1047
  name: canonicalToolName,
1059
1048
  callId: msg.call_id,
1060
- input: happyProtocol.attachToolHappierMetaV2({
1049
+ input: names.attachToolHappierMetaV2({
1061
1050
  auto_approved: msg.auto_approved,
1062
1051
  changes: msg.changes
1063
1052
  }, {
@@ -1080,7 +1069,7 @@ async function codexRemoteLauncher(session) {
1080
1069
  session.runtimeSession.sendCodexMessage({
1081
1070
  type: "tool-call-result",
1082
1071
  callId: msg.call_id,
1083
- output: happyProtocol.attachToolHappierMetaV2({
1072
+ output: names.attachToolHappierMetaV2({
1084
1073
  stdout: msg.stdout,
1085
1074
  stderr: msg.stderr,
1086
1075
  success: msg.success
@@ -1089,7 +1078,7 @@ async function codexRemoteLauncher(session) {
1089
1078
  protocol: "acp",
1090
1079
  provider: "codex",
1091
1080
  rawToolName: "CodexPatch",
1092
- canonicalToolName: happyProtocol.resolveCanonicalToolNameV2("CodexPatch")
1081
+ canonicalToolName: names.resolveCanonicalToolNameV2("CodexPatch")
1093
1082
  }),
1094
1083
  id: node_crypto.randomUUID(),
1095
1084
  isError: !msg.success
@@ -1109,8 +1098,13 @@ async function codexRemoteLauncher(session) {
1109
1098
  const thinkingText = typeof thinkingPayload?.text === "string" ? thinkingPayload.text : "";
1110
1099
  if (thinkingText) {
1111
1100
  reasoningProcessor.processDelta(thinkingText);
1112
- if (!thinkingText.startsWith("**")) {
1113
- messageBuffer.updateLastMessage(`[Thinking] ${thinkingText.substring(0, 100)}...`, "system");
1101
+ if (!thinkingText.startsWith("**") && !isResponseInProgress) {
1102
+ const preview = `[Thinking] ${thinkingText.substring(0, 100)}...`;
1103
+ if (currentThinkingMessageId) {
1104
+ messageBuffer.updateMessage(currentThinkingMessageId, preview, { mode: "replace" });
1105
+ } else {
1106
+ currentThinkingMessageId = messageBuffer.addMessage(preview, "system");
1107
+ }
1114
1108
  }
1115
1109
  }
1116
1110
  }
@@ -1139,7 +1133,6 @@ async function codexRemoteLauncher(session) {
1139
1133
  model: executionMode.model,
1140
1134
  sandbox: executionMode.sandbox,
1141
1135
  approvalPolicy: executionMode.approvalPolicy,
1142
- mcpServers: {},
1143
1136
  permissionHandler,
1144
1137
  selectionHandler: {
1145
1138
  handleSelection: (request) => selectionHandler.requestSelection(request)
@@ -1154,20 +1147,6 @@ async function codexRemoteLauncher(session) {
1154
1147
  api.logger.debug("[Codex] Ignoring legacy switch request because Codex is ACP-only");
1155
1148
  emitStatusMessage(message);
1156
1149
  };
1157
- session.setPendingInteractionSuperseder((reason = BaseReasoningProcessor.INTERACTION_SUPERSEDED_ERROR) => {
1158
- return handleIncomingCodexMessageDuringRemoteTurn({
1159
- reason,
1160
- supersedePermissions: (value) => permissionHandler.supersedePendingRequests(value),
1161
- supersedeSelections: (value) => selectionHandler.supersedePendingRequests(value),
1162
- turnInFlight,
1163
- abortActiveTurn,
1164
- onInterrupted: (message) => {
1165
- api.logger.debug("[Codex] Incoming user message interrupted ACP remote turn");
1166
- messageBuffer.addMessage(message, "status");
1167
- session.runtimeSession.sendSessionEvent({ type: "message", message });
1168
- }
1169
- });
1170
- });
1171
1150
  async function handleAbort() {
1172
1151
  api.logger.debug("[Codex] Abort requested - stopping current task");
1173
1152
  try {
@@ -1271,6 +1250,7 @@ async function codexRemoteLauncher(session) {
1271
1250
  const turnSignal = abortController.signal;
1272
1251
  try {
1273
1252
  turnInFlight = true;
1253
+ shouldCommitAccumulatedResponse = false;
1274
1254
  const activeBackend = backend ?? createBackend(message.mode);
1275
1255
  if (!activeBackend) {
1276
1256
  throw new Error("Failed to create Codex ACP backend");
@@ -1292,6 +1272,7 @@ async function codexRemoteLauncher(session) {
1292
1272
  await activeBackend.sendPrompt(acpSessionId, promptToSend);
1293
1273
  await waitForResponseCompleteWithAbort(activeBackend, turnSignal);
1294
1274
  reasoningProcessor.completeCurrent();
1275
+ shouldCommitAccumulatedResponse = true;
1295
1276
  shouldInjectHistoryOnNextSession = false;
1296
1277
  } catch (error) {
1297
1278
  api.logger.warn("Error in codex ACP session:", error);
@@ -1314,7 +1295,9 @@ async function codexRemoteLauncher(session) {
1314
1295
  }
1315
1296
  } finally {
1316
1297
  turnInFlight = false;
1317
- emitFinalAssistantMessage();
1298
+ if (shouldCommitAccumulatedResponse) {
1299
+ emitFinalAssistantMessage();
1300
+ }
1318
1301
  if (!shouldExit) {
1319
1302
  session.runtimeSession.sendCodexMessage({
1320
1303
  type: "task_complete",
@@ -1339,7 +1322,6 @@ async function codexRemoteLauncher(session) {
1339
1322
  await disposeBackend();
1340
1323
  permissionHandler.reset();
1341
1324
  selectionHandler.reset();
1342
- session.setPendingInteractionSuperseder(null);
1343
1325
  session.removeClientSwapCallback(handleClientSwap);
1344
1326
  if (process.stdin.isTTY) {
1345
1327
  try {
@@ -1411,9 +1393,6 @@ async function syncControlledByUserState(sessionClient, controlledByUser) {
1411
1393
  }));
1412
1394
  });
1413
1395
  }
1414
- function shouldSupersedeCodexPendingInteractions(opts) {
1415
- return true;
1416
- }
1417
1396
  function resolveInitialCodexPermissionMode(opts) {
1418
1397
  if (opts.permissionMode) {
1419
1398
  return opts.permissionMode;
@@ -1462,7 +1441,7 @@ async function runCodex(opts) {
1462
1441
  machineId,
1463
1442
  metadata: index.initialMachineMetadata
1464
1443
  });
1465
- const { state, metadata } = BaseReasoningProcessor.createSessionMetadata({
1444
+ const { state, metadata } = names.createSessionMetadata({
1466
1445
  flavor: "codex",
1467
1446
  machineId,
1468
1447
  startedBy: opts.startedBy
@@ -1478,7 +1457,7 @@ async function runCodex(opts) {
1478
1457
  }
1479
1458
  let sessionClient;
1480
1459
  let codexSession = null;
1481
- const { session: initialSession, reconnectionHandle } = BaseReasoningProcessor.setupOfflineReconnection({
1460
+ const { session: initialSession, reconnectionHandle } = names.setupOfflineReconnection({
1482
1461
  api: api$1,
1483
1462
  sessionTag,
1484
1463
  metadata,
@@ -1520,13 +1499,6 @@ async function runCodex(opts) {
1520
1499
  messageModel = message.meta.model || void 0;
1521
1500
  currentModel = messageModel;
1522
1501
  }
1523
- if (shouldSupersedeCodexPendingInteractions({
1524
- startingMode: opts.startingMode,
1525
- currentMode: codexSession?.mode
1526
- })) {
1527
- api.logger.debug("[codex] Incoming user message superseding active remote interaction");
1528
- codexSession?.supersedePendingInteractions(BaseReasoningProcessor.INTERACTION_SUPERSEDED_ERROR);
1529
- }
1530
1502
  messageQueue.push(message.content.text, {
1531
1503
  permissionMode: permissionResolution.resolvedPermissionMode,
1532
1504
  model: messageModel
@@ -1566,6 +1538,5 @@ exports.resolveIncomingCodexPermissionMode = resolveIncomingCodexPermissionMode;
1566
1538
  exports.resolveInitialCodexPermissionMode = resolveInitialCodexPermissionMode;
1567
1539
  exports.resolveQueuedCodexPermissionMode = resolveQueuedCodexPermissionMode;
1568
1540
  exports.runCodex = runCodex;
1569
- exports.shouldSupersedeCodexPendingInteractions = shouldSupersedeCodexPendingInteractions;
1570
1541
  exports.supportsAgentStateUpdateEvents = supportsAgentStateUpdateEvents;
1571
1542
  exports.syncControlledByUserState = syncControlledByUserState;
@@ -1,12 +1,11 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-Emo3rSZH.mjs';
3
- import { readSettings } from './persistence-Blm1hTQA.mjs';
4
- import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate, i as initialMachineMetadata, n as notifyDaemonSessionStarted } from './index-Dh8UTgm4.mjs';
5
- import { B as BasePermissionHandler, g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, b as INTERACTION_TIMED_OUT_ERROR, a as BaseReasoningProcessor, c as createSessionMetadata, s as setupOfflineReconnection } from './BaseReasoningProcessor-1EzrE03x.mjs';
6
- import { h as hashObject, a as MessageBuffer, r as registerKillSessionHandler, M as MessageQueue2 } from './registerKillSessionHandler-Bm7E-03E.mjs';
2
+ import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-D-uiH_TF.mjs';
3
+ import { readSettings } from './persistence-DiNg1DPF.mjs';
4
+ import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate, i as initialMachineMetadata, n as notifyDaemonSessionStarted } from './index-DhheEtRl.mjs';
5
+ import { B as BasePermissionHandler, g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, d as INTERACTION_TIMED_OUT_ERROR, a as BaseReasoningProcessor, b as attachToolHappierMetaV2, r as resolveCanonicalToolNameV2, i as inferToolResultError, c as createSessionMetadata, s as setupOfflineReconnection } from './names-BjEof0E2.mjs';
6
+ import { h as hashObject, a as MessageBuffer, r as registerKillSessionHandler, M as MessageQueue2 } from './registerKillSessionHandler-Cu9rHGsI.mjs';
7
7
  import React, { useState, useRef, useEffect, useCallback } from 'react';
8
8
  import { useStdout, useInput, Box, Text, render } from 'ink';
9
- import { attachToolHappierMetaV2, resolveCanonicalToolNameV2, inferToolResultError } from 'happy-protocol';
10
9
  import 'axios';
11
10
  import 'chalk';
12
11
  import 'fs';
@@ -131,7 +130,6 @@ class CodexSession {
131
130
  keepAliveInterval;
132
131
  onModeChangeCallback;
133
132
  clientSwapCallbacks = [];
134
- supersedePendingInteractionsCallback = null;
135
133
  constructor(opts) {
136
134
  this.path = opts.path;
137
135
  this.api = opts.api;
@@ -172,12 +170,6 @@ class CodexSession {
172
170
  this.clientSwapCallbacks.splice(index, 1);
173
171
  }
174
172
  };
175
- setPendingInteractionSuperseder = (callback) => {
176
- this.supersedePendingInteractionsCallback = callback;
177
- };
178
- supersedePendingInteractions = (reason) => {
179
- return this.supersedePendingInteractionsCallback?.(reason) ?? false;
180
- };
181
173
  onThinkingChange = (thinking) => {
182
174
  this.thinking = thinking;
183
175
  this.client.keepAlive(thinking, this.mode);
@@ -782,21 +774,6 @@ function registerCodexRemoteRpcHandlers(clientSession, handlers) {
782
774
  clientSession.rpcHandlerManager.registerHandler("switch", handlers.handleSwitchToLocal);
783
775
  registerKillSessionHandler(clientSession.rpcHandlerManager, handlers.handleKillSession);
784
776
  }
785
- function handleIncomingCodexMessageDuringRemoteTurn(opts) {
786
- const reason = opts.reason ?? INTERACTION_SUPERSEDED_ERROR;
787
- const supersededPermissions = opts.supersedePermissions(reason);
788
- const supersededSelections = opts.supersedeSelections(reason);
789
- const interruptedTurn = opts.turnInFlight;
790
- const total = supersededPermissions + supersededSelections;
791
- if (interruptedTurn) {
792
- opts.abortActiveTurn();
793
- }
794
- if (total > 0 || interruptedTurn) {
795
- const message = interruptedTurn ? "Current Codex task was canceled because a new user message arrived. Processing the latest message instead." : "Previous pending interaction was canceled because a new user message arrived. Processing the latest message instead.";
796
- opts.onInterrupted(message);
797
- }
798
- return total > 0 || interruptedTurn;
799
- }
800
777
  async function codexRemoteLauncher(session) {
801
778
  const messageBuffer = new MessageBuffer();
802
779
  const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
@@ -814,6 +791,9 @@ async function codexRemoteLauncher(session) {
814
791
  let isResponseInProgress = false;
815
792
  let taskStartedSent = false;
816
793
  let shouldInjectHistoryOnNextSession = false;
794
+ let shouldCommitAccumulatedResponse = false;
795
+ let currentAssistantMessageId = null;
796
+ let currentThinkingMessageId = null;
817
797
  const permissionHandler = new CodexPermissionHandler(session.client);
818
798
  const selectionHandler = new CodexSelectionHandler(session.client);
819
799
  const conversationHistory = new ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
@@ -842,6 +822,9 @@ async function codexRemoteLauncher(session) {
842
822
  accumulatedResponse = "";
843
823
  isResponseInProgress = false;
844
824
  taskStartedSent = false;
825
+ shouldCommitAccumulatedResponse = false;
826
+ currentAssistantMessageId = null;
827
+ currentThinkingMessageId = null;
845
828
  session.onThinkingChange(false);
846
829
  };
847
830
  const abortActiveTurn = () => {
@@ -914,11 +897,17 @@ async function codexRemoteLauncher(session) {
914
897
  return;
915
898
  }
916
899
  if (!isResponseInProgress) {
917
- messageBuffer.removeLastMessage("system");
918
- messageBuffer.addMessage(text, "assistant");
900
+ if (currentThinkingMessageId) {
901
+ messageBuffer.removeMessage(currentThinkingMessageId);
902
+ currentThinkingMessageId = null;
903
+ }
904
+ currentAssistantMessageId = messageBuffer.addMessage(text, "assistant");
919
905
  isResponseInProgress = true;
920
906
  } else {
921
- messageBuffer.updateLastMessage(text, "assistant");
907
+ const updated = currentAssistantMessageId ? messageBuffer.updateMessage(currentAssistantMessageId, text) : false;
908
+ if (!updated) {
909
+ currentAssistantMessageId = messageBuffer.addMessage(text, "assistant");
910
+ }
922
911
  }
923
912
  accumulatedResponse += text;
924
913
  return;
@@ -933,8 +922,8 @@ async function codexRemoteLauncher(session) {
933
922
  });
934
923
  taskStartedSent = true;
935
924
  }
936
- if (!isResponseInProgress) {
937
- messageBuffer.addMessage("Thinking...", "system");
925
+ if (!isResponseInProgress && !currentThinkingMessageId) {
926
+ currentThinkingMessageId = messageBuffer.addMessage("Thinking...", "system");
938
927
  }
939
928
  return;
940
929
  }
@@ -1107,8 +1096,13 @@ async function codexRemoteLauncher(session) {
1107
1096
  const thinkingText = typeof thinkingPayload?.text === "string" ? thinkingPayload.text : "";
1108
1097
  if (thinkingText) {
1109
1098
  reasoningProcessor.processDelta(thinkingText);
1110
- if (!thinkingText.startsWith("**")) {
1111
- messageBuffer.updateLastMessage(`[Thinking] ${thinkingText.substring(0, 100)}...`, "system");
1099
+ if (!thinkingText.startsWith("**") && !isResponseInProgress) {
1100
+ const preview = `[Thinking] ${thinkingText.substring(0, 100)}...`;
1101
+ if (currentThinkingMessageId) {
1102
+ messageBuffer.updateMessage(currentThinkingMessageId, preview, { mode: "replace" });
1103
+ } else {
1104
+ currentThinkingMessageId = messageBuffer.addMessage(preview, "system");
1105
+ }
1112
1106
  }
1113
1107
  }
1114
1108
  }
@@ -1137,7 +1131,6 @@ async function codexRemoteLauncher(session) {
1137
1131
  model: executionMode.model,
1138
1132
  sandbox: executionMode.sandbox,
1139
1133
  approvalPolicy: executionMode.approvalPolicy,
1140
- mcpServers: {},
1141
1134
  permissionHandler,
1142
1135
  selectionHandler: {
1143
1136
  handleSelection: (request) => selectionHandler.requestSelection(request)
@@ -1152,20 +1145,6 @@ async function codexRemoteLauncher(session) {
1152
1145
  logger.debug("[Codex] Ignoring legacy switch request because Codex is ACP-only");
1153
1146
  emitStatusMessage(message);
1154
1147
  };
1155
- session.setPendingInteractionSuperseder((reason = INTERACTION_SUPERSEDED_ERROR) => {
1156
- return handleIncomingCodexMessageDuringRemoteTurn({
1157
- reason,
1158
- supersedePermissions: (value) => permissionHandler.supersedePendingRequests(value),
1159
- supersedeSelections: (value) => selectionHandler.supersedePendingRequests(value),
1160
- turnInFlight,
1161
- abortActiveTurn,
1162
- onInterrupted: (message) => {
1163
- logger.debug("[Codex] Incoming user message interrupted ACP remote turn");
1164
- messageBuffer.addMessage(message, "status");
1165
- session.runtimeSession.sendSessionEvent({ type: "message", message });
1166
- }
1167
- });
1168
- });
1169
1148
  async function handleAbort() {
1170
1149
  logger.debug("[Codex] Abort requested - stopping current task");
1171
1150
  try {
@@ -1269,6 +1248,7 @@ async function codexRemoteLauncher(session) {
1269
1248
  const turnSignal = abortController.signal;
1270
1249
  try {
1271
1250
  turnInFlight = true;
1251
+ shouldCommitAccumulatedResponse = false;
1272
1252
  const activeBackend = backend ?? createBackend(message.mode);
1273
1253
  if (!activeBackend) {
1274
1254
  throw new Error("Failed to create Codex ACP backend");
@@ -1290,6 +1270,7 @@ async function codexRemoteLauncher(session) {
1290
1270
  await activeBackend.sendPrompt(acpSessionId, promptToSend);
1291
1271
  await waitForResponseCompleteWithAbort(activeBackend, turnSignal);
1292
1272
  reasoningProcessor.completeCurrent();
1273
+ shouldCommitAccumulatedResponse = true;
1293
1274
  shouldInjectHistoryOnNextSession = false;
1294
1275
  } catch (error) {
1295
1276
  logger.warn("Error in codex ACP session:", error);
@@ -1312,7 +1293,9 @@ async function codexRemoteLauncher(session) {
1312
1293
  }
1313
1294
  } finally {
1314
1295
  turnInFlight = false;
1315
- emitFinalAssistantMessage();
1296
+ if (shouldCommitAccumulatedResponse) {
1297
+ emitFinalAssistantMessage();
1298
+ }
1316
1299
  if (!shouldExit) {
1317
1300
  session.runtimeSession.sendCodexMessage({
1318
1301
  type: "task_complete",
@@ -1337,7 +1320,6 @@ async function codexRemoteLauncher(session) {
1337
1320
  await disposeBackend();
1338
1321
  permissionHandler.reset();
1339
1322
  selectionHandler.reset();
1340
- session.setPendingInteractionSuperseder(null);
1341
1323
  session.removeClientSwapCallback(handleClientSwap);
1342
1324
  if (process.stdin.isTTY) {
1343
1325
  try {
@@ -1409,9 +1391,6 @@ async function syncControlledByUserState(sessionClient, controlledByUser) {
1409
1391
  }));
1410
1392
  });
1411
1393
  }
1412
- function shouldSupersedeCodexPendingInteractions(opts) {
1413
- return true;
1414
- }
1415
1394
  function resolveInitialCodexPermissionMode(opts) {
1416
1395
  if (opts.permissionMode) {
1417
1396
  return opts.permissionMode;
@@ -1518,13 +1497,6 @@ async function runCodex(opts) {
1518
1497
  messageModel = message.meta.model || void 0;
1519
1498
  currentModel = messageModel;
1520
1499
  }
1521
- if (shouldSupersedeCodexPendingInteractions({
1522
- startingMode: opts.startingMode,
1523
- currentMode: codexSession?.mode
1524
- })) {
1525
- logger.debug("[codex] Incoming user message superseding active remote interaction");
1526
- codexSession?.supersedePendingInteractions(INTERACTION_SUPERSEDED_ERROR);
1527
- }
1528
1500
  messageQueue.push(message.content.text, {
1529
1501
  permissionMode: permissionResolution.resolvedPermissionMode,
1530
1502
  model: messageModel
@@ -1560,4 +1532,4 @@ async function runCodex(opts) {
1560
1532
  }
1561
1533
  }
1562
1534
 
1563
- export { resolveIncomingCodexPermissionMode, resolveInitialCodexPermissionMode, resolveQueuedCodexPermissionMode, runCodex, shouldSupersedeCodexPendingInteractions, supportsAgentStateUpdateEvents, syncControlledByUserState };
1535
+ export { resolveIncomingCodexPermissionMode, resolveInitialCodexPermissionMode, resolveQueuedCodexPermissionMode, runCodex, supportsAgentStateUpdateEvents, syncControlledByUserState };