happy-imou-cloud 2.1.28 → 2.1.30

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/dist/{BaseReasoningProcessor-DYVFvY85.mjs → BaseReasoningProcessor-C1iacoJW.mjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-AsSwxX2U.cjs → BaseReasoningProcessor-Ch9R4qmn.cjs} +2 -2
  3. package/dist/{ProviderSelectionHandler-Cd_vN8wA.mjs → ProviderSelectionHandler-2siFKlgs.mjs} +2 -2
  4. package/dist/{ProviderSelectionHandler-BKfo21qx.cjs → ProviderSelectionHandler-Dx6x0Nd4.cjs} +2 -2
  5. package/dist/{api-DYS9sGJr.mjs → api-C68U-kRs.mjs} +626 -126
  6. package/dist/{api-ChV_1TP7.cjs → api-DK1gyZAZ.cjs} +626 -126
  7. package/dist/{command-ErrXrwTw.cjs → command-Cb9nikZh.cjs} +2 -2
  8. package/dist/{command-Bx9UY5D5.mjs → command-D32x08k9.mjs} +2 -2
  9. package/dist/{index-CDyeCS7U.cjs → index-BLeiCte-.cjs} +174 -32
  10. package/dist/{index-DtlrIihs.mjs → index-DQ76ZTNL.mjs} +171 -29
  11. package/dist/index.cjs +2 -2
  12. package/dist/index.mjs +2 -2
  13. package/dist/lib.cjs +1 -1
  14. package/dist/lib.d.cts +100 -0
  15. package/dist/lib.d.mts +100 -0
  16. package/dist/lib.mjs +1 -1
  17. package/dist/{registerKillSessionHandler-IlzXqONk.mjs → registerKillSessionHandler-CadrzRgP.mjs} +16 -6
  18. package/dist/{registerKillSessionHandler-CBuJR_D8.cjs → registerKillSessionHandler-DD9uUk4w.cjs} +16 -6
  19. package/dist/{runClaude-VlpAUO9C.mjs → runClaude-CkY6XYJa.mjs} +4 -4
  20. package/dist/{runClaude-D_YCDVmM.cjs → runClaude-U9sxsnU-.cjs} +4 -4
  21. package/dist/{runCodex-jisfibyM.cjs → runCodex-Beikmv-L.cjs} +134 -9
  22. package/dist/{runCodex-CL1yQHxl.mjs → runCodex-C6kV0jfX.mjs} +134 -9
  23. package/dist/{runGemini-BtBrzhkF.cjs → runGemini-BTyqf5MR.cjs} +4 -4
  24. package/dist/{runGemini-EPv-yxY4.mjs → runGemini-IEzJdhc-.mjs} +4 -4
  25. package/package.json +1 -1
  26. package/scripts/release-smoke.mjs +3 -0
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var persistence = require('./api-ChV_1TP7.cjs');
4
- var registerKillSessionHandler = require('./registerKillSessionHandler-CBuJR_D8.cjs');
5
- var index = require('./index-CDyeCS7U.cjs');
3
+ var persistence = require('./api-DK1gyZAZ.cjs');
4
+ var registerKillSessionHandler = require('./registerKillSessionHandler-DD9uUk4w.cjs');
5
+ var index = require('./index-BLeiCte-.cjs');
6
6
  require('cross-spawn');
7
7
  require('@agentclientprotocol/sdk');
8
8
  var node_crypto = require('node:crypto');
@@ -26,8 +26,8 @@ require('tweetnacl');
26
26
  require('open');
27
27
  var React = require('react');
28
28
  var ink = require('ink');
29
- var ProviderSelectionHandler = require('./ProviderSelectionHandler-BKfo21qx.cjs');
30
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-AsSwxX2U.cjs');
29
+ var ProviderSelectionHandler = require('./ProviderSelectionHandler-Dx6x0Nd4.cjs');
30
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-Ch9R4qmn.cjs');
31
31
  require('zod');
32
32
  require('socket.io-client');
33
33
  require('expo-server-sdk');
