happy-imou-cloud 2.1.3 → 2.1.4

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 (30) hide show
  1. package/bin/happy-cloud.mjs +39 -39
  2. package/dist/{BaseReasoningProcessor-BrcBFCoL.cjs → BaseReasoningProcessor-DgdsExMH.cjs} +3 -3
  3. package/dist/{BaseReasoningProcessor-CPLK0a8y.mjs → BaseReasoningProcessor-lTsZVuAU.mjs} +3 -3
  4. package/dist/{ProviderSelectionHandler-f7_I3vQa.cjs → ProviderSelectionHandler-Bavm9TDG.cjs} +2 -2
  5. package/dist/{ProviderSelectionHandler-CrXfMTg1.mjs → ProviderSelectionHandler-CGTnB7ba.mjs} +2 -2
  6. package/dist/{api-OoiG7XjD.cjs → api-B6ESNpGB.cjs} +3 -3
  7. package/dist/{api-BGv79x9Q.mjs → api-l8X03rs-.mjs} +3 -3
  8. package/dist/{command-FbV44egL.mjs → command-BVCkEMtp.mjs} +3 -3
  9. package/dist/{command-DAYJSP16.cjs → command-DPLKOzMr.cjs} +3 -3
  10. package/dist/{index-D9lWHpn-.cjs → index-D1BP-fEm.cjs} +406 -34
  11. package/dist/{index-TRC83Ks9.mjs → index-D72RMo5Z.mjs} +403 -31
  12. package/dist/index.cjs +3 -3
  13. package/dist/index.mjs +3 -3
  14. package/dist/lib.cjs +1 -1
  15. package/dist/lib.mjs +1 -1
  16. package/dist/{persistence-Cmgj3ubQ.mjs → persistence-CyFjFOlN.mjs} +1 -1
  17. package/dist/{persistence-lN9HV4IZ.cjs → persistence-EDmI-c8T.cjs} +1 -1
  18. package/dist/{registerKillSessionHandler-pk4Ohq4Y.cjs → registerKillSessionHandler-71xCO8e_.cjs} +6 -5
  19. package/dist/{registerKillSessionHandler-NZd3xieQ.mjs → registerKillSessionHandler-DAVhkb-l.mjs} +6 -5
  20. package/dist/{runClaude-7St9-Jci.mjs → runClaude-BRhQLKjh.mjs} +5 -5
  21. package/dist/{runClaude-BP-O6ucu.cjs → runClaude-DjnTGJGC.cjs} +5 -5
  22. package/dist/{runCodex-BV6kKtTO.cjs → runCodex-BHq7Rnq7.cjs} +6 -6
  23. package/dist/{runCodex-BaXi_9BC.mjs → runCodex-DUs_jBE-.mjs} +6 -6
  24. package/dist/{runGemini-BiYKqJqO.cjs → runGemini-hkZeOnA_.cjs} +6 -6
  25. package/dist/{runGemini-ClNqE9N3.mjs → runGemini-pmvBZ6qU.mjs} +6 -6
  26. package/package.json +3 -3
  27. package/scripts/devtools/README.md +9 -9
  28. package/scripts/e2e/fake-codex-acp-agent.mjs +139 -139
  29. package/scripts/e2e/local-server-session-roundtrip.mjs +1063 -1063
  30. package/scripts/ensureAcpSdkCompat.mjs +1 -1
@@ -1,6 +1,6 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
2
- import { l as logger, e as encodeBase64, c as configuration, k as buildAuthenticatedHeaders, S as SigningBootstrapRequiredError, m as SIGNING_BOOTSTRAP_REQUIRED_MESSAGE, n as encodeBase64Url, h as delay, o as buildClientHeaders, q as decodeBase64, r as HAPPY_CLOUD_DAEMON_PORT, p as packageJson, A as ApiClient, t as HeadTailPreviewBuffer, u as getLatestDaemonLog } from './api-BGv79x9Q.mjs';
3
- import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-Cmgj3ubQ.mjs';
2
+ import { l as logger, e as encodeBase64, c as configuration, k as buildAuthenticatedHeaders, S as SigningBootstrapRequiredError, m as SIGNING_BOOTSTRAP_REQUIRED_MESSAGE, n as encodeBase64Url, h as delay, o as buildClientHeaders, q as decodeBase64, r as HAPPY_CLOUD_DAEMON_PORT, p as packageJson, A as ApiClient, t as HeadTailPreviewBuffer, u as getLatestDaemonLog } from './api-l8X03rs-.mjs';
3
+ import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-CyFjFOlN.mjs';
4
4
  import { z } from 'zod';
5
5
  import fs, { writeFile as writeFile$1, rename, unlink as unlink$1 } from 'fs/promises';
6
6
  import os, { homedir } from 'os';
@@ -4842,6 +4842,296 @@ function truncateDisplayMessage(value, maxLength) {
4842
4842
  return `${formatted.substring(0, maxLength)}...`;
4843
4843
  }
4844
4844
 
