happy-imou-cloud 2.0.3 → 2.0.5

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 (23) hide show
  1. package/dist/{BaseReasoningProcessor-_wxlqKB8.cjs → BaseReasoningProcessor-DPVZIJ4n.cjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-B37yOHxo.mjs → BaseReasoningProcessor-bFVTvf3Q.mjs} +2 -2
  3. package/dist/{api-D9dIR956.cjs → api-DaqnNHfl.cjs} +4 -2
  4. package/dist/{api-DpQIC-DJ.mjs → api-DoHt-HyL.mjs} +4 -2
  5. package/dist/{command-CdXv1zNF.cjs → command-D9-hmqVq.cjs} +3 -3
  6. package/dist/{command-DRqrBuHM.mjs → command-Dl9SrMnv.mjs} +3 -3
  7. package/dist/{index-CriPm_z9.mjs → index-C5wR2qKT.mjs} +359 -70
  8. package/dist/{index-LYPXVO_L.cjs → index-Dc92gnxM.cjs} +361 -72
  9. package/dist/index.cjs +3 -3
  10. package/dist/index.mjs +3 -3
  11. package/dist/lib.cjs +1 -1
  12. package/dist/lib.mjs +1 -1
  13. package/dist/{persistence-PzKU0QCa.cjs → persistence-D6Y0604_.cjs} +1 -1
  14. package/dist/{persistence-CqgPgbzN.mjs → persistence-QqeBvUxX.mjs} +1 -1
  15. package/dist/{registerKillSessionHandler-BDBPoQSA.cjs → registerKillSessionHandler-C6yXr8ky.cjs} +2 -2
  16. package/dist/{registerKillSessionHandler-C3M_-4Zg.mjs → registerKillSessionHandler-CC9zGBPE.mjs} +2 -2
  17. package/dist/{runClaude-D6Pdkevn.mjs → runClaude-CZ8gxaJL.mjs} +4 -4
  18. package/dist/{runClaude-IeRSC5qX.cjs → runClaude-gHKFB1UG.cjs} +5 -5
  19. package/dist/{runCodex-WRmgSK6L.cjs → runCodex-CdjzG1N7.cjs} +113 -25
  20. package/dist/{runCodex-CsfUU1Wb.mjs → runCodex-DT7g4MPm.mjs} +111 -26
  21. package/dist/{runGemini-CrH3dQ0Y.mjs → runGemini-CmY5386l.mjs} +55 -21
  22. package/dist/{runGemini-qBh6zs5G.cjs → runGemini-DxjvRmOc.cjs} +55 -21
  23. package/package.json +2 -1
@@ -1,11 +1,12 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-DpQIC-DJ.mjs';
3
- import { readSettings } from './persistence-CqgPgbzN.mjs';
4
- import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate, i as initialMachineMetadata, n as notifyDaemonSessionStarted } from './index-CriPm_z9.mjs';
5
- import { B as BasePermissionHandler, g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, b as INTERACTION_TIMED_OUT_ERROR, a as BaseReasoningProcessor, c as createSessionMetadata, s as setupOfflineReconnection } from './BaseReasoningProcessor-B37yOHxo.mjs';
6
- import { h as hashObject, a as MessageBuffer, r as registerKillSessionHandler, M as MessageQueue2 } from './registerKillSessionHandler-C3M_-4Zg.mjs';
2
+ import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-DoHt-HyL.mjs';
3
+ import { readSettings } from './persistence-QqeBvUxX.mjs';
4
+ import { f as formatDisplayMessage, v as validateCodexAcpSpawn, d as createCodexBackend, t as truncateDisplayMessage, b as stopCaffeinate, i as initialMachineMetadata, n as notifyDaemonSessionStarted } from './index-C5wR2qKT.mjs';
5
+ import { B as BasePermissionHandler, g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, b as INTERACTION_TIMED_OUT_ERROR, a as BaseReasoningProcessor, c as createSessionMetadata, s as setupOfflineReconnection } from './BaseReasoningProcessor-bFVTvf3Q.mjs';
6
+ import { h as hashObject, a as MessageBuffer, r as registerKillSessionHandler, M as MessageQueue2 } from './registerKillSessionHandler-CC9zGBPE.mjs';
7
7
  import React, { useState, useRef, useEffect, useCallback } from 'react';
