nolo-cli 0.164.0-alpha.5 → 0.166.0-alpha.1

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 (85) hide show
  1. package/{_executeModel-M5PGAD3Z.js → _executeModel-XPCZ5RBB.js} +21 -21
  2. package/{accountResolver-55EDKEIK.js → accountResolver-JS7QDNNL.js} +1 -1
  3. package/{agentDeleteCommand-FNLCIWA7.js → agentDeleteCommand-OGJISSU7.js} +27 -27
  4. package/{agentEmailCommands-SBPLOOIY.js → agentEmailCommands-XGD4KL64.js} +28 -28
  5. package/{agentListCommands-GOCGOQUB.js → agentListCommands-34W3Q23M.js} +44 -21
  6. package/{agentMachineCommands-L7NY3BCY.js → agentMachineCommands-BFAPCDL5.js} +14 -14
  7. package/{agentRecordCommands-GHQNXIVM.js → agentRecordCommands-IHO3IDQK.js} +27 -27
  8. package/{agentRunCommand-2QU75CBD.js → agentRunCommand-MQGSEJPR.js} +28 -28
  9. package/{agentRuntimeLocal-J6I63NZC.js → agentRuntimeLocal-3EDL6FJP.js} +11 -11
  10. package/{agentSlice-JOVX3KY3.js → agentSlice-FHAWX2N7.js} +1 -1
  11. package/{appDeleteCommands-KKLAK2UR.js → appDeleteCommands-4NDA5UOW.js} +16 -16
  12. package/{appDeployCommands-PXWK4FAX.js → appDeployCommands-ST3R26X3.js} +16 -16
  13. package/{appDeployStatusCommands-3NGWDZTX.js → appDeployStatusCommands-7NARROTP.js} +16 -16
  14. package/{appGetCommands-APWYPEO3.js → appGetCommands-BWJF2GVT.js} +16 -16
  15. package/{appListCommands-OP7IRALO.js → appListCommands-KHC5STHO.js} +16 -16
  16. package/{authCommand-3Z52KJID.js → authCommand-OVBMDPIF.js} +1 -1
  17. package/{chunk-YTWGTCVW.js → chunk-3WYHEMHF.js} +14 -14
  18. package/{chunk-N665S3Z2.js → chunk-4M5NB6HV.js} +2 -2
  19. package/{chunk-MLEANT7D.js → chunk-6HAE54KH.js} +2 -2
  20. package/{chunk-L2JMH4I5.js → chunk-6LYCXISC.js} +6 -3
  21. package/{chunk-QXZH5UDF.js → chunk-7NKZA46B.js} +2 -2
  22. package/{chunk-QA2C5NKI.js → chunk-ASSNAASW.js} +1 -1
  23. package/{chunk-U34KT53V.js → chunk-BSKTDOGA.js} +6 -2
  24. package/{chunk-IPQ3W3CZ.js → chunk-BWLTQSBQ.js} +10 -10
  25. package/{chunk-ULQAD7ZY.js → chunk-CEXJ6Y3C.js} +1 -1
  26. package/{chunk-4L4K6YR7.js → chunk-DI7ZFGDQ.js} +1 -1
  27. package/{chunk-ZU4J4GRW.js → chunk-E3J37BFW.js} +3 -3
  28. package/{chunk-EFGBXVOC.js → chunk-ENZVVNIQ.js} +2 -2
  29. package/{chunk-DE3RG4GV.js → chunk-FVKOS527.js} +2 -2
  30. package/{chunk-5E5VB7PS.js → chunk-GHG5ONT5.js} +10 -9
  31. package/{chunk-YVPQATSC.js → chunk-GPLUFN2E.js} +7 -1
  32. package/{chunk-3N5VQFR7.js → chunk-GSKYA637.js} +2 -2
  33. package/{chunk-Y2UYLA5L.js → chunk-GVT4GTDD.js} +5 -5
  34. package/{chunk-TDMS3H4D.js → chunk-H3THOSSL.js} +3 -3
  35. package/{chunk-F3SOW2EU.js → chunk-HEC32F3G.js} +1 -1
  36. package/{chunk-W7FGZRLK.js → chunk-I72LPLCP.js} +1 -1
  37. package/{chunk-JGXBS3CI.js → chunk-JB7B7EH3.js} +8 -8
  38. package/chunk-JLR5NWP2.js +548 -0
  39. package/{chunk-ZZDVBZOP.js → chunk-K3NJW7LY.js} +6 -4
  40. package/{chunk-CNWKLQRL.js → chunk-KSTEXKL6.js} +70 -36
  41. package/{chunk-5IKRTRRR.js → chunk-MCGCC5BA.js} +1 -1
  42. package/{chunk-GVGQKI6E.js → chunk-MV2VYO4L.js} +85 -33
  43. package/{chunk-35CEDQD6.js → chunk-P3JTVV3J.js} +139 -29
  44. package/{chunk-RBMYJSZF.js → chunk-P46JXWXJ.js} +2 -2
  45. package/{chunk-647HBTHJ.js → chunk-QPW5KIX3.js} +2 -2
  46. package/{chunk-6MXDOUMH.js → chunk-R4BMKAR5.js} +70 -8
  47. package/{chunk-TT644UJD.js → chunk-SAZSXMTR.js} +1 -1
  48. package/{chunk-3M52COK5.js → chunk-SLAZGVZN.js} +71 -3
  49. package/{chunk-ZMVXHANW.js → chunk-STFIUL6J.js} +1 -1
  50. package/{chunk-2AB2HA4M.js → chunk-TDX2L4W2.js} +8 -2
  51. package/{chunk-DJ2BOPJY.js → chunk-TQGP2LAX.js} +1 -1
  52. package/{chunk-2MWKM3NP.js → chunk-UCQ6TM4H.js} +5 -5
  53. package/{chunk-OC72ZET2.js → chunk-V2KGGU2X.js} +10 -10
  54. package/{chunk-ZKBZLQTG.js → chunk-XGJTJIMA.js} +3 -3
  55. package/{chunk-WYJTNSVL.js → chunk-XKVWXU6D.js} +35 -4
  56. package/{chunk-BL4HFN6L.js → chunk-YL26TH2V.js} +1 -1
  57. package/{chunk-4JCAW7TO.js → chunk-Z2LMCNOD.js} +2 -2
  58. package/{commandRegistry-6VNTR43G.js → commandRegistry-QCIEJGYN.js} +49 -49
  59. package/{contentThunks-7JLGMPNX.js → contentThunks-Y5PIKT2D.js} +5 -5
  60. package/{cooldownCommands-JFKTYS2D.js → cooldownCommands-NS63RGBO.js} +2 -2
  61. package/{createAgentAutomationAction-WSQ3VZ3X.js → createAgentAutomationAction-ZAMCZGS3.js} +5 -5
  62. package/{createDialogAction-4SHMWQYD.js → createDialogAction-RRSAGTPA.js} +6 -6
  63. package/{createPageAction-GHYKDASE.js → createPageAction-QQTGDZGC.js} +6 -6
  64. package/{dialogCommands-3W6AIUXT.js → dialogCommands-4ONUY3PM.js} +15 -15
  65. package/{dialogSlice-YXRGO7UV.js → dialogSlice-PS42ZUMV.js} +4 -4
  66. package/{docCreateCommands-KQHQNLRX.js → docCreateCommands-UMNAXUXH.js} +14 -14
  67. package/{docDeleteCommands-O3DWFX2W.js → docDeleteCommands-FDG74KV7.js} +15 -15
  68. package/{docReadCommands-2U2BUONC.js → docReadCommands-YOWFYZF4.js} +14 -14
  69. package/{docStore-2U6GZMDG.js → docStore-3N4GMKE5.js} +1 -1
  70. package/{docUpdateCommands-MF3C52XI.js → docUpdateCommands-FRRMAFI2.js} +14 -14
  71. package/{handleSendMessageAction-SK6Q2N7Z.js → handleSendMessageAction-LQA55M62.js} +24 -11
  72. package/index.js +4 -4
  73. package/{localRuntimeAdapter-IIGPBSU6.js → localRuntimeAdapter-4HJXHS3I.js} +27 -25
  74. package/{machineCommands-2SN3XNMT.js → machineCommands-3C7IFGSE.js} +26 -26
  75. package/{machineWsRunDispatch-DQE55BK5.js → machineWsRunDispatch-DMEKTEMI.js} +26 -26
  76. package/package.json +1 -1
  77. package/{readlineWorkspace-VM35JAR6.js → readlineWorkspace-5PT2F33I.js} +31 -31
  78. package/{runAgentClientLoop-FR7N5TID.js → runAgentClientLoop-FEG5ZOME.js} +19 -19
  79. package/{spaceCommands-NDPGHDMD.js → spaceCommands-L3XQIY3J.js} +14 -14
  80. package/{streamAgentChatTurn-YHZNWDWS.js → streamAgentChatTurn-QD6ARRXS.js} +23 -23
  81. package/{tools-AEPUZOZ2.js → tools-YQIMXETR.js} +13 -13
  82. package/{tuiSummaryLlmCaller-FESHBDTT.js → tuiSummaryLlmCaller-FQOEF4IE.js} +3 -3
  83. package/{updateDialogTitleAction-QERIYNOM.js → updateDialogTitleAction-YEJY2VIX.js} +5 -5
  84. package/{workloadLifecycle-6O6PMISX.js → workloadLifecycle-MZ2V5L43.js} +1 -1
  85. package/chunk-3MZAGMYY.js +0 -239
