nolo-cli 0.148.0-alpha.1 → 0.151.0-alpha.2
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.
- package/{_executeModel-NFJAMAGJ.js → _executeModel-XHAFJ2MM.js} +134 -91
- package/accountResolver-7RYB4D2P.js +300 -0
- package/action-SXJD5N5R.js +23 -0
- package/{addContentAction-B2DRF7P6.js → addContentAction-ZV774PHH.js} +20 -14
- package/{addDialogAgentAction-2P2FLTLD.js → addDialogAgentAction-A6SMKAGH.js} +26 -22
- package/{agentDeleteCommand-7IDWF6E3.js → agentDeleteCommand-DPUUS56Z.js} +181 -93
- package/{agentEmailCommands-4KW33JII.js → agentEmailCommands-V4P5EFLP.js} +132 -112
- package/{agentGrantCommands-M3XFO6EN.js → agentGrantCommands-HOJ3JBBQ.js} +3 -3
- package/agentListCommands-TWFLUYIZ.js +802 -0
- package/{agentMachineCommands-CMQR4RQ4.js → agentMachineCommands-MELPAZZI.js} +58 -62
- package/{agentProviderCommands-YK2BIIXZ.js → agentProviderCommands-HL6MBLCL.js} +149 -2
- package/{agentPullCommand-HF4A42D4.js → agentPullCommand-FA43RBRU.js} +7 -7
- package/agentRecordCommands-FSWSSQIO.js +154 -0
- package/agentRunCommand-GDBJVOAT.js +183 -0
- package/{agentRunControl-2SKCR4SB.js → agentRunControl-IFM7IGMG.js} +10 -2
- package/{agentRuntimeLocal-AK2QVJHY.js → agentRuntimeLocal-KKSQJMTE.js} +47 -50
- package/{agentSlice-OZ33K224.js → agentSlice-YO2ZLJMD.js} +23 -16
- package/{appDeleteCommands-N3XEVVYC.js → appDeleteCommands-4PL4KYRN.js} +58 -59
- package/{appDeployCommands-AWFIXYVW.js → appDeployCommands-EEEXCEB6.js} +67 -63
- package/{appDeployStatusCommands-CZRON2FO.js → appDeployStatusCommands-35ZX7T66.js} +56 -56
- package/{appGetCommands-XQIUY4TD.js → appGetCommands-WFCHXJWF.js} +56 -56
- package/{appListCommands-NNG4H36Y.js → appListCommands-XY2U6DPF.js} +57 -59
- package/{authCommand-UBJ4EWYZ.js → authCommand-QYN47CQD.js} +371 -68
- package/{authCommands-H6WKKCRW.js → authCommands-77CHYBGF.js} +12 -9
- package/{builtinSkillRegistry-ZMF6YGNO.js → builtinSkillRegistry-TDQ6JB2E.js} +13 -11
- package/{chromeCommands-2N6MEWRU.js → chromeCommands-OBBNJCLS.js} +314 -13
- package/chromeOpsCommands-3Z34RKSE.js +472 -0
- package/{chunk-ALXHV7NK.js → chunk-2GGXHQIW.js} +43 -4
- package/{localRuntimeAuthority-5W6IJRAD.js → chunk-2IXDJNZI.js} +154 -75
- package/{chunk-IVZJWTDI.js → chunk-36OMEXXR.js} +89 -21
- package/{chunk-H6A6X4EK.js → chunk-3MZAGMYY.js} +16 -0
- package/chunk-3PVYUPXK.js +40 -0
- package/chunk-3SZA4U64.js +1192 -0
- package/{chunk-GNMAFAIS.js → chunk-44WXLHFI.js} +1 -1
- package/{chunk-AGGIDPCZ.js → chunk-4JH2UMJR.js} +6 -0
- package/chunk-4LCOCOR5.js +50 -0
- package/chunk-4YRTZIVN.js +871 -0
- package/chunk-556RW72X.js +14110 -0
- package/{chunk-N7J63Q6C.js → chunk-56GBUMO5.js} +10 -1
- package/{chunk-W7XHHYWM.js → chunk-5BHQICF2.js} +5 -1
- package/{chunk-XUWRURDF.js → chunk-5EBLANFT.js} +1 -1
- package/{chunk-3AH7LNUB.js → chunk-5EMSBTQ6.js} +33 -14
- package/{chunk-YRRASA5Q.js → chunk-5MM7NNO6.js} +113 -52
- package/chunk-5MMAK75Q.js +15 -0
- package/{chunk-M5PVFLD4.js → chunk-64K7WX26.js} +90 -21
- package/{chunk-AKG5W4LG.js → chunk-6CCFTVBP.js} +76 -221
- package/chunk-6MJNEXUU.js +614 -0
- package/{chunk-62IL3KQV.js → chunk-6MXDOUMH.js} +15 -3
- package/{chunk-QOKAKDPE.js → chunk-6Q7UTJKR.js} +6 -94
- package/chunk-6QDYSCPW.js +223 -0
- package/{chunk-HYZIYH2H.js → chunk-74RAWNQN.js} +56 -63
- package/chunk-7DPNBQSV.js +9 -0
- package/chunk-7MOXKPHC.js +119 -0
- package/{chunk-523WHFSL.js → chunk-7XKL25PW.js} +1973 -754
- package/{chunk-IAESIMK7.js → chunk-A4MW3YZL.js} +10 -14
- package/chunk-AGIM7IMJ.js +147 -0
- package/{chunk-7CHC4W22.js → chunk-AIZE5TDM.js} +3 -3
- package/{chunk-P4BX6FFU.js → chunk-AOCM7HPT.js} +214 -51
- package/{chunk-5GVBDNTO.js → chunk-AU7AXHUL.js} +1 -1
- package/{chunk-4H22P2JV.js → chunk-AUIJZACN.js} +2073 -1275
- package/{chunk-CIF4X6ZM.js → chunk-AWVFQMOV.js} +25 -3
- package/{chunk-RYZINGPM.js → chunk-BPMPOFWP.js} +347 -235
- package/{chunk-YUNJN43V.js → chunk-BU2YQBV4.js} +215 -28
- package/{chunk-XPRWFQQK.js → chunk-CBHGZRCE.js} +38 -12
- package/{chunk-Y3PMXGLH.js → chunk-CHCS6XPJ.js} +365 -144
- package/chunk-CHOZJMJS.js +78 -0
- package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
- package/{chunk-3SV7RM24.js → chunk-D2QN6CTI.js} +117 -72
- package/{chunk-5TEEECZM.js → chunk-E2AKSW7L.js} +10 -7
- package/{chunk-RSEEDUMS.js → chunk-EDX5XSJM.js} +2 -2
- package/{chunk-BKWMNZ2X.js → chunk-ES633ZS5.js} +280 -98
- package/{chunk-QDSINZM3.js → chunk-EUGTFFO6.js} +2 -23
- package/{chunk-UNYJU5L6.js → chunk-EYLGAEB4.js} +5 -1
- package/{chunk-CU3QB4HW.js → chunk-EYWJT7A2.js} +12 -12
- package/{chunk-BNGW5ASC.js → chunk-EZVK3N5L.js} +66 -18
- package/{chunk-6FGTMQCL.js → chunk-F32Z66T4.js} +6 -10
- package/chunk-FJMRBOPO.js +11507 -0
- package/{chunk-ZOVKKMF6.js → chunk-FY4SDK2E.js} +1 -1
- package/chunk-G6OOUQWJ.js +417 -0
- package/{chunk-PQWU42UQ.js → chunk-GCKHQECX.js} +6 -6
- package/chunk-GKXCHNTE.js +15 -0
- package/{chunk-T7F46O36.js → chunk-GQN2WLAI.js} +20 -11
- package/{chunk-P6GMCCAT.js → chunk-GQV5KHJU.js} +78 -12
- package/{chunk-B2XUQXQX.js → chunk-HIQ4GF53.js} +191 -68
- package/{chunk-YUWMM4US.js → chunk-HKX3ULQB.js} +34 -22
- package/{chunk-GMZLP5DV.js → chunk-HNUWUO75.js} +30 -19
- package/{chunk-5UTFL4QJ.js → chunk-I2ZMGXXF.js} +10 -5
- package/chunk-I42VC5KR.js +15 -0
- package/{chunk-3BXNTXYI.js → chunk-I4SN4NUQ.js} +1199 -56
- package/chunk-IA7TRNNR.js +11 -0
- package/{chunk-WIWM4FE3.js → chunk-IJERIUXS.js} +55 -748
- package/{chunk-CPUFH46E.js → chunk-ILU2NPWY.js} +10 -10
- package/{chunk-SLLGJZDT.js → chunk-ISQL4V7C.js} +4 -4
- package/chunk-IT3ZZRJE.js +12 -0
- package/{chunk-LPVCRQMM.js → chunk-IZ7OJB6K.js} +20 -16
- package/{chunk-DY7ANLKG.js → chunk-JKMLSTZK.js} +43 -12
- package/{chunk-6TPOEJMQ.js → chunk-JZX2XLKC.js} +64 -23
- package/{chunk-27ONFIEY.js → chunk-K2AER7RX.js} +19 -12
- package/{chunk-O2OWEFII.js → chunk-KFHQQ3NO.js} +1 -1
- package/{chunk-QXGPFY6J.js → chunk-LGN377P3.js} +27 -17
- package/{chunk-L36OWPP3.js → chunk-LIQJTQRN.js} +118 -139
- package/{chunk-FWQEKRTD.js → chunk-LTRUTOHX.js} +36 -31
- package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
- package/{chunk-5J3PYNUP.js → chunk-NYYFIKHI.js} +17 -3
- package/{chunk-6O4IK4V2.js → chunk-OFFL4DCR.js} +1 -1
- package/{chunk-B6SAMB33.js → chunk-OWYYDMGJ.js} +209 -9
- package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
- package/{chunk-CTUQJVQM.js → chunk-P5QACQDK.js} +1 -1
- package/{chunk-DIXLJWCD.js → chunk-PCKVQXYV.js} +274 -93
- package/{chunk-4JMDLJAD.js → chunk-PJNFNEJE.js} +114 -37
- package/{chunk-Z4CSIXYP.js → chunk-PLSVXHSA.js} +3 -3
- package/{chunk-BIDGLJQ3.js → chunk-PLXDDGBK.js} +45 -8
- package/chunk-PWTNI4N7.js +47 -0
- package/chunk-QFEW2ULV.js +42 -0
- package/{chunk-RGNEEJ3Y.js → chunk-QLQ573SU.js} +35 -9
- package/chunk-QQ56R7KS.js +88 -0
- package/chunk-QYPE3TS3.js +43 -0
- package/{chunk-4DPP773Q.js → chunk-RSHPU4PD.js} +59 -11
- package/chunk-RVWMAFIT.js +134 -0
- package/{chunk-ESHYE7WU.js → chunk-S73EPYNC.js} +10 -7
- package/{chunk-UQNS32WZ.js → chunk-SCMHQUMK.js} +1 -1
- package/{chunk-T767MPHB.js → chunk-SMENBO3M.js} +354 -120
- package/{chunk-PCVVZ2MH.js → chunk-SSFDFOVT.js} +26 -31
- package/chunk-SW4S4XYB.js +1794 -0
- package/{chunk-HUFPWXFW.js → chunk-T6X3D7NB.js} +572 -430
- package/chunk-TY3TIUJK.js +89 -0
- package/{chunk-X2QRZXZH.js → chunk-TYJ5XFEA.js} +4 -4
- package/{chunk-ALFH24P3.js → chunk-TYYRSFBG.js} +197 -155
- package/{chunk-7KVZ5LDQ.js → chunk-UBUH2TCC.js} +18 -4
- package/chunk-UEILX4EV.js +15 -0
- package/chunk-UHTDNB5Y.js +140 -0
- package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
- package/{chunk-OHOVNO7I.js → chunk-UOKFKFPO.js} +6 -3
- package/{chunk-XISEYOGH.js → chunk-USHQX6VT.js} +5 -5
- package/chunk-UUPR3TD7.js +53 -0
- package/{chunk-HDLLCBRF.js → chunk-VEA7H5FG.js} +2 -2
- package/chunk-VHGD6FHV.js +116 -0
- package/chunk-VIWDGTDA.js +8 -0
- package/{chunk-GOH6RW6F.js → chunk-VJXHL6MH.js} +34 -11
- package/{chunk-4XEYAFLY.js → chunk-VL5KOY2C.js} +623 -94
- package/{chunk-EADNWBAZ.js → chunk-VP3BINY7.js} +13 -0
- package/{chunk-EOARMOVD.js → chunk-W4S6OTSC.js} +6 -3
- package/chunk-WD4XYDYC.js +567 -0
- package/chunk-WJZOQR2J.js +151 -0
- package/{chunk-AUDNYVRC.js → chunk-XETG4RIX.js} +5 -5
- package/{chunk-MX574M24.js → chunk-XI7DGLUK.js} +4 -4
- package/{chunk-3L2WKC3W.js → chunk-XPWGOTBQ.js} +8 -1
- package/chunk-XRUSXPCQ.js +514 -0
- package/{chunk-I4OPU5TK.js → chunk-XS47QOFV.js} +273 -11
- package/{chunk-S5XGT6GB.js → chunk-XZNCX52W.js} +30 -9
- package/{chunk-2JMMBU6V.js → chunk-Y2DXOPSO.js} +1920 -644
- package/{chunk-5OA5HMTL.js → chunk-YLMMECCH.js} +1 -1
- package/{chunk-CFT5HBGW.js → chunk-YVLQXTUB.js} +448 -12
- package/chunk-YVPQATSC.js +709 -0
- package/{chunk-DCFPQW22.js → chunk-Z7OJUX6S.js} +122 -107
- package/chunk-ZEZC7IIM.js +126 -0
- package/{chunk-ALGORS6Y.js → chunk-ZF6526IQ.js} +43 -8
- package/chunk-ZIWPQEFU.js +165 -0
- package/chunk-ZKZ5X2HS.js +7012 -0
- package/chunk-ZRAU6T47.js +56 -0
- package/{cliExecutor-AWYR3T33.js → cliExecutor-BWBF2MTI.js} +4 -3
- package/{clipboardy-BX4NMYHE.js → clipboardy-GCO3GT3I.js} +3 -8
- package/{commandRegistry-YOEQUA7T.js → commandRegistry-XN7C5GHO.js} +183 -107
- package/contentThunks-5L7YQI3S.js +84 -0
- package/{cooldownCommands-ZLEPIB4A.js → cooldownCommands-JFKTYS2D.js} +2 -2
- package/{createAgentAutomationAction-5EJL6ROU.js → createAgentAutomationAction-QOPOLCRK.js} +53 -44
- package/createDialogAction-MZ66VY5Q.js +76 -0
- package/{createPageAction-75ELC64R.js → createPageAction-VQDJIXMY.js} +65 -54
- package/cursorProvider-YGGNMVWX.js +6123 -0
- package/{db-VQSAOWAO.js → db-2QOTXYGH.js} +11 -5
- package/{dbSlice-DQ32LYTJ.js → dbSlice-J37OGIXH.js} +19 -13
- package/{deleteFile-NX6QHCWZ.js → deleteFile-6JWDDRVP.js} +10 -6
- package/dialogCommands-YZLSJB6X.js +113 -0
- package/{dialogSlice-KSXPGJB2.js → dialogSlice-6RODVYCK.js} +53 -39
- package/{docCreateCommands-ZSLGVBZT.js → docCreateCommands-JB2RRMRJ.js} +54 -57
- package/{docDeleteCommands-5N4GVZBG.js → docDeleteCommands-AQENULNM.js} +56 -58
- package/{docReadCommands-YJSAA7AV.js → docReadCommands-DYD25YLQ.js} +53 -56
- package/{docStore-AROBVRCR.js → docStore-ZZA3OPM5.js} +25 -16
- package/{docUpdateCommands-WEMLSW6W.js → docUpdateCommands-3GVS23QL.js} +54 -57
- package/{fetchMessages-67MEFPZR.js → fetchMessages-IIJWQ3HR.js} +5 -4
- package/{getPricing-NMMFT3YI.js → getPricing-FKK3F5EJ.js} +11 -9
- package/{handleSendMessageAction-EGNWHAUB.js → handleSendMessageAction-DVG5U26T.js} +619 -165
- package/index.js +11 -7
- package/{lib-FRRS27KN.js → lib-4YTWAGY7.js} +581 -248
- package/{localDialogRead-EBRS242U.js → localDialogRead-FSOMOPDZ.js} +2 -2
- package/localRuntimeAdapter-HXRHFKRC.js +244 -0
- package/localRuntimeAuthority-JDAD7CB6.js +16 -0
- package/{localRuntimeDb-3LRMNLCM.js → localRuntimeDb-CVC62PM5.js} +1 -1
- package/{machineCommands-ARZYKGGE.js → machineCommands-5KBF4RCC.js} +503 -161
- package/{machineInfo-66ZFUMLE.js → machineInfo-UKPTZO5Y.js} +2 -2
- package/machineWsRunDispatch-4OQDEDOR.js +169 -0
- package/{memberThunks-5ZXPR63F.js → memberThunks-66DH6ABQ.js} +25 -18
- package/{models-ZPU5EDF4.js → models-LAS4B2B5.js} +2 -2
- package/package.json +1 -1
- package/{providerPresetApply-DD6NGWW6.js → providerPresetApply-MY66I6NT.js} +10 -10
- package/{providerRegistry-XDRLMYGJ.js → providerRegistry-QOE2FT57.js} +13 -9
- package/{read-EPTJRAEF.js → read-DC4NUGN6.js} +12 -8
- package/{readDocTool-W4NDXNEX.js → readDocTool-NCJ5NT25.js} +1 -1
- package/{readlineWorkspace-3XOFVARF.js → readlineWorkspace-RIE62QVZ.js} +5022 -921
- package/{removeDialogAgentAction-OSYNZRX7.js → removeDialogAgentAction-E2H3OZU6.js} +29 -28
- package/{runAgentClientLoop-UMF7VZYZ.js → runAgentClientLoop-KLUUXBZS.js} +154 -97
- package/{runtimeDoctorCommands-ID23PNNZ.js → runtimeDoctorCommands-GIOGC5SC.js} +17 -17
- package/secretCommands-ZXZRLR3R.js +700 -0
- package/setDialogExtraReferencesAction-SITRPMYU.js +37 -0
- package/{setPrimaryDialogAgentAction-WZ7KI3YA.js → setPrimaryDialogAgentAction-U7N45TGC.js} +30 -29
- package/{chunk-SONWNI3L.js → settingThunks-Y7SVJOMZ.js} +223 -928
- package/{skillDiscovery-ZBU76COE.js → skillDiscovery-QC35EQY4.js} +2 -2
- package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
- package/{spaceCommands-UJOVU4XI.js → spaceCommands-ZR5BR3GX.js} +59 -59
- package/{streamAgentChatTurn-GYGMYOSM.js → streamAgentChatTurn-MN2SSPGA.js} +309 -165
- package/{switchDialogAgentAction-GMR7WN3P.js → switchDialogAgentAction-OMGBD3N2.js} +26 -22
- package/{tableCommands-G7RV3RU3.js → tableCommands-U3QDY4L6.js} +19 -17
- package/{toolApiClient-CVGWM4PN.js → toolApiClient-7WSJJJBV.js} +6 -5
- package/tools-W2MOLERY.js +124 -0
- package/tuiSummaryLlmCaller-BM3VSTBU.js +130 -0
- package/{updateCommands-4EHDLF5J.js → updateCommands-NQXAGFM7.js} +3 -3
- package/{updateDialogTitleAction-4U5W4AMH.js → updateDialogTitleAction-Z4JX6REN.js} +102 -57
- package/workloadLifecycle-36DXRZKU.js +320 -0
- package/action-GI44T4DR.js +0 -31
- package/agentListCommands-IW3GQVUP.js +0 -427
- package/agentRecordCommands-4YBSYPIY.js +0 -134
- package/agentRunCommand-5MU5X5OT.js +0 -161
- package/browser-image-compression-MFDTD7K6.js +0 -1763
- package/chatQueueReduxAdapter-HVHA2HPM.js +0 -186
- package/chromeOpsCommands-IXRLN57H.js +0 -289
- package/chunk-42Z3EMC4.js +0 -25363
- package/chunk-CQ3WA2NE.js +0 -299
- package/chunk-CYSYR67N.js +0 -93
- package/chunk-IAG4FHOJ.js +0 -34
- package/chunk-JBTJAPUF.js +0 -35
- package/chunk-K2CSUCHJ.js +0 -620
- package/chunk-LTRXGFMS.js +0 -83
- package/chunk-M76ECQRD.js +0 -13658
- package/chunk-MEYIRKDN.js +0 -8967
- package/chunk-OCZKATRC.js +0 -129
- package/chunk-OTGFTBLI.js +0 -13
- package/chunk-PUOC4YRO.js +0 -394
- package/chunk-QU5A4LYX.js +0 -2415
- package/chunk-URMS4XY2.js +0 -10
- package/chunk-UV6VISQJ.js +0 -20
- package/chunk-VJVNU77E.js +0 -83
- package/chunk-WRMKCKZ3.js +0 -13807
- package/chunk-Y5GCAMGP.js +0 -9
- package/chunk-YPREESF4.js +0 -225
- package/contentThunks-AK2F3KNC.js +0 -73
- package/createDialogAction-F5WEWA47.js +0 -66
- package/dialogCommands-G7YBVAMC.js +0 -102
- package/levelLazyShim-GZBKODGI.js +0 -7
- package/machineWsRunDispatch-I7F4L532.js +0 -149
- package/serverStoreFactory-YMXDF4NI.js +0 -20
- package/setDialogExtraReferencesAction-M32UYNCG.js +0 -30
- package/settingSlice-Q6EKL7EQ.js +0 -204
- package/syncMapping-N6RGXGBW.js +0 -437
- package/tools-DU4JXVAV.js +0 -111
- package/tuiSummaryLlmCaller-3YFNHCTW.js +0 -128
- package/{chunk-SV5IJK6K.js → chunk-NBTY7YJF.js} +3 -3
- package/{chunk-2SYTUTLI.js → chunk-YBNHPX4S.js} +3 -3
- package/{offlineMarxistsAgentCommand-HGXZV4XJ.js → offlineMarxistsAgentCommand-2QTHJCHV.js} +4 -4
|
@@ -2,23 +2,14 @@ import {
|
|
|
2
2
|
estimateTokenCount
|
|
3
3
|
} from "./chunk-PSCNXBYA.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
MODEL_LOOKUP_MAP
|
|
6
|
+
} from "./chunk-I4SN4NUQ.js";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
ALL_MODELS
|
|
9
|
+
} from "./chunk-RVWMAFIT.js";
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import {
|
|
14
|
-
getRuntimeServerContext
|
|
15
|
-
} from "./chunk-WIWM4FE3.js";
|
|
16
|
-
import {
|
|
17
|
-
API_ENDPOINTS
|
|
18
|
-
} from "./chunk-LCBAMY2M.js";
|
|
19
|
-
import {
|
|
20
|
-
normalizeServerOrigin
|
|
21
|
-
} from "./chunk-CF7PE763.js";
|
|
11
|
+
isPlatformManagedProvider
|
|
12
|
+
} from "./chunk-CHCS6XPJ.js";
|
|
22
13
|
|
|
23
14
|
// packages/core/chat/messageContentSerialize.ts
|
|
24
15
|
var serializeMessageContent = (content, imagePlaceholder = "[\u56FE\u7247]") => {
|
|
@@ -42,209 +33,6 @@ var serializeMessageContent = (content, imagePlaceholder = "[\u56FE\u7247]") =>
|
|
|
42
33
|
return null;
|
|
43
34
|
};
|
|
44
35
|
|
|
45
|
-
// packages/app/utils/imageUtils.ts
|
|
46
|
-
var BYTES_PER_MB = 1024 * 1024;
|
|
47
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
48
|
-
var parseDataUrl = (dataUrl) => {
|
|
49
|
-
const trimmed = dataUrl.trim();
|
|
50
|
-
const parts = trimmed.split(",");
|
|
51
|
-
if (parts.length < 2 || !parts[0] || !parts[1]) {
|
|
52
|
-
console.warn("[imageUtils] parseDataUrl: invalid data URL", {
|
|
53
|
-
hasHeader: !!parts[0],
|
|
54
|
-
hasBody: !!parts[1]
|
|
55
|
-
});
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
const header = parts[0];
|
|
59
|
-
const base64 = parts[1];
|
|
60
|
-
const mimeMatch = header.match(/:(.*?);/);
|
|
61
|
-
const mime = mimeMatch?.[1];
|
|
62
|
-
if (!mime) {
|
|
63
|
-
console.warn("[imageUtils] parseDataUrl: cannot extract mime from", header);
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
return { mime, base64 };
|
|
67
|
-
};
|
|
68
|
-
function dataURLtoFile(dataUrl, filename) {
|
|
69
|
-
try {
|
|
70
|
-
const parsed = parseDataUrl(dataUrl);
|
|
71
|
-
if (!parsed) return null;
|
|
72
|
-
const { mime, base64 } = parsed;
|
|
73
|
-
const binaryString = atob(base64);
|
|
74
|
-
const length = binaryString.length;
|
|
75
|
-
const u8arr = new Uint8Array(length);
|
|
76
|
-
for (let i = 0; i < length; i++) {
|
|
77
|
-
u8arr[i] = binaryString.charCodeAt(i);
|
|
78
|
-
}
|
|
79
|
-
return new File([u8arr], filename, { type: mime });
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.error("[imageUtils] Error converting data URL to File:", error);
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
var appendNoCacheQuery = (url) => {
|
|
86
|
-
const stamp = `_t=${Date.now()}`;
|
|
87
|
-
return url.includes("?") ? `${url}&${stamp}` : `${url}?${stamp}`;
|
|
88
|
-
};
|
|
89
|
-
var tryLoadImage = (url) => new Promise((resolve) => {
|
|
90
|
-
const img = new Image();
|
|
91
|
-
const cleanup = () => {
|
|
92
|
-
img.onload = null;
|
|
93
|
-
img.onerror = null;
|
|
94
|
-
};
|
|
95
|
-
img.onload = () => {
|
|
96
|
-
cleanup();
|
|
97
|
-
resolve(true);
|
|
98
|
-
};
|
|
99
|
-
img.onerror = () => {
|
|
100
|
-
cleanup();
|
|
101
|
-
resolve(false);
|
|
102
|
-
};
|
|
103
|
-
img.src = url;
|
|
104
|
-
});
|
|
105
|
-
var waitForFileReady = async (url, {
|
|
106
|
-
maxWaitMs = 4e3,
|
|
107
|
-
intervalMs = 250
|
|
108
|
-
} = {}) => {
|
|
109
|
-
const start = Date.now();
|
|
110
|
-
while (Date.now() - start < maxWaitMs) {
|
|
111
|
-
const tryUrl = appendNoCacheQuery(url);
|
|
112
|
-
const ok = await tryLoadImage(tryUrl);
|
|
113
|
-
if (ok) {
|
|
114
|
-
console.debug("[imageUtils] waitForFileReady: image loaded for", url);
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
await sleep(intervalMs);
|
|
118
|
-
}
|
|
119
|
-
console.warn("[imageUtils] waitForFileReady: timeout for", url);
|
|
120
|
-
return false;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
// packages/database/fileUrl.ts
|
|
124
|
-
var normalizeFileId = (fileId) => {
|
|
125
|
-
if (typeof fileId !== "string") return "";
|
|
126
|
-
return fileId.trim();
|
|
127
|
-
};
|
|
128
|
-
var buildDatabaseFileContentUrl = (serverOrigin, fileId) => {
|
|
129
|
-
const normalizedServer = normalizeServerOrigin(serverOrigin);
|
|
130
|
-
const normalizedFileId = normalizeFileId(fileId);
|
|
131
|
-
if (!normalizedServer || !normalizedFileId) {
|
|
132
|
-
return null;
|
|
133
|
-
}
|
|
134
|
-
return `${normalizedServer}${API_ENDPOINTS.DATABASE}/file/content/${normalizedFileId}`;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
// packages/chat/messages/fileUrl.ts
|
|
138
|
-
var buildMessageFileContentUrl = (serverOrigin, fileId) => buildDatabaseFileContentUrl(serverOrigin, fileId);
|
|
139
|
-
|
|
140
|
-
// packages/chat/messages/imagePayloadPersistence.ts
|
|
141
|
-
var stripDurableImageInlinePayload = (part) => {
|
|
142
|
-
if (!part || typeof part !== "object") return part;
|
|
143
|
-
const { original_data_url: _originalDataUrl, ...withoutOriginalDataUrl } = part;
|
|
144
|
-
if (withoutOriginalDataUrl.type !== "image_url" || !withoutOriginalDataUrl.google_native || typeof withoutOriginalDataUrl.google_native !== "object") {
|
|
145
|
-
return withoutOriginalDataUrl;
|
|
146
|
-
}
|
|
147
|
-
const { google_native: _googleNative, ...durablePart } = withoutOriginalDataUrl;
|
|
148
|
-
return durablePart;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// packages/chat/messages/messageContent.ts
|
|
152
|
-
var isDataUrlImage = (url) => typeof url === "string" && url.startsWith("data:image");
|
|
153
|
-
var uploadGeneratedImageDataUrl = async (url, dialogId, messageId, index, dispatch, getState, options) => {
|
|
154
|
-
const fileName = `generated-image-${dialogId}-${messageId}-${index}.png`;
|
|
155
|
-
const file = dataURLtoFile(url, fileName);
|
|
156
|
-
if (!file) {
|
|
157
|
-
console.warn(
|
|
158
|
-
"[messageContent] dataURLtoFile failed, drop generated image inline payload"
|
|
159
|
-
);
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
const customKey = `generated-image-${dialogId}-${messageId}-${index}`;
|
|
163
|
-
let metadata;
|
|
164
|
-
try {
|
|
165
|
-
metadata = await dispatch(upload({ file, customKey })).unwrap();
|
|
166
|
-
} catch (err) {
|
|
167
|
-
console.warn(
|
|
168
|
-
"[messageContent] upload generated image failed, drop inline payload:",
|
|
169
|
-
err
|
|
170
|
-
);
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
const state = getState();
|
|
174
|
-
const { currentServer } = getRuntimeServerContext(state);
|
|
175
|
-
const fileId = metadata?.dbKey || metadata?.id;
|
|
176
|
-
if (!currentServer || !fileId) {
|
|
177
|
-
console.warn(
|
|
178
|
-
"[messageContent] missing currentServer or fileId, drop inline payload",
|
|
179
|
-
{ currentServer, fileId }
|
|
180
|
-
);
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
if (options?.spaceId) {
|
|
184
|
-
try {
|
|
185
|
-
const agentPrefix = options.agentName ? `[${options.agentName}] ` : "";
|
|
186
|
-
const title = `${agentPrefix}Generated Image ${index + 1}`;
|
|
187
|
-
await addContentAction({
|
|
188
|
-
spaceId: options.spaceId,
|
|
189
|
-
contentKey: fileId,
|
|
190
|
-
title,
|
|
191
|
-
type: "image" /* IMAGE */
|
|
192
|
-
}, { dispatch, getState });
|
|
193
|
-
console.log(`[messageContent] Saved generated image to space: ${options.spaceId}`);
|
|
194
|
-
} catch (err) {
|
|
195
|
-
console.error("[messageContent] Failed to save generated image to space:", err);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
const imageUrl = buildMessageFileContentUrl(currentServer, fileId);
|
|
199
|
-
if (!imageUrl) {
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
const ready = await waitForFileReady(imageUrl);
|
|
203
|
-
if (!ready) {
|
|
204
|
-
console.warn(
|
|
205
|
-
"[messageContent] uploaded generated image not ready, drop inline payload:",
|
|
206
|
-
imageUrl
|
|
207
|
-
);
|
|
208
|
-
return null;
|
|
209
|
-
}
|
|
210
|
-
return imageUrl;
|
|
211
|
-
};
|
|
212
|
-
var normalizeAssistantContentBuffer = async (contentBuffer, dialogId, messageId, dispatch, getState, options) => {
|
|
213
|
-
if (!Array.isArray(contentBuffer) || contentBuffer.length === 0) {
|
|
214
|
-
return contentBuffer;
|
|
215
|
-
}
|
|
216
|
-
const updated = await Promise.all(
|
|
217
|
-
contentBuffer.map(async (part, index) => {
|
|
218
|
-
if (!part || part.type !== "image_url" || !part.image_url || !isDataUrlImage(part.image_url.url)) {
|
|
219
|
-
return part;
|
|
220
|
-
}
|
|
221
|
-
const newUrl = await uploadGeneratedImageDataUrl(
|
|
222
|
-
part.image_url.url,
|
|
223
|
-
dialogId,
|
|
224
|
-
messageId,
|
|
225
|
-
index,
|
|
226
|
-
dispatch,
|
|
227
|
-
getState,
|
|
228
|
-
options
|
|
229
|
-
);
|
|
230
|
-
if (!newUrl) {
|
|
231
|
-
return {
|
|
232
|
-
type: "text",
|
|
233
|
-
text: "[\u56FE\u7247\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u751F\u6210\u56FE\u7247]"
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
return stripDurableImageInlinePayload({
|
|
237
|
-
...part,
|
|
238
|
-
image_url: {
|
|
239
|
-
...part.image_url,
|
|
240
|
-
url: newUrl
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
})
|
|
244
|
-
);
|
|
245
|
-
return updated;
|
|
246
|
-
};
|
|
247
|
-
|
|
248
36
|
// packages/ai/context/retention.ts
|
|
249
37
|
var SAFE_BUFFER_RATIO = 0.95;
|
|
250
38
|
var CACHE_FIRST_RETENTION_STRENGTH = 0.95;
|
|
@@ -629,12 +417,18 @@ var COMPACTION_SUMMARY_SYSTEM_PROMPT = `\u4F60\u662F\u5BF9\u8BDD\u4E0A\u4E0B\u65
|
|
|
629
417
|
\u8981\u6C42\uFF1A
|
|
630
418
|
1) \u4F7F\u7528\u5BF9\u8BDD\u4E3B\u8BED\u8A00\uFF1B\u6DF7\u5408\u8BED\u8A00\u65F6\u4F18\u5148\u7528\u6237\u4E3B\u8981\u8BED\u8A00\uFF1B\u4E13\u6709\u540D\u8BCD\u3001\u6587\u4EF6\u8DEF\u5F84\u3001\u6807\u8BC6\u7B26\u3001\u547D\u4EE4\u4FDD\u7559\u539F\u6587\uFF0C\u4E0D\u8981\u7FFB\u8BD1\u6216\u8F6C\u8FF0\u3002
|
|
631
419
|
2) \u5173\u952E\u4E8B\u5B9E\u6863\u6848\u7684**\u524D\u4E24\u9879\u56FA\u5B9A\u662F**\uFF1A
|
|
632
|
-
- \u300C\u539F\u59CB\u76EE\u6807\u300D\uFF1A\
|
|
420
|
+
- \u300C\u539F\u59CB\u76EE\u6807\u300D\uFF1A\u8FD9\u6BB5\u5BF9\u8BDD**\u6700\u521D**\u7684\u610F\u56FE\u4E0E\u539F\u8BDD\uFF08\u5C3D\u91CF\u4FDD\u7559\u4ED6\u7684\u539F\u8BDD\u4E0E\u7528\u8BCD\uFF0C\u4E0D\u8981\u6539\u5199\u6210\u4EFB\u52A1\u6E05\u5355\uFF09\u3002
|
|
421
|
+
"\u6700\u521D"\u6307\u5F00\u5BF9\u8BDD\u90A3\u4E00\u523B\u2014\u2014\u4E0D\u5F97\u7528\u5BF9\u8BDD\u540E\u6765\u7684\u67D0\u53E5\u7528\u6237\u8BDD\uFF08\u5982\u4E34\u7761\u59D4\u6258\u3001\u4E2D\u671F\u8F6C\u8FF0\uFF09\u66FF\u4EE3\u6700\u521D\u76EE\u6807\uFF1B
|
|
422
|
+
\u6700\u521D\u539F\u8BDD\u4E0D\u5728\u672C\u6B21\u538B\u7F29\u8303\u56F4\u5185\u65F6\uFF0C\u6309\u300C\u8F93\u5165\u672A\u8986\u76D6\u300D\u5199"\u8F93\u5165\u4E2D\u672A\u89C1"\uFF0C\u518D\u4F9D\u636E\u5BF9\u8BDD\u5185\u6700\u65E9\u53EF\u8003\u7684\u590D\u8FF0\u5E76\u6CE8\u660E\u3002
|
|
633
423
|
\u589E\u91CF\u66F4\u65B0\u65F6\u6CBF\u7528\u3010\u73B0\u6709\u8BB0\u5FC6\u3011\u91CC\u5DF2\u6709\u7684\u300C\u539F\u59CB\u76EE\u6807\u300D\uFF0C\u4E0D\u8981\u88AB\u65B0\u589E\u5BF9\u8BDD\u6539\u5199\u2014\u2014\u5B83\u662F\u7A33\u5B9A\u5B57\u6BB5\uFF1B
|
|
634
424
|
\u4EC5\u5F53\u65B0\u5BF9\u8BDD\u660E\u786E\u8868\u660E\u539F\u6587\u6709\u4E8B\u5B9E\u6027\u9519\u8BEF\u65F6\u624D\u4FEE\u6B63\uFF0C\u5E76\u5728\u300C\u76EE\u6807\u6F14\u5316\u300D\u91CC\u6CE8\u660E\u3002
|
|
635
425
|
- \u300C\u76EE\u6807\u6F14\u5316\u300D\uFF1A\u82E5\u4E2D\u9014\u8F6C\u5411\uFF0C\u5199\u6E05\u8F6C\u5411\u4E86\u4EC0\u4E48\u3001\u56E0\u4E3A\u4EC0\u4E48\uFF1B\u6CA1\u6709\u8F6C\u5411\u5C31\u5199\u300C\u65E0\u8F6C\u5411\u300D\u6216\u7701\u7565\u8FD9\u4E00\u9879\uFF0C\u4E0D\u8981\u786C\u51D1\u3002
|
|
636
426
|
\u88AB\u540E\u7EED\u5DE5\u4F5C\u53D6\u4EE3\u7684\u662F"\u65B9\u6848"\uFF0C\u4E0D\u662F"\u7528\u6237\u7684\u521D\u59CB\u610F\u56FE"\u2014\u2014\u521D\u59CB\u610F\u56FE\u4E0D\u5F97\u7701\u7565\u3002
|
|
637
427
|
\u5176\u540E\u624D\u662F\uFF1A\u7528\u6237\u504F\u597D\u3001\u7EA6\u675F\u3001\u6280\u672F\u6808\u3001\u786E\u5B9A\u7684\u6587\u4EF6\u8DEF\u5F84\u3001\u6838\u5FC3\u51B3\u7B56\u3001\u672A\u5B8C\u6210\u5F85\u529E\u3002\u4FDD\u7559\u786E\u5207\u503C\uFF08\u7AEF\u53E3\u53F7\u3001\u7248\u672C\u53F7\u3001\u8DEF\u5F84\u3001\u53D8\u91CF\u540D\u3001\u9519\u8BEF\u4FE1\u606F\u539F\u6587\uFF09\uFF0C\u4E0D\u8981\u6982\u62EC\u6210"\u67D0\u4E2A\u7AEF\u53E3"\u6216"\u67D0\u4E2A\u6587\u4EF6"\u6216"\u67D0\u62A5\u9519"\u3002
|
|
428
|
+
\u5173\u952E\u4E8B\u5B9E\u6863\u6848\u8FD8\u5FC5\u987B\u5305\u542B\u4EE5\u4E0B\u4E09\u9879\uFF08\u53EF\u63A5\u5728\u56FA\u5B9A\u4E24\u9879\u4E4B\u540E\uFF0C\u7F3A\u4FE1\u606F\u65F6\u5982\u5B9E\u5199\u660E\uFF0C\u4E0D\u5F97\u7701\u7565\uFF09\uFF1A
|
|
429
|
+
- \u300C\u5DF2\u8BC1\u4F2A\u7684\u5047\u8BBE\u300D\uFF1A\u88AB\u8BC1\u636E\u5426\u51B3\u6216\u51B3\u5B9A\u4E0D\u91C7\u7528\u7684\u7ED3\u8BBA\u5355\u5217\uFF0C\u6CE8\u660E"\u5DF2\u8BC1\u4F2A/\u4E0D\u91C7\u7528"\u53CA\u4F9D\u636E\uFF0C\u9632\u6B62\u7EED\u4F5C\u628A\u5B83\u5F53\u4E8B\u5B9E\u91CD\u542F\u3002
|
|
430
|
+
- \u300C\u5361\u70B9\u4E0E\u9700\u7528\u6237\u51B3\u5B9A\u300D\uFF1A\u963B\u585E\u9879\u5361\u5728\u54EA\u3001\u9700\u8981\u7528\u6237\u63D0\u4F9B\u4EC0\u4E48\uFF08\u6388\u6743 / \u51ED\u636E / \u51B3\u5B9A\uFF09\uFF0C\u5199\u6E05\u695A\uFF0C\u4E0D\u5F97\u542B\u7CCA\u3002
|
|
431
|
+
- \u300C\u8F93\u5165\u672A\u8986\u76D6\u300D\uFF1A\u538B\u7F29\u8303\u56F4\u5185\u67E5\u4E0D\u5230\u7684\u5173\u952E\u4FE1\u606F\uFF08\u5982\u521D\u59CB\u539F\u8BDD\u3001\u6307\u5B9A id\uFF09\uFF0C\u5FC5\u987B\u5199"\u8F93\u5165\u4E2D\u672A\u89C1"\uFF0C\u7981\u6B62\u8111\u8865\u3002
|
|
638
432
|
3) \u5BF9\u8BDD\u8FDB\u5C55\u4E0E\u5F85\u529E\u4EE5\u7B2C\u4E00\u4EBA\u79F0\u7EED\u4F5C\u7B14\u8BB0\u7684\u53E3\u543B\u5199\uFF08"\u6211\u505A\u4E86\u2026""\u7528\u6237\u8981\u6C42\u2026""\u4E0B\u4E00\u6B65\u6211\u9700\u8981\u2026"\uFF09\uFF0C\u4E0D\u8981\u5199\u6210\u7B2C\u4E09\u65B9\u89C2\u5BDF\u62A5\u544A\u3002\u5148\u6781\u7B80\u6982\u62EC\u65E7\u4E0A\u4E0B\u6587\uFF0C\u518D\u66F4\u8BE6\u7EC6\u8BB0\u5F55\u6700\u8FD1\u8FDB\u5C55\u3001\u7ED3\u8BBA\u3001\u5206\u6B67\u4E0E\u4E0B\u4E00\u6B65\u3002\u5BF9\u4E8E\u58F0\u79F0\u5DF2\u5B8C\u6210\u4F46\u5C1A\u672A\u9A8C\u8BC1\u7684\u5DE5\u4F5C\uFF08\u5982\u5DE5\u5177\u8C03\u7528\u8FD4\u56DE\u6210\u529F\u4F46\u7ED3\u679C\u672A\u4EBA\u5DE5\u786E\u8BA4\uFF09\uFF0C\u660E\u786E\u6807\u6CE8"\uFF08\u5F85\u9A8C\u8BC1\uFF09"\u2014\u2014\u4E0D\u8981\u9ED8\u8BA4\u4FE1\u4EFB\u5DE5\u5177\u8FD4\u56DE\u503C\u3002
|
|
639
433
|
4) \u6587\u4EF6\u64CD\u4F5C\u6E05\u5355\uFF1A\u5217\u51FA\u672C\u6B21\u538B\u7F29\u8303\u56F4\u5185\u8BFB\u53D6\u3001\u5199\u5165\u3001\u7F16\u8F91\u8FC7\u7684\u6587\u4EF6\u8DEF\u5F84\u53CA\u64CD\u4F5C\u7C7B\u578B\uFF08\u5982: - \u8BFB\u53D6: path/to/file\uFF1B\u82E5\u672A\u6D89\u53CA\u6587\u4EF6\u64CD\u4F5C\u5199"\u65E0"\uFF09\u3002
|
|
640
434
|
5) \u5FFD\u7565\u5BD2\u6684\u3001\u91CD\u590D\u5C1D\u8BD5\u548C\u65E0\u4EF7\u503C\u5E9F\u8BDD\uFF1B**\u5DF2\u653E\u5F03\u7684\u65B9\u6848/\u5C1D\u8BD5**\u53EF\u4EE5\u7701\u7565\uFF0C\u4F46\u7528\u6237\u5F53\u521D\u7684\u610F\u56FE\u4E0E\u7406\u7531\u4E0D\u53EF\u7701\u7565\uFF08\u89C1\u7B2C 2 \u6761\uFF09\u3002
|
|
@@ -710,16 +504,165 @@ function formatFileOperationsFromMessages(msgs, resolveCanonicalName) {
|
|
|
710
504
|
return allOps.map((op) => `- ${typeLabelMap[op.type]}: ${op.path}`).join("\n");
|
|
711
505
|
}
|
|
712
506
|
var TOOL_RESULT_TRUNCATE_CHARS = 4e3;
|
|
507
|
+
var SUMMARY_INPUT_MAX_TOKENS = 3e4;
|
|
508
|
+
function computeSummaryInputTokenCap(contextWindow) {
|
|
509
|
+
const halfWindow = typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > 0 ? Math.floor(contextWindow * 0.5) : SUMMARY_INPUT_MAX_TOKENS;
|
|
510
|
+
return Math.max(1, Math.min(SUMMARY_INPUT_MAX_TOKENS, halfWindow));
|
|
511
|
+
}
|
|
512
|
+
function capTextToTokenBudget(text, maxTokens) {
|
|
513
|
+
const marker = `
|
|
514
|
+
|
|
515
|
+
[... summary input capped to ${maxTokens} tokens ...]`;
|
|
516
|
+
const markerTokens = estimateTokenCount(marker);
|
|
517
|
+
const budget = Math.max(0, maxTokens - markerTokens);
|
|
518
|
+
if (estimateTokenCount(text) <= budget) return text;
|
|
519
|
+
let lo = 0;
|
|
520
|
+
let hi = text.length;
|
|
521
|
+
while (lo < hi) {
|
|
522
|
+
const mid = lo + hi + 1 >> 1;
|
|
523
|
+
if (estimateTokenCount(text.slice(0, mid)) <= budget) lo = mid;
|
|
524
|
+
else hi = mid - 1;
|
|
525
|
+
}
|
|
526
|
+
return `${text.slice(0, lo)}${marker}`;
|
|
527
|
+
}
|
|
528
|
+
function capSummaryInputToTokenBudget(items, maxTotalTokens) {
|
|
529
|
+
if (items.length === 0) return "";
|
|
530
|
+
const sepTokens = estimateTokenCount("\n");
|
|
531
|
+
const kept = [];
|
|
532
|
+
let used = 0;
|
|
533
|
+
for (let i = items.length - 1; i >= 0; i -= 1) {
|
|
534
|
+
const t = estimateTokenCount(items[i]);
|
|
535
|
+
const sep = kept.length > 0 ? sepTokens : 0;
|
|
536
|
+
if (kept.length > 0 && used + sep + t > maxTotalTokens) break;
|
|
537
|
+
used += sep + t;
|
|
538
|
+
kept.push(items[i]);
|
|
539
|
+
}
|
|
540
|
+
kept.reverse();
|
|
541
|
+
const result = kept.join("\n");
|
|
542
|
+
return estimateTokenCount(result) > maxTotalTokens ? capTextToTokenBudget(result, maxTotalTokens) : result;
|
|
543
|
+
}
|
|
544
|
+
var EVIDENCE_LINE_PATTERNS = [
|
|
545
|
+
// commit sha:必须带 git 语境(commit/sha/HEAD/merge/push 输出 a..b)且含字母+数字
|
|
546
|
+
/\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,
|
|
547
|
+
/\b(?=[0-9a-f]*[a-f])(?=[0-9a-f]*\d)[0-9a-f]{7,40}\.\.(?=[0-9a-f]*[a-f])[0-9a-f]{7,40}\b/,
|
|
548
|
+
// 测试结论:带计数的 pass/fail,或 bun/jest 风格的 (pass)/(fail) 行首
|
|
549
|
+
/\b\d+\s+(?:pass|passed|fail|failed|tests?)\b/i,
|
|
550
|
+
/^\s*\((?:pass|fail)\)/i,
|
|
551
|
+
/^\s*(?:FAIL|PASS|ERROR)\b[:\s]/,
|
|
552
|
+
// 退出码 / HTTP 状态:必须带键名
|
|
553
|
+
/\bexit(?:\s*code|Code|_code)?\s*[=:]\s*\d+/i,
|
|
554
|
+
/\bHTTP\/[\d.]+\s+[1-5]\d{2}\b/,
|
|
555
|
+
/\b(?:status|statusCode|http_code|code)\s*[=:]\s*[1-5]\d{2}\b/i,
|
|
556
|
+
// 错误:行首的 XxxError:/Exception:,或 error: 前缀;超时带 timeout 关键结构
|
|
557
|
+
/^\s*(?:Uncaught\s+)?[A-Z]\w*(?:Error|Exception)\b\s*:/,
|
|
558
|
+
/^\s*(?:error|fatal|panic)\s*:/i,
|
|
559
|
+
/\bTimeout\s+\d+\s*ms\s+exceeded\b/i,
|
|
560
|
+
// 堆栈帧
|
|
561
|
+
/^\s*at\s+\S+.*:\d+(?::\d+)?\)?\s*$/
|
|
562
|
+
];
|
|
563
|
+
function isEvidenceLine(line) {
|
|
564
|
+
if (!line) return false;
|
|
565
|
+
return EVIDENCE_LINE_PATTERNS.some((re) => re.test(line));
|
|
566
|
+
}
|
|
567
|
+
function selectEvidenceLines(lines) {
|
|
568
|
+
return lines.filter(isEvidenceLine);
|
|
569
|
+
}
|
|
570
|
+
var HEAD_SHARE = 0.4;
|
|
571
|
+
var TAIL_SHARE = 0.4;
|
|
572
|
+
function evidenceTruncateBudget(maxChars) {
|
|
573
|
+
const markerReserve = 96;
|
|
574
|
+
const usable = Math.max(0, maxChars - markerReserve);
|
|
575
|
+
const headCap = Math.floor(usable * HEAD_SHARE);
|
|
576
|
+
const tailCap = Math.floor(usable * TAIL_SHARE);
|
|
577
|
+
return {
|
|
578
|
+
markerReserve,
|
|
579
|
+
headCap,
|
|
580
|
+
tailCap,
|
|
581
|
+
evidenceCap: Math.max(0, usable - headCap - tailCap)
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
function takeHeadLines(lines, cap) {
|
|
585
|
+
let text = "";
|
|
586
|
+
let consumed = 0;
|
|
587
|
+
for (const line of lines) {
|
|
588
|
+
const candidate = consumed === 0 ? line : `${text}
|
|
589
|
+
${line}`;
|
|
590
|
+
if (candidate.length > cap) {
|
|
591
|
+
if (consumed === 0 && cap > 0) {
|
|
592
|
+
return { text: line.slice(0, cap), consumed: 1 };
|
|
593
|
+
}
|
|
594
|
+
break;
|
|
595
|
+
}
|
|
596
|
+
text = candidate;
|
|
597
|
+
consumed += 1;
|
|
598
|
+
}
|
|
599
|
+
return { text, consumed };
|
|
600
|
+
}
|
|
601
|
+
function takeTailLines(lines, cap) {
|
|
602
|
+
if (cap <= 0 || lines.length === 0) return { text: "", consumed: 0 };
|
|
603
|
+
let text = "";
|
|
604
|
+
let consumed = 0;
|
|
605
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
606
|
+
const candidate = consumed === 0 ? lines[i] : `${lines[i]}
|
|
607
|
+
${text}`;
|
|
608
|
+
if (candidate.length > cap) {
|
|
609
|
+
if (consumed === 0) return { text: lines[i].slice(-cap), consumed: 1 };
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
text = candidate;
|
|
613
|
+
consumed += 1;
|
|
614
|
+
}
|
|
615
|
+
return { text, consumed };
|
|
616
|
+
}
|
|
617
|
+
function shrinkToFit(head, evidence, tail, makeMarker, maxChars) {
|
|
618
|
+
const joinBody = () => head.concat(evidence, tail).join("\n");
|
|
619
|
+
let marker = makeMarker(joinBody().length);
|
|
620
|
+
while (joinBody().length + marker.length > maxChars) {
|
|
621
|
+
if (evidence.length > 0) evidence.pop();
|
|
622
|
+
else if (tail.length > 0) tail.pop();
|
|
623
|
+
else if (head.length > 0) head.pop();
|
|
624
|
+
else break;
|
|
625
|
+
marker = makeMarker(joinBody().length);
|
|
626
|
+
}
|
|
627
|
+
const result = joinBody() + marker;
|
|
628
|
+
return result.length > maxChars ? result.slice(0, maxChars) : result;
|
|
629
|
+
}
|
|
713
630
|
function truncateContentForSummary(role, content, maxChars = TOOL_RESULT_TRUNCATE_CHARS) {
|
|
714
631
|
if (role !== "tool" || content.length <= maxChars) return content;
|
|
715
|
-
const
|
|
716
|
-
const
|
|
717
|
-
|
|
632
|
+
const lines = content.split("\n");
|
|
633
|
+
const budget = evidenceTruncateBudget(maxChars);
|
|
634
|
+
const head = takeHeadLines(lines, budget.headCap);
|
|
635
|
+
const tail = takeTailLines(
|
|
636
|
+
lines.slice(0, lines.length - head.consumed),
|
|
637
|
+
budget.tailCap
|
|
638
|
+
);
|
|
639
|
+
const middle = lines.slice(head.consumed, lines.length - tail.consumed);
|
|
640
|
+
const evidence = selectEvidenceLines(middle);
|
|
641
|
+
if (evidence.length === 0) {
|
|
642
|
+
return `${content.slice(0, maxChars)}
|
|
718
643
|
|
|
719
|
-
[... ${
|
|
644
|
+
[... ${content.length - maxChars} chars truncated ...]`;
|
|
645
|
+
}
|
|
646
|
+
const headLines = head.text ? head.text.split("\n") : [];
|
|
647
|
+
const tailLines = tail.text ? tail.text.split("\n") : [];
|
|
648
|
+
const evidenceLines = [];
|
|
649
|
+
let evidenceUsed = 0;
|
|
650
|
+
for (const line of evidence) {
|
|
651
|
+
if (evidenceUsed + line.length > budget.evidenceCap) break;
|
|
652
|
+
evidenceLines.push(line);
|
|
653
|
+
evidenceUsed += line.length;
|
|
654
|
+
}
|
|
655
|
+
const marker = (bodyChars) => {
|
|
656
|
+
const note = evidenceLines.length > 0 ? `
|
|
657
|
+
[... \u5DF2\u4FDD\u7559 ${evidenceLines.length} \u6761\u8BC1\u636E\u884C ...]` : "";
|
|
658
|
+
return `
|
|
659
|
+
|
|
660
|
+
[... ${content.length - bodyChars} chars truncated ...]${note}`;
|
|
661
|
+
};
|
|
662
|
+
return shrinkToFit(headLines, evidenceLines, tailLines, marker, maxChars);
|
|
720
663
|
}
|
|
721
|
-
function formatMessagesForSummaryWithTruncation(msgs, maxToolResultChars = TOOL_RESULT_TRUNCATE_CHARS) {
|
|
722
|
-
|
|
664
|
+
function formatMessagesForSummaryWithTruncation(msgs, maxToolResultChars = TOOL_RESULT_TRUNCATE_CHARS, maxTotalTokens) {
|
|
665
|
+
const items = msgs.map((msg) => {
|
|
723
666
|
const rawContent = serializeMessageContent(msg.content) || "";
|
|
724
667
|
const truncated = truncateContentForSummary(
|
|
725
668
|
msg.role,
|
|
@@ -728,7 +671,11 @@ function formatMessagesForSummaryWithTruncation(msgs, maxToolResultChars = TOOL_
|
|
|
728
671
|
);
|
|
729
672
|
const text = truncated || formatMessageContentFallback(msg);
|
|
730
673
|
return `${msg.role}: ${text}`;
|
|
731
|
-
})
|
|
674
|
+
});
|
|
675
|
+
if (typeof maxTotalTokens === "number" && Number.isFinite(maxTotalTokens) && maxTotalTokens > 0) {
|
|
676
|
+
return capSummaryInputToTokenBudget(items, maxTotalTokens);
|
|
677
|
+
}
|
|
678
|
+
return items.join("\n");
|
|
732
679
|
}
|
|
733
680
|
function buildCompactionMetrics(args) {
|
|
734
681
|
const {
|
|
@@ -843,13 +790,175 @@ var isMeaningfulResponsesOutput = (event) => {
|
|
|
843
790
|
return false;
|
|
844
791
|
};
|
|
845
792
|
|
|
846
|
-
// packages/
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
793
|
+
// packages/ai/llm/getModelContextWindow.ts
|
|
794
|
+
var DEFAULT_CONTEXT_WINDOW = 256e3;
|
|
795
|
+
var QWEN_3_6_CONTEXT_WINDOW = 262144;
|
|
796
|
+
var GLM_5_2_CONTEXT_WINDOW = 1e6;
|
|
797
|
+
var GPT_6_1_SOL_CONTEXT_WINDOW = 5e5;
|
|
798
|
+
var GPT_6_1_SOL_PATTERN = /(^|\/)gpt-6\.1[- ]sol(?![a-z])/;
|
|
799
|
+
function channelPinnedContextWindow(normalizedName) {
|
|
800
|
+
if (GPT_6_1_SOL_PATTERN.test(normalizedName)) return GPT_6_1_SOL_CONTEXT_WINDOW;
|
|
801
|
+
return void 0;
|
|
802
|
+
}
|
|
803
|
+
var ANTIGRAVITY_EFFORT_SUFFIXES = [
|
|
804
|
+
"-tiered",
|
|
805
|
+
"-extra-low",
|
|
806
|
+
"-low",
|
|
807
|
+
"-medium",
|
|
808
|
+
"-high"
|
|
809
|
+
];
|
|
810
|
+
function stripEffortSuffix(model) {
|
|
811
|
+
for (const suffix of ANTIGRAVITY_EFFORT_SUFFIXES) {
|
|
812
|
+
if (model.endsWith(suffix) && model.length > suffix.length) {
|
|
813
|
+
return model.slice(0, -suffix.length);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
return model;
|
|
817
|
+
}
|
|
818
|
+
function stripPreviewSuffix(model) {
|
|
819
|
+
const suffix = "-preview";
|
|
820
|
+
if (model.endsWith(suffix) && model.length > suffix.length) {
|
|
821
|
+
return model.slice(0, -suffix.length);
|
|
822
|
+
}
|
|
823
|
+
return model;
|
|
824
|
+
}
|
|
825
|
+
function stripModelTag(model) {
|
|
826
|
+
const colonIndex = model.indexOf(":");
|
|
827
|
+
if (colonIndex > 0) {
|
|
828
|
+
return model.slice(0, colonIndex);
|
|
829
|
+
}
|
|
830
|
+
return model;
|
|
831
|
+
}
|
|
832
|
+
var fullModelMap = null;
|
|
833
|
+
var getFullModelMap = () => {
|
|
834
|
+
if (!fullModelMap) {
|
|
835
|
+
fullModelMap = /* @__PURE__ */ new Map();
|
|
836
|
+
for (const [provider, models] of Object.entries(MODEL_LOOKUP_MAP)) {
|
|
837
|
+
for (const model of models) {
|
|
838
|
+
const entry = { ...model, provider };
|
|
839
|
+
fullModelMap.set(model.name, entry);
|
|
840
|
+
if (model.displayName) {
|
|
841
|
+
fullModelMap.set(model.displayName.toLowerCase(), entry);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return fullModelMap;
|
|
847
|
+
};
|
|
848
|
+
var legacyModelMap = null;
|
|
849
|
+
var getLegacyModelMap = () => {
|
|
850
|
+
if (!legacyModelMap) {
|
|
851
|
+
legacyModelMap = /* @__PURE__ */ new Map();
|
|
852
|
+
for (const model of ALL_MODELS) {
|
|
853
|
+
legacyModelMap.set(model.name, model);
|
|
854
|
+
if (model.displayName) {
|
|
855
|
+
legacyModelMap.set(model.displayName.toLowerCase(), model);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return legacyModelMap;
|
|
860
|
+
};
|
|
861
|
+
function fuzzyContextWindow(normalizedName) {
|
|
862
|
+
const bareModelName = (normalizedName.includes("/") ? normalizedName.slice(normalizedName.lastIndexOf("/") + 1) : normalizedName).replace(/:.*$/, "");
|
|
863
|
+
if (normalizedName.includes("qwen-long") || normalizedName.includes("qwen3-long")) return 10485760;
|
|
864
|
+
if (normalizedName.includes("qwen-coder") || normalizedName.includes("qwen3-coder")) return 1048576;
|
|
865
|
+
if (normalizedName.includes("qwen3.8") || normalizedName.includes("qwen3p8")) return 1e6;
|
|
866
|
+
if (normalizedName.includes("minimax-m3") || normalizedName.includes("minimax_m3")) return 1e6;
|
|
867
|
+
if (bareModelName === "mimo-v2.6-pro" || normalizedName === "mimo v2.6 pro") return 1048576;
|
|
868
|
+
if (normalizedName.includes("glm-5.3") || normalizedName.includes("glm5.3")) return 105e4;
|
|
869
|
+
if (normalizedName.includes("glm-5.2") || normalizedName.includes("glm5.2")) return GLM_5_2_CONTEXT_WINDOW;
|
|
870
|
+
if (normalizedName.includes("deepseek")) return 1e6;
|
|
871
|
+
if (GPT_6_1_SOL_PATTERN.test(normalizedName)) return GPT_6_1_SOL_CONTEXT_WINDOW;
|
|
872
|
+
if (normalizedName.includes("gpt-5") || normalizedName.includes("gpt-4.1")) return 1047576;
|
|
873
|
+
if (normalizedName.startsWith("cursor-grok-4.5")) return 1e6;
|
|
874
|
+
if (normalizedName.includes("claude-4.6")) return 1e6;
|
|
875
|
+
if (normalizedName.includes("gemini-3.1")) return 1e6;
|
|
876
|
+
if (normalizedName.includes("gemini")) return 1048576;
|
|
877
|
+
if (normalizedName.includes("qwen3.6") || normalizedName.includes("qwen3p6")) return QWEN_3_6_CONTEXT_WINDOW;
|
|
878
|
+
if (normalizedName.includes("qwen3.7") || normalizedName.includes("qwen3p7")) return 262144;
|
|
879
|
+
if (normalizedName.includes("minimax-m2") || normalizedName.includes("minimax_m2")) return 262144;
|
|
880
|
+
if (normalizedName.includes("mistral-large-4")) {
|
|
881
|
+
const rest = normalizedName.slice(
|
|
882
|
+
normalizedName.indexOf("mistral-large-4") + "mistral-large-4".length
|
|
883
|
+
);
|
|
884
|
+
if (rest === "" || /^[-:_@/\s]/.test(rest)) return 524288;
|
|
885
|
+
}
|
|
886
|
+
if (normalizedName.includes("mistral-vibe-cli") || normalizedName.includes("mistral-medium-3.5") || normalizedName.includes("mistral-medium-3-5") || normalizedName.includes("mistral-medium-latest") || normalizedName.includes("mistral-medium-2604") || normalizedName.includes("mistral-large-latest") || normalizedName.includes("mistral-large-2512") || normalizedName.includes("mistral-small-latest") || normalizedName.includes("mistral-small-2603") || normalizedName.includes("magistral-medium-latest") || normalizedName.includes("magistral-small-latest") || // 展示名(TUI 传 displayName 的路径;Mistral 不在 MODEL_LOOKUP_MAP,无法走精确表):
|
|
887
|
+
normalizedName.includes("mistral vibe cli") || normalizedName.includes("mistral medium 3.5") || normalizedName.includes("mistral large (latest)")) {
|
|
888
|
+
return 262144;
|
|
889
|
+
}
|
|
890
|
+
if (bareModelName === "mistral-medium" || bareModelName === "mistral-medium-3") return 262144;
|
|
891
|
+
if (normalizedName.includes("mistral-embed") || normalizedName.includes("codestral-embed")) return 8192;
|
|
892
|
+
if (normalizedName.includes("mistral-ocr")) return 16384;
|
|
893
|
+
if (normalizedName.includes("mistral-moderation")) return 131072;
|
|
894
|
+
if (normalizedName.includes("codestral") || normalizedName.includes("mistral-code")) return 256e3;
|
|
895
|
+
if (normalizedName.includes("claude")) return 2e5;
|
|
896
|
+
if (normalizedName.includes("llama3.1") || normalizedName.includes("llama-3.1") || normalizedName.includes("llama3.2") || normalizedName.includes("llama-3.2") || normalizedName.includes("llama3.3") || normalizedName.includes("llama-3.3") || normalizedName.includes("qwen2.5") || normalizedName.includes("qwen-2.5") || normalizedName.includes("mistral-nemo") || normalizedName.includes("phi3.5") || normalizedName.includes("phi-3.5") || normalizedName.includes("phi4") || normalizedName.includes("phi-4")) {
|
|
897
|
+
return 131072;
|
|
898
|
+
}
|
|
899
|
+
if (normalizedName.includes("qwen2") || normalizedName.includes("qwen-2") || normalizedName.includes("mistral") || normalizedName.includes("mixtral")) {
|
|
900
|
+
return 32768;
|
|
901
|
+
}
|
|
902
|
+
if (normalizedName.includes("codellama") || normalizedName.includes("starcoder") || normalizedName.includes("phi3") || normalizedName.includes("phi-3")) {
|
|
903
|
+
return 16384;
|
|
904
|
+
}
|
|
905
|
+
if (normalizedName.includes("llama3") || normalizedName.includes("llama-3") || normalizedName.includes("gemma2") || normalizedName.includes("gemma-2") || normalizedName.includes("gemma")) {
|
|
906
|
+
return 8192;
|
|
907
|
+
}
|
|
908
|
+
if (normalizedName.includes("llama2") || normalizedName.includes("llama-2") || normalizedName.includes("llama")) {
|
|
909
|
+
return 4096;
|
|
910
|
+
}
|
|
911
|
+
return void 0;
|
|
852
912
|
}
|
|
913
|
+
var findModelContextWindow = (modelName, provider) => {
|
|
914
|
+
if (!modelName) return void 0;
|
|
915
|
+
const onPlatformChannel = isPlatformManagedProvider(provider, modelName);
|
|
916
|
+
const normalizedName = modelName.toLowerCase();
|
|
917
|
+
const map = getFullModelMap();
|
|
918
|
+
const rawCandidates = [modelName, normalizedName];
|
|
919
|
+
const strippedTag = stripModelTag(modelName);
|
|
920
|
+
if (strippedTag !== modelName) {
|
|
921
|
+
rawCandidates.push(strippedTag, strippedTag.toLowerCase());
|
|
922
|
+
}
|
|
923
|
+
const candidates = [];
|
|
924
|
+
for (const base of rawCandidates) {
|
|
925
|
+
candidates.push(base);
|
|
926
|
+
const strippedEffort = stripEffortSuffix(base);
|
|
927
|
+
if (strippedEffort !== base) {
|
|
928
|
+
candidates.push(strippedEffort, strippedEffort.toLowerCase());
|
|
929
|
+
}
|
|
930
|
+
const strippedPreview = stripPreviewSuffix(base);
|
|
931
|
+
if (strippedPreview !== base) {
|
|
932
|
+
candidates.push(strippedPreview, strippedPreview.toLowerCase());
|
|
933
|
+
}
|
|
934
|
+
if (strippedEffort !== base) {
|
|
935
|
+
const strippedBoth = stripPreviewSuffix(strippedEffort);
|
|
936
|
+
if (strippedBoth !== strippedEffort) {
|
|
937
|
+
candidates.push(strippedBoth, strippedBoth.toLowerCase());
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
for (const candidate of candidates) {
|
|
942
|
+
const model = map.get(candidate);
|
|
943
|
+
if (model?.contextWindow) {
|
|
944
|
+
if (!onPlatformChannel && isPlatformManagedProvider(model.provider, model.name) && channelPinnedContextWindow(model.name.toLowerCase()) !== void 0) {
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
return typeof model.contextWindow === "number" ? model.contextWindow : void 0;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
if (!onPlatformChannel) {
|
|
951
|
+
const pinned = channelPinnedContextWindow(normalizedName);
|
|
952
|
+
if (pinned !== void 0) return pinned;
|
|
953
|
+
}
|
|
954
|
+
return fuzzyContextWindow(normalizedName);
|
|
955
|
+
};
|
|
956
|
+
var getModelContextWindow = (modelName, provider) => findModelContextWindow(modelName, provider) ?? DEFAULT_CONTEXT_WINDOW;
|
|
957
|
+
var getModelInfo = (modelName) => {
|
|
958
|
+
if (!modelName) return null;
|
|
959
|
+
const map = getLegacyModelMap();
|
|
960
|
+
return map.get(modelName) || map.get(modelName.toLowerCase()) || null;
|
|
961
|
+
};
|
|
853
962
|
|
|
854
963
|
export {
|
|
855
964
|
normalizeTimingMs,
|
|
@@ -860,11 +969,12 @@ export {
|
|
|
860
969
|
withProviderCallTimingFields,
|
|
861
970
|
isMeaningfulChatCompletionOutput,
|
|
862
971
|
isMeaningfulResponsesOutput,
|
|
863
|
-
clipCompactText,
|
|
864
972
|
planContextUsage,
|
|
865
|
-
|
|
973
|
+
DEFAULT_CONTEXT_WINDOW,
|
|
974
|
+
findModelContextWindow,
|
|
975
|
+
getModelContextWindow,
|
|
976
|
+
getModelInfo,
|
|
866
977
|
serializeMessageContent,
|
|
867
|
-
normalizeAssistantContentBuffer,
|
|
868
978
|
resolveCompressionTriggerRatio,
|
|
869
979
|
truncateToolOutputForContext,
|
|
870
980
|
planCompression,
|
|
@@ -872,6 +982,8 @@ export {
|
|
|
872
982
|
COMPACTION_SUMMARY_SYSTEM_PROMPT,
|
|
873
983
|
buildCompactionUserContent,
|
|
874
984
|
formatFileOperationsFromMessages,
|
|
985
|
+
TOOL_RESULT_TRUNCATE_CHARS,
|
|
986
|
+
computeSummaryInputTokenCap,
|
|
875
987
|
formatMessagesForSummaryWithTruncation,
|
|
876
988
|
buildCompactionMetricsFromPlan,
|
|
877
989
|
formatCompactionMetricsLog
|