happy-imou-cloud 2.1.39 → 2.1.41

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 (25) hide show
  1. package/dist/{BaseReasoningProcessor-BUTolvO5.cjs → BaseReasoningProcessor-DAPsauUX.cjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-Cbp6sIDm.mjs → BaseReasoningProcessor-Dica2zdX.mjs} +2 -2
  3. package/dist/{ProviderSelectionHandler-B22eXuym.cjs → ProviderSelectionHandler-4nuTd8AP.cjs} +2 -2
  4. package/dist/{ProviderSelectionHandler-DrSgStLw.mjs → ProviderSelectionHandler-CmeZ92yO.mjs} +2 -2
  5. package/dist/{api-BoeZDGwx.cjs → api-C_Tnx4UG.cjs} +131 -5
  6. package/dist/{api-wcqkneTg.mjs → api-CwNEbJBM.mjs} +131 -6
  7. package/dist/{command-CkYq_KwA.cjs → command-C3RwwPVD.cjs} +2 -2
  8. package/dist/{command-DcgK0y3F.mjs → command-D0FxDynx.mjs} +2 -2
  9. package/dist/{index-B9mt95QV.mjs → index-D5m2Duxd.mjs} +7 -7
  10. package/dist/{index-Cgor8CE7.cjs → index-Dh0qGrEd.cjs} +10 -10
  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 +195 -40
  15. package/dist/lib.d.mts +195 -40
  16. package/dist/lib.mjs +1 -1
  17. package/dist/{registerKillSessionHandler-Buc97BEh.mjs → registerKillSessionHandler-6JloVYkb.mjs} +132 -7
  18. package/dist/{registerKillSessionHandler-DtXhn2Cd.cjs → registerKillSessionHandler-Bkh8uLhC.cjs} +132 -7
  19. package/dist/{runClaude-BYKNCDEU.mjs → runClaude-Bng_IsE7.mjs} +59 -5
  20. package/dist/{runClaude-CwXQwmgw.cjs → runClaude-mIFO7YxF.cjs} +59 -5
  21. package/dist/{runCodex-DqAddhDE.mjs → runCodex-DAc6flez.mjs} +34 -8
  22. package/dist/{runCodex-BkB_YKhV.cjs → runCodex-cNuxGshy.cjs} +34 -8
  23. package/dist/{runGemini-3jkfOtlr.mjs → runGemini-DdXj8ltI.mjs} +65 -7
  24. package/dist/{runGemini-B4uXPrue.cjs → runGemini-DsRFV8WN.cjs} +65 -7
  25. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var node_crypto = require('node:crypto');
4
- var persistence = require('./api-BoeZDGwx.cjs');
4
+ var persistence = require('./api-C_Tnx4UG.cjs');
5
5
  require('cross-spawn');
6
6
  require('@agentclientprotocol/sdk');
7
- var index = require('./index-Cgor8CE7.cjs');
7
+ var index = require('./index-Dh0qGrEd.cjs');
8
8
  require('ps-list');
9
9
  require('fs');
10
10
  require('path');
@@ -25,9 +25,9 @@ require('tweetnacl');
25
25
  require('open');
26
26
  var React = require('react');
27
27
  var ink = require('ink');
28
- var ProviderSelectionHandler = require('./ProviderSelectionHandler-B22eXuym.cjs');
28
+ var ProviderSelectionHandler = require('./ProviderSelectionHandler-4nuTd8AP.cjs');
29
29
  var types = require('./types-DVk3crez.cjs');
30
- var registerKillSessionHandler = require('./registerKillSessionHandler-DtXhn2Cd.cjs');
30
+ var registerKillSessionHandler = require('./registerKillSessionHandler-Bkh8uLhC.cjs');
31
31
  require('socket.io-client');
32
32
  require('expo-server-sdk');
33
33
  var node_util = require('node:util');