@@ -9,21 +9,21 @@ import {
9
9
  import {
10
10
  clearCredentialAvailability,
11
11
  markCredentialUnavailable,
12
- readCredentialAvailability,
13
12
  readCredentialEntry,
13
+ readEffectiveCredentialEntry,
14
14
  recordCredentialProbe
15
- } from "./chunk-6MXDOUMH.js";
15
+ } from "./chunk-R4BMKAR5.js";
16
16
  import {
17
17
  agentRunCardLabels,
18
18
  t
19
- } from "./chunk-2AB2HA4M.js";
19
+ } from "./chunk-TDX2L4W2.js";
20
20
  import {
21
21
  defaultLoopbackRequest
22
22
  } from "./chunk-VP3BINY7.js";
23
23
  import {
24
24
  OAUTH_PROVIDER_REFS,
25
25
  buildLocalAgentLookupKeys
26
- } from "./chunk-BL4HFN6L.js";
26
+ } from "./chunk-YL26TH2V.js";
27
27
  import {
28
28
  LOCAL_CODEX_AGENT_ID,
29
29
  LOCAL_CODEX_AGENT_KEY,
@@ -64,7 +64,7 @@ import {
64
64
  import {
65
65
  inlineImageUrlsForCustomProvider,
66
66
  prepareTools
67
- } from "./chunk-DE3RG4GV.js";
67
+ } from "./chunk-FVKOS527.js";
68
68
  import {
69
69
  getServerProviderSecret
70
70
  } from "./chunk-HS7MLR74.js";
@@ -86,18 +86,18 @@ import {
86
86
  resolveCliLocalRuntimeKeyCapability,
87
87
  resolveCliLocalSpawnDispatch,
88
88
  resolveStartAgentRunCwd
89
- } from "./chunk-YTWGTCVW.js";
89
+ } from "./chunk-3WYHEMHF.js";
90
90
  import {
91
91
  deriveCredentialGroup,
92
92
  deriveCustomProviderCredentialGroup
93
- } from "./chunk-WYJTNSVL.js";
93
+ } from "./chunk-XKVWXU6D.js";
94
94
  import {
95
95
  fetchWithTransientRetry,
96
96
  isTransientFetchError
97
97
  } from "./chunk-KFHREHUQ.js";
