nolo-cli 0.211.0 → 0.213.0

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 (173) hide show
  1. package/{_executeModel-VVQEOY3D.js → _executeModel-CUJLCFWR.js} +57 -54
  2. package/{action-U235TV4P.js → action-DF5UYSJF.js} +4 -4
  3. package/{addContentAction-7C76J7ST.js → addContentAction-WERAONNY.js} +9 -9
  4. package/{addDialogAgentAction-KTYANUEC.js → addDialogAgentAction-7VI7YRML.js} +16 -13
  5. package/{agentDeleteCommand-WHRU6VDJ.js → agentDeleteCommand-XJORXPGU.js} +80 -76
  6. package/{agentEmailCommands-ALLHXPW3.js → agentEmailCommands-XTYYFR6Z.js} +85 -80
  7. package/{agentListCommands-POKMEKMS.js → agentListCommands-OBLRBLHS.js} +237 -115
  8. package/{agentMachineCommands-WJLZLBPI.js → agentMachineCommands-5FMT3OT5.js} +33 -31
  9. package/{agentProviderCommands-MN3ABDME.js → agentProviderCommands-Q5O33MED.js} +33 -4
  10. package/{agentRecordCommands-OULZW3KM.js → agentRecordCommands-ZQ7SVYGG.js} +75 -70
  11. package/{agentRunCommand-ZNG4LGNQ.js → agentRunCommand-WS7IGO2W.js} +77 -73
  12. package/{agentRunControl-AF7BMR22.js → agentRunControl-TAMHJQSR.js} +8 -7
  13. package/{agentRuntimeLocal-YMUHFV5M.js → agentRuntimeLocal-SOO2OPJG.js} +30 -27
  14. package/{agentSlice-WNGUIMQZ.js → agentSlice-CHR6KOZN.js} +13 -13
  15. package/{appDeleteCommands-6MXPLAVF.js → appDeleteCommands-GUP6P5YE.js} +34 -32
  16. package/{appDeployCommands-ERRSVASW.js → appDeployCommands-MH2FX4O5.js} +34 -32
  17. package/{appDeployStatusCommands-ULICISLI.js → appDeployStatusCommands-SUHN3HPJ.js} +34 -32
  18. package/{appGetCommands-WYYYWROF.js → appGetCommands-YWDEX6Z4.js} +34 -32
  19. package/{appListCommands-DFCUCRCV.js → appListCommands-ZQVMLPAY.js} +34 -32
  20. package/{authCommand-ZJMWXFMA.js → authCommand-PWX2ZNUP.js} +15 -15
  21. package/{authCommands-WK6E42L2.js → authCommands-HV3EAU3V.js} +2 -2
  22. package/{builtinSkillRegistry-HH75G5J3.js → builtinSkillRegistry-2QETTQPM.js} +5 -4
  23. package/{chromeOpsCommands-HEN5AX2J.js → chromeOpsCommands-DIVM2K3T.js} +1 -1
  24. package/{chunk-TRZP7JZ7.js → chunk-2QHFH3DR.js} +1 -0
  25. package/{chunk-XE4Q46FF.js → chunk-3CGG2PAL.js} +1 -1
  26. package/{chunk-YUXQAVRD.js → chunk-3UKL3HPD.js} +251 -14
  27. package/{chunk-BSISWVB4.js → chunk-4I7ERB7F.js} +1 -1
  28. package/{chunk-5ORJGHTL.js → chunk-4T2WNOY7.js} +6 -6
  29. package/{chunk-W5VC7F7V.js → chunk-5MQRBSMW.js} +84 -91
  30. package/{chunk-YLTLB5A7.js → chunk-6DWMYIUY.js} +7 -6
  31. package/chunk-6VLJ6YA7.js +11751 -0
  32. package/{chunk-KSTEXKL6.js → chunk-75XIDFBW.js} +4 -3
  33. package/{chunk-BTYQAODF.js → chunk-7BT37FK3.js} +196 -308
  34. package/{chunk-27E2CBBY.js → chunk-7OCO4TDT.js} +1 -1
  35. package/{chunk-V3M6IXQI.js → chunk-7QTZCMKL.js} +335 -131
  36. package/chunk-7RFNTILS.js +2213 -0
  37. package/{chunk-NHQKWPLP.js → chunk-7Y4YTDQF.js} +25 -23
  38. package/{chunk-CKAHAVMK.js → chunk-A7TFUNZO.js} +35 -25
  39. package/{chunk-PJNFNEJE.js → chunk-ALQ3657A.js} +28 -2
  40. package/{chunk-NV572QM3.js → chunk-BBJ22CLB.js} +15 -15
  41. package/chunk-CJEIOP3E.js +0 -0
  42. package/{chunk-4WCEC56C.js → chunk-COFEN36Z.js} +2 -2
  43. package/{chunk-25OB36GU.js → chunk-CRHOO2ZR.js} +4 -4
  44. package/{chunk-NTSRCTUX.js → chunk-CTPXME7U.js} +2 -2
  45. package/{chunk-TPCDYNJK.js → chunk-EHGEOAHI.js} +3 -3
  46. package/{chunk-Y2WUYX4I.js → chunk-EHSZD5OI.js} +1 -1
  47. package/{chunk-SU3QL7YG.js → chunk-FUGMREBO.js} +2 -2
  48. package/{chunk-UMEGDH6A.js → chunk-FW6YHHLI.js} +8 -8
  49. package/chunk-FY7F4Q6X.js +127 -0
  50. package/{chunk-25M2K6OA.js → chunk-G2BQWAVT.js} +3 -3
  51. package/chunk-G7MLNNEX.js +84 -0
  52. package/{chunk-DQLB4NQ3.js → chunk-GPVRUGGY.js} +2 -2
  53. package/{chunk-RQ22OZD7.js → chunk-H2TJUNCH.js} +1 -1
  54. package/{chunk-XPHZK3PJ.js → chunk-H4UOTUOX.js} +165 -51
  55. package/{chunk-CVCRAO6Q.js → chunk-H5HF7TJA.js} +9 -7
  56. package/{chunk-OP7PTBAJ.js → chunk-H7PPIYWP.js} +9 -9
  57. package/{chunk-QQM464AL.js → chunk-HPFCI4SK.js} +3 -3
  58. package/chunk-HRMJUN5J.js +26 -0
  59. package/{chunk-WI6OGHXJ.js → chunk-HSVBJRF4.js} +5 -5
  60. package/{chunk-RYWO5AKN.js → chunk-HUBHAQK2.js} +10 -10
  61. package/{chunk-LKDF3ATR.js → chunk-INUFILG6.js} +1 -1
  62. package/{chunk-NXCGNS4N.js → chunk-IXNGOHV5.js} +2 -2
  63. package/{chunk-ET2CWLIJ.js → chunk-J2NHJ7WX.js} +4 -4
  64. package/{chunk-ECX3NKRD.js → chunk-JY5NGFFH.js} +11 -0
  65. package/chunk-KC4XDTT3.js +227 -0
  66. package/{chunk-ADBWFYJD.js → chunk-KFLT5KAD.js} +9 -9
  67. package/{chunk-PLYWH7XM.js → chunk-KIM6CLW5.js} +7 -7
  68. package/{chunk-7IYBN7IA.js → chunk-LLRPJECG.js} +22 -13
  69. package/{chunk-3J3U3KXB.js → chunk-MDB67IWP.js} +5 -5
  70. package/chunk-MMA3LZ3W.js +105 -0
  71. package/{chunk-XDMGY5IU.js → chunk-MOIJOHA5.js} +227 -11
  72. package/{chunk-NLT32XBZ.js → chunk-NJLL224W.js} +2 -2
  73. package/{chunk-JBOUVTZX.js → chunk-NOKUNJON.js} +15 -4
  74. package/{chunk-C2XZM3K4.js → chunk-NSAPDIN2.js} +12 -27
  75. package/{chunk-PAFTGNWA.js → chunk-O2TZF4AI.js} +2 -2
  76. package/{chunk-UIOEHFF6.js → chunk-OQHIVPG4.js} +1 -0
  77. package/{chunk-TCTSYFDM.js → chunk-OQPKUBPB.js} +19 -6
  78. package/{chunk-X4F26D5K.js → chunk-P5L7CXOC.js} +58 -33
  79. package/{chunk-OXME3PEE.js → chunk-PCLE46CE.js} +1 -1
  80. package/{chunk-UCPAVEQB.js → chunk-PYRUW7XN.js} +1 -1
  81. package/{chunk-YXOBCDNW.js → chunk-QG4AOSON.js} +12 -49
  82. package/{chunk-RXCCWVA2.js → chunk-QHPRUL4O.js} +3 -3
  83. package/{chunk-I5PBXF7O.js → chunk-R5O4QAWG.js} +1 -1
  84. package/{chunk-HD3WR3TD.js → chunk-RLBNLZVC.js} +1 -1
  85. package/{chunk-SN5XE6GQ.js → chunk-RPQXPZZF.js} +4 -4
  86. package/{chunk-ZOO3WJIE.js → chunk-RSHTSUEG.js} +948 -108
  87. package/{chunk-6HVBI6TI.js → chunk-RZOV7OMV.js} +12 -229
  88. package/{chunk-D2MDMY2M.js → chunk-SVYO6AO7.js} +7 -1
  89. package/{chunk-IIHY4ZAI.js → chunk-TAKB25RM.js} +8 -4
  90. package/{chunk-ZN5AH4BY.js → chunk-TX5EYMGT.js} +6 -6
  91. package/{chunk-CKOO42G5.js → chunk-UHJGXRJ4.js} +4 -4
  92. package/{chunk-M4NTDZG3.js → chunk-UYD5HQ6T.js} +857 -295
  93. package/{chunk-WTKYP6QO.js → chunk-V5Y3R6BT.js} +114 -6
  94. package/{chunk-3RQVYR4B.js → chunk-VNYYOX3V.js} +59 -20
  95. package/{chunk-4LEGTOSR.js → chunk-VO4WSAVP.js} +3 -3
  96. package/{chunk-LNYHAKBP.js → chunk-W4S457LU.js} +1 -1
  97. package/{chunk-RIALQUSF.js → chunk-WMTBPBMP.js} +6 -6
  98. package/chunk-WPORQFYN.js +74 -0
  99. package/{chunk-Y6M7KJOA.js → chunk-WRYQ35LQ.js} +5 -5
  100. package/{chunk-YKFP6UGT.js → chunk-WYDI6TGM.js} +17 -17
  101. package/{chunk-SCYQJPGA.js → chunk-X7SDOJUM.js} +147 -20
  102. package/chunk-XFYFMTOM.js +92 -0
  103. package/{chunk-LT3EAHJY.js → chunk-XHQC4PXX.js} +65 -49
  104. package/{chunk-2WZXXAQD.js → chunk-YB3YZK56.js} +67 -1
  105. package/{chunk-JKW6LERJ.js → chunk-YJAFKXMU.js} +14 -14
  106. package/{chunk-GSQNH63I.js → chunk-YTF4WH7J.js} +3 -19
  107. package/{chunk-DA7CTWT4.js → chunk-YWSEPJ7C.js} +5 -5
  108. package/{chunk-3V2QMRNN.js → chunk-ZL5RAEEB.js} +3 -3
  109. package/{chunk-NEZGPBL7.js → chunk-ZNWI6OVT.js} +2 -2
  110. package/{chunk-MBS6CTZB.js → chunk-ZXOUUDCG.js} +266 -2014
  111. package/cliAgentConfigHelpers-WJBZQTLW.js +41 -0
  112. package/{commandRegistry-FI2IOQ3U.js → commandRegistry-W63CYRZJ.js} +91 -87
  113. package/{contentThunks-5LKNNDGY.js → contentThunks-U7PL5MQD.js} +27 -26
  114. package/{cooldownCommands-YXLWOXWR.js → cooldownCommands-TIGUHXTD.js} +3 -3
  115. package/{createAgentAutomationAction-TI4QG4CY.js → createAgentAutomationAction-OLBQDD6R.js} +27 -26
  116. package/{createDialogAction-TJ3JKLO4.js → createDialogAction-SVH6B3SB.js} +29 -28
  117. package/{createPageAction-GKXT6WEH.js → createPageAction-F4DIWZ2Z.js} +29 -28
  118. package/{dbSlice-LPMZ2DGJ.js → dbSlice-BVH2YZPQ.js} +8 -8
  119. package/{deleteFile-EPUQHKPA.js → deleteFile-5YOEKV4U.js} +4 -4
  120. package/{dialogCommands-IWPXIZ5P.js → dialogCommands-KHIEPY3M.js} +38 -36
  121. package/{dialogSlice-ZWNNS7GZ.js → dialogSlice-ZCTDV2PZ.js} +25 -24
  122. package/{dialogUsageCommand-ZCPPHPJ5.js → dialogUsageCommand-7KCPYGHG.js} +1 -1
  123. package/{docCreateCommands-HFSPKJSI.js → docCreateCommands-DPMZI7G5.js} +32 -30
  124. package/{docDeleteCommands-CRL62POH.js → docDeleteCommands-IRQQLUBT.js} +34 -33
  125. package/{docReadCommands-QOTOX3XW.js → docReadCommands-LK37XH6L.js} +32 -30
  126. package/{docStore-WYLRB7ED.js → docStore-V2KECILA.js} +11 -11
  127. package/{docUpdateCommands-7BMH4MCA.js → docUpdateCommands-O6T3HJHH.js} +32 -30
  128. package/{fetchMessages-YY4SATNR.js → fetchMessages-NR4KNQLO.js} +3 -3
  129. package/{getPricing-OQXBJ6VZ.js → getPricing-2MNMXEVG.js} +3 -3
  130. package/{handleSendMessageAction-P27YP2DQ.js → handleSendMessageAction-2PE25WM3.js} +49 -47
  131. package/hostCredentialCreate-S233UMAP.js +357 -0
  132. package/index.js +7 -7
  133. package/{keys-P4ZDOVJW.js → keys-BEGDOTRL.js} +3 -1
  134. package/{localDialogRead-5VCMQQZF.js → localDialogRead-7NNDVVF7.js} +1 -1
  135. package/{localRuntimeAdapter-GP6ZSSO3.js → localRuntimeAdapter-KY6WXNBR.js} +82 -75
  136. package/{machineCommands-6Z6H4BFX.js → machineCommands-Q6HA3IXF.js} +74 -69
  137. package/{machineWsRunDispatch-F2ZIXMYM.js → machineWsRunDispatch-WWJQ6WR3.js} +74 -69
  138. package/{memberThunks-YSEFJF47.js → memberThunks-7EDJADWU.js} +9 -9
  139. package/package.json +1 -1
  140. package/{projectArchive-PIGEOX3D.js → projectArchive-DRTDIMEV.js} +29 -28
  141. package/{providerPresetApply-ZYMLQA46.js → providerPresetApply-YXGV6NXB.js} +4 -4
  142. package/{providerRegistry-E34XWDLJ.js → providerRegistry-S6UL6UNA.js} +4 -4
  143. package/{read-DIIQBOOO.js → read-4V2RMG7N.js} +4 -4
  144. package/{readDocTool-HXYGOEA7.js → readDocTool-BH6ATGQO.js} +1 -1
  145. package/{readlineWorkspace-UG25G7KC.js → readlineWorkspace-2W4WRCOU.js} +437 -217
  146. package/{removeDialogAgentAction-ALJDUJ2E.js → removeDialogAgentAction-LYAZGNKW.js} +18 -15
  147. package/{runAgentClientLoop-IO5F7TCZ.js → runAgentClientLoop-J2VQBS2Z.js} +55 -52
  148. package/{runtimeDoctorCommands-PGAA47G5.js → runtimeDoctorCommands-QAI3MBKQ.js} +6 -6
  149. package/{secretCommands-ZCZ4KVET.js → secretCommands-LXDWOLZ6.js} +4 -4
  150. package/{setDialogExtraReferencesAction-O3SVMD5A.js → setDialogExtraReferencesAction-OCRPGPYH.js} +11 -11
  151. package/{setPrimaryDialogAgentAction-HE7RVFFF.js → setPrimaryDialogAgentAction-HFJDQIBU.js} +19 -16
  152. package/{settingThunks-BWWJQG4L.js → settingThunks-RAMHMTGM.js} +13 -12
  153. package/{spaceCommands-UAELIFEI.js → spaceCommands-KVJZVKVO.js} +32 -31
  154. package/{streamAgentChatTurn-VUKZQYJR.js → streamAgentChatTurn-GHBMJJ6S.js} +63 -60
  155. package/{switchDialogAgentAction-3VZS7SOS.js → switchDialogAgentAction-EBRMW3RA.js} +16 -13
  156. package/{tools-VRXJAVYI.js → tools-EWKCPKMS.js} +49 -46
  157. package/{tuiSummaryLlmCaller-TGCHZLSW.js → tuiSummaryLlmCaller-ALQYUUWB.js} +48 -19
  158. package/{updateCommands-Q6CYAEYJ.js → updateCommands-ZQYU6SCI.js} +5 -3
  159. package/{updateDialogTitleAction-MULWCJCW.js → updateDialogTitleAction-5GGMBTDF.js} +40 -72
  160. package/usageCommand-F4IPVMIZ.js +32 -0
  161. package/usageRebuildCommand-HAW2AD5N.js +626 -0
  162. package/{windowsSelfUpdate-XSQVF2GK.js → windowsSelfUpdate-257DV2T6.js} +2 -2
  163. package/{workloadLifecycle-4BEQHMSD.js → workloadLifecycle-4C42SVBD.js} +1 -0
  164. package/chunk-4LCOCOR5.js +0 -50
  165. package/chunk-7AUQ3WCW.js +0 -51
  166. package/chunk-ZRAU6T47.js +0 -56
  167. package/{agentFavoriteCommands-GAFEXKKP.js → agentFavoriteCommands-EDK743YA.js} +1 -1
  168. package/{agentGrantCommands-V5FOQKFD.js → agentGrantCommands-RQWK2TEV.js} +1 -1
  169. package/{agentPullCommand-2JMJP5BS.js → agentPullCommand-6EM3URVK.js} +1 -1
  170. package/{chunk-A2ZMIRLN.js → chunk-INN4LTAJ.js} +5 -5
  171. package/{chunk-PV6JJAUB.js → chunk-TCZHTTUU.js} +8 -8
  172. package/{chunk-AKE53VMW.js → chunk-ZCWRMUWT.js} +0 -0
  173. package/{tableCommands-D7WR4QSM.js → tableCommands-MP6VFSVT.js} +3 -3