@@ -1000,6 +1000,7 @@ async function claudeAcpRemoteLauncher(session) {
1000
1000
  let currentModeHash = null;
1001
1001
  let pending = null;
1002
1002
  let accumulatedResponse = "";
1003
+ let currentAssistantStreamStartLength = 0;
1003
1004
  let accumulatedThinking = "";
1004
1005
  let isResponseInProgress = false;
1005
1006
  let taskStartedSent = false;
@@ -1008,6 +1009,8 @@ async function claudeAcpRemoteLauncher(session) {
1008
1009
  let shouldInjectHistoryOnNextSession = false;
1009
1010
  let unexpectedRuntimeStopRecovery = null;
1010
1011
  let readyAlreadySent = false;
1012
+ let currentHappyOrgTurn = null;
1013
+ const assistantMessageStream = new persistence.AssistantMessageStream();
1011
1014
  const permissionHandler = new ClaudeAcpPermissionHandler(session.client);
1012
1015
  const selectionHandler = new ProviderSelectionHandler.ProviderSelectionHandler(session.client, "Claude");
1013
1016
  const conversationHistory = new registerKillSessionHandler.ConversationHistory({
@@ -1059,13 +1062,35 @@ async function claudeAcpRemoteLauncher(session) {
1059
1062
  };
1060
1063
  const resetTurnState = () => {
1061
1064
  accumulatedResponse = "";
1065
+ currentAssistantStreamStartLength = 0;
1062
1066
  accumulatedThinking = "";
1063
1067
  isResponseInProgress = false;
1064
1068
  taskStartedSent = false;
1065
1069
  currentAssistantMessageId = null;
1066
1070
  currentThinkingMessageId = null;
1071
+ currentHappyOrgTurn = null;
1072
+ assistantMessageStream.reset();
1067
1073
  session.onThinkingChange(false);
1068
1074
  };
1075
+ const emitAssistantMessageDelta = (text) => {
1076
+ if (currentHappyOrgTurn) {
1077
+ return false;
1078
+ }
1079
+ if (!text.trim()) {
1080
+ return false;
1081
+ }
1082
+ if (!assistantMessageStream.hasActive()) {
1083
+ currentAssistantStreamStartLength = accumulatedResponse.length - text.length;
1084
+ }
1085
+ const stream = assistantMessageStream.delta();
1086
+ session.client.sendAgentMessage("claude", {
1087
+ type: "message",
1088
+ message: text,
1089
+ id: stream.messageId,
1090
+ ...stream
1091
+ });
1092
+ return true;
1093
+ };
1069
1094
  const emitPendingThinkingMessage = () => {
1070
1095
  const thinking = accumulatedThinking.trim();
1071
1096
  if (!thinking) {
@@ -1083,15 +1108,19 @@ async function claudeAcpRemoteLauncher(session) {
1083
1108
  if (!finalMessage) {
1084
1109
  accumulatedResponse = "";
1085
1110
  isResponseInProgress = false;
1111
+ assistantMessageStream.reset();
1086
1112
  return;
1087
1113
  }
1088
1114
  if (currentAssistantMessageId) {
1089
1115
  messageBuffer.updateMessage(currentAssistantMessageId, finalMessage, { mode: "replace" });
1090
1116
  }
1091
1117
  conversationHistory.addAssistantMessage(finalMessage);
1118
+ const hadActiveStream = assistantMessageStream.hasActive();
1119
+ const stream = hadActiveStream ? assistantMessageStream.commit() : null;
1092
1120
  session.client.sendAgentMessage("claude", {
1093
1121
  type: "message",
1094
- message: finalMessage
1122
+ message: hadActiveStream ? finalMessage.slice(currentAssistantStreamStartLength) : finalMessage,
1123
+ ...stream ? { id: stream.messageId, ...stream } : {}
1095
1124
  });
1096
1125
  session.client.sendClaudeSessionMessage({
1097
1126
  type: "assistant",
@@ -1109,8 +1138,29 @@ async function claudeAcpRemoteLauncher(session) {
1109
1138
  }
1110
1139
  });
1111
1140
  accumulatedResponse = "";
1141
+ currentAssistantStreamStartLength = 0;
1112
1142
  isResponseInProgress = false;
1113
1143
  };
1144
+ const commitActiveAssistantMessageStream = () => {
1145
+ if (!assistantMessageStream.hasActive()) {
1146
+ return false;
1147
+ }
1148
+ const finalMessage = accumulatedResponse.trim();
1149
+ if (!finalMessage) {
1150
+ assistantMessageStream.reset();
1151
+ currentAssistantStreamStartLength = accumulatedResponse.length;
1152
+ return false;
1153
+ }
1154
+ const stream = assistantMessageStream.commit();
1155
+ session.client.sendAgentMessage("claude", {
1156
+ type: "message",
1157
+ message: finalMessage.slice(currentAssistantStreamStartLength),
1158
+ id: stream.messageId,
1159
+ ...stream
1160
+ });
1161
+ currentAssistantStreamStartLength = accumulatedResponse.length;
1162
+ return true;
1163
+ };
1114
1164
  const disposeRuntimeHandle = async () => {
1115
1165
  if (!runtimeHandle) {
1116
1166
  return;
@@ -1188,6 +1238,7 @@ async function claudeAcpRemoteLauncher(session) {
1188
1238
  }
1189
1239
  }
1190
1240
  accumulatedResponse += text;
1241
+ emitAssistantMessageDelta(text);
1191
1242
  return;
1192
1243
  }
1193
1244
  case "status": {
@@ -1220,6 +1271,7 @@ async function claudeAcpRemoteLauncher(session) {
1220
1271
  return;
1221
1272
  }
1222
1273
  case "tool-call": {
1274
+ commitActiveAssistantMessageStream();
1223
1275
  emitPendingThinkingMessage();
1224
1276
  const toolArgs = index.truncateDisplayMessage(msg.args, 100);
1225
1277
  messageBuffer.addMessage(
@@ -1330,6 +1382,7 @@ ${systemPrompt}` : systemPrompt,
1330
1382
  const abortActiveTurn = async () => {
1331
1383
  const activeController = rotateAbortController();
1332
1384
  activeController.abort();
1385
+ assistantMessageStream.reset();
1333
1386
  session.onThinkingChange(false);
1334
1387
  if (runtimeHandle) {
1335
1388
  await runtimeHandle.cancel().catch((error) => {
@@ -1443,6 +1496,7 @@ ${systemPrompt}` : systemPrompt,
1443
1496
  let turnStatus = "task_complete";
1444
1497
  try {
1445
1498
  turnInFlight = true;
1499
+ currentHappyOrgTurn = message.mode.happyOrg ?? null;
1446
1500
  const activeRuntimeHandle = runtimeHandle ?? await createRuntimeHandle(message.mode);
1447
1501
  let promptToSend = message.message;
1448
1502
  if (shouldInjectHistoryOnNextSession && conversationHistory.hasHistory()) {
@@ -1,6 +1,6 @@
1
- import { p as preserveSessionRuntimeMetadata, l as logger, b as connectionState, A as ApiClient } from './api-wcqkneTg.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, j as buildTurnResultPushNotification, c as registerKillSessionHandler, k as buildReadyPushNotification, l as launchRuntimeHandleWithFactoryResult, m as extractPermissionRequestPushContext, n as buildPermissionPushNotification, o as renderTerminalOutputPreview, p as inferToolResultError, q as forwardAgentMessageToProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, r as resolveHappyOrgQueuedTurn, s as syncControlledByUserState } from './registerKillSessionHandler-Buc97BEh.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-B9mt95QV.mjs';
1
+ import { p as preserveSessionRuntimeMetadata, l as logger, d as AssistantMessageStream, b as connectionState, A as ApiClient } from './api-CwNEbJBM.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, j as buildTurnResultPushNotification, c as registerKillSessionHandler, k as buildReadyPushNotification, l as launchRuntimeHandleWithFactoryResult, m as extractPermissionRequestPushContext, n as buildPermissionPushNotification, o as renderTerminalOutputPreview, p as inferToolResultError, q as forwardAgentMessageToProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, r as resolveHappyOrgQueuedTurn, s as syncControlledByUserState } from './registerKillSessionHandler-6JloVYkb.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-D5m2Duxd.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-DrSgStLw.mjs';
28
- import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-Cbp6sIDm.mjs';
27
+ import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-CmeZ92yO.mjs';
28
+ import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-Dica2zdX.mjs';
29
29
  import 'zod';
30
30
  import 'socket.io-client';
31
31
  import 'expo-server-sdk';
@@ -706,6 +706,7 @@ async function codexRemoteLauncher(session) {
706
706
  let readyAlreadySent = false;
707
707
  let accumulatedResponse = "";
708
708
  let emittedResponseLength = 0;
709
+ let currentAssistantStreamStartLength = 0;
709
710
  let isResponseInProgress = false;
710
711
  let taskStartedSent = false;
711
712
  let shouldInjectHistoryOnNextSession = false;
@@ -715,6 +716,7 @@ async function codexRemoteLauncher(session) {
715
716
  let currentThinkingMessageId = null;
716
717
  let currentHappyOrgTurn = null;
717
718
  let unexpectedRuntimeStopRecovery = null;
719
+ const assistantMessageStream = new AssistantMessageStream();
718
720
  const permissionHandler = new CodexPermissionHandler(session.client);
719
721
  const selectionHandler = new CodexSelectionHandler(session.client);
720
722
  const conversationHistory = new ConversationHistory$1({ maxMessages: 20, maxCharacters: 5e4 });
@@ -750,18 +752,21 @@ async function codexRemoteLauncher(session) {
750
752
  reasoningProcessor.abort();
751
753
  accumulatedResponse = "";
752
754
  emittedResponseLength = 0;
755
+ currentAssistantStreamStartLength = 0;
753
756
  isResponseInProgress = false;
754
757
  taskStartedSent = false;
755
758
  shouldCommitAccumulatedResponse = false;
756
759
  currentAssistantMessageId = null;
757
760
  currentThinkingMessageId = null;
758
761
  currentHappyOrgTurn = null;
762
+ assistantMessageStream.reset();
759
763
  session.onThinkingChange(false);
760
764
  };
761
765
  const abortActiveTurn = () => {
762
766
  const activeController = rotateAbortController();
763
767
  activeController.abort();
764
768
  reasoningProcessor.abort();
769
+ assistantMessageStream.reset();
765
770
  session.onThinkingChange(false);
766
771
  if (runtimeHandle) {
767
772
  void runtimeHandle.cancel().catch((error) => {
@@ -794,6 +799,7 @@ async function codexRemoteLauncher(session) {
794
799
  message,
795
800
  id: randomUUID()
796
801
  });
802
+ assistantMessageStream.reset();
797
803
  };
798
804
  const emitTurnReport = (report) => {
799
805
  session.runtimeSession.sendCodexMessage({
@@ -865,18 +871,37 @@ async function codexRemoteLauncher(session) {
865
871
  if (currentHappyOrgTurn && !opts?.force) {
866
872
  return false;
867
873
  }
868
- const nextMessage = accumulatedResponse.slice(emittedResponseLength);
874
+ const hadActiveStream = assistantMessageStream.hasActive();
875
+ if (!opts?.force && !hadActiveStream) {
876
+ currentAssistantStreamStartLength = emittedResponseLength;
877
+ }
878
+ const nextMessage = opts?.force && hadActiveStream ? accumulatedResponse.slice(currentAssistantStreamStartLength) : opts?.force ? accumulatedResponse : accumulatedResponse.slice(emittedResponseLength);
869
879
  if (!nextMessage.trim()) {
880
+ if (opts?.force) {
881
+ assistantMessageStream.reset();
882
+ currentAssistantStreamStartLength = emittedResponseLength;
883
+ }
870
884
  return false;
871
885
  }
886
+ const stream = opts?.force ? assistantMessageStream.commit() : assistantMessageStream.delta();
872
887
  session.runtimeSession.sendCodexMessage({
873
888
  type: "message",
874
889
  message: nextMessage,
875
- id: randomUUID()
890
+ id: stream.messageId,
891
+ ...stream
876
892
  });
877
893
  emittedResponseLength = accumulatedResponse.length;
894
+ if (opts?.force) {
895
+ currentAssistantStreamStartLength = emittedResponseLength;
896
+ }
878
897
  return true;
879
898
  };
899
+ const commitActiveAssistantMessageStream = () => {
900
+ if (!assistantMessageStream.hasActive()) {
901
+ return false;
902
+ }
903
+ return emitPendingAssistantMessageDelta({ force: true });
904
+ };
880
905
  const setupRuntimeMessageHandler = (activeRuntimeHandle) => {
881
906
  const forwardAgentMessage = (agentMessage) => {
882
907
  forwardAgentMessageToProviderSession(agentMessage, {
@@ -907,6 +932,7 @@ async function codexRemoteLauncher(session) {
907
932
  }
908
933
  }
909
934
  accumulatedResponse += text;
935
+ emitPendingAssistantMessageDelta();
910
936
  return;
911
937
  }
912
938
  case "status": {
@@ -940,7 +966,7 @@ async function codexRemoteLauncher(session) {
940
966
  return;
941
967
  }
942
968
  case "tool-call": {
943
- emitPendingAssistantMessageDelta();
969
+ commitActiveAssistantMessageStream();
944
970
  const toolArgs = hasRenderableToolPayload(msg.args) ? truncateDisplayMessage(msg.args, 100) : "";
945
971
  messageBuffer.addMessage(
946
972
  `Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}` : ""}`,
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var persistence = require('./api-BoeZDGwx.cjs');
4
- var registerKillSessionHandler = require('./registerKillSessionHandler-DtXhn2Cd.cjs');
5
- var index = require('./index-Cgor8CE7.cjs');
3
+ var persistence = require('./api-C_Tnx4UG.cjs');
4
+ var registerKillSessionHandler = require('./registerKillSessionHandler-Bkh8uLhC.cjs');
5
+ var index = require('./index-Dh0qGrEd.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-B22eXuym.cjs');
30
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-BUTolvO5.cjs');
29
+ var ProviderSelectionHandler = require('./ProviderSelectionHandler-4nuTd8AP.cjs');
30
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-DAPsauUX.cjs');
31
31
  require('zod');
32
32
  require('socket.io-client');
33
33
  require('expo-server-sdk');
@@ -708,6 +708,7 @@ async function codexRemoteLauncher(session) {
708
708
  let readyAlreadySent = false;
709
709
  let accumulatedResponse = "";
710
710
  let emittedResponseLength = 0;
711
+ let currentAssistantStreamStartLength = 0;
711
712
  let isResponseInProgress = false;
712
713
  let taskStartedSent = false;
713
714
  let shouldInjectHistoryOnNextSession = false;
@@ -717,6 +718,7 @@ async function codexRemoteLauncher(session) {
717
718
  let currentThinkingMessageId = null;
718
719
  let currentHappyOrgTurn = null;
719
720
  let unexpectedRuntimeStopRecovery = null;
721
+ const assistantMessageStream = new persistence.AssistantMessageStream();
720
722
  const permissionHandler = new CodexPermissionHandler(session.client);
721
723
  const selectionHandler = new CodexSelectionHandler(session.client);
722
724
  const conversationHistory = new registerKillSessionHandler.ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
@@ -752,18 +754,21 @@ async function codexRemoteLauncher(session) {
752
754
  reasoningProcessor.abort();
753
755
  accumulatedResponse = "";
754
756
  emittedResponseLength = 0;
757
+ currentAssistantStreamStartLength = 0;
755
758
  isResponseInProgress = false;
756
759
  taskStartedSent = false;
757
760
  shouldCommitAccumulatedResponse = false;
758
761
  currentAssistantMessageId = null;
759
762
  currentThinkingMessageId = null;
760
763
  currentHappyOrgTurn = null;
764
+ assistantMessageStream.reset();
761
765
  session.onThinkingChange(false);
762
766
  };
763
767
  const abortActiveTurn = () => {
764
768
  const activeController = rotateAbortController();
765
769
  activeController.abort();
766
770
  reasoningProcessor.abort();
771
+ assistantMessageStream.reset();
767
772
  session.onThinkingChange(false);
768
773
  if (runtimeHandle) {
769
774
  void runtimeHandle.cancel().catch((error) => {
@@ -796,6 +801,7 @@ async function codexRemoteLauncher(session) {
796
801
  message,
797
802
  id: node_crypto.randomUUID()
798
803
  });
804
+ assistantMessageStream.reset();
799
805
  };
800
806
  const emitTurnReport = (report) => {
801
807
  session.runtimeSession.sendCodexMessage({
@@ -867,18 +873,37 @@ async function codexRemoteLauncher(session) {
867
873
  if (currentHappyOrgTurn && !opts?.force) {
868
874
  return false;
869
875
  }
870
- const nextMessage = accumulatedResponse.slice(emittedResponseLength);
876
+ const hadActiveStream = assistantMessageStream.hasActive();
877
+ if (!opts?.force && !hadActiveStream) {
878
+ currentAssistantStreamStartLength = emittedResponseLength;
879
+ }
880
+ const nextMessage = opts?.force && hadActiveStream ? accumulatedResponse.slice(currentAssistantStreamStartLength) : opts?.force ? accumulatedResponse : accumulatedResponse.slice(emittedResponseLength);
871
881
  if (!nextMessage.trim()) {
882
+ if (opts?.force) {
883
+ assistantMessageStream.reset();
884
+ currentAssistantStreamStartLength = emittedResponseLength;
885
+ }
872
886
  return false;
873
887
  }
888
+ const stream = opts?.force ? assistantMessageStream.commit() : assistantMessageStream.delta();
874
889
  session.runtimeSession.sendCodexMessage({
875
890
  type: "message",
876
891
  message: nextMessage,
877
- id: node_crypto.randomUUID()
892
+ id: stream.messageId,
893
+ ...stream
878
894
  });
879
895
  emittedResponseLength = accumulatedResponse.length;
896
+ if (opts?.force) {
897
+ currentAssistantStreamStartLength = emittedResponseLength;
898
+ }
880
899
  return true;
881
900
  };
901
+ const commitActiveAssistantMessageStream = () => {
902
+ if (!assistantMessageStream.hasActive()) {
903
+ return false;
904
+ }
905
+ return emitPendingAssistantMessageDelta({ force: true });
906
+ };
882
907
  const setupRuntimeMessageHandler = (activeRuntimeHandle) => {
883
908
  const forwardAgentMessage = (agentMessage) => {
884
909
  registerKillSessionHandler.forwardAgentMessageToProviderSession(agentMessage, {
@@ -909,6 +934,7 @@ async function codexRemoteLauncher(session) {
909
934
  }
910
935
  }
911
936
  accumulatedResponse += text;
937
+ emitPendingAssistantMessageDelta();
912
938
  return;
913
939
  }
914
940
  case "status": {
@@ -942,7 +968,7 @@ async function codexRemoteLauncher(session) {
942
968
  return;
943
969
  }
944
970
  case "tool-call": {
945
- emitPendingAssistantMessageDelta();
971
+ commitActiveAssistantMessageStream();
946
972
  const toolArgs = hasRenderableToolPayload(msg.args) ? index.truncateDisplayMessage(msg.args, 100) : "";
947
973
  messageBuffer.addMessage(
948
974
  `Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}` : ""}`,
@@ -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-wcqkneTg.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, j as buildTurnResultPushNotification, k as buildReadyPushNotification, l as launchRuntimeHandleWithFactoryResult, m as extractPermissionRequestPushContext, n as buildPermissionPushNotification, o as renderTerminalOutputPreview, p as inferToolResultError, q as forwardAgentMessageToProviderSession } from './registerKillSessionHandler-Buc97BEh.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-B9mt95QV.mjs';
7
- import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-Cbp6sIDm.mjs';
4
+ import { l as logger, b as connectionState, A as ApiClient, d as AssistantMessageStream } from './api-CwNEbJBM.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, j as buildTurnResultPushNotification, k as buildReadyPushNotification, l as launchRuntimeHandleWithFactoryResult, m as extractPermissionRequestPushContext, n as buildPermissionPushNotification, o as renderTerminalOutputPreview, p as inferToolResultError, q as forwardAgentMessageToProviderSession } from './registerKillSessionHandler-6JloVYkb.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-D5m2Duxd.mjs';
7
+ import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-Dica2zdX.mjs';
8
8
  import 'cross-spawn';
9
9
  import '@agentclientprotocol/sdk';
10
10
  import 'ps-list';
@@ -690,6 +690,7 @@ async function runGemini(opts) {
690
690
  let currentModeHash = null;
691
691
  let unexpectedRuntimeStopRecovery = null;
692
692
  let readyAlreadySent = false;
693
+ let currentHappyOrgTurn = null;
693
694
  async function handleAbort() {
694
695
  logger.debug("[Gemini] Abort requested - stopping current task");
695
696
  if (!turnAbortedSent) {
@@ -701,6 +702,7 @@ async function runGemini(opts) {
701
702
  }
702
703
  reasoningProcessor.abort();
703
704
  diffProcessor.reset();
705
+ assistantMessageStream.reset();
704
706
  try {
705
707
  abortController.abort();
706
708
  messageQueue.reset();
@@ -840,20 +842,72 @@ async function runGemini(opts) {
840
842
  });
841
843
  };
842
844
  let accumulatedResponse = "";
845
+ let currentAssistantStreamStartLength = 0;
843
846
  let isResponseInProgress = false;
844
847
  let hadToolCallInTurn = false;
845
848
  let taskStartedSent = false;
849
+ const assistantMessageStream = new AssistantMessageStream();
846
850
  const resetTurnState = () => {
847
851
  reasoningProcessor.abort();
848
852
  diffProcessor.reset();
849
853
  accumulatedResponse = "";
854
+ currentAssistantStreamStartLength = 0;
850
855
  isResponseInProgress = false;
851
856
  hadToolCallInTurn = false;
852
857
  taskStartedSent = false;
853
858
  turnAbortedSent = false;
859
+ currentHappyOrgTurn = null;
860
+ assistantMessageStream.reset();
854
861
  thinking = false;
855
862
  session.keepAlive(thinking, "remote");
856
863
  };
864
+ const emitAssistantMessageDelta = (text) => {
865
+ if (currentHappyOrgTurn) {
866
+ return false;
867
+ }
868
+ if (!text.trim()) {
869
+ return false;
870
+ }
871
+ if (!assistantMessageStream.hasActive()) {
872
+ currentAssistantStreamStartLength = accumulatedResponse.length - text.length;
873
+ }
874
+ const stream = assistantMessageStream.delta();
875
+ session.sendAgentMessage("gemini", {
876
+ type: "message",
877
+ message: text,
878
+ id: stream.messageId,
879
+ ...stream
880
+ });
881
+ return true;
882
+ };
883
+ const buildAssistantMessageCommit = (message) => {
884
+ if (!assistantMessageStream.hasActive()) {
885
+ return {
886
+ type: "message",
887
+ message,
888
+ id: randomUUID()
889
+ };
890
+ }
891
+ const stream = assistantMessageStream.commit();
892
+ return {
893
+ type: "message",
894
+ message: message.slice(currentAssistantStreamStartLength),
895
+ id: stream.messageId,
896
+ ...stream
897
+ };
898
+ };
899
+ const commitActiveAssistantMessageStream = () => {
900
+ if (!assistantMessageStream.hasActive()) {
901
+ return false;
902
+ }
903
+ const messagePayload = buildAssistantMessageCommit(accumulatedResponse);
904
+ if (!messagePayload.message.trim()) {
905
+ return false;
906
+ }
907
+ session.sendAgentMessage("gemini", messagePayload);
908
+ currentAssistantStreamStartLength = accumulatedResponse.length;
909
+ return true;
910
+ };
857
911
  const disposeRuntimeHandle = async () => {
858
912
  if (!runtimeHandle) {
859
913
  return;
@@ -921,6 +975,7 @@ async function runGemini(opts) {
921
975
  logger.debug(`[gemini] Updated response, chunk length: ${msg.textDelta.length}, total accumulated: ${accumulatedResponse.length + msg.textDelta.length}`);
922
976
  }
923
977
  accumulatedResponse += msg.textDelta;
978
+ emitAssistantMessageDelta(msg.textDelta);
924
979
  }
925
980
  break;
926
981
  case "status":
@@ -977,9 +1032,11 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
977
1032
  type: "message",
978
1033
  message: `Error: ${errorMessage}`
979
1034
  });
1035
+ assistantMessageStream.reset();
980
1036
  }
981
1037
  break;
982
1038
  case "tool-call":
1039
+ commitActiveAssistantMessageStream();
983
1040
  hadToolCallInTurn = true;
984
1041
  const toolArgs = msg.args ? JSON.stringify(msg.args).substring(0, 100) : "";
985
1042
  const isInvestigationTool = msg.toolName === "codebase_investigator" || typeof msg.toolName === "string" && msg.toolName.includes("investigator");
@@ -1204,10 +1261,12 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1204
1261
  throw new Error("Gemini runtime session not started");
1205
1262
  }
1206
1263
  accumulatedResponse = "";
1264
+ currentAssistantStreamStartLength = 0;
1207
1265
  isResponseInProgress = false;
1208
1266
  hadToolCallInTurn = false;
1209
1267
  taskStartedSent = false;
1210
1268
  turnAbortedSent = false;
1269
+ currentHappyOrgTurn = message.mode.happyOrg ?? null;
1211
1270
  let promptToSend = message.message;
1212
1271
  if (shouldInjectHistoryOnNextSession && conversationHistory.hasHistory()) {
1213
1272
  const historyContext = conversationHistory.getContextForNewSession();
@@ -1359,11 +1418,10 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1359
1418
  logger.debug(`[gemini] Warning: Incomplete options block detected`);
1360
1419
  }
1361
1420
  const messagePayload = {
1362
- type: "message",
1363
- message: finalMessageText,
1364
- id: randomUUID(),
1421
+ ...buildAssistantMessageCommit(finalMessageText),
1365
1422
  ...options.length > 0 && { options }
1366
1423
  };
1424
+ currentAssistantStreamStartLength = accumulatedResponse.length;
1367
1425
  logger.debug(`[gemini] Sending complete message to mobile (length: ${finalMessageText.length}): ${finalMessageText.substring(0, 100)}...`);
1368
1426
  session.sendAgentMessage("gemini", messagePayload);
1369
1427
  if (!shouldExit) {