98
98
  import {
99
99
  resolveAgentRequiredPackIds
100
- } from "./chunk-RBMYJSZF.js";
100
+ } from "./chunk-P46JXWXJ.js";
101
101
  import {
102
102
  applyBuiltinAgentRuntimeOverride,
103
103
  applyTokenUsageToDayStats,
@@ -106,14 +106,14 @@ import {
106
106
  resolveBuiltinPlatformAgentConfig,
107
107
  runKeyed,
108
108
  validateAskChoiceInput
109
- } from "./chunk-OC72ZET2.js";
109
+ } from "./chunk-V2KGGU2X.js";
110
110
  import {
111
111
  BUILTIN_DIALOG_LLM_CHAT_FALLBACK_MODEL,
112
112
  BUILTIN_TITLE_LLM_CONFIG
113
113
  } from "./chunk-523DITKR.js";
114
114
  import {
115
115
  fetchServerSyncedCredential
116
- } from "./chunk-ZKBZLQTG.js";
116
+ } from "./chunk-XGJTJIMA.js";
117
117
  import {
118
118
  isTombstoneRecord
119
119
  } from "./chunk-D2MDMY2M.js";
@@ -170,7 +170,7 @@ import {
170
170
  runExecShellGates,
171
171
  validateConfiguredRootExecutionLease,
172
172
  verifyOwnerRouteAck
173
- } from "./chunk-5E5VB7PS.js";
173
+ } from "./chunk-GHG5ONT5.js";
174
174
  import {
175
175
  accumulateGeminiChunks,
176
176
  buildGeminiGenerateContentRequest,
@@ -193,35 +193,37 @@ import {
193
193
  readPlatformChatSseCompletion,
194
194
  resolvePlatformChatProviderConfig,
195
195
  shouldUsePlatformChatProvider
196
- } from "./chunk-QXZH5UDF.js";
196
+ } from "./chunk-7NKZA46B.js";
197
197
  import {
198
198
  readSseDataValues,
199
199
  readSseFrames
200
200
  } from "./chunk-HNUWUO75.js";
201
201
  import {
202
202
  resolveAgentRuntimeConfigFromRecord
203
- } from "./chunk-ULQAD7ZY.js";
203
+ } from "./chunk-CEXJ6Y3C.js";
204
204
  import {
205
205
  resolveHistoricalToolContentCap
206
- } from "./chunk-U34KT53V.js";
206
+ } from "./chunk-BSKTDOGA.js";
207
207
  import {
208
208
  collectStablePromptPrefix,
209
209
  convertMessagesToResponsesInput,
210
210
  findAgentStatePairingIssues,
211
211
  stablePromptCacheKey,
212
212
  toResponsesTools
213
- } from "./chunk-4L4K6YR7.js";
213
+ } from "./chunk-DI7ZFGDQ.js";
214
214
  import {
215
215
  buildNoloWorkspaceOpenAiTools,
216
+ filterClientNoloWorkspaceToolNames,
216
217
  parseNoloWorkspaceToolArguments,
217
218
  resolveRuntimeToolSurfaceForAgent
218
- } from "./chunk-3M52COK5.js";
219
+ } from "./chunk-SLAZGVZN.js";
219
220
  import {
221
+ isCapacitySaturatedRateLimit,
220
222
  mergeAvailabilityDeadline,
221
223
  resolveAvailabilityAction,
222
224
  resolveCooldownGate,
223
225
  resolveCredentialKeyWithFallback
224
- } from "./chunk-3MZAGMYY.js";
226
+ } from "./chunk-JLR5NWP2.js";
225
227
  import {
226
228
  buildDialogFallbackTitleFromUserInput,
227
229
  normalizeDialogTitle
@@ -229,7 +231,7 @@ import {
229
231
  import {
230
232
  isOAuthApiKeyRef,
231
233
  normalizeUsage
232
- } from "./chunk-F3SOW2EU.js";
234
+ } from "./chunk-HEC32F3G.js";
233
235
  import {
234
236
  isDevinOAuthAgent
235
237
  } from "./chunk-5ZUL4CUO.js";
@@ -239,7 +241,7 @@ import {
239
241
  observeMeaningfulProviderResponse,
240
242
  observeMeaningfulProviderResponseAt,
241
243
  withProviderCallTimingFields
242
- } from "./chunk-QA2C5NKI.js";
244
+ } from "./chunk-ASSNAASW.js";
243
245
  import {
244
246
  clipCompactText
245
247
  } from "./chunk-5MMAK75Q.js";
@@ -1186,7 +1188,9 @@ function buildOpenAiTools(args) {
1186
1188
  }),
1187
1189
  ...buildCliChromeConnectorOpenAiTools({ toolNames: args.toolNames }),
1188
1190
  ...buildServerPlatformOpenAiTools({ toolNames: args.toolNames }),