8
8
  import { useStdout, useInput, Box, Text, render } from 'ink';
9
+ import { attachToolHappierMetaV2, resolveCanonicalToolNameV2, inferToolResultError } from 'happy-protocol';
9
10
  import 'axios';
10
11
  import 'chalk';
11
12
  import 'fs';
@@ -736,7 +737,8 @@ function normalizeCodexBackendError(error) {
736
737
  const text = formatDisplayMessage(error).trim();
737
738
  const stderrText = record ? formatDisplayMessage(record.stderr).trim() : "";
738
739
  const detailText = record ? formatDisplayMessage(record.detail).trim() : "";
739
- const searchableText = [text, stderrText, detailText].filter(Boolean).join("\n");
740
+ const dataText = record ? formatDisplayMessage(record.data).trim() : "";
741
+ const searchableText = [text, stderrText, detailText, dataText].filter(Boolean).join("\n");
740
742
  const prefix = typeof error === "object" && error !== null ? [
741
743
  record?.code !== void 0 && record?.code !== null ? `[code=${String(record.code)}]` : "",
742
744
  record?.status !== void 0 && record?.status !== null ? `[status=${String(record.status)}]` : ""
@@ -749,6 +751,9 @@ function normalizeCodexBackendError(error) {
749
751
  const hint = "The configured Codex ACP command does not speak the ACP protocol. Make sure HAPPY_CODEX_ACP_BIN points to codex-acp, not the codex CLI.";
750
752
  return prefix ? `${prefix} ${hint}` : hint;
751
753
  }
754
+ if (typeof record?.message === "string" && record.message.trim().toLowerCase() === "internal error" && dataText) {
755
+ return prefix ? `${prefix} ${dataText}` : dataText;
756
+ }
752
757
  if (error instanceof Error && text) {
753
758
  return text;
754
759
  }
@@ -868,6 +873,14 @@ async function codexRemoteLauncher(session) {
868
873
  messageBuffer.addMessage(message, "status");
869
874
  session.runtimeSession.sendSessionEvent({ type: "message", message });
870
875
  };
876
+ const emitUserVisibleErrorMessage = (message) => {
877
+ emitStatusMessage(message);
878
+ session.runtimeSession.sendCodexMessage({
879
+ type: "message",
880
+ message,
881
+ id: randomUUID()
882
+ });
883
+ };
871
884
  const queueHistoryInjectionForRestart = (reason) => {
872
885
  messageBuffer.addMessage("\u2550".repeat(40), "status");
873
886
  if (conversationHistory.hasHistory()) {
@@ -938,21 +951,28 @@ async function codexRemoteLauncher(session) {
938
951
  }
939
952
  case "tool-call": {
940
953
  const toolArgs = msg.args ? truncateDisplayMessage(msg.args, 100) : "";
954
+ const canonicalToolName = resolveCanonicalToolNameV2(msg.toolName);
941
955
  messageBuffer.addMessage(
942
956
  `Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}` : ""}`,
943
957
  "tool"
944
958
  );
945
959
  session.runtimeSession.sendCodexMessage({
946
960
  type: "tool-call",
947
- name: msg.toolName,
961
+ name: canonicalToolName,
948
962
  callId: msg.callId,
949
- input: msg.args,
963
+ input: attachToolHappierMetaV2(msg.args, {
964
+ v: 2,
965
+ protocol: "acp",
966
+ provider: "codex",
967
+ rawToolName: msg.toolName,
968
+ canonicalToolName
969
+ }),
950
970
  id: randomUUID()
951
971
  });
952
972
  return;
953
973
  }
954
974
  case "tool-result": {
955
- const isError = msg.result && typeof msg.result === "object" && "error" in msg.result;
975
+ const isError = inferToolResultError(msg.result);
956
976
  const resultText = truncateDisplayMessage(msg.result, 200) || (isError ? "Unknown error" : "");
957
977
  messageBuffer.addMessage(
958
978
  `${isError ? "Error:" : "Result:"} ${resultText}`.trim(),
@@ -961,8 +981,15 @@ async function codexRemoteLauncher(session) {
961
981
  session.runtimeSession.sendCodexMessage({
962
982
  type: "tool-call-result",
963
983
  callId: msg.callId,
964
- output: msg.result,
965
- id: randomUUID()
984
+ output: attachToolHappierMetaV2(msg.result, {
985
+ v: 2,
986
+ protocol: "acp",
987
+ provider: "codex",
988
+ rawToolName: msg.toolName,
989
+ canonicalToolName: resolveCanonicalToolNameV2(msg.toolName)
990
+ }),
991
+ id: randomUUID(),
992
+ isError
966
993
  });
967
994
  return;
968
995
  }
@@ -983,7 +1010,7 @@ async function codexRemoteLauncher(session) {
983
1010
  session.runtimeSession.sendCodexMessage({
984
1011
  type: "terminal-output",
985
1012
  data: terminalOutput,
986
- callId: randomUUID()
1013
+ callId: msg.callId ?? randomUUID()
987
1014
  });
988
1015
  return;
989
1016
  }
@@ -1001,11 +1028,19 @@ async function codexRemoteLauncher(session) {
1001
1028
  case "exec-approval-request": {
1002
1029
  const { call_id, type, ...inputs } = msg;
1003
1030
  messageBuffer.addMessage(`Exec approval requested: ${call_id}`, "tool");
1031
+ const rawToolName = "CodexBash";
1032
+ const canonicalToolName = resolveCanonicalToolNameV2(rawToolName);
1004
1033
  session.runtimeSession.sendCodexMessage({
1005
1034
  type: "tool-call",
1006
- name: "CodexBash",
1035
+ name: canonicalToolName,
1007
1036
  callId: call_id,
1008
- input: inputs,
1037
+ input: attachToolHappierMetaV2(inputs, {
1038
+ v: 2,
1039
+ protocol: "acp",
1040
+ provider: "codex",
1041
+ rawToolName,
1042
+ canonicalToolName
1043
+ }),
1009
1044
  id: randomUUID()
1010
1045
  });
1011
1046
  return;
@@ -1014,14 +1049,22 @@ async function codexRemoteLauncher(session) {
1014
1049
  const changeCount = Object.keys(msg.changes || {}).length;
1015
1050
  const filesMsg = changeCount === 1 ? "1 file" : `${changeCount} files`;
1016
1051
  messageBuffer.addMessage(`Modifying ${filesMsg}...`, "tool");
1052
+ const rawToolName = "CodexPatch";
1053
+ const canonicalToolName = resolveCanonicalToolNameV2(rawToolName);
1017
1054
  session.runtimeSession.sendCodexMessage({
1018
1055
  type: "tool-call",
1019
- name: "CodexPatch",
1056
+ name: canonicalToolName,
1020
1057
  callId: msg.call_id,
1021
- input: {
1058
+ input: attachToolHappierMetaV2({
1022
1059
  auto_approved: msg.auto_approved,
1023
1060
  changes: msg.changes
1024
- },
1061
+ }, {
1062
+ v: 2,
1063
+ protocol: "acp",
1064
+ provider: "codex",
1065
+ rawToolName,
1066
+ canonicalToolName
1067
+ }),
1025
1068
  id: randomUUID()
1026
1069
  });
1027
1070
  return;
@@ -1035,12 +1078,19 @@ async function codexRemoteLauncher(session) {
1035
1078
  session.runtimeSession.sendCodexMessage({
1036
1079
  type: "tool-call-result",
1037
1080
  callId: msg.call_id,
1038
- output: {
1081
+ output: attachToolHappierMetaV2({
1039
1082
  stdout: msg.stdout,
1040
1083
  stderr: msg.stderr,
1041
1084
  success: msg.success
1042
- },
1043
- id: randomUUID()
1085
+ }, {
1086
+ v: 2,
1087
+ protocol: "acp",
1088
+ provider: "codex",
1089
+ rawToolName: "CodexPatch",
1090
+ canonicalToolName: resolveCanonicalToolNameV2("CodexPatch")
1091
+ }),
1092
+ id: randomUUID(),
1093
+ isError: !msg.success
1044
1094
  });
1045
1095
  return;
1046
1096
  }
@@ -1253,7 +1303,7 @@ async function codexRemoteLauncher(session) {
1253
1303
  emitStatusMessage("Aborted by user");
1254
1304
  } else {
1255
1305
  const errorMessage = normalizeCodexBackendError(error);
1256
- emitStatusMessage(errorMessage);
1306
+ emitUserVisibleErrorMessage(errorMessage);
1257
1307
  if (conversationHistory.hasHistory()) {
1258
1308
  shouldInjectHistoryOnNextSession = true;
1259
1309
  }
@@ -1362,10 +1412,39 @@ async function syncControlledByUserState(sessionClient, controlledByUser) {
1362
1412
  function shouldSupersedeCodexPendingInteractions(opts) {
1363
1413
  return true;
1364
1414
  }
1415
+ function resolveInitialCodexPermissionMode(opts) {
1416
+ if (opts.permissionMode) {
1417
+ return opts.permissionMode;
1418
+ }
1419
+ const startingMode = opts.startingMode ?? (opts.startedBy === "daemon" ? "remote" : "local");
1420
+ if (opts.startedBy === "daemon" && startingMode === "remote") {
1421
+ return "yolo";
1422
+ }
1423
+ return void 0;
1424
+ }
1425
+ function resolveQueuedCodexPermissionMode(opts) {
1426
+ if (opts.preserveCurrentOnDefault && opts.messagePermissionMode === "default" && opts.currentPermissionMode) {
1427
+ return opts.currentPermissionMode;
1428
+ }
1429
+ return opts.messagePermissionMode ?? opts.currentPermissionMode ?? "default";
1430
+ }
1431
+ function resolveIncomingCodexPermissionMode(opts) {
1432
+ const resolvedPermissionMode = resolveQueuedCodexPermissionMode(opts);
1433
+ return {
1434
+ resolvedPermissionMode,
1435
+ nextCurrentPermissionMode: resolvedPermissionMode
1436
+ };
1437
+ }
1365
1438
  async function runCodex(opts) {
1366
1439
  const sessionTag = randomUUID();
1367
1440
  connectionState.setBackend("Codex");
1368
1441
  const requestedStartingMode = opts.startingMode ?? (opts.startedBy === "daemon" ? "remote" : "local");
1442
+ const initialPermissionMode = resolveInitialCodexPermissionMode({
1443
+ permissionMode: opts.permissionMode,
1444
+ startedBy: opts.startedBy,
1445
+ startingMode: requestedStartingMode
1446
+ });
1447
+ const preserveCurrentPermissionModeForRemoteDefault = opts.startedBy === "daemon" && requestedStartingMode === "remote";
1369
1448
  if (opts.startedBy === "daemon" && requestedStartingMode === "local") {
1370
1449
  throw new Error("Daemon-spawned Codex sessions cannot use local mode.");
1371
1450
  }
@@ -1420,14 +1499,20 @@ async function runCodex(opts) {
1420
1499
  }
1421
1500
  }
1422
1501
  const messageQueue = new MessageQueue2(getCodexExecutionFingerprint);
1423
- let currentPermissionMode;
1502
+ let currentPermissionMode = initialPermissionMode;
1424
1503
  let currentModel;
1425
1504
  sessionClient.onUserMessage((message) => {
1426
- let messagePermissionMode = currentPermissionMode;
1505
+ const previousPermissionMode = currentPermissionMode;
1506
+ let messagePermissionMode = previousPermissionMode;
1427
1507
  if (message.meta?.permissionMode) {
1428
1508
  messagePermissionMode = message.meta.permissionMode;
1429
- currentPermissionMode = messagePermissionMode;
1430
1509
  }
1510
+ const permissionResolution = resolveIncomingCodexPermissionMode({
1511
+ messagePermissionMode,
1512
+ currentPermissionMode: previousPermissionMode,
1513
+ preserveCurrentOnDefault: preserveCurrentPermissionModeForRemoteDefault
1514
+ });
1515
+ currentPermissionMode = permissionResolution.nextCurrentPermissionMode;
1431
1516
  let messageModel = currentModel;
1432
1517
  if (message.meta?.hasOwnProperty("model")) {
1433
1518
  messageModel = message.meta.model || void 0;
@@ -1441,7 +1526,7 @@ async function runCodex(opts) {
1441
1526
  codexSession?.supersedePendingInteractions(INTERACTION_SUPERSEDED_ERROR);
1442
1527
  }
1443
1528
  messageQueue.push(message.content.text, {
1444
- permissionMode: messagePermissionMode || "default",
1529
+ permissionMode: permissionResolution.resolvedPermissionMode,
1445
1530
  model: messageModel
1446
1531
  });
1447
1532
  });
@@ -1475,4 +1560,4 @@ async function runCodex(opts) {
1475
1560
  }
1476
1561
  }
1477
1562
 
1478
- export { runCodex, shouldSupersedeCodexPendingInteractions, supportsAgentStateUpdateEvents, syncControlledByUserState };
1563
+ export { resolveIncomingCodexPermissionMode, resolveInitialCodexPermissionMode, resolveQueuedCodexPermissionMode, runCodex, shouldSupersedeCodexPendingInteractions, supportsAgentStateUpdateEvents, syncControlledByUserState };
@@ -1,11 +1,12 @@
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, i as isAuthenticationRequiredError } from './api-DpQIC-DJ.mjs';
5
- import { readSettings } from './persistence-CqgPgbzN.mjs';
6
- import { B as BasePermissionHandler, a as BaseReasoningProcessor, c as createSessionMetadata, s as setupOfflineReconnection } from './BaseReasoningProcessor-B37yOHxo.mjs';
7
- import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, s as saveGeminiModelToConfig, a as createGeminiBackend, b as stopCaffeinate } from './index-CriPm_z9.mjs';
8
- import { M as MessageQueue2, h as hashObject, a as MessageBuffer, r as registerKillSessionHandler } from './registerKillSessionHandler-C3M_-4Zg.mjs';
4
+ import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-DoHt-HyL.mjs';
5
+ import { readSettings } from './persistence-QqeBvUxX.mjs';
6
+ import { B as BasePermissionHandler, a as BaseReasoningProcessor, c as createSessionMetadata, s as setupOfflineReconnection } from './BaseReasoningProcessor-bFVTvf3Q.mjs';
7
+ import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, s as saveGeminiModelToConfig, a as createGeminiBackend, b as stopCaffeinate } from './index-C5wR2qKT.mjs';
8
+ import { M as MessageQueue2, h as hashObject, a as MessageBuffer, r as registerKillSessionHandler } from './registerKillSessionHandler-CC9zGBPE.mjs';
9
+ import { attachToolHappierMetaV2, resolveCanonicalToolNameV2, inferToolResultError } from 'happy-protocol';
9
10
  import 'axios';
10
11
  import 'chalk';
11
12
  import 'fs';
@@ -948,17 +949,24 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
948
949
  if (isInvestigationTool && msg.args && typeof msg.args === "object" && "objective" in msg.args) {
949
950
  logger.debug(`[gemini] \u{1F50D} Investigation objective: ${String(msg.args.objective).substring(0, 150)}...`);
950
951
  }
952
+ const canonicalToolName = resolveCanonicalToolNameV2(msg.toolName);
951
953
  messageBuffer.addMessage(`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}${toolArgs.length >= 100 ? "..." : ""}` : ""}`, "tool");
952
954
  session.sendAgentMessage("gemini", {
953
955
  type: "tool-call",
954
- name: msg.toolName,
956
+ name: canonicalToolName,
955
957
  callId: msg.callId,
956
- input: msg.args,
958
+ input: attachToolHappierMetaV2(msg.args, {
959
+ v: 2,
960
+ protocol: "acp",
961
+ provider: "gemini",
962
+ rawToolName: msg.toolName,
963
+ canonicalToolName
964
+ }),
957
965
  id: randomUUID()
958
966
  });
959
967
  break;
960
968
  case "tool-result":
961
- const isError = msg.result && typeof msg.result === "object" && "error" in msg.result;
969
+ const isError = inferToolResultError(msg.result);
962
970
  const resultText = typeof msg.result === "string" ? msg.result.substring(0, 200) : JSON.stringify(msg.result).substring(0, 200);
963
971
  const truncatedResult = resultText + (typeof msg.result === "string" && msg.result.length > 200 ? "..." : "");
964
972
  const resultSize = typeof msg.result === "string" ? msg.result.length : JSON.stringify(msg.result).length;
@@ -979,8 +987,15 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
979
987
  session.sendAgentMessage("gemini", {
980
988
  type: "tool-result",
981
989
  callId: msg.callId,
982
- output: msg.result,
983
- id: randomUUID()
990
+ output: attachToolHappierMetaV2(msg.result, {
991
+ v: 2,
992
+ protocol: "acp",
993
+ provider: "gemini",
994
+ rawToolName: msg.toolName,
995
+ canonicalToolName: resolveCanonicalToolNameV2(msg.toolName)
996
+ }),
997
+ id: randomUUID(),
998
+ isError
984
999
  });
985
1000
  break;
986
1001
  case "fs-edit":
@@ -1008,7 +1023,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1008
1023
  session.sendAgentMessage("gemini", {
1009
1024
  type: "terminal-output",
1010
1025
  data: msg.data,
1011
- callId: msg.callId || randomUUID()
1026
+ callId: msg.callId ?? randomUUID()
1012
1027
  });
1013
1028
  break;
1014
1029
  case "permission-request":
@@ -1027,12 +1042,18 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1027
1042
  const { call_id, type, ...inputs } = execApprovalMsg;
1028
1043
  logger.debug(`[gemini] Exec approval request received: ${callId}`);
1029
1044
  messageBuffer.addMessage(`Exec approval requested: ${callId}`, "tool");
1045
+ const execCanonicalToolName = resolveCanonicalToolNameV2("GeminiBash");
1030
1046
  session.sendAgentMessage("gemini", {
1031
1047
  type: "tool-call",
1032
- name: "GeminiBash",
1033
- // Similar to Codex's CodexBash
1048
+ name: execCanonicalToolName,
1034
1049
  callId,
1035
- input: inputs,
1050
+ input: attachToolHappierMetaV2(inputs, {
1051
+ v: 2,
1052
+ protocol: "acp",
1053
+ provider: "gemini",
1054
+ rawToolName: "GeminiBash",
1055
+ canonicalToolName: execCanonicalToolName
1056
+ }),
1036
1057
  id: randomUUID()
1037
1058
  });
1038
1059
  break;
@@ -1044,15 +1065,21 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1044
1065
  const filesMsg = changeCount === 1 ? "1 file" : `${changeCount} files`;
1045
1066
  messageBuffer.addMessage(`Modifying ${filesMsg}...`, "tool");
1046
1067
  logger.debug(`[gemini] Patch apply begin: ${patchCallId}, files: ${changeCount}`);
1068
+ const patchCanonicalToolName = resolveCanonicalToolNameV2("GeminiPatch");
1047
1069
  session.sendAgentMessage("gemini", {
1048
1070
  type: "tool-call",
1049
- name: "GeminiPatch",
1050
- // Similar to Codex's CodexPatch
1071
+ name: patchCanonicalToolName,
1051
1072
  callId: patchCallId,
1052
- input: {
1073
+ input: attachToolHappierMetaV2({
1053
1074
  auto_approved,
1054
1075
  changes
1055
- },
1076
+ }, {
1077
+ v: 2,
1078
+ protocol: "acp",
1079
+ provider: "gemini",
1080
+ rawToolName: "GeminiPatch",
1081
+ canonicalToolName: patchCanonicalToolName
1082
+ }),
1056
1083
  id: randomUUID()
1057
1084
  });
1058
1085
  break;
@@ -1071,12 +1098,19 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1071
1098
  session.sendAgentMessage("gemini", {
1072
1099
  type: "tool-result",
1073
1100
  callId: patchEndCallId,
1074
- output: {
1101
+ output: attachToolHappierMetaV2({
1075
1102
  stdout,
1076
1103
  stderr,
1077
1104
  success
1078
- },
1079
- id: randomUUID()
1105
+ }, {
1106
+ v: 2,
1107
+ protocol: "acp",
1108
+ provider: "gemini",
1109
+ rawToolName: "GeminiPatch",
1110
+ canonicalToolName: resolveCanonicalToolNameV2("GeminiPatch")
1111
+ }),
1112
+ id: randomUUID(),
1113
+ isError: !success
1080
1114
  });
1081
1115
  break;
1082
1116
  case "event":
@@ -3,11 +3,12 @@
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
5
  var node_crypto = require('node:crypto');
6
- var api = require('./api-D9dIR956.cjs');
7
- var persistence = require('./persistence-PzKU0QCa.cjs');
8
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-_wxlqKB8.cjs');
9
- var index = require('./index-LYPXVO_L.cjs');
10
- var registerKillSessionHandler = require('./registerKillSessionHandler-BDBPoQSA.cjs');
6
+ var api = require('./api-DaqnNHfl.cjs');
7
+ var persistence = require('./persistence-D6Y0604_.cjs');
8
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-DPVZIJ4n.cjs');
9
+ var index = require('./index-Dc92gnxM.cjs');
10
+ var registerKillSessionHandler = require('./registerKillSessionHandler-C6yXr8ky.cjs');
11
+ var happyProtocol = require('happy-protocol');
11
12
  require('axios');
12
13
  require('chalk');
13
14
  require('fs');
@@ -950,17 +951,24 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
950
951
  if (isInvestigationTool && msg.args && typeof msg.args === "object" && "objective" in msg.args) {
951
952
  api.logger.debug(`[gemini] \u{1F50D} Investigation objective: ${String(msg.args.objective).substring(0, 150)}...`);
952
953
  }
954
+ const canonicalToolName = happyProtocol.resolveCanonicalToolNameV2(msg.toolName);
953
955
  messageBuffer.addMessage(`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}${toolArgs.length >= 100 ? "..." : ""}` : ""}`, "tool");
954
956
  session.sendAgentMessage("gemini", {
955
957
  type: "tool-call",
956
- name: msg.toolName,
958
+ name: canonicalToolName,
957
959
  callId: msg.callId,
958
- input: msg.args,
960
+ input: happyProtocol.attachToolHappierMetaV2(msg.args, {
961
+ v: 2,
962
+ protocol: "acp",
963
+ provider: "gemini",
964
+ rawToolName: msg.toolName,
965
+ canonicalToolName
966
+ }),
959
967
  id: node_crypto.randomUUID()
960
968
  });
961
969
  break;
962
970
  case "tool-result":
963
- const isError = msg.result && typeof msg.result === "object" && "error" in msg.result;
971
+ const isError = happyProtocol.inferToolResultError(msg.result);
964
972
  const resultText = typeof msg.result === "string" ? msg.result.substring(0, 200) : JSON.stringify(msg.result).substring(0, 200);
965
973
  const truncatedResult = resultText + (typeof msg.result === "string" && msg.result.length > 200 ? "..." : "");
966
974
  const resultSize = typeof msg.result === "string" ? msg.result.length : JSON.stringify(msg.result).length;
@@ -981,8 +989,15 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
981
989
  session.sendAgentMessage("gemini", {
982
990
  type: "tool-result",
983
991
  callId: msg.callId,
984
- output: msg.result,
985
- id: node_crypto.randomUUID()
992
+ output: happyProtocol.attachToolHappierMetaV2(msg.result, {
993
+ v: 2,
994
+ protocol: "acp",
995
+ provider: "gemini",
996
+ rawToolName: msg.toolName,
997
+ canonicalToolName: happyProtocol.resolveCanonicalToolNameV2(msg.toolName)
998
+ }),
999
+ id: node_crypto.randomUUID(),
1000
+ isError
986
1001
  });
987
1002
  break;
988
1003
  case "fs-edit":
@@ -1010,7 +1025,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1010
1025
  session.sendAgentMessage("gemini", {
1011
1026
  type: "terminal-output",
1012
1027
  data: msg.data,
1013
- callId: msg.callId || node_crypto.randomUUID()
1028
+ callId: msg.callId ?? node_crypto.randomUUID()
1014
1029
  });
1015
1030
  break;
1016
1031
  case "permission-request":
@@ -1029,12 +1044,18 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1029
1044
  const { call_id, type, ...inputs } = execApprovalMsg;
1030
1045
  api.logger.debug(`[gemini] Exec approval request received: ${callId}`);
1031
1046
  messageBuffer.addMessage(`Exec approval requested: ${callId}`, "tool");
1047
+ const execCanonicalToolName = happyProtocol.resolveCanonicalToolNameV2("GeminiBash");
1032
1048
  session.sendAgentMessage("gemini", {
1033
1049
  type: "tool-call",
1034
- name: "GeminiBash",
1035
- // Similar to Codex's CodexBash
1050
+ name: execCanonicalToolName,
1036
1051
  callId,
1037
- input: inputs,
1052
+ input: happyProtocol.attachToolHappierMetaV2(inputs, {
1053
+ v: 2,
1054
+ protocol: "acp",
1055
+ provider: "gemini",
1056
+ rawToolName: "GeminiBash",
1057
+ canonicalToolName: execCanonicalToolName
1058
+ }),
1038
1059
  id: node_crypto.randomUUID()
1039
1060
  });
1040
1061
  break;
@@ -1046,15 +1067,21 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1046
1067
  const filesMsg = changeCount === 1 ? "1 file" : `${changeCount} files`;
1047
1068
  messageBuffer.addMessage(`Modifying ${filesMsg}...`, "tool");
1048
1069
  api.logger.debug(`[gemini] Patch apply begin: ${patchCallId}, files: ${changeCount}`);
1070
+ const patchCanonicalToolName = happyProtocol.resolveCanonicalToolNameV2("GeminiPatch");
1049
1071
  session.sendAgentMessage("gemini", {
1050
1072
  type: "tool-call",
1051
- name: "GeminiPatch",
1052
- // Similar to Codex's CodexPatch
1073
+ name: patchCanonicalToolName,
1053
1074
  callId: patchCallId,
1054
- input: {
1075
+ input: happyProtocol.attachToolHappierMetaV2({
1055
1076
  auto_approved,
1056
1077
  changes
1057
- },
1078
+ }, {
1079
+ v: 2,
1080
+ protocol: "acp",
1081
+ provider: "gemini",
1082
+ rawToolName: "GeminiPatch",
1083
+ canonicalToolName: patchCanonicalToolName
1084
+ }),
1058
1085
  id: node_crypto.randomUUID()
1059
1086
  });
1060
1087
  break;
@@ -1073,12 +1100,19 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1073
1100
  session.sendAgentMessage("gemini", {
1074
1101
  type: "tool-result",
1075
1102
  callId: patchEndCallId,
1076
- output: {
1103
+ output: happyProtocol.attachToolHappierMetaV2({
1077
1104
  stdout,
1078
1105
  stderr,
1079
1106
  success
1080
- },
1081
- id: node_crypto.randomUUID()
1107
+ }, {
1108
+ v: 2,
1109
+ protocol: "acp",
1110
+ provider: "gemini",
1111
+ rawToolName: "GeminiPatch",
1112
+ canonicalToolName: happyProtocol.resolveCanonicalToolNameV2("GeminiPatch")
1113
+ }),
1114
+ id: node_crypto.randomUUID(),
1115
+ isError: !success
1082
1116
  });
1083
1117
  break;
1084
1118
  case "event":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-imou-cloud",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "description": "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI",
5
5
  "author": "long.zhu",
6
6
  "license": "MIT",
@@ -99,6 +99,7 @@
99
99
  "expo-server-sdk": "^3.15.0",
100
100
  "fastify": "^5.6.2",
101
101
  "fastify-type-provider-zod": "4.0.2",
102
+ "happy-protocol": "0.1.0",
102
103
  "http-proxy": "^1.18.1",
103
104
  "http-proxy-middleware": "^3.0.5",
104
105
  "ink": "^6.5.1",