@@ -1,12 +1,12 @@
1
+ import {
2
+ ALL_MODELS
3
+ } from "./chunk-T43B7LB2.js";
1
4
  import {
2
5
  estimateTokenCount
3
6
  } from "./chunk-PSCNXBYA.js";
4
7
  import {
5
8
  MODEL_LOOKUP_MAP
6
9
  } from "./chunk-SM3NSZJV.js";
7
- import {
8
- ALL_MODELS
9
- } from "./chunk-T43B7LB2.js";
10
10
  import {
11
11
  isPlatformManagedProvider,
12
12
  resolvePlatformEffectiveModel
@@ -40,71 +40,6 @@ function sha256Hex(text) {
40
40
  return SHA256(text).toString();
41
41
  }
42
42
 
43
- // packages/ai/context/retention.ts
44
- var SAFE_BUFFER_RATIO = 0.95;
45
- var CACHE_FIRST_RETENTION_STRENGTH = 0.95;
46
- var clamp = (v, min, max) => Math.min(max, Math.max(min, v));
47
- var planContextUsage = (params) => {
48
- const { contextWindow, summaryTokens, recentLoad } = params;
49
- const safeWindowLimit = Math.floor(contextWindow * SAFE_BUFFER_RATIO);
50
- const iq = CACHE_FIRST_RETENTION_STRENGTH;
51
- const isLargeWindow = contextWindow >= 512e3;
52
- const isSmallWindow = contextWindow <= 64e3;
53
- let baseHistoryRatio;
54
- if (isLargeWindow) {
55
- baseHistoryRatio = 0.8 + 0.2 * iq;
56
- } else if (isSmallWindow) {
57
- baseHistoryRatio = 0.35 + 0.3 * iq;
58
- } else {
59
- baseHistoryRatio = 0.55 + 0.3 * iq;
60
- }
61
- let historyRatio = baseHistoryRatio;
62
- switch (recentLoad) {
63
- case "light": {
64
- const maxRatio = isLargeWindow ? 1 : isSmallWindow ? 0.75 : 0.85;
65
- historyRatio = clamp(historyRatio * 1.05, 0.3, maxRatio);
66
- break;
67
- }
68
- case "heavy": {
69
- const maxRatio = isLargeWindow ? 0.98 : isSmallWindow ? 0.7 : 0.8;
70
- const multiplier = isLargeWindow ? 0.98 : isSmallWindow ? 0.9 : 0.9;
71
- historyRatio = clamp(historyRatio * multiplier, 0.3, maxRatio);
72
- break;
73
- }
74
- case "medium":
75
- default: {
76
- const maxRatio = isLargeWindow ? 1 : isSmallWindow ? 0.75 : 0.85;
77
- historyRatio = clamp(historyRatio, 0.3, maxRatio);
78
- break;
79
- }
80
- }
81
- const historyBudget = Math.max(
82
- 0,
83
- Math.floor(safeWindowLimit * historyRatio)
84
- );
85
- const minRawRatio = isSmallWindow ? 0.5 : isLargeWindow ? 0.2 : 0.3;
86
- const rawMessageBudget = Math.max(
87
- Math.floor(historyBudget * minRawRatio),
88
- historyBudget - summaryTokens,
89
- 0
90
- );
91
- let minTailTokens;
92
- if (recentLoad === "light") {
93
- minTailTokens = Math.min(
94
- Math.floor(safeWindowLimit * 0.3),
95
- 8e3
96
- );
97
- } else if (recentLoad === "heavy") {
98
- minTailTokens = Math.max(
99
- Math.floor(safeWindowLimit * 0.25),
100
- 16e3
101
- );
102
- } else {
103
- minTailTokens = Math.floor(safeWindowLimit * 0.2);
104
- }
105
- return { historyBudget, rawMessageBudget, minTailTokens };
106
- };
107
-
108
43
  // packages/ai/context/toolOutputCap.ts
109
44
  var TOOL_OUTPUT_CAP_WINDOW_RATIO = 0.12;
110
45
  var TOOL_OUTPUT_CAP_MIN_TOKENS = 4e3;
@@ -114,8 +49,8 @@ var COMPRESSION_TRIGGER_RATIO_MIN = 0.5;
114
49
  var ROUND_OVERHEAD_WINDOW_RATIO = 0.08;
115
50
  var ROUND_OVERHEAD_MIN_TOKENS = 4e3;
116
51
  var ROUND_OVERHEAD_MAX_TOKENS = 24e3;
117
- var clamp2 = (v, min, max) => Math.min(max, Math.max(min, v));
118
- var capToolOutputTokens = (contextWindow) => clamp2(
52
+ var clamp = (v, min, max) => Math.min(max, Math.max(min, v));
53
+ var capToolOutputTokens = (contextWindow) => clamp(
119
54
  Math.floor(contextWindow * TOOL_OUTPUT_CAP_WINDOW_RATIO),
120
55
  TOOL_OUTPUT_CAP_MIN_TOKENS,
121
56
  TOOL_OUTPUT_CAP_MAX_TOKENS
@@ -124,12 +59,12 @@ var resolveCompressionTriggerRatio = (contextWindow) => {
124
59
  if (typeof contextWindow !== "number" || !Number.isFinite(contextWindow) || contextWindow <= 0) {
125
60
  return COMPRESSION_TRIGGER_RATIO_MAX;
126
61
  }
127
- const headroom = capToolOutputTokens(contextWindow) + clamp2(
62
+ const headroom = capToolOutputTokens(contextWindow) + clamp(
128
63
  Math.floor(contextWindow * ROUND_OVERHEAD_WINDOW_RATIO),
129
64
  ROUND_OVERHEAD_MIN_TOKENS,
130
65
  ROUND_OVERHEAD_MAX_TOKENS
131
66
  );
132
- return clamp2(
67
+ return clamp(
133
68
  1 - headroom / contextWindow,
134
69
  COMPRESSION_TRIGGER_RATIO_MIN,
135
70
  COMPRESSION_TRIGGER_RATIO_MAX
@@ -182,24 +117,6 @@ var getMessageTokenCount = (msg) => {
182
117
  return tokens;
183
118
  };
184
119
  var hasOpenEndedToolCall = (msg) => !!msg && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0;
185
- var classifyConversationLoad = (msgs) => {
186
- const N = 20;
187
- if (!Array.isArray(msgs) || msgs.length === 0) return "light";
188
- const tail = msgs.slice(-N);
189
- const tokenSamples = tail.map(getMessageTokenCount);
190
- if (tokenSamples.length === 0) return "light";
191
- const sum = tokenSamples.reduce((acc, v) => acc + v, 0);
192
- const avg = sum / tokenSamples.length;
193
- const sorted = [...tokenSamples].sort((a, b) => a - b);
194
- const p95 = sorted[Math.floor((sorted.length - 1) * 0.95)];
195
- if (p95 < 200 && avg < 120) {
196
- return "light";
197
- }
198
- if (p95 > 2e3 || avg > 1200) {
199
- return "heavy";
200
- }
201
- return "medium";
202
- };
203
120
  var normalizeContextUsageRatio = (value) => {
204
121
  if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
205
122
  const ratio = value > 1 ? value / 100 : value;
@@ -224,21 +141,18 @@ function findPendingMessages(allMsgs, summarizedBeforeId) {
224
141
  }
225
142
  function shouldTriggerCompaction(args) {
226
143
  const {
227
- pendingMsgCount,
228
144
  totalUsed,
229
145
  historyBudget,
230
146
  triggerRatio,
231
147
  force,
232
148
  reason,
233
- realContextUsagePercent,
234
- coldResume,
235
- lastMsg
149
+ realContextUsagePercent
236
150
  } = args;
237
151
  const usageRatio = normalizeContextUsageRatio(realContextUsagePercent);
238
152
  const triggeredByRealUsage = usageRatio !== void 0 && usageRatio >= triggerRatio;
239
153
  const triggeredByEstimate = usageRatio === void 0 && totalUsed >= historyBudget;
240
- const shouldRunActiveSummary = force && reason === "manual" && (pendingMsgCount < MIN_TRIGGER_PENDING_COUNT || !hasOpenEndedToolCall(lastMsg));
241
- const triggeredByColdResume = coldResume === true && pendingMsgCount >= MIN_TRIGGER_PENDING_COUNT;
154
+ const shouldRunActiveSummary = force && reason === "manual";
155
+ const triggeredByColdResume = false;
242
156
  return {
243
157
  trigger: triggeredByRealUsage || triggeredByEstimate || shouldRunActiveSummary || triggeredByColdResume,
244
158
  triggeredByRealUsage,
@@ -246,11 +160,7 @@ function shouldTriggerCompaction(args) {
246
160
  triggeredByColdResume
247
161
  };
248
162
  }
249
- function calculateCompressCount(pendingMsgs, rawMessageBudget, opts) {
250
- const { keepTailCount, totalUsed, historyBudget } = opts;
251
- if (keepTailCount && totalUsed < historyBudget) {
252
- return Math.max(0, pendingMsgs.length - ACTIVE_SUMMARY_TAIL_KEEP_COUNT);
253
- }
163
+ function calculateCompressCount(pendingMsgs, rawMessageBudget) {
254
164
  let tokensToKeep = 0;
255
165
  let keepCount = 0;
256
166
  for (let i = pendingMsgs.length - 1; i >= 0; i--) {
@@ -286,19 +196,20 @@ function resolveEffectiveCompactionBudgets(args) {
286
196
  maxRetainedRatio
287
197
  };
288
198
  }
289
- function guardToolChainBoundary(pendingMsgs, compressCount) {
290
- let count = compressCount;
291
- while (count < pendingMsgs.length && pendingMsgs[count].role === "tool") {
292
- count++;
293
- }
294
- while (count > 0 && hasOpenEndedToolCall(pendingMsgs[count - 1])) {
295
- if (count < pendingMsgs.length && pendingMsgs[count].role === "tool") {
296
- count++;
297
- } else {
298
- count--;
299
- break;
199
+ function guardToolChainBoundary(pendingMsgs, compressCount, preserveByProjection) {
200
+ let safeLimit = Math.max(0, pendingMsgs.length - 1);
201
+ if (!preserveByProjection) {
202
+ for (let i = pendingMsgs.length - 1; i >= 0; i--) {
203
+ if (pendingMsgs[i].role === "user") {
204
+ safeLimit = i;
205
+ break;
206
+ }
300
207
  }
301
208
  }
209
+ let count = Math.min(compressCount, safeLimit);
210
+ while (count > 0 && (pendingMsgs[count]?.role === "tool" || hasOpenEndedToolCall(pendingMsgs[count - 1]))) {
211
+ count--;
212
+ }
302
213
  return count;
303
214
  }
304
215
  function planCompression(input) {
@@ -310,7 +221,7 @@ function planCompression(input) {
310
221
  force = false,
311
222
  reason,
312
223
  realContextUsagePercent,
313
- coldResume
224
+ preserveLatestUserByProjection = false
314
225
  } = input;
315
226
  const { pendingMsgs, startIndex } = findPendingMessages(allMsgs, summarizedBeforeId);
316
227
  if (pendingMsgs.length === 0) {
@@ -329,30 +240,31 @@ function planCompression(input) {
329
240
  }
330
241
  const summaryTokens = estimateTokenCount(summary || "");
331
242
  const pendingTokens = pendingMsgs.reduce((sum, msg) => sum + getMessageTokenCount(msg), 0);
332
- const totalUsed = summaryTokens + pendingTokens;
333
- const adjustedSummaryTokens = Math.max(summaryTokens, 1e3);
334
- const recentLoad = classifyConversationLoad(pendingMsgs);
335
- const { historyBudget, rawMessageBudget } = planContextUsage({
336
- contextWindow,
337
- summaryTokens: adjustedSummaryTokens,
338
- recentLoad
339
- });
243
+ let coveredUserTokens = 0;
244
+ if (preserveLatestUserByProjection && summary && startIndex > 0) {
245
+ for (let i = startIndex - 1; i >= 0; i--) {
246
+ if (allMsgs[i].role === "user") {
247
+ coveredUserTokens = getMessageTokenCount(allMsgs[i]);
248
+ break;
249
+ }
250
+ }
251
+ }
252
+ const totalUsed = summaryTokens + coveredUserTokens + pendingTokens;
340
253
  const triggerRatio = resolveCompressionTriggerRatio(contextWindow);
254
+ const historyBudget = Math.floor(contextWindow * triggerRatio);
255
+ const rawMessageBudget = Math.max(0, historyBudget - summaryTokens);
341
256
  const {
342
257
  trigger,
343
258
  triggeredByRealUsage,
344
259
  shouldRunActiveSummary,
345
260
  triggeredByColdResume
346
261
  } = shouldTriggerCompaction({
347
- pendingMsgCount: pendingMsgs.length,
348
262
  totalUsed,
349
263
  historyBudget,
350
264
  triggerRatio,
351
265
  force,
352
266
  reason,
353
- realContextUsagePercent,
354
- coldResume,
355
- lastMsg: pendingMsgs[pendingMsgs.length - 1]
267
+ realContextUsagePercent
356
268
  });
357
269
  const diagnostics = {
358
270
  pendingMsgCount: pendingMsgs.length,
@@ -371,44 +283,41 @@ function planCompression(input) {
371
283
  emptyReason: "not-triggered"
372
284
  });
373
285
  }
374
- const { effectiveHistoryBudget, effectiveRawMessageBudget } = resolveEffectiveCompactionBudgets({
286
+ const { effectiveRawMessageBudget } = resolveEffectiveCompactionBudgets({
375
287
  contextWindow,
376
288
  triggerRatio,
377
289
  historyBudget,
378
290
  rawMessageBudget,
379
- summaryTokens
291
+ summaryTokens: Math.max(summaryTokens, Math.min(1e3, Math.floor(contextWindow * 0.1)))
380
292
  });
381
- let compressCount = calculateCompressCount(
293
+ const minimumPrefixTokens = Math.min(1e3, Math.floor(contextWindow * 0.1));
294
+ const tailBudget = Math.min(effectiveRawMessageBudget, Math.max(0, pendingTokens - minimumPrefixTokens));
295
+ let compressCount = guardToolChainBoundary(
382
296
  pendingMsgs,
383
- effectiveRawMessageBudget,
384
- {
385
- keepTailCount: shouldRunActiveSummary || triggeredByRealUsage || triggeredByColdResume,
386
- totalUsed,
387
- historyBudget: effectiveHistoryBudget
388
- }
297
+ calculateCompressCount(pendingMsgs, tailBudget),
298
+ preserveLatestUserByProjection
389
299
  );
390
- compressCount = guardToolChainBoundary(pendingMsgs, compressCount);
391
- const allowSmallPrefix = reason !== "task_completed" && (shouldRunActiveSummary || triggeredByRealUsage || diagnostics.triggeredByEstimate);
392
- if (allowSmallPrefix && (compressCount < MIN_COMPRESS_COUNT || pendingMsgs.length < MIN_TRIGGER_PENDING_COUNT)) {
393
- let safeLimit = pendingMsgs.length - 1;
300
+ if (preserveLatestUserByProjection) {
301
+ let latestUser = -1;
394
302
  for (let i = pendingMsgs.length - 1; i >= 0; i--) {
395
303
  if (pendingMsgs[i].role === "user") {
396
- safeLimit = i;
304
+ latestUser = i;
397
305
  break;
398
306
  }
399
307
  }
400
- compressCount = Math.min(compressCount, safeLimit);
401
- while (compressCount > 0 && (pendingMsgs[compressCount]?.role === "tool" || hasOpenEndedToolCall(pendingMsgs[compressCount - 1]))) {
402
- compressCount--;
403
- }
404
- if (compressCount === 0) {
405
- return emptyPlan(startIndex, {
406
- ...diagnostics,
407
- compressCount,
408
- emptyReason: "no-safe-prefix"
409
- });
308
+ const preservedTokens = latestUser >= 0 && latestUser < compressCount ? getMessageTokenCount(pendingMsgs[latestUser]) : latestUser < 0 ? coveredUserTokens : 0;
309
+ if (preservedTokens > 0) {
310
+ compressCount = guardToolChainBoundary(
311
+ pendingMsgs,
312
+ calculateCompressCount(pendingMsgs, Math.max(0, tailBudget - preservedTokens)),
313
+ true
314
+ );
410
315
  }
411
316
  }
317
+ if (compressCount === 0) {
318
+ return emptyPlan(startIndex, { ...diagnostics, compressCount, emptyReason: "no-safe-prefix" });
319
+ }
320
+ const allowSmallPrefix = reason !== "task_completed" && (shouldRunActiveSummary || triggeredByRealUsage || diagnostics.triggeredByEstimate);
412
321
  const compressibleTokens = pendingMsgs.slice(0, compressCount).reduce((sum, msg) => sum + getMessageTokenCount(msg), 0);
413
322
  if (compressCount < MIN_COMPRESS_COUNT && !(allowSmallPrefix && compressibleTokens >= 1e3)) {
414
323
  return emptyPlan(startIndex, {
@@ -516,21 +425,139 @@ function extractFileOperationsFromCalls(calls, resolveCanonicalName) {
516
425
  }
517
426
  return result;
518
427
  }
519
- function formatFileOperationsFromMessages(msgs, resolveCanonicalName) {
520
- const allOps = [];
428
+ function makeBoundedExcerpt(content) {
429
+ const evidence = selectEvidenceLines(content.split("\n"));
430
+ return (maxChars) => {
431
+ if (content.length <= maxChars) return content;
432
+ const marker = `
433
+ [... ${content.length} chars projected ...]
434
+ `;
435
+ const available = maxChars - marker.length;
436
+ if (available < 3) return marker.trim();
437
+ const evidenceCap = Math.floor(available * 0.2);
438
+ const selected = [];
439
+ let evidenceLength = 0;
440
+ for (const line of evidence) {
441
+ const cost = line.length + 1;
442
+ if (evidenceLength + cost > evidenceCap) continue;
443
+ selected.push(line);
444
+ evidenceLength += cost;
445
+ }
446
+ const remainder = available - evidenceLength;
447
+ const headLength = Math.ceil(remainder / 2);
448
+ const tailLength = Math.floor(remainder / 2);
449
+ return content.slice(0, headLength) + marker + (selected.length ? selected.join("\n") + "\n" : "") + (tailLength ? content.slice(-tailLength) : "");
450
+ };
451
+ }
452
+ function buildBoundedCompactionRequest(args) {
453
+ const { msgsToCompress: msgs, previousSummary, contextWindow } = args;
454
+ if (!Number.isFinite(contextWindow) || contextWindow <= 0) return { status: "blocked", reason: "invalid-window" };
455
+ if (!msgs.length) return { status: "blocked", reason: "empty-input" };
456
+ const window = Math.floor(contextWindow);
457
+ const outputTokenBudget = Math.min(8192, Math.max(1, Math.floor(window / 4)));
458
+ const cap = Math.min(computeSummaryInputTokenCap(contextWindow), window - outputTokenBudget);
459
+ const systemTokens = estimateTokenCount(COMPACTION_SUMMARY_SYSTEM_PROMPT);
460
+ for (let i = 0; i < msgs.length; ) {
461
+ const msg = msgs[i];
462
+ if (msg.role === "tool") return { status: "blocked", reason: "no-safe-group" };
463
+ const calls = msg.role === "assistant" && Array.isArray(msg.tool_calls) ? msg.tool_calls : [];
464
+ if (!calls.length) {
465
+ i++;
466
+ continue;
467
+ }
468
+ const ids = calls.map((call) => call.id);
469
+ const hasIds = ids.every((id) => typeof id === "string" && id.length > 0);
470
+ if (!hasIds && ids.some((id) => id !== void 0) || hasIds && new Set(ids).size !== ids.length) {
471
+ return { status: "blocked", reason: "no-safe-group" };
472
+ }
473
+ const remaining2 = new Set(ids);
474
+ let count = 0;
475
+ i++;
476
+ while (i < msgs.length && msgs[i].role === "tool") {
477
+ const id = msgs[i].tool_call_id;
478
+ if (hasIds ? !id || !remaining2.delete(id) : id !== void 0) {
479
+ return { status: "blocked", reason: "no-safe-group" };
480
+ }
481
+ count++;
482
+ i++;
483
+ }
484
+ if (count !== calls.length || hasIds && remaining2.size) return { status: "blocked", reason: "no-safe-group" };
485
+ }
486
+ const canonicalize = args.canonicalizeToolName ?? ((name) => name);
487
+ const operations = /* @__PURE__ */ new Map();
521
488
  for (const msg of msgs) {
522
489
  if (!Array.isArray(msg.tool_calls)) continue;
523
- allOps.push(
524
- ...extractFileOperationsFromCalls(msg.tool_calls, resolveCanonicalName)
525
- );
490
+ for (const op of extractFileOperationsFromCalls(msg.tool_calls, canonicalize)) {
491
+ operations.set(JSON.stringify([op.type, op.path]), op);
492
+ }
526
493
  }
527
- if (allOps.length === 0) return "\u65E0";
528
- const typeLabelMap = {
529
- read: "\u8BFB\u53D6",
530
- write: "\u5199\u5165",
531
- edit: "\u7F16\u8F91"
494
+ const labelsByOperation = { read: "\u8BFB\u53D6", write: "\u5199\u5165", edit: "\u7F16\u8F91" };
495
+ const fileOpsText = [...operations.values()].map((op) => `- ${labelsByOperation[op.type]}: ${op.path}`).join("\n") || "\u65E0";
496
+ const note = "\u4EE5\u4E0B\u662F\u6709\u635F\u6295\u5F71\uFF0C\u90E8\u5206\u6D88\u606F\u53EF\u80FD\u88AB\u622A\u53D6\uFF1B\u539F\u6587\u4ECD\u5B58\u5386\u53F2\u3002";
497
+ const omitted = "[... \u5185\u5BB9\u5DF2\u622A\u53D6 ...]";
498
+ const contents = msgs.map((msg) => serializeMessageContent(msg.content) || formatMessageContentFallback(msg));
499
+ const excerpts = contents.map((content, i) => msgs[i].role === "user" ? void 0 : makeBoundedExcerpt(content));
500
+ const raw = contents.map((content, i) => msgs[i].role === "tool" ? excerpts[i](TOOL_RESULT_TRUNCATE_CHARS) : content);
501
+ const labels = msgs.map((msg) => `${msg.role} [id=${JSON.stringify(msg.id)}]: `);
502
+ const projected = msgs.map((msg, i) => msg.role === "user" ? raw[i] : omitted);
503
+ const makePrompt = () => buildCompactionUserContent({
504
+ previousSummary,
505
+ fileOpsText,
506
+ messagesText: `${note}
507
+ ${labels.map((label, i) => label + projected[i]).join("\n")}`
508
+ });
509
+ const base = makePrompt();
510
+ const baseTokens = systemTokens + estimateTokenCount(base);
511
+ if (baseTokens > cap) return { status: "blocked", reason: "no-budget" };
512
+ const remaining = cap - baseTokens;
513
+ const demands = raw.map((text, i) => msgs[i].role === "user" ? 0 : estimateTokenCount(text));
514
+ const weights = msgs.map((msg) => msg.role === "assistant" ? 2 : 1);
515
+ let low = 0;
516
+ let high = remaining + 1;
517
+ while (low + 1 < high) {
518
+ const mid = Math.floor((low + high) / 2);
519
+ const used = demands.reduce((sum, demand, i) => sum + Math.min(demand, mid * weights[i]), 0);
520
+ if (used <= remaining) low = mid;
521
+ else high = mid;
522
+ }
523
+ let extra = remaining - demands.reduce((sum, demand, i) => sum + Math.min(demand, low * weights[i]), 0);
524
+ for (let i = 0; i < msgs.length; i++) {
525
+ if (msgs[i].role === "user") continue;
526
+ let allowance = Math.min(demands[i], low * weights[i]);
527
+ const bonus = Math.min(extra, demands[i] - allowance);
528
+ allowance += bonus;
529
+ extra -= bonus;
530
+ if (demands[i] <= allowance) {
531
+ projected[i] = raw[i];
532
+ continue;
533
+ }
534
+ let lo = 0;
535
+ let hi = Math.min(contents[i].length, msgs[i].role === "tool" ? TOOL_RESULT_TRUNCATE_CHARS : contents[i].length);
536
+ let best = omitted;
537
+ while (lo <= hi) {
538
+ const mid = Math.floor((lo + hi) / 2);
539
+ const candidate = excerpts[i](mid);
540
+ if (estimateTokenCount(candidate) <= allowance) {
541
+ best = candidate;
542
+ lo = mid + 1;
543
+ } else {
544
+ hi = mid - 1;
545
+ }
546
+ }
547
+ projected[i] = best;
548
+ }
549
+ const promptContent = makePrompt();
550
+ const inputTokens = systemTokens + estimateTokenCount(promptContent);
551
+ if (inputTokens > cap) return { status: "blocked", reason: "no-budget" };
552
+ return {
553
+ status: "ready",
554
+ promptContent,
555
+ coveredMessages: msgs.slice(),
556
+ summarizedBeforeId: msgs[msgs.length - 1].id,
557
+ inputTokens,
558
+ outputTokenBudget,
559
+ partial: false
532
560
  };
533
- return allOps.map((op) => `- ${typeLabelMap[op.type]}: ${op.path}`).join("\n");
534
561
  }
535
562
  var TOOL_RESULT_TRUNCATE_CHARS = 4e3;
536
563
  var SUMMARY_INPUT_MAX_TOKENS = 3e4;
@@ -538,38 +565,6 @@ function computeSummaryInputTokenCap(contextWindow) {
538
565
  const halfWindow = typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > 0 ? Math.floor(contextWindow * 0.5) : SUMMARY_INPUT_MAX_TOKENS;
539
566
  return Math.max(1, Math.min(SUMMARY_INPUT_MAX_TOKENS, halfWindow));
540
567
  }
541
- function capTextToTokenBudget(text, maxTokens) {
542
- const marker = `
543
-
544
- [... summary input capped to ${maxTokens} tokens ...]`;
545
- const markerTokens = estimateTokenCount(marker);
546
- const budget = Math.max(0, maxTokens - markerTokens);
547
- if (estimateTokenCount(text) <= budget) return text;
548
- let lo = 0;
549
- let hi = text.length;
550
- while (lo < hi) {
551
- const mid = lo + hi + 1 >> 1;
552
- if (estimateTokenCount(text.slice(0, mid)) <= budget) lo = mid;
553
- else hi = mid - 1;
554
- }
555
- return `${text.slice(0, lo)}${marker}`;
556
- }
557
- function capSummaryInputToTokenBudget(items, maxTotalTokens) {
558
- if (items.length === 0) return "";
559
- const sepTokens = estimateTokenCount("\n");
560
- const kept = [];
561
- let used = 0;
562
- for (let i = items.length - 1; i >= 0; i -= 1) {
563
- const t = estimateTokenCount(items[i]);
564
- const sep = kept.length > 0 ? sepTokens : 0;
565
- if (kept.length > 0 && used + sep + t > maxTotalTokens) break;
566
- used += sep + t;
567
- kept.push(items[i]);
568
- }
569
- kept.reverse();
570
- const result = kept.join("\n");
571
- return estimateTokenCount(result) > maxTotalTokens ? capTextToTokenBudget(result, maxTotalTokens) : result;
572
- }
573
568
  var EVIDENCE_LINE_PATTERNS = [
574
569
  // commit sha:必须带 git 语境(commit/sha/HEAD/merge/push 输出 a..b)且含字母+数字
575
570
  /\b(?:commit|sha|HEAD|merge|revert|cherry-pick)\b[^\n]{0,24}\b(?=[0-9a-f]*[a-f])(?=[0-9a-f]*\d)[0-9a-f]{7,40}\b/i,
@@ -596,116 +591,6 @@ function isEvidenceLine(line) {
596
591
  function selectEvidenceLines(lines) {
597
592
  return lines.filter(isEvidenceLine);
598
593
  }
599
- var HEAD_SHARE = 0.4;
600
- var TAIL_SHARE = 0.4;
601
- function evidenceTruncateBudget(maxChars) {
602
- const markerReserve = 96;
603
- const usable = Math.max(0, maxChars - markerReserve);
604
- const headCap = Math.floor(usable * HEAD_SHARE);
605
- const tailCap = Math.floor(usable * TAIL_SHARE);
606
- return {
607
- markerReserve,
608
- headCap,
609
- tailCap,
610
- evidenceCap: Math.max(0, usable - headCap - tailCap)
611
- };
612
- }
613
- function takeHeadLines(lines, cap) {
614
- let text = "";
615
- let consumed = 0;
616
- for (const line of lines) {
617
- const candidate = consumed === 0 ? line : `${text}
618
- ${line}`;
619
- if (candidate.length > cap) {
620
- if (consumed === 0 && cap > 0) {
621
- return { text: line.slice(0, cap), consumed: 1 };
622
- }
623
- break;
624
- }
625
- text = candidate;
626
- consumed += 1;
627
- }
628
- return { text, consumed };
629
- }
630
- function takeTailLines(lines, cap) {
631
- if (cap <= 0 || lines.length === 0) return { text: "", consumed: 0 };
632
- let text = "";
633
- let consumed = 0;
634
- for (let i = lines.length - 1; i >= 0; i -= 1) {
635
- const candidate = consumed === 0 ? lines[i] : `${lines[i]}
636
- ${text}`;
637
- if (candidate.length > cap) {
638
- if (consumed === 0) return { text: lines[i].slice(-cap), consumed: 1 };
639
- break;
640
- }
641
- text = candidate;
642
- consumed += 1;
643
- }
644
- return { text, consumed };
645
- }
646
- function shrinkToFit(head, evidence, tail, makeMarker, maxChars) {
647
- const joinBody = () => head.concat(evidence, tail).join("\n");
648
- let marker = makeMarker(joinBody().length);
649
- while (joinBody().length + marker.length > maxChars) {
650
- if (evidence.length > 0) evidence.pop();
651
- else if (tail.length > 0) tail.pop();
652
- else if (head.length > 0) head.pop();
653
- else break;
654
- marker = makeMarker(joinBody().length);
655
- }
656
- const result = joinBody() + marker;
657
- return result.length > maxChars ? result.slice(0, maxChars) : result;
658
- }
659
- function truncateContentForSummary(role, content, maxChars = TOOL_RESULT_TRUNCATE_CHARS) {
660
- if (role !== "tool" || content.length <= maxChars) return content;
661
- const lines = content.split("\n");
662
- const budget = evidenceTruncateBudget(maxChars);
663
- const head = takeHeadLines(lines, budget.headCap);
664
- const tail = takeTailLines(
665
- lines.slice(0, lines.length - head.consumed),
666
- budget.tailCap
667
- );
668
- const middle = lines.slice(head.consumed, lines.length - tail.consumed);
669
- const evidence = selectEvidenceLines(middle);
670
- if (evidence.length === 0) {
671
- return `${content.slice(0, maxChars)}
672
-
673
- [... ${content.length - maxChars} chars truncated ...]`;
674
- }
675
- const headLines = head.text ? head.text.split("\n") : [];
676
- const tailLines = tail.text ? tail.text.split("\n") : [];
677
- const evidenceLines = [];
678
- let evidenceUsed = 0;
679
- for (const line of evidence) {
680
- if (evidenceUsed + line.length > budget.evidenceCap) break;
681
- evidenceLines.push(line);
682
- evidenceUsed += line.length;
683
- }
684
- const marker = (bodyChars) => {
685
- const note = evidenceLines.length > 0 ? `
686
- [... \u5DF2\u4FDD\u7559 ${evidenceLines.length} \u6761\u8BC1\u636E\u884C ...]` : "";
687
- return `
688
-
689
- [... ${content.length - bodyChars} chars truncated ...]${note}`;
690
- };
691
- return shrinkToFit(headLines, evidenceLines, tailLines, marker, maxChars);
692
- }
693
- function formatMessagesForSummaryWithTruncation(msgs, maxToolResultChars = TOOL_RESULT_TRUNCATE_CHARS, maxTotalTokens) {
694
- const items = msgs.map((msg) => {
695
- const rawContent = serializeMessageContent(msg.content) || "";
696
- const truncated = truncateContentForSummary(
697
- msg.role,
698
- rawContent,
699
- maxToolResultChars
700
- );
701
- const text = truncated || formatMessageContentFallback(msg);
702
- return `${msg.role}: ${text}`;
703
- });
704
- if (typeof maxTotalTokens === "number" && Number.isFinite(maxTotalTokens) && maxTotalTokens > 0) {
705
- return capSummaryInputToTokenBudget(items, maxTotalTokens);
706
- }
707
- return items.join("\n");
708
- }
709
594
  function buildCompactionMetrics(args) {
710
595
  const {
711
596
  reason,
@@ -892,6 +777,11 @@ function fuzzyContextWindow(normalizedName) {
892
777
  }
893
778
  return void 0;
894
779
  }
780
+ var findCodexOAuthPinnedContextWindow = (modelName, provider) => {
781
+ if (!modelName) return void 0;
782
+ if (isPlatformManagedProvider(provider, modelName)) return void 0;
783
+ return channelPinnedContextWindow(modelName.toLowerCase());
784
+ };
895
785
  var findModelContextWindow = (modelName, provider) => {
896
786
  if (!modelName) return void 0;
897
787
  const onPlatformChannel = isPlatformManagedProvider(provider, modelName);
@@ -954,8 +844,8 @@ var getModelInfo = (modelName) => {
954
844
  };
955
845
 
956
846
  export {
957
- planContextUsage,
958
847
  DEFAULT_CONTEXT_WINDOW,
848
+ findCodexOAuthPinnedContextWindow,
959
849
  findModelContextWindow,
960
850
  getModelContextWindow,
961
851
  getModelInfo,
@@ -963,14 +853,12 @@ export {
963
853
  serializeMessageContent,
964
854
  resolveCompressionTriggerRatio,
965
855
  truncateToolOutputForContext,
856
+ getMessageTokenCount,
857
+ resolveEffectiveCompactionBudgets,
966
858
  planCompression,
967
859
  COMPACTION_SUMMARY_SCHEMA_VERSION,
968
860
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
969
- buildCompactionUserContent,
970
- formatFileOperationsFromMessages,
971
- TOOL_RESULT_TRUNCATE_CHARS,
972
- computeSummaryInputTokenCap,
973
- formatMessagesForSummaryWithTruncation,
861
+ buildBoundedCompactionRequest,
974
862
  buildCompactionMetricsFromPlan,
975
863
  formatCompactionMetricsLog,
976
864
  computeSummarySourceMetadata
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  generatePkcePair,
3
3
  startCallbackServer
4
- } from "./chunk-SN5XE6GQ.js";
4
+ } from "./chunk-RPQXPZZF.js";
5
5
  import {
6
6
  toErrorMessage
7
7
  } from "./chunk-HNMXYYJR.js";