nolo-cli 0.47.0-alpha.2 → 0.47.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/{_executeModel-5PG6CUWD.js → _executeModel-4NLFAYUJ.js} +14 -12
  2. package/{agentDeleteCommand-SHSPQZHI.js → agentDeleteCommand-O5XR2A7X.js} +2 -2
  3. package/{agentEmailCommands-LQKO5GRW.js → agentEmailCommands-QXG4VPDL.js} +16 -13
  4. package/{agentListCommands-5QTNEYMQ.js → agentListCommands-NF75BYVM.js} +2 -2
  5. package/{agentMachineCommands-P5K454CN.js → agentMachineCommands-KGOXL5IA.js} +6 -5
  6. package/{agentRecordCommands-Z4QYCNP4.js → agentRecordCommands-MV6RBJU2.js} +16 -13
  7. package/{agentRunCommand-HV3Y34B5.js → agentRunCommand-PGKXK34X.js} +17 -14
  8. package/{agentRunControl-LHXOP4IU.js → agentRunControl-4GHHSXFZ.js} +1 -1
  9. package/{agentRuntimeLocal-ZKXYFLXI.js → agentRuntimeLocal-O6X4KCUS.js} +2 -2
  10. package/{agentSlice-NKFLP3RI.js → agentSlice-HM5KSZIO.js} +1 -1
  11. package/{agentSuperviseCommands-IMRZ56RC.js → agentSuperviseCommands-VB6BUS5H.js} +2 -2
  12. package/{appDeleteCommands-XYGAZIJX.js → appDeleteCommands-SZTC24KA.js} +2 -2
  13. package/{appDeployCommands-7T5CABRB.js → appDeployCommands-EAUHYRPF.js} +2 -2
  14. package/{appDeployStatusCommands-KTFQMRPZ.js → appDeployStatusCommands-K3AKGODG.js} +2 -2
  15. package/{appGetCommands-HOX2ULSV.js → appGetCommands-L56BQOH5.js} +2 -2
  16. package/{appListCommands-3SLCEHND.js → appListCommands-WTZKJM4T.js} +2 -2
  17. package/{chatQueueReduxAdapter-WMMBQK3Y.js → chatQueueReduxAdapter-Z7GK6NWM.js} +2 -2
  18. package/{chunk-RQSOAMPJ.js → chunk-3L2WKC3W.js} +12 -7
  19. package/{chunk-4ZNDBDWG.js → chunk-4RUHYZLJ.js} +2 -2
  20. package/chunk-5XTOKQLW.js +121 -0
  21. package/{chunk-HOM6NILS.js → chunk-65NEZURC.js} +1 -1
  22. package/{chunk-IWUPQUWA.js → chunk-6H5FASZ4.js} +1 -1
  23. package/{chunk-MQRZ5QUH.js → chunk-ALXHV7NK.js} +4 -2
  24. package/{chunk-WPFNAEIW.js → chunk-B75HVLQU.js} +1 -1
  25. package/{chunk-MUIJYGYW.js → chunk-BPRFPWWC.js} +1 -1
  26. package/{chunk-G46DB6KG.js → chunk-BPYHNK6B.js} +2 -2
  27. package/{chunk-YNOGNUBC.js → chunk-CXCSIBWY.js} +73 -27
  28. package/{chunk-XMI3APSU.js → chunk-E5HL3EXN.js} +6 -6
  29. package/chunk-EADNWBAZ.js +59 -0
  30. package/{chunk-H2JQB6B6.js → chunk-EPSE5WQL.js} +2 -2
  31. package/{chunk-25J3BB35.js → chunk-EUG45QJR.js} +90 -27
  32. package/{chunk-Q6DMA2OM.js → chunk-GEGFB75V.js} +38 -193
  33. package/{chunk-7XZ5GXSN.js → chunk-J3UALFHL.js} +1 -1
  34. package/{chunk-5BPZLBFB.js → chunk-KMWZ2MEG.js} +8 -6
  35. package/chunk-NF64D32W.js +8 -0
  36. package/{chunk-MWT2BBCH.js → chunk-T4P5XHZZ.js} +12 -10
  37. package/{chunk-FAWK6DBF.js → chunk-UVEH34NR.js} +8 -8
  38. package/{chunk-6LYUN76O.js → chunk-V7FV73B7.js} +3 -3
  39. package/{chunk-AEXP2UZT.js → chunk-WHVQA7PJ.js} +8 -2
  40. package/{chunk-5PPFYHU2.js → chunk-WQDU7TFJ.js} +2 -2
  41. package/{chunk-JEGPB5H2.js → chunk-XXS34H5T.js} +3 -3
  42. package/{createAgentAutomationAction-ENDNA3Q4.js → createAgentAutomationAction-QWWQTQ2Q.js} +3 -3
  43. package/{createDialogAction-2KNX6S2D.js → createDialogAction-XDMNGRXN.js} +4 -4
  44. package/{createPageAction-SNBCYPK6.js → createPageAction-74TUIHWA.js} +3 -3
  45. package/{dialogCommands-6E5P35DG.js → dialogCommands-WPG6I2ZR.js} +8 -3
  46. package/{dialogSlice-RTPOD6EW.js → dialogSlice-YUVIK53X.js} +2 -2
  47. package/{docCreateCommands-JWY25UFB.js → docCreateCommands-3T6427C5.js} +2 -2
  48. package/{docDeleteCommands-BPJOCSX4.js → docDeleteCommands-6ZXYJWUC.js} +2 -2
  49. package/{docReadCommands-BSEZCYTQ.js → docReadCommands-3VVYJYXK.js} +2 -2
  50. package/{docStore-TYHVLU7G.js → docStore-4J3GA3JF.js} +4 -4
  51. package/{docUpdateCommands-S2IE2VV4.js → docUpdateCommands-Z3RO54Y7.js} +2 -2
  52. package/{handleSendMessageAction-QYXDQXGH.js → handleSendMessageAction-5H53O6P2.js} +2 -2
  53. package/index.js +46 -46
  54. package/{machineCommands-QCE4KLGR.js → machineCommands-3L465LNQ.js} +17 -14
  55. package/{machineWsRunDispatch-FBRMGU5D.js → machineWsRunDispatch-YOHDI23Y.js} +16 -13
  56. package/package.json +1 -1
  57. package/{readlineWorkspace-2TACWKMN.js → readlineWorkspace-SQMRU5UF.js} +22 -19
  58. package/{runAgentClientLoop-GBLDVBT5.js → runAgentClientLoop-4Z2U3Y4R.js} +12 -10
  59. package/{spaceCommands-XOLPJMRK.js → spaceCommands-BH3JJ5NE.js} +2 -2
  60. package/{spaceSlice-OQPAGQDP.js → spaceSlice-R23R5VKL.js} +3 -3
  61. package/{streamAgentChatTurn-SN5XJJ7U.js → streamAgentChatTurn-L2NUEMDF.js} +13 -11
  62. package/{tools-Y65Y3CI4.js → tools-W7X3QSN2.js} +9 -7
  63. package/{updateDialogTitleAction-OAOP7CCE.js → updateDialogTitleAction-Y3NM74D7.js} +3 -3
