happy-imou-cloud 2.0.19 → 2.0.21

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 (28) hide show
  1. package/dist/{BaseReasoningProcessor-CTaamD5D.cjs → BaseReasoningProcessor-0nj-PMFc.cjs} +3 -3
  2. package/dist/{BaseReasoningProcessor-pY3tfQ0E.mjs → BaseReasoningProcessor-DnVC7liC.mjs} +3 -3
  3. package/dist/{ProviderSelectionHandler-CYs2k-z1.cjs → ProviderSelectionHandler-Bafuy28L.cjs} +2 -2
  4. package/dist/{ProviderSelectionHandler-C8pLBbE4.mjs → ProviderSelectionHandler-R-2r7ItM.mjs} +2 -2
  5. package/dist/{api-B922KGF8.mjs → api-DJe9WP9M.mjs} +77 -4
  6. package/dist/{api-DmpNsXS1.cjs → api-MGlKcEf3.cjs} +78 -3
  7. package/dist/{command-uX614XS4.mjs → command-CfyFnMv2.mjs} +3 -3
  8. package/dist/{command-B4L9Deq_.cjs → command-DAlFmWmr.cjs} +3 -3
  9. package/dist/{index-BkAY8k_1.mjs → index-CHXCgpwi.mjs} +48 -15
  10. package/dist/{index-D0VIxWJC.cjs → index-CgVjDJpt.cjs} +51 -18
  11. package/dist/index.cjs +3 -3
  12. package/dist/index.mjs +3 -3
  13. package/dist/lib.cjs +1 -1
  14. package/dist/lib.d.cts +357 -0
  15. package/dist/lib.d.mts +357 -0
  16. package/dist/lib.mjs +1 -1
  17. package/dist/{persistence-BfGHkCeJ.mjs → persistence-CkP90vEt.mjs} +1 -1
  18. package/dist/{persistence-ZZDZ6dl9.cjs → persistence-DLFUNI9q.cjs} +1 -1
  19. package/dist/{registerKillSessionHandler-DZ1sXUOg.cjs → registerKillSessionHandler-Cs_INk4A.cjs} +356 -3
  20. package/dist/{registerKillSessionHandler-BqeqMcNV.mjs → registerKillSessionHandler-DsHTZDsU.mjs} +354 -4
  21. package/dist/{runClaude-taQoQffg.cjs → runClaude-BGSgcyUp.cjs} +72 -9
  22. package/dist/{runClaude-CVBty_g7.mjs → runClaude-DAQAEmHe.mjs} +72 -9
  23. package/dist/{runCodex-jA1hK-nj.mjs → runCodex-B2UpSn82.mjs} +102 -14
  24. package/dist/{runCodex-JcA8vuC7.cjs → runCodex-earICaxw.cjs} +102 -14
  25. package/dist/{runGemini-BqKLrnid.mjs → runGemini-BBUmH1Qh.mjs} +73 -9
  26. package/dist/{runGemini-DZ0x4eaa.cjs → runGemini-D5RAIaR0.cjs} +73 -9
  27. package/package.json +1 -1
  28. package/scripts/release-smoke.mjs +20 -4
