nolo-cli 0.1.30 → 0.1.31

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 (308) hide show
  1. package/agent-runtime/agentRecordConfig.ts +0 -2
  2. package/agent-runtime/hostAdapter.ts +0 -1
  3. package/agent-runtime/hostRuntimeCapabilities.ts +7 -0
  4. package/agent-runtime/hostRuntimeConfig.ts +86 -0
  5. package/agent-runtime/index.ts +13 -0
  6. package/agent-runtime/localToolPolicy.ts +13 -6
  7. package/agent-runtime/localWorkspaceTools.ts +333 -30
  8. package/agent-runtime/platformChatProvider.ts +4 -1
  9. package/agent-runtime/runtimeToolPolicy.ts +32 -47
  10. package/agent-runtime/shellCommandPolicy.ts +117 -0
  11. package/agent-runtime/toolGate.ts +38 -0
  12. package/agentRecordCommands.ts +1 -1
  13. package/agentRecordHelpers.ts +35 -20
  14. package/agentRunParsing.ts +18 -5
  15. package/agentRuntimeLocal.ts +10 -0
  16. package/ai/agent/agentRunDialogLineage.ts +56 -0
  17. package/ai/agent/agentSlice.ts +45 -10
  18. package/ai/agent/avatarUtils.ts +1 -1
  19. package/ai/agent/buildSystemPrompt.ts +1 -2
  20. package/ai/agent/cliExecutor.ts +330 -19
  21. package/ai/agent/createAgentSchema.ts +22 -0
  22. package/ai/agent/hooks/fetchPublicAgents.ts +14 -39
  23. package/ai/agent/hooks/usePublicAgents.ts +90 -192
  24. package/ai/agent/publicAgentCatalog.ts +359 -0
  25. package/ai/agent/publicAgentIdentity.ts +76 -0
  26. package/ai/agent/server/fetchPublicAgents.ts +21 -46
  27. package/ai/agent/serverOrigin.ts +7 -0
  28. package/ai/agent/streamAgentChatTurn.ts +23 -21
  29. package/ai/agent/streamAgentChatTurnUtils.ts +292 -6
  30. package/ai/agent/types.ts +2 -0
  31. package/ai/agent/web/agentDisplayUtils.ts +171 -0
  32. package/ai/agent/web/useAgentModelAvatarComponent.ts +32 -0
  33. package/ai/ai.locale.ts +8 -0
  34. package/ai/chat/sendOpenAICompletionsRequest.native.ts +15 -0
  35. package/ai/chat/sendOpenAICompletionsRequest.ts +93 -1
  36. package/ai/chat/sendOpenAIResponseRequest.ts +86 -9
  37. package/ai/chat/updateTotalUsage.ts +7 -0
  38. package/ai/llm/deepinfra.ts +30 -15
  39. package/ai/llm/mistral.ts +3 -4
  40. package/ai/llm/providers.ts +2 -0
  41. package/ai/llm/types.ts +15 -0
  42. package/ai/memory/capture.ts +3 -3
  43. package/ai/memory/consolidate.ts +2 -2
  44. package/ai/memory/delete.ts +4 -3
  45. package/ai/memory/query.ts +3 -3
  46. package/ai/memory/remember.ts +2 -2
  47. package/ai/memory/store.ts +3 -3
  48. package/ai/memory/storeShared.ts +3 -2
  49. package/ai/policy/commercialMultiplier.ts +16 -0
  50. package/ai/token/billingAdminAuditEvent.ts +68 -0
  51. package/ai/token/billingAdminAuditEventWriter.ts +41 -0
  52. package/ai/token/billingAnomaly.ts +90 -0
  53. package/ai/token/billingAnomalyLifecycle.ts +54 -0
  54. package/ai/token/billingAnomalyLifecycleWriter.ts +44 -0
  55. package/ai/token/billingAnomalyWriter.ts +41 -0
  56. package/ai/token/calculatePrice.ts +3 -2
  57. package/ai/token/deepinfraReconciliation.ts +153 -0
  58. package/ai/token/deepinfraRequestIdQuery.ts +92 -0
  59. package/ai/token/externalToolCost.ts +54 -41
  60. package/ai/token/missingUsageEstimate.ts +12 -3
  61. package/ai/token/normalizeUsage.ts +45 -5
  62. package/ai/token/openaiReconciliation.ts +188 -0
  63. package/ai/token/providerBillableEvent.ts +84 -0
  64. package/ai/token/providerBillableEventWriter.ts +36 -0
  65. package/ai/token/providerBillingAnomalyDrilldown.ts +308 -0
  66. package/ai/token/providerBillingDrilldown.ts +361 -0
  67. package/ai/token/providerBillingHealthReport.ts +366 -0
  68. package/ai/token/providerCall.ts +144 -0
  69. package/ai/token/providerCallSweeper.ts +168 -0
  70. package/ai/token/providerCallWriter.ts +33 -0
  71. package/ai/token/providerCredential.ts +89 -0
  72. package/ai/token/providerCredentialAnomaly.ts +154 -0
  73. package/ai/token/providerCredentialLifecycle.ts +59 -0
  74. package/ai/token/providerCredentialLifecycleWriter.ts +44 -0
  75. package/ai/token/providerCredentialRegistry.ts +83 -0
  76. package/ai/token/providerCredentialRegistryCommand.ts +97 -0
  77. package/ai/token/providerCredentialRegistryList.ts +124 -0
  78. package/ai/token/providerCredentialRegistryResolver.ts +150 -0
  79. package/ai/token/providerCredentialRegistryWriter.ts +41 -0
  80. package/ai/token/providerCredentialRotationCommand.ts +102 -0
  81. package/ai/token/providerCredentialRuntime.ts +56 -0
  82. package/ai/token/providerDispatchIntent.ts +67 -0
  83. package/ai/token/providerDispatchIntentWriter.ts +36 -0
  84. package/ai/token/providerGateway.ts +260 -0
  85. package/ai/token/providerReconciliation.ts +148 -0
  86. package/ai/token/providerReconciliationLocal.ts +97 -0
  87. package/ai/token/providerReconciliationRunner.ts +165 -0
  88. package/ai/token/providerReconciliationWriter.ts +41 -0
  89. package/ai/token/ratingResult.ts +202 -0
  90. package/ai/token/ratingResultWriter.ts +33 -0
  91. package/ai/token/serverDialogProjection.ts +5 -3
  92. package/ai/token/serverTokenWriter.ts +11 -3
  93. package/ai/token/types.ts +10 -0
  94. package/ai/tools/agent/callAgentTool.ts +3 -4
  95. package/ai/tools/agent/presets/appBuilderPreset.ts +5 -7
  96. package/ai/tools/agent/runStreamingAgentTool.ts +1 -2
  97. package/ai/tools/agent/streamParallelAgentsTool.ts +2 -3
  98. package/ai/tools/readXPostTool.ts +1 -5
  99. package/app/admin/adminPages.ts +9 -0
  100. package/app/i18n/i18n.config.ts +5 -0
  101. package/app/i18n/translations/pricing.locale.ts +397 -0
  102. package/app/utils/desktopAgentRuntimeStatusClient.ts +5 -4
  103. package/app/utils/desktopAgentRuntimeTurnClient.ts +4 -1
  104. package/app/utils/imageUtils.ts +64 -34
  105. package/auth/adminPermissions.ts +18 -0
  106. package/auth/authSlice.ts +26 -12
  107. package/auth/hooks/useFetchUsers.ts +3 -0
  108. package/auth/routes.ts +46 -0
  109. package/auth/server/accessActivity.ts +4 -3
  110. package/auth/server/adminPermissions.ts +43 -0
  111. package/auth/server/adminUsageReport.ts +375 -0
  112. package/auth/server/billingAnomalies.ts +235 -0
  113. package/auth/server/billingUsageReport.ts +41 -2
  114. package/auth/server/creatorEarningCreditConversion.ts +10 -2
  115. package/auth/server/deduct.ts +14 -7
  116. package/auth/server/delete.ts +10 -2
  117. package/auth/server/disable.ts +4 -3
  118. package/auth/server/emailAutomation.ts +7 -5
  119. package/auth/server/emailDbConfig.ts +4 -2
  120. package/auth/server/emailDelivery.ts +24 -20
  121. package/auth/server/emailDeliveryGuards.ts +10 -7
  122. package/auth/server/emailPreferences.ts +6 -4
  123. package/auth/server/emailReport.ts +6 -4
  124. package/auth/server/emailRuntimeConfig.ts +3 -3
  125. package/auth/server/emailScenarioNotifications.ts +9 -8
  126. package/auth/server/enable.ts +4 -3
  127. package/auth/server/getRechargeHistory.ts +3 -2
  128. package/auth/server/getUser.ts +3 -2
  129. package/auth/server/gptProAccess.ts +44 -0
  130. package/auth/server/inviteReward.ts +10 -7
  131. package/auth/server/listusers.ts +6 -4
  132. package/auth/server/login.ts +2 -2
  133. package/auth/server/productEntitlements.ts +7 -4
  134. package/auth/server/productPurchase.ts +10 -2
  135. package/auth/server/providerBillingDrilldown.ts +47 -0
  136. package/auth/server/providerBillingHealth.ts +71 -0
  137. package/auth/server/providerCredentials.ts +136 -0
  138. package/auth/server/recharge.ts +14 -8
  139. package/auth/server/revokeSessions.ts +4 -3
  140. package/auth/server/route.ts +77 -0
  141. package/auth/server/sendEmail.ts +5 -4
  142. package/auth/server/signup.ts +10 -3
  143. package/auth/server/token.ts +53 -55
  144. package/auth/server/tokenUsageBilling.ts +18 -7
  145. package/auth/server/usageManagementAccess.ts +43 -0
  146. package/auth/server/usageReport.ts +59 -0
  147. package/auth/types.ts +12 -0
  148. package/auth/utils.ts +24 -22
  149. package/authCommands.ts +36 -2
  150. package/buildPublish.ts +3 -1
  151. package/buildPublishArtifactAssembly.ts +62 -1
  152. package/buildPublishImportAnalysis.ts +21 -16
  153. package/chat/dialog/dialogLaunchScope.ts +32 -0
  154. package/chat/dialog/objectAssistantRegistry.ts +2 -2
  155. package/chat/dialog/useCreateDialog.ts +1 -1
  156. package/chat/hooks/useChatInput.ts +41 -10
  157. package/chat/messages/messageSlice.ts +5 -1
  158. package/chat/messages/pendingAttachmentParts.ts +28 -2
  159. package/chat/messages/sendFirstMessage.ts +76 -79
  160. package/chat/messages/types.ts +9 -0
  161. package/chat/messages/web/streamingMarkdownModel.ts +41 -0
  162. package/chat/messages/web/useStreamingReveal.ts +91 -0
  163. package/chat/web/messageInputAgentUi.ts +94 -6
  164. package/cliEnvHelpers.ts +8 -0
  165. package/cliRuntimeDoctorReport.ts +193 -0
  166. package/client/agentConfigResolver.test.ts +0 -2
  167. package/client/agentRun.test.ts +171 -10
  168. package/client/agentRun.ts +44 -637
  169. package/client/agentRunInput.ts +10 -0
  170. package/client/agentRunLocalExecutor.ts +179 -0
  171. package/client/agentRunServerTransport.ts +394 -0
  172. package/client/agentRunTaskRunRecorder.ts +176 -0
  173. package/client/localRuntimeAdapter.test.ts +236 -9
  174. package/client/localRuntimeAdapter.ts +221 -23
  175. package/client/localToolPolicy.test.ts +28 -4
  176. package/connector-experimental/daemonLauncher.ts +38 -4
  177. package/connectorRunArtifact.ts +34 -10
  178. package/connectorWebSocketTarget.ts +9 -5
  179. package/core/builtinAgents.ts +155 -11
  180. package/create/space/contentLabels.ts +1 -1
  181. package/create/space/contentTypeMeta.ts +3 -2
  182. package/create/space/sidebarVisibleTypes.ts +27 -0
  183. package/create/space/space.locale.ts +76 -4
  184. package/database/actions/agentReadResolution.ts +2 -8
  185. package/database/actions/read.ts +11 -9
  186. package/database/actions/readAndWait.ts +10 -5
  187. package/database/server/agentDelegation.ts +3 -2
  188. package/database/server/authorityStoreConformance.ts +209 -0
  189. package/database/server/authorityStoreTypes.ts +31 -0
  190. package/database/server/coreDataProxy.ts +1 -1
  191. package/database/server/dataHandlers.ts +13 -5
  192. package/database/server/db.ts +15 -34
  193. package/database/server/delete.ts +88 -71
  194. package/database/server/emailRepository.ts +11 -9
  195. package/database/server/fileService.ts +2 -1
  196. package/database/server/legacyServerDb.ts +58 -0
  197. package/database/server/levelAuthorityStore.ts +75 -0
  198. package/database/server/memoryAuthorityStore.ts +133 -0
  199. package/database/server/patch.ts +13 -12
  200. package/database/server/query.ts +3 -2
  201. package/database/server/read.ts +33 -30
  202. package/database/server/resourceAccess.ts +7 -5
  203. package/database/server/serverStoreFactory.ts +124 -0
  204. package/database/server/spaceMemberAuthority.ts +3 -2
  205. package/database/server/storeBatchCompat.ts +37 -0
  206. package/database/server/testAuthorityStore.ts +76 -0
  207. package/database/server/write.ts +29 -27
  208. package/integrations/anthropic/anthropicModels.ts +12 -12
  209. package/integrations/deepseek/models.ts +67 -67
  210. package/integrations/google/models.ts +111 -53
  211. package/integrations/openai/models.ts +22 -22
  212. package/integrations/xai/models.ts +1 -1
  213. package/localRuntimeDb.ts +39 -2
  214. package/machineCommandPrompts.ts +2 -0
  215. package/machineCommands.ts +193 -63
  216. package/machineWsRunDispatch.ts +80 -15
  217. package/machineWsSession.ts +39 -2
  218. package/noloReadBridgePrompt.ts +16 -0
  219. package/package.json +99 -6
  220. package/render/layout/mainLayoutViewMode.ts +25 -0
  221. package/render/page/server/createPage.ts +3 -1
  222. package/render/page/server/handleCreatePage.ts +2 -11
  223. package/runtimeDoctorCommands.ts +15 -66
  224. package/server/api/methods.ts +34 -12
  225. package/server/api/tableHandlers.ts +6 -3
  226. package/server/authenticateToken.ts +47 -2
  227. package/server/billingLedgerRoutes.ts +15 -0
  228. package/server/buildManifest.ts +54 -0
  229. package/server/coreReadiness.ts +34 -25
  230. package/server/coreRuntime.ts +15 -10
  231. package/server/handlers/activityStatsHandler.ts +5 -2
  232. package/server/handlers/agentEmailRegistrationE2EHandler.ts +25 -23
  233. package/server/handlers/agentRun/agentLookup.ts +1 -7
  234. package/server/handlers/agentRun/autonomousRuntime.ts +11 -10
  235. package/server/handlers/agentRun/builtinAgents.ts +12 -88
  236. package/server/handlers/agentRun/continueDialogContext.ts +15 -3
  237. package/server/handlers/agentRun/{inheritedDialogPrompt.ts → conversationReference.ts} +3 -3
  238. package/server/handlers/agentRun/dialogLookup.ts +4 -3
  239. package/server/handlers/agentRun/index.ts +864 -404
  240. package/server/handlers/agentRun/localRuntimeBootstrap.ts +17 -1
  241. package/server/handlers/agentRun/loop.ts +920 -508
  242. package/server/handlers/agentRun/machineConnector.ts +56 -8
  243. package/server/handlers/agentRun/machineRunAudit.ts +3 -2
  244. package/server/handlers/agentRun/modelUsageToolHandlers.ts +13 -10
  245. package/server/handlers/agentRun/requestContext.ts +12 -8
  246. package/server/handlers/agentRun/runtimeExecutionContext.ts +15 -3
  247. package/server/handlers/agentRun/runtimePreparation.ts +26 -24
  248. package/server/handlers/agentRun/runtimeRouting.ts +25 -40
  249. package/server/handlers/agentRun/runtimeSystemMessages.ts +65 -0
  250. package/server/handlers/agentRun/saveDialog.ts +97 -87
  251. package/server/handlers/agentRun/taskRunToolHandler.ts +9 -7
  252. package/server/handlers/agentRun/toolExecutor.ts +42 -78
  253. package/server/handlers/agentRun/types.ts +2 -1
  254. package/server/handlers/appDeployStatusStore.ts +17 -10
  255. package/server/handlers/appDomainHandler.ts +21 -15
  256. package/server/handlers/appLegacyInfraCleanup.ts +5 -2
  257. package/server/handlers/appSandboxHandler.ts +29 -8
  258. package/server/handlers/appSpaceAccess.ts +15 -8
  259. package/server/handlers/chatHandler.ts +22 -2
  260. package/server/handlers/chatUpstreamRetry.ts +225 -2
  261. package/server/handlers/connector/connectorConnectionRegistry.ts +55 -7
  262. package/server/handlers/connector/connectorWebSocket.ts +14 -10
  263. package/server/handlers/desktopAgentRuntimeAdapter.ts +4 -4
  264. package/server/handlers/desktopAgentRuntimeHostCapabilities.ts +25 -0
  265. package/server/handlers/desktopAgentRuntimeReadiness.ts +62 -0
  266. package/server/handlers/desktopAgentRuntimeStatusHandler.ts +38 -30
  267. package/server/handlers/desktopAgentRuntimeTurnHandler.ts +7 -3
  268. package/server/handlers/desktopAgentRuntimeTurnService.ts +39 -45
  269. package/server/handlers/desktopLlamaRuntimeHandler.ts +85 -51
  270. package/server/handlers/desktopUpdaterHandler.ts +132 -24
  271. package/server/handlers/favoriteHandlers.ts +8 -2
  272. package/server/handlers/getDialogBillingHandler.ts +4 -3
  273. package/server/handlers/getTransactionsHandler.ts +5 -2
  274. package/server/handlers/machines/machineBinding.ts +1 -0
  275. package/server/handlers/machines/machineHandlers.ts +0 -14
  276. package/server/handlers/machines/machineInstallAssets.ts +4 -2
  277. package/server/handlers/notificationEmitter.ts +5 -3
  278. package/server/handlers/notificationsHandler.ts +5 -2
  279. package/server/handlers/providerCallsRecentHandler.ts +234 -0
  280. package/server/handlers/providerReconciliationRunHandler.ts +180 -0
  281. package/server/handlers/providerRequestIdsHandler.ts +105 -0
  282. package/server/handlers/tableAccess.ts +6 -2
  283. package/server/handlers/tableToolHandlers.ts +28 -14
  284. package/server/handlers/userSecretsHandler.ts +17 -6
  285. package/server/handlers/versionHandler.ts +9 -4
  286. package/server/handlers/versionStore.ts +18 -10
  287. package/server/html/ssrPreload.ts +5 -3
  288. package/server/payments/crypto/cryptoUsdcBasePaymentProvider.ts +11 -8
  289. package/server/payments/crypto/cryptoUsdcBaseScanner.ts +12 -7
  290. package/server/payments/crypto/cryptoUsdtTronPaymentProvider.ts +11 -8
  291. package/server/payments/crypto/cryptoUsdtTronScanner.ts +9 -7
  292. package/server/payments/waffo/waffoPaymentProvider.ts +12 -9
  293. package/server/runtimeRole.ts +15 -0
  294. package/server/scheduler/scheduledTaskRuntime.ts +4 -2
  295. package/server/scheduler/schedulerService.ts +2 -2
  296. package/server/taskRunBridgeRoutes.ts +8 -5
  297. package/share/server/fetchCommunityShares.ts +1 -1
  298. package/share/server/helpers.ts +19 -17
  299. package/share/server/importShare.ts +9 -13
  300. package/share/server/listCommunityShares.ts +4 -4
  301. package/share/server/purchaseDoc.ts +8 -16
  302. package/share/server/readCommunityShareCover.ts +3 -2
  303. package/share/server/readSharedTable.ts +14 -13
  304. package/share/server/tableReplication.ts +42 -39
  305. package/spaceAttachCommands.ts +135 -0
  306. package/spaceInternalCommandEntries.ts +2 -0
  307. package/ai/agent/runtimeServerBase.ts +0 -37
  308. package/server/handlers/desktopAgentRuntimeHostFacts.ts +0 -40