@@ -505,6 +505,110 @@ function getCodexExecutionFingerprint(mode) {
505
505
  });
506
506
  }
507
507
 
508
+ const WINDOWS_FAIL_FAST_EXIT_CODE = 3221226505;
509
+ const CODEX_LARGE_OUTPUT_RECOVERY_HINT = `[HAPPY RUNTIME NOTE]
510
+ The previous Codex process exited while handling oversized command output.
511
+ Avoid commands that dump full build/test/log output into the session.
512
+ Redirect long output to a file and inspect summaries or tails instead.`;
513
+ function buildErrorPrefix(record) {
514
+ if (!record) {
515
+ return "";
516
+ }
517
+ return [
518
+ record.code !== void 0 && record.code !== null ? `[code=${String(record.code)}]` : "",
519
+ record.status !== void 0 && record.status !== null ? `[status=${String(record.status)}]` : ""
520
+ ].filter(Boolean).join(" ");
521
+ }
522
+ function formatWindowsExitCode(exitCode) {
523
+ if (process.platform !== "win32" || !Number.isInteger(exitCode) || exitCode < 0) {
524
+ return null;
525
+ }
526
+ return `0x${(exitCode >>> 0).toString(16).toUpperCase().padStart(8, "0")}`;
527
+ }
528
+ function extractFirstRelevantStderrLine(stderrText) {
529
+ const lines = stderrText.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
530
+ for (const line of lines) {
531
+ if (!/^note:\s+run with\b/i.test(line)) {
532
+ return line;
533
+ }
534
+ }
535
+ return lines[0] ?? null;
536
+ }
537
+ function looksLikeUpstreamApiError(searchableLower) {
538
+ return searchableLower.includes("upstream") || searchableLower.includes("rate limit") || searchableLower.includes("429") || searchableLower.includes("quota") || searchableLower.includes("insufficient_quota") || searchableLower.includes("unauthorized") || searchableLower.includes("forbidden");
539
+ }
540
+ function extractLocalProcessExit(error) {
541
+ const record = typeof error === "object" && error !== null ? error : null;
542
+ const text = index.formatDisplayMessage(error).trim();
543
+ const stderrTextFromRecord = record ? index.formatDisplayMessage(record.stderr).trim() : "";
544
+ const stderrFromTextMatch = text.match(/Recent stderr:\s*([\s\S]+)$/i);
545
+ const stderrText = stderrTextFromRecord || stderrFromTextMatch?.[1]?.trim() || "";
546
+ let exitCode = typeof record?.exitCode === "number" && Number.isFinite(record.exitCode) ? record.exitCode : null;
547
+ let signal = typeof record?.signal === "string" && record.signal.trim() ? record.signal.trim() : null;
548
+ if (exitCode === null) {
549
+ const codeMatch = text.match(/(?:exited with code|Exit code:)\s*(\d+)/i);
550
+ if (codeMatch) {
551
+ const parsed = Number(codeMatch[1]);
552
+ if (Number.isFinite(parsed)) {
553
+ exitCode = parsed;
554
+ }
555
+ }
556
+ }
557
+ if (!signal) {
558
+ const signalMatch = text.match(/(?:due to signal|Signal:)\s*([A-Z0-9_]+)/i);
559
+ if (signalMatch) {
560
+ signal = signalMatch[1];
561
+ }
562
+ }
563
+ if (exitCode === null && !signal) {
564
+ return null;
565
+ }
566
+ const phaseMatch = text.match(/\bduring\s+([a-z][a-z ]*)$/i);
567
+ return {
568
+ exitCode,
569
+ signal,
570
+ phase: phaseMatch?.[1]?.trim() || null,
571
+ stderrText
572
+ };
573
+ }
574
+ function formatCodexLocalProcessExit(error) {
575
+ const localExit = extractLocalProcessExit(error);
576
+ if (!localExit) {
577
+ return null;
578
+ }
579
+ const phaseSuffix = localExit.phase ? ` during ${localExit.phase}` : "";
580
+ let message = "";
581
+ if (localExit.exitCode !== null) {
582
+ const windowsHex = formatWindowsExitCode(localExit.exitCode);
583
+ if (windowsHex && localExit.exitCode === WINDOWS_FAIL_FAST_EXIT_CODE) {
584
+ message = `Codex local process exited with code ${localExit.exitCode} (${windowsHex}, Windows fail-fast exception)${phaseSuffix}`;
585
+ } else if (windowsHex) {
586
+ message = `Codex local process exited with code ${localExit.exitCode} (${windowsHex})${phaseSuffix}`;
587
+ } else {
588
+ message = `Codex local process exited with code ${localExit.exitCode}${phaseSuffix}`;
589
+ }
590
+ } else if (localExit.signal) {
591
+ message = `Codex local process exited due to signal ${localExit.signal}${phaseSuffix}`;
592
+ }
593
+ const stderrLine = extractFirstRelevantStderrLine(localExit.stderrText);
594
+ if (!stderrLine) {
595
+ return message;
596
+ }
597
+ if (/memory allocation of .* failed/i.test(stderrLine)) {
598
+ return `${message}. Recent stderr suggests an out-of-memory failure: ${stderrLine}`;
599
+ }
600
+ return `${message}. Recent stderr: ${stderrLine}`;
601
+ }
602
+ function shouldInjectLargeOutputRecoveryHint(error) {
603
+ const record = typeof error === "object" && error !== null ? error : null;
604
+ const searchableText = [
605
+ index.formatDisplayMessage(error).trim(),
606
+ record ? index.formatDisplayMessage(record.stderr).trim() : "",
607
+ record ? index.formatDisplayMessage(record.detail).trim() : "",
608
+ record ? index.formatDisplayMessage(record.data).trim() : ""
609
+ ].filter(Boolean).join("\n").toLowerCase();
610
+ return searchableText.includes("memory allocation of") || searchableText.includes("out of memory") || searchableText.includes("oversized command output");
611
+ }
508
612
  function normalizeCodexBackendError(error) {
509
613
  const record = typeof error === "object" && error !== null ? error : null;
510
614
  const text = index.formatDisplayMessage(error).trim();
@@ -512,11 +616,12 @@ function normalizeCodexBackendError(error) {
512
616
  const detailText = record ? index.formatDisplayMessage(record.detail).trim() : "";
513
617
  const dataText = record ? index.formatDisplayMessage(record.data).trim() : "";
514
618
  const searchableText = [text, stderrText, detailText, dataText].filter(Boolean).join("\n");
515
- const prefix = typeof error === "object" && error !== null ? [
516
- record?.code !== void 0 && record?.code !== null ? `[code=${String(record.code)}]` : "",
517
- record?.status !== void 0 && record?.status !== null ? `[status=${String(record.status)}]` : ""
518
- ].filter(Boolean).join(" ") : "";
619
+ const prefix = buildErrorPrefix(record);
519
620
  const searchableLower = searchableText.toLowerCase();
621
+ const localExitMessage = formatCodexLocalProcessExit(error);
622
+ if (localExitMessage) {
623
+ return localExitMessage;
624
+ }
520
625
  if (searchableText.includes("Failed to locate @zed-industries/codex-acp-")) {
521
626
  const hint = "Codex ACP could not start because the @zed-industries/codex-acp platform binary is missing. Reinstall codex-acp for this machine, or set HAPPY_CODEX_ACP_BIN to a working codex-acp executable.";
522
627
  return prefix ? `${prefix} ${hint}` : hint;
@@ -530,8 +635,14 @@ function normalizeCodexBackendError(error) {
530
635
  return prefix ? `${prefix} ${hint}` : hint;
531
636
  }
532
637
  if (typeof record?.message === "string" && record.message.trim().toLowerCase() === "internal error" && dataText) {
638
+ if (looksLikeUpstreamApiError(dataText.toLowerCase())) {
639
+ return prefix ? `Codex upstream API error ${prefix} ${dataText}` : `Codex upstream API error: ${dataText}`;
640
+ }
533
641
  return prefix ? `${prefix} ${dataText}` : dataText;
534
642
  }
643
+ if (looksLikeUpstreamApiError(searchableLower) && text) {
644
+ return prefix ? `Codex upstream API error ${prefix} ${text}` : `Codex upstream API error: ${text}`;
645
+ }
535
646
  if (error instanceof Error && text) {
536
647
  return text;
537
648
  }
@@ -598,6 +709,7 @@ async function codexRemoteLauncher(session) {
598
709
  let isResponseInProgress = false;
599
710
  let taskStartedSent = false;
600
711
  let shouldInjectHistoryOnNextSession = false;
712
+ let shouldInjectLargeOutputRecoveryHintOnNextSession = false;
601
713
  let shouldCommitAccumulatedResponse = false;
602
714
  let currentAssistantMessageId = null;
603
715
  let currentThinkingMessageId = null;
@@ -688,6 +800,9 @@ async function codexRemoteLauncher(session) {
688
800
  }
689
801
  const errorMessage = normalizeCodexBackendError(detail);
690
802
  unexpectedRuntimeStopRecovery = (async () => {
803
+ if (shouldInjectLargeOutputRecoveryHint(detail)) {
804
+ shouldInjectLargeOutputRecoveryHintOnNextSession = true;
805
+ }
691
806
  queueHistoryInjectionForRestart(
692
807
  `Codex runtime stopped unexpectedly (${errorMessage}). Starting a new Codex session on the next message...`
693
808
  );
@@ -1057,6 +1172,13 @@ async function codexRemoteLauncher(session) {
1057
1172
  }
1058
1173
  session.onThinkingChange(true);
1059
1174
  let promptToSend = message.message;
1175
+ if (shouldInjectLargeOutputRecoveryHintOnNextSession) {
1176
+ promptToSend = `${CODEX_LARGE_OUTPUT_RECOVERY_HINT}
1177
+
1178
+ ${promptToSend}`;
1179
+ shouldInjectLargeOutputRecoveryHintOnNextSession = false;
1180
+ persistence.logger.debug("[Codex] Injected large-output recovery hint into the next session prompt");
1181
+ }
1060
1182
  if (shouldInjectHistoryOnNextSession && conversationHistory.hasHistory()) {
1061
1183
  const historyContext = conversationHistory.getContextForNewSession();
1062
1184
  promptToSend = historyContext + promptToSend;
@@ -1083,6 +1205,9 @@ async function codexRemoteLauncher(session) {
1083
1205
  turnStatus = "turn_aborted";
1084
1206
  emitCodexTurnAborted(session);
1085
1207
  const errorMessage = normalizeCodexBackendError(error);
1208
+ if (shouldInjectLargeOutputRecoveryHint(error)) {
1209
+ shouldInjectLargeOutputRecoveryHintOnNextSession = true;
1210
+ }
1086
1211
  emitUserVisibleErrorMessage(errorMessage);
1087
1212
  if (conversationHistory.hasHistory()) {
1088
1213
  shouldInjectHistoryOnNextSession = true;
@@ -1,6 +1,6 @@
1
- import { p as preserveSessionRuntimeMetadata, l as logger, b as connectionState, A as ApiClient } from './api-DYS9sGJr.mjs';
2
- import { B as BasePermissionHandler, h as hashObject, d as MessageBuffer, C as ConversationHistory$1, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, c as registerKillSessionHandler, l as launchRuntimeHandleWithFactoryResult, j as renderOutputPreview, k as inferToolResultError, m as forwardAgentMessageToProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, r as resolveHappyOrgQueuedTurn, s as syncControlledByUserState } from './registerKillSessionHandler-IlzXqONk.mjs';
3
- import { f as formatDisplayMessage, v as validateCodexAcpSpawn, h as createCodexBackend, t as truncateDisplayMessage, b as closeProviderSession, e as stopCaffeinate, i as readManagedSessionTag, j as resolveManagedSessionTag } from './index-DtlrIihs.mjs';
1
+ import { p as preserveSessionRuntimeMetadata, l as logger, b as connectionState, A as ApiClient } from './api-C68U-kRs.mjs';
2
+ import { B as BasePermissionHandler, h as hashObject, d as MessageBuffer, C as ConversationHistory$1, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, c as registerKillSessionHandler, l as launchRuntimeHandleWithFactoryResult, j as renderOutputPreview, k as inferToolResultError, m as forwardAgentMessageToProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, r as resolveHappyOrgQueuedTurn, s as syncControlledByUserState } from './registerKillSessionHandler-CadrzRgP.mjs';
3
+ import { f as formatDisplayMessage, v as validateCodexAcpSpawn, h as createCodexBackend, t as truncateDisplayMessage, b as closeProviderSession, e as stopCaffeinate, i as readManagedSessionTag, j as resolveManagedSessionTag } from './index-DQ76ZTNL.mjs';
4
4
  import 'cross-spawn';
5
5
  import '@agentclientprotocol/sdk';
6
6
  import { randomUUID } from 'node:crypto';
@@ -24,8 +24,8 @@ 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-Cd_vN8wA.mjs';
28
- import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-DYVFvY85.mjs';
27
+ import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-2siFKlgs.mjs';
28
+ import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-C1iacoJW.mjs';
29
29
  import 'zod';
30
30
  import 'socket.io-client';
31
31
  import 'expo-server-sdk';
@@ -503,6 +503,110 @@ function getCodexExecutionFingerprint(mode) {
503
503
  });
504
504
  }
505
505
 
506
+ const WINDOWS_FAIL_FAST_EXIT_CODE = 3221226505;
507
+ const CODEX_LARGE_OUTPUT_RECOVERY_HINT = `[HAPPY RUNTIME NOTE]
508
+ The previous Codex process exited while handling oversized command output.
509
+ Avoid commands that dump full build/test/log output into the session.
510
+ Redirect long output to a file and inspect summaries or tails instead.`;
511
+ function buildErrorPrefix(record) {
512
+ if (!record) {
513
+ return "";
514
+ }
515
+ return [
516
+ record.code !== void 0 && record.code !== null ? `[code=${String(record.code)}]` : "",
517
+ record.status !== void 0 && record.status !== null ? `[status=${String(record.status)}]` : ""
518
+ ].filter(Boolean).join(" ");
519
+ }
520
+ function formatWindowsExitCode(exitCode) {
521
+ if (process.platform !== "win32" || !Number.isInteger(exitCode) || exitCode < 0) {
522
+ return null;
523
+ }
524
+ return `0x${(exitCode >>> 0).toString(16).toUpperCase().padStart(8, "0")}`;
525
+ }
526
+ function extractFirstRelevantStderrLine(stderrText) {
527
+ const lines = stderrText.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
528
+ for (const line of lines) {
529
+ if (!/^note:\s+run with\b/i.test(line)) {
530
+ return line;
531
+ }
532
+ }
533
+ return lines[0] ?? null;
534
+ }
535
+ function looksLikeUpstreamApiError(searchableLower) {
536
+ return searchableLower.includes("upstream") || searchableLower.includes("rate limit") || searchableLower.includes("429") || searchableLower.includes("quota") || searchableLower.includes("insufficient_quota") || searchableLower.includes("unauthorized") || searchableLower.includes("forbidden");
537
+ }
538
+ function extractLocalProcessExit(error) {
539
+ const record = typeof error === "object" && error !== null ? error : null;
540
+ const text = formatDisplayMessage(error).trim();
541
+ const stderrTextFromRecord = record ? formatDisplayMessage(record.stderr).trim() : "";
542
+ const stderrFromTextMatch = text.match(/Recent stderr:\s*([\s\S]+)$/i);
543
+ const stderrText = stderrTextFromRecord || stderrFromTextMatch?.[1]?.trim() || "";
544
+ let exitCode = typeof record?.exitCode === "number" && Number.isFinite(record.exitCode) ? record.exitCode : null;
545
+ let signal = typeof record?.signal === "string" && record.signal.trim() ? record.signal.trim() : null;
546
+ if (exitCode === null) {
547
+ const codeMatch = text.match(/(?:exited with code|Exit code:)\s*(\d+)/i);
548
+ if (codeMatch) {
549
+ const parsed = Number(codeMatch[1]);
550
+ if (Number.isFinite(parsed)) {
551
+ exitCode = parsed;
552
+ }
553
+ }
554
+ }
555
+ if (!signal) {
556
+ const signalMatch = text.match(/(?:due to signal|Signal:)\s*([A-Z0-9_]+)/i);
557
+ if (signalMatch) {
558
+ signal = signalMatch[1];
559
+ }
560
+ }
561
+ if (exitCode === null && !signal) {
562
+ return null;
563
+ }
564
+ const phaseMatch = text.match(/\bduring\s+([a-z][a-z ]*)$/i);
565
+ return {
566
+ exitCode,
567
+ signal,
568
+ phase: phaseMatch?.[1]?.trim() || null,
569
+ stderrText
570
+ };
571
+ }
572
+ function formatCodexLocalProcessExit(error) {
573
+ const localExit = extractLocalProcessExit(error);
574
+ if (!localExit) {
575
+ return null;
576
+ }
577
+ const phaseSuffix = localExit.phase ? ` during ${localExit.phase}` : "";
578
+ let message = "";
579
+ if (localExit.exitCode !== null) {
580
+ const windowsHex = formatWindowsExitCode(localExit.exitCode);
581
+ if (windowsHex && localExit.exitCode === WINDOWS_FAIL_FAST_EXIT_CODE) {
582
+ message = `Codex local process exited with code ${localExit.exitCode} (${windowsHex}, Windows fail-fast exception)${phaseSuffix}`;
583
+ } else if (windowsHex) {
584
+ message = `Codex local process exited with code ${localExit.exitCode} (${windowsHex})${phaseSuffix}`;
585
+ } else {
586
+ message = `Codex local process exited with code ${localExit.exitCode}${phaseSuffix}`;
587
+ }
588
+ } else if (localExit.signal) {
589
+ message = `Codex local process exited due to signal ${localExit.signal}${phaseSuffix}`;
590
+ }
591
+ const stderrLine = extractFirstRelevantStderrLine(localExit.stderrText);
592
+ if (!stderrLine) {
593
+ return message;
594
+ }
595
+ if (/memory allocation of .* failed/i.test(stderrLine)) {
596
+ return `${message}. Recent stderr suggests an out-of-memory failure: ${stderrLine}`;
597
+ }
598
+ return `${message}. Recent stderr: ${stderrLine}`;
599
+ }
600
+ function shouldInjectLargeOutputRecoveryHint(error) {
601
+ const record = typeof error === "object" && error !== null ? error : null;
602
+ const searchableText = [
603
+ formatDisplayMessage(error).trim(),
604
+ record ? formatDisplayMessage(record.stderr).trim() : "",
605
+ record ? formatDisplayMessage(record.detail).trim() : "",
606
+ record ? formatDisplayMessage(record.data).trim() : ""
607
+ ].filter(Boolean).join("\n").toLowerCase();
608
+ return searchableText.includes("memory allocation of") || searchableText.includes("out of memory") || searchableText.includes("oversized command output");
609
+ }
506
610
  function normalizeCodexBackendError(error) {
507
611
  const record = typeof error === "object" && error !== null ? error : null;
508
612
  const text = formatDisplayMessage(error).trim();
@@ -510,11 +614,12 @@ function normalizeCodexBackendError(error) {
510
614
  const detailText = record ? formatDisplayMessage(record.detail).trim() : "";
511
615
  const dataText = record ? formatDisplayMessage(record.data).trim() : "";
512
616
  const searchableText = [text, stderrText, detailText, dataText].filter(Boolean).join("\n");
513
- const prefix = typeof error === "object" && error !== null ? [
514
- record?.code !== void 0 && record?.code !== null ? `[code=${String(record.code)}]` : "",
515
- record?.status !== void 0 && record?.status !== null ? `[status=${String(record.status)}]` : ""
516
- ].filter(Boolean).join(" ") : "";
617
+ const prefix = buildErrorPrefix(record);
517
618
  const searchableLower = searchableText.toLowerCase();
619
+ const localExitMessage = formatCodexLocalProcessExit(error);
620
+ if (localExitMessage) {
621
+ return localExitMessage;
622
+ }
518
623
  if (searchableText.includes("Failed to locate @zed-industries/codex-acp-")) {
519
624
  const hint = "Codex ACP could not start because the @zed-industries/codex-acp platform binary is missing. Reinstall codex-acp for this machine, or set HAPPY_CODEX_ACP_BIN to a working codex-acp executable.";
520
625
  return prefix ? `${prefix} ${hint}` : hint;
@@ -528,8 +633,14 @@ function normalizeCodexBackendError(error) {
528
633
  return prefix ? `${prefix} ${hint}` : hint;
529
634
  }
530
635
  if (typeof record?.message === "string" && record.message.trim().toLowerCase() === "internal error" && dataText) {
636
+ if (looksLikeUpstreamApiError(dataText.toLowerCase())) {
637
+ return prefix ? `Codex upstream API error ${prefix} ${dataText}` : `Codex upstream API error: ${dataText}`;
638
+ }
531
639
  return prefix ? `${prefix} ${dataText}` : dataText;
532
640
  }
641
+ if (looksLikeUpstreamApiError(searchableLower) && text) {
642
+ return prefix ? `Codex upstream API error ${prefix} ${text}` : `Codex upstream API error: ${text}`;
643
+ }
533
644
  if (error instanceof Error && text) {
534
645
  return text;
535
646
  }
@@ -596,6 +707,7 @@ async function codexRemoteLauncher(session) {
596
707
  let isResponseInProgress = false;
597
708
  let taskStartedSent = false;
598
709
  let shouldInjectHistoryOnNextSession = false;
710
+ let shouldInjectLargeOutputRecoveryHintOnNextSession = false;
599
711
  let shouldCommitAccumulatedResponse = false;
600
712
  let currentAssistantMessageId = null;
601
713
  let currentThinkingMessageId = null;
@@ -686,6 +798,9 @@ async function codexRemoteLauncher(session) {
686
798
  }
687
799
  const errorMessage = normalizeCodexBackendError(detail);
688
800
  unexpectedRuntimeStopRecovery = (async () => {
801
+ if (shouldInjectLargeOutputRecoveryHint(detail)) {
802
+ shouldInjectLargeOutputRecoveryHintOnNextSession = true;
803
+ }
689
804
  queueHistoryInjectionForRestart(
690
805
  `Codex runtime stopped unexpectedly (${errorMessage}). Starting a new Codex session on the next message...`
691
806
  );
@@ -1055,6 +1170,13 @@ async function codexRemoteLauncher(session) {
1055
1170
  }
1056
1171
  session.onThinkingChange(true);
1057
1172
  let promptToSend = message.message;
1173
+ if (shouldInjectLargeOutputRecoveryHintOnNextSession) {
1174
+ promptToSend = `${CODEX_LARGE_OUTPUT_RECOVERY_HINT}
1175
+
1176
+ ${promptToSend}`;
1177
+ shouldInjectLargeOutputRecoveryHintOnNextSession = false;
1178
+ logger.debug("[Codex] Injected large-output recovery hint into the next session prompt");
1179
+ }
1058
1180
  if (shouldInjectHistoryOnNextSession && conversationHistory.hasHistory()) {
1059
1181
  const historyContext = conversationHistory.getContextForNewSession();
1060
1182
  promptToSend = historyContext + promptToSend;
@@ -1081,6 +1203,9 @@ async function codexRemoteLauncher(session) {
1081
1203
  turnStatus = "turn_aborted";
1082
1204
  emitCodexTurnAborted(session);
1083
1205
  const errorMessage = normalizeCodexBackendError(error);
1206
+ if (shouldInjectLargeOutputRecoveryHint(error)) {
1207
+ shouldInjectLargeOutputRecoveryHintOnNextSession = true;
1208
+ }
1084
1209
  emitUserVisibleErrorMessage(errorMessage);
1085
1210
  if (conversationHistory.hasHistory()) {
1086
1211
  shouldInjectHistoryOnNextSession = true;
@@ -3,10 +3,10 @@
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
5
  var node_crypto = require('node:crypto');
6
- var persistence = require('./api-ChV_1TP7.cjs');
7
- var registerKillSessionHandler = require('./registerKillSessionHandler-CBuJR_D8.cjs');
8
- var index = require('./index-CDyeCS7U.cjs');
9
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-AsSwxX2U.cjs');
6
+ var persistence = require('./api-DK1gyZAZ.cjs');
7
+ var registerKillSessionHandler = require('./registerKillSessionHandler-DD9uUk4w.cjs');
8
+ var index = require('./index-BLeiCte-.cjs');
9
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-Ch9R4qmn.cjs');
10
10
  require('cross-spawn');
11
11
  require('@agentclientprotocol/sdk');
12
12
  require('ps-list');
@@ -1,10 +1,10 @@
1
1
  import { useStdout, useInput, Box, Text, render } from 'ink';
2
2
  import React, { useState, useRef, useEffect, useCallback } from 'react';
3
3
  import { randomUUID } from 'node:crypto';
4
- import { l as logger, b as connectionState, A as ApiClient } from './api-DYS9sGJr.mjs';
5
- import { B as BasePermissionHandler, C as ConversationHistory$1, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, h as hashObject, c as registerKillSessionHandler, d as MessageBuffer, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, l as launchRuntimeHandleWithFactoryResult, j as renderOutputPreview, k as inferToolResultError, m as forwardAgentMessageToProviderSession } from './registerKillSessionHandler-IlzXqONk.mjs';
6
- import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, b as closeProviderSession, s as saveGeminiModelToConfig, d as createGeminiBackend, e as stopCaffeinate } from './index-DtlrIihs.mjs';
7
- import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-DYVFvY85.mjs';
4
+ import { l as logger, b as connectionState, A as ApiClient } from './api-C68U-kRs.mjs';
5
+ import { B as BasePermissionHandler, C as ConversationHistory$1, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, h as hashObject, c as registerKillSessionHandler, d as MessageBuffer, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, l as launchRuntimeHandleWithFactoryResult, j as renderOutputPreview, k as inferToolResultError, m as forwardAgentMessageToProviderSession } from './registerKillSessionHandler-CadrzRgP.mjs';
6
+ import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, b as closeProviderSession, s as saveGeminiModelToConfig, d as createGeminiBackend, e as stopCaffeinate } from './index-DQ76ZTNL.mjs';
7
+ import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-C1iacoJW.mjs';
8
8
  import 'cross-spawn';
9
9
  import '@agentclientprotocol/sdk';
10
10
  import 'ps-list';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-imou-cloud",
3
- "version": "2.1.28",
3
+ "version": "2.1.30",
4
4
  "description": "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI",
5
5
  "author": "long.zhu",
6
6
  "license": "MIT",
@@ -239,9 +239,12 @@ function main() {
239
239
  'src/security/signedTransport.test.ts',
240
240
  'src/agent/initializeAgents.test.ts',
241
241
  'src/agent/factories/factories.test.ts',
242
+ 'src/happyOrg/repo.test.ts',
243
+ 'src/commands/happyOrg.test.ts',
242
244
  'src/packageContract.test.ts',
243
245
  ]);
244
246
  runStep('build', 'yarn', ['build']);
247
+ runToolStep('integration suite', vitest, ['run', '--config', 'vitest.integration.config.ts']);
245
248
  runStep('runtime providers', 'node', ['./bin/happy-cloud.mjs', 'runtime', 'providers']);
246
249
  const helpOutput = runStepCapture('help', 'node', ['./bin/happy-cloud.mjs', '--help']);
247
250
  assertOutputContains(helpOutput, 'hicloud session', 'cli help');