@@ -8,6 +8,13 @@ import {
8
8
  readDbRecordFromServers,
9
9
  readLiveDbRecordAfterTombstoneMerge
10
10
  } from "./chunk-Q24S4NDF.js";
11
+ import {
12
+ fetchWithTransientRetry
13
+ } from "./chunk-5XTOKQLW.js";
14
+ import {
15
+ DRAIN_EXHAUSTED_USER_MESSAGE,
16
+ isDrainExhaustedResponse
17
+ } from "./chunk-3L2WKC3W.js";
11
18
  import {
12
19
  buildDialogAttachmentPlan,
13
20
  extractFileContentIds
@@ -4892,6 +4899,13 @@ function deriveToolErrors(toolMessages) {
4892
4899
  }
4893
4900
  return uniq(errors);
4894
4901
  }
4902
+ async function describeReadFailureStatus(res) {
4903
+ if (res.status !== 503) return `HTTP ${res.status}`;
4904
+ if (await isDrainExhaustedResponse(res)) {
4905
+ return `HTTP 503\uFF08${DRAIN_EXHAUSTED_USER_MESSAGE}\uFF09`;
4906
+ }
4907
+ return "HTTP 503";
4908
+ }
4895
4909
  async function readDialogOverHttp(args) {
4896
4910
  const authHeaders = {
4897
4911
  Authorization: `Bearer ${args.authToken}`,
@@ -4899,17 +4913,21 @@ async function readDialogOverHttp(args) {
4899
4913
  };
4900
4914
  const buildGetConvMsgsBody = () => JSON.stringify({ dialogId: args.dialogId, dialogKey: args.dialogKey, limit: args.limit });
4901
4915
  const readViaBridge = async () => {
4902
- const bridgeRes = await args.fetchImpl(`${args.base}/api/dialog-read`, {
4903
- method: "POST",
4904
- headers: authHeaders,
4905
- body: JSON.stringify({
4906
- dialogKey: args.dialogKey,
4907
- dialogId: args.dialogId,
4908
- limit: args.limit
4909
- })
4910
- });
4916
+ const bridgeRes = await fetchWithTransientRetry(
4917
+ args.fetchImpl,
4918
+ `${args.base}/api/dialog-read`,
4919
+ {
4920
+ method: "POST",
4921
+ headers: authHeaders,
4922
+ body: JSON.stringify({
4923
+ dialogKey: args.dialogKey,
4924
+ dialogId: args.dialogId,
4925
+ limit: args.limit
4926
+ })
4927
+ }
4928
+ );
4911
4929
  if (!bridgeRes.ok) {
4912
- throw Object.assign(new Error(`dialog read bridge failed: HTTP ${bridgeRes.status}`), {
4930
+ throw Object.assign(new Error(`dialog read bridge failed: ${await describeReadFailureStatus(bridgeRes)}`), {
4913
4931
  status: bridgeRes.status,
4914
4932
  base: args.base
4915
4933
  });
@@ -4928,40 +4946,45 @@ async function readDialogOverHttp(args) {
4928
4946
  };
4929
4947
  };
4930
4948
  if (args.messagesOnly) {
4931
- const msgsOnlyRes = await args.fetchImpl(`${args.base}/rpc/getConvMsgs`, {
4932
- method: "POST",
4933
- headers: authHeaders,
4934
- body: buildGetConvMsgsBody()
4935
- });
4949
+ const msgsOnlyRes = await fetchWithTransientRetry(
4950
+ args.fetchImpl,
4951
+ `${args.base}/rpc/getConvMsgs`,
4952
+ {
4953
+ method: "POST",
4954
+ headers: authHeaders,
4955
+ body: buildGetConvMsgsBody()
4956
+ }
4957
+ );
4936
4958
  if (!msgsOnlyRes.ok) {
4937
4959
  if (msgsOnlyRes.status === 401 || msgsOnlyRes.status === 403) return readViaBridge();
4938
- throw Object.assign(new Error(`read dialog messages failed: HTTP ${msgsOnlyRes.status}`), {
4960
+ throw Object.assign(new Error(`read dialog messages failed: ${await describeReadFailureStatus(msgsOnlyRes)}`), {
4939
4961
  status: msgsOnlyRes.status,
4940
4962
  base: args.base
4941
4963
  });
4942
4964
  }
4943
4965
  return { meta: null, msgs: await msgsOnlyRes.json(), source: "http" };
4944
4966
  }
4945
- const metaRes = await args.fetchImpl(
4967
+ const metaRes = await fetchWithTransientRetry(
4968
+ args.fetchImpl,
4946
4969
  `${args.base}/api/v1/db/read/${encodeURIComponent(args.dialogKey)}`,
4947
4970
  { headers: { Authorization: `Bearer ${args.authToken}` } }
4948
4971
  );
4949
4972
  if (!metaRes.ok) {
4950
4973
  if (metaRes.status === 401 || metaRes.status === 403) return readViaBridge();
4951
- throw Object.assign(new Error(`read dialog meta failed: HTTP ${metaRes.status}`), {
4974
+ throw Object.assign(new Error(`read dialog meta failed: ${await describeReadFailureStatus(metaRes)}`), {
4952
4975
  status: metaRes.status,
4953
4976
  base: args.base
4954
4977
  });
4955
4978
  }
4956
4979
  const meta = await metaRes.json();
4957
- const msgsRes = await args.fetchImpl(`${args.base}/rpc/getConvMsgs`, {
4980
+ const msgsRes = await fetchWithTransientRetry(args.fetchImpl, `${args.base}/rpc/getConvMsgs`, {
4958
4981
  method: "POST",
4959
4982
  headers: authHeaders,
4960
4983
  body: buildGetConvMsgsBody()
4961
4984
  });
4962
4985
  if (!msgsRes.ok) {
4963
4986
  if (msgsRes.status === 401 || msgsRes.status === 403) return readViaBridge();
4964
- throw Object.assign(new Error(`read dialog messages failed: HTTP ${msgsRes.status}`), {
4987
+ throw Object.assign(new Error(`read dialog messages failed: ${await describeReadFailureStatus(msgsRes)}`), {
4965
4988
  status: msgsRes.status,
4966
4989
  base: args.base
4967
4990
  });
@@ -5170,7 +5193,12 @@ async function readDialogSnapshot(args) {
5170
5193
  };
5171
5194
  } catch (error) {
5172
5195
  localFailure = describeLocalDialogFailure(error);
5173
- if (!isLevelNotFoundError(error) && !isLevelDbOpenUnavailableError(error)) throw error;
5196
+ if (!isLevelNotFoundError(error) && !isLevelDbOpenUnavailableError(error)) {
5197
+ const enriched = error;
5198
+ enriched.dialogId = args.dialogId;
5199
+ if (localFailure) enriched.local = localFailure;
5200
+ throw enriched;
5201
+ }
5174
5202
  }
5175
5203
  try {
5176
5204
  const result = await tryHttpDialogCandidates({
@@ -5184,8 +5212,9 @@ async function readDialogSnapshot(args) {
5184
5212
  });
5185
5213
  return { ...result, candidateBases };
5186
5214
  } catch (error) {
5215
+ const enriched = error;
5216
+ enriched.dialogId = args.dialogId;
5187
5217
  if (localFailure) {
5188
- const enriched = error;
5189
5218
  enriched.local = localFailure;
5190
5219
  const attemptedPaths = localFailure.paths ?? [localFailure.path];
5191
5220
  enriched.message = `${enriched.message}; local read attempted (${attemptedPaths.join(" \u2192 ")}): ${localFailure.reason}`;
@@ -5427,7 +5456,36 @@ async function readSpaceDialogRecords(args) {
5427
5456
  return { spaceId, records, failures };
5428
5457
  }
5429
5458
  var MAX_ATTEMPT_LINES = 5;
5430
- function formatDialogReadFailure(error) {
5459
+ function isCleanDialogNotFoundFailure(error) {
5460
+ if (typeof error !== "object" || error === null) return false;
5461
+ const attempts = Array.isArray(error.attempts) ? error.attempts : [];
5462
+ const hasHttp = attempts.length > 0;
5463
+ if (hasHttp) {
5464
+ const allHttp404 = attempts.every((attempt) => attempt.status === 404);
5465
+ if (!allHttp404) return false;
5466
+ }
5467
+ const localFailure = error.local;
5468
+ if (localFailure) {
5469
+ if (localFailure.attempts && localFailure.attempts.length > 0) {
5470
+ const allLocalClean = localFailure.attempts.every(
5471
+ (a) => a.status === "miss" || a.status === "missing" || a.status === "locked"
5472
+ );
5473
+ if (!allLocalClean) return false;
5474
+ } else {
5475
+ return false;
5476
+ }
5477
+ }
5478
+ return hasHttp || Boolean(localFailure);
5479
+ }
5480
+ function formatDialogReadFailure(error, fallbackDialogId) {
5481
+ const targetId = typeof error === "object" && error !== null && typeof error.dialogId === "string" && error.dialogId || fallbackDialogId;
5482
+ if (isCleanDialogNotFoundFailure(error)) {
5483
+ logger.debug(
5484
+ { error, dialogId: targetId },
5485
+ "dialog not found across all local and HTTP candidates"
5486
+ );
5487
+ return targetId ? `[nolo] dialog ${targetId} not found` : `[nolo] dialog not found`;
5488
+ }
5431
5489
  const message = toErrorMessage(error);
5432
5490
  const attempts = typeof error === "object" && error !== null && Array.isArray(error.attempts) ? error.attempts : [];
5433
5491
  const lines = [`[nolo] dialog read failed: ${message}`];
@@ -5448,7 +5506,7 @@ function formatDialogReadFailure(error) {
5448
5506
  }
5449
5507
  if (localFailure.locked) {
5450
5508
  lines.push(
5451
- " - \u5BBF\u4E3B\u8FDB\u7A0B\u6301\u6709 LevelDB \u6392\u4ED6\u9501\u65F6\uFF0C\u672C\u5730\u53EA\u8BFB\u4E0D\u53EF\u7528\uFF1A\u5EFA\u8BAE\u5173\u95ED\u5BBF\u4E3B\uFF08\u5982 dev server / \u8FD0\u884C\u4E2D\u7684 agent run\uFF09\u540E\u91CD\u8BD5\uFF0C\u6216\u6539\u7528 server \u7AEF\u70B9\u8BFB\u53D6\u3002"
5509
+ " - \u672C\u5730\u5E93\u6B63\u88AB\u67D0\u4E2A\u8FDB\u7A0B\u6301\u6709 LevelDB \u6392\u4ED6\u9501\uFF08\u5E38\u5E38\u5C31\u662F\u5F53\u524D TUI \u5BBF\u4E3B\u8FDB\u7A0B\u81EA\u5DF1\uFF0C\u672C\u5730\u53EA\u8BFB\u5728\u6301\u9501\u671F\u95F4\u4E0D\u53EF\u7528\uFF09\uFF1B\u8BF7\u901A\u8FC7 server \u7AEF\u70B9\u8BFB\u53D6\u8BE5 dialog\u3002"
5452
5510
  );
5453
5511
  }
5454
5512
  }
@@ -5522,7 +5580,9 @@ async function runDialogReadCommand(args, deps = {}) {
5522
5580
  dialogId: target.dialogId,
5523
5581
  dialogKey: target.dialogKey,
5524
5582
  fetchImpl: deps.fetchImpl ?? fetch,
5525
- limit
5583
+ limit,
5584
+ readLocalDialog: deps.readLocalDialog,
5585
+ readLocalDialogAtDbPath: deps.readLocalDialogAtDbPath
5526
5586
  });
5527
5587
  const orderedMsgs = Array.isArray(read.msgs) ? [...read.msgs].reverse() : read.msgs;
5528
5588
  const lastAssistantMessage = Array.isArray(orderedMsgs) ? [...orderedMsgs].reverse().find((message) => message?.role === "assistant" || message?.authorRole === "assistant") : null;
@@ -5583,7 +5643,7 @@ async function runDialogReadCommand(args, deps = {}) {
5583
5643
  output.write("\n");
5584
5644
  return 0;
5585
5645
  } catch (error) {
5586
- output.write(`${formatDialogReadFailure(error)}
5646
+ output.write(`${formatDialogReadFailure(error, target.dialogId)}
5587
5647
  `);
5588
5648
  return 1;
5589
5649
  }
@@ -5619,7 +5679,9 @@ async function runDialogStatusCommand(args, deps = {}) {
5619
5679
  dialogId: target.dialogId,
5620
5680
  dialogKey: target.dialogKey,
5621
5681
  fetchImpl: deps.fetchImpl ?? fetch,
5622
- limit: 1
5682
+ limit: 1,
5683
+ readLocalDialog: deps.readLocalDialog,
5684
+ readLocalDialogAtDbPath: deps.readLocalDialogAtDbPath
5623
5685
  });
5624
5686
  output.write(renderCompactDialogStatus({
5625
5687
  ...read.meta ?? {},
@@ -6033,6 +6095,7 @@ export {
6033
6095
  isScheduledDialog,
6034
6096
  isLevelDbOpenUnavailableError,
6035
6097
  readDialogSnapshot,
6098
+ isCleanDialogNotFoundFailure,
6036
6099
  runDialogReadCommand,
6037
6100
  runDialogStatusCommand,
6038
6101
  runDialogQueryCommand,
@@ -5,6 +5,9 @@ import {
5
5
  refreshOpenAiCodexToken,
6
6
  xaiRefresh
7
7
  } from "./chunk-I4JISVWK.js";
8
+ import {
9
+ defaultLoopbackRequest
10
+ } from "./chunk-EADNWBAZ.js";
8
11
  import {
9
12
  clearCredentialAvailability,
10
13
  markCredentialUnavailable,
@@ -43,7 +46,7 @@ import {
43
46
  spawnLocalBackgroundRun,
44
47
  terminateRunProcess,
45
48
  withQueueLock
46
- } from "./chunk-AEXP2UZT.js";
49
+ } from "./chunk-WHVQA7PJ.js";
47
50
  import {
48
51
  inferCaptureIntent
49
52
  } from "./chunk-AYXSUBVC.js";
@@ -53,7 +56,7 @@ import {
53
56
  import {
54
57
  inlineImageUrlsForCustomProvider,
55
58
  prepareTools
56
- } from "./chunk-IWUPQUWA.js";
59
+ } from "./chunk-6H5FASZ4.js";
57
60
  import {
58
61
  getServerProviderSecret
59
62
  } from "./chunk-HS7MLR74.js";
@@ -72,13 +75,11 @@ import {
72
75
  rememberMemoryFunctionSchema,
73
76
  resolveAgentRequiredPackIds,
74
77
  setTodoListFunc
75
- } from "./chunk-YNOGNUBC.js";
78
+ } from "./chunk-CXCSIBWY.js";
76
79
  import {
77
- createDrainExhaustedResponse,
78
- isCoreDrainingBody,
79
- normalizeNonNegativeMs,
80
- parseRetryAfterHeaderMs
81
- } from "./chunk-RQSOAMPJ.js";
80
+ fetchWithTransientRetry,
81
+ isTransientFetchError
82
+ } from "./chunk-5XTOKQLW.js";
82
83
  import {
83
84
  TASK_PREVIEW_MAX,
84
85
  formatListRunsCard,
@@ -97,13 +98,13 @@ import {
97
98
  prepareTokenUsageData,
98
99
  resolveBuiltinPlatformAgentConfig,
99
100
  runKeyed
100
- } from "./chunk-FAWK6DBF.js";
101
+ } from "./chunk-UVEH34NR.js";
101
102
  import {
102
103
  BUILTIN_TITLE_LLM_CONFIG
103
104
  } from "./chunk-EVBFYPDC.js";
104
105
  import {
105
106
  fetchServerSyncedCredential
106
- } from "./chunk-6LYUN76O.js";
107
+ } from "./chunk-V7FV73B7.js";
107
108
  import {
108
109
  require_date_fns
109
110
  } from "./chunk-M76ECQRD.js";
@@ -142,7 +143,7 @@ import {
142
143
  parseSyncServersEnv,
143
144
  resolveOpenAiCompatibleProviderConfig,
144
145
  summarizeToolArguments
145
- } from "./chunk-MUIJYGYW.js";
146
+ } from "./chunk-BPRFPWWC.js";
146
147
  import {
147
148
  buildPlatformChatCompletionRequest,
148
149
  canUsePlatformChatProvider,
@@ -235,9 +236,6 @@ import {
235
236
  import {
236
237
  NOLO_CLUSTER_SERVERS
237
238
  } from "./chunk-LCBAMY2M.js";
238
- import {
239
- isLoopbackHostname
240
- } from "./chunk-4SN6J65J.js";
241
239
  import {
242
240
  normalizeServerOrigin
243
241
  } from "./chunk-CF7PE763.js";
@@ -1474,164 +1472,6 @@ function isAnthropicOAuthAgent(agent) {
1474
1472
  return agent.apiKeyRef?.trim().toLowerCase() === "claude";
1475
1473
  }
1476
1474
 
1477
- // packages/cli/client/localRuntimeFetchRetry.ts
1478
- import { request as httpRequest } from "node:http";
1479
- import { request as httpsRequest } from "node:https";
1480
- var TRANSIENT_FETCH_MAX_ATTEMPTS = 3;
1481
- var TRANSIENT_FETCH_RETRY_BASE_DELAY_MS = 250;
1482
- var CORE_DRAINING_MAX_ATTEMPTS = 30;
1483
- var RETRYABLE_HTTP_STATUSES = /* @__PURE__ */ new Set([429, 503]);
1484
- function isTransientFetchError(error) {
1485
- const message = toErrorMessage(error);
1486
- return /certificate|handshake|network|socket|timed out|timeout|ECONNRESET/i.test(
1487
- message
1488
- );
1489
- }
1490
- async function defaultSleep(ms) {
1491
- await new Promise((resolve) => setTimeout(resolve, ms));
1492
- }
1493
- function transientFetchRetryDelayMs(attempt) {
1494
- return Math.min(attempt * TRANSIENT_FETCH_RETRY_BASE_DELAY_MS, 2e3);
1495
- }
1496
- var MAX_RETRY_DELAY_MS = 1e4;
1497
- async function resolveRetryAfterMs(response, attempt) {
1498
- const headerMs = parseRetryAfterHeaderMs(
1499
- response.headers.get("retry-after")
1500
- );
1501
- if (headerMs !== null) {
1502
- return Math.min(headerMs, MAX_RETRY_DELAY_MS);
1503
- }
1504
- try {
1505
- const body = await response.clone().text();
1506
- const parsed = JSON.parse(body);
1507
- const ms = normalizeNonNegativeMs(parsed?.retryAfterMs, 0);
1508
- if (ms > 0) return Math.min(ms, MAX_RETRY_DELAY_MS);
1509
- } catch {
1510
- }
1511
- return transientFetchRetryDelayMs(attempt);
1512
- }
1513
- function isLoopbackUrl(input) {
1514
- try {
1515
- const target = typeof input === "string" || input instanceof URL ? new URL(String(input)) : new URL(input.url);
1516
- return isLoopbackHostname(target.hostname);
1517
- } catch {
1518
- return false;
1519
- }
1520
- }
1521
- function toNodeRequestBody(body) {
1522
- if (typeof body === "string") return Buffer.from(body);
1523
- if (body instanceof Uint8Array) return Buffer.from(body);
1524
- if (body instanceof ArrayBuffer) return Buffer.from(body);
1525
- return null;
1526
- }
1527
- async function defaultLoopbackRequest(input, init) {
1528
- const target = typeof input === "string" || input instanceof URL ? new URL(String(input)) : new URL(input.url);
1529
- const headers = new Headers(init?.headers);
1530
- const body = toNodeRequestBody(init?.body);
1531
- if (body && !headers.has("Content-Length")) {
1532
- headers.set("Content-Length", String(body.byteLength));
1533
- }
1534
- return await new Promise((resolve, reject) => {
1535
- const requestImpl = target.protocol === "https:" ? httpsRequest : httpRequest;
1536
- const req = requestImpl(
1537
- target,
1538
- {
1539
- method: init?.method ?? "GET",
1540
- headers: Object.fromEntries(headers.entries())
1541
- },
1542
- (res) => {
1543
- const chunks = [];
1544
- res.on(
1545
- "data",
1546
- (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))
1547
- );
1548
- res.on("end", () => {
1549
- resolve(
1550
- new Response(Buffer.concat(chunks), {
1551
- status: res.statusCode ?? 500,
1552
- headers: res.headers
1553
- })
1554
- );
1555
- });
1556
- }
1557
- );
1558
- req.on("error", reject);
1559
- init?.signal?.addEventListener(
1560
- "abort",
1561
- () => {
1562
- req.destroy(
1563
- init.signal?.reason instanceof Error ? init.signal.reason : new Error("request aborted")
1564
- );
1565
- reject(init.signal?.reason ?? new Error("request aborted"));
1566
- },
1567
- { once: true }
1568
- );
1569
- if (body) req.write(body);
1570
- req.end();
1571
- });
1572
- }
1573
- async function isCoreDrainingResponse(response) {
1574
- if (response.status !== 503) return false;
1575
- try {
1576
- const body = await response.clone().json();
1577
- return isCoreDrainingBody(body);
1578
- } catch {
1579
- return false;
1580
- }
1581
- }
1582
- async function fetchWithTransientRetry(fetchImpl, input, init, options = {}) {
1583
- const retryableStatuses = options.retryableStatuses ?? RETRYABLE_HTTP_STATUSES;
1584
- const requestedMaxAttempts = Number(options.maxAttempts);
1585
- const maxAttempts = Number.isFinite(requestedMaxAttempts) ? Math.min(100, Math.max(1, Math.floor(requestedMaxAttempts))) : TRANSIENT_FETCH_MAX_ATTEMPTS;
1586
- const requestedCoreDrainingMaxAttempts = Number(options.coreDrainingMaxAttempts);
1587
- const coreDrainingMaxAttempts = Number.isFinite(requestedCoreDrainingMaxAttempts) ? Math.min(100, Math.max(1, Math.floor(requestedCoreDrainingMaxAttempts))) : CORE_DRAINING_MAX_ATTEMPTS;
1588
- const loopMaxAttempts = Math.max(maxAttempts, coreDrainingMaxAttempts);
1589
- let lastError;
1590
- for (let attempt = 1; attempt <= loopMaxAttempts; attempt += 1) {
1591
- try {
1592
- if (options.loopbackRequest && isLoopbackUrl(input)) {
1593
- return await options.loopbackRequest(input, init);
1594
- }
1595
- const response = await fetchImpl(input, init);
1596
- const retryableStatus = retryableStatuses.has(response.status) && !init?.signal?.aborted;
1597
- const callerAllowsRetry = retryableStatus ? await options.shouldRetryResponse?.(response) ?? true : false;
1598
- if (retryableStatus && callerAllowsRetry) {
1599
- const coreDraining = await isCoreDrainingResponse(response);
1600
- const attemptBudget = coreDraining ? coreDrainingMaxAttempts : maxAttempts;
1601
- if (attempt < attemptBudget) {
1602
- const delayMs = await resolveRetryAfterMs(response, attempt);
1603
- options.onRetry?.({
1604
- attempt: attempt + 1,
1605
- maxAttempts: attemptBudget,
1606
- delayMs
1607
- });
1608
- await (options.sleep ?? defaultSleep)(delayMs);
1609
- continue;
1610
- }
1611
- if (coreDraining) {
1612
- return createDrainExhaustedResponse(response);
1613
- }
1614
- }
1615
- return response;
1616
- } catch (error) {
1617
- if (init?.signal?.aborted) throw error;
1618
- if (!isTransientFetchError(error)) throw error;
1619
- if (options.retryNetworkErrors === false) throw error;
1620
- lastError = error;
1621
- if (attempt < maxAttempts) {
1622
- const delayMs = transientFetchRetryDelayMs(attempt);
1623
- options.onRetry?.({
1624
- attempt: attempt + 1,
1625
- maxAttempts,
1626
- delayMs
1627
- });
1628
- await (options.sleep ?? defaultSleep)(delayMs);
1629
- }
1630
- }
1631
- }
1632
- throw lastError;
1633
- }
1634
-
1635
1475
  // packages/cli/client/cliWorkspaceToolVariants.ts
1636
1476
  function shouldUseDeclaredOnlyLocalWorkspaceTools(env) {
1637
1477
  const value = env.NOLO_LOCAL_WORKSPACE_TOOLSET || env.NOLO_LOCAL_TOOLSET_MODE || "";
@@ -2836,7 +2676,7 @@ async function readSseEvents(response) {
2836
2676
  return ev && !Array.isArray(ev) ? ev : null;
2837
2677
  });
2838
2678
  }
2839
- var defaultSleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2679
+ var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2840
2680
  async function callCodexResponsesOnce(args, accountId) {
2841
2681
  const fetchImpl = args.fetchImpl ?? fetch;
2842
2682
  const identity = createCodexRequestIdentity();
@@ -2901,7 +2741,7 @@ async function fetchCodexResponsesCompletion(args) {
2901
2741
  }
2902
2742
  };
2903
2743
  }
2904
- const sleep = args.sleep ?? defaultSleep2;
2744
+ const sleep = args.sleep ?? defaultSleep;
2905
2745
  const requestedMaxAttempts = Number(args.maxAttempts);
2906
2746
  const maxAttempts = Number.isFinite(requestedMaxAttempts) ? Math.min(10, Math.max(1, Math.floor(requestedMaxAttempts))) : CODEX_STREAM_MAX_ATTEMPTS;
2907
2747
  let result = await callCodexResponsesOnce(args, accountId);
@@ -9561,7 +9401,7 @@ var BUSY_STREAM_RETRY_DELAY_MS = 1200;
9561
9401
  function isBusyProviderStreamError(error) {
9562
9402
  return BUSY_STREAM_ERROR_RE.test(toErrorMessage(error));
9563
9403
  }
9564
- async function defaultSleep3(ms) {
9404
+ async function defaultSleep2(ms) {
9565
9405
  await new Promise((resolve) => setTimeout(resolve, ms));
9566
9406
  }
9567
9407
  function isRetryableProviderStreamError(error) {
@@ -9602,7 +9442,7 @@ function withProviderStreamRetry(provider, deps) {
9602
9442
  }
9603
9443
  if (isBusyProviderStreamError(error)) {
9604
9444
  deps.activityReporter?.("\u670D\u52A1\u5668\u7D27\u5F20 \xB7 \u7A0D\u5019\u81EA\u52A8\u91CD\u8BD5");
9605
- await (deps.sleep ?? defaultSleep3)(BUSY_STREAM_RETRY_DELAY_MS);
9445
+ await (deps.sleep ?? defaultSleep2)(BUSY_STREAM_RETRY_DELAY_MS);
9606
9446
  } else {
9607
9447
  deps.activityReporter?.("\u4E0A\u6E38\u6D41\u4E2D\u65AD \xB7 \u81EA\u52A8\u91CD\u8BD5");
9608
9448
  }
@@ -10706,15 +10546,14 @@ function buildRunStatusPayload(reconciled, deps, opts = {}) {
10706
10546
  startedAt: reconciled.startedAt,
10707
10547
  endedAt: reconciled.endedAt ?? null,
10708
10548
  exitCode: reconciled.exitCode ?? null,
10709
- // Expose dialogId so the caller can read the agent's actual output
10710
- // via `nolo dialog read <dialogId>`. The dialog is the authoritative
10711
- // result store; the run log is the child process stdout/stderr,
10712
- // whose contents vary by provider (some stream tokens to stdout,
10713
- // some only emit startup + stderr). Because status does not carry
10714
- // logTail by default, a "done" run with an empty logTail is
10715
- // indistinguishable from a hung run without this field. Surfacing
10716
- // dialogId gives the caller a reliable way to fetch the result.
10717
- ...reconciled.dialogId ? { dialogId: reconciled.dialogId } : {},
10549
+ // Non-ephemeral runs expose dialogId so the caller can read the
10550
+ // agent's actual output via `nolo dialog read <dialogId>`. Ephemeral
10551
+ // runs do not persist a dialog (their ephemeral dialogId is synthetic)
10552
+ // and instead return `{ ephemeral: true, dialogNote: ... }`.
10553
+ ...reconciled.ephemeral ? {
10554
+ ephemeral: true,
10555
+ dialogNote: "\u6B64 run \u672A\u6301\u4E45\u5316 dialog\uFF0C\u7ED3\u679C\u89C1 run \u8F93\u51FA"
10556
+ } : reconciled.dialogId ? { dialogId: reconciled.dialogId } : {},
10718
10557
  ...reportExists ? { reportPath } : {},
10719
10558
  // Progress is what makes tailLines:0 an actual answer to "is it
10720
10559
  // stuck?". Without it a poll returns `running` and a pid, so the only
@@ -10777,6 +10616,7 @@ ${JSON.stringify(args.input)}`;
10777
10616
  ...dodCommands && dodCommands.length > 0 ? { dodCommands } : {},
10778
10617
  cwd: deps.cwd ?? process.cwd(),
10779
10618
  message,
10619
+ ...args.ephemeral === true ? { ephemeral: true } : {},
10780
10620
  output: noopOutput
10781
10621
  },
10782
10622
  deps
@@ -10830,7 +10670,7 @@ ${JSON.stringify(args.input)}`;
10830
10670
  };
10831
10671
  }
10832
10672
  async function spawnContinuationRun(reconciled, userInput, deps) {
10833
- if (!reconciled.dialogId) {
10673
+ if (!reconciled.ephemeral && !reconciled.dialogId) {
10834
10674
  throw new Error("\u8BE5 run \u65E0\u5173\u8054 dialog\uFF0C\u65E0\u6CD5\u7EED\u8DD1\u3002");
10835
10675
  }
10836
10676
  const agentKey = reconciled.agentKey;
@@ -10838,12 +10678,14 @@ async function spawnContinuationRun(reconciled, userInput, deps) {
10838
10678
  const rawArgs = [
10839
10679
  "--agent",
10840
10680
  agentKey,
10841
- "--continue",
10842
- reconciled.dialogId,
10681
+ // 仅非 ephemeral 且确有 dialogId 时才续接原 dialog。ephemeral 不落盘,
10682
+ // 其 dialogId 是合成的,绝不能透传给子进程 --continue(子进程读不到必然
10683
+ // 全链路 404);续跑转为开一个新的 ephemeral run。
10684
+ ...!reconciled.ephemeral && reconciled.dialogId ? ["--continue", reconciled.dialogId] : [],
10843
10685
  "--msg-file",
10844
10686
  "PLACEHOLDER",
10845
10687
  "--bg",
10846
- ...reconciled.ephemeral === true ? ["--ephemeral"] : []
10688
+ ...reconciled.ephemeral ? ["--ephemeral"] : []
10847
10689
  ];
10848
10690
  const { runId: newRunId, batchId: resolvedBatchId } = await spawnLocalBackgroundRun(
10849
10691
  {
@@ -10856,6 +10698,7 @@ async function spawnContinuationRun(reconciled, userInput, deps) {
10856
10698
  ...reconciled.parentDialogId ? { parentDialogId: reconciled.parentDialogId } : {},
10857
10699
  cwd: reconciled.cwd ?? deps.cwd ?? process.cwd(),
10858
10700
  message: userInput,
10701
+ ...reconciled.ephemeral ? { ephemeral: true } : {},
10859
10702
  output: noopOutput
10860
10703
  },
10861
10704
  deps
@@ -10867,7 +10710,8 @@ async function spawnContinuationRun(reconciled, userInput, deps) {
10867
10710
  content: JSON.stringify({
10868
10711
  runId: reconciled.runId,
10869
10712
  newRunId,
10870
- dialogId: reconciled.dialogId,
10713
+ // ephemeral 的 dialogId 是合成的(不落盘),不外泄;调用方按 ephemeral 语义处理。
10714
+ ...reconciled.ephemeral ? { ephemeral: true } : { dialogId: reconciled.dialogId },
10871
10715
  mode: "continue",
10872
10716
  status: "running",
10873
10717
  ...agentName ? { agentName } : {},
@@ -11030,7 +10874,8 @@ function createCliControlAgentRunExecutor(deps = {}) {
11030
10874
  return {
11031
10875
  content: JSON.stringify({
11032
10876
  runId: reconciled.runId,
11033
- ...afterCheck.dialogId || reconciled.dialogId ? { dialogId: afterCheck.dialogId ?? reconciled.dialogId } : {},
10877
+ // ephemeral 不外泄合成 dialogId;非 ephemeral 保持原 dialogId 透出。
10878
+ ...reconciled.ephemeral ? { ephemeral: true } : afterCheck.dialogId || reconciled.dialogId ? { dialogId: afterCheck.dialogId ?? reconciled.dialogId } : {},
11034
10879
  mode: "enqueue",
11035
10880
  consumed: true,
11036
10881
  status: afterCheck.status,
@@ -11052,7 +10897,8 @@ function createCliControlAgentRunExecutor(deps = {}) {
11052
10897
  return {
11053
10898
  content: JSON.stringify({
11054
10899
  runId: reconciled.runId,
11055
- ...reconciled.dialogId ? { dialogId: reconciled.dialogId } : {},
10900
+ // ephemeral 不外泄合成 dialogId(enqueue 场景同样收敛)。
10901
+ ...reconciled.ephemeral ? { ephemeral: true } : reconciled.dialogId ? { dialogId: reconciled.dialogId } : {},
11056
10902
  mode: "enqueue",
11057
10903
  queued: queuedCount,
11058
10904
  status: "running",
@@ -12411,7 +12257,6 @@ function createCliLocalRuntimeAdapter(deps) {
12411
12257
 
12412
12258
  export {
12413
12259
  clearCliLocalRuntimePreparedAgentCache,
12414
- isTransientFetchError,
12415
12260
  isSubtaskRun,
12416
12261
  summarizeEndpoint,
12417
12262
  isBuiltinNoloAgentRef,
@@ -3,7 +3,7 @@ import {
3
3
  resolveRunReportJsonPath,
4
4
  resolveRunReportPath,
5
5
  resolveRunsDir
6
- } from "./chunk-AEXP2UZT.js";
6
+ } from "./chunk-WHVQA7PJ.js";
7
7
 
8
8
  // packages/cli/agentRunReport.ts
9
9
  import { homedir as nodeHomedir } from "node:os";
@@ -10,14 +10,16 @@ import {
10
10
  fetchAndSerializeTable,
11
11
  resolveBuiltinSkillPage,
12
12
  waitForAbortableDelay
13
- } from "./chunk-YNOGNUBC.js";
13
+ } from "./chunk-CXCSIBWY.js";
14
+ import {
15
+ isGatewayHttpStatus
16
+ } from "./chunk-NF64D32W.js";
14
17
  import {
15
18
  createDrainExhaustedResponse,
16
19
  isCoreDrainingBody,
17
- isGatewayHttpStatus,
18
20
  normalizeNonNegativeMs,
19
21
  parseRetryAfterHeaderMs
20
- } from "./chunk-RQSOAMPJ.js";
22
+ } from "./chunk-3L2WKC3W.js";
21
23
  import {
22
24
  slateToSimplifiedMarkdown
23
25
  } from "./chunk-FJHLA6SX.js";
@@ -26,13 +28,13 @@ import {
26
28
  } from "./chunk-MEYIRKDN.js";
27
29
  import {
28
30
  fetchAndCacheMessages
29
- } from "./chunk-FAWK6DBF.js";
31
+ } from "./chunk-UVEH34NR.js";
30
32
  import {
31
33
  shouldUseServerProxy
32
34
  } from "./chunk-YYLHWIW6.js";
33
35
  import {
34
36
  fetchServerSyncedCredential
35
- } from "./chunk-6LYUN76O.js";
37
+ } from "./chunk-V7FV73B7.js";
36
38
  import {
37
39
  buildSkillGuidancePromptBlock,
38
40
  extractRuntimePageCapabilities,
@@ -44,7 +46,7 @@ import {
44
46
  buildRuntimeGuidanceBlocks,
45
47
  normalizeChatCompletionsBodyForProvider,
46
48
  resolveToolGuidedSections
47
- } from "./chunk-G46DB6KG.js";
49
+ } from "./chunk-BPYHNK6B.js";
48
50
  import {
49
51
  convertMessagesToResponsesInput,
50
52
  getUsageRequestOptions,
@@ -0,0 +1,8 @@
1
+ // packages/core/gatewayHttpStatus.ts
2
+ function isGatewayHttpStatus(status) {
3
+ return status === 502 || status === 503 || status === 504;
4
+ }
5
+
6
+ export {
7
+ isGatewayHttpStatus
8
+ };