@@ -0,0 +1,193 @@
1
+ import { resolveAgentRuntimeDecision } from "./agent-runtime/runtimeDecision";
2
+ import type { AgentRuntimeDecision } from "./agent-runtime/types";
3
+ import type { LocalRuntimeProbeResult } from "./agentCommandSupport";
4
+ import type { EnvLike } from "./cliEnvHelpers";
5
+
6
+ export type CliRuntimeDoctorProbe = {
7
+ levelDb: {
8
+ ok: boolean;
9
+ path: string;
10
+ error?: string;
11
+ };
12
+ agentConfig: {
13
+ key: string;
14
+ cacheReady: boolean;
15
+ found: boolean;
16
+ };
17
+ provider: {
18
+ available: boolean;
19
+ label: string;
20
+ };
21
+ sync: {
22
+ available: boolean;
23
+ };
24
+ serverFallback: {
25
+ available: boolean;
26
+ url: string;
27
+ };
28
+ };
29
+
30
+ export type CliRuntimeDoctorReport = {
31
+ decision: AgentRuntimeDecision;
32
+ levelDb: {
33
+ status: "ok" | "failed";
34
+ path: string;
35
+ error?: string;
36
+ };
37
+ agentConfig: {
38
+ status: "found" | "missing";
39
+ value: string;
40
+ };
41
+ provider: {
42
+ status: "available" | "missing";
43
+ label: string;
44
+ };
45
+ sync: {
46
+ status: "available" | "unavailable";
47
+ };
48
+ serverFallback: {
49
+ status: "available" | "unavailable";
50
+ value: string;
51
+ };
52
+ };
53
+
54
+ function readLocalAgentKey(env: EnvLike) {
55
+ return env.NOLO_LOCAL_AGENT_KEY || env.NOLO_AGENT || "";
56
+ }
57
+
58
+ function detectLocalProvider(env: EnvLike) {
59
+ return Boolean(
60
+ env.OPENAI_API_KEY ||
61
+ env.ANTHROPIC_API_KEY ||
62
+ env.GOOGLE_API_KEY ||
63
+ env.NOLO_LOCAL_OPENAI_BASE_URL ||
64
+ env.OLLAMA_BASE_URL
65
+ );
66
+ }
67
+
68
+ function detectProviderLabel(env: EnvLike) {
69
+ if (env.NOLO_LOCAL_OPENAI_BASE_URL) {
70
+ return `openai-compatible endpoint ${env.NOLO_LOCAL_OPENAI_BASE_URL}`;
71
+ }
72
+ if (env.OLLAMA_BASE_URL) {
73
+ return `ollama-compatible endpoint ${env.OLLAMA_BASE_URL}`;
74
+ }
75
+ if (env.OPENAI_API_KEY) return "openai via env OPENAI_API_KEY";
76
+ if (env.ANTHROPIC_API_KEY) return "anthropic via env ANTHROPIC_API_KEY";
77
+ if (env.GOOGLE_API_KEY) return "google via env GOOGLE_API_KEY";
78
+ return "missing";
79
+ }
80
+
81
+ export function buildCliRuntimeDoctorProbe(input: {
82
+ env: EnvLike;
83
+ localProbe: LocalRuntimeProbeResult;
84
+ authToken: string;
85
+ serverUrl: string;
86
+ }): CliRuntimeDoctorProbe {
87
+ const agentKey = input.localProbe.agentKey || readLocalAgentKey(input.env);
88
+ const cacheReady = Boolean(input.env.NOLO_AGENT_CACHE_READY);
89
+ return {
90
+ levelDb: {
91
+ ok: input.localProbe.ok,
92
+ path: input.localProbe.dbPath,
93
+ ...(input.localProbe.error ? { error: input.localProbe.error } : {}),
94
+ },
95
+ agentConfig: {
96
+ key: agentKey,
97
+ cacheReady,
98
+ found: input.localProbe.ok && input.localProbe.agentFound && (Boolean(agentKey) || cacheReady),
99
+ },
100
+ provider: {
101
+ available: detectLocalProvider(input.env),
102
+ label: detectProviderLabel(input.env),
103
+ },
104
+ sync: {
105
+ available: Boolean(input.authToken),
106
+ },
107
+ serverFallback: {
108
+ available: Boolean(input.authToken || input.env.NOLO_SERVER || input.env.BASE_URL),
109
+ url: input.serverUrl,
110
+ },
111
+ };
112
+ }
113
+
114
+ export function buildCliRuntimeDoctorReport(
115
+ probe: CliRuntimeDoctorProbe
116
+ ): CliRuntimeDoctorReport {
117
+ const missingLocalCapabilities = [
118
+ ...(probe.levelDb.ok ? [] : ["leveldb"]),
119
+ ...(probe.agentConfig.found ? [] : ["agent-config"]),
120
+ ...(probe.provider.available ? [] : ["provider"]),
121
+ ];
122
+ const decision = resolveAgentRuntimeDecision({
123
+ requestedMode: "auto",
124
+ syncRequested: false,
125
+ host: "cli",
126
+ hasLocalAgentConfig: probe.agentConfig.found,
127
+ hasLocalProvider: probe.provider.available,
128
+ hasLocalPersistence: true,
129
+ missingLocalCapabilities,
130
+ requiresServer: false,
131
+ serverFallbackAvailable: probe.serverFallback.available,
132
+ });
133
+
134
+ return {
135
+ decision,
136
+ levelDb: {
137
+ status: probe.levelDb.ok ? "ok" : "failed",
138
+ path: probe.levelDb.path,
139
+ ...(probe.levelDb.error ? { error: probe.levelDb.error } : {}),
140
+ },
141
+ agentConfig: {
142
+ status: probe.agentConfig.found ? "found" : "missing",
143
+ value: probe.agentConfig.key || (probe.agentConfig.cacheReady ? "cache ready" : "no local agent key"),
144
+ },
145
+ provider: {
146
+ status: probe.provider.available ? "available" : "missing",
147
+ label: probe.provider.label,
148
+ },
149
+ sync: {
150
+ status: probe.sync.available ? "available" : "unavailable",
151
+ },
152
+ serverFallback: {
153
+ status: probe.serverFallback.available ? "available" : "unavailable",
154
+ value: probe.serverFallback.available ? probe.serverFallback.url : "unavailable",
155
+ },
156
+ };
157
+ }
158
+
159
+ export function formatCliRuntimeDoctorReport(
160
+ report: CliRuntimeDoctorReport
161
+ ): string {
162
+ const lines = [
163
+ `Runtime: ${report.decision.mode}`,
164
+ `Reason: ${report.decision.reason}`,
165
+ `LevelDB: ${report.levelDb.status}`,
166
+ `DB path: ${report.levelDb.path}`,
167
+ ];
168
+ if (report.levelDb.error) {
169
+ lines.push(`DB error: ${report.levelDb.error}`);
170
+ }
171
+ if (report.agentConfig.status === "found") {
172
+ lines.push(`Agent config: found (${report.agentConfig.value})`);
173
+ } else if (report.agentConfig.value === "no local agent key") {
174
+ lines.push("Agent config: missing (no local agent key)");
175
+ } else {
176
+ lines.push(`Agent config: missing (${report.agentConfig.value})`);
177
+ }
178
+ lines.push(`Provider: ${report.provider.status} (${report.provider.label})`);
179
+ lines.push("Persistence: LevelDB local store");
180
+ lines.push(
181
+ `Sync: ${report.sync.status}${
182
+ report.sync.status === "available" ? "" : " (not authenticated)"
183
+ }`
184
+ );
185
+ lines.push(`Server fallback: ${report.serverFallback.value}`);
186
+ if (report.decision.missingLocalCapabilities.length > 0) {
187
+ lines.push("Missing local capabilities:");
188
+ for (const capability of report.decision.missingLocalCapabilities) {
189
+ lines.push(`- ${capability}`);
190
+ }
191
+ }
192
+ return `${lines.join("\n")}\n`;
193
+ }
@@ -17,7 +17,6 @@ describe("agent config resolver", () => {
17
17
  toolNames: ["legacyTool", "readFile"],
18
18
  tools: ["readFile", "applyEdit"],
19
19
  runtimeBinding: { machineId: "machine-1", localWorkspaceMode: "task-worktree" },
20
- delegation: { target: "local" },
21
20
  temperature: 0.2,
22
21
  top_p: 0.9,
23
22
  max_tokens: 4096,
@@ -36,7 +35,6 @@ describe("agent config resolver", () => {
36
35
  toolNames: ["legacyTool", "readFile", "applyEdit"],
37
36
  runtimeBinding: { machineId: "machine-1", localWorkspaceMode: "task-worktree" },
38
37
  localWorkspaceMode: "task-worktree",
39
- delegation: { target: "local" },
40
38
  temperature: 0.2,
41
39
  top_p: 0.9,
42
40
  max_tokens: 4096,
@@ -49,8 +49,8 @@ describe("cli agent run client", () => {
49
49
  });
50
50
 
51
51
  test("calls the Nolo HTTP API directly when AUTH_TOKEN is present", async () => {
52
- const output = new CaptureOutput();
53
- const requests: Array<{ url: string; body: any; auth: string | null }> = [];
52
+ const output = new CaptureOutput();
53
+ const requests: Array<{ url: string; body: any; auth: string | null }> = [];
54
54
 
55
55
  const result = await runAgentTurn({
56
56
  agentName: "nolo",
@@ -97,10 +97,89 @@ describe("cli agent run client", () => {
97
97
  ]);
98
98
  expect(result).toEqual({ exitCode: 0, dialogId: "dialog-1" });
99
99
  expect(output.text()).toContain("nolo -> working");
100
- expect(output.text()).toContain("nolo > hi");
100
+ expect(output.text()).toContain("nolo > hi");
101
101
  expect(output.text()).not.toContain("tokens=");
102
102
  });
103
103
 
104
+ test("retries machine-bound cluster runs on a sibling server when the primary registry is unavailable", async () => {
105
+ const output = new CaptureOutput();
106
+ const requests: string[] = [];
107
+
108
+ const result = await runAgentTurn({
109
+ agentName: "frontend",
110
+ agentKey: "frontend-implementer",
111
+ serverUrl: "https://nolo.chat",
112
+ message: "hello",
113
+ scriptDir: "C:/missing/scripts",
114
+ env: { AUTH_TOKEN: "token-123" },
115
+ output,
116
+ runtimeMode: "server",
117
+ scriptPathExists: () => false,
118
+ fetchImpl: async (url) => {
119
+ requests.push(String(url));
120
+ if (String(url) === "https://nolo.chat/api/agent/run") {
121
+ return Response.json({
122
+ error: "Runtime binding unavailable",
123
+ reason: "bound_machine_unavailable",
124
+ message: "Bound runtime machine is not available on this cluster node.",
125
+ }, { status: 409 });
126
+ }
127
+ return Response.json({
128
+ content: "cluster ok",
129
+ dialogId: "dialog-us",
130
+ });
131
+ },
132
+ });
133
+
134
+ expect(result).toEqual({ exitCode: 0, dialogId: "dialog-us" });
135
+ expect(requests).toEqual([
136
+ "https://nolo.chat/api/agent/run",
137
+ "https://us.nolo.chat/api/agent/run",
138
+ ]);
139
+ expect(output.text()).toContain("retrying https://us.nolo.chat");
140
+ expect(output.text()).toContain("frontend > cluster ok");
141
+ });
142
+
143
+ test("follows an explicit retryServerBase hint before cluster sibling fallback", async () => {
144
+ const output = new CaptureOutput();
145
+ const requests: string[] = [];
146
+
147
+ const result = await runAgentTurn({
148
+ agentName: "frontend",
149
+ agentKey: "frontend-implementer",
150
+ serverUrl: "https://router.nolo.chat",
151
+ message: "hello",
152
+ scriptDir: "C:/missing/scripts",
153
+ env: { AUTH_TOKEN: "token-123" },
154
+ output,
155
+ runtimeMode: "server",
156
+ scriptPathExists: () => false,
157
+ fetchImpl: async (url) => {
158
+ requests.push(String(url));
159
+ if (String(url) === "https://router.nolo.chat/api/agent/run") {
160
+ return Response.json({
161
+ error: "Runtime binding unavailable",
162
+ reason: "bound_machine_unavailable",
163
+ message: "Bound runtime machine is not available on this cluster node.",
164
+ retryServerBase: "https://us.nolo.chat",
165
+ }, { status: 409 });
166
+ }
167
+ return Response.json({
168
+ content: "sticky ok",
169
+ dialogId: "dialog-sticky",
170
+ });
171
+ },
172
+ });
173
+
174
+ expect(result).toEqual({ exitCode: 0, dialogId: "dialog-sticky" });
175
+ expect(requests).toEqual([
176
+ "https://router.nolo.chat/api/agent/run",
177
+ "https://us.nolo.chat/api/agent/run",
178
+ ]);
179
+ expect(output.text()).toContain("retrying https://us.nolo.chat");
180
+ expect(output.text()).toContain("frontend > sticky ok");
181
+ });
182
+
104
183
  test("prepends task-run context for HTTP agent runs", async () => {
105
184
  const output = new CaptureOutput();
106
185
  const requests: Array<{ body: any }> = [];
@@ -249,6 +328,66 @@ describe("cli agent run client", () => {
249
328
  expect(result).toEqual({ exitCode: 0, dialogId: "dialog-1" });
250
329
  });
251
330
 
331
+ test("drops inherited lineage when continueDialogId is authoritative for HTTP runs and trims it", async () => {
332
+ const output = new CaptureOutput();
333
+ const requests: Array<{ body: any }> = [];
334
+
335
+ await runAgentTurn({
336
+ agentName: "nolo",
337
+ agentKey: "agent-pub-test",
338
+ serverUrl: "https://nolo.chat",
339
+ message: "hello",
340
+ continueDialogId: " dialog-existing ",
341
+ inheritedFromDialogKey: "dialog-user-1-dialog-2",
342
+ parentDialogId: "dialog-2",
343
+ scriptDir: "C:/missing/scripts",
344
+ env: { AUTH_TOKEN: "token-123" },
345
+ output,
346
+ runtimeMode: "server",
347
+ scriptPathExists: () => false,
348
+ fetchImpl: async (_url, init) => {
349
+ requests.push({ body: JSON.parse(String(init?.body)) });
350
+ return Response.json({ content: "ok", dialogId: "dialog-1" });
351
+ },
352
+ });
353
+
354
+ expect(requests[0]?.body).toMatchObject({
355
+ continueDialogId: "dialog-existing",
356
+ });
357
+ expect(requests[0]?.body).not.toHaveProperty("inheritedFromDialogKey");
358
+ expect(requests[0]?.body).not.toHaveProperty("parentDialogId");
359
+ });
360
+
361
+ test("treats blank continueDialogId as absent for HTTP runs", async () => {
362
+ const output = new CaptureOutput();
363
+ const requests: Array<{ body: any }> = [];
364
+
365
+ await runAgentTurn({
366
+ agentName: "nolo",
367
+ agentKey: "agent-pub-test",
368
+ serverUrl: "https://nolo.chat",
369
+ message: "hello",
370
+ continueDialogId: " ",
371
+ inheritedFromDialogKey: "dialog-user-1-dialog-2",
372
+ parentDialogId: "dialog-2",
373
+ scriptDir: "C:/missing/scripts",
374
+ env: { AUTH_TOKEN: "token-123" },
375
+ output,
376
+ runtimeMode: "server",
377
+ scriptPathExists: () => false,
378
+ fetchImpl: async (_url, init) => {
379
+ requests.push({ body: JSON.parse(String(init?.body)) });
380
+ return Response.json({ content: "ok", dialogId: "dialog-1" });
381
+ },
382
+ });
383
+
384
+ expect(requests[0]?.body).not.toHaveProperty("continueDialogId");
385
+ expect(requests[0]?.body).toMatchObject({
386
+ inheritedFromDialogKey: "dialog-user-1-dialog-2",
387
+ parentDialogId: "dialog-2",
388
+ });
389
+ });
390
+
252
391
  test("records background task-run handoff as running instead of completed", async () => {
253
392
  const output = new CaptureOutput();
254
393
  const writebacks: any[] = [];
@@ -1064,8 +1203,8 @@ describe("cli agent run client", () => {
1064
1203
  expect(output.text()).toContain("Set AUTH_TOKEN");
1065
1204
  });
1066
1205
 
1067
- test("prints a friendly connection hint instead of crashing on transport errors", async () => {
1068
- const output = new CaptureOutput();
1206
+ test("prints a friendly connection hint instead of crashing on transport errors", async () => {
1207
+ const output = new CaptureOutput();
1069
1208
 
1070
1209
  const result = await runAgentTurn({
1071
1210
  agentName: "nolo",
@@ -1081,8 +1220,30 @@ describe("cli agent run client", () => {
1081
1220
  },
1082
1221
  });
1083
1222
 
1084
- expect(result).toEqual({ exitCode: 1 });
1085
- expect(output.text()).toContain("Could not reach http://127.0.0.1:38123/api/agent/run");
1086
- expect(output.text()).toContain("set NOLO_SERVER");
1087
- });
1088
- });
1223
+ expect(result).toEqual({ exitCode: 1 });
1224
+ expect(output.text()).toContain("Could not reach http://127.0.0.1:38123/api/agent/run");
1225
+ expect(output.text()).toContain("set NOLO_SERVER");
1226
+ });
1227
+
1228
+ test("mentions sandboxed network isolation for remote transport failures", async () => {
1229
+ const output = new CaptureOutput();
1230
+
1231
+ const result = await runAgentTurn({
1232
+ agentName: "nolo",
1233
+ agentKey: "agent-pub-test",
1234
+ serverUrl: "https://nolo.chat",
1235
+ message: "hello",
1236
+ scriptDir: "C:/missing/scripts",
1237
+ env: { AUTH_TOKEN: "token-123" },
1238
+ output,
1239
+ scriptPathExists: () => false,
1240
+ fetchImpl: async () => {
1241
+ throw new TypeError("Unable to connect. Is the computer able to access the url?");
1242
+ },
1243
+ });
1244
+
1245
+ expect(result).toEqual({ exitCode: 1 });
1246
+ expect(output.text()).toContain("sandboxed agent session");
1247
+ expect(output.text()).toContain("host machine can reach the server");
1248
+ });
1249
+ });