1189
- ...buildNoloWorkspaceOpenAiTools({ toolNames: args.toolNames }),
1191
+ ...buildNoloWorkspaceOpenAiTools({
1192
+ toolNames: filterClientNoloWorkspaceToolNames(args.toolNames)
1193
+ }),
1190
1194
  ...buildOrchestrationOpenAiTools({
1191
1195
  toolNameSet,
1192
1196
  env: args.env
@@ -3550,6 +3554,19 @@ async function readStructuredErrorCode(response) {
3550
3554
  }
3551
3555
  }
3552
3556
  async function shouldRetryOwnerProxyResponse(response) {
3557
+ if (response.status === 429) {
3558
+ try {
3559
+ let body;
3560
+ try {
3561
+ body = await response.clone().json();
3562
+ } catch {
3563
+ body = await response.clone().text();
3564
+ }
3565
+ return isCapacitySaturatedRateLimit(body, Date.now(), response.headers);
3566
+ } catch {
3567
+ return false;
3568
+ }
3569
+ }
3553
3570
  if (response.status === 503) {
3554
3571
  try {
3555
3572
  const body = await response.clone().json();
@@ -9538,8 +9555,8 @@ async function createLocalDockerWorkload(args) {
9538
9555
  }
9539
9556
  const createLifecycle = args.createLifecycle ?? (async () => {
9540
9557
  const [{ DockerWorkloadLifecycle, createDockerBindingAuthorizer }, accounts] = await Promise.all([
9541
- import("./workloadLifecycle-6O6PMISX.js"),
9542
- import("./accountResolver-55EDKEIK.js")
9558
+ import("./workloadLifecycle-MZ2V5L43.js"),
9559
+ import("./accountResolver-JS7QDNNL.js")
9543
9560
  ]);
9544
9561
  const resolveAccount = args.resolveAccount ?? accounts.createDockerAccountResolver({
9545
9562
  env: args.env,
@@ -11836,6 +11853,65 @@ var isJsBundle = extname(currentMetaFile) === ".js";
11836
11853
  var SOURCE_CLI_DIR = isJsBundle ? dirname4(currentMetaFile) : dirname4(dirname4(currentMetaFile));
11837
11854
  var CLI_DIR = isCompiledBinary() ? dirname4(process.execPath) : SOURCE_CLI_DIR;
11838
11855
  var CLI_ENTRYPOINT = isCompiledBinary() ? process.execPath : isJsBundle ? currentMetaFile : join6(SOURCE_CLI_DIR, "index.ts");
11856
+ var KNOWN_HINT_LABELS = /* @__PURE__ */ new Map([
11857
+ ["usage_limit_reached", "usage-limit"],
11858
+ ["rate_limit_exceeded", "rate-limit"],
11859
+ ["insufficient_quota", "insufficient-quota"],
11860
+ ["quota_exceeded", "quota-exceeded"],
11861
+ ["invalid_request_error", "invalid-request"],
11862
+ ["authentication_error", "auth"],
11863
+ ["permission_denied", "permission-denied"],
11864
+ ["model_not_found", "model-not-found"],
11865
+ ["context_length_exceeded", "context-length"],
11866
+ ["proxy_failed", "proxy-failed"],
11867
+ ["upstream_transport_error", "upstream-transport"],
11868
+ ["core_draining", "core-draining"],
11869
+ ["owner_origin_mismatch", "owner-origin-mismatch"],
11870
+ ["overloaded", "overloaded"],
11871
+ ["capacity", "capacity"]
11872
+ ]);
11873
+ function hintLabelOf(raw) {
11874
+ return KNOWN_HINT_LABELS.get(raw.trim().toLowerCase());
11875
+ }
11876
+ function collectSafeHints(body, out = [], depth = 0) {
11877
+ if (depth > 2 || out.length >= 3) return out;
11878
+ if (Array.isArray(body)) {
11879
+ for (const item of body) collectSafeHints(item, out, depth + 1);
11880
+ return out;
11881
+ }
11882
+ if (!body || typeof body !== "object") return out;
11883
+ for (const [k, v] of Object.entries(body)) {
11884
+ const normalizedKey = k.toLowerCase().replace(/[-_]/g, "");
11885
+ if ((normalizedKey === "code" || normalizedKey === "type") && typeof v === "string") {
11886
+ const label = hintLabelOf(v);
11887
+ if (label && out.length < 3 && !out.includes(label)) {
11888
+ out.push(label);
11889
+ }
11890
+ } else if (v && typeof v === "object") {
11891
+ collectSafeHints(v, out, depth + 1);
11892
+ }
11893
+ }
11894
+ return out;
11895
+ }
11896
+ function buildSafeBodyPreview(body, classification = "unknown") {
11897
+ try {
11898
+ const serialized = typeof body === "string" ? body : JSON.stringify(body ?? "");
11899
+ const hints = collectSafeHints(body);
11900
+ const parts = [`class=${classification}`, `len=${serialized.length}`];
11901
+ if (hints.length > 0) parts.push(`hints=${hints.join("|")}`);
11902
+ return parts.join(" ");
11903
+ } catch {
11904
+ return void 0;
11905
+ }
11906
+ }
11907
+ function formatSafeIsoDeadline(epochMs) {
11908
+ try {
11909
+ const d = new Date(epochMs);
11910
+ return Number.isFinite(d.getTime()) ? d.toISOString() : "";
11911
+ } catch {
11912
+ return "";
11913
+ }
11914
+ }
11839
11915
  async function recordLocalAvailabilityForAgent(args) {
11840
11916
  const now = args.now ?? Date.now;
11841
11917
  const { deps, status } = args;
@@ -11845,6 +11921,39 @@ async function recordLocalAvailabilityForAgent(args) {
11845
11921
  const action = resolveAvailabilityAction(status, args.body, now());
11846
11922
  if (action.kind === "noop") return void 0;
11847
11923
  const credentialKey = resolveCredentialKeyWithFallback(agentConfig);
11924
+ try {
11925
+ if (action.kind === "mark") {
11926
+ const payload = {
11927
+ agentKey: key,
11928
+ credentialKey,
11929
+ status,
11930
+ nextAvailableAt: action.nextAvailableAt,
11931
+ nextAvailableAtIso: formatSafeIsoDeadline(action.nextAvailableAt)
11932
+ };
11933
+ const bodyClass = (() => {
11934
+ try {
11935
+ if (status === 429) {
11936
+ return isCapacitySaturatedRateLimit(args.body, now()) ? "capacity-saturated" : "quota-or-unknown";
11937
+ }
11938
+ return status >= 500 ? "server-error" : "other";
11939
+ } catch {
11940
+ return "unclassified";
11941
+ }
11942
+ })();
11943
+ const bodyPreview = buildSafeBodyPreview(args.body, bodyClass);
11944
+ if (bodyPreview !== void 0) {
11945
+ payload.bodyPreview = bodyPreview;
11946
+ }
11947
+ logLocalRuntimeDiagnostic("availability.mark", payload);
11948
+ } else if (action.kind === "clear") {
11949
+ logLocalRuntimeDiagnostic("availability.clear", {
11950
+ agentKey: key,
11951
+ credentialKey,
11952
+ status
11953
+ });
11954
+ }
11955
+ } catch {
11956
+ }
11848
11957
  if (credentialKey) {
11849
11958
  if (action.kind === "mark") {
11850
11959
  await markCredentialUnavailable(
@@ -12464,8 +12573,10 @@ function createCliLocalRuntimeAdapter(deps) {
12464
12573
  const credentialKeyForGate = resolveCredentialKeyWithFallback(
12465
12574
  agentConfig
12466
12575
  );
12467
- const credentialCooldowns = credentialKeyForGate ? await readCredentialAvailability(deps.env, nowMs).catch(() => ({})) : {};
12468
- const credentialCooldownAt = credentialKeyForGate ? credentialCooldowns[credentialKeyForGate] : void 0;
12576
+ const gateEntry = credentialKeyForGate ? await readEffectiveCredentialEntry(credentialKeyForGate, deps.env, nowMs).catch(
12577
+ () => void 0
12578
+ ) : void 0;
12579
+ const credentialCooldownAt = gateEntry?.nextAvailableAt;
12469
12580
  const agentLevelNextAvailableAt = agentConfig.nextAvailableAt;
12470
12581
  const effectiveNextAvailableAt = typeof credentialCooldownAt === "number" ? mergeAvailabilityDeadline(
12471
12582
  agentLevelNextAvailableAt,
@@ -12478,9 +12589,6 @@ function createCliLocalRuntimeAdapter(deps) {
12478
12589
  body,
12479
12590
  now
12480
12591
  }).then(() => void 0);
12481
- const gateEntry = credentialKeyForGate ? await readCredentialEntry(credentialKeyForGate, deps.env, nowMs).catch(
12482
- () => void 0
12483
- ) : void 0;
12484
12592
  const gateDecision = resolveCooldownGate(
12485
12593
  {
12486
12594
  nextAvailableAt: effectiveNextAvailableAt,
@@ -12493,8 +12601,9 @@ function createCliLocalRuntimeAdapter(deps) {
12493
12601
  `agent temporarily unavailable until ${new Date(Number(effectiveNextAvailableAt)).toISOString()}`
12494
12602
  );
12495
12603
  }
12496
- if (gateDecision === "probe" && credentialKeyForGate) {
12497
- await recordCredentialProbe(credentialKeyForGate, deps.env, nowMs).catch(
12604
+ const activeKeyForGate = gateEntry?.matchedKey || credentialKeyForGate;
12605
+ if (gateDecision === "probe" && activeKeyForGate) {
12606
+ await recordCredentialProbe(activeKeyForGate, deps.env, nowMs).catch(
12498
12607
  () => void 0
12499
12608
  );
12500
12609
  }
@@ -12845,6 +12954,7 @@ export {
12845
12954
  saveCliDialogSummary,
12846
12955
  loadCliDialogLastContextUsage,
12847
12956
  resolveLocalInstaboxToolRoute,
12957
+ buildSafeBodyPreview,
12848
12958
  recordLocalAvailabilityForAgent,
12849
12959
  setCliAutoCompactionSummaryFallback,
12850
12960
  getCliAutoCompactionSummaryFallback,
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VYNMQ6HW.js";
9
9
  import {
10
10
  fetchAndCacheTableRows
11
- } from "./chunk-ZMVXHANW.js";
11
+ } from "./chunk-STFIUL6J.js";
12
12
  import {
13
13
  require_react
14
14
  } from "./chunk-YDH3FDFQ.js";
@@ -521,7 +521,7 @@ var executeToolRun = createAsyncThunk(
521
521
  if (!executionInput) {
522
522
  throw new Error(`ToolRun ${id} has no input to execute with.`);
523
523
  }
524
- const { findToolExecutor } = await import("./tools-AEPUZOZ2.js");
524
+ const { findToolExecutor } = await import("./tools-YQIMXETR.js");
525
525
  const { executor } = findToolExecutor(run.toolName);
526
526
  toolRunStarted({
527
527
  id: run.id,
@@ -2,7 +2,7 @@ import {
2
2
  clipMultilineText,
3
3
  fetchAndSerializeTable,
4
4
  waitForAbortableDelay
5
- } from "./chunk-RBMYJSZF.js";
5
+ } from "./chunk-P46JXWXJ.js";
6
6
  import {
7
7
  isGatewayHttpStatus
8
8
  } from "./chunk-NF64D32W.js";
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-AGIM7IMJ.js";
22
22
  import {
23
23
  fetchAndCacheMessages
24
- } from "./chunk-OC72ZET2.js";
24
+ } from "./chunk-V2KGGU2X.js";
25
25
  import {
26
26
  createSpaceKey
27
27
  } from "./chunk-UAD2WT54.js";
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  mergeAvailabilityDeadline,
3
+ resolveCredentialCandidateKeys,
3
4
  resolveCredentialKeyWithFallback
4
- } from "./chunk-3MZAGMYY.js";
5
+ } from "./chunk-JLR5NWP2.js";
5
6
 
6
7
  // packages/agent-runtime/credentialAvailability.ts
7
8
  import { homedir } from "node:os";
@@ -66,10 +67,56 @@ async function readCredentialAvailability(env = process.env, now = Date.now()) {
66
67
  Object.entries(entries).map(([key, entry]) => [key, entry.nextAvailableAt])
67
68
  );
68
69
  }
69
- async function readCredentialEntry(credentialKey, env = process.env, now = Date.now()) {
70
+ async function readEffectiveCredentialEntry(credentialKey, env = process.env, now = Date.now()) {
70
71
  if (!credentialKey) return void 0;
72
+ const candidates = resolveCredentialCandidateKeys(credentialKey);
73
+ if (candidates.length === 0) return void 0;
71
74
  const entries = await readCredentialEntries(env, now);
72
- return entries[credentialKey];
75
+ let effectiveEntry;
76
+ const activeCandidates = [];
77
+ for (const key of candidates) {
78
+ const entry = entries[key];
79
+ if (!entry || entry.nextAvailableAt <= now) continue;
80
+ activeCandidates.push({ key, markedAt: entry.markedAt });
81
+ if (!effectiveEntry) {
82
+ effectiveEntry = { ...entry, matchedKey: key };
83
+ } else {
84
+ const mergedDeadline = mergeAvailabilityDeadline(
85
+ effectiveEntry.nextAvailableAt,
86
+ entry.nextAvailableAt
87
+ );
88
+ const mergedProbe = effectiveEntry.lastProbeAt !== void 0 || entry.lastProbeAt !== void 0 ? Math.max(effectiveEntry.lastProbeAt ?? 0, entry.lastProbeAt ?? 0) : void 0;
89
+ const mergedMarkedAt = effectiveEntry.markedAt !== void 0 || entry.markedAt !== void 0 ? Math.max(effectiveEntry.markedAt ?? 0, entry.markedAt ?? 0) : void 0;
90
+ effectiveEntry = {
91
+ nextAvailableAt: mergedDeadline ?? entry.nextAvailableAt,
92
+ ...mergedMarkedAt !== void 0 ? { markedAt: mergedMarkedAt } : {},
93
+ ...mergedProbe !== void 0 ? { lastProbeAt: mergedProbe } : {},
94
+ matchedKey: effectiveEntry.matchedKey
95
+ };
96
+ }
97
+ }
98
+ if (effectiveEntry) {
99
+ effectiveEntry.candidates = activeCandidates;
100
+ }
101
+ return effectiveEntry;
102
+ }
103
+ function resolveEffectiveCredentialCooldown(credentialKey, credentialAvailability, now = 0) {
104
+ if (!credentialKey) return void 0;
105
+ const candidates = resolveCredentialCandidateKeys(credentialKey);
106
+ let effective;
107
+ for (const key of candidates) {
108
+ const at = credentialAvailability[key];
109
+ if (typeof at === "number" && Number.isFinite(at) && (now === 0 || at > now)) {
110
+ effective = mergeAvailabilityDeadline(effective, at);
111
+ }
112
+ }
113
+ return effective;
114
+ }
115
+ async function readCredentialEntry(credentialKey, env = process.env, now = Date.now()) {
116
+ const effective = await readEffectiveCredentialEntry(credentialKey, env, now);
117
+ if (!effective) return void 0;
118
+ const { matchedKey, candidates, ...entry } = effective;
119
+ return entry;
73
120
  }
74
121
  async function writeCredentialAvailability(live, env = process.env) {
75
122
  const path = resolveCredentialAvailabilityPath(env);
@@ -106,16 +153,30 @@ async function clearCredentialAvailabilityIfMarkedAt(credentialKey, expectedMark
106
153
  async function clearCredentialAvailability(credentialKey, env = process.env, now = Date.now()) {
107
154
  if (!credentialKey) return;
108
155
  const live = await readCredentialEntries(env, now);
109
- if (!(credentialKey in live)) return;
110
- delete live[credentialKey];
156
+ const candidates = resolveCredentialCandidateKeys(credentialKey);
157
+ let changed = false;
158
+ for (const key of candidates) {
159
+ if (key in live) {
160
+ delete live[key];
161
+ changed = true;
162
+ }
163
+ }
164
+ if (!changed) return;
111
165
  await writeCredentialAvailability(live, env);
112
166
  }
113
167
  async function recordCredentialProbe(credentialKey, env = process.env, now = Date.now()) {
114
168
  if (!credentialKey) return;
115
169
  const live = await readCredentialEntries(env, now);
116
- const existing = live[credentialKey];
170
+ let targetKey = credentialKey;
171
+ if (!(targetKey in live)) {
172
+ const candidates = resolveCredentialCandidateKeys(credentialKey);
173
+ const found = candidates.find((k) => k in live);
174
+ if (!found) return;
175
+ targetKey = found;
176
+ }
177
+ const existing = live[targetKey];
117
178
  if (!existing) return;
118
- live[credentialKey] = { ...existing, lastProbeAt: now };
179
+ live[targetKey] = { ...existing, lastProbeAt: now };
119
180
  await writeCredentialAvailability(live, env);
120
181
  }
121
182
  function applyCredentialAvailability(agents, credentialAvailability) {
@@ -123,7 +184,7 @@ function applyCredentialAvailability(agents, credentialAvailability) {
123
184
  return agents.map((agent) => {
124
185
  const key = resolveCredentialKeyWithFallback(agent);
125
186
  if (!key) return agent;
126
- const at = credentialAvailability[key];
187
+ const at = resolveEffectiveCredentialCooldown(key, credentialAvailability);
127
188
  if (typeof at !== "number") return agent;
128
189
  const merged = mergeAvailabilityDeadline(
129
190
  agent.nextAvailableAt,
@@ -138,6 +199,7 @@ function applyCredentialAvailability(agents, credentialAvailability) {
138
199
 
139
200
  export {
140
201
  readCredentialAvailability,
202
+ readEffectiveCredentialEntry,
141
203
  readCredentialEntry,
142
204
  markCredentialUnavailable,
143
205
  clearCredentialAvailabilityIfMarkedAt,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  shouldUseServerProxy
3
- } from "./chunk-F3SOW2EU.js";
3
+ } from "./chunk-HEC32F3G.js";
4
4
  import {
5
5
  ANTIGRAVITY_CLOUD_CODE_BASE_URL,
6
6
  isAntigravityCloudCodeBaseUrl,
@@ -36,7 +36,11 @@ var DEFAULT_PRIVATE_NOLO_WORKSPACE_TOOLS = [
36
36
  "listTables",
37
37
  "queryTableRows",
38
38
  "cliWhoami",
39
- "cliDoctor"
39
+ "cliDoctor",
40
+ "list_cloud_resources",
41
+ "cloud_probe"
42
+ // cloud_exec 故意不在此清单:硬边界是「永不默认开 exec」。它只在 agent 显式启用时出现,
43
+ // 且只读 run 会被 HIGH_RISK_MUTATION_TOOL_NAMES 挡住(runtimeToolSurface.test.ts 钉住)。
40
44
  ];
41
45
  var DEFAULT_SUBTASK_REFERENCE_NOLO_WORKSPACE_TOOLS = [
42
46
  "readDialog",
@@ -72,7 +76,11 @@ var HIGH_RISK_MUTATION_TOOL_NAMES = [
72
76
  // 编排副作用:startAgentRun 会另起一次 run(子 run 的只读与否由调用方参数决定),
73
77
  // controlAgentRun 能追加指令/停止它;只读 run 不应拿到这两个(review A-1)。
74
78
  "startAgentRun",
75
- "controlAgentRun"
79
+ "controlAgentRun",
80
+ // 受控云端执行:在用户拥有的云资源上跑任意命令,不可重放、副作用在云端。
81
+ // 硬边界:它永不进 DEFAULT_PRIVATE_NOLO_WORKSPACE_TOOLS(见该清单注释),
82
+ // 必须由 agent 显式启用才出现;这里进名单保证只读 run 即使被显式要求也拿不到。
83
+ "cloud_exec"
76
84
  ];
77
85
  function resolveReadOnlyToolConstraints(additionalBlockedTools) {
78
86
  return {
@@ -770,9 +778,33 @@ var NOLO_WORKSPACE_TOOL_NAMES = [
770
778
  "listTables",
771
779
  "queryTableRows",
772
780
  "cliWhoami",
773
- "cliDoctor"
781
+ "cliDoctor",
782
+ "list_cloud_resources",
783
+ "cloud_probe",
784
+ "cloud_exec"
774
785
  ];
786
+ var SERVER_ONLY_NOLO_WORKSPACE_TOOL_NAMES = [
787
+ "list_cloud_resources",
788
+ "cloud_probe",
789
+ "cloud_exec"
790
+ ];
791
+ var SERVER_ONLY_NOLO_WORKSPACE_TOOL_NAME_SET = new Set(SERVER_ONLY_NOLO_WORKSPACE_TOOL_NAMES);
792
+ function isServerOnlyNoloWorkspaceTool(name) {
793
+ return SERVER_ONLY_NOLO_WORKSPACE_TOOL_NAME_SET.has(name);
794
+ }
795
+ var CLI_NOLO_WORKSPACE_TOOL_NAMES = NOLO_WORKSPACE_TOOL_NAMES.filter(
796
+ (name) => !isServerOnlyNoloWorkspaceTool(name)
797
+ );
798
+ function filterClientNoloWorkspaceToolNames(toolNames) {
799
+ if (!toolNames) return [...CLI_NOLO_WORKSPACE_TOOL_NAMES];
800
+ return toolNames.filter((name) => !isServerOnlyNoloWorkspaceTool(name));
801
+ }
775
802
  var NOLO_WORKSPACE_TOOL_NAME_SET = new Set(NOLO_WORKSPACE_TOOL_NAMES);
803
+ var CLOSED_OBJECT_SCHEMA_TOOL_NAMES = /* @__PURE__ */ new Set([
804
+ "list_cloud_resources",
805
+ "cloud_probe",
806
+ "cloud_exec"
807
+ ]);
776
808
  var DIALOG_ID_RE = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
777
809
  var DIALOG_PATH_RE = /^\/(?:space\/([^/]+)\/)?dialog-(.+)-([0-9A-HJKMNP-TV-Z]{26})\/?$/i;
778
810
  function stringToolParam(description) {
@@ -791,6 +823,7 @@ function buildNoloWorkspaceOpenAiTools(args) {
791
823
  parameters: {
792
824
  type: "object",
793
825
  properties,
826
+ ...CLOSED_OBJECT_SCHEMA_TOOL_NAMES.has(name) ? { additionalProperties: false } : {},
794
827
  ...required.length ? { required } : {}
795
828
  }
796
829
  }
@@ -875,6 +908,39 @@ function buildNoloWorkspaceOpenAiTools(args) {
875
908
  }, ["table"]);
876
909
  add("cliWhoami", "Show the current Nolo CLI login state.", {});
877
910
  add("cliDoctor", "Show Nolo CLI doctor diagnostics.", {});
911
+ add("list_cloud_resources", "List accessible cloud resources for personal or organization scope. Never outputs credentials.", {
912
+ ownerKind: {
913
+ type: "string",
914
+ enum: ["user", "organization"],
915
+ description: "Owner scope kind. Defaults to user (caller)."
916
+ },
917
+ organizationId: stringToolParam("Required when ownerKind is organization."),
918
+ platformId: stringToolParam("Optional cloud platform filter (e.g. docker, cloudflare, gcp).")
919
+ });
920
+ add("cloud_probe", "Probe read-only connectivity and readiness of a cloud resource. Never accepts credential parameters.", {
921
+ resourceId: stringToolParam("Target cloud resource ID to probe.")
922
+ }, ["resourceId"]);
923
+ add("cloud_exec", 'Execute a shell task on an owned cloud resource through the server execution gate (authorization \u2192 capability \u2192 idempotent single-flight \u2192 audit \u2192 adapter). Never accepts credential parameters; refusals come back as { status: "blocked", reasonCode } instead of throwing.', {
924
+ resourceId: stringToolParam("Target cloud resource ID the caller owns or may use."),
925
+ task: {
926
+ type: "object",
927
+ properties: {
928
+ kind: { type: "string", enum: ["shell"], description: "Task kind. Only shell is supported." },
929
+ argv: {
930
+ type: "array",
931
+ items: { type: "string" },
932
+ description: "Command and arguments: 1..32 items, each at most 512 characters, no NUL."
933
+ },
934
+ timeoutMs: {
935
+ type: "integer",
936
+ description: "Optional timeout in milliseconds, clamped to 1000..120000."
937
+ }
938
+ },
939
+ additionalProperties: false,
940
+ required: ["kind", "argv"]
941
+ },
942
+ idempotencyKey: stringToolParam("Caller idempotency key, 8..128 characters of [A-Za-z0-9_.:-]; a concurrent duplicate is rejected.")
943
+ }, ["resourceId", "task", "idempotencyKey"]);
878
944
  return tools;
879
945
  }
880
946
  function noloPositiveIntegerString(value) {
@@ -1428,6 +1494,8 @@ export {
1428
1494
  BRIDGE_STREAM_MAX_CHARS,
1429
1495
  readTextStreamUpToChars,
1430
1496
  NOLO_WORKSPACE_TOOL_NAMES,
1497
+ CLI_NOLO_WORKSPACE_TOOL_NAMES,
1498
+ filterClientNoloWorkspaceToolNames,
1431
1499
  buildNoloWorkspaceOpenAiTools,
1432
1500
  noloPositiveIntegerString,
1433
1501
  noloStringArg,
@@ -2,7 +2,7 @@ import {
2
2
  deleteDialog,
3
3
  runtime_default,
4
4
  toast
5
- } from "./chunk-OC72ZET2.js";
5
+ } from "./chunk-V2KGGU2X.js";
6
6
  import {
7
7
  getCurrentSpaceId,
8
8
  getCurrentSpaceIdRaw,
@@ -180,8 +180,8 @@ var STRINGS = {
180
180
  zh: "\u672C\u6B21\u56DE\u590D\u51FA\u9519\u3002\u5DF2\u6392\u961F\u7684\u6D88\u606F\u4ECD\u4FDD\u7559\uFF0C\u6309 Enter \u53EF\u91CD\u65B0\u53D1\u9001\u3002"
181
181
  },
182
182
  quotaExhaustedHint: {
183
- en: "This agent seems to have hit a quota/rate limit (HTTP 429).\nUse /agent to switch to another agent and keep going \u2014 the dialog context is preserved.",
184
- zh: "\u5F53\u524D agent \u4F3C\u4E4E\u989D\u5EA6/\u901F\u7387\u53D7\u9650\uFF08429\uFF09\u3002\n\u53EF\u4EE5\u7528 /agent \u5207\u6362\u5230\u5176\u4ED6 agent \u540E\u7EE7\u7EED\uFF0C\u540C\u4E00\u5BF9\u8BDD\u4F1A\u4FDD\u7559\u4E0A\u4E0B\u6587\u3002"
183
+ en: "This agent is temporarily unavailable (HTTP 429).\nUse /agent to switch to another agent and keep going \u2014 the dialog context is preserved.",
184
+ zh: "\u5F53\u524D agent \u6682\u65F6\u4E0D\u53EF\u7528\uFF08HTTP 429\uFF09\u3002\n\u53EF\u4EE5\u7528 /agent \u5207\u6362\u5230\u5176\u4ED6 agent \u540E\u7EE7\u7EED\uFF0C\u540C\u4E00\u5BF9\u8BDD\u4F1A\u4FDD\u7559\u4E0A\u4E0B\u6587\u3002"
185
185
  },
186
186
  balanceExhaustedHint: {
187
187
  en: 'Your message is saved in this dialog \u2014 top up, then send again or say "continue" to pick up where you left off.',
@@ -406,6 +406,12 @@ var STRINGS = {
406
406
  en: "[nolo] Upstream rate limit ({0}): {1}",
407
407
  zh: "[nolo] \u4E0A\u6E38\u9650\u6D41\uFF08{0}\uFF09\uFF1A{1}"
408
408
  },
409
+ // 上游明确表示「服务容量饱和」(如 Codex 的 "is at capacity")。这与账号额度
410
+ // 无关,用「额度」措辞会让人误以为是自己配额用完了。单独一档。
411
+ localRunRateLimitCapacity: {
412
+ en: "[nolo] Upstream service at capacity ({0}): {1}",
413
+ zh: "[nolo] \u4E0A\u6E38\u670D\u52A1\u5BB9\u91CF\u9971\u548C\uFF08{0}\uFF09\uFF1A{1}"
414
+ },
409
415
  // 第 2 行复位提示:沿用 extractRateLimitResetHint 抓到的上游原文(不换算),
410
416
  // 只作括号补充;没抓到就没有这段括号。
411
417
  localRunRateLimitResetNote: {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  readDbRecord,
3
3
  writeAgentRecord
4
- } from "./chunk-5IKRTRRR.js";
4
+ } from "./chunk-MCGCC5BA.js";
5
5
  import {
6
6
  buildSkillSummaryMarker
7
7
  } from "./chunk-VF4K2QE6.js";