nolo-cli 0.149.0-alpha.1 → 0.151.0-alpha.3
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-OW3H7ICR.js → _executeModel-T7ANHTUW.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-4L5KCKFY.js} +181 -93
- package/{agentEmailCommands-A6XBQZBN.js → agentEmailCommands-2IMMIRO2.js} +132 -112
- package/{agentGrantCommands-M3XFO6EN.js → agentGrantCommands-HOJ3JBBQ.js} +3 -3
- package/agentListCommands-TWFLUYIZ.js +802 -0
- package/{agentMachineCommands-DQPUIMAC.js → agentMachineCommands-KIWXWT6L.js} +58 -62
- package/{agentProviderCommands-YK2BIIXZ.js → agentProviderCommands-HL6MBLCL.js} +149 -2
- package/{agentPullCommand-HF4A42D4.js → agentPullCommand-FA43RBRU.js} +7 -7
- package/agentRecordCommands-727NPCRW.js +154 -0
- package/agentRunCommand-JASIG3FZ.js +183 -0
- package/{agentRunControl-2SKCR4SB.js → agentRunControl-IFM7IGMG.js} +10 -2
- package/{agentRuntimeLocal-AK2QVJHY.js → agentRuntimeLocal-KKSQJMTE.js} +47 -50
- package/{agentSlice-O4RUQUMT.js → agentSlice-SLV57QGU.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-ID7LNBWR.js → chunk-3T4ZG6AC.js} +1920 -644
- 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-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-TXH4IWJL.js → chunk-626KHJNX.js} +20 -11
- 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-IAESIMK7.js → chunk-A4MW3YZL.js} +10 -14
- package/{chunk-OMRJYNCI.js → chunk-AG7MCDLR.js} +26 -31
- package/chunk-AGIM7IMJ.js +147 -0
- package/{chunk-7CHC4W22.js → chunk-AIZE5TDM.js} +3 -3
- package/chunk-AJ3G7X2K.js +7012 -0
- 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-YAQJJDC2.js → chunk-BJEZC5RA.js} +214 -51
- 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-CYJWI3NH.js +119 -0
- package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
- package/{chunk-3SV7RM24.js → chunk-D2QN6CTI.js} +117 -72
- package/{chunk-TZZ2WRBL.js → chunk-DFDXM2Y4.js} +20 -16
- package/{chunk-5TEEECZM.js → chunk-E2AKSW7L.js} +10 -7
- package/{chunk-RSEEDUMS.js → chunk-EDX5XSJM.js} +2 -2
- 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-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-P6GMCCAT.js → chunk-GQV5KHJU.js} +78 -12
- package/{chunk-B2XUQXQX.js → chunk-HIQ4GF53.js} +191 -68
- package/{chunk-GMZLP5DV.js → chunk-HNUWUO75.js} +30 -19
- package/{chunk-UASIEDKM.js → chunk-I2XLRXVX.js} +36 -31
- 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-BIDGLJQ3.js → chunk-IK2TSJQA.js} +45 -8
- 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-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-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-TB3MIBRC.js → chunk-PIDUNDFS.js} +572 -430
- package/{chunk-4JMDLJAD.js → chunk-PJNFNEJE.js} +114 -37
- package/chunk-PKZKOVA5.js +11507 -0
- package/{chunk-Z4CSIXYP.js → chunk-PLSVXHSA.js} +3 -3
- 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-HTVYCXBP.js → chunk-RN2GPWN6.js} +354 -120
- package/{chunk-ATLTFRYJ.js → chunk-ROCUB2H2.js} +280 -98
- 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-SW4S4XYB.js +1794 -0
- package/{chunk-ZUEK6A6C.js → chunk-TTH4HOJD.js} +1973 -754
- 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-MST6R3E4.js → chunk-U5GPBQDG.js} +34 -22
- package/chunk-U5ICMAFV.js +14110 -0
- 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-3DAVPNFT.js → chunk-V4EE3D54.js} +122 -107
- 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-DXHL7G2L.js → chunk-VWW6O2TL.js} +274 -93
- 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-5OA5HMTL.js → chunk-YLMMECCH.js} +1 -1
- package/{chunk-CFT5HBGW.js → chunk-YVLQXTUB.js} +448 -12
- package/chunk-YVPQATSC.js +709 -0
- package/chunk-ZEZC7IIM.js +126 -0
- package/{chunk-ALGORS6Y.js → chunk-ZF6526IQ.js} +43 -8
- package/chunk-ZIWPQEFU.js +165 -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-2KBOXZQC.js → commandRegistry-NBLZEMCW.js} +183 -107
- package/contentThunks-6AIWNSGO.js +84 -0
- package/{cooldownCommands-ZLEPIB4A.js → cooldownCommands-JFKTYS2D.js} +2 -2
- package/{createAgentAutomationAction-5UGTB26P.js → createAgentAutomationAction-4BUS65DZ.js} +53 -44
- package/createDialogAction-QAIKSCG4.js +76 -0
- package/{createPageAction-CDLDKPRM.js → createPageAction-DXCZ334C.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-N3YB65G5.js → dialogSlice-PVUSMKFW.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-E3CEOV5Q.js → docStore-CSEBEMKP.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-DQAD5ERJ.js → handleSendMessageAction-G2TLYGC4.js} +422 -118
- 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-B4TAYYA7.js +244 -0
- package/localRuntimeAuthority-JDAD7CB6.js +16 -0
- package/{localRuntimeDb-3LRMNLCM.js → localRuntimeDb-CVC62PM5.js} +1 -1
- package/{machineCommands-HAP75VSG.js → machineCommands-6OBFD3XF.js} +503 -161
- package/{machineInfo-66ZFUMLE.js → machineInfo-UKPTZO5Y.js} +2 -2
- package/machineWsRunDispatch-OO7N3O3Y.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-7BC66QSX.js → readlineWorkspace-UIQN7JUR.js} +5017 -915
- package/{removeDialogAgentAction-OSYNZRX7.js → removeDialogAgentAction-E2H3OZU6.js} +29 -28
- package/{runAgentClientLoop-6E6UC3CE.js → runAgentClientLoop-GS3SGG37.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-3UXPYFNX.js → streamAgentChatTurn-4XYC33KE.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-P77EE7Q4.js +124 -0
- package/tuiSummaryLlmCaller-BM3VSTBU.js +130 -0
- package/{updateCommands-4EHDLF5J.js → updateCommands-NQXAGFM7.js} +3 -3
- package/{updateDialogTitleAction-UPFV7TDT.js → updateDialogTitleAction-CIANVPZC.js} +102 -57
- package/workloadLifecycle-36DXRZKU.js +320 -0
- package/action-GI44T4DR.js +0 -31
- package/agentListCommands-IW3GQVUP.js +0 -427
- package/agentRecordCommands-VCA76W6B.js +0 -134
- package/agentRunCommand-YNLDKVR7.js +0 -161
- package/browser-image-compression-MFDTD7K6.js +0 -1763
- package/chatQueueReduxAdapter-TJRMXMYA.js +0 -186
- package/chromeOpsCommands-IXRLN57H.js +0 -289
- package/chunk-36KZDDO5.js +0 -2415
- package/chunk-ACQD6YI2.js +0 -25363
- package/chunk-CQ3WA2NE.js +0 -299
- package/chunk-CYSYR67N.js +0 -93
- 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-PZZTFEKK.js +0 -34
- package/chunk-URMS4XY2.js +0 -10
- package/chunk-UV6VISQJ.js +0 -20
- package/chunk-VJVNU77E.js +0 -83
- package/chunk-XYJSY4KG.js +0 -13807
- package/chunk-Y5GCAMGP.js +0 -9
- package/chunk-YPREESF4.js +0 -225
- package/contentThunks-BDIQRZR6.js +0 -73
- package/createDialogAction-B7VGVEVU.js +0 -66
- package/dialogCommands-G7YBVAMC.js +0 -102
- package/levelLazyShim-GZBKODGI.js +0 -7
- package/machineWsRunDispatch-L32G7C4P.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-MKYDMWA4.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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findPotentialSecrets
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6QDYSCPW.js";
|
|
4
4
|
import {
|
|
5
5
|
buildLocalRunEnv,
|
|
6
6
|
isFullstackCodingAgentRef,
|
|
@@ -9,14 +9,16 @@ import {
|
|
|
9
9
|
resolveRawAgentInput,
|
|
10
10
|
resolveServerUrl,
|
|
11
11
|
writeUsage
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-IK2TSJQA.js";
|
|
13
|
+
import {
|
|
14
|
+
getReadableCliDb
|
|
15
|
+
} from "./chunk-P5QACQDK.js";
|
|
13
16
|
import {
|
|
14
|
-
agentRunCardLabels,
|
|
15
17
|
createCliLocalRuntimeAdapter,
|
|
16
18
|
detectCurrentMachineId,
|
|
17
|
-
getCliLocale,
|
|
18
19
|
isBuiltinNoloAgentRef,
|
|
19
20
|
isCliProviderAgentConfig,
|
|
21
|
+
isDockerRuntimeKey,
|
|
20
22
|
isLiveAgentRunObservation,
|
|
21
23
|
isMachineBoundLocalhostCustomProvider,
|
|
22
24
|
isSubtaskRun,
|
|
@@ -24,151 +26,203 @@ import {
|
|
|
24
26
|
resolveAuthToken as resolveAuthToken2,
|
|
25
27
|
resolveBoundMachineId,
|
|
26
28
|
resolveFileWriteGateEnabled,
|
|
27
|
-
resolveLocalUserId
|
|
28
|
-
|
|
29
|
-
toolLabel,
|
|
30
|
-
toolLabelVariants
|
|
31
|
-
} from "./chunk-XYJSY4KG.js";
|
|
29
|
+
resolveLocalUserId
|
|
30
|
+
} from "./chunk-PKZKOVA5.js";
|
|
32
31
|
import {
|
|
33
32
|
clearCredentialAvailability,
|
|
34
33
|
readCredentialEntry,
|
|
35
34
|
recordCredentialProbe
|
|
36
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-6MXDOUMH.js";
|
|
37
36
|
import {
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
agentRunCardLabels,
|
|
38
|
+
getCliLocale,
|
|
39
|
+
t,
|
|
40
|
+
toolLabel,
|
|
41
|
+
toolLabelVariants
|
|
42
|
+
} from "./chunk-SW4S4XYB.js";
|
|
40
43
|
import {
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
_appendEntityBatch,
|
|
45
|
+
_appendEvidenceBatch,
|
|
46
|
+
_appendRelationBatch,
|
|
47
|
+
_appendRetiredStateBatch,
|
|
48
|
+
_appendStateBatch,
|
|
49
|
+
getMemoryEntityVNext,
|
|
50
|
+
getMemoryEvidenceVNext,
|
|
51
|
+
getMemoryEvidenceVNextStrict,
|
|
52
|
+
getMemoryStateVNext,
|
|
53
|
+
listMemoryStatesForEntityVNext,
|
|
54
|
+
loadMemoryVNextCatalog,
|
|
55
|
+
putMemoryEvidenceVNext
|
|
56
|
+
} from "./chunk-TY3TIUJK.js";
|
|
43
57
|
import {
|
|
44
58
|
readDbRecord,
|
|
45
59
|
resolveAgentRecordFromHybridStore
|
|
46
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-ZF6526IQ.js";
|
|
47
61
|
import {
|
|
48
62
|
isLocalCliAgentKey
|
|
49
|
-
} from "./chunk-
|
|
50
|
-
import {
|
|
51
|
-
extractGoogleValidationLink
|
|
52
|
-
} from "./chunk-BMQ2MJUK.js";
|
|
53
|
-
import {
|
|
54
|
-
createRunActivityTracker,
|
|
55
|
-
popSingleQueueMessage,
|
|
56
|
-
readRunRecord,
|
|
57
|
-
resolveRunQueuePath,
|
|
58
|
-
settleRunTerminalAuthoritatively,
|
|
59
|
-
spawnLocalBackgroundRun
|
|
60
|
-
} from "./chunk-CFT5HBGW.js";
|
|
61
|
-
import {
|
|
62
|
-
isCliAuthorityBrokerProtocolError,
|
|
63
|
-
isCliAuthorityBrokerTimeoutError,
|
|
64
|
-
isCliAuthorityBrokerUnavailableError
|
|
65
|
-
} from "./chunk-EXAJ6DCR.js";
|
|
66
|
-
import {
|
|
67
|
-
getDefaultCliLocalRuntimeDb
|
|
68
|
-
} from "./chunk-ZOVKKMF6.js";
|
|
63
|
+
} from "./chunk-NBTY7YJF.js";
|
|
69
64
|
import {
|
|
70
65
|
CliProviderQuotaError
|
|
71
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-VL5KOY2C.js";
|
|
67
|
+
import {
|
|
68
|
+
resolveMachineId
|
|
69
|
+
} from "./chunk-S73EPYNC.js";
|
|
72
70
|
import {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
} from "./chunk-LTRXGFMS.js";
|
|
71
|
+
extractGoogleValidationLink
|
|
72
|
+
} from "./chunk-BMQ2MJUK.js";
|
|
76
73
|
import {
|
|
77
|
-
|
|
78
|
-
} from "./chunk-
|
|
74
|
+
resolveCliLocalRuntimeKeyCapability
|
|
75
|
+
} from "./chunk-3T4ZG6AC.js";
|
|
79
76
|
import {
|
|
80
77
|
isTransientFetchError
|
|
81
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-I2ZMGXXF.js";
|
|
79
|
+
import {
|
|
80
|
+
parseUiCard,
|
|
81
|
+
uiCardFallback
|
|
82
|
+
} from "./chunk-ROCUB2H2.js";
|
|
82
83
|
import {
|
|
83
84
|
isGatewayHttpStatus
|
|
84
85
|
} from "./chunk-NF64D32W.js";
|
|
85
86
|
import {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
formatNotFoundRunCard,
|
|
89
|
-
formatStartRunCard,
|
|
90
|
-
formatStatusRunCard,
|
|
91
|
-
formatStopRunCard,
|
|
92
|
-
isAgentRunTerminalStatus
|
|
93
|
-
} from "./chunk-4JMDLJAD.js";
|
|
87
|
+
parsePositiveFiniteNumberOrFallback
|
|
88
|
+
} from "./chunk-XPWGOTBQ.js";
|
|
94
89
|
import {
|
|
95
90
|
buildMemorySubjectsForAgent,
|
|
96
91
|
chooseMemoryOwners,
|
|
97
92
|
loadMemoryCandidatesFromDb,
|
|
98
93
|
resolveAgentMemoryPolicy
|
|
99
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-AG7MCDLR.js";
|
|
100
95
|
import {
|
|
101
96
|
API_REPORTED_COST_MULTIPLIER,
|
|
102
97
|
parseUiAskChoiceContent
|
|
103
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-U5ICMAFV.js";
|
|
104
99
|
import {
|
|
105
100
|
isOAuthApiKeyRef
|
|
106
|
-
} from "./chunk-
|
|
107
|
-
import {
|
|
108
|
-
buildSkillDiscoveryContextLayer
|
|
109
|
-
} from "./chunk-5GVBDNTO.js";
|
|
101
|
+
} from "./chunk-UKZX3NHN.js";
|
|
110
102
|
import {
|
|
111
103
|
parseExternalSkillMarkdown,
|
|
112
104
|
parseSkillDocProtocol
|
|
113
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-XETG4RIX.js";
|
|
114
106
|
import {
|
|
115
107
|
LOCAL_AGENT_CONFIG_MISSING_CODE,
|
|
116
108
|
LOCAL_TURN_ABORTED_CODE,
|
|
117
109
|
readActionGate
|
|
118
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-AUIJZACN.js";
|
|
119
111
|
import {
|
|
112
|
+
devinChannelContextWindow,
|
|
120
113
|
resolveAgentRuntimeConfigFromRecord
|
|
121
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-UOKFKFPO.js";
|
|
115
|
+
import {
|
|
116
|
+
isDevinOAuthAgent
|
|
117
|
+
} from "./chunk-5ZUL4CUO.js";
|
|
122
118
|
import {
|
|
123
119
|
createThinkParserState,
|
|
124
120
|
flushThinkParser,
|
|
125
121
|
processThinkChunk
|
|
126
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-56GBUMO5.js";
|
|
123
|
+
import {
|
|
124
|
+
ATTACHMENT_PART_TYPE,
|
|
125
|
+
ATTACHMENT_PART_VERSION,
|
|
126
|
+
describeAttachmentForModel,
|
|
127
|
+
normalizeAttachmentPart
|
|
128
|
+
} from "./chunk-WJZOQR2J.js";
|
|
127
129
|
import {
|
|
130
|
+
PROBE_INTERVAL_MS,
|
|
128
131
|
QUOTA_ERROR_PATTERNS,
|
|
129
132
|
isQuotaExhaustedError,
|
|
130
133
|
isQuotaLimited403Body,
|
|
131
134
|
mergeAvailabilityDeadline,
|
|
132
135
|
resolveCooldownGate,
|
|
133
136
|
resolveCredentialKeyWithFallback
|
|
134
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-3MZAGMYY.js";
|
|
135
138
|
import {
|
|
136
|
-
isAntigravityOAuthAgent
|
|
137
|
-
} from "./chunk-S5XGT6GB.js";
|
|
138
|
-
import {
|
|
139
|
-
resolveClientVersion
|
|
140
|
-
} from "./chunk-27ONFIEY.js";
|
|
141
|
-
import {
|
|
142
|
-
DEFAULT_CONTEXT_WINDOW,
|
|
143
|
-
getModelContextWindow,
|
|
144
139
|
normalizeUsage
|
|
145
|
-
} from "./chunk-
|
|
140
|
+
} from "./chunk-6CCFTVBP.js";
|
|
141
|
+
import {
|
|
142
|
+
findModelContextWindow
|
|
143
|
+
} from "./chunk-BPMPOFWP.js";
|
|
146
144
|
import {
|
|
147
145
|
clipCompactText
|
|
148
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-5MMAK75Q.js";
|
|
149
147
|
import {
|
|
150
148
|
compactWhitespace
|
|
151
149
|
} from "./chunk-DWLEOOGR.js";
|
|
152
150
|
import {
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
normalizeRuntimeToolPolicyOverride,
|
|
152
|
+
resolveEffectiveRuntimeToolPolicy
|
|
153
|
+
} from "./chunk-LIQJTQRN.js";
|
|
154
|
+
import {
|
|
155
|
+
BUILTIN_NOLO_AGENT_KEY,
|
|
156
|
+
BUILTIN_NOLO_AGENT_NAME,
|
|
157
|
+
builtinAgentCatalogEntryById,
|
|
158
|
+
parseBuiltinPlatformAgentId
|
|
159
|
+
} from "./chunk-EZVK3N5L.js";
|
|
160
|
+
import {
|
|
161
|
+
parsePublicAgentId
|
|
162
|
+
} from "./chunk-M2EJHDJP.js";
|
|
163
|
+
import {
|
|
164
|
+
createMemoryKey,
|
|
165
|
+
ulid
|
|
166
|
+
} from "./chunk-5EMSBTQ6.js";
|
|
167
|
+
import {
|
|
168
|
+
isAntigravityOAuthAgent
|
|
169
|
+
} from "./chunk-XZNCX52W.js";
|
|
170
|
+
import {
|
|
171
|
+
createRunActivityTracker,
|
|
172
|
+
createShellApprovalChild,
|
|
173
|
+
getRunResultHeaderMeta,
|
|
174
|
+
popSingleQueueMessage,
|
|
175
|
+
readRunRecord,
|
|
176
|
+
recordRunResultHeaderMeta,
|
|
177
|
+
resolveResultServerMeta,
|
|
178
|
+
resolveRunQueuePath,
|
|
179
|
+
serverOriginForDialog,
|
|
180
|
+
settleRunTerminalAuthoritatively,
|
|
181
|
+
spawnLocalBackgroundRun
|
|
182
|
+
} from "./chunk-YVLQXTUB.js";
|
|
183
|
+
import {
|
|
184
|
+
formatAgentListCard,
|
|
185
|
+
formatFinishedRunCard,
|
|
186
|
+
formatListRunsCard,
|
|
187
|
+
formatNotFoundRunCard,
|
|
188
|
+
formatStartRunCard,
|
|
189
|
+
formatStatusRunCard,
|
|
190
|
+
formatStopRunCard,
|
|
191
|
+
isAgentRunTerminalStatus
|
|
192
|
+
} from "./chunk-PJNFNEJE.js";
|
|
193
|
+
import {
|
|
194
|
+
estimateTokenCount
|
|
195
|
+
} from "./chunk-PSCNXBYA.js";
|
|
196
|
+
import {
|
|
197
|
+
resolveClientVersion
|
|
198
|
+
} from "./chunk-K2AER7RX.js";
|
|
155
199
|
import {
|
|
156
200
|
findModelConfig
|
|
157
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-I4SN4NUQ.js";
|
|
158
202
|
import {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
203
|
+
asTrimmedString
|
|
204
|
+
} from "./chunk-3EUW3WEO.js";
|
|
205
|
+
import {
|
|
206
|
+
isCliAuthorityBrokerProtocolError,
|
|
207
|
+
isCliAuthorityBrokerTimeoutError,
|
|
208
|
+
isCliAuthorityBrokerUnavailableError
|
|
209
|
+
} from "./chunk-EXAJ6DCR.js";
|
|
210
|
+
import {
|
|
211
|
+
toErrorMessage
|
|
212
|
+
} from "./chunk-HNMXYYJR.js";
|
|
213
|
+
import {
|
|
214
|
+
getDefaultCliLocalRuntimeDb
|
|
215
|
+
} from "./chunk-FY4SDK2E.js";
|
|
165
216
|
import {
|
|
166
217
|
getLogger,
|
|
167
218
|
normalizeError
|
|
168
|
-
} from "./chunk-
|
|
219
|
+
} from "./chunk-EYLGAEB4.js";
|
|
169
220
|
import {
|
|
170
221
|
resolveAuthToken
|
|
171
222
|
} from "./chunk-A7GB5UGH.js";
|
|
223
|
+
import {
|
|
224
|
+
asOptionalTrimmedString
|
|
225
|
+
} from "./chunk-G3SUCT4W.js";
|
|
172
226
|
import {
|
|
173
227
|
readPipeText,
|
|
174
228
|
spawnProcess
|
|
@@ -177,34 +231,242 @@ import {
|
|
|
177
231
|
CLIENT_VERSION_TOO_OLD_CODE,
|
|
178
232
|
NOLO_CLIENT_VERSION_HEADER,
|
|
179
233
|
buildClientVersionUpgradeMessage
|
|
180
|
-
} from "./chunk-
|
|
181
|
-
import {
|
|
182
|
-
parsePositiveFiniteNumberOrFallback
|
|
183
|
-
} from "./chunk-Y5GCAMGP.js";
|
|
184
|
-
import {
|
|
185
|
-
createMemoryKey,
|
|
186
|
-
ulid
|
|
187
|
-
} from "./chunk-3AH7LNUB.js";
|
|
234
|
+
} from "./chunk-CHCS6XPJ.js";
|
|
188
235
|
import {
|
|
189
236
|
asTrimmedLowercaseString
|
|
190
237
|
} from "./chunk-QSJ3HFEF.js";
|
|
191
238
|
import {
|
|
192
|
-
|
|
193
|
-
} from "./chunk-
|
|
194
|
-
import {
|
|
195
|
-
BUILTIN_NOLO_AGENT_KEY,
|
|
196
|
-
BUILTIN_NOLO_AGENT_NAME,
|
|
197
|
-
builtinAgentCatalogEntryById
|
|
198
|
-
} from "./chunk-BNGW5ASC.js";
|
|
199
|
-
import {
|
|
200
|
-
parsePublicAgentId
|
|
201
|
-
} from "./chunk-M2EJHDJP.js";
|
|
202
|
-
import {
|
|
203
|
-
asTrimmedString
|
|
204
|
-
} from "./chunk-3EUW3WEO.js";
|
|
239
|
+
buildSkillDiscoveryContextLayer
|
|
240
|
+
} from "./chunk-AU7AXHUL.js";
|
|
205
241
|
import {
|
|
206
|
-
|
|
207
|
-
|
|
242
|
+
buildAgentsMdLayer,
|
|
243
|
+
buildMemoryOverlayLayer,
|
|
244
|
+
buildMemoryUseGuidanceLayer,
|
|
245
|
+
partitionScopedBlocks,
|
|
246
|
+
renderTurnContextBlocksWithScope
|
|
247
|
+
} from "./chunk-VEA7H5FG.js";
|
|
248
|
+
|
|
249
|
+
// packages/agent-runtime/modelLayerOverride.ts
|
|
250
|
+
var MODEL_LAYER_KEYS = [
|
|
251
|
+
"provider",
|
|
252
|
+
"model",
|
|
253
|
+
"apiSource",
|
|
254
|
+
"cliProvider",
|
|
255
|
+
"useServerProxy",
|
|
256
|
+
"apiKey",
|
|
257
|
+
"apiKeyRef",
|
|
258
|
+
"apiKeyHeader",
|
|
259
|
+
"customProviderUrl",
|
|
260
|
+
"credentialRef",
|
|
261
|
+
"credentialSynced",
|
|
262
|
+
"temperature",
|
|
263
|
+
"top_p",
|
|
264
|
+
"frequency_penalty",
|
|
265
|
+
"presence_penalty",
|
|
266
|
+
"max_tokens",
|
|
267
|
+
"reasoning_effort",
|
|
268
|
+
"enableThinking",
|
|
269
|
+
"thinkingBudget"
|
|
270
|
+
];
|
|
271
|
+
function mergeReferences(base, extra) {
|
|
272
|
+
const safeBase = Array.isArray(base) ? base : [];
|
|
273
|
+
const safeExtra = Array.isArray(extra) ? extra : [];
|
|
274
|
+
const seen = /* @__PURE__ */ new Set();
|
|
275
|
+
const merged = [];
|
|
276
|
+
for (const item of [...safeBase, ...safeExtra]) {
|
|
277
|
+
const key = item?.dbKey;
|
|
278
|
+
if (key && seen.has(key)) continue;
|
|
279
|
+
if (key) seen.add(key);
|
|
280
|
+
if (item) merged.push(item);
|
|
281
|
+
}
|
|
282
|
+
return merged;
|
|
283
|
+
}
|
|
284
|
+
var asNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
285
|
+
function buildModelLayerOverride(agent) {
|
|
286
|
+
if (!agent || !asNonEmptyString(agent.provider) || !asNonEmptyString(agent.model)) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
const override = {
|
|
290
|
+
provider: agent.provider,
|
|
291
|
+
model: agent.model
|
|
292
|
+
};
|
|
293
|
+
for (const key of MODEL_LAYER_KEYS) {
|
|
294
|
+
if (key === "provider" || key === "model") continue;
|
|
295
|
+
const value = agent[key];
|
|
296
|
+
if (value !== void 0) {
|
|
297
|
+
override[key] = value;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (Array.isArray(agent.references) && agent.references.length > 0) {
|
|
301
|
+
override.references = agent.references;
|
|
302
|
+
}
|
|
303
|
+
return override;
|
|
304
|
+
}
|
|
305
|
+
function applyModelLayerOverride(base, override) {
|
|
306
|
+
const next = { ...base };
|
|
307
|
+
for (const key of MODEL_LAYER_KEYS) {
|
|
308
|
+
delete next[key];
|
|
309
|
+
}
|
|
310
|
+
for (const key of MODEL_LAYER_KEYS) {
|
|
311
|
+
const value = override[key];
|
|
312
|
+
if (value !== void 0) {
|
|
313
|
+
next[key] = value;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const merged = mergeReferences(
|
|
317
|
+
base.references,
|
|
318
|
+
override.references
|
|
319
|
+
);
|
|
320
|
+
if (merged.length > 0) {
|
|
321
|
+
next.references = merged;
|
|
322
|
+
} else {
|
|
323
|
+
delete next.references;
|
|
324
|
+
}
|
|
325
|
+
return next;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// packages/cli/tui/localAttachmentParts.ts
|
|
329
|
+
import { statSync } from "node:fs";
|
|
330
|
+
import path from "node:path";
|
|
331
|
+
var EXT_MIME = {
|
|
332
|
+
jpg: "image/jpeg",
|
|
333
|
+
jpeg: "image/jpeg",
|
|
334
|
+
png: "image/png",
|
|
335
|
+
gif: "image/gif",
|
|
336
|
+
webp: "image/webp",
|
|
337
|
+
bmp: "image/bmp",
|
|
338
|
+
tif: "image/tiff",
|
|
339
|
+
tiff: "image/tiff",
|
|
340
|
+
heic: "image/heic",
|
|
341
|
+
heif: "image/heif",
|
|
342
|
+
svg: "image/svg+xml",
|
|
343
|
+
mp3: "audio/mpeg",
|
|
344
|
+
m4a: "audio/mp4",
|
|
345
|
+
wav: "audio/wav",
|
|
346
|
+
ogg: "audio/ogg",
|
|
347
|
+
oga: "audio/ogg",
|
|
348
|
+
opus: "audio/opus",
|
|
349
|
+
flac: "audio/flac",
|
|
350
|
+
aac: "audio/aac",
|
|
351
|
+
amr: "audio/amr",
|
|
352
|
+
wma: "audio/x-ms-wma",
|
|
353
|
+
mp4: "video/mp4",
|
|
354
|
+
m4v: "video/x-m4v",
|
|
355
|
+
mov: "video/quicktime",
|
|
356
|
+
mkv: "video/x-matroska",
|
|
357
|
+
webm: "video/webm",
|
|
358
|
+
avi: "video/x-msvideo",
|
|
359
|
+
wmv: "video/x-ms-wmv",
|
|
360
|
+
mpg: "video/mpeg",
|
|
361
|
+
mpeg: "video/mpeg",
|
|
362
|
+
"3gp": "video/3gpp",
|
|
363
|
+
flv: "video/x-flv",
|
|
364
|
+
pdf: "application/pdf",
|
|
365
|
+
txt: "text/plain",
|
|
366
|
+
md: "text/markdown",
|
|
367
|
+
json: "application/json",
|
|
368
|
+
csv: "text/csv",
|
|
369
|
+
zip: "application/zip",
|
|
370
|
+
apk: "application/vnd.android.package-archive"
|
|
371
|
+
};
|
|
372
|
+
var mimeTypeForLocalPath = (filePath) => {
|
|
373
|
+
const ext = path.extname(filePath).slice(1).toLowerCase();
|
|
374
|
+
return EXT_MIME[ext] ?? "application/octet-stream";
|
|
375
|
+
};
|
|
376
|
+
var defaultStatSize = (filePath) => {
|
|
377
|
+
try {
|
|
378
|
+
const stat = statSync(filePath);
|
|
379
|
+
return stat.isFile() ? stat.size : null;
|
|
380
|
+
} catch {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
var buildLocalAttachments = (input) => {
|
|
385
|
+
const machineId = typeof input.machineId === "string" ? input.machineId.trim() : "";
|
|
386
|
+
const workspaceRoot = typeof input.workspaceRoot === "string" ? input.workspaceRoot.trim() : "";
|
|
387
|
+
const statSize = input.statSize ?? defaultStatSize;
|
|
388
|
+
const mimeTypeOf = input.mimeTypeOf ?? mimeTypeForLocalPath;
|
|
389
|
+
const parts = [];
|
|
390
|
+
const skipped = [];
|
|
391
|
+
const seen = /* @__PURE__ */ new Set();
|
|
392
|
+
for (const raw of input.paths) {
|
|
393
|
+
const filePath = typeof raw === "string" ? raw.trim() : "";
|
|
394
|
+
if (!filePath || seen.has(filePath)) continue;
|
|
395
|
+
seen.add(filePath);
|
|
396
|
+
if (!machineId) {
|
|
397
|
+
skipped.push({ path: filePath, reason: "machine-unbound" });
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
const size = statSize(filePath);
|
|
401
|
+
if (size === null || !Number.isFinite(size) || size < 0) {
|
|
402
|
+
skipped.push({ path: filePath, reason: "unreadable" });
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const normalized = normalizeAttachmentPart({
|
|
406
|
+
type: ATTACHMENT_PART_TYPE,
|
|
407
|
+
v: ATTACHMENT_PART_VERSION,
|
|
408
|
+
source: {
|
|
409
|
+
kind: "local-file",
|
|
410
|
+
path: filePath,
|
|
411
|
+
machineId,
|
|
412
|
+
...workspaceRoot ? { workspaceRoot } : {}
|
|
413
|
+
},
|
|
414
|
+
name: path.basename(filePath),
|
|
415
|
+
mimeType: mimeTypeOf(filePath),
|
|
416
|
+
size
|
|
417
|
+
});
|
|
418
|
+
if (normalized.status !== "valid") {
|
|
419
|
+
skipped.push({ path: filePath, reason: "invalid-part" });
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
parts.push(normalized.attachment);
|
|
423
|
+
}
|
|
424
|
+
const cardText = parts.map((part) => describeAttachmentForModel(part)).join("\n");
|
|
425
|
+
return { parts, skipped, cardText };
|
|
426
|
+
};
|
|
427
|
+
var appendAttachmentCard = (message, cardText) => {
|
|
428
|
+
if (!cardText) return message;
|
|
429
|
+
return message.trim() ? `${message}
|
|
430
|
+
|
|
431
|
+
${cardText}` : cardText;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
// packages/chat/messages/attachmentWriteRollout.ts
|
|
435
|
+
var ENABLE_REMOTE_ATTACHMENT_PART_WRITES = false;
|
|
436
|
+
|
|
437
|
+
// packages/ai/context/contextOccupancy.ts
|
|
438
|
+
function estimateMessagesTokens(messages) {
|
|
439
|
+
return messages.reduce((total, message) => {
|
|
440
|
+
const content = typeof message.content === "string" ? message.content : message.content == null ? "" : JSON.stringify(message.content);
|
|
441
|
+
return total + estimateTokenCount(content) + 4;
|
|
442
|
+
}, 0);
|
|
443
|
+
}
|
|
444
|
+
function historyTokensBeforeLatestAssistant(messages) {
|
|
445
|
+
const total = estimateMessagesTokens(messages);
|
|
446
|
+
const latest = messages[messages.length - 1];
|
|
447
|
+
if (latest?.role !== "assistant") return total;
|
|
448
|
+
return Math.max(0, total - estimateMessagesTokens([latest]));
|
|
449
|
+
}
|
|
450
|
+
function resolveOccupancy(input) {
|
|
451
|
+
if (input.authoritativeInput !== void 0 && input.authoritativeInput > 0) {
|
|
452
|
+
const generated = Math.max(0, input.generatedSinceAuthority ?? 0);
|
|
453
|
+
return {
|
|
454
|
+
tokens: input.authoritativeInput + generated,
|
|
455
|
+
estimated: generated > 0
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
return {
|
|
459
|
+
tokens: Math.max(0, input.baselineEstimate ?? 0),
|
|
460
|
+
estimated: true
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
function resolveOccupancyWindow(ref) {
|
|
464
|
+
if (!ref.model) return void 0;
|
|
465
|
+
if (isDevinOAuthAgent(ref)) {
|
|
466
|
+
return devinChannelContextWindow(ref.model) ?? findModelContextWindow(ref.model, ref.provider);
|
|
467
|
+
}
|
|
468
|
+
return findModelContextWindow(ref.model, ref.provider);
|
|
469
|
+
}
|
|
208
470
|
|
|
209
471
|
// packages/cli/client/tokenUsage.ts
|
|
210
472
|
var PLATFORM_CREDIT_UNIT = "credits";
|
|
@@ -216,7 +478,9 @@ function resolveEffectiveModel(opts) {
|
|
|
216
478
|
if (isUsableModelId(opts.model)) return opts.model;
|
|
217
479
|
const agentKey = opts.agentKey?.trim();
|
|
218
480
|
if (!agentKey) return void 0;
|
|
219
|
-
return builtinAgentCatalogEntryById(
|
|
481
|
+
return builtinAgentCatalogEntryById(
|
|
482
|
+
parseBuiltinPlatformAgentId(agentKey) ?? parsePublicAgentId(agentKey)
|
|
483
|
+
)?.model;
|
|
220
484
|
}
|
|
221
485
|
function resolveAgentModelIdentity(opts) {
|
|
222
486
|
const model = resolveEffectiveModel(opts);
|
|
@@ -229,11 +493,32 @@ function resolveAgentModelIdentity(opts) {
|
|
|
229
493
|
}
|
|
230
494
|
function resolveAgentContextWindow(opts) {
|
|
231
495
|
const model = resolveEffectiveModel(opts);
|
|
232
|
-
if (model) return
|
|
233
|
-
|
|
234
|
-
|
|
496
|
+
if (model) return resolveContextWindow(model);
|
|
497
|
+
const byName = opts.agentName?.trim() ? resolveOccupancyWindow({ model: opts.agentName }) : void 0;
|
|
498
|
+
if (byName !== void 0) return byName;
|
|
499
|
+
const candidates = [
|
|
500
|
+
...modelSlugCandidates(opts.agentKey, 2),
|
|
501
|
+
...modelSlugCandidates(opts.agentName, 1)
|
|
502
|
+
];
|
|
503
|
+
for (const candidate of candidates) {
|
|
504
|
+
const window = resolveOccupancyWindow({ model: candidate });
|
|
505
|
+
if (window !== void 0) return window;
|
|
506
|
+
}
|
|
507
|
+
return void 0;
|
|
508
|
+
}
|
|
509
|
+
var AGENT_KEY_PREFIX = /^agent-[a-z0-9]+-/i;
|
|
510
|
+
function modelSlugCandidates(source, maxDrop) {
|
|
511
|
+
const raw = source?.trim();
|
|
512
|
+
if (!raw) return [];
|
|
513
|
+
const base = raw.replace(/\s+/g, "-").toLowerCase();
|
|
514
|
+
const seed = base.replace(AGENT_KEY_PREFIX, "");
|
|
515
|
+
const out = [seed];
|
|
516
|
+
if (seed !== base) out.push(base);
|
|
517
|
+
const segments = seed.split("-");
|
|
518
|
+
for (let drop = 1; drop <= maxDrop && drop < segments.length; drop++) {
|
|
519
|
+
out.push(segments.slice(drop).join("-"));
|
|
235
520
|
}
|
|
236
|
-
return
|
|
521
|
+
return [...new Set(out.filter(Boolean))];
|
|
237
522
|
}
|
|
238
523
|
var PROVIDER_LOOKUP_ORDER = [
|
|
239
524
|
"openrouter",
|
|
@@ -271,7 +556,7 @@ function resolveContextWindow(model) {
|
|
|
271
556
|
const config = findModelConfig(provider, raw);
|
|
272
557
|
if (config?.contextWindow) return config.contextWindow;
|
|
273
558
|
}
|
|
274
|
-
return
|
|
559
|
+
return resolveOccupancyWindow({ model: raw });
|
|
275
560
|
}
|
|
276
561
|
function buildTurnTokenUsage(usage, model) {
|
|
277
562
|
const parsed = parseUsageRecord(usage);
|
|
@@ -324,11 +609,66 @@ function formatTokenCount(value) {
|
|
|
324
609
|
const compact = value / 1e6;
|
|
325
610
|
return compact >= 100 ? `${Math.round(compact)}M` : `${compact.toFixed(1).replace(/\.0$/, "")}M`;
|
|
326
611
|
}
|
|
327
|
-
function
|
|
328
|
-
if (
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
612
|
+
function resolveAuthorityTurnCount(turns) {
|
|
613
|
+
if (turns.length === 0) return 0;
|
|
614
|
+
const latest = turns[turns.length - 1];
|
|
615
|
+
if (latest?.role === "assistant") {
|
|
616
|
+
return Math.max(0, turns.length - 1);
|
|
617
|
+
}
|
|
618
|
+
return turns.length;
|
|
619
|
+
}
|
|
620
|
+
function computeBaselineContextTokens(options) {
|
|
621
|
+
const { authoritativeInput, lastAuthorityTurnCount, turns, fallbackEstimate } = options;
|
|
622
|
+
if (authoritativeInput !== void 0 && authoritativeInput > 0 && lastAuthorityTurnCount !== void 0 && lastAuthorityTurnCount >= 0) {
|
|
623
|
+
const turnsSinceAuthority = turns.slice(lastAuthorityTurnCount);
|
|
624
|
+
const addedTokens = estimateMessagesTokens(turnsSinceAuthority);
|
|
625
|
+
return authoritativeInput + addedTokens;
|
|
626
|
+
}
|
|
627
|
+
return typeof fallbackEstimate === "function" ? fallbackEstimate() : fallbackEstimate;
|
|
628
|
+
}
|
|
629
|
+
function resolveContextUsage(opts = {}) {
|
|
630
|
+
const tokens = opts.tokens;
|
|
631
|
+
const contextWindow = tokens?.contextWindow ?? opts.fallbackContextWindow;
|
|
632
|
+
const authoritativeInput = tokens && tokens.input > 0 ? tokens.input : void 0;
|
|
633
|
+
const baselineEstimate = opts.estimatedContextTokens != null && opts.estimatedContextTokens > 0 ? opts.estimatedContextTokens : void 0;
|
|
634
|
+
const generatedSinceAuthority = opts.turnEstimatedTokens != null && opts.turnEstimatedTokens > 0 ? opts.turnEstimatedTokens : void 0;
|
|
635
|
+
const occupancy = resolveOccupancy({
|
|
636
|
+
authoritativeInput,
|
|
637
|
+
baselineEstimate: authoritativeInput === void 0 && baselineEstimate !== void 0 ? baselineEstimate + (generatedSinceAuthority ?? 0) : baselineEstimate,
|
|
638
|
+
generatedSinceAuthority
|
|
639
|
+
});
|
|
640
|
+
const hasInputSignal = authoritativeInput !== void 0 || baselineEstimate !== void 0 || generatedSinceAuthority !== void 0;
|
|
641
|
+
const used = hasInputSignal ? occupancy.tokens : void 0;
|
|
642
|
+
const usage = { estimated: occupancy.estimated };
|
|
643
|
+
if (used !== void 0) usage.used = used;
|
|
644
|
+
if (contextWindow != null) usage.contextWindow = contextWindow;
|
|
645
|
+
if (used !== void 0 && contextWindow != null && contextWindow > 0) {
|
|
646
|
+
usage.left = Math.max(0, contextWindow - used);
|
|
647
|
+
usage.pct = used / contextWindow * 100;
|
|
648
|
+
}
|
|
649
|
+
return usage;
|
|
650
|
+
}
|
|
651
|
+
function renderTokenStatus(tokens, fallback) {
|
|
652
|
+
const usage = resolveContextUsage({
|
|
653
|
+
tokens,
|
|
654
|
+
fallbackContextWindow: fallback?.contextWindow,
|
|
655
|
+
estimatedContextTokens: fallback?.estimatedContextTokens,
|
|
656
|
+
turnEstimatedTokens: fallback?.turnEstimatedTokens
|
|
657
|
+
});
|
|
658
|
+
const cache = tokens?.cacheRead != null && tokens.cacheRead > 0 ? ` (cache ${formatTokenCount(tokens.cacheRead)})` : "";
|
|
659
|
+
if (usage.contextWindow === void 0) {
|
|
660
|
+
const inStr = usage.used !== void 0 ? `${usage.estimated ? "~" : ""}${formatTokenCount(usage.used)}` : "\u2014";
|
|
661
|
+
const outStr = tokens ? formatTokenCount(tokens.output) : "\u2014";
|
|
662
|
+
return `in ${inStr}${cache} out ${outStr} left \u2014`;
|
|
663
|
+
}
|
|
664
|
+
if (!tokens) {
|
|
665
|
+
if (usage.used === void 0) return "in \u2014 out \u2014 left \u2014";
|
|
666
|
+
const left2 = usage.left !== void 0 ? `~${formatTokenCount(usage.left)}` : "\u2014";
|
|
667
|
+
return `in ~${formatTokenCount(usage.used)} out \u2014 left ${left2}`;
|
|
668
|
+
}
|
|
669
|
+
const inputText = tokens.input > 0 || usage.used === void 0 ? formatTokenCount(tokens.input) : `~${formatTokenCount(usage.used)}`;
|
|
670
|
+
const left = tokens.remaining != null ? formatTokenCount(tokens.remaining) : usage.left !== void 0 ? `${usage.estimated ? "~" : ""}${formatTokenCount(usage.left)}` : "\u2014";
|
|
671
|
+
return `in ${inputText}${cache} out ${formatTokenCount(tokens.output)} left ${left}`;
|
|
332
672
|
}
|
|
333
673
|
function shouldShowUsage(env) {
|
|
334
674
|
return env.NOLO_DEBUG === "1" || env.NOLO_SHOW_USAGE === "1";
|
|
@@ -1013,11 +1353,17 @@ function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSou
|
|
|
1013
1353
|
activeStyles.push(value);
|
|
1014
1354
|
}
|
|
1015
1355
|
};
|
|
1356
|
+
let lastContentTokenIndex = -1;
|
|
1357
|
+
for (let i = tokens.length - 1; i >= 0; i -= 1) {
|
|
1358
|
+
if (tokens[i].kind !== "sgr") {
|
|
1359
|
+
lastContentTokenIndex = i;
|
|
1360
|
+
break;
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
let plainCharIndexAtStart = 0;
|
|
1016
1364
|
let start = 0;
|
|
1017
1365
|
while (start < tokens.length) {
|
|
1018
|
-
if (
|
|
1019
|
-
if (rows.length > 0) break;
|
|
1020
|
-
}
|
|
1366
|
+
if (start > lastContentTokenIndex && rows.length > 0) break;
|
|
1021
1367
|
const openingStyles = [...activeStyles];
|
|
1022
1368
|
const isContinuation = rows.length > 0;
|
|
1023
1369
|
const currentPrefixWidth = isContinuation ? visibleWidth(hangingIndent) : prefixWidth;
|
|
@@ -1065,13 +1411,7 @@ function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSou
|
|
|
1065
1411
|
let segSourceEnd = lineSourceStart;
|
|
1066
1412
|
let foundFirst = false;
|
|
1067
1413
|
const rowMapping = [];
|
|
1068
|
-
let plainCharIndex =
|
|
1069
|
-
for (let i = 0; i < start; i++) {
|
|
1070
|
-
const tok = tokens[i];
|
|
1071
|
-
if (tok.kind === "char" && tok.charIndex >= prefixCharCount) {
|
|
1072
|
-
plainCharIndex += tok.value.length;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1414
|
+
let plainCharIndex = plainCharIndexAtStart;
|
|
1075
1415
|
for (let i = start; i < segmentEnd; i++) {
|
|
1076
1416
|
const tok = tokens[i];
|
|
1077
1417
|
if (tok.kind === "char" && tok.charIndex >= prefixCharCount) {
|
|
@@ -1108,6 +1448,7 @@ function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSou
|
|
|
1108
1448
|
if (start >= tokens.length && rawLineLength !== void 0) {
|
|
1109
1449
|
segSourceEnd = lineSourceStart + rawLineLength;
|
|
1110
1450
|
}
|
|
1451
|
+
plainCharIndexAtStart = plainCharIndex;
|
|
1111
1452
|
rows.push({
|
|
1112
1453
|
rendered: rowRendered,
|
|
1113
1454
|
sourceStart: segSourceStart,
|
|
@@ -1527,6 +1868,19 @@ function surfaceBackgroundSequence(env = process.env, brightness = resolveTuiBri
|
|
|
1527
1868
|
if (!supportsTruecolor(env)) return "";
|
|
1528
1869
|
return hexToBgSgr((SURFACE_HEX[activeThemeName] ?? SURFACE_HEX.trail)[brightness]);
|
|
1529
1870
|
}
|
|
1871
|
+
function composerSurfaceBackgroundSequence(env = process.env, brightness = resolveTuiBrightness(env)) {
|
|
1872
|
+
if (!supportsTruecolor(env)) return "";
|
|
1873
|
+
if (resolveTuiThemeMode(env) === "terminal" && activeTerminalBaseHex === null && detectColorFgBgBrightness(env) === null) {
|
|
1874
|
+
return "";
|
|
1875
|
+
}
|
|
1876
|
+
const base = resolveTerminalBaseHex(brightness);
|
|
1877
|
+
const channels = readHexChannels(base.replace(/^#/, "").toUpperCase());
|
|
1878
|
+
const baseLuma = channels ? (0.299 * channels[0] + 0.587 * channels[1] + 0.114 * channels[2]) / 255 : null;
|
|
1879
|
+
const darkCanvas = baseLuma === null ? brightness === "dark" : baseLuma < 0.5;
|
|
1880
|
+
const tint = darkCanvas ? "FFFFFF" : "000000";
|
|
1881
|
+
const weight = darkCanvas ? 0.1 : 0.07;
|
|
1882
|
+
return hexToBgSgr(blendHex(tint, base, weight));
|
|
1883
|
+
}
|
|
1530
1884
|
function userSurfaceBackgroundSequence(env = process.env, brightness = resolveTuiBrightness(env)) {
|
|
1531
1885
|
if (!supportsTruecolor(env)) return "";
|
|
1532
1886
|
if (resolveTuiThemeMode(env) === "terminal" && activeTerminalBaseHex === null && detectColorFgBgBrightness(env) === null) {
|
|
@@ -8462,6 +8816,68 @@ function styleRichMarkdownLine(line, brightness) {
|
|
|
8462
8816
|
}
|
|
8463
8817
|
return styleInlineMarkdown(line, brightness);
|
|
8464
8818
|
}
|
|
8819
|
+
var FenceTracker = class {
|
|
8820
|
+
inFence = false;
|
|
8821
|
+
inMermaid = false;
|
|
8822
|
+
fenceLang = "unknown";
|
|
8823
|
+
mermaidBody = [];
|
|
8824
|
+
isInFence() {
|
|
8825
|
+
return this.inFence;
|
|
8826
|
+
}
|
|
8827
|
+
isInMermaid() {
|
|
8828
|
+
return this.inMermaid;
|
|
8829
|
+
}
|
|
8830
|
+
processLine(line) {
|
|
8831
|
+
if (isCodeFenceLine(line)) {
|
|
8832
|
+
if (this.inMermaid) {
|
|
8833
|
+
const body = this.mermaidBody;
|
|
8834
|
+
this.mermaidBody = [];
|
|
8835
|
+
this.inMermaid = false;
|
|
8836
|
+
this.inFence = false;
|
|
8837
|
+
this.fenceLang = "unknown";
|
|
8838
|
+
return { kind: "close-mermaid", body };
|
|
8839
|
+
}
|
|
8840
|
+
if (this.inFence) {
|
|
8841
|
+
this.inFence = false;
|
|
8842
|
+
this.fenceLang = "unknown";
|
|
8843
|
+
return { kind: "close-code" };
|
|
8844
|
+
}
|
|
8845
|
+
const lang = readFenceLanguage(line);
|
|
8846
|
+
this.fenceLang = normalizeCodeLang(lang);
|
|
8847
|
+
this.inFence = true;
|
|
8848
|
+
if (/^mermaid$/i.test(lang)) {
|
|
8849
|
+
this.inMermaid = true;
|
|
8850
|
+
this.mermaidBody = [];
|
|
8851
|
+
return { kind: "open" };
|
|
8852
|
+
}
|
|
8853
|
+
return { kind: "open" };
|
|
8854
|
+
}
|
|
8855
|
+
if (this.inMermaid) {
|
|
8856
|
+
this.mermaidBody.push(line);
|
|
8857
|
+
return { kind: "mermaid-body" };
|
|
8858
|
+
}
|
|
8859
|
+
if (this.inFence) {
|
|
8860
|
+
return { kind: "code-line", lang: this.fenceLang };
|
|
8861
|
+
}
|
|
8862
|
+
return { kind: "outside" };
|
|
8863
|
+
}
|
|
8864
|
+
/**
|
|
8865
|
+
* Take unclosed mermaid body lines if currently inside a mermaid block.
|
|
8866
|
+
* Resets mermaid and fence state. Returns null if not in a mermaid block.
|
|
8867
|
+
*/
|
|
8868
|
+
flushMermaid(extraLines) {
|
|
8869
|
+
if (!this.inMermaid) return null;
|
|
8870
|
+
if (extraLines && extraLines.length > 0) {
|
|
8871
|
+
this.mermaidBody.push(...extraLines);
|
|
8872
|
+
}
|
|
8873
|
+
const body = this.mermaidBody;
|
|
8874
|
+
this.mermaidBody = [];
|
|
8875
|
+
this.inMermaid = false;
|
|
8876
|
+
this.inFence = false;
|
|
8877
|
+
this.fenceLang = "unknown";
|
|
8878
|
+
return body;
|
|
8879
|
+
}
|
|
8880
|
+
};
|
|
8465
8881
|
function renderMermaidBody(bodyLines, brightness) {
|
|
8466
8882
|
const body = bodyLines.join("\n");
|
|
8467
8883
|
const rendered = renderMermaidBlock(body, brightness, true);
|
|
@@ -8476,52 +8892,27 @@ function formatAssistantDisplay(text, options = {}) {
|
|
|
8476
8892
|
const lines = polished.split("\n");
|
|
8477
8893
|
const out = [];
|
|
8478
8894
|
let i = 0;
|
|
8479
|
-
|
|
8480
|
-
let fenceLang = "unknown";
|
|
8481
|
-
let inMermaid = false;
|
|
8482
|
-
let mermaidBody = null;
|
|
8483
|
-
const flushMermaid = () => {
|
|
8484
|
-
if (mermaidBody !== null) {
|
|
8485
|
-
out.push(renderMermaidBody(mermaidBody, brightness));
|
|
8486
|
-
mermaidBody = null;
|
|
8487
|
-
}
|
|
8488
|
-
};
|
|
8895
|
+
const tracker = new FenceTracker();
|
|
8489
8896
|
while (i < lines.length) {
|
|
8490
8897
|
const line = lines[i];
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
flushMermaid();
|
|
8495
|
-
inMermaid = false;
|
|
8496
|
-
inFence = false;
|
|
8497
|
-
out.push(`${STYLE.dim}${line}${STYLE.reset}`);
|
|
8498
|
-
i++;
|
|
8499
|
-
continue;
|
|
8500
|
-
}
|
|
8501
|
-
if (inFence) {
|
|
8502
|
-
fenceLang = "unknown";
|
|
8503
|
-
inFence = false;
|
|
8504
|
-
out.push(`${STYLE.dim}${line}${STYLE.reset}`);
|
|
8505
|
-
i++;
|
|
8506
|
-
continue;
|
|
8507
|
-
}
|
|
8508
|
-
inFence = true;
|
|
8509
|
-
fenceLang = normalizeCodeLang(lang);
|
|
8510
|
-
if (/^mermaid$/i.test(lang)) {
|
|
8511
|
-
inMermaid = true;
|
|
8512
|
-
mermaidBody = [];
|
|
8513
|
-
}
|
|
8898
|
+
const event = tracker.processLine(line);
|
|
8899
|
+
if (event.kind === "close-mermaid") {
|
|
8900
|
+
out.push(renderMermaidBody(event.body, brightness));
|
|
8514
8901
|
out.push(`${STYLE.dim}${line}${STYLE.reset}`);
|
|
8515
8902
|
i++;
|
|
8516
8903
|
continue;
|
|
8517
8904
|
}
|
|
8518
|
-
if (
|
|
8519
|
-
|
|
8905
|
+
if (event.kind === "open" || event.kind === "close-code") {
|
|
8906
|
+
out.push(`${STYLE.dim}${line}${STYLE.reset}`);
|
|
8520
8907
|
i++;
|
|
8521
8908
|
continue;
|
|
8522
8909
|
}
|
|
8523
|
-
if (
|
|
8524
|
-
|
|
8910
|
+
if (event.kind === "mermaid-body") {
|
|
8911
|
+
i++;
|
|
8912
|
+
continue;
|
|
8913
|
+
}
|
|
8914
|
+
if (event.kind === "code-line") {
|
|
8915
|
+
out.push(highlightCodeLine(line, event.lang, brightness));
|
|
8525
8916
|
i++;
|
|
8526
8917
|
continue;
|
|
8527
8918
|
}
|
|
@@ -8562,7 +8953,10 @@ function formatAssistantDisplay(text, options = {}) {
|
|
|
8562
8953
|
out.push(styleRichMarkdownLine(line, brightness));
|
|
8563
8954
|
i++;
|
|
8564
8955
|
}
|
|
8565
|
-
flushMermaid();
|
|
8956
|
+
const unclosed = tracker.flushMermaid();
|
|
8957
|
+
if (unclosed !== null) {
|
|
8958
|
+
out.push(renderMermaidBody(unclosed, brightness));
|
|
8959
|
+
}
|
|
8566
8960
|
return out.join("\n");
|
|
8567
8961
|
}
|
|
8568
8962
|
function emitFormattedAssistantBlock(write, text, trailingNewline = false) {
|
|
@@ -8598,10 +8992,7 @@ function needsListProseBreath(prev, next, prevLine = "") {
|
|
|
8598
8992
|
function createRenderAwareStreamWriter(args) {
|
|
8599
8993
|
const brightness = resolveTuiBrightness();
|
|
8600
8994
|
let buffer = "";
|
|
8601
|
-
|
|
8602
|
-
let fenceLang = "unknown";
|
|
8603
|
-
let inMermaid = false;
|
|
8604
|
-
let mermaidBody = [];
|
|
8995
|
+
const tracker = new FenceTracker();
|
|
8605
8996
|
let lastKind = null;
|
|
8606
8997
|
let lastLine = "";
|
|
8607
8998
|
let pendingBlankRow = false;
|
|
@@ -8615,7 +9006,7 @@ function createRenderAwareStreamWriter(args) {
|
|
|
8615
9006
|
if (needsListProseBreath(lastKind, nextKind, lastLine)) args.write("\n");
|
|
8616
9007
|
};
|
|
8617
9008
|
const flushPartialProse = () => {
|
|
8618
|
-
if (
|
|
9009
|
+
if (tracker.isInFence() || buffer.length < PARTIAL_FLUSH_THRESHOLD) return;
|
|
8619
9010
|
const firstLine = buffer.split("\n", 1)[0] ?? "";
|
|
8620
9011
|
if (isTableRow(firstLine) || classifyStreamLine(firstLine) !== "prose") return;
|
|
8621
9012
|
const Segmenter = Intl.Segmenter;
|
|
@@ -8638,34 +9029,19 @@ function createRenderAwareStreamWriter(args) {
|
|
|
8638
9029
|
const lines = buffer.split("\n");
|
|
8639
9030
|
if (lines.length < 2) break;
|
|
8640
9031
|
const firstLine = lines[0] ?? "";
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
inFence = false;
|
|
8648
|
-
fenceLang = "unknown";
|
|
8649
|
-
emitBreathIfNeeded("fence");
|
|
8650
|
-
args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
|
|
9032
|
+
const event = tracker.processLine(firstLine);
|
|
9033
|
+
if (event.kind === "close-mermaid") {
|
|
9034
|
+
const diagram = renderMermaidBody(event.body, brightness);
|
|
9035
|
+
args.write(diagram + "\n");
|
|
9036
|
+
emitBreathIfNeeded("fence");
|
|
9037
|
+
args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
|
|
8651
9038
|
`);
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
fenceLang = "unknown";
|
|
8659
|
-
inFence = false;
|
|
8660
|
-
} else {
|
|
8661
|
-
const lang = readFenceLanguage(firstLine);
|
|
8662
|
-
fenceLang = normalizeCodeLang(lang);
|
|
8663
|
-
if (/^mermaid$/i.test(lang)) {
|
|
8664
|
-
inMermaid = true;
|
|
8665
|
-
mermaidBody = [];
|
|
8666
|
-
}
|
|
8667
|
-
inFence = true;
|
|
8668
|
-
}
|
|
9039
|
+
lastKind = "fence";
|
|
9040
|
+
lastLine = firstLine;
|
|
9041
|
+
buffer = lines.slice(1).join("\n");
|
|
9042
|
+
continue;
|
|
9043
|
+
}
|
|
9044
|
+
if (event.kind === "open" || event.kind === "close-code") {
|
|
8669
9045
|
emitBreathIfNeeded("fence");
|
|
8670
9046
|
args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
|
|
8671
9047
|
`);
|
|
@@ -8674,13 +9050,12 @@ function createRenderAwareStreamWriter(args) {
|
|
|
8674
9050
|
buffer = lines.slice(1).join("\n");
|
|
8675
9051
|
continue;
|
|
8676
9052
|
}
|
|
8677
|
-
if (
|
|
8678
|
-
mermaidBody.push(firstLine);
|
|
9053
|
+
if (event.kind === "mermaid-body") {
|
|
8679
9054
|
buffer = lines.slice(1).join("\n");
|
|
8680
9055
|
continue;
|
|
8681
9056
|
}
|
|
8682
|
-
if (
|
|
8683
|
-
args.write(`${highlightCodeLine(firstLine,
|
|
9057
|
+
if (event.kind === "code-line") {
|
|
9058
|
+
args.write(`${highlightCodeLine(firstLine, event.lang, brightness)}
|
|
8684
9059
|
`);
|
|
8685
9060
|
lastKind = "fence";
|
|
8686
9061
|
lastLine = firstLine;
|
|
@@ -8688,7 +9063,7 @@ function createRenderAwareStreamWriter(args) {
|
|
|
8688
9063
|
continue;
|
|
8689
9064
|
}
|
|
8690
9065
|
const trimmedFirst = firstLine.trim();
|
|
8691
|
-
if ((trimmedFirst.startsWith("$$") || trimmedFirst.startsWith("\\[")) && !
|
|
9066
|
+
if ((trimmedFirst.startsWith("$$") || trimmedFirst.startsWith("\\[")) && !tracker.isInFence()) {
|
|
8692
9067
|
const isBracket = trimmedFirst.startsWith("\\[");
|
|
8693
9068
|
const closeMarker = isBracket ? "\\]" : "$$";
|
|
8694
9069
|
if (trimmedFirst.length > 2 && trimmedFirst.endsWith(closeMarker)) {
|
|
@@ -8772,16 +9147,17 @@ function createRenderAwareStreamWriter(args) {
|
|
|
8772
9147
|
flushPartialProse();
|
|
8773
9148
|
},
|
|
8774
9149
|
flush() {
|
|
8775
|
-
if (
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
9150
|
+
if (tracker.isInMermaid()) {
|
|
9151
|
+
const extra = buffer ? buffer.split("\n") : void 0;
|
|
9152
|
+
const unclosed = tracker.flushMermaid(extra);
|
|
9153
|
+
if (unclosed !== null) {
|
|
9154
|
+
args.write(renderMermaidBody(unclosed, brightness) + "\n");
|
|
9155
|
+
}
|
|
8780
9156
|
buffer = "";
|
|
8781
9157
|
return;
|
|
8782
9158
|
}
|
|
8783
9159
|
if (!buffer) return;
|
|
8784
|
-
if (
|
|
9160
|
+
if (tracker.isInFence()) {
|
|
8785
9161
|
args.write(buffer);
|
|
8786
9162
|
} else {
|
|
8787
9163
|
emitFormattedAssistantBlock(args.write, buffer);
|
|
@@ -8806,17 +9182,45 @@ function redactSecrets(text) {
|
|
|
8806
9182
|
);
|
|
8807
9183
|
}
|
|
8808
9184
|
|
|
8809
|
-
//
|
|
8810
|
-
var
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
9185
|
+
// packages/cli/tui/askTextSanitize.ts
|
|
9186
|
+
var ASK_SECRET_PLACEHOLDER = "\u27E8redacted\u27E9";
|
|
9187
|
+
var C0_C1_CONTROL_REGEX = /[\x00-\x1f\x7f-\x9f]/g;
|
|
9188
|
+
var NORMAL_GIST_SECRET_PATTERNS = [
|
|
9189
|
+
/\bbearer\s+[A-Za-z0-9._~+/=-]{8,}/i,
|
|
9190
|
+
/\bsk-(?:ant-)?(?:api)?[0-9a-zA-Z-]{10,}/,
|
|
9191
|
+
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{10,}/,
|
|
9192
|
+
/\bxox[baprs]-[A-Za-z0-9-]{10,}/
|
|
9193
|
+
];
|
|
9194
|
+
function withholdIfSecretLike(gist) {
|
|
9195
|
+
if (!gist) return "";
|
|
9196
|
+
if (findPotentialSecrets(gist).length > 0) return "";
|
|
9197
|
+
if (NORMAL_GIST_SECRET_PATTERNS.some((pattern) => pattern.test(gist))) return "";
|
|
9198
|
+
return gist;
|
|
9199
|
+
}
|
|
9200
|
+
function toText(value) {
|
|
9201
|
+
return typeof value === "string" ? value : String(value ?? "");
|
|
9202
|
+
}
|
|
9203
|
+
function cleanAskText(value) {
|
|
9204
|
+
return stripAnsi2(toText(value)).replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").replace(C0_C1_CONTROL_REGEX, "").replace(/\s+/g, " ").trim();
|
|
9205
|
+
}
|
|
9206
|
+
function safeAskText(value, max) {
|
|
9207
|
+
const cleaned = redactSecrets(cleanAskText(value));
|
|
9208
|
+
if (!cleaned) return "";
|
|
9209
|
+
const guarded = withholdIfSecretLike(cleaned) || ASK_SECRET_PLACEHOLDER;
|
|
9210
|
+
return max === void 0 ? guarded : clipCompactText(guarded, max, "\u2026");
|
|
9211
|
+
}
|
|
9212
|
+
|
|
9213
|
+
// node_modules/diff/libesm/diff/base.js
|
|
9214
|
+
var Diff = class {
|
|
9215
|
+
diff(oldStr, newStr, options = {}) {
|
|
9216
|
+
let callback;
|
|
9217
|
+
if (typeof options === "function") {
|
|
9218
|
+
callback = options;
|
|
9219
|
+
options = {};
|
|
9220
|
+
} else if ("callback" in options) {
|
|
9221
|
+
callback = options.callback;
|
|
9222
|
+
}
|
|
9223
|
+
const oldString = this.castInput(oldStr, options);
|
|
8820
9224
|
const newString = this.castInput(newStr, options);
|
|
8821
9225
|
const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
|
|
8822
9226
|
const newTokens = this.removeEmpty(this.tokenize(newString, options));
|
|
@@ -8906,16 +9310,16 @@ var Diff = class {
|
|
|
8906
9310
|
}
|
|
8907
9311
|
}
|
|
8908
9312
|
}
|
|
8909
|
-
addToPath(
|
|
8910
|
-
const last =
|
|
9313
|
+
addToPath(path2, added, removed, oldPosInc, options) {
|
|
9314
|
+
const last = path2.lastComponent;
|
|
8911
9315
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
8912
9316
|
return {
|
|
8913
|
-
oldPos:
|
|
9317
|
+
oldPos: path2.oldPos + oldPosInc,
|
|
8914
9318
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
8915
9319
|
};
|
|
8916
9320
|
} else {
|
|
8917
9321
|
return {
|
|
8918
|
-
oldPos:
|
|
9322
|
+
oldPos: path2.oldPos + oldPosInc,
|
|
8919
9323
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
8920
9324
|
};
|
|
8921
9325
|
}
|
|
@@ -9060,14 +9464,14 @@ function tokenize(value, options) {
|
|
|
9060
9464
|
import { homedir as osHomedir } from "node:os";
|
|
9061
9465
|
|
|
9062
9466
|
// packages/core/foldHomePath.ts
|
|
9063
|
-
function foldHomePath(
|
|
9064
|
-
if (!
|
|
9467
|
+
function foldHomePath(path2, home) {
|
|
9468
|
+
if (!path2) return path2;
|
|
9065
9469
|
if (home) {
|
|
9066
9470
|
const cleanHome = home.endsWith("/") ? home.slice(0, -1) : home;
|
|
9067
|
-
if (
|
|
9068
|
-
if (
|
|
9471
|
+
if (path2 === cleanHome) return "~";
|
|
9472
|
+
if (path2.startsWith(cleanHome + "/")) return `~${path2.slice(cleanHome.length)}`;
|
|
9069
9473
|
}
|
|
9070
|
-
return
|
|
9474
|
+
return path2.replace(/^(\/Users\/[^/]+|\/home\/[^/]+)(\/|$)/, "~$2");
|
|
9071
9475
|
}
|
|
9072
9476
|
|
|
9073
9477
|
// packages/cli/client/formatReadPathTree.ts
|
|
@@ -9094,10 +9498,10 @@ function clipPathAware(value, max = 72) {
|
|
|
9094
9498
|
if (filenameOnly.length <= max) return filenameOnly;
|
|
9095
9499
|
return clipCompactText(value, max, "\u2026");
|
|
9096
9500
|
}
|
|
9097
|
-
function formatHomePath(
|
|
9098
|
-
if (!
|
|
9501
|
+
function formatHomePath(path2, customHomedir) {
|
|
9502
|
+
if (!path2) return "";
|
|
9099
9503
|
const home = customHomedir || (typeof process !== "undefined" ? process.env?.HOME : void 0) || (typeof osHomedir === "function" ? osHomedir() : "");
|
|
9100
|
-
return foldHomePath(
|
|
9504
|
+
return foldHomePath(path2, home);
|
|
9101
9505
|
}
|
|
9102
9506
|
function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
9103
9507
|
const inputPath = rawPath || (typeof metadata?.path === "string" ? metadata.path : void 0) || (typeof metadata?.filePath === "string" ? metadata.filePath : void 0) || "file";
|
|
@@ -9117,10 +9521,10 @@ function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
|
9117
9521
|
const clippedPath = clipPathAware(formattedPath, 72);
|
|
9118
9522
|
return `${clippedPath}${rangePart}`;
|
|
9119
9523
|
}
|
|
9120
|
-
function formatSearchItemQuery(query,
|
|
9524
|
+
function formatSearchItemQuery(query, path2, customHomedir) {
|
|
9121
9525
|
let text = (query || "").trim();
|
|
9122
|
-
if (
|
|
9123
|
-
const formattedPath = formatHomePath(
|
|
9526
|
+
if (path2) {
|
|
9527
|
+
const formattedPath = formatHomePath(path2, customHomedir);
|
|
9124
9528
|
if (formattedPath) {
|
|
9125
9529
|
text = text ? `${text} in ${formattedPath}` : formattedPath;
|
|
9126
9530
|
}
|
|
@@ -9176,7 +9580,7 @@ function parseUiAskChoiceForCli(event) {
|
|
|
9176
9580
|
label: String(parsed.selected.label ?? "").trim(),
|
|
9177
9581
|
userMessage: String(parsed.selected.userMessage ?? "").trim()
|
|
9178
9582
|
} : void 0;
|
|
9179
|
-
const answers = Array.isArray(parsed.answers) ? parsed.answers : void 0;
|
|
9583
|
+
const answers = Array.isArray(parsed.answers) ? parsed.answers.filter((a) => Boolean(a && typeof a === "object")) : void 0;
|
|
9180
9584
|
const cancelled = Boolean(parsed.cancelled);
|
|
9181
9585
|
const resolved = Boolean(
|
|
9182
9586
|
event.metadata?.resolved || selected || cancelled || answers && answers.length > 0
|
|
@@ -9197,7 +9601,7 @@ function formatUiAskChoiceBlock(event, colorEnabled) {
|
|
|
9197
9601
|
if (!parsed) return null;
|
|
9198
9602
|
const lines = [];
|
|
9199
9603
|
lines.push("");
|
|
9200
|
-
const questionText = parsed.question
|
|
9604
|
+
const questionText = safeAskText(parsed.question, 200);
|
|
9201
9605
|
if (colorEnabled) {
|
|
9202
9606
|
lines.push(`${themeText("\u2753 ", "info", true)}${styleCliText(questionText, "cyan", true)}`);
|
|
9203
9607
|
} else {
|
|
@@ -9212,7 +9616,8 @@ function formatUiAskChoiceBlock(event, colorEnabled) {
|
|
|
9212
9616
|
return `${lines.join("\n")}
|
|
9213
9617
|
`;
|
|
9214
9618
|
}
|
|
9215
|
-
const
|
|
9619
|
+
const rawSelected = parsed.selected?.label || parsed.selected?.userMessage;
|
|
9620
|
+
const selectedLabel = rawSelected ? safeAskText(rawSelected, 160) : parsed.answers ? parsed.answers.map((a) => safeAskText(a.userMessage, 160)).filter(Boolean).join(", ") : "";
|
|
9216
9621
|
const marker = t("askChoiceHistorySelected");
|
|
9217
9622
|
const displayLabel = selectedLabel || "\u2014";
|
|
9218
9623
|
if (colorEnabled) {
|
|
@@ -9225,8 +9630,9 @@ function formatUiAskChoiceBlock(event, colorEnabled) {
|
|
|
9225
9630
|
if (parsed.answers && parsed.answers.length > 1) {
|
|
9226
9631
|
for (const answer of parsed.answers) {
|
|
9227
9632
|
if (!answer.userMessage) continue;
|
|
9633
|
+
const answerText = safeAskText(answer.userMessage, 160);
|
|
9228
9634
|
lines.push(
|
|
9229
|
-
colorEnabled ? ` ${themeText("\xB7", "chrome", true)} ${
|
|
9635
|
+
colorEnabled ? ` ${themeText("\xB7", "chrome", true)} ${answerText}` : ` \xB7 ${answerText}`
|
|
9230
9636
|
);
|
|
9231
9637
|
}
|
|
9232
9638
|
}
|
|
@@ -9235,7 +9641,7 @@ function formatUiAskChoiceBlock(event, colorEnabled) {
|
|
|
9235
9641
|
}
|
|
9236
9642
|
parsed.choices.forEach((choice, i) => {
|
|
9237
9643
|
const num = String(i + 1);
|
|
9238
|
-
const label = choice.label;
|
|
9644
|
+
const label = safeAskText(choice.label, 160);
|
|
9239
9645
|
if (colorEnabled) {
|
|
9240
9646
|
lines.push(
|
|
9241
9647
|
` ${themeText(num + ".", "chrome", true)} ${label}`
|
|
@@ -9251,6 +9657,87 @@ function formatUiAskChoiceBlock(event, colorEnabled) {
|
|
|
9251
9657
|
lines.push(` ${hint}`);
|
|
9252
9658
|
}
|
|
9253
9659
|
return `${lines.join("\n")}
|
|
9660
|
+
`;
|
|
9661
|
+
}
|
|
9662
|
+
function formatShowInteractionBlock(event, colorEnabled) {
|
|
9663
|
+
const label = toolLabel(event.toolName || "show_interaction");
|
|
9664
|
+
let parsedPayload;
|
|
9665
|
+
if (typeof event.content === "string") {
|
|
9666
|
+
try {
|
|
9667
|
+
parsedPayload = JSON.parse(event.content);
|
|
9668
|
+
} catch {
|
|
9669
|
+
const metadata = event.metadata ?? {};
|
|
9670
|
+
const rawMetaError = metadata.error ?? metadata.errorMessage;
|
|
9671
|
+
const rawMessage = event.message?.trim();
|
|
9672
|
+
const rawContent = event.content.trim();
|
|
9673
|
+
let reason = "";
|
|
9674
|
+
if (typeof rawMetaError === "string" && rawMetaError.trim()) {
|
|
9675
|
+
reason = rawMetaError.trim();
|
|
9676
|
+
} else if (rawMessage) {
|
|
9677
|
+
reason = rawMessage;
|
|
9678
|
+
} else if (/^\[工具\s*"[^"]+"\s*执行失败:\s*[^\]]+\]$/.test(rawContent)) {
|
|
9679
|
+
reason = rawContent;
|
|
9680
|
+
}
|
|
9681
|
+
const detail = reason ? clip(redactSecrets(cleanUserText(reason)), 96) : "invalid card payload";
|
|
9682
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${detail}`, colorEnabled, "error");
|
|
9683
|
+
}
|
|
9684
|
+
} else if (event.content && typeof event.content === "object") {
|
|
9685
|
+
parsedPayload = event.content;
|
|
9686
|
+
} else {
|
|
9687
|
+
const metadata = event.metadata ?? {};
|
|
9688
|
+
const rawMetaError = metadata.error ?? metadata.errorMessage;
|
|
9689
|
+
const reason = typeof rawMetaError === "string" && rawMetaError.trim() || event.message?.trim() || "";
|
|
9690
|
+
const detail = reason ? clip(redactSecrets(cleanUserText(reason)), 96) : "invalid card payload";
|
|
9691
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${detail}`, colorEnabled, "error");
|
|
9692
|
+
}
|
|
9693
|
+
if (parsedPayload && typeof parsedPayload === "object" && parsedPayload.error) {
|
|
9694
|
+
const detail = typeof parsedPayload.detail === "string" && parsedPayload.detail.trim() ? clip(redactSecrets(cleanUserText(parsedPayload.detail)), 96) : "card error";
|
|
9695
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${detail}`, colorEnabled, "error");
|
|
9696
|
+
}
|
|
9697
|
+
const rawCard = parsedPayload && typeof parsedPayload === "object" && (parsedPayload.type === "show_interaction" || parsedPayload.card !== void 0) ? parsedPayload.card : parsedPayload;
|
|
9698
|
+
const parsedCard = parseUiCard(rawCard);
|
|
9699
|
+
if (!parsedCard.ok) {
|
|
9700
|
+
const errorText = clip(redactSecrets(cleanUserText(parsedCard.error)), 96);
|
|
9701
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${errorText}`, colorEnabled, "error");
|
|
9702
|
+
}
|
|
9703
|
+
const fallback = uiCardFallback(parsedCard.value);
|
|
9704
|
+
const maxLines = 12;
|
|
9705
|
+
const maxDisplayWidth = 400;
|
|
9706
|
+
const rawLines = fallback.split("\n");
|
|
9707
|
+
const clippedLines = [];
|
|
9708
|
+
let currentWidth = 0;
|
|
9709
|
+
let wasClipped = false;
|
|
9710
|
+
for (let i = 0; i < rawLines.length; i++) {
|
|
9711
|
+
if (clippedLines.length >= maxLines) {
|
|
9712
|
+
wasClipped = true;
|
|
9713
|
+
break;
|
|
9714
|
+
}
|
|
9715
|
+
const cleanLine = redactSecrets(cleanUserText(rawLines[i]));
|
|
9716
|
+
const lineWidth = displayWidth(cleanLine);
|
|
9717
|
+
const separatorWidth = clippedLines.length > 0 ? 1 : 0;
|
|
9718
|
+
if (currentWidth + lineWidth + separatorWidth > maxDisplayWidth) {
|
|
9719
|
+
const remainingWidth = maxDisplayWidth - currentWidth - separatorWidth;
|
|
9720
|
+
if (remainingWidth > 0) {
|
|
9721
|
+
clippedLines.push(truncateByDisplayWidth(cleanLine, remainingWidth));
|
|
9722
|
+
}
|
|
9723
|
+
wasClipped = true;
|
|
9724
|
+
break;
|
|
9725
|
+
}
|
|
9726
|
+
clippedLines.push(cleanLine);
|
|
9727
|
+
currentWidth += lineWidth + separatorWidth;
|
|
9728
|
+
}
|
|
9729
|
+
if (clippedLines.length === 0 && rawLines.length > 0 && maxDisplayWidth > 0) {
|
|
9730
|
+
const cleanLine = redactSecrets(cleanUserText(rawLines[0]));
|
|
9731
|
+
clippedLines.push(truncateByDisplayWidth(cleanLine, maxDisplayWidth));
|
|
9732
|
+
wasClipped = true;
|
|
9733
|
+
}
|
|
9734
|
+
if (wasClipped) {
|
|
9735
|
+
clippedLines.push("\u2026");
|
|
9736
|
+
}
|
|
9737
|
+
const cleanLines = clippedLines.map((l) => colorEnabled ? themeText(l, "muted", true) : l);
|
|
9738
|
+
return `
|
|
9739
|
+
${cleanLines.join("\n")}
|
|
9740
|
+
|
|
9254
9741
|
`;
|
|
9255
9742
|
}
|
|
9256
9743
|
function formatToolTraceLine(text, colorEnabled, accent = "none") {
|
|
@@ -9273,6 +9760,7 @@ function renderRunCard(snapshot, opts) {
|
|
|
9273
9760
|
...snapshot,
|
|
9274
9761
|
agentName: snapshot.agentName ? cleanUserText(snapshot.agentName) : snapshot.agentName,
|
|
9275
9762
|
taskPreview: snapshot.taskPreview ? cleanUserText(snapshot.taskPreview) : snapshot.taskPreview,
|
|
9763
|
+
title: snapshot.title ? cleanUserText(snapshot.title) : snapshot.title,
|
|
9276
9764
|
lastAssistantText: snapshot.lastAssistantText ? cleanUserText(snapshot.lastAssistantText) : snapshot.lastAssistantText,
|
|
9277
9765
|
lastToolNames: snapshot.lastToolNames?.map(cleanUserText)
|
|
9278
9766
|
} : snapshot;
|
|
@@ -9283,6 +9771,7 @@ function renderRunCard(snapshot, opts) {
|
|
|
9283
9771
|
} : { errorMessage: source.errorMessage, logLines: source.logLines };
|
|
9284
9772
|
const body = isAgentRunTerminalStatus(snapshot.status) ? formatFinishedRunCard(name, snapshot.status, {
|
|
9285
9773
|
runId: snapshot.runId,
|
|
9774
|
+
...snapshot.title ? { title: snapshot.title } : {},
|
|
9286
9775
|
toolCallCount: source.toolCallCount,
|
|
9287
9776
|
lastToolNames: source.lastToolNames,
|
|
9288
9777
|
lastAssistantText: source.lastAssistantText,
|
|
@@ -9292,6 +9781,7 @@ function renderRunCard(snapshot, opts) {
|
|
|
9292
9781
|
labels
|
|
9293
9782
|
}) : formatStatusRunCard(name, snapshot.status, {
|
|
9294
9783
|
runId: snapshot.runId,
|
|
9784
|
+
...snapshot.title ? { title: snapshot.title } : {},
|
|
9295
9785
|
toolCallCount: source.toolCallCount,
|
|
9296
9786
|
lastToolNames: source.lastToolNames,
|
|
9297
9787
|
lastAssistantText: source.lastAssistantText,
|
|
@@ -9312,7 +9802,10 @@ function recoverOrchestrationCard(event, toolName, opts) {
|
|
|
9312
9802
|
try {
|
|
9313
9803
|
const parsed = JSON.parse(trimmed);
|
|
9314
9804
|
const agents = Array.isArray(parsed.agents) ? parsed.agents : [];
|
|
9315
|
-
|
|
9805
|
+
const card = formatAgentListCard(agents);
|
|
9806
|
+
const lines = card.split("\n");
|
|
9807
|
+
lines[0] = t("agentsListLabel", String(agents.length));
|
|
9808
|
+
return lines.join("\n");
|
|
9316
9809
|
} catch {
|
|
9317
9810
|
return null;
|
|
9318
9811
|
}
|
|
@@ -9336,9 +9829,11 @@ function recoverOrchestrationCard(event, toolName, opts) {
|
|
|
9336
9829
|
if (kind === "start") {
|
|
9337
9830
|
const name = safe ? cleanUserText(snapshot.agentName ?? "agent") : snapshot.agentName ?? "agent";
|
|
9338
9831
|
const task = snapshot.taskPreview ? safe ? cleanUserText(snapshot.taskPreview) : snapshot.taskPreview : snapshot.taskPreview;
|
|
9832
|
+
const title = snapshot.title ? safe ? cleanUserText(snapshot.title) : snapshot.title : snapshot.title;
|
|
9339
9833
|
return formatStartRunCard(name, snapshot.status, {
|
|
9340
9834
|
task,
|
|
9341
9835
|
runId: snapshot.runId,
|
|
9836
|
+
...title ? { title } : {},
|
|
9342
9837
|
labels
|
|
9343
9838
|
});
|
|
9344
9839
|
}
|
|
@@ -9436,8 +9931,8 @@ function commandFullGist(command, max) {
|
|
|
9436
9931
|
if (!oneLine) return "";
|
|
9437
9932
|
return truncateByDisplayWidth(redactSecrets(oneLine), max);
|
|
9438
9933
|
}
|
|
9439
|
-
function pathBasenameGist(
|
|
9440
|
-
const segments =
|
|
9934
|
+
function pathBasenameGist(path2) {
|
|
9935
|
+
const segments = path2.split(/[\\/]/).filter((segment) => segment.length > 0);
|
|
9441
9936
|
const base = segments.pop();
|
|
9442
9937
|
return base ? gistClip(base) : "";
|
|
9443
9938
|
}
|
|
@@ -9593,8 +10088,8 @@ function normalToolGistRaw(event) {
|
|
|
9593
10088
|
const metadata = event.metadata ?? {};
|
|
9594
10089
|
const toolName = event.toolName || "";
|
|
9595
10090
|
if (toolName === "readFile") {
|
|
9596
|
-
const
|
|
9597
|
-
if (
|
|
10091
|
+
const path3 = typeof metadata.path === "string" ? metadata.path : typeof metadata.filePath === "string" ? metadata.filePath : "";
|
|
10092
|
+
if (path3) return gistClip(formatReadItemPath(path3, metadata), 52);
|
|
9598
10093
|
}
|
|
9599
10094
|
if (toolName === "fetchWebpage") {
|
|
9600
10095
|
const url = typeof metadata.url === "string" ? metadata.url : "";
|
|
@@ -9602,8 +10097,8 @@ function normalToolGistRaw(event) {
|
|
|
9602
10097
|
}
|
|
9603
10098
|
if (toolName === "exa_search") {
|
|
9604
10099
|
const query2 = typeof metadata.query === "string" ? metadata.query : typeof metadata.pattern === "string" ? metadata.pattern : "";
|
|
9605
|
-
const
|
|
9606
|
-
if (query2 ||
|
|
10100
|
+
const path3 = typeof metadata.path === "string" ? metadata.path : void 0;
|
|
10101
|
+
if (query2 || path3) return formatSearchItemQuery(query2, path3);
|
|
9607
10102
|
}
|
|
9608
10103
|
if (isRunToolName(toolName)) {
|
|
9609
10104
|
const command2 = typeof metadata.command === "string" ? metadata.command : "";
|
|
@@ -9613,26 +10108,14 @@ function normalToolGistRaw(event) {
|
|
|
9613
10108
|
}
|
|
9614
10109
|
const memoryGist = memoryToolGist(toolName, metadata);
|
|
9615
10110
|
if (memoryGist) return memoryGist;
|
|
9616
|
-
const
|
|
9617
|
-
if (
|
|
10111
|
+
const path2 = typeof metadata.path === "string" ? metadata.path : "";
|
|
10112
|
+
if (path2) return pathBasenameGist(path2);
|
|
9618
10113
|
const command = typeof metadata.command === "string" ? metadata.command : "";
|
|
9619
10114
|
if (command) return commandFullGist(command, normalRunGistMaxWidth());
|
|
9620
10115
|
const query = typeof metadata.query === "string" ? metadata.query : "";
|
|
9621
10116
|
if (query) return clipCompactText(query, 64, "\u2026");
|
|
9622
10117
|
return "";
|
|
9623
10118
|
}
|
|
9624
|
-
var NORMAL_GIST_SECRET_PATTERNS = [
|
|
9625
|
-
/\bbearer\s+[A-Za-z0-9._~+/=-]{8,}/i,
|
|
9626
|
-
/\bsk-(?:ant-)?(?:api)?[0-9a-zA-Z-]{10,}/,
|
|
9627
|
-
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{10,}/,
|
|
9628
|
-
/\bxox[baprs]-[A-Za-z0-9-]{10,}/
|
|
9629
|
-
];
|
|
9630
|
-
function withholdIfSecretLike(gist) {
|
|
9631
|
-
if (!gist) return "";
|
|
9632
|
-
if (findPotentialSecrets(gist).length > 0) return "";
|
|
9633
|
-
if (NORMAL_GIST_SECRET_PATTERNS.some((pattern) => pattern.test(gist))) return "";
|
|
9634
|
-
return gist;
|
|
9635
|
-
}
|
|
9636
10119
|
function normalToolGist(event) {
|
|
9637
10120
|
return withholdIfSecretLike(normalToolGistRaw(event));
|
|
9638
10121
|
}
|
|
@@ -9644,8 +10127,6 @@ function formatNormalToolDuration(elapsedMs) {
|
|
|
9644
10127
|
function formatNormalToolLine(event, pending, colorEnabled) {
|
|
9645
10128
|
if (event.type === "tool-call") return "";
|
|
9646
10129
|
const toolName = event.toolName || pending?.toolName || "tool";
|
|
9647
|
-
const todoBlock = formatTodoListForCli(event, colorEnabled);
|
|
9648
|
-
if (todoBlock) return todoBlock;
|
|
9649
10130
|
if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
|
|
9650
10131
|
const block = formatUiAskChoiceBlock(event, colorEnabled);
|
|
9651
10132
|
if (block) return block;
|
|
@@ -9656,6 +10137,9 @@ function formatNormalToolLine(event, pending, colorEnabled) {
|
|
|
9656
10137
|
if (event.type === "tool-result" && toolName === "loadSkill") {
|
|
9657
10138
|
return formatLoadSkillBlock(event, colorEnabled, { safe: true }) ?? "";
|
|
9658
10139
|
}
|
|
10140
|
+
if (event.type === "tool-result" && toolName === "show_interaction") {
|
|
10141
|
+
return formatShowInteractionBlock(event, colorEnabled);
|
|
10142
|
+
}
|
|
9659
10143
|
const label = toolLabel(toolName);
|
|
9660
10144
|
if (readActionGate(event.metadata?.actionGate)) {
|
|
9661
10145
|
return formatToolTraceLine(`\u25B8 ${label} ! ${t("toolNeedsAction")}`, colorEnabled, "error");
|
|
@@ -9708,39 +10192,6 @@ function resolveLoadSkillName(event) {
|
|
|
9708
10192
|
if (match?.[1]) return match[1];
|
|
9709
10193
|
return argName || "skill";
|
|
9710
10194
|
}
|
|
9711
|
-
function formatTodoListForCli(event, colorEnabled) {
|
|
9712
|
-
if (event.type !== "tool-result" || event.toolName !== "setTodoList") {
|
|
9713
|
-
return void 0;
|
|
9714
|
-
}
|
|
9715
|
-
let raw = event.metadata?.displayData;
|
|
9716
|
-
let parsed = typeof raw === "object" && raw !== null;
|
|
9717
|
-
if (typeof raw === "string") {
|
|
9718
|
-
try {
|
|
9719
|
-
raw = JSON.parse(raw);
|
|
9720
|
-
parsed = true;
|
|
9721
|
-
} catch {
|
|
9722
|
-
raw = void 0;
|
|
9723
|
-
}
|
|
9724
|
-
}
|
|
9725
|
-
if (!parsed && typeof event.content === "string") {
|
|
9726
|
-
try {
|
|
9727
|
-
raw = JSON.parse(event.content);
|
|
9728
|
-
parsed = true;
|
|
9729
|
-
} catch {
|
|
9730
|
-
raw = void 0;
|
|
9731
|
-
}
|
|
9732
|
-
}
|
|
9733
|
-
const todos = Array.isArray(raw?.todos) ? raw.todos : void 0;
|
|
9734
|
-
if (!todos) return void 0;
|
|
9735
|
-
if (todos.length === 0) return "\u2611 Todo\n (empty)\n";
|
|
9736
|
-
const lines = todos.map((todo) => {
|
|
9737
|
-
const status = todo?.status === "done" ? "\u2713" : todo?.status === "in_progress" ? "\u25D0" : "\u25CB";
|
|
9738
|
-
const title = typeof todo?.title === "string" ? todo.title : "Untitled task";
|
|
9739
|
-
return ` ${status} ${title}`;
|
|
9740
|
-
});
|
|
9741
|
-
const text = [`\u2611 Todo (${todos.length})`, ...lines].join("\n") + "\n";
|
|
9742
|
-
return colorEnabled ? themeText(text, "chrome") : text;
|
|
9743
|
-
}
|
|
9744
10195
|
function formatLoadSkillBlock(event, colorEnabled, opts) {
|
|
9745
10196
|
if (event.type !== "tool-result" || event.toolName !== "loadSkill") return null;
|
|
9746
10197
|
const skillName = resolveLoadSkillName(event);
|
|
@@ -10385,6 +10836,12 @@ var describeClientVersionTooOldFailure = (message, rawError) => {
|
|
|
10385
10836
|
};
|
|
10386
10837
|
|
|
10387
10838
|
// packages/cli/client/agentRunStream.ts
|
|
10839
|
+
function isMalformedFunctionCallFailure(message) {
|
|
10840
|
+
return message.includes("MALFORMED_FUNCTION_CALL");
|
|
10841
|
+
}
|
|
10842
|
+
function shouldAppendStreamRawErrorDetail(env) {
|
|
10843
|
+
return env?.NOLO_DEBUG === "1" || env?.NOLO_CLI_DEBUG_DETAIL === "1";
|
|
10844
|
+
}
|
|
10388
10845
|
async function readStreamingAgentRun(options, res, existingSpinner) {
|
|
10389
10846
|
const reader = res.body?.getReader();
|
|
10390
10847
|
if (!reader) {
|
|
@@ -10493,15 +10950,18 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
|
|
|
10493
10950
|
};
|
|
10494
10951
|
}
|
|
10495
10952
|
const message = toErrorMessage(error);
|
|
10953
|
+
const malformedToolCall = isMalformedFunctionCallFailure(message);
|
|
10954
|
+
const rawDetail = shouldAppendStreamRawErrorDetail(options.env) ? t("agentRunStream.rawErrorDetail", message) : null;
|
|
10496
10955
|
if (dialogId) {
|
|
10497
|
-
|
|
10498
|
-
`
|
|
10499
|
-
|
|
10500
|
-
`
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
|
|
10504
|
-
);
|
|
10956
|
+
if (malformedToolCall) {
|
|
10957
|
+
options.output.write(`
|
|
10958
|
+
${t("agentRunStream.malformedToolCallRejected", dialogId)}
|
|
10959
|
+
`);
|
|
10960
|
+
if (rawDetail) options.output.write(rawDetail);
|
|
10961
|
+
return { exitCode: 0, dialogId, streamInterrupted: true };
|
|
10962
|
+
}
|
|
10963
|
+
options.output.write(t("agentRunStream.interruptedAfterDialog", dialogId, message));
|
|
10964
|
+
options.output.write(t("agentRunStream.mayStillFinishOnServer"));
|
|
10505
10965
|
return { exitCode: 0, dialogId, streamInterrupted: true };
|
|
10506
10966
|
}
|
|
10507
10967
|
if (isClientVersionTooOldFailure(message, error)) {
|
|
@@ -10509,9 +10969,14 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
|
|
|
10509
10969
|
${describeClientVersionTooOldFailure(message, error)}`);
|
|
10510
10970
|
return { exitCode: 1 };
|
|
10511
10971
|
}
|
|
10512
|
-
|
|
10513
|
-
|
|
10972
|
+
if (malformedToolCall) {
|
|
10973
|
+
options.output.write(`
|
|
10974
|
+
${t("agentRunStream.malformedToolCallRejectedNoDialog")}
|
|
10514
10975
|
`);
|
|
10976
|
+
if (rawDetail) options.output.write(rawDetail);
|
|
10977
|
+
return { exitCode: 1 };
|
|
10978
|
+
}
|
|
10979
|
+
options.output.write(t("agentRunStream.failed", message));
|
|
10515
10980
|
return { exitCode: 1 };
|
|
10516
10981
|
}
|
|
10517
10982
|
if (options.abortSignal?.aborted && !sawDone) {
|
|
@@ -10532,6 +10997,9 @@ ${describeClientVersionTooOldFailure(message, error)}`);
|
|
|
10532
10997
|
return {
|
|
10533
10998
|
exitCode: 0,
|
|
10534
10999
|
...dialogId ? { dialogId } : {},
|
|
11000
|
+
// 结论载体与 local / 非流式 HTTP 路径同契约:流式分支已经把 assistant
|
|
11001
|
+
// 正文累加在 content 里,不随行则 server 流式 run 的结算也拿不到结论。
|
|
11002
|
+
...content ? { finalText: content } : {},
|
|
10535
11003
|
turnTokens: buildTurnTokenUsage(usage, options.agentKey),
|
|
10536
11004
|
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
10537
11005
|
};
|
|
@@ -10738,8 +11206,46 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
|
|
|
10738
11206
|
|
|
10739
11207
|
// packages/cli/client/agentRun.ts
|
|
10740
11208
|
import { ulid as ulid2 } from "ulid";
|
|
11209
|
+
|
|
11210
|
+
// packages/cli/client/balanceErrorPatterns.ts
|
|
11211
|
+
var ZERO_WIDTH_RE = /[\u200b-\u200d\u2060\ufeff]/g;
|
|
11212
|
+
function stripZeroWidthChars(text) {
|
|
11213
|
+
return text.replace(ZERO_WIDTH_RE, "");
|
|
11214
|
+
}
|
|
11215
|
+
var CONTROL_CHAR_RE = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g;
|
|
11216
|
+
function stripControlChars(text) {
|
|
11217
|
+
return text.replace(CONTROL_CHAR_RE, "");
|
|
11218
|
+
}
|
|
11219
|
+
var BALANCE_ERROR_PATTERNS = [
|
|
11220
|
+
/UPSTREAM_402/i,
|
|
11221
|
+
// 裸 HTTP 402 本身就是「Payment Required」:报文里没有任何余额关键词(如只有
|
|
11222
|
+
// `{"error":{}}` 空壳)时也必须走余额块,而不是落进通用 4xx 长文案。
|
|
11223
|
+
// `\b` 保证 `HTTP 4020` 不误命中。
|
|
11224
|
+
/\bHTTP\s*402\b/i,
|
|
11225
|
+
// `insufficient balance` / `insufficient_balance` / `insufficient-balance` /
|
|
11226
|
+
// `Insufficient Balance`(分隔符重复也要认:alpha 里的旧 `/insufficient\s+balance/`
|
|
11227
|
+
// 能覆盖双空格,收窄成 `?` 会回退)。
|
|
11228
|
+
/insufficient[_\s-]+balance/i,
|
|
11229
|
+
/余额不足/,
|
|
11230
|
+
/wallet\s+balance\s+is\s+insufficient/i,
|
|
11231
|
+
/top\s+up\s+your\s+wallet/i,
|
|
11232
|
+
/payment[_ ]required/i
|
|
11233
|
+
];
|
|
11234
|
+
var CODING_PLAN_EXHAUSTED_RE = /coding[_\s-]?plan[_\s-]?exhausted/i;
|
|
11235
|
+
function matchesBalanceError(message) {
|
|
11236
|
+
if (!message) return false;
|
|
11237
|
+
const normalized = stripZeroWidthChars(message);
|
|
11238
|
+
return BALANCE_ERROR_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
11239
|
+
}
|
|
11240
|
+
function isBalanceExhaustedError(error) {
|
|
11241
|
+
if (!error) return false;
|
|
11242
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : String(error?.message ?? "");
|
|
11243
|
+
return matchesBalanceError(message);
|
|
11244
|
+
}
|
|
11245
|
+
|
|
11246
|
+
// packages/cli/client/agentRun.ts
|
|
10741
11247
|
async function loadRunLocalAgentTurn() {
|
|
10742
|
-
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-
|
|
11248
|
+
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-KKSQJMTE.js");
|
|
10743
11249
|
return runLocalAgentTurn;
|
|
10744
11250
|
}
|
|
10745
11251
|
var stripDebugNoise = (s) => s.replace(/\s*raw="[\s\S]*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
|
|
@@ -10763,25 +11269,7 @@ function parseEmbeddedBalanceDetails(message) {
|
|
|
10763
11269
|
const jsonStart = message.indexOf('{"error"');
|
|
10764
11270
|
if (jsonStart < 0) return void 0;
|
|
10765
11271
|
try {
|
|
10766
|
-
|
|
10767
|
-
let inString = false;
|
|
10768
|
-
let escaped = false;
|
|
10769
|
-
let jsonEnd = -1;
|
|
10770
|
-
for (let i = jsonStart; i < message.length; i += 1) {
|
|
10771
|
-
const char = message[i];
|
|
10772
|
-
if (inString) {
|
|
10773
|
-
if (escaped) escaped = false;
|
|
10774
|
-
else if (char === "\\") escaped = true;
|
|
10775
|
-
else if (char === '"') inString = false;
|
|
10776
|
-
} else if (char === '"') {
|
|
10777
|
-
inString = true;
|
|
10778
|
-
} else if (char === "{") {
|
|
10779
|
-
depth += 1;
|
|
10780
|
-
} else if (char === "}" && --depth === 0) {
|
|
10781
|
-
jsonEnd = i + 1;
|
|
10782
|
-
break;
|
|
10783
|
-
}
|
|
10784
|
-
}
|
|
11272
|
+
const jsonEnd = findJsonObjectEnd(message, jsonStart);
|
|
10785
11273
|
if (jsonEnd < 0) return void 0;
|
|
10786
11274
|
const parsed = JSON.parse(message.slice(jsonStart, jsonEnd));
|
|
10787
11275
|
if (!parsed || typeof parsed !== "object") return void 0;
|
|
@@ -10825,6 +11313,7 @@ function resolveRequestedRuntimeMode(options) {
|
|
|
10825
11313
|
return envMode;
|
|
10826
11314
|
return "auto";
|
|
10827
11315
|
}
|
|
11316
|
+
var MACHINE_SHELL_LOCAL_REFUSAL_MESSAGE = "[nolo] --machine-shell can only run on the machine bound in the agent record (runtimeBinding.machineId): a local run cannot honor it, and it never executes on this computer.\n[nolo] Retry without --local / NOLO_RUNTIME_MODE=local, or drop --machine-shell to run on this computer.\n";
|
|
10828
11317
|
function canResolveCollapsedPasteReference(store, content) {
|
|
10829
11318
|
const expand = (text) => expandCollapsedPastes(text, store) !== text;
|
|
10830
11319
|
if (typeof content === "string") return expand(content);
|
|
@@ -10837,15 +11326,31 @@ function buildDefaultLocalRuntimeAdapter(options) {
|
|
|
10837
11326
|
fetchImpl: options.fetchImpl,
|
|
10838
11327
|
cwd: options.localRuntimeCwd,
|
|
10839
11328
|
output: options.output,
|
|
11329
|
+
// TUI 显式注入的真实会话身份;缺省时 adapter 内仍回退 parentDialogId。
|
|
11330
|
+
...options.originSession ? { originSession: options.originSession } : {},
|
|
11331
|
+
// 分享 OAuth agent 的 shell 会话授权(块 D):仅 owner-required 场景生效。
|
|
11332
|
+
...options.shellGrant ? { shellGrant: options.shellGrant } : {},
|
|
11333
|
+
...options.shellApprovalSession ? { shellApprovalSession: options.shellApprovalSession } : {},
|
|
11334
|
+
...options.execShellApproval ? { execShellApproval: options.execShellApproval } : {},
|
|
11335
|
+
// 运行位置展示(块 D):TUI 消费 projectToolExecutionLocation 渲染工具实际
|
|
11336
|
+
// 执行设备/工作区;非 owner-required 场景 adapter 不回调。
|
|
11337
|
+
...options.onToolExecutionLocation ? { onToolExecutionLocation: options.onToolExecutionLocation } : {},
|
|
10840
11338
|
...options.confirmDestructiveAction ? { confirmDestructiveAction: options.confirmDestructiveAction } : {},
|
|
10841
11339
|
...options.requestUserChoice ? { requestUserChoice: options.requestUserChoice } : {},
|
|
10842
11340
|
...options.pastedTextStore?.items.size ? { pastedTextStore: options.pastedTextStore } : {},
|
|
10843
|
-
...options.activityReporter ? { activityReporter: options.activityReporter } : {}
|
|
11341
|
+
...options.activityReporter ? { activityReporter: options.activityReporter } : {},
|
|
11342
|
+
// runtimeKey 接线:不传下去则本地 run 的 runtimeKey 在 agentRun 层就断了
|
|
11343
|
+
// ——adapter 收不到 → docker workload 永不创建,非 docker 云后端也不会
|
|
11344
|
+
// fail-closed(死代码)。
|
|
11345
|
+
...options.runtimeKey ? { runtimeKey: options.runtimeKey } : {}
|
|
10844
11346
|
});
|
|
10845
11347
|
}
|
|
10846
11348
|
function resolveLocalRuntimeAdapter(options) {
|
|
10847
11349
|
return options.localRuntimeAdapter || options.localRuntimeAdapterFactory?.(options.env, {
|
|
10848
|
-
cwd: options.localRuntimeCwd
|
|
11350
|
+
cwd: options.localRuntimeCwd,
|
|
11351
|
+
// 与 buildDefaultLocalRuntimeAdapter 同口径:注入式 factory 也必须拿到
|
|
11352
|
+
// runtimeKey,否则注入了 adapter 的本地 run 会静默丢掉 docker 语义。
|
|
11353
|
+
...options.runtimeKey ? { runtimeKey: options.runtimeKey } : {}
|
|
10849
11354
|
}) || buildDefaultLocalRuntimeAdapter(options);
|
|
10850
11355
|
}
|
|
10851
11356
|
function wrapAdapterEphemeral(adapter) {
|
|
@@ -10874,7 +11379,7 @@ function wrapLoadAgentConfigWithModelOverride(adapter, targetAgentKey, override)
|
|
|
10874
11379
|
}
|
|
10875
11380
|
};
|
|
10876
11381
|
}
|
|
10877
|
-
var
|
|
11382
|
+
var oauthChannelSkipReportedAgentKeys = /* @__PURE__ */ new Set();
|
|
10878
11383
|
function resolveOAuthChannelOwnerSkip(agentConfig, options) {
|
|
10879
11384
|
if (!agentConfig) return null;
|
|
10880
11385
|
const apiKeyRef = typeof agentConfig.apiKeyRef === "string" ? agentConfig.apiKeyRef : void 0;
|
|
@@ -10886,8 +11391,8 @@ function resolveOAuthChannelOwnerSkip(agentConfig, options) {
|
|
|
10886
11391
|
if (!ownerUserId) return null;
|
|
10887
11392
|
const localUserId = resolveLocalUserId(options.env);
|
|
10888
11393
|
if (ownerUserId === localUserId) return null;
|
|
10889
|
-
|
|
10890
|
-
|
|
11394
|
+
const agentName = asOptionalTrimmedString(agentConfig.name) ?? asOptionalTrimmedString(options.agentName) ?? t("agentRun.sharedAgentFallbackName");
|
|
11395
|
+
return t("agentRun.oauthChannelOwnerSkip", agentName) + "\n";
|
|
10891
11396
|
}
|
|
10892
11397
|
async function shouldSkipAutoLocalForServerPlatformTools(options) {
|
|
10893
11398
|
if (isBuiltinNoloAgentRef(options.agentKey)) return false;
|
|
@@ -10903,13 +11408,13 @@ async function shouldSkipAutoLocalForServerPlatformTools(options) {
|
|
|
10903
11408
|
}
|
|
10904
11409
|
const oauthChannelOwnerSkip = resolveOAuthChannelOwnerSkip(agentConfig, options);
|
|
10905
11410
|
if (oauthChannelOwnerSkip) {
|
|
10906
|
-
if (!options.output || typeof options.output !== "object" || !
|
|
11411
|
+
if (!options.output || typeof options.output !== "object" || !oauthChannelSkipReportedAgentKeys.has(options.agentKey)) {
|
|
10907
11412
|
if (options.output && typeof options.output === "object") {
|
|
10908
|
-
|
|
11413
|
+
oauthChannelSkipReportedAgentKeys.add(options.agentKey);
|
|
10909
11414
|
}
|
|
10910
11415
|
options.output.write(oauthChannelOwnerSkip);
|
|
10911
11416
|
}
|
|
10912
|
-
return
|
|
11417
|
+
return false;
|
|
10913
11418
|
}
|
|
10914
11419
|
if (options.localRuntimeCwd) {
|
|
10915
11420
|
return false;
|
|
@@ -10948,14 +11453,15 @@ async function shouldSkipAutoLocalForServerPlatformTools(options) {
|
|
|
10948
11453
|
);
|
|
10949
11454
|
return true;
|
|
10950
11455
|
}
|
|
10951
|
-
function buildUserInputContent(message, imageUrls = []) {
|
|
10952
|
-
if (imageUrls.length === 0) return message;
|
|
11456
|
+
function buildUserInputContent(message, imageUrls = [], attachmentParts = []) {
|
|
11457
|
+
if (imageUrls.length === 0 && attachmentParts.length === 0) return message;
|
|
10953
11458
|
return [
|
|
10954
11459
|
...message.trim() ? [{ type: "text", text: message }] : [],
|
|
10955
11460
|
...imageUrls.map((url) => ({
|
|
10956
11461
|
type: "image_url",
|
|
10957
11462
|
image_url: { url }
|
|
10958
|
-
}))
|
|
11463
|
+
})),
|
|
11464
|
+
...attachmentParts
|
|
10959
11465
|
];
|
|
10960
11466
|
}
|
|
10961
11467
|
function buildSubjectRefs(options) {
|
|
@@ -11000,8 +11506,8 @@ function isMissingLocalAgentConfigError(error, agentRef) {
|
|
|
11000
11506
|
error && typeof error === "object" && "code" in error && error.code === LOCAL_AGENT_CONFIG_MISSING_CODE && error.agentRef === agentRef
|
|
11001
11507
|
);
|
|
11002
11508
|
}
|
|
11003
|
-
var PROVIDER_HTTP_FAILED_RE = /(.+?)
|
|
11004
|
-
var PLATFORM_TRANSPORT_RE = /\
|
|
11509
|
+
var PROVIDER_HTTP_FAILED_RE = /(.+?)(?:\s+provider|\s+proxy) failed:\s*HTTP\s+(\d+)\b/i;
|
|
11510
|
+
var PLATFORM_TRANSPORT_RE = /\b(?:platform provider failed|owner-required proxy failed)\b/i;
|
|
11005
11511
|
var EXTRA_RATE_LIMIT_TEXT_RE = /\brate[\s_-]?limit(?:ed|ing|s)?\b|\bresource[_\s-]?exhausted\b|\bmax_concurrent_reached\b/i;
|
|
11006
11512
|
function looksLikeRateLimitedText(message) {
|
|
11007
11513
|
return EXTRA_RATE_LIMIT_TEXT_RE.test(message) || QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
|
@@ -11048,7 +11554,6 @@ function classifyLocalRunError(message) {
|
|
|
11048
11554
|
kind: "rate-limit",
|
|
11049
11555
|
transport,
|
|
11050
11556
|
status: 429,
|
|
11051
|
-
statusInferred: true,
|
|
11052
11557
|
...quotaExhausted ? { quotaExhausted: true } : {}
|
|
11053
11558
|
};
|
|
11054
11559
|
}
|
|
@@ -11059,7 +11564,8 @@ function classifyLocalRunError(message) {
|
|
|
11059
11564
|
}
|
|
11060
11565
|
return { kind: "generic" };
|
|
11061
11566
|
}
|
|
11062
|
-
var HISTORY_REPLAY_REJECTION_RE = /
|
|
11567
|
+
var HISTORY_REPLAY_REJECTION_RE = /invalid\s+tool\s+call\s+arguments?/i;
|
|
11568
|
+
var REASONING_REPLAY_CONTRACT_RE = /reasoning_content[^.]*must be passed back/i;
|
|
11063
11569
|
var RUN_UNAVAILABLE_PREFIX = "[nolo] auto runtime: local run unavailable";
|
|
11064
11570
|
var NO_FALLBACK = "Not falling back to server.";
|
|
11065
11571
|
var SERVER_FALLBACK_HINT = "or use --server to run on the server explicitly.";
|
|
@@ -11094,39 +11600,268 @@ function buildAuthFailure(ctx) {
|
|
|
11094
11600
|
Detail: ${ctx.message} ${NO_FALLBACK} Use --server to run on the server explicitly.
|
|
11095
11601
|
`;
|
|
11096
11602
|
}
|
|
11097
|
-
|
|
11603
|
+
if (ctx.status === 403 && ctx.message.includes("owner-required proxy failed") && /"code"\s*:\s*"owner_origin_mismatch"/i.test(ctx.message)) {
|
|
11604
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, this run's origin device could not be verified \u2014 no live connector connection for this machine on this server/account; owner_origin_mismatch).
|
|
11605
|
+
\xB7 Start the connector on this machine: \`nolo connect --daemon\` (\`nolo machine status\` shows whether it is online and connected to the same server)
|
|
11606
|
+
\xB7 Force a fully local run with --local (needs a local credential for this agent), or run on the server: --server
|
|
11607
|
+
Detail: ${ctx.message} ${NO_FALLBACK} ${SERVER_FALLBACK_HINT}
|
|
11608
|
+
`;
|
|
11609
|
+
}
|
|
11610
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, auth rejected). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}
|
|
11098
11611
|
`;
|
|
11099
11612
|
}
|
|
11100
11613
|
function isAuthNoTokenBody(message) {
|
|
11101
11614
|
return /"authCode"\s*:\s*"AUTH_NO_TOKEN"/i.test(message) || /no authentication token provided/i.test(message);
|
|
11102
11615
|
}
|
|
11103
11616
|
function buildRejectedPayloadFailure(ctx) {
|
|
11104
|
-
const
|
|
11105
|
-
const
|
|
11617
|
+
const looksLikeReasoningReplay = REASONING_REPLAY_CONTRACT_RE.test(ctx.message);
|
|
11618
|
+
const looksLikeHistoryReplay = !looksLikeReasoningReplay && HISTORY_REPLAY_REJECTION_RE.test(ctx.message);
|
|
11619
|
+
const cause = looksLikeReasoningReplay ? ` This is a thinking-mode replay contract violation: the history contains an assistant tool-call turn without reasoning_content, but this model requires every such turn to pass reasoning back to the API. The upstream may not have returned reasoning for that turn, or the history came from a different model.` : looksLikeHistoryReplay ? ` This usually happens when the dialog history contains tool_calls or reasoning produced by a different model/provider (e.g. after /switch); the new provider rejects that history. Start a fresh dialog, or clean the offending history.` : "";
|
|
11106
11620
|
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, the provider rejected the request body \u2014 this is NOT a local credential/config issue). Detail: ${ctx.message}${cause} ${NO_FALLBACK} Use --server to run on the server explicitly, or start a fresh dialog.
|
|
11107
11621
|
`;
|
|
11108
11622
|
}
|
|
11109
|
-
var
|
|
11623
|
+
var RESET_HINT_UNIT = String.raw`(?:d(?:ays?)?|h(?:ours?|rs?)?|m(?:in(?:ute)?s?)?|s(?:ec(?:ond)?s?)?)`;
|
|
11624
|
+
var RESET_HINT_DURATION = String.raw`\d+(?:\.\d+)?(?:\s*${RESET_HINT_UNIT})?(?:\s*\d+(?:\.\d+)?\s*${RESET_HINT_UNIT})*`;
|
|
11625
|
+
var RATE_LIMIT_RESET_HINT_RE = new RegExp(
|
|
11626
|
+
String.raw`retry[-_\s]?after\s*[:=]?\s*\d[\w:.-]*` + String.raw`|resets?\s+at\s+\d[\w:.-]*` + String.raw`|resets?\s+in\s+${RESET_HINT_DURATION}`,
|
|
11627
|
+
"i"
|
|
11628
|
+
);
|
|
11629
|
+
function findRateLimitResetHint(message) {
|
|
11630
|
+
const match = RATE_LIMIT_RESET_HINT_RE.exec(message);
|
|
11631
|
+
if (!match) return void 0;
|
|
11632
|
+
const end = match.index + match[0].length;
|
|
11633
|
+
if (/^[a-z:-]/i.test(message[end] ?? "")) return void 0;
|
|
11634
|
+
return { raw: match[0], text: match[0].trim(), index: match.index };
|
|
11635
|
+
}
|
|
11110
11636
|
function extractRateLimitResetHint(message) {
|
|
11111
|
-
|
|
11112
|
-
|
|
11637
|
+
return findRateLimitResetHint(message)?.text;
|
|
11638
|
+
}
|
|
11639
|
+
function isStandaloneResetSentence(text, index) {
|
|
11640
|
+
const before = text.slice(0, index).replace(/\s+$/, "");
|
|
11641
|
+
return before === "" || /[.。!!??;;]$/.test(before);
|
|
11642
|
+
}
|
|
11643
|
+
var RATE_LIMIT_DETAIL_MAX_CHARS = 140;
|
|
11644
|
+
var UPSTREAM_TAG_MAX_CHARS = 64;
|
|
11645
|
+
function findJsonObjectEnd(text, from) {
|
|
11646
|
+
const open = text[from];
|
|
11647
|
+
if (open !== "{" && open !== "[") return -1;
|
|
11648
|
+
const close = open === "{" ? "}" : "]";
|
|
11649
|
+
let depth = 0;
|
|
11650
|
+
let inString = false;
|
|
11651
|
+
let escaped = false;
|
|
11652
|
+
for (let i = from; i < text.length; i += 1) {
|
|
11653
|
+
const ch = text[i];
|
|
11654
|
+
if (inString) {
|
|
11655
|
+
if (escaped) escaped = false;
|
|
11656
|
+
else if (ch === "\\") escaped = true;
|
|
11657
|
+
else if (ch === '"') inString = false;
|
|
11658
|
+
continue;
|
|
11659
|
+
}
|
|
11660
|
+
if (ch === '"') inString = true;
|
|
11661
|
+
else if (ch === open) depth += 1;
|
|
11662
|
+
else if (ch === close) {
|
|
11663
|
+
depth -= 1;
|
|
11664
|
+
if (depth === 0) return i + 1;
|
|
11665
|
+
}
|
|
11666
|
+
}
|
|
11667
|
+
return -1;
|
|
11668
|
+
}
|
|
11669
|
+
function stripRateLimitDetailsArray(message) {
|
|
11670
|
+
const KEY = "details=";
|
|
11671
|
+
let out = message;
|
|
11672
|
+
let searchFrom = 0;
|
|
11673
|
+
for (; ; ) {
|
|
11674
|
+
const keyIndex = out.indexOf(KEY, searchFrom);
|
|
11675
|
+
if (keyIndex === -1) return out;
|
|
11676
|
+
let openIndex = keyIndex + KEY.length;
|
|
11677
|
+
while (openIndex < out.length && /\s/.test(out[openIndex])) openIndex += 1;
|
|
11678
|
+
if (out[openIndex] !== "[") {
|
|
11679
|
+
searchFrom = keyIndex + KEY.length;
|
|
11680
|
+
continue;
|
|
11681
|
+
}
|
|
11682
|
+
const endIndex = findJsonObjectEnd(out, openIndex);
|
|
11683
|
+
if (endIndex === -1) return out;
|
|
11684
|
+
out = `${out.slice(0, keyIndex)} ${out.slice(endIndex)}`;
|
|
11685
|
+
searchFrom = keyIndex;
|
|
11686
|
+
}
|
|
11687
|
+
}
|
|
11688
|
+
function stripRateLimitTransportPrefix(message) {
|
|
11689
|
+
let out = message.trim();
|
|
11690
|
+
const localPrefix = /^local(?:\s+\S+)?\s+provider failed:\s*/i.exec(out);
|
|
11691
|
+
if (localPrefix) {
|
|
11692
|
+
out = out.slice(localPrefix[0].length);
|
|
11693
|
+
} else {
|
|
11694
|
+
const proxyPrefix = /^server chat proxy[^:]*:\s*/i.exec(out);
|
|
11695
|
+
if (proxyPrefix) out = out.slice(proxyPrefix[0].length);
|
|
11696
|
+
}
|
|
11697
|
+
return out.replace(/^HTTP\s+\d{3}\b[\s:,-]*/i, "").trim();
|
|
11698
|
+
}
|
|
11699
|
+
function describeUpstreamTag(ctx) {
|
|
11700
|
+
const source = stripZeroWidthChars(ctx.message);
|
|
11701
|
+
const clean2 = (value) => {
|
|
11702
|
+
if (value === void 0) return void 0;
|
|
11703
|
+
const normalized = stripControlChars(value).replace(/\s+/g, " ").trim();
|
|
11704
|
+
if (!normalized) return void 0;
|
|
11705
|
+
return normalized.length > UPSTREAM_TAG_MAX_CHARS ? `${normalized.slice(0, UPSTREAM_TAG_MAX_CHARS - 1).trimEnd()}\u2026` : normalized;
|
|
11706
|
+
};
|
|
11707
|
+
const provider = clean2(/^local\s+(\S+)\s+provider failed/i.exec(source)?.[1]);
|
|
11708
|
+
const model = clean2(/"model"\s*:\s*"([^"]+)"/.exec(source)?.[1]);
|
|
11709
|
+
const parts = [provider, model].filter((part) => Boolean(part));
|
|
11710
|
+
return parts.length > 0 ? parts.join(" \xB7 ") : ctx.where;
|
|
11711
|
+
}
|
|
11712
|
+
function sanitizeRateLimitDetail(message, stripResetSentence) {
|
|
11713
|
+
const withoutNoise = stripRateLimitTransportPrefix(
|
|
11714
|
+
// 控制字符(ESC 清屏 / 光标移动)是 provider 可控文本,先剥再进用户文案。
|
|
11715
|
+
stripControlChars(stripRateLimitDetailsArray(stripDebugNoise(message)))
|
|
11716
|
+
);
|
|
11717
|
+
const collapse = (text) => text.replace(/\s+/g, " ").replace(/([.。!!??])\s+(?=[.。!!??])/g, "").replace(/([.。!!??])\1+/g, "$1").replace(/[\s,;:,;:]+$/, "").trim();
|
|
11718
|
+
const hint = stripResetSentence ? findRateLimitResetHint(withoutNoise) : void 0;
|
|
11719
|
+
const stripped = hint && isStandaloneResetSentence(withoutNoise, hint.index) ? `${withoutNoise.slice(0, hint.index)} ${withoutNoise.slice(hint.index + hint.raw.length)}` : withoutNoise;
|
|
11720
|
+
const detail = collapse(stripped) || collapse(withoutNoise);
|
|
11721
|
+
return detail.length > RATE_LIMIT_DETAIL_MAX_CHARS ? `${detail.slice(0, RATE_LIMIT_DETAIL_MAX_CHARS - 1).trimEnd()}\u2026` : detail;
|
|
11722
|
+
}
|
|
11723
|
+
function formatCooldownUntilLocal(iso, now = /* @__PURE__ */ new Date()) {
|
|
11724
|
+
const at = new Date(iso);
|
|
11725
|
+
if (Number.isNaN(at.getTime())) return iso;
|
|
11726
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
11727
|
+
const time = `${pad(at.getHours())}:${pad(at.getMinutes())}`;
|
|
11728
|
+
const sameDay = at.getFullYear() === now.getFullYear() && at.getMonth() === now.getMonth() && at.getDate() === now.getDate();
|
|
11729
|
+
return sameDay ? time : `${pad(at.getMonth() + 1)}-${pad(at.getDate())} ${time}`;
|
|
11730
|
+
}
|
|
11731
|
+
var RESET_HINT_VALUE_RE = /^(?:resets?\s+(?:in|at)\s*|retry[-_\s]?after\s*[:=]?\s*(?:in\s+)?)(.*)$/i;
|
|
11732
|
+
var RESET_HINT_DURATION_RE = /^(?:(\d+)\s*d(?:ays?)?)?\s*(?:(\d+)\s*h(?:ours?|rs?)?)?\s*(?:(\d+)\s*m(?:in(?:ute)?s?)?)?\s*(?:(\d+)\s*s(?:ec(?:ond)?s?)?)?$/i;
|
|
11733
|
+
var RESET_HINT_ABSOLUTE_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}/;
|
|
11734
|
+
var RESET_HINT_IN_BRANCH_RE = /^resets?\s+in\b/i;
|
|
11735
|
+
var RESET_HINT_UNIT_IN_VALUE_RE = new RegExp(String.raw`\d\s*${RESET_HINT_UNIT}`, "i");
|
|
11736
|
+
function parseResetHintSeconds(value) {
|
|
11737
|
+
if (/^\d+$/.test(value)) return Number(value);
|
|
11738
|
+
const match = RESET_HINT_DURATION_RE.exec(value);
|
|
11739
|
+
if (!match || !match.slice(1).some(Boolean)) return void 0;
|
|
11740
|
+
const [days, hours, minutes, seconds] = match.slice(1).map((part) => Number(part ?? 0));
|
|
11741
|
+
return days * 86400 + hours * 3600 + minutes * 60 + seconds;
|
|
11742
|
+
}
|
|
11743
|
+
function formatRateLimitResetHint(hint, locale) {
|
|
11744
|
+
const value = (RESET_HINT_VALUE_RE.exec(hint.trim())?.[1] ?? hint).trim();
|
|
11745
|
+
if (!value) return void 0;
|
|
11746
|
+
if (RESET_HINT_IN_BRANCH_RE.test(hint.trim()) && !RESET_HINT_UNIT_IN_VALUE_RE.test(value)) {
|
|
11747
|
+
return void 0;
|
|
11748
|
+
}
|
|
11749
|
+
if (RESET_HINT_ABSOLUTE_RE.test(value)) return formatCooldownUntilLocal(value);
|
|
11750
|
+
const seconds = parseResetHintSeconds(value);
|
|
11751
|
+
if (seconds === void 0) return value;
|
|
11752
|
+
const minutes = Math.round(seconds / 60);
|
|
11753
|
+
const zh = locale === "zh";
|
|
11754
|
+
if (minutes < 1) return zh ? "<1 \u5206\u949F" : "<1m";
|
|
11755
|
+
const days = Math.floor(minutes / 1440);
|
|
11756
|
+
const hours = Math.floor(minutes % 1440 / 60);
|
|
11757
|
+
const rest = minutes % 60;
|
|
11758
|
+
const parts = [];
|
|
11759
|
+
if (days > 0) parts.push(zh ? `${days} \u5929` : `${days}d`);
|
|
11760
|
+
if (hours > 0) parts.push(zh ? `${hours} \u5C0F\u65F6` : `${hours}h`);
|
|
11761
|
+
if (rest > 0) parts.push(zh ? `${rest} \u5206` : `${rest}m`);
|
|
11762
|
+
return parts.join(" ");
|
|
11113
11763
|
}
|
|
11114
11764
|
function buildRateLimitFailure(ctx) {
|
|
11115
|
-
const
|
|
11116
|
-
const
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11765
|
+
const headlineKey = ctx.quotaExhausted ? "localRunRateLimitQuota" : "localRunRateLimitThrottled";
|
|
11766
|
+
const lines = [
|
|
11767
|
+
t(
|
|
11768
|
+
headlineKey,
|
|
11769
|
+
describeUpstreamTag(ctx),
|
|
11770
|
+
sanitizeRateLimitDetail(ctx.message, Boolean(ctx.cooldownUntil))
|
|
11771
|
+
)
|
|
11772
|
+
];
|
|
11773
|
+
const cooldownUntil = ctx.cooldownUntil;
|
|
11774
|
+
if (cooldownUntil) {
|
|
11775
|
+
const resetValue = formatRateLimitResetHint(
|
|
11776
|
+
extractRateLimitResetHint(ctx.message) ?? "",
|
|
11777
|
+
getCliLocale()
|
|
11778
|
+
);
|
|
11779
|
+
lines.push(
|
|
11780
|
+
t(
|
|
11781
|
+
"localRunRateLimitCooldown",
|
|
11782
|
+
formatCooldownUntilLocal(cooldownUntil),
|
|
11783
|
+
resetValue ? t("localRunRateLimitResetNote", resetValue) : "",
|
|
11784
|
+
String(Math.round(PROBE_INTERVAL_MS / 6e4))
|
|
11785
|
+
)
|
|
11786
|
+
);
|
|
11787
|
+
}
|
|
11788
|
+
lines.push(t("localRunRateLimitExits"));
|
|
11789
|
+
return `${lines.join("\n")}
|
|
11790
|
+
`;
|
|
11791
|
+
}
|
|
11792
|
+
var BALANCE_DETAIL_MAX_CHARS = RATE_LIMIT_DETAIL_MAX_CHARS;
|
|
11793
|
+
function stripEmbeddedErrorJson(message) {
|
|
11794
|
+
const KEY = '{"error"';
|
|
11795
|
+
let out = message;
|
|
11796
|
+
let searchFrom = 0;
|
|
11797
|
+
for (; ; ) {
|
|
11798
|
+
const keyIndex = out.indexOf(KEY, searchFrom);
|
|
11799
|
+
if (keyIndex === -1) return out;
|
|
11800
|
+
const endIndex = findJsonObjectEnd(out, keyIndex);
|
|
11801
|
+
if (endIndex === -1) return out;
|
|
11802
|
+
out = `${out.slice(0, keyIndex)} ${out.slice(endIndex)}`;
|
|
11803
|
+
searchFrom = keyIndex;
|
|
11804
|
+
}
|
|
11805
|
+
}
|
|
11806
|
+
function sanitizeBalanceDetail(message) {
|
|
11807
|
+
const withoutNoise = stripEmbeddedErrorJson(stripDebugNoise(message));
|
|
11808
|
+
const detail = stripControlChars(
|
|
11809
|
+
stripZeroWidthChars(stripRateLimitTransportPrefix(withoutNoise))
|
|
11810
|
+
).replace(/(\d{3})\[/g, "$1 [").replace(/\s+/g, " ").replace(/([.。!!??])\s+(?=[.。!!??])/g, "").replace(/([.。!!??])\1+/g, "$1").replace(/[\s,;:,;:]+$/, "").trim();
|
|
11811
|
+
return detail.length > BALANCE_DETAIL_MAX_CHARS ? `${detail.slice(0, BALANCE_DETAIL_MAX_CHARS - 1).trimEnd()}\u2026` : detail;
|
|
11812
|
+
}
|
|
11813
|
+
function extractBalanceErrorMarker(message) {
|
|
11814
|
+
const bodyStart = message.indexOf('{"error"');
|
|
11815
|
+
const body = bodyStart === -1 ? message : message.slice(bodyStart);
|
|
11816
|
+
const match = /"(?:code|type|status)"\s*:\s*"([^"\\]{1,60})"/.exec(body);
|
|
11817
|
+
const marker = match?.[1].trim();
|
|
11818
|
+
return marker ? marker : void 0;
|
|
11819
|
+
}
|
|
11820
|
+
function extractBalanceResetAt(message) {
|
|
11821
|
+
const text = stripZeroWidthChars(message);
|
|
11822
|
+
const iso = /"reset_at"\s*:\s*"([^"]+)"/.exec(text)?.[1];
|
|
11823
|
+
if (iso) {
|
|
11824
|
+
const at2 = new Date(iso.trim());
|
|
11825
|
+
return Number.isNaN(at2.getTime()) ? void 0 : at2.getTime();
|
|
11826
|
+
}
|
|
11827
|
+
const epoch = /"reset_at"\s*:\s*(\d{9,16})/.exec(text)?.[1];
|
|
11828
|
+
if (!epoch) return void 0;
|
|
11829
|
+
const value = Number(epoch);
|
|
11830
|
+
if (!Number.isFinite(value)) return void 0;
|
|
11831
|
+
const at = new Date(value >= 1e12 ? value : value * 1e3);
|
|
11832
|
+
return Number.isNaN(at.getTime()) ? void 0 : at.getTime();
|
|
11833
|
+
}
|
|
11834
|
+
function buildBalanceFailure(ctx) {
|
|
11835
|
+
const normalized = stripZeroWidthChars(ctx.message);
|
|
11836
|
+
const balanceDetails = parseEmbeddedBalanceDetails(normalized);
|
|
11837
|
+
const reason = balanceDetails ? t("balanceInsufficientReason", balanceDetails.required, balanceDetails.current) : sanitizeBalanceDetail(extractEmbeddedErrorMessage(normalized) ?? ctx.message) || extractBalanceErrorMarker(normalized) || t("localRunBalanceUnknownReason");
|
|
11838
|
+
const lines = [
|
|
11839
|
+
t(
|
|
11840
|
+
CODING_PLAN_EXHAUSTED_RE.test(normalized) ? "localRunBalanceCodingPlan" : "localRunBalanceExhausted",
|
|
11841
|
+
describeUpstreamTag(ctx),
|
|
11842
|
+
reason
|
|
11843
|
+
)
|
|
11844
|
+
];
|
|
11845
|
+
const resetAt = extractBalanceResetAt(normalized);
|
|
11846
|
+
if (resetAt !== void 0 && resetAt > Date.now()) {
|
|
11847
|
+
lines.push(
|
|
11848
|
+
t(
|
|
11849
|
+
"localRunBalanceReset",
|
|
11850
|
+
formatCooldownUntilLocal(new Date(resetAt).toISOString())
|
|
11851
|
+
)
|
|
11852
|
+
);
|
|
11853
|
+
}
|
|
11854
|
+
lines.push(t("localRunBalanceExits"));
|
|
11855
|
+
return `${lines.join("\n")}
|
|
11121
11856
|
`;
|
|
11122
11857
|
}
|
|
11123
11858
|
function buildTransientFailure(ctx) {
|
|
11124
|
-
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}; this is an upstream/gateway issue, not your local credential or config). Detail: ${ctx.message} ${NO_FALLBACK} Retry shortly, ${SERVER_FALLBACK_HINT}
|
|
11859
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}; this is an upstream/gateway issue, not your local credential or config). Detail: ${ctx.message} ${NO_FALLBACK} Retry shortly, ${SERVER_FALLBACK_HINT}
|
|
11125
11860
|
`;
|
|
11126
11861
|
}
|
|
11127
11862
|
function buildUpstreamFailure(ctx) {
|
|
11128
11863
|
const fix = ctx.where === "server chat proxy" ? `Check the agent's provider/api-key settings on nolo.chat` : `Check the agent's endpoint/model settings`;
|
|
11129
|
-
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}
|
|
11864
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}
|
|
11130
11865
|
`;
|
|
11131
11866
|
}
|
|
11132
11867
|
function formatLocalTurnFailureLine(error) {
|
|
@@ -11137,6 +11872,17 @@ function formatLocalTurnFailureLine(error) {
|
|
|
11137
11872
|
return `[nolo] ${t("llmRequestTimedOut", deadline)}
|
|
11138
11873
|
`;
|
|
11139
11874
|
}
|
|
11875
|
+
const cls = classifyLocalRunError(message);
|
|
11876
|
+
if (cls.kind === "rate-limit") {
|
|
11877
|
+
const rawCooldownUntil = error && typeof error === "object" ? error.cooldownUntil : void 0;
|
|
11878
|
+
return buildRateLimitFailure({
|
|
11879
|
+
message,
|
|
11880
|
+
where: "local provider",
|
|
11881
|
+
status: cls.status,
|
|
11882
|
+
...cls.quotaExhausted ? { quotaExhausted: true } : {},
|
|
11883
|
+
...typeof rawCooldownUntil === "string" && rawCooldownUntil ? { cooldownUntil: rawCooldownUntil } : {}
|
|
11884
|
+
});
|
|
11885
|
+
}
|
|
11140
11886
|
return `[nolo] Local agent run failed: ${message}
|
|
11141
11887
|
`;
|
|
11142
11888
|
}
|
|
@@ -11167,22 +11913,11 @@ function describeLocalRunFailure(message, rawError) {
|
|
|
11167
11913
|
return `${RUN_UNAVAILABLE_PREFIX} \u670D\u52A1\u5668\u7D27\u5F20${shown !== "\u670D\u52A1\u5668\u7D27\u5F20" ? ` (${shown})` : ""} (PLATFORM_LLM_BUSY)${cleanedBusyDetail ? `: ${cleanedBusyDetail}` : ""}. ${NO_FALLBACK} \u5E73\u53F0\u6A21\u578B\u4E0A\u6E38\u7E41\u5FD9\uFF0C\u7A0D\u540E\u91CD\u8BD5\u6216\u6362\u4E2A\u6A21\u578B\u3002Retry shortly, ${SERVER_FALLBACK_HINT}
|
|
11168
11914
|
`;
|
|
11169
11915
|
}
|
|
11170
|
-
if (
|
|
11171
|
-
|
|
11172
|
-
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
/^[^:]*provider failed: HTTP \d{3}\s*/,
|
|
11176
|
-
""
|
|
11177
|
-
);
|
|
11178
|
-
const balanceDetails = parseEmbeddedBalanceDetails(cleanedMessage);
|
|
11179
|
-
const shownMessage = balanceDetails ? t(
|
|
11180
|
-
"balanceInsufficientReason",
|
|
11181
|
-
balanceDetails.required,
|
|
11182
|
-
balanceDetails.current
|
|
11183
|
-
) : extractEmbeddedErrorMessage(cleanedMessage) ?? fallback;
|
|
11184
|
-
return `[nolo] ${shownMessage}
|
|
11185
|
-
`;
|
|
11916
|
+
if (matchesBalanceError(message)) {
|
|
11917
|
+
return buildBalanceFailure({
|
|
11918
|
+
message,
|
|
11919
|
+
where: PLATFORM_TRANSPORT_RE.test(message) ? "server chat proxy" : "local provider"
|
|
11920
|
+
});
|
|
11186
11921
|
}
|
|
11187
11922
|
if (/maximum context length/i.test(message)) {
|
|
11188
11923
|
const details = parseContextLengthDetails(message);
|
|
@@ -11192,31 +11927,39 @@ function describeLocalRunFailure(message, rawError) {
|
|
|
11192
11927
|
}
|
|
11193
11928
|
if (isCliAuthorityBrokerTimeoutError(rawError) || /CLI authority broker .* timed out/i.test(message)) {
|
|
11194
11929
|
const cleaned = stripDebugNoise(message);
|
|
11195
|
-
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker timed out and did not respond in time (an existing broker process may be unresponsive). Check the local broker process or retry, ${SERVER_FALLBACK_HINT}
|
|
11930
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker timed out and did not respond in time (an existing broker process may be unresponsive). Check the local broker process or retry, ${SERVER_FALLBACK_HINT}
|
|
11196
11931
|
`;
|
|
11197
11932
|
}
|
|
11198
11933
|
if (/CLI authority broker could not attach or take ownership/i.test(message)) {
|
|
11199
11934
|
const cleaned = stripDebugNoise(message);
|
|
11200
|
-
|
|
11935
|
+
if (/EADDRINUSE/i.test(message)) {
|
|
11936
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} Use --server to run on the server explicitly.
|
|
11937
|
+
`;
|
|
11938
|
+
}
|
|
11939
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local runtime could not attach to an existing broker or take database ownership. Check running broker processes holding the local authority store or retry, ${SERVER_FALLBACK_HINT}
|
|
11201
11940
|
`;
|
|
11202
11941
|
}
|
|
11203
11942
|
if (isCliAuthorityBrokerUnavailableError(rawError) || /CLI authority broker unavailable at/i.test(message)) {
|
|
11204
11943
|
const cleaned = stripDebugNoise(message);
|
|
11205
|
-
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker is unavailable. Start or restart the local authority broker and retry, ${SERVER_FALLBACK_HINT}
|
|
11944
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker is unavailable. Start or restart the local authority broker and retry, ${SERVER_FALLBACK_HINT}
|
|
11206
11945
|
`;
|
|
11207
11946
|
}
|
|
11208
11947
|
if (isCliAuthorityBrokerProtocolError(rawError) || /CLI authority broker protocol|CLI authority broker .* returned malformed response/i.test(message)) {
|
|
11209
11948
|
const cleaned = stripDebugNoise(message);
|
|
11210
|
-
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker returned a protocol or malformed response error. Check the running broker process and retry, ${SERVER_FALLBACK_HINT}
|
|
11949
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker returned a protocol or malformed response error. Check the running broker process and retry, ${SERVER_FALLBACK_HINT}
|
|
11211
11950
|
`;
|
|
11212
11951
|
}
|
|
11213
11952
|
const cls = classifyLocalRunError(message);
|
|
11214
11953
|
if (cls.kind === "generic") {
|
|
11954
|
+
if (/owner-required route not acknowledged/i.test(message)) {
|
|
11955
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${message}). ${NO_FALLBACK} The server returned a successful response but did not acknowledge the owner route. Check server version or proxy configuration, ${SERVER_FALLBACK_HINT}
|
|
11956
|
+
`;
|
|
11957
|
+
}
|
|
11215
11958
|
if (isTransientFetchError(message)) {
|
|
11216
11959
|
return `${RUN_UNAVAILABLE_PREFIX} (${message}). ${NO_FALLBACK} The upstream connection dropped mid-request (transient network/gateway issue \u2014 not a local credential or config problem). Send again (or say "continue") to retry in the same conversation.
|
|
11217
11960
|
`;
|
|
11218
11961
|
}
|
|
11219
|
-
return `${RUN_UNAVAILABLE_PREFIX} (${message}). ${NO_FALLBACK} Fix the local credential/config and retry, ${SERVER_FALLBACK_HINT}
|
|
11962
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${message}). ${NO_FALLBACK} Fix the local credential/config and retry, ${SERVER_FALLBACK_HINT}
|
|
11220
11963
|
`;
|
|
11221
11964
|
}
|
|
11222
11965
|
const cooldownUntil = rawError && typeof rawError === "object" ? rawError.cooldownUntil : void 0;
|
|
@@ -11224,7 +11967,6 @@ function describeLocalRunFailure(message, rawError) {
|
|
|
11224
11967
|
message,
|
|
11225
11968
|
where: cls.transport === "platform" ? "server chat proxy" : "local provider",
|
|
11226
11969
|
status: cls.status,
|
|
11227
|
-
...cls.statusInferred ? { statusInferred: true } : {},
|
|
11228
11970
|
...cls.quotaExhausted ? { quotaExhausted: true } : {},
|
|
11229
11971
|
...cooldownUntil ? { cooldownUntil } : {},
|
|
11230
11972
|
...credentialAccountId ? { credentialAccountId } : {}
|
|
@@ -11321,8 +12063,10 @@ async function runHttpAgentTurn(options, authToken) {
|
|
|
11321
12063
|
...options.dialogAgentMode ? { dialogAgentMode: options.dialogAgentMode } : {},
|
|
11322
12064
|
...subjectRefs ? { subjectRefs } : {},
|
|
11323
12065
|
...blockedToolNames !== void 0 ? { blockedToolNames } : {},
|
|
11324
|
-
...allowedToolNames !== void 0 ? { allowedToolNames } : {}
|
|
12066
|
+
...allowedToolNames !== void 0 ? { allowedToolNames } : {},
|
|
12067
|
+
...options.runtimeToolPolicyOverride ? { runtimeToolPolicyOverride: options.runtimeToolPolicyOverride } : {}
|
|
11325
12068
|
},
|
|
12069
|
+
...options.strictContinueHistory ? { strictContinueHistory: true } : {},
|
|
11326
12070
|
...options.continueDialogId ? { continueDialogId: options.continueDialogId } : {},
|
|
11327
12071
|
...options.spaceId ? { spaceId: options.spaceId } : {},
|
|
11328
12072
|
...options.category ? { category: options.category } : {},
|
|
@@ -11330,6 +12074,7 @@ async function runHttpAgentTurn(options, authToken) {
|
|
|
11330
12074
|
...options.parentDialogId ? { parentDialogId: options.parentDialogId } : {},
|
|
11331
12075
|
...options.background ? { background: true } : {},
|
|
11332
12076
|
...options.ephemeral ? { ephemeral: true } : {},
|
|
12077
|
+
...options.runtimeKey ? { runtimeKey: options.runtimeKey } : {},
|
|
11333
12078
|
...typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : {},
|
|
11334
12079
|
...options.modelOverride ? { runtimeOptions: { quickChatModelOverride: options.modelOverride } } : {},
|
|
11335
12080
|
...serverContextBlockScopes ? { contextBlockScopes: serverContextBlockScopes } : {},
|
|
@@ -11440,15 +12185,24 @@ ${options.agentName} > (no text response)
|
|
|
11440
12185
|
const turnCredits = platformCreditsFromUsage(
|
|
11441
12186
|
data?.usage
|
|
11442
12187
|
);
|
|
11443
|
-
|
|
12188
|
+
const serverResult = {
|
|
11444
12189
|
exitCode: 0,
|
|
11445
12190
|
...typeof data?.dialogId === "string" && data.dialogId ? { dialogId: data.dialogId } : {},
|
|
12191
|
+
// 结论载体与 local 路径同契约(server 模式 / 本地配置缺失时的兜底通道):
|
|
12192
|
+
// 结算点只认 result.finalText,HTTP 派发不给就等于这批 run 没有结论载体,
|
|
12193
|
+
// status 里既无 lastAssistantText 也无 resultFile。content 已在上面算好。
|
|
12194
|
+
...content ? { finalText: content } : {},
|
|
11446
12195
|
turnTokens: buildTurnTokenUsage(
|
|
11447
12196
|
data?.usage,
|
|
11448
12197
|
typeof data?.model === "string" ? data.model : options.agentKey
|
|
11449
12198
|
),
|
|
11450
12199
|
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
11451
12200
|
};
|
|
12201
|
+
recordRunResultHeaderMeta(serverResult, {
|
|
12202
|
+
model: typeof data?.model === "string" ? data.model : void 0,
|
|
12203
|
+
dialogServer: serverOriginForDialog(options.serverUrl)
|
|
12204
|
+
});
|
|
12205
|
+
return serverResult;
|
|
11452
12206
|
}
|
|
11453
12207
|
async function runInjectedLocalAgentTurn(options) {
|
|
11454
12208
|
return runLocalAgentTurnForCli(options, { reportFailure: true });
|
|
@@ -11459,8 +12213,40 @@ async function refreshMissingLocalAgentConfig(options) {
|
|
|
11459
12213
|
const agentConfig = await adapter.loadAgentConfig(options.agentKey);
|
|
11460
12214
|
return Boolean(agentConfig);
|
|
11461
12215
|
}
|
|
12216
|
+
async function releaseAdapterSandboxWorkload(adapter) {
|
|
12217
|
+
const release = adapter?.releaseLocalSandboxWorkload;
|
|
12218
|
+
if (typeof release !== "function") return;
|
|
12219
|
+
try {
|
|
12220
|
+
await release.call(adapter);
|
|
12221
|
+
} catch {
|
|
12222
|
+
}
|
|
12223
|
+
}
|
|
11462
12224
|
async function runLocalAgentTurnForCli(options, settings) {
|
|
11463
12225
|
const resolvedBaseAdapter = resolveLocalRuntimeAdapter(options);
|
|
12226
|
+
try {
|
|
12227
|
+
if (options.runtimeKey) {
|
|
12228
|
+
const prepare = resolvedBaseAdapter?.prepareLocalRuntimeWorkload;
|
|
12229
|
+
if (typeof prepare === "function") {
|
|
12230
|
+
try {
|
|
12231
|
+
await prepare.call(resolvedBaseAdapter);
|
|
12232
|
+
} catch (error) {
|
|
12233
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12234
|
+
options.output.write(`[nolo] ${message}
|
|
12235
|
+
`);
|
|
12236
|
+
return { exitCode: 1, localError: error };
|
|
12237
|
+
}
|
|
12238
|
+
}
|
|
12239
|
+
}
|
|
12240
|
+
return await runLocalAgentTurnForCliWithAdapter(
|
|
12241
|
+
options,
|
|
12242
|
+
settings,
|
|
12243
|
+
resolvedBaseAdapter
|
|
12244
|
+
);
|
|
12245
|
+
} finally {
|
|
12246
|
+
await releaseAdapterSandboxWorkload(resolvedBaseAdapter);
|
|
12247
|
+
}
|
|
12248
|
+
}
|
|
12249
|
+
async function runLocalAgentTurnForCliWithAdapter(options, settings, resolvedBaseAdapter) {
|
|
11464
12250
|
const baseAdapter = (() => {
|
|
11465
12251
|
let adapter2 = resolvedBaseAdapter && options.modelOverride ? wrapLoadAgentConfigWithModelOverride(
|
|
11466
12252
|
resolvedBaseAdapter,
|
|
@@ -11483,15 +12269,17 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
11483
12269
|
const blockedToolNames = options.blockedToolNames?.filter(
|
|
11484
12270
|
(name) => name.trim()
|
|
11485
12271
|
);
|
|
11486
|
-
const runtimeContext = subjectRefs || allowedToolNames !== void 0 || blockedToolNames !== void 0 || options.parentWakeOnTerminal || options.dialogAgentMode ? {
|
|
12272
|
+
const runtimeContext = subjectRefs || allowedToolNames !== void 0 || blockedToolNames !== void 0 || options.runtimeToolPolicyOverride || options.parentWakeOnTerminal || options.dialogAgentMode ? {
|
|
11487
12273
|
...subjectRefs ? { subjectRefs } : {},
|
|
11488
12274
|
...options.dialogAgentMode ? { dialogAgentMode: options.dialogAgentMode } : {},
|
|
11489
12275
|
...allowedToolNames !== void 0 ? { allowedToolNames } : {},
|
|
11490
12276
|
...blockedToolNames !== void 0 ? { blockedToolNames } : {},
|
|
12277
|
+
...options.runtimeToolPolicyOverride ? { runtimeToolPolicyOverride: options.runtimeToolPolicyOverride } : {},
|
|
11491
12278
|
...options.parentWakeOnTerminal ? { parentWakeOnTerminal: true } : {},
|
|
11492
12279
|
...options.parentDialogId ? { parentThreadId: options.parentDialogId } : {}
|
|
11493
12280
|
} : void 0;
|
|
11494
12281
|
const currentDialogId = options.continueDialogId ?? ulid2();
|
|
12282
|
+
const freshDialog = options.freshDialog ?? !options.continueDialogId;
|
|
11495
12283
|
const turnId = `turn-${ulid2()}`;
|
|
11496
12284
|
const runtimeContextWithOwnership = {
|
|
11497
12285
|
...runtimeContext ?? {},
|
|
@@ -11507,26 +12295,44 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
11507
12295
|
});
|
|
11508
12296
|
turnOutput.spinner.start();
|
|
11509
12297
|
try {
|
|
12298
|
+
const localAttachmentPaths = (options.localAttachmentPaths ?? []).filter(
|
|
12299
|
+
(p) => typeof p === "string" && p.trim().length > 0
|
|
12300
|
+
);
|
|
12301
|
+
const { cardText: localAttachmentCard, parts: localAttachmentParts } = buildLocalAttachments({
|
|
12302
|
+
paths: localAttachmentPaths,
|
|
12303
|
+
machineId: localAttachmentPaths.length > 0 ? await resolveCurrentMachineId(options) : void 0,
|
|
12304
|
+
...options.localRuntimeCwd ? { workspaceRoot: options.localRuntimeCwd } : {}
|
|
12305
|
+
});
|
|
12306
|
+
const messageForLocal = appendAttachmentCard(options.message, localAttachmentCard);
|
|
12307
|
+
const durableAttachmentParts = ENABLE_REMOTE_ATTACHMENT_PART_WRITES ? localAttachmentParts : [];
|
|
12308
|
+
const hasDurableAttachments = durableAttachmentParts.length > 0;
|
|
11510
12309
|
const runLocalAgentTurn = await loadRunLocalAgentTurn();
|
|
11511
12310
|
const result = await runLocalAgentTurn({
|
|
11512
12311
|
adapter,
|
|
11513
12312
|
agentRef: options.agentKey,
|
|
11514
12313
|
userLanguage: options.userLanguage ?? options.env.NOLO_LANG ?? null,
|
|
11515
|
-
input: buildUserInputContent(
|
|
11516
|
-
...expandedMessage !== options.message ? {
|
|
11517
|
-
persistedInput: buildUserInputContent(
|
|
12314
|
+
input: buildUserInputContent(messageForLocal, options.imageUrls),
|
|
12315
|
+
...expandedMessage !== options.message || localAttachmentCard !== "" ? {
|
|
12316
|
+
persistedInput: hasDurableAttachments ? buildUserInputContent(
|
|
11518
12317
|
expandedMessage,
|
|
12318
|
+
options.imageUrls,
|
|
12319
|
+
durableAttachmentParts
|
|
12320
|
+
) : buildUserInputContent(
|
|
12321
|
+
appendAttachmentCard(expandedMessage, localAttachmentCard),
|
|
11519
12322
|
options.imageUrls
|
|
11520
12323
|
),
|
|
11521
|
-
persistedInputReference: buildUserInputContent(
|
|
12324
|
+
persistedInputReference: hasDurableAttachments ? buildUserInputContent(
|
|
11522
12325
|
options.message,
|
|
11523
|
-
options.imageUrls
|
|
11524
|
-
|
|
12326
|
+
options.imageUrls,
|
|
12327
|
+
durableAttachmentParts
|
|
12328
|
+
) : buildUserInputContent(messageForLocal, options.imageUrls)
|
|
11525
12329
|
} : {},
|
|
11526
12330
|
...options.pastedTextStore ? {
|
|
11527
12331
|
contextReferenceResolver: (reference) => canResolveCollapsedPasteReference(options.pastedTextStore, reference)
|
|
11528
12332
|
} : {},
|
|
11529
12333
|
continueDialogId: currentDialogId,
|
|
12334
|
+
...options.strictContinueHistory ? { strictContinueHistory: true } : {},
|
|
12335
|
+
...freshDialog ? { freshDialog: true } : {},
|
|
11530
12336
|
fileWriteSessionId: currentDialogId,
|
|
11531
12337
|
fileWriteGateEnabled: resolveFileWriteGateEnabled(options.env),
|
|
11532
12338
|
spaceId: options.spaceId,
|
|
@@ -11585,9 +12391,10 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
11585
12391
|
});
|
|
11586
12392
|
turnOutput.finish(result.content);
|
|
11587
12393
|
const turnCredits = sumPlatformCredits(result.usageRecords);
|
|
11588
|
-
|
|
12394
|
+
const turnResult = {
|
|
11589
12395
|
exitCode: 0,
|
|
11590
12396
|
dialogId: result.dialogId,
|
|
12397
|
+
...typeof result.content === "string" && result.content.trim() ? { finalText: result.content } : {},
|
|
11591
12398
|
title: result.title,
|
|
11592
12399
|
...result.titlePatchPromise ? { titlePatchPromise: result.titlePatchPromise } : {},
|
|
11593
12400
|
...pickEmptyAssistantFlags(result),
|
|
@@ -11599,6 +12406,17 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
11599
12406
|
...turnCredits !== void 0 ? { turnCredits } : {},
|
|
11600
12407
|
...result.usageRecords?.length ? { usageRecords: result.usageRecords } : {}
|
|
11601
12408
|
};
|
|
12409
|
+
const serverMeta = resolveResultServerMeta({
|
|
12410
|
+
env: options.env ?? {},
|
|
12411
|
+
userId: resolveLocalUserId(options.env ?? {}),
|
|
12412
|
+
hasSubjectRefs: (buildSubjectRefs(options)?.length ?? 0) > 0
|
|
12413
|
+
});
|
|
12414
|
+
recordRunResultHeaderMeta(turnResult, {
|
|
12415
|
+
model: result.model,
|
|
12416
|
+
dialogServer: serverMeta.server,
|
|
12417
|
+
serverSync: serverMeta.serverSync
|
|
12418
|
+
});
|
|
12419
|
+
return turnResult;
|
|
11602
12420
|
} catch (error) {
|
|
11603
12421
|
turnOutput.spinner.stop();
|
|
11604
12422
|
turnOutput.cancel({
|
|
@@ -11633,12 +12451,6 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
11633
12451
|
} else {
|
|
11634
12452
|
options.output.write(failureLine);
|
|
11635
12453
|
}
|
|
11636
|
-
if (cooldownUntil) {
|
|
11637
|
-
options.output.write(
|
|
11638
|
-
`[nolo] \u5DF2\u6807\u8BB0\u51B7\u5374\u81F3 ${cooldownUntil}\uFF0C\u5230\u671F\u524D\u6D3E\u53D1\u8BE5 agent \u4F1A\u88AB\u51B7\u5374\u95E8\u63A7\u62E6\u622A\u3002
|
|
11639
|
-
`
|
|
11640
|
-
);
|
|
11641
|
-
}
|
|
11642
12454
|
}
|
|
11643
12455
|
return {
|
|
11644
12456
|
exitCode: 1,
|
|
@@ -11650,6 +12462,7 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
11650
12462
|
}
|
|
11651
12463
|
}
|
|
11652
12464
|
async function checkLocalAvailabilityBeforeHttpDispatch(options) {
|
|
12465
|
+
if (options.runtimeKey && !isDockerRuntimeKey(options.runtimeKey)) return null;
|
|
11653
12466
|
const adapter = resolveLocalRuntimeAdapter(options);
|
|
11654
12467
|
if (!adapter || typeof adapter.loadAgentConfig !== "function") return null;
|
|
11655
12468
|
let config;
|
|
@@ -11688,14 +12501,19 @@ async function checkLocalAvailabilityBeforeHttpDispatch(options) {
|
|
|
11688
12501
|
}
|
|
11689
12502
|
if (gateDecision !== "blocked") return { credentialKey };
|
|
11690
12503
|
options.output.write(
|
|
11691
|
-
|
|
11692
|
-
|
|
12504
|
+
`${t(
|
|
12505
|
+
"agentCooldownBlocked",
|
|
12506
|
+
options.agentName || options.agentKey,
|
|
12507
|
+
formatCooldownUntilLocal(
|
|
12508
|
+
new Date(Number(effectiveNextAvailableAt)).toISOString()
|
|
12509
|
+
)
|
|
12510
|
+
)}
|
|
11693
12511
|
`
|
|
11694
12512
|
);
|
|
11695
12513
|
return { exitCode: 1 };
|
|
11696
12514
|
}
|
|
11697
12515
|
function foldLocalResultForTui(localResult) {
|
|
11698
|
-
|
|
12516
|
+
const folded = {
|
|
11699
12517
|
exitCode: localResult.exitCode,
|
|
11700
12518
|
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
11701
12519
|
title: localResult.title,
|
|
@@ -11712,16 +12530,57 @@ function foldLocalResultForTui(localResult) {
|
|
|
11712
12530
|
// 漏过 turnCredits(fix/tui-session-credits),usageRecords 是同坑位新字段。
|
|
11713
12531
|
...localResult.usageRecords?.length ? { usageRecords: localResult.usageRecords } : {},
|
|
11714
12532
|
...localResult.streamInterrupted ? { streamInterrupted: localResult.streamInterrupted } : {},
|
|
11715
|
-
...localResult.pendingToolName ? { pendingToolName: localResult.pendingToolName } : {}
|
|
12533
|
+
...localResult.pendingToolName ? { pendingToolName: localResult.pendingToolName } : {},
|
|
12534
|
+
// 结论正文必须随行:auto→local 是本函数的唯一出口(runAgentTurn 的两处
|
|
12535
|
+
// 成功分支都 return foldLocalResultForTui(...)),漏掉它 = 默认派发路径
|
|
12536
|
+
// 上 finalText 永远到不了结算点 → agentRunCommand 的 settleRunTerminal-
|
|
12537
|
+
// Authoritatively 拿不到 lastAssistantText → `.result.md` 不写、status 无
|
|
12538
|
+
// resultFile,编排者只能去啃带 ANSI 的 .log(同坑位历史:turnCredits)。
|
|
12539
|
+
...localResult.finalText ? { finalText: localResult.finalText } : {}
|
|
11716
12540
|
};
|
|
12541
|
+
const headerMeta = getRunResultHeaderMeta(localResult);
|
|
12542
|
+
recordRunResultHeaderMeta(folded, headerMeta);
|
|
12543
|
+
return folded;
|
|
11717
12544
|
}
|
|
11718
12545
|
async function runAgentTurn(options) {
|
|
11719
12546
|
const authToken = resolveAuthToken2(options.env);
|
|
11720
|
-
const
|
|
12547
|
+
const requestedRuntimeMode = resolveRequestedRuntimeMode(options);
|
|
12548
|
+
if (options.requireRemoteDispatch && requestedRuntimeMode === "local") {
|
|
12549
|
+
options.output.write(MACHINE_SHELL_LOCAL_REFUSAL_MESSAGE);
|
|
12550
|
+
return { exitCode: 1 };
|
|
12551
|
+
}
|
|
12552
|
+
const runtimeMode = options.requireRemoteDispatch ? "server" : requestedRuntimeMode;
|
|
11721
12553
|
if (runtimeMode === "local") {
|
|
12554
|
+
const runtimeKeyIsLocallyFulfillable = resolveCliLocalRuntimeKeyCapability(options.runtimeKey).fulfillableByCliLocal;
|
|
12555
|
+
if (options.runtimeKey && !runtimeKeyIsLocallyFulfillable) {
|
|
12556
|
+
options.output.write("[nolo] \u672C\u5730 run \u7531\u672C\u673A\u6C99\u76D2\u51B3\u5B9A\uFF0C\u4E0D\u652F\u6301\u6307\u5B9A\u4E91\u540E\u7AEF\n");
|
|
12557
|
+
return { exitCode: 1 };
|
|
12558
|
+
}
|
|
11722
12559
|
return runInjectedLocalAgentTurn(options);
|
|
11723
12560
|
}
|
|
11724
|
-
if (runtimeMode === "auto" && shouldAttemptAutoLocal(options)) {
|
|
12561
|
+
if (runtimeMode === "auto" && !options.runtimeKey && shouldAttemptAutoLocal(options)) {
|
|
12562
|
+
const rawAdapter = resolveLocalRuntimeAdapter(options);
|
|
12563
|
+
let config;
|
|
12564
|
+
const invalidateConfig = () => {
|
|
12565
|
+
config = void 0;
|
|
12566
|
+
};
|
|
12567
|
+
if (rawAdapter) {
|
|
12568
|
+
options = {
|
|
12569
|
+
...options,
|
|
12570
|
+
localRuntimeAdapter: {
|
|
12571
|
+
...rawAdapter,
|
|
12572
|
+
loadAgentConfig: async (agentRef) => {
|
|
12573
|
+
if (agentRef !== options.agentKey) {
|
|
12574
|
+
return rawAdapter.loadAgentConfig(agentRef);
|
|
12575
|
+
}
|
|
12576
|
+
if (config) return config;
|
|
12577
|
+
const loaded = await rawAdapter.loadAgentConfig(agentRef);
|
|
12578
|
+
if (loaded) config = loaded;
|
|
12579
|
+
return loaded;
|
|
12580
|
+
}
|
|
12581
|
+
}
|
|
12582
|
+
};
|
|
12583
|
+
}
|
|
11725
12584
|
const skipLocal = await shouldSkipAutoLocalForServerPlatformTools(options);
|
|
11726
12585
|
if (!skipLocal) {
|
|
11727
12586
|
const localResult = await runLocalAgentTurnForCli(options, {
|
|
@@ -11730,6 +12589,7 @@ async function runAgentTurn(options) {
|
|
|
11730
12589
|
if (localResult.exitCode === 0) {
|
|
11731
12590
|
return foldLocalResultForTui(localResult);
|
|
11732
12591
|
}
|
|
12592
|
+
invalidateConfig();
|
|
11733
12593
|
if (isMissingLocalAgentConfigError(localResult.localError, options.agentKey)) {
|
|
11734
12594
|
options.output.write(
|
|
11735
12595
|
`[nolo] Local agent config was missing; refreshing local config and retrying local once.
|
|
@@ -11744,8 +12604,10 @@ async function runAgentTurn(options) {
|
|
|
11744
12604
|
if (retriedLocalResult.exitCode === 0) {
|
|
11745
12605
|
return foldLocalResultForTui(retriedLocalResult);
|
|
11746
12606
|
}
|
|
12607
|
+
invalidateConfig();
|
|
11747
12608
|
}
|
|
11748
12609
|
} catch {
|
|
12610
|
+
invalidateConfig();
|
|
11749
12611
|
}
|
|
11750
12612
|
}
|
|
11751
12613
|
const localErrorMessage = localResult.localError ? toErrorMessage(localResult.localError) : "local runtime failed";
|
|
@@ -11783,23 +12645,204 @@ async function runAgentTurn(options) {
|
|
|
11783
12645
|
return httpResult;
|
|
11784
12646
|
}
|
|
11785
12647
|
|
|
12648
|
+
// packages/cli/client/terminalProgramStatus.ts
|
|
12649
|
+
var TERMINAL_PROGRAM_STATUS_APP = "nolo";
|
|
12650
|
+
var KNOWN_STATES = /* @__PURE__ */ new Set([
|
|
12651
|
+
"idle",
|
|
12652
|
+
"working",
|
|
12653
|
+
"blocked",
|
|
12654
|
+
"done",
|
|
12655
|
+
"error"
|
|
12656
|
+
]);
|
|
12657
|
+
var KNOWN_KINDS = /* @__PURE__ */ new Set([
|
|
12658
|
+
"permission",
|
|
12659
|
+
"question",
|
|
12660
|
+
"auth"
|
|
12661
|
+
]);
|
|
12662
|
+
function encodeTerminalProgramStatus(report) {
|
|
12663
|
+
const state2 = report?.state;
|
|
12664
|
+
if (typeof state2 !== "string" || !KNOWN_STATES.has(state2)) return null;
|
|
12665
|
+
const pairs = [`state=${state2}`, `app=${TERMINAL_PROGRAM_STATUS_APP}`];
|
|
12666
|
+
if (state2 === "blocked" && typeof report.kind === "string" && KNOWN_KINDS.has(report.kind)) {
|
|
12667
|
+
pairs.push(`kind=${report.kind}`);
|
|
12668
|
+
}
|
|
12669
|
+
return `\x1B]7501;${pairs.join(":")}\x1B\\`;
|
|
12670
|
+
}
|
|
12671
|
+
function emitTerminalProgramStatus(output, report) {
|
|
12672
|
+
if (!output || typeof output.write !== "function") return false;
|
|
12673
|
+
if (output.isTTY !== true) return false;
|
|
12674
|
+
const sequence2 = encodeTerminalProgramStatus(report);
|
|
12675
|
+
if (sequence2 === null) return false;
|
|
12676
|
+
try {
|
|
12677
|
+
output.write(sequence2);
|
|
12678
|
+
return true;
|
|
12679
|
+
} catch {
|
|
12680
|
+
return false;
|
|
12681
|
+
}
|
|
12682
|
+
}
|
|
12683
|
+
|
|
12684
|
+
// packages/cli/client/terminalRunStatus.ts
|
|
12685
|
+
var FAILED_EMPTY_ASSISTANT_REASONS = /* @__PURE__ */ new Set([
|
|
12686
|
+
"length_truncated",
|
|
12687
|
+
"stream_truncated",
|
|
12688
|
+
"repetition_loop",
|
|
12689
|
+
"stagnant_tool_calls"
|
|
12690
|
+
]);
|
|
12691
|
+
var isRunResultStalledOrTruncated = (result) => !result.emptyAssistantOutputUsable && FAILED_EMPTY_ASSISTANT_REASONS.has(result.emptyAssistantFallbackReason ?? "");
|
|
12692
|
+
function resolveTerminalProgramStatusState(input) {
|
|
12693
|
+
if (input.interrupted) return "idle";
|
|
12694
|
+
if (input.stalledOrTruncated || input.exitCode !== 0) return "error";
|
|
12695
|
+
return "done";
|
|
12696
|
+
}
|
|
12697
|
+
|
|
12698
|
+
// packages/cli/client/oneShotTerminalStatus.ts
|
|
12699
|
+
function resolveOneShotTerminalState(result) {
|
|
12700
|
+
return resolveTerminalProgramStatusState({
|
|
12701
|
+
exitCode: result.exitCode,
|
|
12702
|
+
interrupted: result.streamInterrupted,
|
|
12703
|
+
stalledOrTruncated: result.stalledOrTruncated
|
|
12704
|
+
});
|
|
12705
|
+
}
|
|
12706
|
+
function createOneShotTerminalStatus(output) {
|
|
12707
|
+
let last;
|
|
12708
|
+
let terminal = false;
|
|
12709
|
+
const report = (state2) => {
|
|
12710
|
+
if (!output || terminal || last === state2) return;
|
|
12711
|
+
last = state2;
|
|
12712
|
+
if (state2 === "done" || state2 === "error") terminal = true;
|
|
12713
|
+
emitTerminalProgramStatus(output, { state: state2 });
|
|
12714
|
+
};
|
|
12715
|
+
return {
|
|
12716
|
+
working: () => report("working"),
|
|
12717
|
+
settle: (result) => report(resolveOneShotTerminalState(result)),
|
|
12718
|
+
fail: () => report("error")
|
|
12719
|
+
};
|
|
12720
|
+
}
|
|
12721
|
+
|
|
11786
12722
|
// packages/cli/agentRunCommand.ts
|
|
11787
12723
|
import * as nodeFs from "node:fs";
|
|
11788
12724
|
|
|
11789
12725
|
// packages/cli/client/autoModelRouter.ts
|
|
11790
12726
|
var CLI_AUTO_ROUTE_AGENT_KEY = BUILTIN_NOLO_AGENT_KEY;
|
|
11791
12727
|
|
|
11792
|
-
// packages/agent-runtime/
|
|
12728
|
+
// packages/agent-runtime/hostEnvironment.ts
|
|
11793
12729
|
import { existsSync, readFileSync } from "node:fs";
|
|
12730
|
+
import os from "node:os";
|
|
12731
|
+
function parseLinuxOsRelease(content) {
|
|
12732
|
+
let prettyName;
|
|
12733
|
+
let name;
|
|
12734
|
+
let version;
|
|
12735
|
+
for (const line of content.split("\n")) {
|
|
12736
|
+
const trimmed = line.trim();
|
|
12737
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
12738
|
+
const eqIdx = trimmed.indexOf("=");
|
|
12739
|
+
if (eqIdx === -1) continue;
|
|
12740
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
12741
|
+
let val = trimmed.slice(eqIdx + 1).trim();
|
|
12742
|
+
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
|
|
12743
|
+
val = val.slice(1, -1);
|
|
12744
|
+
}
|
|
12745
|
+
if (key === "PRETTY_NAME") {
|
|
12746
|
+
prettyName = val;
|
|
12747
|
+
} else if (key === "NAME") {
|
|
12748
|
+
name = val;
|
|
12749
|
+
} else if (key === "VERSION") {
|
|
12750
|
+
version = val;
|
|
12751
|
+
}
|
|
12752
|
+
}
|
|
12753
|
+
if (prettyName) return prettyName;
|
|
12754
|
+
if (name && version) return `${name} ${version}`;
|
|
12755
|
+
return name;
|
|
12756
|
+
}
|
|
12757
|
+
function probeHostEnvironment(options) {
|
|
12758
|
+
const platform = options?.platform ?? process.platform;
|
|
12759
|
+
const arch = options?.arch ?? os.arch();
|
|
12760
|
+
const release = options?.release ?? os.release();
|
|
12761
|
+
const env = options?.env ?? process.env;
|
|
12762
|
+
let osName = `${platform} ${release}`;
|
|
12763
|
+
if (platform === "linux") {
|
|
12764
|
+
let osReleaseText = options?.osReleaseContent;
|
|
12765
|
+
if (osReleaseText === void 0) {
|
|
12766
|
+
try {
|
|
12767
|
+
if (existsSync("/etc/os-release")) {
|
|
12768
|
+
osReleaseText = readFileSync("/etc/os-release", "utf8");
|
|
12769
|
+
} else if (existsSync("/usr/lib/os-release")) {
|
|
12770
|
+
osReleaseText = readFileSync("/usr/lib/os-release", "utf8");
|
|
12771
|
+
}
|
|
12772
|
+
} catch {
|
|
12773
|
+
}
|
|
12774
|
+
}
|
|
12775
|
+
if (osReleaseText) {
|
|
12776
|
+
const parsed = parseLinuxOsRelease(osReleaseText);
|
|
12777
|
+
if (parsed) {
|
|
12778
|
+
osName = parsed;
|
|
12779
|
+
} else {
|
|
12780
|
+
osName = `Linux ${release}`;
|
|
12781
|
+
}
|
|
12782
|
+
} else {
|
|
12783
|
+
osName = `Linux ${release}`;
|
|
12784
|
+
}
|
|
12785
|
+
} else if (platform === "darwin") {
|
|
12786
|
+
osName = `macOS (${release})`;
|
|
12787
|
+
} else if (platform === "win32") {
|
|
12788
|
+
osName = `Windows (${release})`;
|
|
12789
|
+
}
|
|
12790
|
+
const desktop = env.XDG_CURRENT_DESKTOP || env.XDG_SESSION_DESKTOP || env.DESKTOP_SESSION || void 0;
|
|
12791
|
+
const sessionType = env.XDG_SESSION_TYPE || void 0;
|
|
12792
|
+
const shell = env.SHELL || (platform === "win32" ? env.COMSPEC || "PowerShell" : void 0);
|
|
12793
|
+
return {
|
|
12794
|
+
platform,
|
|
12795
|
+
osName,
|
|
12796
|
+
arch,
|
|
12797
|
+
desktop,
|
|
12798
|
+
sessionType,
|
|
12799
|
+
shell
|
|
12800
|
+
};
|
|
12801
|
+
}
|
|
12802
|
+
function formatHostEnvironmentContent(details) {
|
|
12803
|
+
const lines = ["--- \u5BBF\u4E3B\u73AF\u5883\uFF08Host Environment\uFF09---"];
|
|
12804
|
+
lines.push(`\u64CD\u4F5C\u7CFB\u7EDF: ${details.osName} (${details.arch})`);
|
|
12805
|
+
if (details.desktop || details.sessionType) {
|
|
12806
|
+
const desktopParts = [];
|
|
12807
|
+
if (details.desktop) desktopParts.push(details.desktop);
|
|
12808
|
+
if (details.sessionType) desktopParts.push(details.sessionType);
|
|
12809
|
+
lines.push(`\u684C\u9762\u73AF\u5883: ${desktopParts.join(" / ")}`);
|
|
12810
|
+
}
|
|
12811
|
+
if (details.shell) {
|
|
12812
|
+
lines.push(`\u9ED8\u8BA4 Shell: ${details.shell}`);
|
|
12813
|
+
}
|
|
12814
|
+
return lines.join("\n");
|
|
12815
|
+
}
|
|
12816
|
+
var cachedLayer = null;
|
|
12817
|
+
function buildHostEnvironmentLayer(options) {
|
|
12818
|
+
if (!options && cachedLayer) {
|
|
12819
|
+
return cachedLayer;
|
|
12820
|
+
}
|
|
12821
|
+
const details = probeHostEnvironment(options);
|
|
12822
|
+
const content = formatHostEnvironmentContent(details);
|
|
12823
|
+
const layer = {
|
|
12824
|
+
id: "host-environment",
|
|
12825
|
+
owner: "runtime",
|
|
12826
|
+
cacheScope: "session",
|
|
12827
|
+
content
|
|
12828
|
+
};
|
|
12829
|
+
if (!options) {
|
|
12830
|
+
cachedLayer = layer;
|
|
12831
|
+
}
|
|
12832
|
+
return layer;
|
|
12833
|
+
}
|
|
12834
|
+
|
|
12835
|
+
// packages/agent-runtime/agentsMd.ts
|
|
12836
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
11794
12837
|
import { join } from "node:path";
|
|
11795
12838
|
var AGENTS_MD_MAX_BYTES = 8192;
|
|
11796
12839
|
var AGENTS_MD_CANDIDATES = ["AGENTS.md", "CLAUDE.md"];
|
|
11797
12840
|
function readAgentsMdLayerFromDisk(cwd) {
|
|
11798
12841
|
for (const name of AGENTS_MD_CANDIDATES) {
|
|
11799
12842
|
const filePath = join(cwd, name);
|
|
11800
|
-
if (!
|
|
12843
|
+
if (!existsSync2(filePath)) continue;
|
|
11801
12844
|
try {
|
|
11802
|
-
let content =
|
|
12845
|
+
let content = readFileSync2(filePath, "utf8").trim();
|
|
11803
12846
|
if (!content) continue;
|
|
11804
12847
|
if (Buffer.byteLength(content, "utf8") > AGENTS_MD_MAX_BYTES) {
|
|
11805
12848
|
content = Buffer.from(content, "utf8").subarray(0, AGENTS_MD_MAX_BYTES).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
@@ -11869,14 +12912,14 @@ function runDoDCommands(commands, cwd, deps = {}) {
|
|
|
11869
12912
|
}
|
|
11870
12913
|
|
|
11871
12914
|
// packages/cli/agentRunPrompts.ts
|
|
11872
|
-
import { existsSync as
|
|
12915
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync, statSync as statSync2 } from "node:fs";
|
|
11873
12916
|
import { dirname, extname, isAbsolute, join as join2, relative as relativePath, resolve, sep } from "node:path";
|
|
11874
12917
|
function workflowRefToCandidatePath(cwd, ref) {
|
|
11875
12918
|
const normalized = ref.trim();
|
|
11876
12919
|
if (!normalized) return "";
|
|
11877
12920
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
11878
12921
|
const directPath = resolve(cwd, normalized);
|
|
11879
|
-
if (
|
|
12922
|
+
if (existsSync3(directPath)) return directPath;
|
|
11880
12923
|
}
|
|
11881
12924
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
11882
12925
|
return resolve(cwd, "docs", "workflows", `${fileName}.md`);
|
|
@@ -11889,21 +12932,21 @@ function skillRefToCandidatePath(cwd, ref) {
|
|
|
11889
12932
|
if (!normalized) return "";
|
|
11890
12933
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
11891
12934
|
const directPath = resolve(cwd, normalized);
|
|
11892
|
-
if (
|
|
12935
|
+
if (existsSync3(directPath)) return directPath;
|
|
11893
12936
|
}
|
|
11894
12937
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
11895
12938
|
for (const dir of SKILL_SEARCH_DIRS) {
|
|
11896
12939
|
const skillMdPath = resolve(cwd, dir, fileName, "SKILL.md");
|
|
11897
|
-
if (
|
|
12940
|
+
if (existsSync3(skillMdPath)) return skillMdPath;
|
|
11898
12941
|
}
|
|
11899
12942
|
return resolve(cwd, ".agents", "skills", fileName, "SKILL.md");
|
|
11900
12943
|
}
|
|
11901
12944
|
async function resolveWorkflowReference(ref, cwd = process.cwd()) {
|
|
11902
|
-
const
|
|
11903
|
-
if (!
|
|
12945
|
+
const path2 = workflowRefToCandidatePath(cwd, ref);
|
|
12946
|
+
if (!path2 || !existsSync3(path2)) {
|
|
11904
12947
|
throw new Error(`Workflow reference not found: ${ref}`);
|
|
11905
12948
|
}
|
|
11906
|
-
const markdown =
|
|
12949
|
+
const markdown = readFileSync3(path2, "utf8");
|
|
11907
12950
|
const parsed = parseSkillDocProtocol(markdown);
|
|
11908
12951
|
return {
|
|
11909
12952
|
ref,
|
|
@@ -11920,8 +12963,8 @@ function inlineRelativeRefs(body, skillDir) {
|
|
|
11920
12963
|
const absPath = resolve(skillDir, cleaned);
|
|
11921
12964
|
const relative = relativePath(normalizedSkillDir, absPath);
|
|
11922
12965
|
if (relative.startsWith("..") || isAbsolute(relative)) return match;
|
|
11923
|
-
if (!
|
|
11924
|
-
const refContent =
|
|
12966
|
+
if (!existsSync3(absPath) || !absPath.endsWith(".md")) return match;
|
|
12967
|
+
const refContent = readFileSync3(absPath, "utf8");
|
|
11925
12968
|
return `
|
|
11926
12969
|
|
|
11927
12970
|
### ${label}
|
|
@@ -11933,7 +12976,7 @@ ${refContent}
|
|
|
11933
12976
|
}
|
|
11934
12977
|
function listSkillScripts(skillDir) {
|
|
11935
12978
|
const scriptsDir = join2(skillDir, "scripts");
|
|
11936
|
-
if (!
|
|
12979
|
+
if (!existsSync3(scriptsDir) || !statSync2(scriptsDir).isDirectory()) return null;
|
|
11937
12980
|
const entries = readdirSync(scriptsDir).filter((e) => !e.startsWith("."));
|
|
11938
12981
|
if (entries.length === 0) return null;
|
|
11939
12982
|
return [
|
|
@@ -11959,13 +13002,13 @@ async function resolveSkillReference(ref, options = {}) {
|
|
|
11959
13002
|
markdown = String(contentText);
|
|
11960
13003
|
} else {
|
|
11961
13004
|
const cwd = options.cwd ?? process.cwd();
|
|
11962
|
-
const
|
|
11963
|
-
if (!
|
|
13005
|
+
const path2 = skillRefToCandidatePath(cwd, ref);
|
|
13006
|
+
if (!path2 || !existsSync3(path2)) {
|
|
11964
13007
|
throw new Error(`Skill reference not found: ${ref}`);
|
|
11965
13008
|
}
|
|
11966
|
-
markdown =
|
|
11967
|
-
filePath =
|
|
11968
|
-
skillDir = dirname(
|
|
13009
|
+
markdown = readFileSync3(path2, "utf8");
|
|
13010
|
+
filePath = path2;
|
|
13011
|
+
skillDir = dirname(path2);
|
|
11969
13012
|
}
|
|
11970
13013
|
const parsed = parseSkillDocProtocol(markdown);
|
|
11971
13014
|
const name = parsed.meta?.skillConfig?.name;
|
|
@@ -12068,12 +13111,12 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
|
|
|
12068
13111
|
function normalizeCliImageInput(input) {
|
|
12069
13112
|
if (/^(https?:|data:|file:)/i.test(input)) return input;
|
|
12070
13113
|
const absolutePath = resolve(input);
|
|
12071
|
-
if (!
|
|
12072
|
-
const base64 =
|
|
13114
|
+
if (!existsSync3(absolutePath)) return input;
|
|
13115
|
+
const base64 = readFileSync3(absolutePath).toString("base64");
|
|
12073
13116
|
return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
|
|
12074
13117
|
}
|
|
12075
|
-
function imageMimeTypeForPath(
|
|
12076
|
-
switch (extname(
|
|
13118
|
+
function imageMimeTypeForPath(path2) {
|
|
13119
|
+
switch (extname(path2).toLowerCase()) {
|
|
12077
13120
|
case ".jpg":
|
|
12078
13121
|
case ".jpeg":
|
|
12079
13122
|
return "image/jpeg";
|
|
@@ -12495,8 +13538,8 @@ var scoreMemoryItem = (item, query, nowMs = Date.now(), context) => {
|
|
|
12495
13538
|
const confidence = item.confidence ?? 0;
|
|
12496
13539
|
const typeFit = typeFitScore(item);
|
|
12497
13540
|
const understanding = understandingScore(item);
|
|
12498
|
-
const
|
|
12499
|
-
return 0.25 * queryMatch + 0.2 * identifierMatch + 0.2 *
|
|
13541
|
+
const path2 = pathScore(item, context);
|
|
13542
|
+
return 0.25 * queryMatch + 0.2 * identifierMatch + 0.2 * path2 + 0.09 * retrieval + // weak retrieval signal, NOT successful-use reinforcement
|
|
12500
13543
|
0.16 * createdRecency + 0.06 * importance + 0.03 * confidence + 0.02 * typeFit + 0.01 * understanding;
|
|
12501
13544
|
};
|
|
12502
13545
|
var rankMemoryCandidates = (items, query, context) => {
|
|
@@ -12512,75 +13555,52 @@ var rankMemoryCandidates = (items, query, context) => {
|
|
|
12512
13555
|
});
|
|
12513
13556
|
};
|
|
12514
13557
|
|
|
12515
|
-
// packages/ai/memory/vnext/
|
|
12516
|
-
var
|
|
12517
|
-
var
|
|
12518
|
-
var
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
var
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
const
|
|
12529
|
-
|
|
12530
|
-
|
|
12531
|
-
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
}
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
}
|
|
12561
|
-
if (isLevelNotFoundError(error)) return null;
|
|
12562
|
-
throw error;
|
|
12563
|
-
}
|
|
12564
|
-
};
|
|
12565
|
-
var _appendEntityBatch = (batch, entity) => {
|
|
12566
|
-
batch.put(entityKey(entity.ownerId, entity.id), entity);
|
|
12567
|
-
};
|
|
12568
|
-
var _appendEvidenceBatch = (batch, evidence) => {
|
|
12569
|
-
batch.put(evidenceKey(evidence.ownerId, evidence.id), evidence);
|
|
12570
|
-
};
|
|
12571
|
-
var _appendStateBatch = (batch, state2) => {
|
|
12572
|
-
const key = stateKey(state2.ownerId, state2.id);
|
|
12573
|
-
batch.put(key, state2);
|
|
12574
|
-
batch.put(stateEntityIndexKey(state2.ownerId, state2.entityId, state2.id), { key });
|
|
12575
|
-
};
|
|
12576
|
-
var _appendRetiredStateBatch = (batch, state2) => {
|
|
12577
|
-
batch.put(stateKey(state2.ownerId, state2.id), state2);
|
|
12578
|
-
};
|
|
12579
|
-
var _appendRelationBatch = (batch, relation) => {
|
|
12580
|
-
const key = relationKey(relation.ownerId, relation.id);
|
|
12581
|
-
batch.put(key, relation);
|
|
12582
|
-
batch.put(relationFromIndexKey(relation.ownerId, relation.from, relation.id), { key });
|
|
12583
|
-
batch.put(relationToIndexKey(relation.ownerId, relation.to, relation.id), { key });
|
|
13558
|
+
// packages/ai/memory/vnext/detachedThrottle.ts
|
|
13559
|
+
var DEFAULT_DETACHED_MEMORY_COOLDOWN_MS = 10 * 60 * 1e3;
|
|
13560
|
+
var MAX_COOLDOWN_KEYS = 512;
|
|
13561
|
+
var readMsEnv = (raw, fallback, allowZero) => {
|
|
13562
|
+
if (raw === void 0 || raw.trim() === "") return fallback;
|
|
13563
|
+
const parsed = Number(raw);
|
|
13564
|
+
if (!Number.isFinite(parsed) || parsed < 0) return fallback;
|
|
13565
|
+
if (parsed === 0 && !allowZero) return fallback;
|
|
13566
|
+
return parsed;
|
|
13567
|
+
};
|
|
13568
|
+
var createDetachedThrottle = (input) => {
|
|
13569
|
+
let inFlight2 = false;
|
|
13570
|
+
const lastStartedAt = /* @__PURE__ */ new Map();
|
|
13571
|
+
const resolveCooldownMs = (env = typeof process !== "undefined" ? process.env : {}) => readMsEnv(env[input.cooldownEnvKey], input.defaultCooldownMs, true);
|
|
13572
|
+
const rememberStart = (key, clockMs) => {
|
|
13573
|
+
lastStartedAt.delete(key);
|
|
13574
|
+
lastStartedAt.set(key, clockMs);
|
|
13575
|
+
while (lastStartedAt.size > MAX_COOLDOWN_KEYS) {
|
|
13576
|
+
lastStartedAt.delete(lastStartedAt.keys().next().value);
|
|
13577
|
+
}
|
|
13578
|
+
};
|
|
13579
|
+
return {
|
|
13580
|
+
name: input.name,
|
|
13581
|
+
defaultCooldownMs: input.defaultCooldownMs,
|
|
13582
|
+
cooldownEnvKey: input.cooldownEnvKey,
|
|
13583
|
+
resolveCooldownMs,
|
|
13584
|
+
tryAcquire(key, clockMs, cooldownMs) {
|
|
13585
|
+
if (inFlight2) return "busy";
|
|
13586
|
+
const interval = cooldownMs ?? resolveCooldownMs();
|
|
13587
|
+
const lastStarted = lastStartedAt.get(key);
|
|
13588
|
+
if (interval > 0 && lastStarted !== void 0 && clockMs - lastStarted < interval) {
|
|
13589
|
+
return "cooldown";
|
|
13590
|
+
}
|
|
13591
|
+
inFlight2 = true;
|
|
13592
|
+
rememberStart(key, clockMs);
|
|
13593
|
+
return "run";
|
|
13594
|
+
},
|
|
13595
|
+
release() {
|
|
13596
|
+
inFlight2 = false;
|
|
13597
|
+
},
|
|
13598
|
+
isInFlight: () => inFlight2,
|
|
13599
|
+
reset() {
|
|
13600
|
+
inFlight2 = false;
|
|
13601
|
+
lastStartedAt.clear();
|
|
13602
|
+
}
|
|
13603
|
+
};
|
|
12584
13604
|
};
|
|
12585
13605
|
|
|
12586
13606
|
// packages/ai/memory/vnext/recall.ts
|
|
@@ -12743,6 +13763,20 @@ var buildLegacyMemoryEvidence = (item) => {
|
|
|
12743
13763
|
// packages/ai/memory/vnext/shadowRead.ts
|
|
12744
13764
|
var SHADOW_TIMEOUT_MS = 2e4;
|
|
12745
13765
|
var ERROR_MESSAGE_MAX = 120;
|
|
13766
|
+
var MEMORY_VNEXT_SHADOW_READ_COOLDOWN_ENV = "NOLO_MEMORY_VNEXT_SHADOW_READ_COOLDOWN_MS";
|
|
13767
|
+
var DEFAULT_SHADOW_READ_COOLDOWN_MS = DEFAULT_DETACHED_MEMORY_COOLDOWN_MS;
|
|
13768
|
+
var shadowReadThrottle = createDetachedThrottle({
|
|
13769
|
+
name: "shadow_read",
|
|
13770
|
+
defaultCooldownMs: DEFAULT_SHADOW_READ_COOLDOWN_MS,
|
|
13771
|
+
cooldownEnvKey: MEMORY_VNEXT_SHADOW_READ_COOLDOWN_ENV
|
|
13772
|
+
});
|
|
13773
|
+
var resolveShadowReadCooldownMs = (env) => shadowReadThrottle.resolveCooldownMs(env);
|
|
13774
|
+
var shadowReadThrottleKey = (owners) => owners.map(
|
|
13775
|
+
(owner) => resolveLegacyMemoryPrincipal({
|
|
13776
|
+
ownerType: owner.ownerType,
|
|
13777
|
+
ownerId: owner.ownerId
|
|
13778
|
+
}).principalId
|
|
13779
|
+
).sort().join("");
|
|
12746
13780
|
var normalizeTextKey = (text) => text.trim().replace(/\s+/g, " ").toLowerCase();
|
|
12747
13781
|
var legacyItemKeys = (item) => {
|
|
12748
13782
|
const keys = [normalizeTextKey(item.content ?? "")];
|
|
@@ -12779,14 +13813,35 @@ var withTimeout = async (promise, timeoutMs, label) => {
|
|
|
12779
13813
|
};
|
|
12780
13814
|
var runMemoryVNextShadowRead = async (input) => {
|
|
12781
13815
|
const now = input.ctx.now ?? (() => performance.now());
|
|
12782
|
-
const defaultEmit = (
|
|
13816
|
+
const defaultEmit = (observation) => {
|
|
12783
13817
|
const payload = {
|
|
12784
13818
|
event: "memory_vnext_shadow_read",
|
|
12785
|
-
...
|
|
13819
|
+
...observation
|
|
12786
13820
|
};
|
|
12787
13821
|
console.info("[memory] vnext shadow read", payload);
|
|
12788
13822
|
};
|
|
12789
13823
|
const emit = input.emit ?? defaultEmit;
|
|
13824
|
+
const throttle = shadowReadThrottle.tryAcquire(
|
|
13825
|
+
shadowReadThrottleKey(input.ctx.owners),
|
|
13826
|
+
now(),
|
|
13827
|
+
input.ctx.cooldownMs ?? resolveShadowReadCooldownMs()
|
|
13828
|
+
);
|
|
13829
|
+
if (throttle !== "run") {
|
|
13830
|
+
const skippedObservation = {
|
|
13831
|
+
legacyHitCount: input.legacyItems.length,
|
|
13832
|
+
vnextHitCount: 0,
|
|
13833
|
+
overlapCount: null,
|
|
13834
|
+
legacyOnlyCount: null,
|
|
13835
|
+
vnextOnlyCount: null,
|
|
13836
|
+
legacyLatencyMs: input.legacyLatencyMs,
|
|
13837
|
+
vnextLatencyMs: 0,
|
|
13838
|
+
legacyContextChars: input.legacyContextChars,
|
|
13839
|
+
vnextContextChars: 0,
|
|
13840
|
+
skipped: throttle === "busy" ? "skipped_busy" : "skipped_cooldown"
|
|
13841
|
+
};
|
|
13842
|
+
emit(skippedObservation);
|
|
13843
|
+
return skippedObservation;
|
|
13844
|
+
}
|
|
12790
13845
|
const legacyKeys = new Set(
|
|
12791
13846
|
input.legacyItems.flatMap((item) => legacyItemKeys(item))
|
|
12792
13847
|
);
|
|
@@ -12823,31 +13878,35 @@ var runMemoryVNextShadowRead = async (input) => {
|
|
|
12823
13878
|
} catch (error) {
|
|
12824
13879
|
vnextError = shortError(error);
|
|
12825
13880
|
}
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
|
|
12844
|
-
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
13881
|
+
try {
|
|
13882
|
+
const vnextLatencyMs = Math.round((now() - vnextStartedAt) * 10) / 10;
|
|
13883
|
+
let overlapCount = null;
|
|
13884
|
+
let legacyOnlyCount = null;
|
|
13885
|
+
let vnextOnlyCount = null;
|
|
13886
|
+
if (!vnextError) {
|
|
13887
|
+
let overlap = 0;
|
|
13888
|
+
for (const key of vnextKeys) if (legacyKeys.has(key)) overlap += 1;
|
|
13889
|
+
overlapCount = overlap;
|
|
13890
|
+
legacyOnlyCount = Math.max(0, legacyKeys.size - overlap);
|
|
13891
|
+
vnextOnlyCount = Math.max(0, vnextKeys.size - overlap);
|
|
13892
|
+
}
|
|
13893
|
+
const observation = {
|
|
13894
|
+
legacyHitCount: input.legacyItems.length,
|
|
13895
|
+
vnextHitCount,
|
|
13896
|
+
overlapCount,
|
|
13897
|
+
legacyOnlyCount,
|
|
13898
|
+
vnextOnlyCount,
|
|
13899
|
+
legacyLatencyMs: input.legacyLatencyMs,
|
|
13900
|
+
vnextLatencyMs,
|
|
13901
|
+
legacyContextChars: input.legacyContextChars,
|
|
13902
|
+
vnextContextChars: vnextChars,
|
|
13903
|
+
...vnextError ? { vnextError } : {}
|
|
13904
|
+
};
|
|
13905
|
+
emit(observation);
|
|
13906
|
+
return observation;
|
|
13907
|
+
} finally {
|
|
13908
|
+
shadowReadThrottle.release();
|
|
13909
|
+
}
|
|
12851
13910
|
};
|
|
12852
13911
|
var isMemoryVNextShadowReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_SHADOW_READ === "1" || env.NOLO_MEMORY_VNEXT_SHADOW_READ === "true";
|
|
12853
13912
|
|
|
@@ -13507,6 +14566,31 @@ var shortError2 = (error) => {
|
|
|
13507
14566
|
const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
13508
14567
|
return message.length > ERROR_MESSAGE_MAX2 ? `${message.slice(0, ERROR_MESSAGE_MAX2)}\u2026` : message;
|
|
13509
14568
|
};
|
|
14569
|
+
var DEFAULT_LAZY_PROMOTION_COOLDOWN_MS = DEFAULT_DETACHED_MEMORY_COOLDOWN_MS;
|
|
14570
|
+
var DEFAULT_LAZY_PROMOTION_TIMEOUT_MS = 2e4;
|
|
14571
|
+
var MEMORY_VNEXT_LAZY_PROMOTION_COOLDOWN_ENV = "NOLO_MEMORY_VNEXT_LAZY_PROMOTION_COOLDOWN_MS";
|
|
14572
|
+
var MEMORY_VNEXT_LAZY_PROMOTION_TIMEOUT_ENV = "NOLO_MEMORY_VNEXT_LAZY_PROMOTION_TIMEOUT_MS";
|
|
14573
|
+
var promotionThrottle = createDetachedThrottle({
|
|
14574
|
+
name: "lazy_promotion",
|
|
14575
|
+
defaultCooldownMs: DEFAULT_LAZY_PROMOTION_COOLDOWN_MS,
|
|
14576
|
+
cooldownEnvKey: MEMORY_VNEXT_LAZY_PROMOTION_COOLDOWN_ENV
|
|
14577
|
+
});
|
|
14578
|
+
var resolveLazyPromotionTimeoutMs = (env = typeof process !== "undefined" ? process.env : {}) => readMsEnv(
|
|
14579
|
+
env[MEMORY_VNEXT_LAZY_PROMOTION_TIMEOUT_ENV],
|
|
14580
|
+
DEFAULT_LAZY_PROMOTION_TIMEOUT_MS,
|
|
14581
|
+
false
|
|
14582
|
+
);
|
|
14583
|
+
var withTimeout2 = async (promise, timeoutMs, label) => {
|
|
14584
|
+
let timer;
|
|
14585
|
+
const timeout = new Promise((_, reject) => {
|
|
14586
|
+
timer = setTimeout(() => reject(new Error(label)), timeoutMs);
|
|
14587
|
+
});
|
|
14588
|
+
try {
|
|
14589
|
+
return await Promise.race([promise, timeout]);
|
|
14590
|
+
} finally {
|
|
14591
|
+
if (timer) clearTimeout(timer);
|
|
14592
|
+
}
|
|
14593
|
+
};
|
|
13510
14594
|
var loadExistingContext = async (db, ownerId) => {
|
|
13511
14595
|
const { entities, states } = await loadMemoryVNextCatalog(db, ownerId);
|
|
13512
14596
|
return { entityIds: entities.map((entity) => entity.id), states };
|
|
@@ -13610,6 +14694,17 @@ var runMemoryVNextLazyPromotion = async (input) => {
|
|
|
13610
14694
|
if (inFlight.has(flightKey)) {
|
|
13611
14695
|
return finish({ status: "in_flight" });
|
|
13612
14696
|
}
|
|
14697
|
+
const throttle = promotionThrottle.tryAcquire(
|
|
14698
|
+
deterministicEvidence.ownerId,
|
|
14699
|
+
clock(),
|
|
14700
|
+
input.cooldownMs
|
|
14701
|
+
);
|
|
14702
|
+
if (throttle === "busy") {
|
|
14703
|
+
return finish({ status: "skipped_busy" });
|
|
14704
|
+
}
|
|
14705
|
+
if (throttle === "cooldown") {
|
|
14706
|
+
return finish({ status: "skipped_cooldown" });
|
|
14707
|
+
}
|
|
13613
14708
|
inFlight.add(flightKey);
|
|
13614
14709
|
try {
|
|
13615
14710
|
const evidenceResult = await applyLegacyMemoryEvidence(input.db, input.item);
|
|
@@ -13625,14 +14720,19 @@ var runMemoryVNextLazyPromotion = async (input) => {
|
|
|
13625
14720
|
if (alreadyCovered) {
|
|
13626
14721
|
return finish({ status: "already_covered" });
|
|
13627
14722
|
}
|
|
13628
|
-
const
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
|
|
14723
|
+
const timeoutMs = input.timeoutMs ?? resolveLazyPromotionTimeoutMs();
|
|
14724
|
+
const interpreted = await withTimeout2(
|
|
14725
|
+
runLegacyMemoryMigrationShadow({
|
|
14726
|
+
item: input.item,
|
|
14727
|
+
provider: input.provider,
|
|
14728
|
+
existing,
|
|
14729
|
+
timeoutMs,
|
|
14730
|
+
...input.now === void 0 ? {} : { now: input.now },
|
|
14731
|
+
...input.nextId ? { nextId: input.nextId } : {}
|
|
14732
|
+
}),
|
|
14733
|
+
timeoutMs,
|
|
14734
|
+
`memory vnext lazy promotion interpreter timed out after ${timeoutMs}ms`
|
|
14735
|
+
);
|
|
13636
14736
|
const semanticMutation = withoutImportedEvidence(interpreted.mutation, evidence.id);
|
|
13637
14737
|
if (!hasWrites(semanticMutation)) {
|
|
13638
14738
|
recordNoOpSuppression(
|
|
@@ -13648,6 +14748,7 @@ var runMemoryVNextLazyPromotion = async (input) => {
|
|
|
13648
14748
|
return finish({ status: "error", error: shortError2(error) });
|
|
13649
14749
|
} finally {
|
|
13650
14750
|
inFlight.delete(flightKey);
|
|
14751
|
+
promotionThrottle.release();
|
|
13651
14752
|
}
|
|
13652
14753
|
};
|
|
13653
14754
|
var isMemoryVNextLazyPromotionEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "1" || env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "true";
|
|
@@ -13733,9 +14834,9 @@ async function resolvePureVNextRuntime(input) {
|
|
|
13733
14834
|
});
|
|
13734
14835
|
const entityById = new Map(catalog.entities.map((e) => [e.id, e]));
|
|
13735
14836
|
for (const hit of hits) {
|
|
13736
|
-
const
|
|
13737
|
-
if (seenStateKeys.has(
|
|
13738
|
-
seenStateKeys.add(
|
|
14837
|
+
const stateKey = `${hit.state.ownerId}\0${hit.state.id}`;
|
|
14838
|
+
if (seenStateKeys.has(stateKey)) continue;
|
|
14839
|
+
seenStateKeys.add(stateKey);
|
|
13739
14840
|
selectedItems.push(
|
|
13740
14841
|
buildSynthesizedStateItem(hit.state, entityById.get(hit.state.entityId), owner.ownerType, owner.ownerId)
|
|
13741
14842
|
);
|
|
@@ -14134,8 +15235,9 @@ function fingerprintFor(kind, detail) {
|
|
|
14134
15235
|
function sanitizeFp(s) {
|
|
14135
15236
|
return s.replace(/\s+/g, " ").slice(0, 80);
|
|
14136
15237
|
}
|
|
14137
|
-
var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceId) => {
|
|
15238
|
+
var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceId, signal) => {
|
|
14138
15239
|
try {
|
|
15240
|
+
if (signal?.aborted) throw signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
14139
15241
|
const response = await fetch(`${serverUrl}/api/memory/query`, {
|
|
14140
15242
|
method: "POST",
|
|
14141
15243
|
headers: {
|
|
@@ -14147,7 +15249,7 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
|
|
|
14147
15249
|
userInput,
|
|
14148
15250
|
...spaceId ? { spaceId } : {}
|
|
14149
15251
|
}),
|
|
14150
|
-
signal: AbortSignal.timeout(5e3)
|
|
15252
|
+
signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3)
|
|
14151
15253
|
});
|
|
14152
15254
|
if (!response.ok) {
|
|
14153
15255
|
logDeduped(
|
|
@@ -14161,6 +15263,7 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
|
|
|
14161
15263
|
const block = typeof payload?.promptBlock === "string" ? payload.promptBlock.trim() : "";
|
|
14162
15264
|
return block || null;
|
|
14163
15265
|
} catch (error) {
|
|
15266
|
+
if (signal?.aborted) throw error;
|
|
14164
15267
|
logDeduped(
|
|
14165
15268
|
"info",
|
|
14166
15269
|
fingerprintFor("remote-failed", error instanceof Error ? error.name : void 0),
|
|
@@ -14184,17 +15287,21 @@ var queryLocalMemory = async (env, agentKey, userInput, spaceId) => {
|
|
|
14184
15287
|
return resolution.promptBlock;
|
|
14185
15288
|
};
|
|
14186
15289
|
var resolveCliMemory = async (input) => {
|
|
15290
|
+
if (input.signal?.aborted) throw input.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
14187
15291
|
if (input.authToken && input.serverUrl) {
|
|
14188
15292
|
const remoteBlock = await queryRemoteMemory(
|
|
14189
15293
|
input.serverUrl,
|
|
14190
15294
|
input.authToken,
|
|
14191
15295
|
input.agentKey,
|
|
14192
15296
|
input.userInput,
|
|
14193
|
-
input.spaceId
|
|
15297
|
+
input.spaceId,
|
|
15298
|
+
input.signal
|
|
14194
15299
|
);
|
|
14195
15300
|
if (remoteBlock) return remoteBlock;
|
|
14196
15301
|
}
|
|
15302
|
+
if (input.signal?.aborted) throw input.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
14197
15303
|
try {
|
|
15304
|
+
if (input.signal?.aborted) throw input.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
14198
15305
|
return await queryLocalMemory(
|
|
14199
15306
|
input.env,
|
|
14200
15307
|
input.agentKey,
|
|
@@ -14202,6 +15309,7 @@ var resolveCliMemory = async (input) => {
|
|
|
14202
15309
|
input.spaceId
|
|
14203
15310
|
);
|
|
14204
15311
|
} catch (error) {
|
|
15312
|
+
if (input.signal?.aborted) throw error;
|
|
14205
15313
|
logDeduped(
|
|
14206
15314
|
"warn",
|
|
14207
15315
|
fingerprintFor("local-failed", error instanceof Error ? error.name : void 0),
|
|
@@ -14231,13 +15339,6 @@ function resolveRunOutcome(input) {
|
|
|
14231
15339
|
}
|
|
14232
15340
|
}
|
|
14233
15341
|
}
|
|
14234
|
-
var FAILED_EMPTY_ASSISTANT_REASONS = /* @__PURE__ */ new Set([
|
|
14235
|
-
"length_truncated",
|
|
14236
|
-
"stream_truncated",
|
|
14237
|
-
"repetition_loop",
|
|
14238
|
-
"stagnant_tool_calls"
|
|
14239
|
-
]);
|
|
14240
|
-
var isRunResultStalledOrTruncated = (result) => !result.emptyAssistantOutputUsable && FAILED_EMPTY_ASSISTANT_REASONS.has(result.emptyAssistantFallbackReason ?? "");
|
|
14241
15342
|
var resolveRunSettlementNote = (result) => {
|
|
14242
15343
|
const reason = result.emptyAssistantFallbackReason;
|
|
14243
15344
|
if (!reason || !FAILED_EMPTY_ASSISTANT_REASONS.has(reason)) return {};
|
|
@@ -14260,6 +15361,18 @@ async function resolveAgentRunAgentKey(args) {
|
|
|
14260
15361
|
});
|
|
14261
15362
|
return resolved?.agentKey;
|
|
14262
15363
|
}
|
|
15364
|
+
var MACHINE_SHELL_REQUESTED_POLICY = { runtimeTools: ["execShell"] };
|
|
15365
|
+
async function resolveAgentBoundMachineIdFromRecord(args) {
|
|
15366
|
+
const db = await getReadableCliDb(args.output);
|
|
15367
|
+
const record = await resolveAgentRecordFromHybridStore({
|
|
15368
|
+
agentInput: args.agentKey,
|
|
15369
|
+
cliArgs: args.cliArgs,
|
|
15370
|
+
env: args.env,
|
|
15371
|
+
db,
|
|
15372
|
+
fetchImpl: fetch
|
|
15373
|
+
}).catch(() => null);
|
|
15374
|
+
return resolveBoundMachineId(record) || void 0;
|
|
15375
|
+
}
|
|
14263
15376
|
async function runAgentRunCommand(args, deps) {
|
|
14264
15377
|
const env = deps.env ?? process.env;
|
|
14265
15378
|
const output = deps.output ?? {
|
|
@@ -14270,7 +15383,14 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14270
15383
|
writeUsage(output, deps.commandPath);
|
|
14271
15384
|
return 0;
|
|
14272
15385
|
}
|
|
14273
|
-
|
|
15386
|
+
let parsed;
|
|
15387
|
+
try {
|
|
15388
|
+
parsed = parseAgentRunArgs(args, { commandPath: deps.commandPath });
|
|
15389
|
+
} catch (error) {
|
|
15390
|
+
output.write(`[nolo] ${toErrorMessage(error)}
|
|
15391
|
+
`);
|
|
15392
|
+
return 1;
|
|
15393
|
+
}
|
|
14274
15394
|
if (!parsed) {
|
|
14275
15395
|
writeUsage(output, deps.commandPath);
|
|
14276
15396
|
return 1;
|
|
@@ -14307,7 +15427,19 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14307
15427
|
const watchdogFailure = armStallWatchdog || armTimeoutWatchdog ? new Promise((_, reject) => {
|
|
14308
15428
|
rejectOnWatchdogFailure = reject;
|
|
14309
15429
|
}) : void 0;
|
|
14310
|
-
const
|
|
15430
|
+
const terminalStatus = createOneShotTerminalStatus(
|
|
15431
|
+
parsed.eventsMode || parsed.background || hasRegistry ? null : deps.output ? deps.output : {
|
|
15432
|
+
write: (chunk) => process.stdout.write(chunk),
|
|
15433
|
+
isTTY: process.stdout.isTTY === true
|
|
15434
|
+
}
|
|
15435
|
+
);
|
|
15436
|
+
const raceWithWatchdog = (work) => {
|
|
15437
|
+
const raced = watchdogFailure ? Promise.race([work, watchdogFailure]) : work;
|
|
15438
|
+
return raced.catch((error) => {
|
|
15439
|
+
terminalStatus.fail();
|
|
15440
|
+
throw error;
|
|
15441
|
+
});
|
|
15442
|
+
};
|
|
14311
15443
|
const exitFromWatchdog = (code) => {
|
|
14312
15444
|
try {
|
|
14313
15445
|
processExit(code);
|
|
@@ -14352,6 +15484,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14352
15484
|
const note = `stalled: no progress for ${stallTimeoutMs}ms`;
|
|
14353
15485
|
output.write(`[nolo] local run ${note}
|
|
14354
15486
|
`);
|
|
15487
|
+
terminalStatus.fail();
|
|
14355
15488
|
const outcome = resolveRunOutcome({ kind: "stall" });
|
|
14356
15489
|
const currentActivity = activityTracker?.getActivity();
|
|
14357
15490
|
await finalizeWatchdogOutcome(outcome, note, {
|
|
@@ -14370,6 +15503,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14370
15503
|
const note = `timed out after ${parsed.timeoutMs}ms`;
|
|
14371
15504
|
output.write(`[nolo] local run ${note}
|
|
14372
15505
|
`);
|
|
15506
|
+
terminalStatus.fail();
|
|
14373
15507
|
const outcome = resolveRunOutcome({ kind: "timeout" });
|
|
14374
15508
|
await finalizeWatchdogOutcome(outcome, note);
|
|
14375
15509
|
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
@@ -14380,7 +15514,16 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14380
15514
|
const rawAgentInput = resolveRawAgentInput(args, deps.commandPath) ?? parsed.agentKey;
|
|
14381
15515
|
const fullstackLocal = isFullstackCodingAgentRef(rawAgentInput, parsed.agentKey);
|
|
14382
15516
|
const explicitLocalCli = isLocalCliAgentKey(parsed.agentKey);
|
|
14383
|
-
const
|
|
15517
|
+
const dockerRuntimeLocal = typeof parsed.runtimeKey === "string" && /^docker(:.+)?$/.test(parsed.runtimeKey.trim());
|
|
15518
|
+
const instaboxRuntimeLocal = typeof parsed.runtimeKey === "string" && parsed.runtimeKey.trim() === "instabox";
|
|
15519
|
+
const hostRuntimeLocal = typeof parsed.runtimeKey === "string" && parsed.runtimeKey.trim() === "local";
|
|
15520
|
+
if (hostRuntimeLocal && !args.includes("--allow-host-writes")) {
|
|
15521
|
+
output.write(
|
|
15522
|
+
"[nolo] runtimeKey=local \u4F1A\u5728**\u5BBF\u4E3B\u6587\u4EF6\u7CFB\u7EDF**\u4E0A\u6267\u884C\u5E76\u5199\u5165\uFF0C\u5FC5\u987B\u663E\u5F0F\u52A0 --allow-host-writes \u786E\u8BA4\uFF1B\u8981\u9694\u79BB\u6267\u884C\u8BF7\u7701\u7565 --runtime-key\uFF08\u9ED8\u8BA4\u8FDB docker \u6C99\u76D2\uFF09\u3002\n"
|
|
15523
|
+
);
|
|
15524
|
+
return 1;
|
|
15525
|
+
}
|
|
15526
|
+
const isLocalRun = (dockerRuntimeLocal || instaboxRuntimeLocal || hostRuntimeLocal || !parsed.runtimeKey) && (parsed.runtimeMode === "local" || hostRuntimeLocal || !parsed.runtimeMode && (fullstackLocal || explicitLocalCli || args.includes("--dangerously-allow-shell")));
|
|
14384
15527
|
if (wantsFallbackSuggestions && !isLocalRun) {
|
|
14385
15528
|
output.write("[nolo] --fallback-agent (suggestions) is only supported for local CLI runs (use --local)\n");
|
|
14386
15529
|
return 1;
|
|
@@ -14391,13 +15534,47 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14391
15534
|
|
|
14392
15535
|
[Quota fallback context for agent decision: If this execution for ${parsed.agentKey} hits subscription quota, YOU (the agent) must decide the next agent to use. Do not rely on automatic wrapper. Reason based on the specific task (complexity, length, domain), agent strengths, cost, previous attempt results. Suggested alternatives: ${parsed.fallbackAgentKeys.join(", ")}. Update the task row with attempt history and dispatch the chosen next (via startAgentRun \u5F02\u6B65\u6D3E\u53D1)).]`;
|
|
14393
15536
|
}
|
|
14394
|
-
const resolvedAgentKey = parsed.runtimeMode !== "local" ? await (deps.resolveAgentRunAgentKey ?? resolveAgentRunAgentKey)({
|
|
15537
|
+
const resolvedAgentKey = parsed.runtimeMode !== "local" && !hostRuntimeLocal ? await (deps.resolveAgentRunAgentKey ?? resolveAgentRunAgentKey)({
|
|
14395
15538
|
agentInput: resolveRawAgentInput(args, deps.commandPath) ?? parsed.agentKey,
|
|
14396
15539
|
cliArgs: args,
|
|
14397
15540
|
env,
|
|
14398
15541
|
output
|
|
14399
15542
|
}).catch(() => void 0) : void 0;
|
|
14400
15543
|
const agentKey = resolvedAgentKey ?? parsed.agentKey;
|
|
15544
|
+
let machineShellOverride;
|
|
15545
|
+
if (parsed.machineShell) {
|
|
15546
|
+
const envRuntimeMode = env.NOLO_RUNTIME_MODE;
|
|
15547
|
+
const requestedRuntimeMode = parsed.runtimeMode ? parsed.runtimeMode : envRuntimeMode === "local" || envRuntimeMode === "server" || envRuntimeMode === "auto" ? envRuntimeMode : void 0;
|
|
15548
|
+
if (requestedRuntimeMode === "local") {
|
|
15549
|
+
output.write(MACHINE_SHELL_LOCAL_REFUSAL_MESSAGE);
|
|
15550
|
+
return 1;
|
|
15551
|
+
}
|
|
15552
|
+
const machineId = await (deps.resolveAgentBoundMachineId ?? resolveAgentBoundMachineIdFromRecord)({
|
|
15553
|
+
agentKey,
|
|
15554
|
+
cliArgs: args,
|
|
15555
|
+
env,
|
|
15556
|
+
output
|
|
15557
|
+
}).catch(() => void 0);
|
|
15558
|
+
if (!machineId) {
|
|
15559
|
+
output.write(
|
|
15560
|
+
`[nolo] --machine-shell requires ${agentKey} to be bound to a machine (runtimeBinding.machineId); none found.
|
|
15561
|
+
[nolo] bind it with \`nolo agent bind-current ${agentKey}\` on the target computer, then retry.
|
|
15562
|
+
`
|
|
15563
|
+
);
|
|
15564
|
+
return 1;
|
|
15565
|
+
}
|
|
15566
|
+
machineShellOverride = normalizeRuntimeToolPolicyOverride(
|
|
15567
|
+
MACHINE_SHELL_REQUESTED_POLICY
|
|
15568
|
+
);
|
|
15569
|
+
const baselinePolicy = resolveEffectiveRuntimeToolPolicy({
|
|
15570
|
+
agentConfig: { runtimeToolPolicy: machineShellOverride },
|
|
15571
|
+
host: "web"
|
|
15572
|
+
});
|
|
15573
|
+
output.write(
|
|
15574
|
+
`[nolo] machine-shell: dispatch=server(required) machine=${machineId} runtimeTools=${(machineShellOverride?.runtimeTools ?? []).join(",") || "-"} sandbox=${baselinePolicy?.isolation?.mode ?? "-"} approval=${baselinePolicy?.shell?.commandPolicy ?? "-"} networkPolicy=${baselinePolicy?.shell?.networkPolicy ?? "-"} policySource=web-runtime-safety-baseline
|
|
15575
|
+
`
|
|
15576
|
+
);
|
|
15577
|
+
}
|
|
14401
15578
|
let effectiveAgentKey = agentKey;
|
|
14402
15579
|
let modelOverride = null;
|
|
14403
15580
|
const autoRouteRequested = deps.commandPath?.join(" ") === "chat" && !parsed.continueDialogId && (args.includes("--auto-route") || env.NOLO_AUTO_ROUTE === "1") && env.NOLO_AUTO_ROUTE !== "0";
|
|
@@ -14415,13 +15592,12 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14415
15592
|
}
|
|
14416
15593
|
if (hasExplicitAgent && !modelOverride) {
|
|
14417
15594
|
output.write(
|
|
14418
|
-
"
|
|
15595
|
+
t("agentRun.autoRouteOverrideFailed")
|
|
14419
15596
|
);
|
|
14420
15597
|
} else {
|
|
14421
15598
|
effectiveAgentKey = CLI_AUTO_ROUTE_AGENT_KEY;
|
|
14422
15599
|
if (modelOverride) {
|
|
14423
|
-
output.write(
|
|
14424
|
-
`);
|
|
15600
|
+
output.write(t("agentRun.autoRouteModelOverride", agentKey));
|
|
14425
15601
|
}
|
|
14426
15602
|
}
|
|
14427
15603
|
}
|
|
@@ -14477,7 +15653,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14477
15653
|
}
|
|
14478
15654
|
}
|
|
14479
15655
|
let localRuntimeCwd = parsed.cwd;
|
|
14480
|
-
if (!localRuntimeCwd && parsed.runtimeMode === "local") {
|
|
15656
|
+
if (!localRuntimeCwd && (parsed.runtimeMode === "local" || hostRuntimeLocal)) {
|
|
14481
15657
|
localRuntimeCwd = process.cwd();
|
|
14482
15658
|
}
|
|
14483
15659
|
const runEnv = buildLocalRunEnv({
|
|
@@ -14504,7 +15680,8 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14504
15680
|
spawn: deps.spawn,
|
|
14505
15681
|
fs: deps.fs,
|
|
14506
15682
|
now: deps.now,
|
|
14507
|
-
generateRunId: deps.generateRunId
|
|
15683
|
+
generateRunId: deps.generateRunId,
|
|
15684
|
+
shellApprovalHost: deps.shellApprovalHost
|
|
14508
15685
|
}
|
|
14509
15686
|
);
|
|
14510
15687
|
output.write(`[nolo] runId=${runId}
|
|
@@ -14533,6 +15710,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14533
15710
|
if (agentsMdLayer) scopedLayers.push(agentsMdLayer);
|
|
14534
15711
|
skillContentBlocks.push(...buildSkillContextBlocks(skillReferences));
|
|
14535
15712
|
scopedLayers.push(buildSkillDiscoveryContextLayer(cliCwd));
|
|
15713
|
+
scopedLayers.push(buildHostEnvironmentLayer());
|
|
14536
15714
|
if (!deps.memoryRecallDisabled) {
|
|
14537
15715
|
try {
|
|
14538
15716
|
memoryPromptBlock = await resolveCliMemory({
|
|
@@ -14561,6 +15739,14 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14561
15739
|
);
|
|
14562
15740
|
extraContextBlocks.push(...contextBlockScopes.map((block) => block.content));
|
|
14563
15741
|
}
|
|
15742
|
+
const runRecordParentDialogId = !parsed.parentDialogId && typeof childRunId === "string" && childRunId.length > 0 ? asOptionalTrimmedString(
|
|
15743
|
+
(deps.readRunRecord ?? readRunRecord)(childRunId, {
|
|
15744
|
+
env,
|
|
15745
|
+
homedir: deps.homedir,
|
|
15746
|
+
fs: deps.fs
|
|
15747
|
+
})?.parentDialogId
|
|
15748
|
+
) : void 0;
|
|
15749
|
+
const effectiveParentDialogId = parsed.parentDialogId ?? runRecordParentDialogId;
|
|
14564
15750
|
const formatTurnMessage = (msg) => prependWorkflowReferencePrompt(
|
|
14565
15751
|
prependSubjectDialogMarker(
|
|
14566
15752
|
prependFeatureWorktreeInstruction(
|
|
@@ -14571,239 +15757,263 @@ async function runAgentRunCommand(args, deps) {
|
|
|
14571
15757
|
),
|
|
14572
15758
|
workflowReference
|
|
14573
15759
|
);
|
|
14574
|
-
const
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
14589
|
-
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14603
|
-
|
|
14604
|
-
|
|
14605
|
-
|
|
14606
|
-
|
|
14607
|
-
|
|
14608
|
-
...
|
|
14609
|
-
...
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
|
|
14613
|
-
|
|
14614
|
-
|
|
14615
|
-
|
|
14616
|
-
|
|
14617
|
-
|
|
14618
|
-
|
|
14619
|
-
|
|
14620
|
-
|
|
15760
|
+
const shellApprovalChild = process.connected && typeof process.send === "function" ? createShellApprovalChild(process) : void 0;
|
|
15761
|
+
try {
|
|
15762
|
+
const buildRunOptions = (targetAgentKey, turnMessage = effectiveMessage) => ({
|
|
15763
|
+
...shellApprovalChild ? { execShellApproval: targetAgentKey === agentKey ? shellApprovalChild.authority : {
|
|
15764
|
+
request: async () => {
|
|
15765
|
+
throw new Error("Shell approval agent binding mismatch");
|
|
15766
|
+
},
|
|
15767
|
+
consume: () => {
|
|
15768
|
+
throw new Error("Shell approval agent binding mismatch");
|
|
15769
|
+
}
|
|
15770
|
+
} } : {},
|
|
15771
|
+
agentName: targetAgentKey,
|
|
15772
|
+
agentKey: targetAgentKey,
|
|
15773
|
+
serverUrl: resolveServerUrl(env),
|
|
15774
|
+
message: formatTurnMessage(turnMessage),
|
|
15775
|
+
imageUrls: parsed.imageUrls.map(normalizeCliImageInput),
|
|
15776
|
+
scriptDir: deps.scriptDir,
|
|
15777
|
+
env: runEnv,
|
|
15778
|
+
output,
|
|
15779
|
+
...deps.localRuntimeAdapterFactory ? { localRuntimeAdapterFactory: deps.localRuntimeAdapterFactory } : {},
|
|
15780
|
+
...localRuntimeCwd ? { localRuntimeCwd } : {},
|
|
15781
|
+
// `--machine-shell` 强制锁定 server 派发:绑定校验通过后 runtimeMode 一律为
|
|
15782
|
+
// "server"(+ requireRemoteDispatch 在派发层再兜一次),既不给 auto→local 早退
|
|
15783
|
+
// 留口子,也不受 NOLO_RUNTIME_MODE=local 覆盖(resolveRequestedRuntimeMode 以
|
|
15784
|
+
// options.runtimeMode 优先)。这是在唯一构造 runner 参数的入口做的,quota
|
|
15785
|
+
// fallback / 重试等复用 buildRunOptions 的路径同样被锁住。
|
|
15786
|
+
// 非 machine-shell 时保留本地通道判定:显式 runtimeMode 优先,其次
|
|
15787
|
+
// docker/host 本地目标在本地 run 上回落 runtimeMode=local。
|
|
15788
|
+
...parsed.machineShell ? { runtimeMode: "server", requireRemoteDispatch: true } : parsed.runtimeMode ? { runtimeMode: parsed.runtimeMode } : (dockerRuntimeLocal || instaboxRuntimeLocal || hostRuntimeLocal) && isLocalRun ? { runtimeMode: "local" } : {},
|
|
15789
|
+
// runtimeKey 与 machine-shell 的组合已在 parseAgentRunArgs 入口显式拒绝,
|
|
15790
|
+
// 这里直接透传即可(不再静默丢弃参数)。
|
|
15791
|
+
...parsed.runtimeKey ? { runtimeKey: parsed.runtimeKey } : {},
|
|
15792
|
+
...parsed.continueDialogId ? { continueDialogId: parsed.continueDialogId } : {},
|
|
15793
|
+
...parsed.strictContinueHistory ? { strictContinueHistory: true } : {},
|
|
15794
|
+
...parsed.spaceId ? { spaceId: parsed.spaceId } : {},
|
|
15795
|
+
...parsed.category ? { category: parsed.category } : {},
|
|
15796
|
+
...parsed.inheritedFromDialogKey ? { inheritedFromDialogKey: parsed.inheritedFromDialogKey } : {},
|
|
15797
|
+
...effectiveParentDialogId ? { parentDialogId: effectiveParentDialogId } : {},
|
|
15798
|
+
...parsed.parentWakeOnTerminal ? { parentWakeOnTerminal: true } : {},
|
|
15799
|
+
...parsed.subjectDialogKey ? { subjectDialogKey: parsed.subjectDialogKey } : {},
|
|
15800
|
+
...parsed.subjectRefs?.length ? { subjectRefs: parsed.subjectRefs } : {},
|
|
15801
|
+
...skillAllowedToolOverride !== void 0 ? { allowedToolNames: skillAllowedToolOverride } : parsed.allowedToolNames?.length ? { allowedToolNames: parsed.allowedToolNames } : {},
|
|
15802
|
+
...parsed.blockedToolNames?.length ? { blockedToolNames: parsed.blockedToolNames } : {},
|
|
15803
|
+
...machineShellOverride ? { runtimeToolPolicyOverride: machineShellOverride } : {},
|
|
15804
|
+
...activityTracker ? { onLoopEvent: activityTracker.onLoopEvent } : {},
|
|
15805
|
+
background: parsed.background,
|
|
15806
|
+
noStream: parsed.noStream,
|
|
15807
|
+
ephemeral: parsed.ephemeral,
|
|
15808
|
+
...typeof parsed.timeoutMs === "number" ? { timeoutMs: parsed.timeoutMs } : {},
|
|
15809
|
+
traceTools: parsed.traceTools,
|
|
15810
|
+
...parsed.eventsMode ? { eventsMode: parsed.eventsMode } : {},
|
|
15811
|
+
...parsed.taskEvidence ? { taskEvidence: parsed.taskEvidence } : {},
|
|
15812
|
+
...contextBlockScopes.length > 0 ? { contextBlockScopes } : extraContextBlocks.length > 0 ? { extraContextBlocks } : {}
|
|
15813
|
+
});
|
|
15814
|
+
terminalStatus.working();
|
|
15815
|
+
let result = await raceWithWatchdog(
|
|
14621
15816
|
runner({
|
|
14622
|
-
...buildRunOptions(
|
|
14623
|
-
...
|
|
15817
|
+
...buildRunOptions(effectiveAgentKey),
|
|
15818
|
+
...modelOverride ? { modelOverride } : {}
|
|
14624
15819
|
})
|
|
14625
15820
|
);
|
|
14626
15821
|
clearWatchdogs();
|
|
14627
|
-
|
|
14628
|
-
|
|
14629
|
-
|
|
14630
|
-
if (fallbackResult.turnCredits !== void 0) {
|
|
14631
|
-
runCreditsTotal = (runCreditsTotal ?? 0) + fallbackResult.turnCredits;
|
|
14632
|
-
}
|
|
14633
|
-
if (fallbackResult.exitCode !== 0) {
|
|
14634
|
-
result = {
|
|
14635
|
-
...fallbackResult,
|
|
14636
|
-
...fallbackResult.dialogId || result.dialogId ? { dialogId: fallbackResult.dialogId ?? result.dialogId } : {}
|
|
14637
|
-
};
|
|
15822
|
+
let runCreditsTotal = result.turnCredits;
|
|
15823
|
+
if (result.exitCode !== 0 && isQuotaExhaustedError(result.localError) && isLocalRun && parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0) {
|
|
15824
|
+
const fallbackAgentKey = parsed.fallbackAgentKeys[0];
|
|
14638
15825
|
output.write(
|
|
14639
|
-
`[nolo]
|
|
15826
|
+
`[nolo] quota exhausted on ${agentKey}, falling back to ${fallbackAgentKey}
|
|
14640
15827
|
`
|
|
14641
15828
|
);
|
|
14642
|
-
|
|
14643
|
-
|
|
14644
|
-
|
|
15829
|
+
const fallbackResult = await raceWithWatchdog(
|
|
15830
|
+
runner({
|
|
15831
|
+
...buildRunOptions(fallbackAgentKey),
|
|
15832
|
+
...result.dialogId ? { continueDialogId: result.dialogId } : {}
|
|
15833
|
+
})
|
|
15834
|
+
);
|
|
15835
|
+
clearWatchdogs();
|
|
15836
|
+
if (fallbackResult.exitCode === 0) {
|
|
15837
|
+
result = fallbackResult;
|
|
15838
|
+
}
|
|
15839
|
+
if (fallbackResult.turnCredits !== void 0) {
|
|
15840
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + fallbackResult.turnCredits;
|
|
15841
|
+
}
|
|
15842
|
+
if (fallbackResult.exitCode !== 0) {
|
|
15843
|
+
result = {
|
|
15844
|
+
...fallbackResult,
|
|
15845
|
+
...fallbackResult.dialogId || result.dialogId ? { dialogId: fallbackResult.dialogId ?? result.dialogId } : {}
|
|
15846
|
+
};
|
|
15847
|
+
output.write(
|
|
15848
|
+
`[nolo] fallback to ${fallbackAgentKey} also failed: ${fallbackResult.localError instanceof Error ? fallbackResult.localError.message : String(fallbackResult.localError ?? "unknown error")}
|
|
15849
|
+
`
|
|
15850
|
+
);
|
|
15851
|
+
}
|
|
15852
|
+
} else if (result.localError instanceof CliProviderQuotaError) {
|
|
15853
|
+
output.write(`
|
|
14645
15854
|
[nolo] Quota limit hit for ${parsed.agentKey} (CliProviderQuotaError).
|
|
14646
15855
|
`);
|
|
14647
|
-
|
|
14648
|
-
|
|
15856
|
+
if (parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0) {
|
|
15857
|
+
output.write(`Suggested alternatives for your decision: ${parsed.fallbackAgentKeys.join(", ")}
|
|
14649
15858
|
`);
|
|
14650
|
-
}
|
|
14651
|
-
output.write(`As the orchestrating agent, decide next based on task and re-dispatch (update task state with this attempt).
|
|
14652
|
-
`);
|
|
14653
|
-
}
|
|
14654
|
-
const queueFilePath = parsed.queueFile ?? (childRunId ? resolveRunQueuePath(childRunId, env, deps.homedir) : void 0);
|
|
14655
|
-
const queueFs = deps.fs ?? nodeFs;
|
|
14656
|
-
if (queueFilePath && queueFs.existsSync(queueFilePath) && result.dialogId && result.exitCode === 0) {
|
|
14657
|
-
const MAX_DRAIN_TURNS = 200;
|
|
14658
|
-
let drainTurns = 0;
|
|
14659
|
-
const popSingle = deps.popSingleQueueMessage ?? popSingleQueueMessage;
|
|
14660
|
-
while (drainTurns < MAX_DRAIN_TURNS && queueFs.existsSync(queueFilePath)) {
|
|
14661
|
-
const nextEntry = await popSingle(queueFilePath, deps);
|
|
14662
|
-
if (!nextEntry) {
|
|
14663
|
-
break;
|
|
14664
15859
|
}
|
|
14665
|
-
|
|
14666
|
-
|
|
14667
|
-
|
|
14668
|
-
|
|
14669
|
-
|
|
14670
|
-
|
|
14671
|
-
|
|
14672
|
-
|
|
14673
|
-
|
|
14674
|
-
|
|
14675
|
-
|
|
14676
|
-
if (
|
|
14677
|
-
|
|
15860
|
+
output.write(`As the orchestrating agent, decide next based on task and re-dispatch (update task state with this attempt).
|
|
15861
|
+
`);
|
|
15862
|
+
}
|
|
15863
|
+
const queueFilePath = parsed.queueFile ?? (childRunId ? resolveRunQueuePath(childRunId, env, deps.homedir) : void 0);
|
|
15864
|
+
const queueFs = deps.fs ?? nodeFs;
|
|
15865
|
+
if (queueFilePath && queueFs.existsSync(queueFilePath) && result.dialogId && result.exitCode === 0) {
|
|
15866
|
+
const MAX_DRAIN_TURNS = 200;
|
|
15867
|
+
let drainTurns = 0;
|
|
15868
|
+
const popSingle = deps.popSingleQueueMessage ?? popSingleQueueMessage;
|
|
15869
|
+
while (drainTurns < MAX_DRAIN_TURNS && queueFs.existsSync(queueFilePath)) {
|
|
15870
|
+
const nextEntry = await popSingle(queueFilePath, deps);
|
|
15871
|
+
if (!nextEntry) {
|
|
15872
|
+
break;
|
|
14678
15873
|
}
|
|
14679
|
-
|
|
15874
|
+
drainTurns += 1;
|
|
15875
|
+
try {
|
|
15876
|
+
const turnResult = await raceWithWatchdog(
|
|
15877
|
+
runner({
|
|
15878
|
+
...buildRunOptions(effectiveAgentKey, nextEntry.text),
|
|
15879
|
+
continueDialogId: result.dialogId,
|
|
15880
|
+
...modelOverride ? { modelOverride } : {}
|
|
15881
|
+
})
|
|
15882
|
+
);
|
|
15883
|
+
clearWatchdogs();
|
|
15884
|
+
result = turnResult;
|
|
15885
|
+
if (turnResult.turnCredits !== void 0) {
|
|
15886
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + turnResult.turnCredits;
|
|
15887
|
+
}
|
|
15888
|
+
if (result.exitCode !== 0) {
|
|
15889
|
+
break;
|
|
15890
|
+
}
|
|
15891
|
+
} catch (drainError) {
|
|
15892
|
+
clearWatchdogs();
|
|
15893
|
+
console.error(`[nolo] queue turn failed with exception: ${toErrorMessage(drainError)}`);
|
|
15894
|
+
result = {
|
|
15895
|
+
...result,
|
|
15896
|
+
exitCode: 1,
|
|
15897
|
+
localError: drainError
|
|
15898
|
+
};
|
|
14680
15899
|
break;
|
|
14681
15900
|
}
|
|
14682
|
-
}
|
|
14683
|
-
|
|
14684
|
-
console.error(
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
exitCode: 1,
|
|
14688
|
-
localError: drainError
|
|
14689
|
-
};
|
|
14690
|
-
break;
|
|
15901
|
+
}
|
|
15902
|
+
if (drainTurns >= MAX_DRAIN_TURNS) {
|
|
15903
|
+
console.error(
|
|
15904
|
+
`[nolo] Warning: queue drain loop reached defensive limit of ${MAX_DRAIN_TURNS} turns, stopping.`
|
|
15905
|
+
);
|
|
14691
15906
|
}
|
|
14692
15907
|
}
|
|
14693
|
-
|
|
14694
|
-
|
|
14695
|
-
|
|
14696
|
-
)
|
|
14697
|
-
}
|
|
14698
|
-
|
|
14699
|
-
|
|
14700
|
-
|
|
14701
|
-
output.write(`
|
|
15908
|
+
terminalStatus.settle({
|
|
15909
|
+
exitCode: result.exitCode,
|
|
15910
|
+
streamInterrupted: result.streamInterrupted,
|
|
15911
|
+
stalledOrTruncated: isRunResultStalledOrTruncated(result)
|
|
15912
|
+
});
|
|
15913
|
+
if (result.dialogId) {
|
|
15914
|
+
if (parsed.background) {
|
|
15915
|
+
output.write(`
|
|
14702
15916
|
[nolo] background dialog ${result.dialogId}
|
|
14703
15917
|
`);
|
|
14704
|
-
|
|
15918
|
+
output.write(`[nolo] read: nolo dialog read ${result.dialogId}
|
|
14705
15919
|
`);
|
|
14706
|
-
|
|
14707
|
-
|
|
15920
|
+
} else {
|
|
15921
|
+
output.write(`
|
|
14708
15922
|
[nolo] dialog ${result.dialogId}
|
|
14709
15923
|
`);
|
|
15924
|
+
}
|
|
14710
15925
|
}
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
})
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
`
|
|
15926
|
+
if (shouldPrintLocalRunSummary({ parsed, localRuntimeCwd })) {
|
|
15927
|
+
try {
|
|
15928
|
+
const inspect = deps.inspectLocalRunWorkspace ?? inspectLocalRunWorkspace;
|
|
15929
|
+
const inspection = await inspect(localRuntimeCwd);
|
|
15930
|
+
output.write(formatLocalRunSummary({
|
|
15931
|
+
dialogId: result.dialogId,
|
|
15932
|
+
inspection
|
|
15933
|
+
}));
|
|
15934
|
+
} catch (error) {
|
|
15935
|
+
output.write(
|
|
15936
|
+
`
|
|
14723
15937
|
[nolo] local run summary unavailable: ${toErrorMessage(error)}
|
|
14724
15938
|
`
|
|
14725
|
-
|
|
14726
|
-
}
|
|
14727
|
-
}
|
|
14728
|
-
if (typeof childRunId === "string" && childRunId.length > 0) {
|
|
14729
|
-
const childRecordForDoD = (deps.readRunRecord ?? readRunRecord)(childRunId, {
|
|
14730
|
-
env,
|
|
14731
|
-
homedir: deps.homedir,
|
|
14732
|
-
fs: deps.fs
|
|
14733
|
-
});
|
|
14734
|
-
const isStalledOrTruncated = isRunResultStalledOrTruncated(result);
|
|
14735
|
-
const truncationNote = resolveRunSettlementNote(result);
|
|
14736
|
-
const outcome = resolveRunOutcome({
|
|
14737
|
-
kind: "result",
|
|
14738
|
-
exitCode: result.exitCode,
|
|
14739
|
-
isStalledOrTruncated
|
|
14740
|
-
});
|
|
14741
|
-
let dodResults;
|
|
14742
|
-
try {
|
|
14743
|
-
dodResults = (deps.runDoDCommands ?? runDoDCommands)(
|
|
14744
|
-
childRecordForDoD?.dodCommands,
|
|
14745
|
-
childRecordForDoD?.cwd
|
|
14746
|
-
);
|
|
14747
|
-
} catch (dodError) {
|
|
14748
|
-
console.warn(`[nolo] DoD verification failed to run for ${childRunId}:`, dodError);
|
|
14749
|
-
}
|
|
14750
|
-
let failureReason;
|
|
14751
|
-
let toolCallCount;
|
|
14752
|
-
if (outcome.status === "failed") {
|
|
14753
|
-
if (result.emptyAssistantFallbackReason === "repetition_loop" || result.emptyAssistantFallbackReason === "stagnant_tool_calls") {
|
|
14754
|
-
failureReason = "stalled";
|
|
14755
|
-
} else if (result.localError && isQuotaExhaustedError(result.localError)) {
|
|
14756
|
-
failureReason = "provider_rate_limited";
|
|
14757
|
-
} else if (result.localError) {
|
|
14758
|
-
const errMsg = toErrorMessage(result.localError).toLowerCase();
|
|
14759
|
-
if (errMsg.includes("config_unresolved") || errMsg.includes("unresolved config")) {
|
|
14760
|
-
failureReason = "config_unresolved";
|
|
14761
|
-
} else {
|
|
14762
|
-
failureReason = "provider_error";
|
|
14763
|
-
}
|
|
14764
|
-
}
|
|
14765
|
-
const currentActivity = activityTracker?.getActivity();
|
|
14766
|
-
const rawToolCount = currentActivity?.counters?.toolCalls ?? childRecordForDoD?.activity?.counters?.toolCalls;
|
|
14767
|
-
if (typeof rawToolCount === "number" && rawToolCount > 0) {
|
|
14768
|
-
toolCallCount = rawToolCount;
|
|
15939
|
+
);
|
|
14769
15940
|
}
|
|
14770
15941
|
}
|
|
14771
|
-
|
|
14772
|
-
childRunId,
|
|
14773
|
-
{
|
|
14774
|
-
status: outcome.status,
|
|
14775
|
-
exitCode: outcome.exitCode,
|
|
14776
|
-
dialogId: result.dialogId,
|
|
14777
|
-
...dodResults ? { dodResults } : {},
|
|
14778
|
-
// run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
|
|
14779
|
-
// 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
|
|
14780
|
-
...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
|
|
14781
|
-
...failureReason ? { failureReason } : {},
|
|
14782
|
-
...toolCallCount !== void 0 ? { toolCallCount } : {},
|
|
14783
|
-
...truncationNote
|
|
14784
|
-
},
|
|
14785
|
-
{
|
|
15942
|
+
if (typeof childRunId === "string" && childRunId.length > 0) {
|
|
15943
|
+
const childRecordForDoD = (deps.readRunRecord ?? readRunRecord)(childRunId, {
|
|
14786
15944
|
env,
|
|
14787
15945
|
homedir: deps.homedir,
|
|
14788
|
-
fs: deps.fs
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
|
|
15946
|
+
fs: deps.fs
|
|
15947
|
+
});
|
|
15948
|
+
const isStalledOrTruncated = isRunResultStalledOrTruncated(result);
|
|
15949
|
+
const truncationNote = resolveRunSettlementNote(result);
|
|
15950
|
+
const outcome = resolveRunOutcome({
|
|
15951
|
+
kind: "result",
|
|
15952
|
+
exitCode: result.exitCode,
|
|
15953
|
+
isStalledOrTruncated
|
|
15954
|
+
});
|
|
15955
|
+
let dodResults;
|
|
15956
|
+
try {
|
|
15957
|
+
dodResults = (deps.runDoDCommands ?? runDoDCommands)(
|
|
15958
|
+
childRecordForDoD?.dodCommands,
|
|
15959
|
+
childRecordForDoD?.cwd
|
|
15960
|
+
);
|
|
15961
|
+
} catch (dodError) {
|
|
15962
|
+
console.warn(`[nolo] DoD verification failed to run for ${childRunId}:`, dodError);
|
|
15963
|
+
}
|
|
15964
|
+
let failureReason;
|
|
15965
|
+
let toolCallCount;
|
|
15966
|
+
if (outcome.status === "failed") {
|
|
15967
|
+
if (result.emptyAssistantFallbackReason === "repetition_loop" || result.emptyAssistantFallbackReason === "stagnant_tool_calls") {
|
|
15968
|
+
failureReason = "stalled";
|
|
15969
|
+
} else if (result.localError && isQuotaExhaustedError(result.localError)) {
|
|
15970
|
+
failureReason = "provider_rate_limited";
|
|
15971
|
+
} else if (result.localError) {
|
|
15972
|
+
const errMsg = toErrorMessage(result.localError).toLowerCase();
|
|
15973
|
+
if (errMsg.includes("config_unresolved") || errMsg.includes("unresolved config")) {
|
|
15974
|
+
failureReason = "config_unresolved";
|
|
15975
|
+
} else {
|
|
15976
|
+
failureReason = "provider_error";
|
|
15977
|
+
}
|
|
15978
|
+
}
|
|
15979
|
+
const currentActivity = activityTracker?.getActivity();
|
|
15980
|
+
const rawToolCount = currentActivity?.counters?.toolCalls ?? childRecordForDoD?.activity?.counters?.toolCalls;
|
|
15981
|
+
if (typeof rawToolCount === "number" && rawToolCount > 0) {
|
|
15982
|
+
toolCallCount = rawToolCount;
|
|
15983
|
+
}
|
|
15984
|
+
}
|
|
15985
|
+
await settleRunTerminalAuthoritatively(
|
|
15986
|
+
childRunId,
|
|
15987
|
+
{
|
|
15988
|
+
status: outcome.status,
|
|
15989
|
+
exitCode: outcome.exitCode,
|
|
15990
|
+
dialogId: result.dialogId,
|
|
15991
|
+
...dodResults ? { dodResults } : {},
|
|
15992
|
+
// run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
|
|
15993
|
+
// 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
|
|
15994
|
+
...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
|
|
15995
|
+
...failureReason ? { failureReason } : {},
|
|
15996
|
+
...toolCallCount !== void 0 ? { toolCallCount } : {},
|
|
15997
|
+
...result.finalText ? { lastAssistantText: result.finalText } : {},
|
|
15998
|
+
// 仅用于 .result.md 头(front matter):旁路读取,不改 result 形状。
|
|
15999
|
+
...getRunResultHeaderMeta(result),
|
|
16000
|
+
...truncationNote
|
|
16001
|
+
},
|
|
16002
|
+
{
|
|
16003
|
+
env,
|
|
16004
|
+
homedir: deps.homedir,
|
|
16005
|
+
fs: deps.fs,
|
|
16006
|
+
now: deps.now,
|
|
16007
|
+
sleep: deps.sleep
|
|
16008
|
+
},
|
|
16009
|
+
deps.transitionRunToTerminal
|
|
16010
|
+
);
|
|
16011
|
+
}
|
|
16012
|
+
return result.exitCode;
|
|
16013
|
+
} finally {
|
|
16014
|
+
shellApprovalChild?.close();
|
|
16015
|
+
if (shellApprovalChild && process.connected) process.disconnect();
|
|
14794
16016
|
}
|
|
14795
|
-
return result.exitCode;
|
|
14796
|
-
}
|
|
14797
|
-
var BALANCE_ERROR_PATTERNS = [
|
|
14798
|
-
/UPSTREAM_402/i,
|
|
14799
|
-
/Insufficient Balance/i,
|
|
14800
|
-
/insufficient\s+balance/i,
|
|
14801
|
-
/余额不足/
|
|
14802
|
-
];
|
|
14803
|
-
function isBalanceExhaustedError(error) {
|
|
14804
|
-
if (!error) return false;
|
|
14805
|
-
const message = error instanceof Error ? error.message : typeof error === "string" ? error : String(error?.message ?? "");
|
|
14806
|
-
return BALANCE_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
|
14807
16017
|
}
|
|
14808
16018
|
|
|
14809
16019
|
export {
|
|
@@ -14839,6 +16049,7 @@ export {
|
|
|
14839
16049
|
applyDetectedBackground,
|
|
14840
16050
|
renderSurfaceLine,
|
|
14841
16051
|
surfaceBackgroundSequence,
|
|
16052
|
+
composerSurfaceBackgroundSequence,
|
|
14842
16053
|
userSurfaceBackgroundSequence,
|
|
14843
16054
|
themeText,
|
|
14844
16055
|
tuiRenderThemeFingerprint,
|
|
@@ -14846,12 +16057,16 @@ export {
|
|
|
14846
16057
|
polishBreathInsertsBlankBetween,
|
|
14847
16058
|
formatAssistantDisplay,
|
|
14848
16059
|
redactSecrets,
|
|
16060
|
+
safeAskText,
|
|
14849
16061
|
TUI_TREE_MARKER,
|
|
16062
|
+
estimateMessagesTokens,
|
|
16063
|
+
historyTokensBeforeLatestAssistant,
|
|
14850
16064
|
resolveAgentModelIdentity,
|
|
14851
16065
|
resolveAgentContextWindow,
|
|
14852
16066
|
platformCreditsFromUsage,
|
|
14853
16067
|
formatCreditsChip,
|
|
14854
|
-
|
|
16068
|
+
resolveAuthorityTurnCount,
|
|
16069
|
+
computeBaselineContextTokens,
|
|
14855
16070
|
renderTokenStatus,
|
|
14856
16071
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
14857
16072
|
shouldCollapsePaste,
|
|
@@ -14863,18 +16078,22 @@ export {
|
|
|
14863
16078
|
releaseCollapsedPasteReferences,
|
|
14864
16079
|
expandRangeToCollapsedPasteChips,
|
|
14865
16080
|
findCollapsedPasteSpanAt,
|
|
16081
|
+
emitTerminalProgramStatus,
|
|
16082
|
+
isBalanceExhaustedError,
|
|
14866
16083
|
runAgentTurn,
|
|
14867
16084
|
resolveWorkflowReference,
|
|
14868
16085
|
resolveSkillReference,
|
|
14869
16086
|
buildSkillContextBlocks,
|
|
14870
16087
|
prependSubjectDialogMarker,
|
|
14871
16088
|
normalizeCliImageInput,
|
|
16089
|
+
buildHostEnvironmentLayer,
|
|
14872
16090
|
readAgentsMdLayerFromDisk,
|
|
14873
16091
|
resolveCliMemory,
|
|
16092
|
+
FAILED_EMPTY_ASSISTANT_REASONS,
|
|
16093
|
+
isRunResultStalledOrTruncated,
|
|
16094
|
+
resolveTerminalProgramStatusState,
|
|
14874
16095
|
inspectLocalRunWorkspace,
|
|
14875
16096
|
resolveRunOutcome,
|
|
14876
|
-
isRunResultStalledOrTruncated,
|
|
14877
16097
|
resolveRunSettlementNote,
|
|
14878
|
-
runAgentRunCommand
|
|
14879
|
-
isBalanceExhaustedError
|
|
16098
|
+
runAgentRunCommand
|
|
14880
16099
|
};
|