@@ -1,8 +1,8 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { l as logger, d as backoff, f as delay, g as AsyncLock, c as configuration, s as startOfflineReconnection, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-B922KGF8.mjs';
2
+ import { l as logger, f as backoff, g as delay, h as AsyncLock, c as configuration, s as startOfflineReconnection, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-DJe9WP9M.mjs';
3
3
  import 'cross-spawn';
4
4
  import '@agentclientprotocol/sdk';
5
- import { j as getProjectPath, F as Future, k as claudeLocal, E as ExitCodeError, l as trimIdent, m as createClaudeBackend, f as formatDisplayMessage, t as truncateDisplayMessage, n as claudeCheckSession, e as projectPath, o as mapToClaudeMode, P as PushableAsyncIterable, q as query, A as AbortError, b as stopCaffeinate, p as publishSessionRegistration, u as getEnvironmentInfo, w as startCaffeinate } from './index-BkAY8k_1.mjs';
5
+ import { j as getProjectPath, F as Future, k as claudeLocal, E as ExitCodeError, l as trimIdent, m as createClaudeBackend, f as formatDisplayMessage, t as truncateDisplayMessage, n as claudeCheckSession, e as projectPath, o as mapToClaudeMode, P as PushableAsyncIterable, q as query, A as AbortError, b as stopCaffeinate, p as publishSessionRegistration, u as getEnvironmentInfo, w as startCaffeinate } from './index-CHXCgpwi.mjs';
6
6
  import 'ps-list';
7
7
  import 'fs';
8
8
  import 'path';
@@ -13,7 +13,7 @@ import { dirname, basename, join, resolve } from 'node:path';
13
13
  import { homedir } from 'node:os';
14
14
  import { execSync } from 'node:child_process';
15
15
  import 'node:readline';
16
- import './persistence-BfGHkCeJ.mjs';
16
+ import './persistence-CkP90vEt.mjs';
17
17
  import { readFile } from 'node:fs/promises';
18
18
  import { stat, watch, access } from 'fs/promises';
19
19
  import 'crypto';
@@ -24,9 +24,9 @@ import 'tweetnacl';
24
24
  import 'open';
25
25
  import React, { useState, useRef, useEffect, useCallback } from 'react';
26
26
  import { useStdout, useInput, Box, Text, render } from 'ink';
27
- import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-C8pLBbE4.mjs';
27
+ import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-R-2r7ItM.mjs';
28
28
  import { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
29
- import { B as BasePermissionHandler, d as MessageBuffer, C as ConversationHistory$1, w as waitForResponseCompleteWithAbort, l as launchRuntimeHandleWithFactoryResult, j as forwardAgentMessageToProviderSession, s as syncControlledByUserState, e as ensureManagedProviderMachine, M as MissingMachineIdError, c as createSessionMetadata, b as MessageQueue2, h as hashObject, r as registerKillSessionHandler, f as closeProviderSession } from './registerKillSessionHandler-BqeqMcNV.mjs';
29
+ import { B as BasePermissionHandler, d as MessageBuffer, C as ConversationHistory$1, i as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, j as finalizeHappyOrgTurn, l as launchRuntimeHandleWithFactoryResult, n as forwardAgentMessageToProviderSession, s as syncControlledByUserState, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, c as createSessionMetadata, b as MessageQueue2, h as hashObject, f as registerKillSessionHandler, k as closeProviderSession } from './registerKillSessionHandler-DsHTZDsU.mjs';
30
30
  import 'socket.io-client';
31
31
  import 'expo-server-sdk';
32
32
  import { isDeepStrictEqual } from 'node:util';
@@ -1038,6 +1038,13 @@ async function claudeAcpRemoteLauncher(session) {
1038
1038
  message
1039
1039
  });
1040
1040
  };
1041
+ const emitTurnReport = (report) => {
1042
+ session.client.sendAgentMessage("claude", {
1043
+ type: "turn-report",
1044
+ id: randomUUID(),
1045
+ report
1046
+ });
1047
+ };
1041
1048
  const resetTurnState = () => {
1042
1049
  accumulatedResponse = "";
1043
1050
  isResponseInProgress = false;
@@ -1046,13 +1053,16 @@ async function claudeAcpRemoteLauncher(session) {
1046
1053
  currentThinkingMessageId = null;
1047
1054
  session.onThinkingChange(false);
1048
1055
  };
1049
- const emitFinalAssistantMessage = () => {
1050
- const finalMessage = accumulatedResponse.trim();
1056
+ const emitFinalAssistantMessage = (finalMessageText) => {
1057
+ const finalMessage = (finalMessageText ?? accumulatedResponse).trim();
1051
1058
  if (!finalMessage) {
1052
1059
  accumulatedResponse = "";
1053
1060
  isResponseInProgress = false;
1054
1061
  return;
1055
1062
  }
1063
+ if (currentAssistantMessageId) {
1064
+ messageBuffer.updateMessage(currentAssistantMessageId, finalMessage, { mode: "replace" });
1065
+ }
1056
1066
  conversationHistory.addAssistantMessage(finalMessage);
1057
1067
  session.client.sendAgentMessage("claude", {
1058
1068
  type: "message",
@@ -1364,6 +1374,7 @@ ${systemPrompt}` : systemPrompt,
1364
1374
  permissionHandler.setPermissionMode(message.mode.permissionMode);
1365
1375
  messageBuffer.addMessage(message.message, "user");
1366
1376
  let shouldClearHistoryAfterTurn = false;
1377
+ let turnStatus = "task_complete";
1367
1378
  try {
1368
1379
  const activeRuntimeHandle = runtimeHandle ?? await createRuntimeHandle(message.mode);
1369
1380
  let promptToSend = message.message;
@@ -1374,6 +1385,9 @@ ${systemPrompt}` : systemPrompt,
1374
1385
  promptToSend = historyContext + promptToSend;
1375
1386
  logger.debug(`[ClaudeACP] Injected conversation history context (${historyContext.length} chars)`);
1376
1387
  }
1388
+ if (message.mode.happyOrg) {
1389
+ promptToSend = buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
1390
+ }
1377
1391
  if (specialCommand.type === "compact") {
1378
1392
  emitStatusMessage("Compaction started");
1379
1393
  }
@@ -1387,6 +1401,7 @@ ${systemPrompt}` : systemPrompt,
1387
1401
  const isAbortError = error instanceof Error && error.name === "AbortError";
1388
1402
  const isExpectedInterruption = isAbortError || abortController.signal.aborted || shouldExit;
1389
1403
  if (isExpectedInterruption) {
1404
+ turnStatus = "turn_aborted";
1390
1405
  session.client.sendAgentMessage("claude", {
1391
1406
  type: "turn_aborted",
1392
1407
  id: randomUUID()
@@ -1403,7 +1418,23 @@ ${systemPrompt}` : systemPrompt,
1403
1418
  currentModeHash = null;
1404
1419
  }
1405
1420
  } finally {
1406
- emitFinalAssistantMessage();
1421
+ const finalizedTurn = finalizeHappyOrgTurn({
1422
+ metadata: session.client.getMetadataSnapshot?.() ?? null,
1423
+ queuedTurn: message.mode.happyOrg,
1424
+ responseText: accumulatedResponse,
1425
+ turnStatus
1426
+ });
1427
+ if (finalizedTurn.nextMetadata && typeof session.client.updateMetadata === "function") {
1428
+ session.client.updateMetadata(() => finalizedTurn.nextMetadata);
1429
+ }
1430
+ if (finalizedTurn.report) {
1431
+ emitTurnReport(finalizedTurn.report);
1432
+ }
1433
+ if (finalizedTurn.terminateMessage) {
1434
+ emitStatusMessage(finalizedTurn.terminateMessage);
1435
+ }
1436
+ accumulatedResponse = finalizedTurn.cleanedText;
1437
+ emitFinalAssistantMessage(finalizedTurn.cleanedText);
1407
1438
  if (shouldClearHistoryAfterTurn) {
1408
1439
  conversationHistory.clear();
1409
1440
  emitStatusMessage("Compaction completed");
@@ -3128,8 +3159,28 @@ function resolveClaudeQueuedMessage(message, currentState) {
3128
3159
  function bindClaudeUserMessageQueue(opts) {
3129
3160
  let currentState = { ...opts.initialState };
3130
3161
  opts.session.onUserMessage((message) => {
3162
+ const happyOrgResult = opts.happyOrg ? resolveHappyOrgQueuedTurn({
3163
+ metadata: opts.happyOrg.getMetadata(),
3164
+ message
3165
+ }) : {
3166
+ nextMetadata: null,
3167
+ queuedTurn: null,
3168
+ blocked: false,
3169
+ statusMessage: void 0
3170
+ };
3171
+ if (opts.happyOrg && happyOrgResult.nextMetadata) {
3172
+ opts.happyOrg.updateMetadata(() => happyOrgResult.nextMetadata);
3173
+ }
3174
+ if (happyOrgResult.blocked) {
3175
+ if (happyOrgResult.statusMessage) {
3176
+ opts.happyOrg?.emitStatusMessage(happyOrgResult.statusMessage);
3177
+ }
3178
+ logger.debugLargeJson("[claude] User message blocked by Happy Org runtime:", message);
3179
+ return;
3180
+ }
3131
3181
  const { nextState, queuedMessage } = resolveClaudeQueuedMessage(message, currentState);
3132
3182
  currentState = nextState;
3183
+ queuedMessage.mode.happyOrg = happyOrgResult.queuedTurn;
3133
3184
  if (queuedMessage.isolate) {
3134
3185
  logger.debug(`[claude] Queuing isolated special command: ${queuedMessage.specialCommand}`);
3135
3186
  opts.messageQueue.pushIsolateAndClear(queuedMessage.text, queuedMessage.mode);
@@ -3234,7 +3285,14 @@ async function runClaude(credentials, options = {}) {
3234
3285
  customSystemPrompt: mode.customSystemPrompt,
3235
3286
  appendSystemPrompt: mode.appendSystemPrompt,
3236
3287
  allowedTools: mode.allowedTools,
3237
- disallowedTools: mode.disallowedTools
3288
+ disallowedTools: mode.disallowedTools,
3289
+ happyOrg: mode.happyOrg ? {
3290
+ taskId: mode.happyOrg.context.taskId,
3291
+ organizationId: mode.happyOrg.context.organizationId,
3292
+ memberAgentId: mode.happyOrg.context.memberAgentId,
3293
+ supervisorAgentId: mode.happyOrg.context.supervisorAgentId,
3294
+ reopenContext: mode.happyOrg.reopenContext ?? null
3295
+ } : null
3238
3296
  }));
3239
3297
  bindClaudeUserMessageQueue({
3240
3298
  session,
@@ -3242,6 +3300,11 @@ async function runClaude(credentials, options = {}) {
3242
3300
  initialState: {
3243
3301
  permissionMode: options.permissionMode,
3244
3302
  model: options.model
3303
+ },
3304
+ happyOrg: {
3305
+ getMetadata: () => session.getMetadataSnapshot(),
3306
+ updateMetadata: (handler) => session.updateMetadata(handler),
3307
+ emitStatusMessage: (message) => session.sendSessionEvent({ type: "message", message })
3245
3308
  }
3246
3309
  });
3247
3310
  const cleanup = async () => {
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { l as logger, b as connectionState, A as ApiClient } from './api-B922KGF8.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-BqeqMcNV.mjs';
4
- import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate } from './index-BkAY8k_1.mjs';
2
+ import { l as logger, b as connectionState, A as ApiClient } from './api-DJe9WP9M.mjs';
3
+ import { B as BasePermissionHandler, h as hashObject, d as MessageBuffer, C as ConversationHistory$1, i as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, j as finalizeHappyOrgTurn, f as registerKillSessionHandler, l as launchRuntimeHandleWithFactoryResult, m as inferToolResultError, n as forwardAgentMessageToProviderSession, k as closeProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, r as resolveHappyOrgQueuedTurn, s as syncControlledByUserState } from './registerKillSessionHandler-DsHTZDsU.mjs';
4
+ import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate } from './index-CHXCgpwi.mjs';
5
5
  import 'cross-spawn';
6
6
  import '@agentclientprotocol/sdk';
7
7
  import 'ps-list';
@@ -14,7 +14,7 @@ import 'node:path';
14
14
  import 'node:os';
15
15
  import 'node:child_process';
16
16
  import 'node:readline';
17
- import './persistence-BfGHkCeJ.mjs';
17
+ import './persistence-CkP90vEt.mjs';
18
18
  import 'node:fs/promises';
19
19
  import 'fs/promises';
20
20
  import 'crypto';
@@ -25,8 +25,8 @@ import 'tweetnacl';
25
25
  import 'open';
26
26
  import React, { useState, useRef, useEffect, useCallback } from 'react';
27
27
  import { useStdout, useInput, Box, Text, render } from 'ink';
28
- import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-C8pLBbE4.mjs';
29
- import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-pY3tfQ0E.mjs';
28
+ import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-R-2r7ItM.mjs';
29
+ import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-DnVC7liC.mjs';
30
30
  import 'zod';
31
31
  import 'socket.io-client';
32
32
  import 'expo-server-sdk';
@@ -486,7 +486,16 @@ function resolveCodexAcpExecutionMode(mode) {
486
486
  };
487
487
  }
488
488
  function getCodexExecutionFingerprint(mode) {
489
- return hashObject(resolveCodexAcpExecutionMode(mode));
489
+ return hashObject({
490
+ ...resolveCodexAcpExecutionMode(mode),
491
+ happyOrg: mode.happyOrg ? {
492
+ taskId: mode.happyOrg.context.taskId,
493
+ organizationId: mode.happyOrg.context.organizationId,
494
+ memberAgentId: mode.happyOrg.context.memberAgentId,
495
+ supervisorAgentId: mode.happyOrg.context.supervisorAgentId,
496
+ reopenContext: mode.happyOrg.reopenContext ?? null
497
+ } : null
498
+ });
490
499
  }
491
500
 
492
501
  function normalizeCodexBackendError(error) {
@@ -564,6 +573,8 @@ async function codexRemoteLauncher(session) {
564
573
  let shouldCommitAccumulatedResponse = false;
565
574
  let currentAssistantMessageId = null;
566
575
  let currentThinkingMessageId = null;
576
+ let fatalRuntimeStopError = null;
577
+ let currentHappyOrgTurn = null;
567
578
  const permissionHandler = new CodexPermissionHandler(session.client);
568
579
  const selectionHandler = new CodexSelectionHandler(session.client);
569
580
  const conversationHistory = new ConversationHistory$1({ maxMessages: 20, maxCharacters: 5e4 });
@@ -596,6 +607,7 @@ async function codexRemoteLauncher(session) {
596
607
  shouldCommitAccumulatedResponse = false;
597
608
  currentAssistantMessageId = null;
598
609
  currentThinkingMessageId = null;
610
+ currentHappyOrgTurn = null;
599
611
  session.onThinkingChange(false);
600
612
  };
601
613
  const abortActiveTurn = () => {
@@ -635,6 +647,24 @@ async function codexRemoteLauncher(session) {
635
647
  id: randomUUID()
636
648
  });
637
649
  };
650
+ const emitTurnReport = (report) => {
651
+ session.runtimeSession.sendCodexMessage({
652
+ type: "turn-report",
653
+ id: randomUUID(),
654
+ report
655
+ });
656
+ };
657
+ const handleUnexpectedRuntimeStop = (detail) => {
658
+ if (shouldExit || fatalRuntimeStopError) {
659
+ return;
660
+ }
661
+ const errorMessage = normalizeCodexBackendError(detail);
662
+ fatalRuntimeStopError = new Error(errorMessage);
663
+ emitUserVisibleErrorMessage(errorMessage);
664
+ session.runtimeSession.sendSessionDeath();
665
+ shouldExit = true;
666
+ abortController.abort();
667
+ };
638
668
  const queueHistoryInjectionForRestart = (reason) => {
639
669
  messageBuffer.addMessage("\u2550".repeat(40), "status");
640
670
  if (conversationHistory.hasHistory()) {
@@ -646,17 +676,33 @@ async function codexRemoteLauncher(session) {
646
676
  }
647
677
  emitStatusMessage(reason);
648
678
  };
649
- const emitFinalAssistantMessage = () => {
650
- if (!accumulatedResponse.trim()) {
679
+ const emitFinalAssistantMessage = (finalMessageText) => {
680
+ const finalMessage = (finalMessageText ?? accumulatedResponse).trim();
681
+ if (!finalMessage) {
651
682
  return;
652
683
  }
653
- conversationHistory.addAssistantMessage(accumulatedResponse);
654
- emitPendingAssistantMessageDelta();
684
+ if (currentAssistantMessageId) {
685
+ messageBuffer.updateMessage(currentAssistantMessageId, finalMessage, { mode: "replace" });
686
+ }
687
+ conversationHistory.addAssistantMessage(finalMessage);
688
+ if (currentHappyOrgTurn) {
689
+ session.runtimeSession.sendCodexMessage({
690
+ type: "message",
691
+ message: finalMessage,
692
+ id: randomUUID()
693
+ });
694
+ } else {
695
+ accumulatedResponse = finalMessage;
696
+ emitPendingAssistantMessageDelta({ force: true });
697
+ }
655
698
  accumulatedResponse = "";
656
699
  emittedResponseLength = 0;
657
700
  isResponseInProgress = false;
658
701
  };
659
- const emitPendingAssistantMessageDelta = () => {
702
+ const emitPendingAssistantMessageDelta = (opts) => {
703
+ if (currentHappyOrgTurn && !opts?.force) {
704
+ return false;
705
+ }
660
706
  const nextMessage = accumulatedResponse.slice(emittedResponseLength);
661
707
  if (!nextMessage.trim()) {
662
708
  return false;
@@ -719,6 +765,9 @@ async function codexRemoteLauncher(session) {
719
765
  if (msg.status === "idle" || msg.status === "stopped") {
720
766
  emitPendingAssistantMessageDelta();
721
767
  reasoningProcessor.completeCurrent();
768
+ if (msg.status === "stopped" && !turnInFlight) {
769
+ handleUnexpectedRuntimeStop(msg.detail);
770
+ }
722
771
  return;
723
772
  }
724
773
  if (msg.status === "error") {
@@ -953,6 +1002,8 @@ async function codexRemoteLauncher(session) {
953
1002
  readyAlreadySent = false;
954
1003
  messageBuffer.addMessage(message.message, "user");
955
1004
  const turnSignal = abortController.signal;
1005
+ let turnStatus = "task_complete";
1006
+ currentHappyOrgTurn = message.mode.happyOrg ?? null;
956
1007
  try {
957
1008
  turnInFlight = true;
958
1009
  shouldCommitAccumulatedResponse = false;
@@ -967,6 +1018,9 @@ async function codexRemoteLauncher(session) {
967
1018
  promptToSend = historyContext + promptToSend;
968
1019
  logger.debug(`[Codex] Injected conversation history context (${historyContext.length} chars)`);
969
1020
  }
1021
+ if (message.mode.happyOrg) {
1022
+ promptToSend = buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
1023
+ }
970
1024
  conversationHistory.addUserMessage(message.message);
971
1025
  await activeRuntimeHandle.sendPrompt(promptToSend);
972
1026
  await waitForResponseCompleteWithAbort(activeRuntimeHandle.backend, turnSignal);
@@ -978,6 +1032,7 @@ async function codexRemoteLauncher(session) {
978
1032
  const isAbortError = error instanceof Error && error.name === "AbortError";
979
1033
  const isExpectedInterruption = isAbortError || turnSignal.aborted || shouldExit;
980
1034
  if (isExpectedInterruption) {
1035
+ turnStatus = "turn_aborted";
981
1036
  session.runtimeSession.sendCodexMessage({
982
1037
  type: "turn_aborted",
983
1038
  id: randomUUID()
@@ -994,8 +1049,24 @@ async function codexRemoteLauncher(session) {
994
1049
  }
995
1050
  } finally {
996
1051
  turnInFlight = false;
1052
+ const finalizedTurn = finalizeHappyOrgTurn({
1053
+ metadata: session.runtimeSession.getMetadataSnapshot?.() ?? null,
1054
+ queuedTurn: message.mode.happyOrg,
1055
+ responseText: accumulatedResponse,
1056
+ turnStatus
1057
+ });
1058
+ if (finalizedTurn.nextMetadata && typeof session.runtimeSession.updateMetadata === "function") {
1059
+ session.runtimeSession.updateMetadata(() => finalizedTurn.nextMetadata);
1060
+ }
1061
+ if (finalizedTurn.report) {
1062
+ emitTurnReport(finalizedTurn.report);
1063
+ }
1064
+ if (finalizedTurn.terminateMessage) {
1065
+ emitStatusMessage(finalizedTurn.terminateMessage);
1066
+ }
1067
+ accumulatedResponse = finalizedTurn.cleanedText;
997
1068
  if (shouldCommitAccumulatedResponse) {
998
- emitFinalAssistantMessage();
1069
+ emitFinalAssistantMessage(finalizedTurn.cleanedText);
999
1070
  }
1000
1071
  if (!shouldExit) {
1001
1072
  session.runtimeSession.sendCodexMessage({
@@ -1043,6 +1114,9 @@ async function codexRemoteLauncher(session) {
1043
1114
  }
1044
1115
  messageBuffer.clear();
1045
1116
  }
1117
+ if (fatalRuntimeStopError) {
1118
+ throw fatalRuntimeStopError;
1119
+ }
1046
1120
  logger.debug("[Codex] ACP remote launcher returning: exit", {
1047
1121
  shouldExit,
1048
1122
  queueClosed: session.queue.isClosed(),
@@ -1157,6 +1231,19 @@ async function runCodex(opts) {
1157
1231
  let currentPermissionMode = initialPermissionMode;
1158
1232
  let currentModel;
1159
1233
  sessionClient.onUserMessage((message) => {
1234
+ const happyOrgResult = resolveHappyOrgQueuedTurn({
1235
+ metadata: sessionClient.getMetadataSnapshot?.() ?? metadata,
1236
+ message
1237
+ });
1238
+ if (happyOrgResult.nextMetadata) {
1239
+ sessionClient.updateMetadata(() => happyOrgResult.nextMetadata);
1240
+ }
1241
+ if (happyOrgResult.blocked) {
1242
+ if (happyOrgResult.statusMessage) {
1243
+ sessionClient.sendSessionEvent({ type: "message", message: happyOrgResult.statusMessage });
1244
+ }
1245
+ return;
1246
+ }
1160
1247
  const previousPermissionMode = currentPermissionMode;
1161
1248
  let messagePermissionMode = previousPermissionMode;
1162
1249
  if (message.meta?.permissionMode) {
@@ -1175,7 +1262,8 @@ async function runCodex(opts) {
1175
1262
  }
1176
1263
  messageQueue.push(message.content.text, {
1177
1264
  permissionMode: permissionResolution.resolvedPermissionMode,
1178
- model: messageModel
1265
+ model: messageModel,
1266
+ happyOrg: happyOrgResult.queuedTurn
1179
1267
  });
1180
1268
  });
1181
1269
  codexSession = new CodexSession({
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var node_crypto = require('node:crypto');
4
- var api = require('./api-DmpNsXS1.cjs');
5
- var registerKillSessionHandler = require('./registerKillSessionHandler-DZ1sXUOg.cjs');
6
- var index = require('./index-D0VIxWJC.cjs');
4
+ var api = require('./api-MGlKcEf3.cjs');
5
+ var registerKillSessionHandler = require('./registerKillSessionHandler-Cs_INk4A.cjs');
6
+ var index = require('./index-CgVjDJpt.cjs');
7
7
  require('cross-spawn');
8
8
  require('@agentclientprotocol/sdk');
9
9
  require('ps-list');
@@ -16,7 +16,7 @@ require('node:path');
16
16
  require('node:os');
17
17
  require('node:child_process');
18
18
  require('node:readline');
19
- require('./persistence-ZZDZ6dl9.cjs');
19
+ require('./persistence-DLFUNI9q.cjs');
20
20
  require('node:fs/promises');
21
21
  require('fs/promises');
22
22
  require('crypto');
@@ -27,8 +27,8 @@ require('tweetnacl');
27
27
  require('open');
28
28
  var React = require('react');
29
29
  var ink = require('ink');
30
- var ProviderSelectionHandler = require('./ProviderSelectionHandler-CYs2k-z1.cjs');
31
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-CTaamD5D.cjs');
30
+ var ProviderSelectionHandler = require('./ProviderSelectionHandler-Bafuy28L.cjs');
31
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-0nj-PMFc.cjs');
32
32
  require('zod');
33
33
  require('socket.io-client');
34
34
  require('expo-server-sdk');
@@ -488,7 +488,16 @@ function resolveCodexAcpExecutionMode(mode) {
488
488
  };
489
489
  }
490
490
  function getCodexExecutionFingerprint(mode) {
491
- return registerKillSessionHandler.hashObject(resolveCodexAcpExecutionMode(mode));
491
+ return registerKillSessionHandler.hashObject({
492
+ ...resolveCodexAcpExecutionMode(mode),
493
+ happyOrg: mode.happyOrg ? {
494
+ taskId: mode.happyOrg.context.taskId,
495
+ organizationId: mode.happyOrg.context.organizationId,
496
+ memberAgentId: mode.happyOrg.context.memberAgentId,
497
+ supervisorAgentId: mode.happyOrg.context.supervisorAgentId,
498
+ reopenContext: mode.happyOrg.reopenContext ?? null
499
+ } : null
500
+ });
492
501
  }
493
502
 
494
503
  function normalizeCodexBackendError(error) {
@@ -566,6 +575,8 @@ async function codexRemoteLauncher(session) {
566
575
  let shouldCommitAccumulatedResponse = false;
567
576
  let currentAssistantMessageId = null;
568
577
  let currentThinkingMessageId = null;
578
+ let fatalRuntimeStopError = null;
579
+ let currentHappyOrgTurn = null;
569
580
  const permissionHandler = new CodexPermissionHandler(session.client);
570
581
  const selectionHandler = new CodexSelectionHandler(session.client);
571
582
  const conversationHistory = new registerKillSessionHandler.ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
@@ -598,6 +609,7 @@ async function codexRemoteLauncher(session) {
598
609
  shouldCommitAccumulatedResponse = false;
599
610
  currentAssistantMessageId = null;
600
611
  currentThinkingMessageId = null;
612
+ currentHappyOrgTurn = null;
601
613
  session.onThinkingChange(false);
602
614
  };
603
615
  const abortActiveTurn = () => {
@@ -637,6 +649,24 @@ async function codexRemoteLauncher(session) {
637
649
  id: node_crypto.randomUUID()
638
650
  });
639
651
  };
652
+ const emitTurnReport = (report) => {
653
+ session.runtimeSession.sendCodexMessage({
654
+ type: "turn-report",
655
+ id: node_crypto.randomUUID(),
656
+ report
657
+ });
658
+ };
659
+ const handleUnexpectedRuntimeStop = (detail) => {
660
+ if (shouldExit || fatalRuntimeStopError) {
661
+ return;
662
+ }
663
+ const errorMessage = normalizeCodexBackendError(detail);
664
+ fatalRuntimeStopError = new Error(errorMessage);
665
+ emitUserVisibleErrorMessage(errorMessage);
666
+ session.runtimeSession.sendSessionDeath();
667
+ shouldExit = true;
668
+ abortController.abort();
669
+ };
640
670
  const queueHistoryInjectionForRestart = (reason) => {
641
671
  messageBuffer.addMessage("\u2550".repeat(40), "status");
642
672
  if (conversationHistory.hasHistory()) {
@@ -648,17 +678,33 @@ async function codexRemoteLauncher(session) {
648
678
  }
649
679
  emitStatusMessage(reason);
650
680
  };
651
- const emitFinalAssistantMessage = () => {
652
- if (!accumulatedResponse.trim()) {
681
+ const emitFinalAssistantMessage = (finalMessageText) => {
682
+ const finalMessage = (finalMessageText ?? accumulatedResponse).trim();
683
+ if (!finalMessage) {
653
684
  return;
654
685
  }
655
- conversationHistory.addAssistantMessage(accumulatedResponse);
656
- emitPendingAssistantMessageDelta();
686
+ if (currentAssistantMessageId) {
687
+ messageBuffer.updateMessage(currentAssistantMessageId, finalMessage, { mode: "replace" });
688
+ }
689
+ conversationHistory.addAssistantMessage(finalMessage);
690
+ if (currentHappyOrgTurn) {
691
+ session.runtimeSession.sendCodexMessage({
692
+ type: "message",
693
+ message: finalMessage,
694
+ id: node_crypto.randomUUID()
695
+ });
696
+ } else {
697
+ accumulatedResponse = finalMessage;
698
+ emitPendingAssistantMessageDelta({ force: true });
699
+ }
657
700
  accumulatedResponse = "";
658
701
  emittedResponseLength = 0;
659
702
  isResponseInProgress = false;
660
703
  };
661
- const emitPendingAssistantMessageDelta = () => {
704
+ const emitPendingAssistantMessageDelta = (opts) => {
705
+ if (currentHappyOrgTurn && !opts?.force) {
706
+ return false;
707
+ }
662
708
  const nextMessage = accumulatedResponse.slice(emittedResponseLength);
663
709
  if (!nextMessage.trim()) {
664
710
  return false;
@@ -721,6 +767,9 @@ async function codexRemoteLauncher(session) {
721
767
  if (msg.status === "idle" || msg.status === "stopped") {
722
768
  emitPendingAssistantMessageDelta();
723
769
  reasoningProcessor.completeCurrent();
770
+ if (msg.status === "stopped" && !turnInFlight) {
771
+ handleUnexpectedRuntimeStop(msg.detail);
772
+ }
724
773
  return;
725
774
  }
726
775
  if (msg.status === "error") {
@@ -955,6 +1004,8 @@ async function codexRemoteLauncher(session) {
955
1004
  readyAlreadySent = false;
956
1005
  messageBuffer.addMessage(message.message, "user");
957
1006
  const turnSignal = abortController.signal;
1007
+ let turnStatus = "task_complete";
1008
+ currentHappyOrgTurn = message.mode.happyOrg ?? null;
958
1009
  try {
959
1010
  turnInFlight = true;
960
1011
  shouldCommitAccumulatedResponse = false;
@@ -969,6 +1020,9 @@ async function codexRemoteLauncher(session) {
969
1020
  promptToSend = historyContext + promptToSend;
970
1021
  api.logger.debug(`[Codex] Injected conversation history context (${historyContext.length} chars)`);
971
1022
  }
1023
+ if (message.mode.happyOrg) {
1024
+ promptToSend = registerKillSessionHandler.buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
1025
+ }
972
1026
  conversationHistory.addUserMessage(message.message);
973
1027
  await activeRuntimeHandle.sendPrompt(promptToSend);
974
1028
  await registerKillSessionHandler.waitForResponseCompleteWithAbort(activeRuntimeHandle.backend, turnSignal);
@@ -980,6 +1034,7 @@ async function codexRemoteLauncher(session) {
980
1034
  const isAbortError = error instanceof Error && error.name === "AbortError";
981
1035
  const isExpectedInterruption = isAbortError || turnSignal.aborted || shouldExit;
982
1036
  if (isExpectedInterruption) {
1037
+ turnStatus = "turn_aborted";
983
1038
  session.runtimeSession.sendCodexMessage({
984
1039
  type: "turn_aborted",
985
1040
  id: node_crypto.randomUUID()
@@ -996,8 +1051,24 @@ async function codexRemoteLauncher(session) {
996
1051
  }
997
1052
  } finally {
998
1053
  turnInFlight = false;
1054
+ const finalizedTurn = registerKillSessionHandler.finalizeHappyOrgTurn({
1055
+ metadata: session.runtimeSession.getMetadataSnapshot?.() ?? null,
1056
+ queuedTurn: message.mode.happyOrg,
1057
+ responseText: accumulatedResponse,
1058
+ turnStatus
1059
+ });
1060
+ if (finalizedTurn.nextMetadata && typeof session.runtimeSession.updateMetadata === "function") {
1061
+ session.runtimeSession.updateMetadata(() => finalizedTurn.nextMetadata);
1062
+ }
1063
+ if (finalizedTurn.report) {
1064
+ emitTurnReport(finalizedTurn.report);
1065
+ }
1066
+ if (finalizedTurn.terminateMessage) {
1067
+ emitStatusMessage(finalizedTurn.terminateMessage);
1068
+ }
1069
+ accumulatedResponse = finalizedTurn.cleanedText;
999
1070
  if (shouldCommitAccumulatedResponse) {
1000
- emitFinalAssistantMessage();
1071
+ emitFinalAssistantMessage(finalizedTurn.cleanedText);
1001
1072
  }
1002
1073
  if (!shouldExit) {
1003
1074
  session.runtimeSession.sendCodexMessage({
@@ -1045,6 +1116,9 @@ async function codexRemoteLauncher(session) {
1045
1116
  }
1046
1117
  messageBuffer.clear();
1047
1118
  }
1119
+ if (fatalRuntimeStopError) {
1120
+ throw fatalRuntimeStopError;
1121
+ }
1048
1122
  api.logger.debug("[Codex] ACP remote launcher returning: exit", {
1049
1123
  shouldExit,
1050
1124
  queueClosed: session.queue.isClosed(),
@@ -1159,6 +1233,19 @@ async function runCodex(opts) {
1159
1233
  let currentPermissionMode = initialPermissionMode;
1160
1234
  let currentModel;
1161
1235
  sessionClient.onUserMessage((message) => {
1236
+ const happyOrgResult = registerKillSessionHandler.resolveHappyOrgQueuedTurn({
1237
+ metadata: sessionClient.getMetadataSnapshot?.() ?? metadata,
1238
+ message
1239
+ });
1240
+ if (happyOrgResult.nextMetadata) {
1241
+ sessionClient.updateMetadata(() => happyOrgResult.nextMetadata);
1242
+ }
1243
+ if (happyOrgResult.blocked) {
1244
+ if (happyOrgResult.statusMessage) {
1245
+ sessionClient.sendSessionEvent({ type: "message", message: happyOrgResult.statusMessage });
1246
+ }
1247
+ return;
1248
+ }
1162
1249
  const previousPermissionMode = currentPermissionMode;
1163
1250
  let messagePermissionMode = previousPermissionMode;
1164
1251
  if (message.meta?.permissionMode) {
@@ -1177,7 +1264,8 @@ async function runCodex(opts) {
1177
1264
  }
1178
1265
  messageQueue.push(message.content.text, {
1179
1266
  permissionMode: permissionResolution.resolvedPermissionMode,
1180
- model: messageModel
1267
+ model: messageModel,
1268
+ happyOrg: happyOrgResult.queuedTurn
1181
1269
  });
1182
1270
  });
1183
1271
  codexSession = new CodexSession({