nolo-cli 0.54.0 → 0.61.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/{_executeModel-OPTKYHJA.js → _executeModel-CKT6RGTL.js} +48 -45
- package/{action-ORXWW2ZG.js → action-76JX3JX3.js} +7 -6
- package/{addContentAction-53BZ34AE.js → addContentAction-V3NAZRTJ.js} +6 -5
- package/{addDialogAgentAction-JRYUS54Y.js → addDialogAgentAction-RZOAF46K.js} +5 -4
- package/{agentDeleteCommand-FJIWU2BS.js → agentDeleteCommand-VN7NPXQ4.js} +30 -27
- package/{agentEmailCommands-CE32L43B.js → agentEmailCommands-F2TNAV4A.js} +59 -56
- package/{agentGrantCommands-2LEZDADN.js → agentGrantCommands-R3VQEZJR.js} +1 -1
- package/{agentListCommands-VJNKULIK.js → agentListCommands-OSM2ANI3.js} +61 -31
- package/{agentMachineCommands-HCJ3WQXL.js → agentMachineCommands-MTPWYVRV.js} +31 -28
- package/{agentPullCommand-M552CYSI.js → agentPullCommand-N7L2CT7L.js} +2 -2
- package/{agentRecordCommands-QFWERED4.js → agentRecordCommands-VWAWTVVC.js} +57 -54
- package/{agentRunCommand-G3GQMUNN.js → agentRunCommand-PLZOBNVK.js} +61 -58
- package/{agentRunControl-INKFDXDA.js → agentRunControl-WECMOO6O.js} +11 -6
- package/{agentRuntimeLocal-K327ELSL.js → agentRuntimeLocal-XCJLRWQE.js} +26 -23
- package/{agentSlice-ODKF4J6M.js → agentSlice-F6DOP4IW.js} +8 -7
- package/{appDeleteCommands-XUXMFDI4.js → appDeleteCommands-3BCFTRFJ.js} +30 -27
- package/{appDeployCommands-37F4GPCU.js → appDeployCommands-B4GMHCYA.js} +30 -27
- package/{appDeployStatusCommands-WSPU7TUK.js → appDeployStatusCommands-4MN36WIG.js} +30 -27
- package/{appGetCommands-YLOBA3EM.js → appGetCommands-4GJIEUAX.js} +30 -27
- package/{appListCommands-UD62R5ME.js → appListCommands-CHU53GSX.js} +30 -27
- package/{authCommand-OK6HLHGS.js → authCommand-WOTWLJNF.js} +35 -29
- package/{authCommands-2DUIUEMT.js → authCommands-ILTBI6JV.js} +7 -5
- package/{chatQueueReduxAdapter-TV2TUOQS.js → chatQueueReduxAdapter-HNSQXNIR.js} +20 -18
- package/{chunk-HPW5MNDQ.js → chunk-22BTGNSP.js} +113 -57
- package/{chunk-TR4DXUYX.js → chunk-2HPRMEEZ.js} +1180 -736
- package/{chunk-UNZDCI3O.js → chunk-2KDR4CWE.js} +35 -4
- package/{chunk-3ZTR7ZO4.js → chunk-2PGGC63K.js} +1 -1
- package/{chunk-JXIP6ZWH.js → chunk-37QVS7BU.js} +18 -5
- package/{chunk-EA5OYZVD.js → chunk-37XDGCY7.js} +1 -1
- package/chunk-3BLB7QKO.js +433 -0
- package/{chunk-CS6TCJ7E.js → chunk-3JQ2NRYU.js} +30 -7
- package/{chunk-RHMDMTDK.js → chunk-3JWKQDA4.js} +2 -2
- package/{chunk-3LKZRP7E.js → chunk-3QGUVVX5.js} +2 -2
- package/{chunk-SSXTSPSG.js → chunk-45YO6H7P.js} +71 -30
- package/{chunk-EJE33XNR.js → chunk-4C4ST2YE.js} +1521 -565
- package/{chunk-YLCUU3WM.js → chunk-4NJEIGBQ.js} +5 -5
- package/{chunk-K4NISKOR.js → chunk-5ZYA4JJ3.js} +47 -17
- package/{chunk-3Y2K5O2R.js → chunk-7A3RRUCQ.js} +125 -40
- package/{chunk-5FCIPEKT.js → chunk-7O7KH4X5.js} +1051 -926
- package/{chunk-6HDYSFLO.js → chunk-7UF7CQ6B.js} +3 -3
- package/{chunk-SUEIAK5N.js → chunk-AQMVUA7N.js} +1 -0
- package/{chunk-WQHGJHAL.js → chunk-AVE2YR4F.js} +732 -726
- package/{chunk-6COJEAYH.js → chunk-B7DXRX7F.js} +44 -37
- package/chunk-BFU6C242.js +66 -0
- package/{chunk-IA3A5373.js → chunk-C3FZR5EC.js} +1 -1
- package/{chunk-IWUMSAQF.js → chunk-CJCJF5XB.js} +26 -3
- package/{chunk-UGBHDMHI.js → chunk-CP7VIDZ7.js} +1 -1
- package/{chunk-JON2PHYT.js → chunk-CTCW7U7N.js} +1 -1
- package/{chunk-YBFJQC2M.js → chunk-D5XKNNUV.js} +65 -42
- package/{chunk-7NYDJAQ7.js → chunk-DNNSCSA2.js} +5 -5
- package/{chunk-NI2BS6UD.js → chunk-DWUCB2A3.js} +1 -1
- package/{chunk-AA564GBL.js → chunk-DZZL7UBV.js} +1 -1
- package/{chunk-75MSWWUE.js → chunk-E6RGHPDR.js} +5 -3
- package/chunk-EDKF7RX4.js +30 -0
- package/{chunk-FJHMLRDQ.js → chunk-ES6CVKVD.js} +21 -27
- package/{chunk-SYYUU7EV.js → chunk-FHAGENAS.js} +2 -3
- package/{chunk-NJUQBYFJ.js → chunk-FKFMIBTT.js} +3 -1
- package/{chunk-INZZJSQF.js → chunk-FZGV4FGK.js} +24 -12
- package/{chunk-YQBXOHE6.js → chunk-GAL47RNP.js} +1 -1
- package/{chunk-UOWXD4VN.js → chunk-HBPV76EK.js} +335 -243
- package/{chunk-MLEZPE3U.js → chunk-HLU5Q2GV.js} +4 -4
- package/{chunk-TC6P4NDR.js → chunk-HQP7HJDL.js} +6 -6
- package/{chunk-7FAS3NEF.js → chunk-IYCUMIYS.js} +19 -15
- package/{chunk-AUVFJGPC.js → chunk-JX5PJCWS.js} +7 -5
- package/{chunk-LYGNQHUW.js → chunk-JYYZCK2Z.js} +2 -4
- package/{chunk-XOJRZUPF.js → chunk-KWSQR2KK.js} +14 -29
- package/{chunk-2WBFJHQA.js → chunk-L7B47JXR.js} +34 -39
- package/{chunk-EICIFHVS.js → chunk-LAFC3B2I.js} +1 -1
- package/{chunk-N4JKMCY3.js → chunk-LJKICKVC.js} +2 -2
- package/chunk-M3JEW6N6.js +193 -0
- package/{chunk-LRGKOI5Y.js → chunk-MBOEV4L2.js} +7 -3
- package/{chunk-SVDMVX4G.js → chunk-MMZ6ZTVO.js} +112 -73
- package/{chunk-JDSUTNYY.js → chunk-MP64VFGD.js} +2 -2
- package/{chunk-NFLA6GSU.js → chunk-MXUDQZXQ.js} +44 -5
- package/chunk-N4G4PKQ6.js +23 -0
- package/{chunk-KXKQO4Q6.js → chunk-NTW5GWDM.js} +58 -1
- package/chunk-ONXOABJR.js +215 -0
- package/{chunk-TY3ADTX5.js → chunk-OZX2IPKM.js} +7 -2
- package/{chunk-Q4XZVZPN.js → chunk-P7OOB7QP.js} +1 -1
- package/{chunk-XIJZOCSP.js → chunk-PEZJEQAO.js} +1 -1
- package/{chunk-SWJGJMTW.js → chunk-PQDIDWGX.js} +1 -1
- package/chunk-PSCNXBYA.js +11 -0
- package/{chunk-BY2FF2C4.js → chunk-QEFJJS2I.js} +55 -73
- package/{chunk-BG7J6Y5X.js → chunk-QEW2MFDQ.js} +1 -1
- package/{chunk-KLIBF3BY.js → chunk-RDBARW6T.js} +8 -3
- package/{chunk-ZVOHVJI3.js → chunk-RJ2SAFB5.js} +82 -35
- package/{chunk-MYMBBB6Q.js → chunk-RVWRKFUB.js} +5 -3
- package/{chunk-43CXXVJD.js → chunk-RXX4GDIH.js} +1 -1
- package/chunk-SEJ5OS6F.js +49 -0
- package/{chunk-SAJSBPI2.js → chunk-SOJM57FX.js} +5 -2
- package/{chunk-EKLRRZIN.js → chunk-SPAQ4PVV.js} +0 -5
- package/{chunk-L7NG2M6H.js → chunk-TRV2MIDW.js} +89 -74
- package/{chunk-5UAYZEXO.js → chunk-UZPQSVM6.js} +1 -1
- package/{chunk-SVC3GGUA.js → chunk-VMWYBIXG.js} +7 -5
- package/{chunk-ZHXJ6M7T.js → chunk-W7XHHYWM.js} +4 -0
- package/{chunk-UR66XPVF.js → chunk-XAVSS3KE.js} +21 -3
- package/{chunk-A65UV3M5.js → chunk-XOKOSO35.js} +10 -19
- package/{chunk-VZMUOPYG.js → chunk-XTJTN3RW.js} +46 -3
- package/{chunk-T5HJEUQN.js → chunk-YCDWJX45.js} +1 -1
- package/{chunk-BBTN4NQD.js → chunk-Z4QSJILV.js} +85 -13
- package/{chunk-O5FLGN2L.js → chunk-ZRSJ3JEH.js} +6 -2
- package/{cliExecutor-BBUVQU4L.js → cliExecutor-HG3S345O.js} +1 -1
- package/{codingSkills-BCQXRZOI.js → codingSkills-VDXQYWX4.js} +2 -2
- package/{contentThunks-KNI6VXLT.js → contentThunks-7YG2ZYQC.js} +21 -19
- package/{cooldownCommands-GI5NNWGL.js → cooldownCommands-BSCH2W7P.js} +2 -2
- package/{createAgentAutomationAction-OK4L33KF.js → createAgentAutomationAction-PJQSCAIO.js} +23 -21
- package/{createDialogAction-JDSMY4AY.js → createDialogAction-SFEJX6SP.js} +23 -21
- package/{createPageAction-T7RA3HCG.js → createPageAction-B7WRHOQO.js} +24 -22
- package/{dbSlice-TVX6SN2T.js → dbSlice-IBVOBVMS.js} +5 -4
- package/{deleteFile-JYKRT7C3.js → deleteFile-FWP2PSBG.js} +3 -2
- package/{dialogCommands-UQZYWOOV.js → dialogCommands-VL2X22QC.js} +30 -27
- package/{dialogSlice-TYW2G7IL.js → dialogSlice-ANMACABO.js} +20 -18
- package/{docCreateCommands-OA6HZBWO.js → docCreateCommands-ITLGZ5YI.js} +29 -26
- package/{docDeleteCommands-KBB3YQI2.js → docDeleteCommands-LH3YNL4C.js} +30 -27
- package/{docReadCommands-ZLMFVC67.js → docReadCommands-YAJ77F36.js} +29 -26
- package/{docStore-2URPBVCS.js → docStore-D4HGHPWI.js} +6 -5
- package/{docUpdateCommands-HMH5KUON.js → docUpdateCommands-DQBOMH2G.js} +29 -26
- package/{getPricing-RFOPUWHY.js → getPricing-NM3NUTAS.js} +4 -4
- package/handleSendMessageAction-DF2OABGW.js +675 -0
- package/index.js +79 -88
- package/{lib-2ZTNRXR4.js → lib-FRRS27KN.js} +63 -28
- package/{localRuntimeAuthority-KQDAE64E.js → localRuntimeAuthority-R5UBODT3.js} +6 -4
- package/{localRuntimeDb-PF7CFKDL.js → localRuntimeDb-P37ZTX55.js} +1 -1
- package/{machineCommands-RK6L7ZWL.js → machineCommands-JXDYQ5LB.js} +296 -79
- package/{machineWsRunDispatch-3X64DW2Z.js → machineWsRunDispatch-3QHI7JX5.js} +55 -52
- package/{memberThunks-THZYZFSN.js → memberThunks-VZI6G7YZ.js} +10 -8
- package/{models-JVKUEER5.js → models-FAMINFZ7.js} +2 -2
- package/package.json +3 -2
- package/{read-K4JU4MQC.js → read-2BYWW7AA.js} +3 -2
- package/{readDocTool-LQGR6FUN.js → readDocTool-LC3A7QTB.js} +1 -1
- package/{readlineWorkspace-XUFJV3RS.js → readlineWorkspace-KVZTEAHB.js} +4365 -2795
- package/{removeDialogAgentAction-ECHCFB7N.js → removeDialogAgentAction-SFYZXHNK.js} +8 -7
- package/{runAgentClientLoop-24GQ2AW6.js → runAgentClientLoop-KGTEL7ZP.js} +49 -45
- package/{runtimeDoctorCommands-JKTTN723.js → runtimeDoctorCommands-CROTMULY.js} +7 -5
- package/{setDialogExtraReferencesAction-KCVJNGMB.js → setDialogExtraReferencesAction-Q32RGFTA.js} +6 -5
- package/{setPrimaryDialogAgentAction-VDOBOMKC.js → setPrimaryDialogAgentAction-BFYJHUJS.js} +8 -7
- package/{settingSlice-VR2IJSXC.js → settingSlice-IRUU4VFB.js} +6 -5
- package/{skillDiscovery-2QTZINON.js → skillDiscovery-NTRLM6KP.js} +1 -1
- package/{spaceCommands-S5YJJXL7.js → spaceCommands-KNAYWMCZ.js} +33 -215
- package/{streamAgentChatTurn-QHKP3ABO.js → streamAgentChatTurn-FLYPTXKZ.js} +105 -73
- package/{switchDialogAgentAction-5L4UP7VI.js → switchDialogAgentAction-L2KOKCGG.js} +5 -4
- package/{tableCommands-R6WFRDYF.js → tableCommands-SUNTHAYX.js} +1 -1
- package/{toolApiClient-53U4UDFF.js → toolApiClient-VGYUB4P5.js} +2 -1
- package/{tools-SSXSTC3O.js → tools-CVLUXK6P.js} +37 -34
- package/{tuiSummaryLlmCaller-URFJHFC5.js → tuiSummaryLlmCaller-F3DPFFZM.js} +15 -13
- package/{updateCommands-IYKLF3JX.js → updateCommands-AJYSD73Y.js} +2 -2
- package/{updateDialogTitleAction-YFYAEW3T.js → updateDialogTitleAction-HWJIZEIV.js} +23 -21
- package/agentSuperviseCommands-5AR3DKNN.js +0 -640
- package/chunk-6IGD47IC.js +0 -19
- package/chunk-FD36SCCD.js +0 -105
- package/chunk-GRFK2XP4.js +0 -230
- package/chunk-HJTAGT3W.js +0 -370
- package/handleSendMessageAction-GO53TY7U.js +0 -409
|
@@ -1,640 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
generateRunReport,
|
|
3
|
-
parseDoDResultsFromMarkdown
|
|
4
|
-
} from "./chunk-HJTAGT3W.js";
|
|
5
|
-
import {
|
|
6
|
-
checkStaleRun,
|
|
7
|
-
finalizeRunRecord,
|
|
8
|
-
isRunTerminalStatus,
|
|
9
|
-
readRunRecord,
|
|
10
|
-
resolveRunReportJsonPath,
|
|
11
|
-
resolveRunReportPath,
|
|
12
|
-
resolveRunsDir,
|
|
13
|
-
spawnLocalBackgroundRun,
|
|
14
|
-
terminateRunProcess
|
|
15
|
-
} from "./chunk-SSXTSPSG.js";
|
|
16
|
-
import "./chunk-KXKQO4Q6.js";
|
|
17
|
-
import {
|
|
18
|
-
toErrorMessage
|
|
19
|
-
} from "./chunk-HNMXYYJR.js";
|
|
20
|
-
import {
|
|
21
|
-
readOption
|
|
22
|
-
} from "./chunk-A7GB5UGH.js";
|
|
23
|
-
import "./chunk-OLZBQWZU.js";
|
|
24
|
-
import "./chunk-LCBAMY2M.js";
|
|
25
|
-
import "./chunk-4SN6J65J.js";
|
|
26
|
-
import "./chunk-CF7PE763.js";
|
|
27
|
-
import "./chunk-G3SUCT4W.js";
|
|
28
|
-
import "./chunk-4VNS5WPM.js";
|
|
29
|
-
|
|
30
|
-
// packages/cli/agentSuperviseCommands.ts
|
|
31
|
-
import { homedir as nodeHomedir } from "node:os";
|
|
32
|
-
import * as nodeFs from "node:fs";
|
|
33
|
-
import { isAbsolute, join, resolve } from "node:path";
|
|
34
|
-
function parseTaskQueueMarkdown(content, options = {}) {
|
|
35
|
-
if (!content || typeof content !== "string" || content.trim().length === 0) {
|
|
36
|
-
throw new Error("Task queue markdown content is empty or invalid.");
|
|
37
|
-
}
|
|
38
|
-
const lines = content.split(/\r?\n/);
|
|
39
|
-
const tasks = [];
|
|
40
|
-
let currentTitle = null;
|
|
41
|
-
let currentLines = [];
|
|
42
|
-
let taskIndex = 0;
|
|
43
|
-
function flushCurrent() {
|
|
44
|
-
if (currentTitle !== null) {
|
|
45
|
-
const brief = currentLines.join("\n").trim();
|
|
46
|
-
taskIndex += 1;
|
|
47
|
-
tasks.push({
|
|
48
|
-
id: `task-${taskIndex}`,
|
|
49
|
-
title: currentTitle,
|
|
50
|
-
brief
|
|
51
|
-
});
|
|
52
|
-
currentLines = [];
|
|
53
|
-
currentTitle = null;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
for (const line of lines) {
|
|
57
|
-
const headerMatch = line.match(/^##\s+(.*)$/);
|
|
58
|
-
if (headerMatch) {
|
|
59
|
-
flushCurrent();
|
|
60
|
-
currentTitle = headerMatch[1].trim();
|
|
61
|
-
} else if (currentTitle !== null) {
|
|
62
|
-
currentLines.push(line);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
flushCurrent();
|
|
66
|
-
if (tasks.length === 0) {
|
|
67
|
-
throw new Error(
|
|
68
|
-
"Invalid queue format: No task sections (## ...) found in queue file."
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
if (!options.allowEmpty) {
|
|
72
|
-
const emptyTask = tasks.find((t) => !t.brief || t.brief.trim().length === 0);
|
|
73
|
-
if (emptyTask) {
|
|
74
|
-
throw new Error(
|
|
75
|
-
`Invalid queue format: Task "${emptyTask.title}" has an empty brief.`
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return tasks;
|
|
80
|
-
}
|
|
81
|
-
function parseAgentSuperviseArgs(args) {
|
|
82
|
-
if (args.includes("--help") || args.includes("-h")) {
|
|
83
|
-
return { help: true };
|
|
84
|
-
}
|
|
85
|
-
const agentKey = readOption(args, "--agent") || readOption(args, "-a");
|
|
86
|
-
const queueFile = readOption(args, "--queue") || readOption(args, "-q");
|
|
87
|
-
const cwd = readOption(args, "--cwd");
|
|
88
|
-
const maxRetriesStr = readOption(args, "--max-retries");
|
|
89
|
-
const maxRetries = maxRetriesStr ? parseInt(maxRetriesStr, 10) : 3;
|
|
90
|
-
if (isNaN(maxRetries) || maxRetries < 0) {
|
|
91
|
-
return { error: `Invalid --max-retries: "${maxRetriesStr}". Must be a non-negative integer.` };
|
|
92
|
-
}
|
|
93
|
-
const stallMinutesStr = readOption(args, "--stall-minutes");
|
|
94
|
-
const stallMinutes = stallMinutesStr ? parseFloat(stallMinutesStr) : 60;
|
|
95
|
-
if (isNaN(stallMinutes) || stallMinutes <= 0) {
|
|
96
|
-
return { error: `Invalid --stall-minutes: "${stallMinutesStr}". Must be a positive number.` };
|
|
97
|
-
}
|
|
98
|
-
const pollIntervalStr = readOption(args, "--poll-interval") || readOption(args, "--poll-interval-s");
|
|
99
|
-
const pollIntervalSec = pollIntervalStr ? parseFloat(pollIntervalStr) : 60;
|
|
100
|
-
if (isNaN(pollIntervalSec) || pollIntervalSec <= 0) {
|
|
101
|
-
return { error: `Invalid --poll-interval: "${pollIntervalStr}". Must be a positive number.` };
|
|
102
|
-
}
|
|
103
|
-
const dodCommands = [];
|
|
104
|
-
for (let i = 0; i < args.length; i++) {
|
|
105
|
-
if (args[i] === "--dod" && typeof args[i + 1] === "string") {
|
|
106
|
-
dodCommands.push(args[i + 1]);
|
|
107
|
-
i += 1;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (!agentKey) {
|
|
111
|
-
return { error: "Missing required option: --agent <agentId>" };
|
|
112
|
-
}
|
|
113
|
-
if (!queueFile) {
|
|
114
|
-
return { error: "Missing required option: --queue <tasks.md>" };
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
parsed: {
|
|
118
|
-
agentKey,
|
|
119
|
-
queueFile,
|
|
120
|
-
cwd,
|
|
121
|
-
maxRetries,
|
|
122
|
-
stallMinutes,
|
|
123
|
-
pollIntervalSec,
|
|
124
|
-
dodCommands: dodCommands.length > 0 ? dodCommands : void 0
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
function evaluateRunAcceptance(record, reportData) {
|
|
129
|
-
if (record.status !== "done") {
|
|
130
|
-
return {
|
|
131
|
-
passed: false,
|
|
132
|
-
reason: `Run ended with status "${record.status}" (exitCode: ${typeof record.exitCode === "number" ? record.exitCode : "-"})`
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
if (!record.dodCommands || record.dodCommands.length === 0) {
|
|
136
|
-
return {
|
|
137
|
-
passed: true,
|
|
138
|
-
reason: "Run completed successfully (no DoD commands specified)"
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
if (reportData?.reportJson?.dodResults && reportData.reportJson.dodResults.length > 0) {
|
|
142
|
-
const dodResults = reportData.reportJson.dodResults;
|
|
143
|
-
const failures = dodResults.filter((r) => r.exitCode !== 0);
|
|
144
|
-
if (failures.length > 0) {
|
|
145
|
-
const failedCmds = failures.map((f) => `"${f.command}" (exitCode: ${f.exitCode})`).join(", ");
|
|
146
|
-
return {
|
|
147
|
-
passed: false,
|
|
148
|
-
reason: `DoD verification failed: ${failedCmds}`,
|
|
149
|
-
dodResults
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
return {
|
|
153
|
-
passed: true,
|
|
154
|
-
reason: "All DoD commands passed successfully",
|
|
155
|
-
dodResults
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
if (reportData?.reportMarkdown) {
|
|
159
|
-
const parsed = parseDoDResultsFromMarkdown(reportData.reportMarkdown);
|
|
160
|
-
if (parsed.dodResults.length > 0) {
|
|
161
|
-
const failures = parsed.dodResults.filter((r) => r.exitCode !== 0);
|
|
162
|
-
if (failures.length > 0) {
|
|
163
|
-
const failedCmds = failures.map((f) => `"${f.command}" (exitCode: ${f.exitCode})`).join(", ");
|
|
164
|
-
return {
|
|
165
|
-
passed: false,
|
|
166
|
-
reason: `DoD verification failed: ${failedCmds}`
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
return {
|
|
170
|
-
passed: true,
|
|
171
|
-
reason: "All DoD commands passed successfully (parsed from report.md)"
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
passed: false,
|
|
177
|
-
reason: "DoD verification results not found in run report"
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
function evaluateRetryDecision(input) {
|
|
181
|
-
const retriesUsed = input.currentAttemptCount - 1;
|
|
182
|
-
if (retriesUsed < input.maxRetries) {
|
|
183
|
-
return {
|
|
184
|
-
shouldRetry: true,
|
|
185
|
-
nextAttemptNumber: input.currentAttemptCount + 1,
|
|
186
|
-
reason: `Attempt ${input.currentAttemptCount} failed (${input.failureReason}). Retrying (retry ${retriesUsed + 1}/${input.maxRetries})...`
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
return {
|
|
190
|
-
shouldRetry: false,
|
|
191
|
-
nextAttemptNumber: input.currentAttemptCount + 1,
|
|
192
|
-
reason: `Max retries (${input.maxRetries}) exceeded after ${input.currentAttemptCount} attempts. Marking as failed-supervisor. Reason: ${input.failureReason}`
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
function checkRunStall(input) {
|
|
196
|
-
const fileEdits = input.record.activity?.counters?.fileEdits ?? 0;
|
|
197
|
-
const toolCalls = input.record.activity?.counters?.toolCalls ?? 0;
|
|
198
|
-
const llmCalls = input.record.activity?.counters?.llmCalls ?? 0;
|
|
199
|
-
const currentCount = fileEdits + toolCalls + llmCalls;
|
|
200
|
-
let lastChangedAt = input.lastActivityChangedAt;
|
|
201
|
-
if (currentCount > input.lastActivityCount) {
|
|
202
|
-
lastChangedAt = input.nowMs;
|
|
203
|
-
}
|
|
204
|
-
const isLlmInFlight = input.record.activity?.inFlight?.kind === "llm";
|
|
205
|
-
if (isLlmInFlight) {
|
|
206
|
-
lastChangedAt = input.nowMs;
|
|
207
|
-
}
|
|
208
|
-
const stallMs = input.stallMinutes * 60 * 1e3;
|
|
209
|
-
const idleMs = input.nowMs - lastChangedAt;
|
|
210
|
-
const isStalled = input.record.status === "running" && !isLlmInFlight && idleMs >= stallMs;
|
|
211
|
-
return {
|
|
212
|
-
isStalled,
|
|
213
|
-
currentActivityCount: currentCount,
|
|
214
|
-
lastActivityChangedAt: lastChangedAt
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
function resolveSuperviseSummaryPath(env, homedir = nodeHomedir, options) {
|
|
218
|
-
if (typeof options === "string") {
|
|
219
|
-
return join(resolveRunsDir(env, homedir), `supervise-${options}.md`);
|
|
220
|
-
}
|
|
221
|
-
const ts = options?.timestamp || (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
222
|
-
const nonce = options?.nonce || Math.random().toString(36).slice(2, 8);
|
|
223
|
-
return join(resolveRunsDir(env, homedir), `supervise-${ts}-${nonce}.md`);
|
|
224
|
-
}
|
|
225
|
-
function renderSuperviseSummaryMarkdown(summary) {
|
|
226
|
-
const lines = [];
|
|
227
|
-
lines.push("# Nolo Agent Supervise \u4EFB\u52A1\u6C47\u603B\u62A5\u544A");
|
|
228
|
-
lines.push("");
|
|
229
|
-
lines.push("## \u6267\u884C\u6982\u89C8");
|
|
230
|
-
lines.push("");
|
|
231
|
-
lines.push("| \u914D\u7F6E / \u6307\u6807 | \u503C |");
|
|
232
|
-
lines.push("| --- | --- |");
|
|
233
|
-
lines.push(`| Agent | ${summary.agentKey} |`);
|
|
234
|
-
lines.push(`| \u5DE5\u4F5C\u76EE\u5F55 | ${summary.cwd} |`);
|
|
235
|
-
lines.push(`| \u5F00\u59CB\u65F6\u95F4 | ${summary.startedAt} |`);
|
|
236
|
-
lines.push(`| \u7ED3\u675F\u65F6\u95F4 | ${summary.endedAt} |`);
|
|
237
|
-
lines.push(`| \u6700\u5927\u91CD\u8BD5\u6570 | ${summary.maxRetries} |`);
|
|
238
|
-
lines.push(`| \u505C\u6EDE\u8D85\u65F6 (\u5206) | ${summary.stallMinutes} |`);
|
|
239
|
-
lines.push(`| \u8F6E\u8BE2\u95F4\u9694 (\u79D2) | ${summary.pollIntervalSec} |`);
|
|
240
|
-
lines.push(`| \u603B\u4EFB\u52A1\u6570 | ${summary.totalTasks} |`);
|
|
241
|
-
lines.push(`| \u5B8C\u6210\u4EFB\u52A1\u6570 | ${summary.completedTasks} |`);
|
|
242
|
-
lines.push(`| \u5931\u8D25\u4EFB\u52A1\u6570 | ${summary.failedTasks} |`);
|
|
243
|
-
if (summary.interruptedTasks > 0) {
|
|
244
|
-
lines.push(`| \u4E2D\u65AD\u4EFB\u52A1\u6570 | ${summary.interruptedTasks} |`);
|
|
245
|
-
}
|
|
246
|
-
lines.push("");
|
|
247
|
-
lines.push("## \u4EFB\u52A1\u660E\u7EC6");
|
|
248
|
-
lines.push("");
|
|
249
|
-
lines.push("| \u5E8F\u53F7 | \u4EFB\u52A1\u6807\u9898 | \u5C1D\u8BD5\u6B21\u6570 | \u6700\u7EC8\u72B6\u6001 | \u6700\u7EC8 Run ID | \u9A8C\u6536\u62A5\u544A |");
|
|
250
|
-
lines.push("| --- | --- | --- | --- | --- | --- |");
|
|
251
|
-
for (let i = 0; i < summary.tasks.length; i++) {
|
|
252
|
-
const t = summary.tasks[i];
|
|
253
|
-
const taskNum = i + 1;
|
|
254
|
-
const attemptsCount = t.attempts.length;
|
|
255
|
-
const finalRunId = t.finalRunId || (t.attempts[t.attempts.length - 1]?.runId ?? "-");
|
|
256
|
-
const lastAttempt = t.attempts[t.attempts.length - 1];
|
|
257
|
-
const reportLink = lastAttempt?.reportPath ? `\`${lastAttempt.reportPath}\`` : "-";
|
|
258
|
-
lines.push(
|
|
259
|
-
`| ${taskNum} | ${t.task.title.replace(/\|/g, "\\|")} | ${attemptsCount} | ${t.finalStatus} | ${finalRunId} | ${reportLink} |`
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
lines.push("");
|
|
263
|
-
lines.push("## Run \u5C1D\u8BD5\u8BE6\u60C5");
|
|
264
|
-
lines.push("");
|
|
265
|
-
for (const t of summary.tasks) {
|
|
266
|
-
lines.push(`### ${t.task.title}`);
|
|
267
|
-
lines.push(`- \u6700\u7EC8\u72B6\u6001: **${t.finalStatus}** (\u5171\u5C1D\u8BD5 ${t.attempts.length} \u6B21)`);
|
|
268
|
-
for (let i = 0; i < t.attempts.length; i++) {
|
|
269
|
-
const att = t.attempts[i];
|
|
270
|
-
const attemptNum = i + 1;
|
|
271
|
-
const statusNote = att.dodPassed === false ? "DoD\u672A\u901A\u8FC7" : att.status === "stalled" ? "\u505C\u6EDE\u6B62\u635F" : att.status;
|
|
272
|
-
lines.push(
|
|
273
|
-
` - \u5C1D\u8BD5 #${attemptNum}: Run ID \`${att.runId}\` \u2014 \u72B6\u6001: ${statusNote}${att.reportPath ? ` \u2014 [\u62A5\u544A: ${att.reportPath}]` : ""}${att.error ? ` (${att.error})` : ""}`
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
lines.push("");
|
|
277
|
-
}
|
|
278
|
-
lines.push("---");
|
|
279
|
-
lines.push(`_\u751F\u6210\u65F6\u95F4: ${summary.endedAt}_`);
|
|
280
|
-
lines.push("");
|
|
281
|
-
return lines.join("\n");
|
|
282
|
-
}
|
|
283
|
-
function renderSuperviseHelpText() {
|
|
284
|
-
return [
|
|
285
|
-
"Usage: nolo agent supervise --agent <agentId> --queue <tasks.md> [options]",
|
|
286
|
-
"",
|
|
287
|
-
"Supervise serial execution of a task queue with watchdog monitoring and retries.",
|
|
288
|
-
"",
|
|
289
|
-
"Options:",
|
|
290
|
-
" --agent, -a <agentId> Agent ID or key to run tasks with (required)",
|
|
291
|
-
" --queue, -q <tasks.md> Path to markdown queue file with ## task sections (required)",
|
|
292
|
-
" --cwd <dir> Working directory for task execution (default: current working dir)",
|
|
293
|
-
" --max-retries <number> Maximum retries per task upon failure or DoD rejection (default: 3)",
|
|
294
|
-
" --stall-minutes <number> Stop and retry task if no edit/tool/LLM activity within N minutes (default: 60)",
|
|
295
|
-
" --poll-interval <seconds> Polling interval in seconds (default: 60)",
|
|
296
|
-
" --dod <command> Definition of Done command to verify upon task completion (repeatable)",
|
|
297
|
-
" --help, -h Show this help and exit",
|
|
298
|
-
"",
|
|
299
|
-
"Queue format:",
|
|
300
|
-
" tasks.md should contain task briefs separated by H2 headings:",
|
|
301
|
-
" ## task: Task 1 title",
|
|
302
|
-
" Complete brief instructions for task 1...",
|
|
303
|
-
"",
|
|
304
|
-
" ## task: Task 2 title",
|
|
305
|
-
" Complete brief instructions for task 2..."
|
|
306
|
-
].join("\n");
|
|
307
|
-
}
|
|
308
|
-
async function runAgentSuperviseCommand(args, deps = {}) {
|
|
309
|
-
const output = deps.output ?? process.stdout;
|
|
310
|
-
const fs = deps.fs ?? nodeFs;
|
|
311
|
-
const env = deps.env ?? process.env;
|
|
312
|
-
const homedir = deps.homedir ?? nodeHomedir;
|
|
313
|
-
const now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
314
|
-
const sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
315
|
-
const spawnLocalRun = deps.spawnLocalRun ?? spawnLocalBackgroundRun;
|
|
316
|
-
const checkStale = deps.checkStale ?? checkStaleRun;
|
|
317
|
-
const terminateRun = deps.terminateRun ?? terminateRunProcess;
|
|
318
|
-
const readRecord = deps.readRecord ?? readRunRecord;
|
|
319
|
-
const parseResult = parseAgentSuperviseArgs(args);
|
|
320
|
-
if (parseResult.help) {
|
|
321
|
-
output.write(renderSuperviseHelpText() + "\n");
|
|
322
|
-
return 0;
|
|
323
|
-
}
|
|
324
|
-
if (parseResult.error || !parseResult.parsed) {
|
|
325
|
-
output.write(`[nolo] agent supervise error: ${parseResult.error || "invalid arguments"}
|
|
326
|
-
`);
|
|
327
|
-
output.write("Run `nolo agent supervise --help` for usage.\n");
|
|
328
|
-
return 1;
|
|
329
|
-
}
|
|
330
|
-
const { agentKey, queueFile, cwd: targetCwd, maxRetries, stallMinutes, pollIntervalSec, dodCommands } = parseResult.parsed;
|
|
331
|
-
const resolvedCwd = targetCwd ? isAbsolute(targetCwd) ? targetCwd : resolve(process.cwd(), targetCwd) : process.cwd();
|
|
332
|
-
const queueFilePath = isAbsolute(queueFile) ? queueFile : resolve(process.cwd(), queueFile);
|
|
333
|
-
let queueContent;
|
|
334
|
-
try {
|
|
335
|
-
queueContent = fs.readFileSync(queueFilePath, "utf8");
|
|
336
|
-
} catch (err) {
|
|
337
|
-
output.write(`[nolo] agent supervise error: Could not read queue file "${queueFilePath}": ${toErrorMessage(err)}
|
|
338
|
-
`);
|
|
339
|
-
return 1;
|
|
340
|
-
}
|
|
341
|
-
let tasks;
|
|
342
|
-
try {
|
|
343
|
-
tasks = parseTaskQueueMarkdown(queueContent);
|
|
344
|
-
} catch (err) {
|
|
345
|
-
output.write(`[nolo] agent supervise error: ${toErrorMessage(err)}
|
|
346
|
-
`);
|
|
347
|
-
return 1;
|
|
348
|
-
}
|
|
349
|
-
const startTime = now();
|
|
350
|
-
output.write(`[nolo] Starting agent supervise queue (${tasks.length} tasks) with agent "${agentKey}"
|
|
351
|
-
`);
|
|
352
|
-
output.write(`[nolo] CWD: ${resolvedCwd}, maxRetries: ${maxRetries}, stallMinutes: ${stallMinutes}, pollInterval: ${pollIntervalSec}s
|
|
353
|
-
`);
|
|
354
|
-
let isInterrupted = false;
|
|
355
|
-
const onSigint = () => {
|
|
356
|
-
if (isInterrupted) return;
|
|
357
|
-
isInterrupted = true;
|
|
358
|
-
output.write("\n[nolo] Interrupted (SIGINT). Stopping active supervisor run...\n");
|
|
359
|
-
};
|
|
360
|
-
const hasNativeProcess = typeof process !== "undefined" && typeof process.on === "function";
|
|
361
|
-
if (hasNativeProcess) {
|
|
362
|
-
process.on("SIGINT", onSigint);
|
|
363
|
-
}
|
|
364
|
-
const taskResults = [];
|
|
365
|
-
try {
|
|
366
|
-
for (let tIndex = 0; tIndex < tasks.length; tIndex++) {
|
|
367
|
-
if (isInterrupted || deps.abortSignal?.aborted) {
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
const task = tasks[tIndex];
|
|
371
|
-
output.write(`
|
|
372
|
-
[nolo] >>> [${tIndex + 1}/${tasks.length}] Starting task: "${task.title}"
|
|
373
|
-
`);
|
|
374
|
-
let attemptCount = 0;
|
|
375
|
-
const attempts = [];
|
|
376
|
-
let taskDone = false;
|
|
377
|
-
let finalStatus = "failed-supervisor";
|
|
378
|
-
let finalRunId;
|
|
379
|
-
while (!taskDone && !isInterrupted && !deps.abortSignal?.aborted) {
|
|
380
|
-
attemptCount += 1;
|
|
381
|
-
const attemptLabel = attemptCount === 1 ? "Initial run" : `Retry attempt #${attemptCount - 1}`;
|
|
382
|
-
output.write(`[nolo] [${task.title}] ${attemptLabel} spawning...
|
|
383
|
-
`);
|
|
384
|
-
let runId;
|
|
385
|
-
try {
|
|
386
|
-
const rawArgs = [
|
|
387
|
-
"--agent",
|
|
388
|
-
agentKey,
|
|
389
|
-
"--msg-file",
|
|
390
|
-
"PLACEHOLDER",
|
|
391
|
-
"--bg",
|
|
392
|
-
...resolvedCwd ? ["--cwd", resolvedCwd] : [],
|
|
393
|
-
...dodCommands ? dodCommands.flatMap((d) => ["--dod", d]) : []
|
|
394
|
-
];
|
|
395
|
-
const spawned = await spawnLocalRun(
|
|
396
|
-
{
|
|
397
|
-
rawArgs,
|
|
398
|
-
commandPath: ["agent", "run"],
|
|
399
|
-
cliEntrypointPath: deps.cliEntrypointPath,
|
|
400
|
-
agentKey,
|
|
401
|
-
cwd: resolvedCwd,
|
|
402
|
-
message: task.brief,
|
|
403
|
-
dodCommands,
|
|
404
|
-
output
|
|
405
|
-
},
|
|
406
|
-
deps
|
|
407
|
-
);
|
|
408
|
-
runId = spawned.runId;
|
|
409
|
-
finalRunId = runId;
|
|
410
|
-
output.write(`[nolo] [${task.title}] Run started: ${runId}${spawned.pid ? ` (pid: ${spawned.pid})` : ""}
|
|
411
|
-
`);
|
|
412
|
-
let record = readRecord(runId, deps);
|
|
413
|
-
let lastActivityCount = (record?.activity?.counters?.fileEdits ?? 0) + (record?.activity?.counters?.toolCalls ?? 0) + (record?.activity?.counters?.llmCalls ?? 0);
|
|
414
|
-
let lastActivityChangedAt = now().getTime();
|
|
415
|
-
while (!isInterrupted && !deps.abortSignal?.aborted) {
|
|
416
|
-
const pollMs = pollIntervalSec * 1e3;
|
|
417
|
-
await sleep(pollMs);
|
|
418
|
-
if (isInterrupted || deps.abortSignal?.aborted) {
|
|
419
|
-
break;
|
|
420
|
-
}
|
|
421
|
-
record = checkStale(runId, deps) ?? readRecord(runId, deps);
|
|
422
|
-
if (!record) {
|
|
423
|
-
output.write(`[nolo] [${task.title}] Run ${runId} record missing.
|
|
424
|
-
`);
|
|
425
|
-
break;
|
|
426
|
-
}
|
|
427
|
-
if (isRunTerminalStatus(record.status)) {
|
|
428
|
-
break;
|
|
429
|
-
}
|
|
430
|
-
const nowMs = now().getTime();
|
|
431
|
-
const stallCheck = checkRunStall({
|
|
432
|
-
record,
|
|
433
|
-
lastActivityCount,
|
|
434
|
-
lastActivityChangedAt,
|
|
435
|
-
nowMs,
|
|
436
|
-
stallMinutes
|
|
437
|
-
});
|
|
438
|
-
lastActivityCount = stallCheck.currentActivityCount;
|
|
439
|
-
lastActivityChangedAt = stallCheck.lastActivityChangedAt;
|
|
440
|
-
if (stallCheck.isStalled) {
|
|
441
|
-
output.write(
|
|
442
|
-
`[nolo] [${task.title}] Run ${runId} stalled (no activity for ${stallMinutes}m). Stopping run...
|
|
443
|
-
`
|
|
444
|
-
);
|
|
445
|
-
await terminateRun(record, "SIGTERM", deps);
|
|
446
|
-
finalizeRunRecord(
|
|
447
|
-
runId,
|
|
448
|
-
{ status: "killed", note: `stalled: no activity growth within ${stallMinutes}m` },
|
|
449
|
-
deps
|
|
450
|
-
);
|
|
451
|
-
record = readRecord(runId, deps) ?? { ...record, status: "killed" };
|
|
452
|
-
break;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
if (isInterrupted || deps.abortSignal?.aborted) {
|
|
456
|
-
if (record && !isRunTerminalStatus(record.status)) {
|
|
457
|
-
await terminateRun(record, "SIGTERM", deps);
|
|
458
|
-
finalizeRunRecord(runId, { status: "killed", note: "interrupted by SIGINT" }, deps);
|
|
459
|
-
record = readRecord(runId, deps) ?? { ...record, status: "killed" };
|
|
460
|
-
}
|
|
461
|
-
attempts.push({
|
|
462
|
-
runId,
|
|
463
|
-
startedAt: record?.startedAt ?? now().toISOString(),
|
|
464
|
-
endedAt: record?.endedAt ?? now().toISOString(),
|
|
465
|
-
status: "unknown",
|
|
466
|
-
error: "Interrupted by user"
|
|
467
|
-
});
|
|
468
|
-
finalStatus = "interrupted";
|
|
469
|
-
break;
|
|
470
|
-
}
|
|
471
|
-
const terminalRecord = record ?? {
|
|
472
|
-
runId,
|
|
473
|
-
agentKey,
|
|
474
|
-
startedAt: now().toISOString(),
|
|
475
|
-
status: "failed",
|
|
476
|
-
logPath: ""
|
|
477
|
-
};
|
|
478
|
-
const reportPath = resolveRunReportPath(runId, env, homedir);
|
|
479
|
-
const reportJsonPath = resolveRunReportJsonPath(runId, env, homedir);
|
|
480
|
-
let reportMarkdown;
|
|
481
|
-
let reportJson;
|
|
482
|
-
try {
|
|
483
|
-
if (fs.existsSync(reportJsonPath)) {
|
|
484
|
-
reportJson = JSON.parse(fs.readFileSync(reportJsonPath, "utf8"));
|
|
485
|
-
}
|
|
486
|
-
} catch {
|
|
487
|
-
}
|
|
488
|
-
try {
|
|
489
|
-
if (fs.existsSync(reportPath)) {
|
|
490
|
-
reportMarkdown = fs.readFileSync(reportPath, "utf8");
|
|
491
|
-
}
|
|
492
|
-
} catch {
|
|
493
|
-
}
|
|
494
|
-
if (!reportJson && !reportMarkdown) {
|
|
495
|
-
try {
|
|
496
|
-
const gen = await generateRunReport(terminalRecord, { env, homedir, fs, now, forceReport: true });
|
|
497
|
-
reportMarkdown = gen.markdown;
|
|
498
|
-
reportJson = gen.report;
|
|
499
|
-
} catch {
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
const acceptance = evaluateRunAcceptance(terminalRecord, { reportJson, reportMarkdown });
|
|
503
|
-
if (acceptance.passed) {
|
|
504
|
-
taskDone = true;
|
|
505
|
-
finalStatus = "done";
|
|
506
|
-
attempts.push({
|
|
507
|
-
runId,
|
|
508
|
-
startedAt: terminalRecord.startedAt,
|
|
509
|
-
endedAt: terminalRecord.endedAt ?? now().toISOString(),
|
|
510
|
-
status: terminalRecord.status,
|
|
511
|
-
exitCode: terminalRecord.exitCode,
|
|
512
|
-
reportPath: fs.existsSync(reportPath) ? reportPath : void 0,
|
|
513
|
-
reportJsonPath: fs.existsSync(reportJsonPath) ? reportJsonPath : void 0,
|
|
514
|
-
dodPassed: true
|
|
515
|
-
});
|
|
516
|
-
output.write(`[nolo] [${task.title}] PASSED (run ${runId})
|
|
517
|
-
`);
|
|
518
|
-
} else {
|
|
519
|
-
const isStalled = terminalRecord.note?.includes("stalled");
|
|
520
|
-
attempts.push({
|
|
521
|
-
runId,
|
|
522
|
-
startedAt: terminalRecord.startedAt,
|
|
523
|
-
endedAt: terminalRecord.endedAt ?? now().toISOString(),
|
|
524
|
-
status: isStalled ? "stalled" : terminalRecord.status,
|
|
525
|
-
exitCode: terminalRecord.exitCode,
|
|
526
|
-
reportPath: fs.existsSync(reportPath) ? reportPath : void 0,
|
|
527
|
-
reportJsonPath: fs.existsSync(reportJsonPath) ? reportJsonPath : void 0,
|
|
528
|
-
dodPassed: false,
|
|
529
|
-
error: acceptance.reason
|
|
530
|
-
});
|
|
531
|
-
output.write(`[nolo] [${task.title}] REJECTED: ${acceptance.reason}
|
|
532
|
-
`);
|
|
533
|
-
const decision = evaluateRetryDecision({
|
|
534
|
-
currentAttemptCount: attemptCount,
|
|
535
|
-
maxRetries,
|
|
536
|
-
failureReason: acceptance.reason || "run failed"
|
|
537
|
-
});
|
|
538
|
-
if (decision.shouldRetry) {
|
|
539
|
-
output.write(`[nolo] [${task.title}] ${decision.reason}
|
|
540
|
-
`);
|
|
541
|
-
} else {
|
|
542
|
-
output.write(`[nolo] [${task.title}] ${decision.reason}
|
|
543
|
-
`);
|
|
544
|
-
finalStatus = "failed-supervisor";
|
|
545
|
-
break;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
} catch (attemptErr) {
|
|
549
|
-
const errorMsg = `Attempt error: ${toErrorMessage(attemptErr)}`;
|
|
550
|
-
output.write(`[nolo] [${task.title}] ${errorMsg}
|
|
551
|
-
`);
|
|
552
|
-
attempts.push({
|
|
553
|
-
runId: runId || "unknown",
|
|
554
|
-
startedAt: now().toISOString(),
|
|
555
|
-
endedAt: now().toISOString(),
|
|
556
|
-
status: "failed",
|
|
557
|
-
error: errorMsg
|
|
558
|
-
});
|
|
559
|
-
const decision = evaluateRetryDecision({
|
|
560
|
-
currentAttemptCount: attemptCount,
|
|
561
|
-
maxRetries,
|
|
562
|
-
failureReason: errorMsg
|
|
563
|
-
});
|
|
564
|
-
if (decision.shouldRetry) {
|
|
565
|
-
output.write(`[nolo] [${task.title}] ${decision.reason}
|
|
566
|
-
`);
|
|
567
|
-
} else {
|
|
568
|
-
output.write(`[nolo] [${task.title}] ${decision.reason}
|
|
569
|
-
`);
|
|
570
|
-
finalStatus = "failed-supervisor";
|
|
571
|
-
break;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
taskResults.push({
|
|
576
|
-
task,
|
|
577
|
-
attempts,
|
|
578
|
-
retries: Math.max(0, attempts.length - 1),
|
|
579
|
-
finalStatus: isInterrupted ? "interrupted" : finalStatus,
|
|
580
|
-
finalRunId
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
} finally {
|
|
584
|
-
if (hasNativeProcess) {
|
|
585
|
-
process.off("SIGINT", onSigint);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
const endTime = now();
|
|
589
|
-
const completedTasks = taskResults.filter((t) => t.finalStatus === "done").length;
|
|
590
|
-
const failedTasks = taskResults.filter((t) => t.finalStatus === "failed-supervisor").length;
|
|
591
|
-
const interruptedTasks = taskResults.filter((t) => t.finalStatus === "interrupted").length;
|
|
592
|
-
const summaryFilePath = resolveSuperviseSummaryPath(env, homedir, {
|
|
593
|
-
timestamp: endTime.toISOString().replace(/[:.]/g, "-")
|
|
594
|
-
});
|
|
595
|
-
const summary = {
|
|
596
|
-
agentKey,
|
|
597
|
-
cwd: resolvedCwd,
|
|
598
|
-
startedAt: startTime.toISOString(),
|
|
599
|
-
endedAt: endTime.toISOString(),
|
|
600
|
-
maxRetries,
|
|
601
|
-
stallMinutes,
|
|
602
|
-
pollIntervalSec,
|
|
603
|
-
tasks: taskResults,
|
|
604
|
-
totalTasks: tasks.length,
|
|
605
|
-
completedTasks,
|
|
606
|
-
failedTasks,
|
|
607
|
-
interruptedTasks,
|
|
608
|
-
summaryFilePath
|
|
609
|
-
};
|
|
610
|
-
const summaryMarkdown = renderSuperviseSummaryMarkdown(summary);
|
|
611
|
-
try {
|
|
612
|
-
const runsDir = resolveRunsDir(env, homedir);
|
|
613
|
-
fs.mkdirSync(runsDir, { recursive: true });
|
|
614
|
-
fs.writeFileSync(summaryFilePath, summaryMarkdown, "utf8");
|
|
615
|
-
output.write(`
|
|
616
|
-
[nolo] Supervise summary written to: ${summaryFilePath}
|
|
617
|
-
|
|
618
|
-
`);
|
|
619
|
-
} catch (err) {
|
|
620
|
-
output.write(`[nolo] Warning: Could not write summary file to ${summaryFilePath}: ${toErrorMessage(err)}
|
|
621
|
-
|
|
622
|
-
`);
|
|
623
|
-
}
|
|
624
|
-
output.write(summaryMarkdown + "\n");
|
|
625
|
-
if (isInterrupted) {
|
|
626
|
-
return 130;
|
|
627
|
-
}
|
|
628
|
-
return completedTasks === tasks.length ? 0 : 1;
|
|
629
|
-
}
|
|
630
|
-
export {
|
|
631
|
-
checkRunStall,
|
|
632
|
-
evaluateRetryDecision,
|
|
633
|
-
evaluateRunAcceptance,
|
|
634
|
-
parseAgentSuperviseArgs,
|
|
635
|
-
parseTaskQueueMarkdown,
|
|
636
|
-
renderSuperviseHelpText,
|
|
637
|
-
renderSuperviseSummaryMarkdown,
|
|
638
|
-
resolveSuperviseSummaryPath,
|
|
639
|
-
runAgentSuperviseCommand
|
|
640
|
-
};
|
package/chunk-6IGD47IC.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// packages/agent-runtime/responseGuidelines.ts
|
|
2
|
-
var buildResponseGuidelines = (isMobile) => {
|
|
3
|
-
if (isMobile) {
|
|
4
|
-
return `--- \u54CD\u5E94\u5C55\u793A\u6307\u5357\uFF08\u7A84\u5C4F / TUI / \u79FB\u52A8\u7AEF\uFF09 ---
|
|
5
|
-
\u5F53\u524D\u5904\u4E8E\u7A84\u5C4F\u6216\u7EC8\u7AEF\u89C6\u56FE\uFF0C\u91C7\u7528\u7D27\u51D1\u3001\u9AD8\u626B\u63CF\u7387\u6392\u7248\uFF1A\u7ED3\u8BBA/\u5173\u952E\u72B6\u6001\u7F6E\u9876\uFF0C\u77ED\u6BB5\u843D\uFF082-4 \u53E5\uFF09\u5E76\u4FDD\u6301\u7A7A\u884C\uFF0C\u62D2\u7EDD\u6587\u5B57\u5899\u3002
|
|
6
|
-
- \u5217\u8868\u9879\u7528\u300C- **\u6838\u5FC3\u8BCD**\uFF1A\u8BF4\u660E\u300D\uFF1B\u5D4C\u5957\u6700\u591A 2 \u5C42\uFF0C\u5B50\u5217\u8868\u7F29\u8FDB 2 \u7A7A\u683C\uFF1B\u5E76\u5217\u7528\u65E0\u5E8F\u5217\u8868\uFF0C\u6B65\u9AA4\u7528\u6709\u5E8F\u5217\u8868\u3002
|
|
7
|
-
- **\u8868\u683C\u964D\u7EA7**\uFF1A\u4E25\u7981\u4F7F\u7528 \u22654 \u5217\u7684\u5927\u5BBD\u8868\uFF08\u7A84\u5C4F/\u7EC8\u7AEF\u6298\u884C\u4E25\u91CD\u9519\u4F4D\uFF09\uFF0C\u6539\u7528\u952E\u503C\u6E05\u5355\u6216\u7EB5\u5411\u5361\u7247\u3002
|
|
8
|
-
- \u514B\u5236\u5206\u5272\u7EBF\uFF08\u4EC5\u5927\u4E3B\u9898\u5207\u6362\u6216\u7ED3\u8BBA\u524D\uFF0C\u524D\u540E\u7559\u7A7A\u884C\uFF09\uFF1B\u8DEF\u5F84\u3001\u547D\u4EE4\u4E0E\u53C2\u6570\u7528\u53CD\u5F15\u53F7 \` \` \u5305\u88F9\uFF1B\u4EE3\u7801\u5757\u6807\u660E\u8BED\u8A00\u4E14\u907F\u514D\u6A2A\u5411\u8D85\u957F\u884C\uFF1B\u514B\u5236 Emoji\u3002`;
|
|
9
|
-
}
|
|
10
|
-
return `--- \u54CD\u5E94\u5C55\u793A\u6307\u5357\uFF08\u5BBD\u5C4F / \u684C\u9762\u7AEF\uFF09 ---
|
|
11
|
-
\u5F53\u524D\u5904\u4E8E\u5927\u5C4F\u89C6\u56FE\uFF1A\u5C42\u6B21\u6E05\u6670\u7684\u5168\u666F\u7ED3\u6784\uFF0C\u91CD\u8981\u6A21\u5757\u7528\u4E8C\u7EA7/\u4E09\u7EA7\u6807\u9898\u5212\u5206\uFF1B\u6BB5\u843D 2-4 \u53E5\u5E76\u7559\u7A7A\u884C\uFF0C\u76F4\u5954\u4E3B\u9898\u3002
|
|
12
|
-
- \u5217\u8868\u9879\u7528\u300C- **\u6838\u5FC3\u8BCD**\uFF1A\u8BF4\u660E\u300D\uFF1B\u5D4C\u5957\u6700\u591A 2 \u5C42\uFF0C\u5B50\u5217\u8868\u7F29\u8FDB 2 \u7A7A\u683C\uFF1B\u5E76\u5217\u7528\u65E0\u5E8F\u5217\u8868\uFF0C\u6B65\u9AA4\u7528\u6709\u5E8F\u5217\u8868\u3002
|
|
13
|
-
- **\u8868\u683C\u4E0E\u5BF9\u6BD4**\uFF1A\u5BBD\u5C4F\u4E0B\u53EF\u9002\u5EA6\u4F7F\u7528 Markdown \u591A\u5217\u8868\u683C\u505A\u65B9\u6848\u5BF9\u6BD4\u3001\u53C2\u6570\u6C47\u603B\u6216\u77E9\u9635\u5206\u6790\u3002
|
|
14
|
-
- \u53EF\u5C55\u793A\u66F4\u5B8C\u6574\u7684\u4EE3\u7801\u4E0A\u4E0B\u6587\u4E0E\u591A\u6B65\u6267\u884C\u793A\u4F8B\uFF1B\u8DEF\u5F84\u3001\u547D\u4EE4\u4E0E\u53C2\u6570\u7528\u53CD\u5F15\u53F7 \` \` \u5305\u88F9\uFF0C\u4EE3\u7801\u5757\u6807\u660E\u8BED\u8A00\uFF1B\u514B\u5236\u5206\u5272\u7EBF\u4E0E Emoji\u3002`;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export {
|
|
18
|
-
buildResponseGuidelines
|
|
19
|
-
};
|