4845
+ const DEFAULT_RESPONSE_WAIT_TIMEOUT_MS = 10 * 6e4;
4846
+ const DEFAULT_POST_PROMPT_NO_UPDATES_TIMEOUT_MS$1 = 2 * 6e4;
4847
+ const TIMEOUT_FAST_WORDS = ["fast", "quick", "low", "minimal", "light", "shallow", "short", "economy"];
4848
+ const TIMEOUT_BALANCED_WORDS = ["balanced", "medium", "normal", "default", "standard", "auto"];
4849
+ const TIMEOUT_DEEP_WORDS = ["deep", "high", "max", "maximum", "extended", "long", "intense", "thorough"];
4850
+ const CACHE_OFF_WORDS = ["off", "none", "disabled", "disable", "false"];
4851
+ const CACHE_DEFAULT_WORDS = ["default", "auto", "balanced", "standard", "normal"];
4852
+ const CACHE_AGGRESSIVE_WORDS = ["aggressive", "enabled", "enable", "on", "high", "max", "maximum", "full", "always"];
4853
+ const TIMEOUT_OPTION_HINTS = ["timeout", "latency", "speed", "effort", "thought", "thinking", "reasoning", "reason", "depth"];
4854
+ const CACHE_OPTION_HINTS = ["cache", "caching", "cached", "reuse", "replay"];
4855
+ function normalizeAgentKey(agentName) {
4856
+ return agentName.replace(/[^a-z0-9]+/gi, "_").replace(/^_+|_+$/g, "").toUpperCase();
4857
+ }
4858
+ function readEnvValue(env, names) {
4859
+ for (const name of names) {
4860
+ const raw = env[name]?.trim();
4861
+ if (raw) {
4862
+ return raw;
4863
+ }
4864
+ }
4865
+ return null;
4866
+ }
4867
+ function readTimeoutProfile(agentName, env) {
4868
+ const agentKey = normalizeAgentKey(agentName);
4869
+ const raw = readEnvValue(env, [
4870
+ `HAPPY_${agentKey}_ACP_TIMEOUT_PROFILE`,
4871
+ `HAPPIER_${agentKey}_ACP_TIMEOUT_PROFILE`,
4872
+ "HAPPY_ACP_TIMEOUT_PROFILE",
4873
+ "HAPPIER_ACP_TIMEOUT_PROFILE"
4874
+ ])?.toLowerCase();
4875
+ if (!raw) {
4876
+ return { value: "balanced", source: "default" };
4877
+ }
4878
+ if (["fast", "quick", "low", "minimal", "light", "shallow"].includes(raw)) {
4879
+ return { value: "fast", source: "env" };
4880
+ }
4881
+ if (["deep", "high", "max", "maximum", "extended", "long", "thorough"].includes(raw)) {
4882
+ return { value: "deep", source: "env" };
4883
+ }
4884
+ return { value: "balanced", source: "env" };
4885
+ }
4886
+ function readCachePolicy(agentName, env) {
4887
+ const agentKey = normalizeAgentKey(agentName);
4888
+ const raw = readEnvValue(env, [
4889
+ `HAPPY_${agentKey}_ACP_CACHE_POLICY`,
4890
+ `HAPPIER_${agentKey}_ACP_CACHE_POLICY`,
4891
+ "HAPPY_ACP_CACHE_POLICY",
4892
+ "HAPPIER_ACP_CACHE_POLICY"
4893
+ ])?.toLowerCase();
4894
+ if (!raw) {
4895
+ return { value: "default", source: "default" };
4896
+ }
4897
+ if (["off", "none", "disabled", "disable", "false"].includes(raw)) {
4898
+ return { value: "off", source: "env" };
4899
+ }
4900
+ if (["aggressive", "enabled", "enable", "on", "high", "max", "maximum", "full", "always"].includes(raw)) {
4901
+ return { value: "aggressive", source: "env" };
4902
+ }
4903
+ return { value: "default", source: "env" };
4904
+ }
4905
+ function normalizeText(value) {
4906
+ return (value ?? "").toLowerCase();
4907
+ }
4908
+ function tokenize(...parts) {
4909
+ return parts.map((part) => normalizeText(part)).join(" ").split(/[^a-z0-9]+/g).filter(Boolean);
4910
+ }
4911
+ function includesAny(tokens, expected) {
4912
+ return expected.some((candidate) => tokens.includes(candidate));
4913
+ }
4914
+ function isSelectSessionConfigOption(option) {
4915
+ return option.type === "select";
4916
+ }
4917
+ function isBooleanSessionConfigOption(option) {
4918
+ return option.type === "boolean";
4919
+ }
4920
+ function flattenSelectOptions(options) {
4921
+ const flattened = [];
4922
+ for (const option of options) {
4923
+ if (Array.isArray(option.options)) {
4924
+ flattened.push(...option.options);
4925
+ continue;
4926
+ }
4927
+ flattened.push(option);
4928
+ }
4929
+ return flattened;
4930
+ }
4931
+ function classifyConfigOption(option) {
4932
+ const tokens = tokenize(option.id, option.name, option.description, option.category);
4933
+ if (option.category === "thought_level" || includesAny(tokens, TIMEOUT_OPTION_HINTS)) {
4934
+ return "timeout";
4935
+ }
4936
+ if (includesAny(tokens, CACHE_OPTION_HINTS)) {
4937
+ return "cache";
4938
+ }
4939
+ return null;
4940
+ }
4941
+ function scoreTimeoutChoice(option, profile, currentValue) {
4942
+ const tokens = tokenize(option.value, option.name, option.description);
4943
+ let score = 0;
4944
+ if (profile === "fast" && includesAny(tokens, TIMEOUT_FAST_WORDS)) {
4945
+ score += 4;
4946
+ }
4947
+ if (profile === "balanced" && includesAny(tokens, TIMEOUT_BALANCED_WORDS)) {
4948
+ score += 4;
4949
+ }
4950
+ if (profile === "deep" && includesAny(tokens, TIMEOUT_DEEP_WORDS)) {
4951
+ score += 4;
4952
+ }
4953
+ if (profile === "balanced" && option.value === currentValue) {
4954
+ score += 2;
4955
+ }
4956
+ return score;
4957
+ }
4958
+ function scoreCacheChoice(option, policy, currentValue) {
4959
+ const tokens = tokenize(option.value, option.name, option.description);
4960
+ let score = 0;
4961
+ if (policy === "off" && includesAny(tokens, CACHE_OFF_WORDS)) {
4962
+ score += 4;
4963
+ }
4964
+ if (policy === "default" && includesAny(tokens, CACHE_DEFAULT_WORDS)) {
4965
+ score += 4;
4966
+ }
4967
+ if (policy === "aggressive" && includesAny(tokens, CACHE_AGGRESSIVE_WORDS)) {
4968
+ score += 4;
4969
+ }
4970
+ if (policy === "default" && option.value === currentValue) {
4971
+ score += 2;
4972
+ }
4973
+ return score;
4974
+ }
4975
+ function chooseTimeoutValue(option, profile) {
4976
+ if (!isSelectSessionConfigOption(option)) {
4977
+ return null;
4978
+ }
4979
+ const candidates = flattenSelectOptions(option.options);
4980
+ let best = null;
4981
+ for (const candidate of candidates) {
4982
+ const score = scoreTimeoutChoice(candidate, profile, option.currentValue);
4983
+ if (score <= 0) {
4984
+ continue;
4985
+ }
4986
+ if (!best || score > best.score) {
4987
+ best = { value: candidate.value, score };
4988
+ }
4989
+ }
4990
+ return best?.value ?? null;
4991
+ }
4992
+ function chooseCacheValue(option, policy) {
4993
+ if (isBooleanSessionConfigOption(option)) {
4994
+ if (policy === "off") {
4995
+ return false;
4996
+ }
4997
+ if (policy === "aggressive") {
4998
+ return true;
4999
+ }
5000
+ return null;
5001
+ }
5002
+ if (!isSelectSessionConfigOption(option)) {
5003
+ return null;
5004
+ }
5005
+ const candidates = flattenSelectOptions(option.options);
5006
+ let best = null;
5007
+ for (const candidate of candidates) {
5008
+ const score = scoreCacheChoice(candidate, policy, option.currentValue);
5009
+ if (score <= 0) {
5010
+ continue;
5011
+ }
5012
+ if (!best || score > best.score) {
5013
+ best = { value: candidate.value, score };
5014
+ }
5015
+ }
5016
+ return best?.value ?? null;
5017
+ }
5018
+ function buildSetSessionConfigOptionRequest(options) {
5019
+ if (typeof options.value === "boolean") {
5020
+ return {
5021
+ sessionId: options.sessionId,
5022
+ configId: options.configId,
5023
+ type: "boolean",
5024
+ value: options.value
5025
+ };
5026
+ }
5027
+ return {
5028
+ sessionId: options.sessionId,
5029
+ configId: options.configId,
5030
+ value: options.value
5031
+ };
5032
+ }
5033
+ function resolveAcpSessionPreferences(options) {
5034
+ const mergedEnv = {
5035
+ ...process.env,
5036
+ ...options.env ?? {}
5037
+ };
5038
+ const timeout = readTimeoutProfile(options.agentName, mergedEnv);
5039
+ const cache = readCachePolicy(options.agentName, mergedEnv);
5040
+ return {
5041
+ agentName: options.agentName,
5042
+ timeoutProfile: timeout.value,
5043
+ timeoutSource: timeout.source,
5044
+ cachePolicy: cache.value,
5045
+ cacheSource: cache.source
5046
+ };
5047
+ }
5048
+ function scaleAcpTimeoutMs(baseMs, kind, profile) {
5049
+ if (profile === "balanced") {
5050
+ return baseMs;
5051
+ }
5052
+ const multipliers = profile === "fast" ? {
5053
+ init: 0.75,
5054
+ tool: 0.75,
5055
+ investigation: 0.75,
5056
+ think: 0.5,
5057
+ execute: 0.75
5058
+ } : {
5059
+ init: 1.5,
5060
+ tool: 1.5,
5061
+ investigation: 1.5,
5062
+ think: 2,
5063
+ execute: 1.5
5064
+ };
5065
+ const minimums = {
5066
+ init: 15e3,
5067
+ tool: 6e4,
5068
+ investigation: 5 * 6e4,
5069
+ think: 15e3,
5070
+ execute: 2 * 6e4
5071
+ };
5072
+ return Math.max(minimums[kind], Math.round(baseMs * multipliers[kind]));
5073
+ }
5074
+ function resolveAcpResponseWaitTimeoutMs(profile) {
5075
+ if (profile === "fast") {
5076
+ return 5 * 6e4;
5077
+ }
5078
+ if (profile === "deep") {
5079
+ return 20 * 6e4;
5080
+ }
5081
+ return DEFAULT_RESPONSE_WAIT_TIMEOUT_MS;
5082
+ }
5083
+ function resolveAcpPostPromptNoUpdatesTimeoutMs(baseMs, profile) {
5084
+ if (profile === "fast") {
5085
+ return Math.max(3e4, Math.min(baseMs, 45e3));
5086
+ }
5087
+ if (profile === "deep") {
5088
+ return Math.max(baseMs, 4 * 6e4);
5089
+ }
5090
+ return baseMs || DEFAULT_POST_PROMPT_NO_UPDATES_TIMEOUT_MS$1;
5091
+ }
5092
+ function buildAcpSessionConfigPresetPlan(options) {
5093
+ const plan = [];
5094
+ for (const option of options.configOptions ?? []) {
5095
+ const kind = classifyConfigOption(option);
5096
+ if (kind === "timeout" && options.preferences.timeoutSource === "env") {
5097
+ const targetValue = chooseTimeoutValue(option, options.preferences.timeoutProfile);
5098
+ if (targetValue && targetValue !== option.currentValue) {
5099
+ plan.push({
5100
+ kind,
5101
+ optionId: option.id,
5102
+ optionName: option.name,
5103
+ currentValue: option.currentValue,
5104
+ targetValue,
5105
+ request: buildSetSessionConfigOptionRequest({
5106
+ sessionId: options.sessionId,
5107
+ configId: option.id,
5108
+ value: targetValue
5109
+ })
5110
+ });
5111
+ }
5112
+ continue;
5113
+ }
5114
+ if (kind === "cache" && options.preferences.cacheSource === "env") {
5115
+ const targetValue = chooseCacheValue(option, options.preferences.cachePolicy);
5116
+ if (targetValue && targetValue !== option.currentValue) {
5117
+ plan.push({
5118
+ kind,
5119
+ optionId: option.id,
5120
+ optionName: option.name,
5121
+ currentValue: option.currentValue,
5122
+ targetValue,
5123
+ request: buildSetSessionConfigOptionRequest({
5124
+ sessionId: options.sessionId,
5125
+ configId: option.id,
5126
+ value: targetValue
5127
+ })
5128
+ });
5129
+ }
5130
+ }
5131
+ }
5132
+ return plan;
5133
+ }
5134
+
4845
5135
  const DEFAULT_TIMEOUTS = {
4846
5136
  /** Default initialization timeout: 60 seconds */
4847
5137
  init: 6e4,
@@ -4855,11 +5145,14 @@ class DefaultTransport {
4855
5145
  constructor(agentName = "generic-acp") {
4856
5146
  this.agentName = agentName;
4857
5147
  }
5148
+ getTimeoutProfile() {
5149
+ return resolveAcpSessionPreferences({ agentName: this.agentName }).timeoutProfile;
5150
+ }
4858
5151
  /**
4859
5152
  * Default init timeout: 60 seconds
4860
5153
  */
4861
5154
  getInitTimeout() {
4862
- return DEFAULT_TIMEOUTS.init;
5155
+ return scaleAcpTimeoutMs(DEFAULT_TIMEOUTS.init, "init", this.getTimeoutProfile());
4863
5156
  }
4864
5157
  getInitDelayMs() {
4865
5158
  return 0;
@@ -4908,9 +5201,9 @@ class DefaultTransport {
4908
5201
  */
4909
5202
  getToolCallTimeout(_toolCallId, toolKind) {
4910
5203
  if (toolKind === "think") {
4911
- return DEFAULT_TIMEOUTS.think;
5204
+ return scaleAcpTimeoutMs(DEFAULT_TIMEOUTS.think, "think", this.getTimeoutProfile());
4912
5205
  }
4913
- return DEFAULT_TIMEOUTS.toolCall;
5206
+ return scaleAcpTimeoutMs(DEFAULT_TIMEOUTS.toolCall, "tool", this.getTimeoutProfile());
4914
5207
  }
4915
5208
  /**
4916
5209
  * Default: no tool name extraction (return null)
@@ -4925,7 +5218,7 @@ class DefaultTransport {
4925
5218
  return toolName;
4926
5219
  }
4927
5220
  getPostPromptNoUpdatesTimeoutMs() {
4928
- return 2 * 6e4;
5221
+ return resolveAcpPostPromptNoUpdatesTimeoutMs(2 * 6e4, this.getTimeoutProfile());
4929
5222
  }
4930
5223
  }
4931
5224
 
@@ -4962,11 +5255,14 @@ const AVAILABLE_MODELS = [
4962
5255
  ];
4963
5256
  class GeminiTransport {
4964
5257
  agentName = "gemini";
5258
+ getTimeoutProfile() {
5259
+ return resolveAcpSessionPreferences({ agentName: this.agentName }).timeoutProfile;
5260
+ }
4965
5261
  /**
4966
5262
  * Gemini CLI needs 2 minutes for first start (model download, warm-up)
4967
5263
  */
4968
5264
  getInitTimeout() {
4969
- return GEMINI_TIMEOUTS.init;
5265
+ return scaleAcpTimeoutMs(GEMINI_TIMEOUTS.init, "init", this.getTimeoutProfile());
4970
5266
  }
4971
5267
  getInitDelayMs() {
4972
5268
  return GEMINI_TIMEOUTS.initDelay;
@@ -5049,12 +5345,12 @@ class GeminiTransport {
5049
5345
  */
5050
5346
  getToolCallTimeout(toolCallId, toolKind) {
5051
5347
  if (this.isInvestigationTool(toolCallId, toolKind)) {
5052
- return GEMINI_TIMEOUTS.investigation;
5348
+ return scaleAcpTimeoutMs(GEMINI_TIMEOUTS.investigation, "investigation", this.getTimeoutProfile());
5053
5349
  }
5054
5350
  if (toolKind === "think") {
5055
- return GEMINI_TIMEOUTS.think;
5351
+ return scaleAcpTimeoutMs(GEMINI_TIMEOUTS.think, "think", this.getTimeoutProfile());
5056
5352
  }
5057
- return GEMINI_TIMEOUTS.toolCall;
5353
+ return scaleAcpTimeoutMs(GEMINI_TIMEOUTS.toolCall, "tool", this.getTimeoutProfile());
5058
5354
  }
5059
5355
  /**
5060
5356
  * Get idle detection timeout
@@ -5148,22 +5444,20 @@ function readPositiveIntegerEnv$1(name) {
5148
5444
  }
5149
5445
  return value;
5150
5446
  }
5151
- function resolveCodexExecuteTimeoutMs() {
5152
- return readPositiveIntegerEnv$1("HAPPY_CODEX_EXECUTE_TIMEOUT_MS") ?? readPositiveIntegerEnv$1("HAPPIER_CODEX_EXECUTE_TIMEOUT_MS") ?? DEFAULT_CODEX_EXECUTE_TIMEOUT_MS;
5153
- }
5154
5447
  class CodexTransport extends DefaultTransport {
5155
5448
  constructor() {
5156
5449
  super("codex");
5157
5450
  }
5158
5451
  getInitTimeout() {
5159
- return 3e4;
5452
+ return scaleAcpTimeoutMs(3e4, "init", this.getTimeoutProfile());
5160
5453
  }
5161
5454
  getIdleTimeout() {
5162
5455
  return 800;
5163
5456
  }
5164
5457
  getToolCallTimeout(toolCallId, toolKind) {
5165
5458
  if (toolKind === "execute") {
5166
- return resolveCodexExecuteTimeoutMs();
5459
+ const explicit = readPositiveIntegerEnv$1("HAPPY_CODEX_EXECUTE_TIMEOUT_MS") ?? readPositiveIntegerEnv$1("HAPPIER_CODEX_EXECUTE_TIMEOUT_MS");
5460
+ return explicit ?? scaleAcpTimeoutMs(DEFAULT_CODEX_EXECUTE_TIMEOUT_MS, "execute", this.getTimeoutProfile());
5167
5461
  }
5168
5462
  return super.getToolCallTimeout(toolCallId, toolKind);
5169
5463
  }
@@ -5175,7 +5469,7 @@ class ClaudeTransport extends DefaultTransport {
5175
5469
  super("claude");
5176
5470
  }
5177
5471
  getInitTimeout() {
5178
- return 15e3;
5472
+ return scaleAcpTimeoutMs(15e3, "init", this.getTimeoutProfile());
5179
5473
  }
5180
5474
  getIdleTimeout() {
5181
5475
  return 600;
@@ -5188,7 +5482,7 @@ class CursorTransport extends DefaultTransport {
5188
5482
  super("cursor");
5189
5483
  }
5190
5484
  getInitTimeout() {
5191
- return 2e4;
5485
+ return scaleAcpTimeoutMs(2e4, "init", this.getTimeoutProfile());
5192
5486
  }
5193
5487
  getIdleTimeout() {
5194
5488
  return 700;
@@ -5869,14 +6163,14 @@ function readPositiveIntegerEnv(name) {
5869
6163
  return value;
5870
6164
  }
5871
6165
  function resolvePostPromptNoUpdatesTimeoutMs(transport) {
5872
- const transportValue = transport.getPostPromptNoUpdatesTimeoutMs?.();
5873
- if (typeof transportValue === "number" && Number.isFinite(transportValue) && transportValue > 0) {
5874
- return Math.trunc(transportValue);
5875
- }
5876
6166
  const envValue = readPositiveIntegerEnv("HAPPY_ACP_POST_PROMPT_NO_UPDATES_TIMEOUT_MS") ?? readPositiveIntegerEnv("HAPPIER_ACP_POST_PROMPT_NO_UPDATES_TIMEOUT_MS");
5877
6167
  if (envValue != null) {
5878
6168
  return envValue;
5879
6169
  }
6170
+ const transportValue = transport.getPostPromptNoUpdatesTimeoutMs?.();
6171
+ if (typeof transportValue === "number" && Number.isFinite(transportValue) && transportValue > 0) {
6172
+ return Math.trunc(transportValue);
6173
+ }
5880
6174
  return DEFAULT_POST_PROMPT_NO_UPDATES_TIMEOUT_MS;
5881
6175
  }
5882
6176
  function getSessionUpdates(params) {
@@ -6165,6 +6459,10 @@ class AcpBackend {
6165
6459
  constructor(options) {
6166
6460
  this.options = options;
6167
6461
  this.transport = options.transportHandler ?? new DefaultTransport(options.agentName);
6462
+ this.sessionPreferences = resolveAcpSessionPreferences({
6463
+ agentName: options.agentName,
6464
+ env: options.env
6465
+ });
6168
6466
  }
6169
6467
  listeners = [];
6170
6468
  process = null;
@@ -6211,6 +6509,8 @@ class AcpBackend {
6211
6509
  sawSessionUpdateSincePrompt = false;
6212
6510
  /** Transport handler for agent-specific behavior */
6213
6511
  transport;
6512
+ sessionPreferences;
6513
+ sessionConfigOptions = null;
6214
6514
  /** Keep a short rolling stderr buffer so startup failures can surface the real cause. */
6215
6515
  recentStderrLines = [];
6216
6516
  recordRecentStderr(text) {
@@ -6226,6 +6526,60 @@ class AcpBackend {
6226
6526
  getRecentStderrExcerpt() {
6227
6527
  return this.recentStderrLines.slice(-6).join("\n");
6228
6528
  }
6529
+ updateSessionConfigOptions(configOptions) {
6530
+ this.sessionConfigOptions = Array.isArray(configOptions) ? configOptions : null;
6531
+ }
6532
+ syncSessionConfigOptionsFromUpdate(update) {
6533
+ const configOptions = update.configOptions;
6534
+ if (!Array.isArray(configOptions)) {
6535
+ return false;
6536
+ }
6537
+ this.updateSessionConfigOptions(configOptions);
6538
+ return true;
6539
+ }
6540
+ async applySessionConfigPresets() {
6541
+ if (!this.connection || !this.acpSessionId) {
6542
+ return;
6543
+ }
6544
+ const presetPlan = buildAcpSessionConfigPresetPlan({
6545
+ sessionId: this.acpSessionId,
6546
+ configOptions: this.sessionConfigOptions,
6547
+ preferences: this.sessionPreferences
6548
+ });
6549
+ if (presetPlan.length === 0) {
6550
+ return;
6551
+ }
6552
+ logger.debug(
6553
+ `[AcpBackend] Applying ${presetPlan.length} ACP session config preset(s) for ${this.sessionPreferences.agentName}`
6554
+ );
6555
+ for (const preset of presetPlan) {
6556
+ try {
6557
+ logger.debug(
6558
+ `[AcpBackend] Setting ACP session config ${preset.optionId} from ${String(preset.currentValue)} to ${String(preset.targetValue)}`
6559
+ );
6560
+ const response = await this.connection.setSessionConfigOption(preset.request);
6561
+ this.updateSessionConfigOptions(response.configOptions);
6562
+ } catch (error) {
6563
+ logger.warn(
6564
+ `[AcpBackend] Failed to apply ACP session config preset ${preset.optionId}:`,
6565
+ error
6566
+ );
6567
+ }
6568
+ }
6569
+ }
6570
+ getPostPromptNoUpdatesTimeoutMs() {
6571
+ const explicitTimeout = readPositiveIntegerEnv("HAPPY_ACP_POST_PROMPT_NO_UPDATES_TIMEOUT_MS") ?? readPositiveIntegerEnv("HAPPIER_ACP_POST_PROMPT_NO_UPDATES_TIMEOUT_MS");
6572
+ if (explicitTimeout != null) {
6573
+ return explicitTimeout;
6574
+ }
6575
+ if (this.sessionPreferences.timeoutSource === "env") {
6576
+ return resolveAcpPostPromptNoUpdatesTimeoutMs(
6577
+ DEFAULT_POST_PROMPT_NO_UPDATES_TIMEOUT_MS,
6578
+ this.sessionPreferences.timeoutProfile
6579
+ );
6580
+ }
6581
+ return resolvePostPromptNoUpdatesTimeoutMs(this.transport);
6582
+ }
6229
6583
  clearIdleTimeoutState() {
6230
6584
  if (this.idleTimeout) {
6231
6585
  clearTimeout(this.idleTimeout);
@@ -6799,7 +7153,9 @@ ${recentStderrExcerpt}`);
6799
7153
  }
6800
7154
  );
6801
7155
  this.acpSessionId = sessionResponse.sessionId;
7156
+ this.updateSessionConfigOptions(sessionResponse.configOptions);
6802
7157
  logger.debug(`[AcpBackend] Session created: ${this.acpSessionId}`);
7158
+ await this.applySessionConfigPresets();
6803
7159
  this.emitIdleStatus();
6804
7160
  if (initialPrompt) {
6805
7161
  this.sendPrompt(sessionId, initialPrompt).catch((error) => {
@@ -6935,6 +7291,12 @@ ${recentStderrExcerpt}`);
6935
7291
  this.emitUsageTelemetry(update, "acp-usage-update");
6936
7292
  continue;
6937
7293
  }
7294
+ if (sessionUpdateType === "config_option_update") {
7295
+ if (this.syncSessionConfigOptionsFromUpdate(update)) {
7296
+ this.markResponseProgress({ refreshToolTimeouts: false });
7297
+ }
7298
+ continue;
7299
+ }
6938
7300
  if (sessionUpdateType === "task_complete") {
6939
7301
  this.emitUsageTelemetry(update.usage, "acp-session-usage");
6940
7302
  ctx.clearIdleTimeout();
@@ -6950,7 +7312,15 @@ ${recentStderrExcerpt}`);
6950
7312
  this.markResponseProgress();
6951
7313
  }
6952
7314
  const updateTypeStr = sessionUpdateType;
6953
- const handledTypes = ["agent_message_chunk", "tool_call_update", "agent_thought_chunk", "tool_call", "usage_update", "task_complete"];
7315
+ const handledTypes = [
7316
+ "agent_message_chunk",
7317
+ "tool_call_update",
7318
+ "agent_thought_chunk",
7319
+ "tool_call",
7320
+ "usage_update",
7321
+ "config_option_update",
7322
+ "task_complete"
7323
+ ];
6954
7324
  if (updateTypeStr && !handledTypes.includes(updateTypeStr) && !handledLegacy && !handledPlan && !handledThinking && !handledUsage) {
6955
7325
  logger.debug(`[AcpBackend] Unhandled session update type: ${updateTypeStr}`, JSON.stringify(update, null, 2));
6956
7326
  }
@@ -6983,7 +7353,7 @@ ${recentStderrExcerpt}`);
6983
7353
  await this.connection.prompt(promptRequest);
6984
7354
  logger.debug("[AcpBackend] Prompt request sent to ACP connection");
6985
7355
  if (this.waitingForResponse && this.activeToolCalls.size === 0 && this.sawSessionUpdateSincePrompt === false) {
6986
- const noUpdatesTimeoutMs = resolvePostPromptNoUpdatesTimeoutMs(this.transport);
7356
+ const noUpdatesTimeoutMs = this.getPostPromptNoUpdatesTimeoutMs();
6987
7357
  this.postPromptCompletionIdleTimeout = setTimeout(() => {
6988
7358
  this.postPromptCompletionIdleTimeout = null;
6989
7359
  if (this.responseCompletionError || !this.waitingForResponse) {
@@ -7028,7 +7398,7 @@ ${recentStderrExcerpt}`);
7028
7398
  * Wait for the response to complete (idle status after all chunks received)
7029
7399
  * Call this after sendPrompt to wait for Gemini to finish responding
7030
7400
  */
7031
- async waitForResponseComplete(timeoutMs = 10 * 6e4) {
7401
+ async waitForResponseComplete(timeoutMs) {
7032
7402
  if (this.responseCompletionError) {
7033
7403
  throw this.responseCompletionError;
7034
7404
  }
@@ -7043,6 +7413,7 @@ ${recentStderrExcerpt}`);
7043
7413
  if (!this.waitingForResponse) {
7044
7414
  return;
7045
7415
  }
7416
+ const effectiveTimeoutMs = timeoutMs ?? resolveAcpResponseWaitTimeoutMs(this.sessionPreferences.timeoutProfile);
7046
7417
  return new Promise((resolve, reject) => {
7047
7418
  this.idleResolver = () => {
7048
7419
  this.idleResolver = null;
@@ -7056,7 +7427,7 @@ ${recentStderrExcerpt}`);
7056
7427
  this.waitingForResponse = false;
7057
7428
  reject(error);
7058
7429
  };
7059
- this.armResponseWaitTimeout(timeoutMs);
7430
+ this.armResponseWaitTimeout(effectiveTimeoutMs);
7060
7431
  });
7061
7432
  }
7062
7433
  /**
@@ -7135,6 +7506,7 @@ ${recentStderrExcerpt}`);
7135
7506
  this.listeners = [];
7136
7507
  this.connection = null;
7137
7508
  this.acpSessionId = null;
7509
+ this.sessionConfigOptions = null;
7138
7510
  this.clearToolCallTracking();
7139
7511
  this.pendingPermissions.clear();
7140
7512
  }
@@ -9122,11 +9494,11 @@ var launch = /*#__PURE__*/Object.freeze({
9122
9494
 
9123
9495
  const unifiedProviderExecutors = {
9124
9496
  claude: async (opts) => {
9125
- const { runClaude } = await import('./runClaude-7St9-Jci.mjs');
9497
+ const { runClaude } = await import('./runClaude-BRhQLKjh.mjs');
9126
9498
  await runClaude(opts.credentials, opts.claudeOptions ?? {});
9127
9499
  },
9128
9500
  codex: async (opts) => {
9129
- const { runCodex } = await import('./runCodex-BaXi_9BC.mjs');
9501
+ const { runCodex } = await import('./runCodex-DUs_jBE-.mjs');
9130
9502
  await runCodex({
9131
9503
  credentials: opts.credentials,
9132
9504
  startedBy: opts.startedBy,
@@ -9135,7 +9507,7 @@ const unifiedProviderExecutors = {
9135
9507
  });
9136
9508
  },
9137
9509
  gemini: async (opts) => {
9138
- const { runGemini } = await import('./runGemini-ClNqE9N3.mjs');
9510
+ const { runGemini } = await import('./runGemini-pmvBZ6qU.mjs');
9139
9511
  await runGemini({
9140
9512
  credentials: opts.credentials,
9141
9513
  startedBy: opts.startedBy
@@ -9211,7 +9583,7 @@ function shouldRunMainClaudeFlow(opts) {
9211
9583
  return;
9212
9584
  } else if (subcommand === "runtime") {
9213
9585
  if (args[1] === "providers") {
9214
- const { renderRuntimeProviders } = await import('./command-FbV44egL.mjs');
9586
+ const { renderRuntimeProviders } = await import('./command-BVCkEMtp.mjs');
9215
9587
  console.log(renderRuntimeProviders());
9216
9588
  return;
9217
9589
  }
@@ -9389,8 +9761,8 @@ function shouldRunMainClaudeFlow(opts) {
9389
9761
  const projectId = args[3];
9390
9762
  try {
9391
9763
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
9392
- const { readCredentials: readCredentials2 } = await import('./persistence-Cmgj3ubQ.mjs');
9393
- const { ApiClient: ApiClient2 } = await import('./api-BGv79x9Q.mjs').then(function (n) { return n.v; });
9764
+ const { readCredentials: readCredentials2 } = await import('./persistence-CyFjFOlN.mjs');
9765
+ const { ApiClient: ApiClient2 } = await import('./api-l8X03rs-.mjs').then(function (n) { return n.v; });
9394
9766
  let userEmail = void 0;
9395
9767
  try {
9396
9768
  const credentials = await readCredentials2();
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./api-OoiG7XjD.cjs');
5
- require('./persistence-lN9HV4IZ.cjs');
4
+ require('./api-B6ESNpGB.cjs');
5
+ require('./persistence-EDmI-c8T.cjs');
6
6
  require('zod');
7
- require('./index-D9lWHpn-.cjs');
7
+ require('./index-D1BP-fEm.cjs');
8
8
  require('node:child_process');
9
9
  require('node:fs');
10
10
  require('cross-spawn');
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import 'chalk';
2
- import './api-BGv79x9Q.mjs';
3
- import './persistence-Cmgj3ubQ.mjs';
2
+ import './api-l8X03rs-.mjs';
3
+ import './persistence-CyFjFOlN.mjs';
4
4
  import 'zod';
5
- import './index-TRC83Ks9.mjs';
5
+ import './index-D72RMo5Z.mjs';
6
6
  import 'node:child_process';
7
7
  import 'node:fs';
8
8
  import 'cross-spawn';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var api = require('./api-OoiG7XjD.cjs');
3
+ var api = require('./api-B6ESNpGB.cjs');
4
4
  var types = require('./types-DVk3crez.cjs');
5
5
  require('axios');
6
6
  require('chalk');
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-BGv79x9Q.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-l8X03rs-.mjs';
2
2
  export { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
3
3
  import 'axios';
4
4
  import 'chalk';
@@ -1,7 +1,7 @@
1
1
  import { unlink, readFile, mkdir, open, stat, writeFile, rename } from 'node:fs/promises';
2
2
  import { existsSync, unlinkSync, readdirSync, constants, writeFileSync, readFileSync } from 'node:fs';
3
3
  import { join, dirname } from 'node:path';
4
- import { c as configuration, l as logger, e as encodeBase64 } from './api-BGv79x9Q.mjs';
4
+ import { c as configuration, l as logger, e as encodeBase64 } from './api-l8X03rs-.mjs';
5
5
  import * as z from 'zod';
6
6
  import 'axios';
7
7
  import 'chalk';