nolo-cli 0.16.0-alpha.11 → 0.16.0-alpha.13
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-LGHYA5XS.js → _executeModel-Y43RS7DI.js} +10 -9
- package/{agentEmailCommands-KC2QCPQV.js → agentEmailCommands-AJFG5HBG.js} +10 -9
- package/{agentMachineCommands-P7S5WAVA.js → agentMachineCommands-2ACKQSTE.js} +1 -1
- package/{agentRecordCommands-JKZR2TZJ.js → agentRecordCommands-RQTFDKKJ.js} +10 -9
- package/{agentRunCommand-2ELKCBWR.js → agentRunCommand-FAHV33ML.js} +14 -10
- package/{agentRunControl-6ADXVYMR.js → agentRunControl-YVLQ4BW5.js} +24 -1
- package/{agentSlice-NXLMDKR7.js → agentSlice-XEQOAOC6.js} +1 -1
- package/{chunk-ZH62XNZE.js → chunk-6IZTYSJK.js} +641 -31
- package/{chunk-EQTZPEID.js → chunk-A3S7ITGN.js} +17 -40
- package/{chunk-HSASSW4L.js → chunk-BE3IKV5X.js} +5 -5
- package/{chunk-ZXQ52OY2.js → chunk-COIZN2AL.js} +3 -3
- package/{chunk-MYMMNKYL.js → chunk-E5CLOOG5.js} +153 -6
- package/{chunk-47QUPRHO.js → chunk-EPCM5E6C.js} +1 -1
- package/chunk-FKXFCYVO.js +221 -0
- package/{chunk-2WXMU64E.js → chunk-IQJOXIYF.js} +2 -2
- package/{chunk-4LXOVZ4W.js → chunk-KEPSRWXW.js} +8 -8
- package/{chunk-BXXECNBU.js → chunk-MDNZEE6B.js} +1 -1
- package/{chunk-22NGXGN3.js → chunk-N3IKEYV7.js} +1 -1
- package/{chunk-WBA6SIBB.js → chunk-PFAN32FJ.js} +1 -1
- package/{chunk-XEWUC53Z.js → chunk-QSJNZQFD.js} +4 -4
- package/{chunk-6CRACQXW.js → chunk-SPHXTAG6.js} +2 -2
- package/{chunk-D4NCEGGR.js → chunk-TSGUTKW2.js} +83 -233
- package/{createAgentAutomationAction-RKWIMKHW.js → createAgentAutomationAction-G5ZEEBMB.js} +2 -2
- package/{createDialogAction-VN7MEBS3.js → createDialogAction-3EJL6XK6.js} +3 -3
- package/{createPageAction-JBUWBHHC.js → createPageAction-FIUQXAI4.js} +2 -2
- package/{dialogSlice-NNYBU35K.js → dialogSlice-H24LGUPG.js} +2 -2
- package/{docStore-DR22GGF3.js → docStore-EFEUV2FP.js} +3 -3
- package/{handleSendMessageAction-FHITDM7H.js → handleSendMessageAction-PMKHJZGP.js} +2 -2
- package/index.js +20 -20
- package/{machineCommands-3B4IHHVK.js → machineCommands-U3N22344.js} +10 -9
- package/{machineWsRunDispatch-AXZ6OL3V.js → machineWsRunDispatch-BGYPVQPM.js} +10 -9
- package/package.json +1 -1
- package/{readlineWorkspace-DBZCXS7Y.js → readlineWorkspace-HWYYQ2KL.js} +18 -16
- package/{runAgentClientLoop-AB7PQ3TB.js → runAgentClientLoop-3NESZLYZ.js} +8 -7
- package/{spaceSlice-TEJDCU6A.js → spaceSlice-YBORJR2H.js} +2 -2
- package/{streamAgentChatTurn-NZ3HLAXS.js → streamAgentChatTurn-XAPKGQ6M.js} +10 -9
- package/{tools-M4USUF3R.js → tools-RXIDHJ2C.js} +6 -5
- package/{updateDialogTitleAction-SMPQVKWT.js → updateDialogTitleAction-S7AG3P44.js} +2 -2
|
@@ -16,10 +16,11 @@ import {
|
|
|
16
16
|
createCliLocalRuntimeAdapter,
|
|
17
17
|
getCliLocale,
|
|
18
18
|
isBuiltinNoloAgentRef,
|
|
19
|
+
isQuotaExhaustedError,
|
|
19
20
|
parseAgentRunEvent,
|
|
20
21
|
t,
|
|
21
22
|
toolLabel
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-6IZTYSJK.js";
|
|
23
24
|
import {
|
|
24
25
|
getReadableCliDb
|
|
25
26
|
} from "./chunk-W4NVOSFF.js";
|
|
@@ -39,16 +40,8 @@ import {
|
|
|
39
40
|
buildModelLayerOverride
|
|
40
41
|
} from "./chunk-LTRXGFMS.js";
|
|
41
42
|
import {
|
|
42
|
-
formatAgentListCard
|
|
43
|
-
|
|
44
|
-
formatListRunsCard,
|
|
45
|
-
formatNotFoundRunCard,
|
|
46
|
-
formatStartRunCard,
|
|
47
|
-
formatStatusRunCard,
|
|
48
|
-
formatStopRunCard,
|
|
49
|
-
isAgentRunTerminalStatus,
|
|
50
|
-
runShowsLogTail
|
|
51
|
-
} from "./chunk-D4NCEGGR.js";
|
|
43
|
+
formatAgentListCard
|
|
44
|
+
} from "./chunk-TSGUTKW2.js";
|
|
52
45
|
import {
|
|
53
46
|
isGatewayHttpStatus
|
|
54
47
|
} from "./chunk-RQSOAMPJ.js";
|
|
@@ -57,7 +50,7 @@ import {
|
|
|
57
50
|
chooseMemoryOwners,
|
|
58
51
|
loadMemoryCandidatesFromDb,
|
|
59
52
|
resolveAgentMemoryPolicy
|
|
60
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-MDNZEE6B.js";
|
|
61
54
|
import {
|
|
62
55
|
parseExternalSkillMarkdown,
|
|
63
56
|
parseSkillDocProtocol
|
|
@@ -66,7 +59,7 @@ import {
|
|
|
66
59
|
API_REPORTED_COST_MULTIPLIER,
|
|
67
60
|
normalizeUsage,
|
|
68
61
|
parseUiAskChoiceContent
|
|
69
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-KEPSRWXW.js";
|
|
70
63
|
import {
|
|
71
64
|
buildSkillDiscoveryContextBlock
|
|
72
65
|
} from "./chunk-AS3ZQ3O2.js";
|
|
@@ -113,7 +106,17 @@ import {
|
|
|
113
106
|
createRunActivityTracker,
|
|
114
107
|
finalizeRunRecord,
|
|
115
108
|
spawnLocalBackgroundRun
|
|
116
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-E5CLOOG5.js";
|
|
110
|
+
import {
|
|
111
|
+
formatFinishedRunCard,
|
|
112
|
+
formatListRunsCard,
|
|
113
|
+
formatNotFoundRunCard,
|
|
114
|
+
formatStartRunCard,
|
|
115
|
+
formatStatusRunCard,
|
|
116
|
+
formatStopRunCard,
|
|
117
|
+
isAgentRunTerminalStatus,
|
|
118
|
+
runShowsLogTail
|
|
119
|
+
} from "./chunk-FKXFCYVO.js";
|
|
117
120
|
import {
|
|
118
121
|
CliProviderQuotaError
|
|
119
122
|
} from "./chunk-CMKUBIGW.js";
|
|
@@ -5239,31 +5242,6 @@ ${mdContent}`);
|
|
|
5239
5242
|
}
|
|
5240
5243
|
return result.exitCode;
|
|
5241
5244
|
}
|
|
5242
|
-
var QUOTA_ERROR_PATTERNS = [
|
|
5243
|
-
/429/,
|
|
5244
|
-
/quota/i,
|
|
5245
|
-
/rate\s*limit/i,
|
|
5246
|
-
/too\s*many\s*requests/i,
|
|
5247
|
-
/额度/,
|
|
5248
|
-
/上限/,
|
|
5249
|
-
/用尽/,
|
|
5250
|
-
/CliProviderQuotaError/i
|
|
5251
|
-
];
|
|
5252
|
-
function isQuotaExhaustedError(error) {
|
|
5253
|
-
if (!error) return false;
|
|
5254
|
-
if (error instanceof CliProviderQuotaError) return true;
|
|
5255
|
-
if (error instanceof Error) {
|
|
5256
|
-
return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error.message));
|
|
5257
|
-
}
|
|
5258
|
-
if (typeof error === "string") {
|
|
5259
|
-
return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error));
|
|
5260
|
-
}
|
|
5261
|
-
const maybeStatus = error.status;
|
|
5262
|
-
if (typeof maybeStatus === "number" && maybeStatus === 429) return true;
|
|
5263
|
-
const maybeStatusCode = error.statusCode;
|
|
5264
|
-
if (typeof maybeStatusCode === "number" && maybeStatusCode === 429) return true;
|
|
5265
|
-
return false;
|
|
5266
|
-
}
|
|
5267
5245
|
var BALANCE_ERROR_PATTERNS = [
|
|
5268
5246
|
/UPSTREAM_402/i,
|
|
5269
5247
|
/Insufficient Balance/i,
|
|
@@ -5332,6 +5310,5 @@ export {
|
|
|
5332
5310
|
normalizeCliImageInput,
|
|
5333
5311
|
inspectLocalRunWorkspace,
|
|
5334
5312
|
runAgentRunCommand,
|
|
5335
|
-
isQuotaExhaustedError,
|
|
5336
5313
|
isBalanceExhaustedError
|
|
5337
5314
|
};
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
inlineImageUrlsForCustomProvider,
|
|
6
6
|
prepareTools,
|
|
7
7
|
shouldInlineImageUrlsForAgent
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-EPCM5E6C.js";
|
|
9
9
|
import {
|
|
10
10
|
performFetchRequest
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QSJNZQFD.js";
|
|
12
12
|
import {
|
|
13
13
|
createSSEParser,
|
|
14
14
|
createToolRunId,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
toolRunSetPending,
|
|
20
20
|
toolRunStarted,
|
|
21
21
|
toolRunSucceeded
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-TSGUTKW2.js";
|
|
23
23
|
import {
|
|
24
24
|
getPublicImageAgentMode
|
|
25
25
|
} from "./chunk-VIDPVFP3.js";
|
|
@@ -29,10 +29,10 @@ import {
|
|
|
29
29
|
messageStreaming,
|
|
30
30
|
selectCurrentSpaceId,
|
|
31
31
|
updateToolMessage
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-KEPSRWXW.js";
|
|
33
33
|
import {
|
|
34
34
|
streamAgentChatTurn
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-COIZN2AL.js";
|
|
36
36
|
import {
|
|
37
37
|
EMPTY_ASSISTANT_REPAIR_PROMPT
|
|
38
38
|
} from "./chunk-RIF3XLXK.js";
|
|
@@ -300,7 +300,7 @@ var slice = createSliceWithThunks({
|
|
|
300
300
|
const overrides = {};
|
|
301
301
|
if (args.systemPromptOverride !== void 0) overrides.prompt = args.systemPromptOverride;
|
|
302
302
|
if (args.toolsOverride !== void 0) overrides.tools = args.toolsOverride;
|
|
303
|
-
const { _executeModel } = await import("./_executeModel-
|
|
303
|
+
const { _executeModel } = await import("./_executeModel-Y43RS7DI.js");
|
|
304
304
|
return _executeModel(
|
|
305
305
|
{
|
|
306
306
|
isStreaming: args.isStreaming ?? false,
|
|
@@ -321,7 +321,7 @@ var slice = createSliceWithThunks({
|
|
|
321
321
|
* - 循环直到无工具调用或触发其他运行时停止条件
|
|
322
322
|
*/
|
|
323
323
|
runAgent: create.asyncThunk(async (args, thunkApi) => {
|
|
324
|
-
const { runAgentClientLoop } = await import("./runAgentClientLoop-
|
|
324
|
+
const { runAgentClientLoop } = await import("./runAgentClientLoop-3NESZLYZ.js");
|
|
325
325
|
const { content: loopContent, toolCallCount } = await runAgentClientLoop(
|
|
326
326
|
{
|
|
327
327
|
agentKey: args.agentKey,
|
|
@@ -337,7 +337,7 @@ var slice = createSliceWithThunks({
|
|
|
337
337
|
* 聊天轮次流式 Agent 调用
|
|
338
338
|
*/
|
|
339
339
|
streamAgentChatTurn: create.asyncThunk(async (args, thunkApi) => {
|
|
340
|
-
const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-
|
|
340
|
+
const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-XAPKGQ6M.js");
|
|
341
341
|
return streamAgentChatTurnHandler(args, thunkApi);
|
|
342
342
|
}),
|
|
343
343
|
/**
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isAgentRunTerminalStatus
|
|
3
|
+
} from "./chunk-FKXFCYVO.js";
|
|
1
4
|
import {
|
|
2
5
|
isCompiledBinary,
|
|
3
6
|
resolveCliEntrypointPath
|
|
@@ -7,7 +10,17 @@ import {
|
|
|
7
10
|
import { homedir as nodeHomedir } from "node:os";
|
|
8
11
|
import { isAbsolute, join, resolve } from "node:path";
|
|
9
12
|
import * as nodeFs from "node:fs";
|
|
10
|
-
import { spawn as nodeSpawn } from "node:child_process";
|
|
13
|
+
import { execFileSync as nodeExecFileSync, spawn as nodeSpawn } from "node:child_process";
|
|
14
|
+
var RUN_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
15
|
+
"done",
|
|
16
|
+
"failed",
|
|
17
|
+
"timeout",
|
|
18
|
+
"killed",
|
|
19
|
+
"orphaned"
|
|
20
|
+
]);
|
|
21
|
+
function isRunTerminalStatus(status) {
|
|
22
|
+
return isAgentRunTerminalStatus(status);
|
|
23
|
+
}
|
|
11
24
|
function resolveNoloHome(env, homedir = nodeHomedir) {
|
|
12
25
|
const fromEnv = env?.NOLO_HOME;
|
|
13
26
|
if (typeof fromEnv === "string" && fromEnv.length > 0) return fromEnv;
|
|
@@ -27,6 +40,11 @@ function defaultGenerateRunId() {
|
|
|
27
40
|
const random = Math.random().toString(36).slice(2, 8);
|
|
28
41
|
return `run-${timestamp}-${random}`;
|
|
29
42
|
}
|
|
43
|
+
function defaultGenerateBatchId() {
|
|
44
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
45
|
+
const random = Math.random().toString(36).slice(2, 8);
|
|
46
|
+
return `batch-${timestamp}-${random}`;
|
|
47
|
+
}
|
|
30
48
|
function writeRunRecord(record, deps = {}) {
|
|
31
49
|
const fs = deps.fs ?? nodeFs;
|
|
32
50
|
const path = resolveRunRecordPath(record.runId, deps.env, deps.homedir);
|
|
@@ -149,6 +167,87 @@ function findRunRecord(target, deps = {}) {
|
|
|
149
167
|
}
|
|
150
168
|
return readRunRecord(target, deps) ?? void 0;
|
|
151
169
|
}
|
|
170
|
+
var DEFAULT_LIST_LIMIT = 20;
|
|
171
|
+
var MAX_LIST_LIMIT = 200;
|
|
172
|
+
function parseStatusFilter(status) {
|
|
173
|
+
if (typeof status !== "string" || status.trim() === "" || status === "all") {
|
|
174
|
+
return void 0;
|
|
175
|
+
}
|
|
176
|
+
const parts = status.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
177
|
+
return parts.length > 0 ? new Set(parts) : void 0;
|
|
178
|
+
}
|
|
179
|
+
function clampLimit(limit) {
|
|
180
|
+
if (typeof limit !== "number" || !Number.isFinite(limit) || limit <= 0) {
|
|
181
|
+
return DEFAULT_LIST_LIMIT;
|
|
182
|
+
}
|
|
183
|
+
const floored = Math.floor(limit);
|
|
184
|
+
if (floored > MAX_LIST_LIMIT) return MAX_LIST_LIMIT;
|
|
185
|
+
if (floored < 1) return 1;
|
|
186
|
+
return floored;
|
|
187
|
+
}
|
|
188
|
+
function queryRunRecords(query, deps = {}) {
|
|
189
|
+
let records = listRunRecords(deps);
|
|
190
|
+
records = records.map(
|
|
191
|
+
(record) => record.status === "running" ? checkStaleRun(record.runId, deps) ?? record : record
|
|
192
|
+
);
|
|
193
|
+
const statusSet = parseStatusFilter(query.status);
|
|
194
|
+
const batchId = typeof query.batchId === "string" && query.batchId.trim() !== "" ? query.batchId.trim() : void 0;
|
|
195
|
+
let filtered = records.filter((record) => {
|
|
196
|
+
if (batchId && record.batchId !== batchId) return false;
|
|
197
|
+
if (statusSet && !statusSet.has(record.status)) return false;
|
|
198
|
+
return true;
|
|
199
|
+
});
|
|
200
|
+
const total = filtered.length;
|
|
201
|
+
const limit = clampLimit(query.limit);
|
|
202
|
+
const offset = typeof query.offset === "number" && Number.isFinite(query.offset) && query.offset > 0 ? Math.floor(query.offset) : 0;
|
|
203
|
+
const sliced = filtered.slice(offset, offset + limit);
|
|
204
|
+
const hasMore = offset + sliced.length < total;
|
|
205
|
+
return { runs: sliced, total, hasMore };
|
|
206
|
+
}
|
|
207
|
+
var DEFAULT_GC_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
208
|
+
function tryUnlinkFile(fs, path) {
|
|
209
|
+
if (typeof path !== "string" || path.length === 0) return true;
|
|
210
|
+
try {
|
|
211
|
+
if (fs.existsSync(path)) {
|
|
212
|
+
fs.unlinkSync(path);
|
|
213
|
+
}
|
|
214
|
+
return true;
|
|
215
|
+
} catch (error) {
|
|
216
|
+
const code = error.code;
|
|
217
|
+
return code === "ENOENT";
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function gcRunRecords(deps = {}, options = {}) {
|
|
221
|
+
const fs = deps.fs ?? nodeFs;
|
|
222
|
+
const now = (deps.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
223
|
+
const nowMs = now instanceof Date ? now.getTime() : Date.parse(String(now));
|
|
224
|
+
const retentionMs = typeof options.retentionMs === "number" && options.retentionMs >= 0 ? options.retentionMs : DEFAULT_GC_RETENTION_MS;
|
|
225
|
+
const records = listRunRecords(deps);
|
|
226
|
+
const sweptIds = [];
|
|
227
|
+
const failedIds = [];
|
|
228
|
+
for (const record of records) {
|
|
229
|
+
if (!isRunTerminalStatus(record.status)) continue;
|
|
230
|
+
const ts = record.reconciledAt ?? record.endedAt ?? record.startedAt;
|
|
231
|
+
const ageMs = nowMs - new Date(ts).getTime();
|
|
232
|
+
if (!Number.isFinite(ageMs) || ageMs < retentionMs) continue;
|
|
233
|
+
const jsonPath = resolveRunRecordPath(record.runId, deps.env, deps.homedir);
|
|
234
|
+
const logPath = resolveRunLogPath(record.runId, deps.env, deps.homedir);
|
|
235
|
+
const msgPath = record.msgFile ?? join(resolveRunsDir(deps.env, deps.homedir), `${record.runId}.msg.md`);
|
|
236
|
+
const logOk = tryUnlinkFile(fs, logPath);
|
|
237
|
+
const msgOk = tryUnlinkFile(fs, msgPath);
|
|
238
|
+
if (!logOk || !msgOk) {
|
|
239
|
+
failedIds.push(record.runId);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const jsonOk = tryUnlinkFile(fs, jsonPath);
|
|
243
|
+
if (jsonOk) {
|
|
244
|
+
sweptIds.push(record.runId);
|
|
245
|
+
} else {
|
|
246
|
+
failedIds.push(record.runId);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { swept: sweptIds.length, sweptIds, failedIds };
|
|
250
|
+
}
|
|
152
251
|
function stripBackgroundFlag(args) {
|
|
153
252
|
const result = [];
|
|
154
253
|
for (const arg of args) {
|
|
@@ -219,6 +318,7 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
|
|
|
219
318
|
const generateRunId = deps.generateRunId ?? defaultGenerateRunId;
|
|
220
319
|
const now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
221
320
|
const runId = generateRunId();
|
|
321
|
+
const batchId = input.batchId ?? (deps.generateBatchId ?? defaultGenerateBatchId)();
|
|
222
322
|
const logPath = resolveRunLogPath(runId, env, homedir);
|
|
223
323
|
const recordPath = resolveRunRecordPath(runId, env, homedir);
|
|
224
324
|
const runsDir = resolveRunsDir(env, homedir);
|
|
@@ -237,7 +337,8 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
|
|
|
237
337
|
startedAt: now().toISOString(),
|
|
238
338
|
...typeof input.timeoutMs === "number" ? { timeoutMs: input.timeoutMs } : {},
|
|
239
339
|
status: "running",
|
|
240
|
-
logPath
|
|
340
|
+
logPath,
|
|
341
|
+
batchId
|
|
241
342
|
};
|
|
242
343
|
fs.writeFileSync(recordPath, JSON.stringify(record, null, 2));
|
|
243
344
|
const { execPath, childArgs } = buildAgentRunChildCommand({
|
|
@@ -261,9 +362,11 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
|
|
|
261
362
|
proc.unref();
|
|
262
363
|
if (typeof proc.pid === "number") {
|
|
263
364
|
record.pid = proc.pid;
|
|
365
|
+
const processStartedAt = (deps.getProcessStartTime ?? defaultGetProcessStartTime)(proc.pid);
|
|
366
|
+
if (processStartedAt) record.processStartedAt = processStartedAt.toISOString();
|
|
264
367
|
fs.writeFileSync(recordPath, JSON.stringify(record, null, 2));
|
|
265
368
|
}
|
|
266
|
-
return { runId, pid: proc.pid, logPath };
|
|
369
|
+
return { runId, pid: proc.pid, logPath, batchId };
|
|
267
370
|
}
|
|
268
371
|
function finalizeRunRecord(runId, update, deps = {}) {
|
|
269
372
|
const record = readRunRecord(runId, deps);
|
|
@@ -285,16 +388,49 @@ function isPidGone(pid, deps = {}) {
|
|
|
285
388
|
return code === "ESRCH";
|
|
286
389
|
}
|
|
287
390
|
}
|
|
391
|
+
function defaultGetProcessStartTime(pid) {
|
|
392
|
+
try {
|
|
393
|
+
const output = nodeExecFileSync("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
394
|
+
encoding: "utf8",
|
|
395
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
396
|
+
timeout: 1e3
|
|
397
|
+
}).trim();
|
|
398
|
+
if (!output) return null;
|
|
399
|
+
const d = new Date(output);
|
|
400
|
+
return isNaN(d.getTime()) ? null : d;
|
|
401
|
+
} catch {
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
var MAX_PROCESS_START_TIME_DIFF_MS = 3e4;
|
|
406
|
+
var MAX_PERSISTED_PROCESS_START_TIME_DIFF_MS = 1e3;
|
|
407
|
+
function isPidReused(pid, expectedStartedAt, deps = {}, maxDiffMs = MAX_PROCESS_START_TIME_DIFF_MS) {
|
|
408
|
+
const getStartTime = deps.getProcessStartTime ?? defaultGetProcessStartTime;
|
|
409
|
+
const procStartTime = getStartTime(pid);
|
|
410
|
+
if (!procStartTime) {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
const recordTime = new Date(expectedStartedAt).getTime();
|
|
414
|
+
if (isNaN(recordTime)) return false;
|
|
415
|
+
const diffMs = Math.abs(procStartTime.getTime() - recordTime);
|
|
416
|
+
return diffMs > maxDiffMs;
|
|
417
|
+
}
|
|
288
418
|
function checkStaleRun(runId, deps = {}) {
|
|
289
419
|
const record = readRunRecord(runId, deps);
|
|
290
420
|
if (!record) return null;
|
|
291
421
|
if (record.status !== "running") return record;
|
|
292
422
|
if (typeof record.pid !== "number") return record;
|
|
293
|
-
|
|
423
|
+
const pidGone = isPidGone(record.pid, deps);
|
|
424
|
+
const expectedStartedAt = record.processStartedAt ?? record.startedAt;
|
|
425
|
+
const maxStartTimeDiffMs = record.processStartedAt ? MAX_PERSISTED_PROCESS_START_TIME_DIFF_MS : MAX_PROCESS_START_TIME_DIFF_MS;
|
|
426
|
+
const pidReused = !pidGone && isPidReused(record.pid, expectedStartedAt, deps, maxStartTimeDiffMs);
|
|
427
|
+
if (!pidGone && !pidReused) return record;
|
|
294
428
|
const now = deps.now ?? (() => /* @__PURE__ */ new Date());
|
|
295
|
-
record.status = "
|
|
296
|
-
record.note = "process gone
|
|
429
|
+
record.status = "orphaned";
|
|
430
|
+
record.note = pidReused ? "orphaned: process gone (pid reused by another process)" : "orphaned: process gone without writing terminal status";
|
|
297
431
|
record.endedAt = now().toISOString();
|
|
432
|
+
record.reconciledAt = now().toISOString();
|
|
433
|
+
record.pid = void 0;
|
|
298
434
|
writeRunRecord(record, deps);
|
|
299
435
|
return record;
|
|
300
436
|
}
|
|
@@ -650,23 +786,34 @@ async function runAgentKillCommand(args, deps) {
|
|
|
650
786
|
}
|
|
651
787
|
|
|
652
788
|
export {
|
|
789
|
+
RUN_TERMINAL_STATUSES,
|
|
790
|
+
isRunTerminalStatus,
|
|
653
791
|
resolveNoloHome,
|
|
654
792
|
resolveRunsDir,
|
|
655
793
|
resolveRunRecordPath,
|
|
656
794
|
resolveRunLogPath,
|
|
657
795
|
defaultGenerateRunId,
|
|
796
|
+
defaultGenerateBatchId,
|
|
658
797
|
writeRunRecord,
|
|
659
798
|
createRunActivityTracker,
|
|
660
799
|
readRunRecord,
|
|
661
800
|
listRunRecords,
|
|
662
801
|
findRunRecordByPid,
|
|
663
802
|
findRunRecord,
|
|
803
|
+
DEFAULT_LIST_LIMIT,
|
|
804
|
+
MAX_LIST_LIMIT,
|
|
805
|
+
queryRunRecords,
|
|
806
|
+
DEFAULT_GC_RETENTION_MS,
|
|
807
|
+
gcRunRecords,
|
|
664
808
|
stripBackgroundFlag,
|
|
665
809
|
absolutizeSkillArgs,
|
|
666
810
|
rewriteMsgFileArg,
|
|
667
811
|
spawnLocalBackgroundRun,
|
|
668
812
|
finalizeRunRecord,
|
|
669
813
|
isPidGone,
|
|
814
|
+
defaultGetProcessStartTime,
|
|
815
|
+
MAX_PROCESS_START_TIME_DIFF_MS,
|
|
816
|
+
isPidReused,
|
|
670
817
|
checkStaleRun,
|
|
671
818
|
runAgentPsCommand,
|
|
672
819
|
runAgentStatusCommand,
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// packages/ai/tools/agent/agentRunDisplayHelpers.ts
|
|
2
|
+
function getAgentRunStatusIcon(status) {
|
|
3
|
+
switch (status) {
|
|
4
|
+
case "running":
|
|
5
|
+
case "pending":
|
|
6
|
+
return "\u23F3";
|
|
7
|
+
case "done":
|
|
8
|
+
return "\u2713";
|
|
9
|
+
case "failed":
|
|
10
|
+
case "timeout":
|
|
11
|
+
return "\u2717";
|
|
12
|
+
case "killed":
|
|
13
|
+
case "cancelled":
|
|
14
|
+
case "cancelling":
|
|
15
|
+
return "\u{1F6D1}";
|
|
16
|
+
case "orphaned":
|
|
17
|
+
return "\u{1F47B}";
|
|
18
|
+
case "not_found":
|
|
19
|
+
default:
|
|
20
|
+
return "?";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
var DEFAULT_LABELS = {
|
|
24
|
+
runStatus: "Run status",
|
|
25
|
+
runStarted: "Run started",
|
|
26
|
+
runStopped: "Run stopped",
|
|
27
|
+
runFinished: "Run finished",
|
|
28
|
+
logTail: "Log tail:",
|
|
29
|
+
runs: (count) => `Runs (${count})`
|
|
30
|
+
};
|
|
31
|
+
function resolveLabels(labels) {
|
|
32
|
+
return {
|
|
33
|
+
runStatus: labels?.runStatus ?? DEFAULT_LABELS.runStatus,
|
|
34
|
+
runStarted: labels?.runStarted ?? DEFAULT_LABELS.runStarted,
|
|
35
|
+
runStopped: labels?.runStopped ?? DEFAULT_LABELS.runStopped,
|
|
36
|
+
runFinished: labels?.runFinished ?? DEFAULT_LABELS.runFinished,
|
|
37
|
+
logTail: labels?.logTail ?? DEFAULT_LABELS.logTail,
|
|
38
|
+
runs: labels?.runs ?? DEFAULT_LABELS.runs
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function shortRunId(runId) {
|
|
42
|
+
const trimmed = typeof runId === "string" ? runId.trim() : "";
|
|
43
|
+
if (!trimmed) return "";
|
|
44
|
+
const segments = trimmed.split("-").filter(Boolean);
|
|
45
|
+
let pick = segments[segments.length - 1] ?? trimmed;
|
|
46
|
+
if (pick.length < 4 && segments.length >= 2) pick = segments.slice(-2).join("-");
|
|
47
|
+
if (!pick) pick = trimmed;
|
|
48
|
+
return pick.length > 8 ? pick.slice(-8) : pick;
|
|
49
|
+
}
|
|
50
|
+
function clipText(text, max) {
|
|
51
|
+
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
52
|
+
return collapsed.length > max ? `${collapsed.slice(0, max - 1)}\u2026` : collapsed;
|
|
53
|
+
}
|
|
54
|
+
function formatDuration(ms) {
|
|
55
|
+
const totalSec = Math.max(0, Math.floor(ms / 1e3));
|
|
56
|
+
if (totalSec < 60) return `${totalSec}s`;
|
|
57
|
+
const totalMin = Math.floor(totalSec / 60);
|
|
58
|
+
if (totalMin < 60) return `${totalMin}m${String(totalSec % 60).padStart(2, "0")}s`;
|
|
59
|
+
return `${Math.floor(totalMin / 60)}h${String(totalMin % 60).padStart(2, "0")}m`;
|
|
60
|
+
}
|
|
61
|
+
function formatRunAge(timing, now = Date.now()) {
|
|
62
|
+
const startedAt = timing?.startedAt;
|
|
63
|
+
if (typeof startedAt !== "number" || !Number.isFinite(startedAt) || startedAt <= 0) {
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
const end = typeof timing?.finishedAt === "number" && Number.isFinite(timing.finishedAt) && timing.finishedAt > 0 ? timing.finishedAt : now;
|
|
67
|
+
return formatDuration(end - startedAt);
|
|
68
|
+
}
|
|
69
|
+
function formatIdentityRow(agentName, runId) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
if (!isAgentNameFallback(agentName)) parts.push(agentName);
|
|
72
|
+
const short = shortRunId(runId);
|
|
73
|
+
if (short) parts.push(`#${short}`);
|
|
74
|
+
return parts.join(" ");
|
|
75
|
+
}
|
|
76
|
+
function isAgentNameFallback(agentName) {
|
|
77
|
+
const trimmed = typeof agentName === "string" ? agentName.trim() : "";
|
|
78
|
+
return !trimmed || trimmed === "agent";
|
|
79
|
+
}
|
|
80
|
+
function resolveRunLabel(run) {
|
|
81
|
+
for (const candidate of [run.agentName, run.name, run.agentKey, run.runId]) {
|
|
82
|
+
if (typeof candidate === "string" && !isAgentNameFallback(candidate)) {
|
|
83
|
+
return candidate.trim();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return "agent";
|
|
87
|
+
}
|
|
88
|
+
function formatStartRunCard(agentName, status = "running", opts) {
|
|
89
|
+
const L = resolveLabels(opts?.labels);
|
|
90
|
+
const icon = getAgentRunStatusIcon(status);
|
|
91
|
+
const lines = [L.runStarted];
|
|
92
|
+
const identity = formatIdentityRow(agentName, opts?.runId);
|
|
93
|
+
if (identity) {
|
|
94
|
+
lines.push(` agent ${identity}`);
|
|
95
|
+
}
|
|
96
|
+
lines.push(` status ${icon} ${status}`);
|
|
97
|
+
const task = opts?.task?.trim();
|
|
98
|
+
if (task) {
|
|
99
|
+
lines.push(` task ${clipText(task, TASK_PREVIEW_MAX)}`);
|
|
100
|
+
}
|
|
101
|
+
return lines.join("\n");
|
|
102
|
+
}
|
|
103
|
+
var TASK_PREVIEW_MAX = 72;
|
|
104
|
+
var NOTE_PREVIEW_MAX = 72;
|
|
105
|
+
function formatProgressRow(toolCallCount, lastToolNames) {
|
|
106
|
+
const parts = [];
|
|
107
|
+
if (typeof toolCallCount === "number" && Number.isFinite(toolCallCount)) {
|
|
108
|
+
parts.push(`${toolCallCount} tools`);
|
|
109
|
+
}
|
|
110
|
+
if (lastToolNames && lastToolNames.length > 0) {
|
|
111
|
+
parts.push(lastToolNames.join(", "));
|
|
112
|
+
}
|
|
113
|
+
return parts.join(" \xB7 ");
|
|
114
|
+
}
|
|
115
|
+
function formatStatusRunCard(agentName, status = "running", opts) {
|
|
116
|
+
const L = resolveLabels(opts?.labels);
|
|
117
|
+
const icon = getAgentRunStatusIcon(status);
|
|
118
|
+
const age = formatRunAge(opts?.timing, opts?.now);
|
|
119
|
+
const lines = [L.runStatus, ` ${icon} ${status}${age ? ` ${age}` : ""}`];
|
|
120
|
+
const identity = formatIdentityRow(agentName, opts?.runId);
|
|
121
|
+
if (identity) {
|
|
122
|
+
lines.push(` agent ${identity}`);
|
|
123
|
+
}
|
|
124
|
+
const progress = formatProgressRow(opts?.toolCallCount, opts?.lastToolNames);
|
|
125
|
+
if (progress) {
|
|
126
|
+
lines.push(` tools ${progress}`);
|
|
127
|
+
}
|
|
128
|
+
const note = opts?.lastAssistantText?.trim();
|
|
129
|
+
if (note) {
|
|
130
|
+
lines.push(` note ${clipText(note, NOTE_PREVIEW_MAX)}`);
|
|
131
|
+
}
|
|
132
|
+
if (opts?.errorMessage?.trim()) {
|
|
133
|
+
lines.push(` error ${opts.errorMessage.trim()}`);
|
|
134
|
+
}
|
|
135
|
+
if (shouldShowLogTail(status, opts?.includeLogTail, opts?.logLines)) {
|
|
136
|
+
lines.push("", L.logTail, ...opts.logLines.map((l) => ` ${l}`));
|
|
137
|
+
}
|
|
138
|
+
return lines.join("\n");
|
|
139
|
+
}
|
|
140
|
+
function runShowsLogTail(status) {
|
|
141
|
+
return status === "failed" || status === "timeout";
|
|
142
|
+
}
|
|
143
|
+
function shouldShowLogTail(status, includeLogTail, logLines) {
|
|
144
|
+
if (includeLogTail === false) return false;
|
|
145
|
+
if (!logLines || logLines.length === 0) return false;
|
|
146
|
+
return runShowsLogTail(status);
|
|
147
|
+
}
|
|
148
|
+
function formatFinishedRunCard(agentName, status, opts) {
|
|
149
|
+
const L = resolveLabels(opts?.labels);
|
|
150
|
+
const icon = getAgentRunStatusIcon(status);
|
|
151
|
+
const age = formatRunAge(opts?.timing, opts?.now);
|
|
152
|
+
const summary = [status, age, formatProgressRow(opts?.toolCallCount, opts?.lastToolNames)].filter(Boolean).join(" \xB7 ");
|
|
153
|
+
const lines = [L.runFinished, ` ${icon} ${summary}`];
|
|
154
|
+
const identity = formatIdentityRow(agentName, opts?.runId);
|
|
155
|
+
if (identity) {
|
|
156
|
+
lines.push(` agent ${identity}`);
|
|
157
|
+
}
|
|
158
|
+
const note = opts?.lastAssistantText?.trim();
|
|
159
|
+
if (note) {
|
|
160
|
+
lines.push(` note ${clipText(note, NOTE_PREVIEW_MAX)}`);
|
|
161
|
+
}
|
|
162
|
+
if (opts?.errorMessage?.trim()) {
|
|
163
|
+
lines.push(` error ${opts.errorMessage.trim()}`);
|
|
164
|
+
}
|
|
165
|
+
if (shouldShowLogTail(status, opts?.includeLogTail, opts?.logLines)) {
|
|
166
|
+
lines.push("", L.logTail, ...opts.logLines.map((l) => ` ${l}`));
|
|
167
|
+
}
|
|
168
|
+
return lines.join("\n");
|
|
169
|
+
}
|
|
170
|
+
function formatStopRunCard(status = "killed", labels) {
|
|
171
|
+
const L = resolveLabels(labels);
|
|
172
|
+
const icon = getAgentRunStatusIcon(status);
|
|
173
|
+
return `${L.runStopped}
|
|
174
|
+
${icon} ${status}`;
|
|
175
|
+
}
|
|
176
|
+
function formatListRunsCard(runs, labels) {
|
|
177
|
+
const L = resolveLabels(labels);
|
|
178
|
+
const lines = [L.runs(runs.length)];
|
|
179
|
+
for (const run of runs) {
|
|
180
|
+
const status = run.status ?? "\u2014";
|
|
181
|
+
const icon = getAgentRunStatusIcon(status);
|
|
182
|
+
lines.push(` ${icon} ${resolveRunLabel(run)}`);
|
|
183
|
+
}
|
|
184
|
+
return lines.join("\n");
|
|
185
|
+
}
|
|
186
|
+
function formatNotFoundRunCard(labels) {
|
|
187
|
+
const L = resolveLabels(labels);
|
|
188
|
+
return `${L.runStatus}
|
|
189
|
+
? not_found`;
|
|
190
|
+
}
|
|
191
|
+
var AGENT_RUN_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
192
|
+
"done",
|
|
193
|
+
"failed",
|
|
194
|
+
"timeout",
|
|
195
|
+
"killed",
|
|
196
|
+
"cancelled",
|
|
197
|
+
// orphaned: pid gone but the run record was still "running" — the process
|
|
198
|
+
// died (killed/OOM/crashed) before writing its own terminal status. Treated
|
|
199
|
+
// as terminal by all display/filter/GC consumers.
|
|
200
|
+
"orphaned"
|
|
201
|
+
]);
|
|
202
|
+
function isAgentRunTerminalStatus(status) {
|
|
203
|
+
return typeof status === "string" && AGENT_RUN_TERMINAL_STATUSES.has(status);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export {
|
|
207
|
+
getAgentRunStatusIcon,
|
|
208
|
+
shortRunId,
|
|
209
|
+
formatRunAge,
|
|
210
|
+
isAgentNameFallback,
|
|
211
|
+
resolveRunLabel,
|
|
212
|
+
formatStartRunCard,
|
|
213
|
+
TASK_PREVIEW_MAX,
|
|
214
|
+
formatStatusRunCard,
|
|
215
|
+
runShowsLogTail,
|
|
216
|
+
formatFinishedRunCard,
|
|
217
|
+
formatStopRunCard,
|
|
218
|
+
formatListRunsCard,
|
|
219
|
+
formatNotFoundRunCard,
|
|
220
|
+
isAgentRunTerminalStatus
|
|
221
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createCliLocalRuntimeAdapter,
|
|
3
3
|
summarizeEndpoint
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6IZTYSJK.js";
|
|
5
5
|
import {
|
|
6
6
|
clipMultilineText
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TSGUTKW2.js";
|
|
8
8
|
import {
|
|
9
9
|
runLocalAgentTurn
|
|
10
10
|
} from "./chunk-RIF3XLXK.js";
|