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
@@ -16,38 +16,38 @@ const scalePrice = (price: ModelPrice, multiplier: number): ModelPrice => ({
16
16
  });
17
17
 
18
18
  const GPT_5_4_STANDARD_PRICE: ModelPrice = {
19
- input: 2.5,
20
- output: 15,
21
- inputCacheHit: 0.25,
19
+ input: 2.5 * 8,
20
+ output: 15 * 8,
21
+ inputCacheHit: 0.25 * 8,
22
22
  };
23
23
 
24
24
  const GPT_5_5_STANDARD_PRICE: ModelPrice = {
25
- input: 5,
26
- output: 30,
27
- inputCacheHit: 0.5,
25
+ input: 5 * 8,
26
+ output: 30 * 8,
27
+ inputCacheHit: 0.5 * 8,
28
28
  };
29
29
 
30
30
  const GPT_5_4_LONG_CONTEXT_PRICE: ModelPrice = {
31
- input: 5,
32
- output: 22.5,
33
- inputCacheHit: 0.5,
31
+ input: 5 * 8,
32
+ output: 22.5 * 8,
33
+ inputCacheHit: 0.5 * 8,
34
34
  };
35
35
 
36
36
  const GPT_5_5_LONG_CONTEXT_PRICE: ModelPrice = {
37
- input: 10,
38
- output: 45,
39
- inputCacheHit: 1,
37
+ input: 10 * 8,
38
+ output: 45 * 8,
39
+ inputCacheHit: 1 * 8,
40
40
  };
41
41
 
42
42
  const GPT_5_4_PRO_STANDARD_PRICE: ModelPrice = {
43
- input: 30,
44
- output: 180,
43
+ input: 30 * 8,
44
+ output: 180 * 8,
45
45
  inputCacheHit: 0,
46
46
  };
47
47
 
48
48
  const GPT_5_4_PRO_LONG_CONTEXT_PRICE: ModelPrice = {
49
- input: 60,
50
- output: 270,
49
+ input: 60 * 8,
50
+ output: 270 * 8,
51
51
  inputCacheHit: 0,
52
52
  };
53
53
 
@@ -141,7 +141,7 @@ export const openAIModels: Model[] = [
141
141
  // OpenAI's current public pricing page does not list GPT Image 2 separately.
142
142
  // Reuse GPT Image 1.5 pricing as a conservative placeholder until official
143
143
  // GPT Image 2 pricing is published.
144
- price: { input: 5, output: 10, inputCacheHit: 1.25 },
144
+ price: { input: 5 * 8, output: 10 * 8, inputCacheHit: 1.25 * 8 },
145
145
  pricePerImage: 0.04 * 8,
146
146
  },
147
147
  {
@@ -190,7 +190,7 @@ export const openAIModels: Model[] = [
190
190
  contextWindow: 400_000,
191
191
  maxOutputTokens: 128_000,
192
192
  supportsReasoningEffort: true,
193
- price: { input: 0.75, output: 4.5, inputCacheHit: 0.075 },
193
+ price: { input: 0.75 * 8, output: 4.5 * 8, inputCacheHit: 0.075 * 8 },
194
194
  },
195
195
  {
196
196
  name: "gpt-5.4-nano",
@@ -200,7 +200,7 @@ export const openAIModels: Model[] = [
200
200
  contextWindow: 400_000,
201
201
  maxOutputTokens: 128_000,
202
202
  supportsReasoningEffort: true,
203
- price: { input: 0.2, output: 1.25, inputCacheHit: 0.02 },
203
+ price: { input: 0.2 * 8, output: 1.25 * 8, inputCacheHit: 0.02 * 8 },
204
204
  },
205
205
  {
206
206
  name: "gpt-5.4-pro",
@@ -247,7 +247,7 @@ export const openAIModels: Model[] = [
247
247
  contextWindow: 400_000,
248
248
  maxOutputTokens: 128_000,
249
249
  supportsReasoningEffort: true,
250
- price: { input: 12.5, output: 100, inputCacheHit: 1.25 },
250
+ price: { input: 1.25 * 8, output: 10 * 8, inputCacheHit: 0.125 * 8 },
251
251
  },
252
252
  {
253
253
  name: "gpt-5-mini",
@@ -256,7 +256,7 @@ export const openAIModels: Model[] = [
256
256
  contextWindow: 400_000,
257
257
  maxOutputTokens: 128_000,
258
258
  supportsReasoningEffort: true,
259
- price: { input: 2.5, output: 20, inputCacheHit: 0.25 },
259
+ price: { input: 0.25 * 8, output: 2 * 8, inputCacheHit: 0.025 * 8 },
260
260
  },
261
261
  {
262
262
  name: "o3-pro",
@@ -266,6 +266,6 @@ export const openAIModels: Model[] = [
266
266
  maxOutputTokens: 100_000,
267
267
  supportsReasoningEffort: true,
268
268
  endpointKey: "responses",
269
- price: { input: 200, output: 800, inputCacheHit: 0 },
269
+ price: { input: 20 * 8, output: 80 * 8, inputCacheHit: 0 },
270
270
  },
271
271
  ];
@@ -6,7 +6,7 @@ export const xaiModels: Model[] = [
6
6
  displayName: "Grok4 0709",
7
7
  hasVision: false,
8
8
  contextWindow: 131072,
9
- price: { input: 3 * 10, output: 15 * 10 }, // 30分 / 150分 → 0.3$ / 1.5$
9
+ price: { input: 3 * 8, output: 15 * 8 }, // $3/$15 per MTok × 7
10
10
  fnCall: true,
11
11
  jsonOutput: true,
12
12
  },
package/localRuntimeDb.ts CHANGED
@@ -20,9 +20,46 @@ export function buildCliLocalRuntimeDbEnv(env: EnvLike = process.env) {
20
20
  };
21
21
  }
22
22
 
23
+ export function isCliLocalRuntimeDbLockError(error: unknown): boolean {
24
+ const queue: unknown[] = [error];
25
+ const seen = new Set<unknown>();
26
+
27
+ while (queue.length > 0) {
28
+ const current = queue.shift();
29
+ if (!current || seen.has(current)) continue;
30
+ seen.add(current);
31
+
32
+ const text = `${(current as any)?.code ?? ""} ${(current as any)?.message ?? current}`;
33
+ if (/LEVEL_LOCKED|Resource temporarily unavailable|\/LOCK|LOCK:|db locked|locked/i.test(text)) {
34
+ return true;
35
+ }
36
+
37
+ if ((current as any)?.cause) queue.push((current as any).cause);
38
+ if (Array.isArray((current as any)?.errors)) queue.push(...(current as any).errors);
39
+ }
40
+
41
+ return false;
42
+ }
43
+
44
+ export function formatCliLocalRuntimeDbOpenError(dbPath: string, error: unknown) {
45
+ if (!isCliLocalRuntimeDbLockError(error)) {
46
+ return error instanceof Error ? error : new Error(String(error));
47
+ }
48
+ return new Error(
49
+ `CLI local runtime DB is locked at ${dbPath}. Another nolo local runtime is already using it. ` +
50
+ "Stop the other local runtime, rerun without --local, or set NOLO_SERVER_DB_PATH to a different cache path.",
51
+ { cause: error instanceof Error ? error : undefined }
52
+ );
53
+ }
54
+
23
55
  export async function getDefaultCliLocalRuntimeDb(): Promise<CliLocalRuntimeDb> {
24
- process.env.NOLO_SERVER_DB_PATH = buildCliLocalRuntimeDbEnv(process.env).NOLO_SERVER_DB_PATH;
56
+ const dbPath = buildCliLocalRuntimeDbEnv(process.env).NOLO_SERVER_DB_PATH;
57
+ process.env.NOLO_SERVER_DB_PATH = dbPath;
25
58
  const { default: serverDb, ensureServerDbOpen } = await import("./database/server/db");
26
- await ensureServerDbOpen();
59
+ try {
60
+ await ensureServerDbOpen();
61
+ } catch (error) {
62
+ throw formatCliLocalRuntimeDbOpenError(dbPath, error);
63
+ }
27
64
  return serverDb as CliLocalRuntimeDb;
28
65
  }
@@ -3,6 +3,7 @@ import {
3
3
  resolveMachineRunPermissionPolicy,
4
4
  type MachineRunPermissionPolicy,
5
5
  } from "./ai/agent/machineRunPermissions";
6
+ import { buildNoloReadOnlyBridgePrompt } from "./noloReadBridgePrompt";
6
7
 
7
8
  export function inferTaskRunRole(agentKey: string, agentConfig: any) {
8
9
  const haystack = [agentKey, agentConfig?.name, agentConfig?.prompt]
@@ -62,6 +63,7 @@ export function buildConnectorCliPrompt(
62
63
  const policy = permissionPolicy ?? resolveMachineRunPermissionPolicy(agentConfig);
63
64
  return [
64
65
  typeof agentConfig?.prompt === "string" ? agentConfig.prompt.trim() : "",
66
+ buildNoloReadOnlyBridgePrompt(),
65
67
  bridgeArgs
66
68
  ? buildTaskRunBridgePrompt({
67
69
  agentKey: bridgeArgs.agentKey,
@@ -1,4 +1,5 @@
1
1
  import type { MachineHeartbeat } from "./connector-experimental/protocol";
2
+ import { NOLO_CLUSTER_SERVERS, normalizeKnownServerOrigin } from "./database/config";
2
3
  import { detectMachineInfo } from "./connector-experimental/machineInfo";
3
4
  import {
4
5
  type HeartbeatLoopOptions,
@@ -42,6 +43,7 @@ export {
42
43
  type MachineCommandDeps = {
43
44
  env?: EnvLike;
44
45
  output?: OutputLike;
46
+ signal?: AbortSignal;
45
47
  cliEntrypointPath?: string;
46
48
  maxConnectorAttempts?: number;
47
49
  sleep?: (ms: number) => Promise<void>;
@@ -60,6 +62,100 @@ type MachineCommandDeps = {
60
62
  };
61
63
 
62
64
  const defaultSleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
65
+ const MACHINE_TOKEN_PREFIX = "sk_machine_";
66
+
67
+ async function sleepWithAbort(ms: number, sleep: (ms: number) => Promise<void>, signal?: AbortSignal) {
68
+ if (!signal) {
69
+ await sleep(ms);
70
+ return;
71
+ }
72
+ if (signal.aborted) return;
73
+ await Promise.race([
74
+ sleep(ms),
75
+ new Promise<void>((resolve) => {
76
+ signal.addEventListener("abort", () => resolve(), { once: true });
77
+ }),
78
+ ]);
79
+ }
80
+
81
+ function resolveConnectorReconnectDelayMs(env: EnvLike) {
82
+ const raw = Number(env.NOLO_CONNECT_RECONNECT_MS ?? "");
83
+ return Number.isFinite(raw) && raw >= 0 ? raw : 5_000;
84
+ }
85
+
86
+ function isMachineToken(token: string) {
87
+ return token.trim().startsWith(MACHINE_TOKEN_PREFIX);
88
+ }
89
+
90
+ function resolveClusterConnectServerUrls(serverUrl: string, authToken: string) {
91
+ const normalizedPrimary = normalizeKnownServerOrigin(serverUrl) ?? serverUrl.trim().replace(/\/+$/, "");
92
+ if (isMachineToken(authToken)) return [normalizedPrimary];
93
+ const normalizedCluster = NOLO_CLUSTER_SERVERS
94
+ .map((baseUrl) => normalizeKnownServerOrigin(baseUrl) ?? baseUrl)
95
+ .filter((value, index, list) => value && list.indexOf(value) === index);
96
+ if (!normalizedCluster.includes(normalizedPrimary)) return [normalizedPrimary];
97
+ return [normalizedPrimary, ...normalizedCluster.filter((baseUrl) => baseUrl !== normalizedPrimary)];
98
+ }
99
+
100
+ function linkAbortSignal(signal: AbortSignal | undefined, controller: AbortController) {
101
+ if (!signal) return;
102
+ if (signal.aborted) {
103
+ controller.abort();
104
+ return;
105
+ }
106
+ signal.addEventListener("abort", () => controller.abort(), { once: true });
107
+ }
108
+
109
+ async function sendMachineHeartbeat(args: {
110
+ serverUrl: string;
111
+ authToken: string;
112
+ fetchImpl: typeof fetch;
113
+ machine: MachineHeartbeat;
114
+ }) {
115
+ const res = await args.fetchImpl(`${args.serverUrl}/api/machines/heartbeat`, {
116
+ method: "POST",
117
+ headers: {
118
+ Authorization: `Bearer ${args.authToken}`,
119
+ "Content-Type": "application/json",
120
+ },
121
+ body: JSON.stringify(args.machine),
122
+ });
123
+
124
+ if (!res.ok) {
125
+ const text = await res.text().catch(() => "");
126
+ throw new Error(`HTTP ${res.status}\n${text}`);
127
+ }
128
+ }
129
+
130
+ async function sendHeartbeatAcrossServers(args: {
131
+ serverUrls: string[];
132
+ authToken: string;
133
+ fetchImpl: typeof fetch;
134
+ machine: MachineHeartbeat;
135
+ output: OutputLike;
136
+ }) {
137
+ let primaryError: Error | null = null;
138
+ for (const [index, serverUrl] of args.serverUrls.entries()) {
139
+ try {
140
+ await sendMachineHeartbeat({
141
+ serverUrl,
142
+ authToken: args.authToken,
143
+ fetchImpl: args.fetchImpl,
144
+ machine: args.machine,
145
+ });
146
+ } catch (error) {
147
+ const resolvedError = error instanceof Error ? error : new Error(String(error));
148
+ if (index === 0) {
149
+ primaryError = resolvedError;
150
+ } else {
151
+ args.output.write(
152
+ `[nolo] secondary connector registration failed for ${serverUrl}: ${resolvedError.message}\n`
153
+ );
154
+ }
155
+ }
156
+ }
157
+ if (primaryError) throw primaryError;
158
+ }
63
159
 
64
160
  async function defaultExecuteCli(
65
161
  provider: string,
@@ -75,9 +171,9 @@ function detectLaunchableMachineInfo() {
75
171
  }
76
172
 
77
173
  export async function runMachineConnectCommand(
78
- args: string[],
79
- deps: MachineCommandDeps = {}
80
- ) {
174
+ args: string[],
175
+ deps: MachineCommandDeps = {}
176
+ ) {
81
177
  const env = deps.env ?? process.env;
82
178
  const output = deps.output ?? process.stdout;
83
179
  const authToken = resolveConnectAuthToken(args, env);
@@ -85,29 +181,31 @@ export async function runMachineConnectCommand(
85
181
  writeAuthMissing(output);
86
182
  return 1;
87
183
  }
88
-
184
+
89
185
  const serverUrl = resolveConnectServerUrl(args, env);
186
+ const serverUrls = resolveClusterConnectServerUrls(serverUrl, authToken);
90
187
  const fetchImpl = deps.fetchImpl ?? fetch;
91
188
  const machine = (deps.machineInfo ?? detectLaunchableMachineInfo)();
92
189
  const sendHeartbeat = async () => {
93
- const res = await fetchImpl(`${serverUrl}/api/machines/heartbeat`, {
94
- method: "POST",
95
- headers: {
96
- Authorization: `Bearer ${authToken}`,
97
- "Content-Type": "application/json",
98
- },
99
- body: JSON.stringify(machine),
100
- });
101
-
102
- if (!res.ok) {
103
- const text = await res.text().catch(() => "");
104
- throw new Error(`HTTP ${res.status}\n${text}`);
105
- }
106
- };
190
+ await sendHeartbeatAcrossServers({
191
+ serverUrls,
192
+ authToken,
193
+ fetchImpl,
194
+ machine,
195
+ output,
196
+ });
197
+ };
107
198
 
108
199
  if (hasFlag(args, "--daemon") || hasFlag(args, "--background")) {
109
200
  return runMachineDaemonCommand({
110
- env,
201
+ env: {
202
+ ...env,
203
+ NOLO_SERVER: serverUrl,
204
+ NOLO_SERVER_URL: serverUrl,
205
+ BASE_URL: serverUrl,
206
+ AUTH_TOKEN: authToken,
207
+ NOLO_MACHINE_API_KEY: authToken,
208
+ },
111
209
  output,
112
210
  cliEntrypointPath: deps.cliEntrypointPath,
113
211
  validateWorkspaceLinks: deps.validateWorkspaceLinks,
@@ -123,50 +221,82 @@ export async function runMachineConnectCommand(
123
221
  const maxAttempts = deps.maxConnectorAttempts ?? Infinity;
124
222
  const sleep = deps.sleep ?? defaultSleep;
125
223
  const reconnectDelayMs = resolveConnectorReconnectDelayMs(env);
126
- for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
127
- const runtimeServerUrl =
128
- env.NOLO_CONNECT_RUNTIME_SERVER_URL ||
129
- env.NOLO_RUNTIME_SERVER_URL ||
130
- serverUrl;
131
- const exitCode = await runMachineWsSession({
132
- env,
133
- output,
134
- machine,
135
- sendHeartbeat,
136
- runHeartbeatLoop: deps.runHeartbeatLoop ?? defaultRunHeartbeatLoop,
137
- connectWebSocket: deps.connectWebSocket ?? defaultConnectWebSocket,
138
- serverUrl,
139
- authToken,
140
- resolveConnectorWebSocketTarget: (options) =>
141
- resolveConnectorWebSocketTarget({
142
- ...options,
143
- fetchImpl,
144
- }),
145
- onMessage: (message, send) =>
146
- handleConnectorRunMessage(
147
- message,
148
- send,
149
- deps.executeCli ?? defaultExecuteCli,
150
- {
151
- ...env,
152
- NOLO_SERVER: runtimeServerUrl,
153
- NOLO_SERVER_URL: runtimeServerUrl,
154
- BASE_URL: runtimeServerUrl,
155
- AUTH_TOKEN: authToken,
156
- NOLO_MACHINE_API_KEY: authToken,
157
- },
158
- fetchImpl,
159
- {
160
- buildConnectorCliPrompt,
161
- }
162
- ),
163
- });
164
- if (exitCode === 2) return 1;
165
- if (attempt >= maxAttempts) return exitCode;
166
- output.write(`[nolo] Connector websocket disconnected. Reconnecting in ${reconnectDelayMs}ms.\n`);
167
- await sleep(reconnectDelayMs);
168
- }
169
- return 0;
224
+ const runServerSession = async (targetServerUrl: string, signal?: AbortSignal) => {
225
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
226
+ if (signal?.aborted) {
227
+ return { serverUrl: targetServerUrl, exitCode: 0 };
228
+ }
229
+ const runtimeServerUrl =
230
+ env.NOLO_CONNECT_RUNTIME_SERVER_URL ||
231
+ env.NOLO_RUNTIME_SERVER_URL ||
232
+ targetServerUrl;
233
+ const exitCode = await runMachineWsSession({
234
+ env,
235
+ output,
236
+ signal,
237
+ machine,
238
+ sendHeartbeat: () =>
239
+ sendMachineHeartbeat({
240
+ serverUrl: targetServerUrl,
241
+ authToken,
242
+ fetchImpl,
243
+ machine,
244
+ }),
245
+ runHeartbeatLoop: deps.runHeartbeatLoop ?? defaultRunHeartbeatLoop,
246
+ connectWebSocket: deps.connectWebSocket ?? defaultConnectWebSocket,
247
+ serverUrl: targetServerUrl,
248
+ authToken,
249
+ resolveConnectorWebSocketTarget: (options) =>
250
+ resolveConnectorWebSocketTarget({
251
+ ...options,
252
+ fetchImpl,
253
+ }),
254
+ onMessage: (message, send) =>
255
+ handleConnectorRunMessage(
256
+ message,
257
+ send,
258
+ deps.executeCli ?? defaultExecuteCli,
259
+ {
260
+ ...env,
261
+ NOLO_SERVER: runtimeServerUrl,
262
+ NOLO_SERVER_URL: runtimeServerUrl,
263
+ BASE_URL: runtimeServerUrl,
264
+ AUTH_TOKEN: authToken,
265
+ NOLO_MACHINE_API_KEY: authToken,
266
+ },
267
+ fetchImpl,
268
+ {
269
+ buildConnectorCliPrompt,
270
+ }
271
+ ),
272
+ });
273
+ if (exitCode === 2) return { serverUrl: targetServerUrl, exitCode: 2 };
274
+ if (signal?.aborted) {
275
+ return { serverUrl: targetServerUrl, exitCode: 0 };
276
+ }
277
+ if (attempt >= maxAttempts) return { serverUrl: targetServerUrl, exitCode };
278
+ output.write(`[nolo] Connector websocket disconnected. Reconnecting in ${reconnectDelayMs}ms.\n`);
279
+ await sleepWithAbort(reconnectDelayMs, sleep, signal);
280
+ }
281
+ return { serverUrl: targetServerUrl, exitCode: 0 };
282
+ };
283
+
284
+ const sessionAbort = new AbortController();
285
+ linkAbortSignal(deps.signal, sessionAbort);
286
+
287
+ const sessionPromises = serverUrls.map(async (targetServerUrl, index) => {
288
+ const result = await runServerSession(targetServerUrl, sessionAbort.signal);
289
+ if (index > 0 && result.exitCode !== 0 && !sessionAbort.signal.aborted) {
290
+ output.write(
291
+ `[nolo] secondary connector registration failed for ${targetServerUrl}: exit ${result.exitCode}\n`
292
+ );
293
+ }
294
+ return result;
295
+ });
296
+ const results = await Promise.all(sessionPromises);
297
+ if (results.some((result) => result.exitCode === 0)) return 0;
298
+ if (results.some((result) => result.exitCode === 2)) return 1;
299
+ return results[0]?.exitCode ?? 1;
170
300
  }
171
301
 
172
302
  if (hasFlag(args, "--watch")) {
@@ -1,4 +1,6 @@
1
1
  import { runLocalAgentTurn, type LocalAgentToolEvent } from "./agent-runtime/localLoop";
2
+ import { resolveHostRuntimeConfigFromEnv } from "./agent-runtime/hostRuntimeConfig";
3
+ import { normalizeAgentRunDialogLineage } from "./ai/agent/agentRunDialogLineage";
2
4
  import {
3
5
  assertMachineRunAllowed as defaultAssertMachineRunAllowed,
4
6
  resolveMachineRunPermissionPolicy as defaultResolveMachineRunPermissionPolicy,
@@ -118,6 +120,24 @@ function requestsLocalWorkspaceRuntime(policy?: ConnectorRuntimePolicy) {
118
120
  );
119
121
  }
120
122
 
123
+ function isMachineBoundLocalCustomProvider(agentConfig: any) {
124
+ const machineId =
125
+ isRecord(agentConfig?.runtimeBinding) && typeof agentConfig.runtimeBinding.machineId === "string"
126
+ ? agentConfig.runtimeBinding.machineId.trim()
127
+ : "";
128
+ const providerUrl =
129
+ typeof agentConfig?.customProviderUrl === "string"
130
+ ? agentConfig.customProviderUrl.trim()
131
+ : "";
132
+ if (!machineId || !providerUrl) return false;
133
+ try {
134
+ const hostname = new URL(providerUrl).hostname.toLowerCase();
135
+ return hostname === "127.0.0.1" || hostname === "localhost" || hostname === "::1";
136
+ } catch {
137
+ return false;
138
+ }
139
+ }
140
+
121
141
  function hasExplicitMachinePermissions(agentConfig: any) {
122
142
  const runtimeBinding = isRecord(agentConfig?.runtimeBinding) ? agentConfig.runtimeBinding : {};
123
143
  return Boolean(
@@ -130,6 +150,7 @@ function hasExplicitMachinePermissions(agentConfig: any) {
130
150
 
131
151
  function runtimeWorkspacePermissionPolicy(
132
152
  runtimePolicy: ConnectorRuntimePolicy | undefined,
153
+ hostRuntimeConfig: { capabilities: { allowShell: boolean } },
133
154
  cwd: string
134
155
  ): PermissionPolicy | null {
135
156
  if (!requestsTaskWorktree(runtimePolicy)) return null;
@@ -137,7 +158,10 @@ function runtimeWorkspacePermissionPolicy(
137
158
  mode: "full_access",
138
159
  allowFilesystemRead: true,
139
160
  allowFilesystemWrite: true,
140
- allowShell: runtimePolicy?.shell?.enabled !== false,
161
+ allowShell:
162
+ hostRuntimeConfig.capabilities.allowShell &&
163
+ Array.isArray(runtimePolicy?.runtimeTools) &&
164
+ runtimePolicy.runtimeTools.includes("execShell"),
141
165
  writableRoots: [cwd],
142
166
  };
143
167
  }
@@ -175,13 +199,20 @@ function mergeToolNames(...values: unknown[]) {
175
199
  function localRuntimeEnvFromPolicy(runtimeEnv: EnvLike, policy?: ConnectorRuntimePolicy): EnvLike {
176
200
  return {
177
201
  ...runtimeEnv,
178
- ...(policy?.shell?.enabled && policy.shell.mode === "worktree"
179
- ? { NOLO_LOCAL_SHELL_MODE: "worktree" }
180
- : {}),
181
202
  ...(policy?.workspace?.cwd ? { NOLO_LOCAL_WORKTREE: policy.workspace.cwd } : {}),
182
203
  };
183
204
  }
184
205
 
206
+ function forwardedUserAuthToken(parsed: any): string {
207
+ const value = parsed?.payload?.meta?.userAuthToken;
208
+ return typeof value === "string" ? value.trim() : "";
209
+ }
210
+
211
+ function withForwardedUserAuthToken(runtimeEnv: EnvLike, parsed: any): EnvLike {
212
+ const userAuthToken = forwardedUserAuthToken(parsed);
213
+ return userAuthToken ? { ...runtimeEnv, AUTH_TOKEN: userAuthToken } : runtimeEnv;
214
+ }
215
+
185
216
  function runtimeWorkspaceRootFromTrace(trace: unknown): string | undefined {
186
217
  if (!Array.isArray(trace)) return undefined;
187
218
  for (const message of trace) {
@@ -241,6 +272,12 @@ async function defaultRunConnectorLocalRuntimeAgent(args: {
241
272
  ? args.parsed.payload.agentConfig
242
273
  : {};
243
274
  const policy = runtimePolicyFromConnectorPayload(args.parsed);
275
+ const wantsTaskWorktree = requestsTaskWorktree(policy);
276
+ const hostRuntimeConfig = resolveHostRuntimeConfigFromEnv({
277
+ env: args.runtimeEnv,
278
+ surface: "connector-local",
279
+ workspaceBinding: wantsTaskWorktree ? "default-cwd" : "explicit-cwd",
280
+ });
244
281
  const agentRecord = {
245
282
  ...payloadAgentConfig,
246
283
  dbKey: agentKey,
@@ -262,12 +299,14 @@ async function defaultRunConnectorLocalRuntimeAgent(args: {
262
299
  [`agent-${args.runtimeEnv.NOLO_USER_ID || "local"}-${agentKey}`, agentRecord],
263
300
  [`agent-${args.runtimeEnv.NOLO_LOCAL_USER_ID || args.runtimeEnv.NOLO_USER_ID || "local"}-${agentKey}`, agentRecord],
264
301
  ]);
265
- const env = localRuntimeEnvFromPolicy(args.runtimeEnv, policy);
266
- const wantsTaskWorktree = requestsTaskWorktree(policy);
302
+ const env = localRuntimeEnvFromPolicy(
303
+ withForwardedUserAuthToken(args.runtimeEnv, args.parsed),
304
+ policy
305
+ );
267
306
  const adapter = createCliLocalRuntimeAdapter({
268
307
  env,
308
+ hostRuntimeConfig,
269
309
  cwd: args.cwd,
270
- useCwdAsTaskWorkspaceBase: wantsTaskWorktree,
271
310
  ...(wantsTaskWorktree
272
311
  ? {
273
312
  prepareTaskWorktree: (input) => prepareTaskWorktree({
@@ -350,6 +389,20 @@ function normalizeConnectorRunTimeoutMs(value: unknown): number | undefined {
350
389
  return Math.floor(value);
351
390
  }
352
391
 
392
+ function normalizeConnectorRunPayloadContinueDialogId(payload: unknown) {
393
+ if (!isRecord(payload)) return payload;
394
+ const dialogLineage = normalizeAgentRunDialogLineage({
395
+ continueDialogId: payload.continueDialogId,
396
+ });
397
+ const normalizedPayload = { ...payload };
398
+ if (dialogLineage.continueDialogId) {
399
+ normalizedPayload.continueDialogId = dialogLineage.continueDialogId;
400
+ } else {
401
+ delete normalizedPayload.continueDialogId;
402
+ }
403
+ return normalizedPayload;
404
+ }
405
+
353
406
  export async function handleConnectorRunMessage(
354
407
  message: string,
355
408
  send: (message: string) => void,
@@ -365,6 +418,12 @@ export async function handleConnectorRunMessage(
365
418
  return;
366
419
  }
367
420
  if (parsed?.type !== "agent.run" || typeof parsed.requestId !== "string") return;
421
+ if (isRecord(parsed)) {
422
+ parsed = {
423
+ ...parsed,
424
+ payload: normalizeConnectorRunPayloadContinueDialogId(parsed.payload),
425
+ };
426
+ }
368
427
  const agentConfig = parsed.payload?.agentConfig ?? {};
369
428
  const sendProgress = (progress: ConnectorRunProgress) => {
370
429
  send(JSON.stringify({
@@ -392,6 +451,11 @@ export async function handleConnectorRunMessage(
392
451
  try {
393
452
  const machinePermissionPolicy = resolveMachineRunPermissionPolicy(agentConfig);
394
453
  const runtimePolicy = runtimePolicyFromConnectorPayload(parsed);
454
+ const hostRuntimeConfig = resolveHostRuntimeConfigFromEnv({
455
+ env: runtimeEnv,
456
+ surface: agentConfig.apiSource === "cli" ? "connector-cli" : "connector-local",
457
+ workspaceBinding: requestsTaskWorktree(runtimePolicy) ? "default-cwd" : "explicit-cwd",
458
+ });
395
459
  const userInput = String(parsed.payload?.userInput ?? "");
396
460
  const timeout = normalizeConnectorRunTimeoutMs(parsed.payload?.timeoutMs);
397
461
  let cwd = resolveConnectorRunCwd({ env: runtimeEnv, policy: machinePermissionPolicy });
@@ -414,7 +478,7 @@ export async function handleConnectorRunMessage(
414
478
  artifactCwd = prepared.path;
415
479
  }
416
480
  const runtimePermissionPolicy = !hasExplicitMachinePermissions(agentConfig)
417
- ? runtimeWorkspacePermissionPolicy(runtimePolicy, cwd)
481
+ ? runtimeWorkspacePermissionPolicy(runtimePolicy, hostRuntimeConfig, cwd)
418
482
  : null;
419
483
  const effectivePermissionPolicy = scopePermissionPolicyToRuntimeWorkspace(
420
484
  runtimePermissionPolicy ?? machinePermissionPolicy,
@@ -472,17 +536,18 @@ export async function handleConnectorRunMessage(
472
536
  updatedAt: Date.now(),
473
537
  });
474
538
  }, 15_000);
539
+ const effectiveRuntimeEnv = withForwardedUserAuthToken(runtimeEnv, parsed);
475
540
  const result = await executeCli(provider, materializedPrompt.prompt, {
476
541
  model: agentConfig.model || undefined,
477
542
  timeout,
478
543
  cwd,
479
544
  yolo: true,
480
545
  env: {
481
- NOLO_SERVER: runtimeEnv.NOLO_SERVER || runtimeEnv.NOLO_SERVER_URL || runtimeEnv.BASE_URL,
482
- NOLO_SERVER_URL: runtimeEnv.NOLO_SERVER_URL || runtimeEnv.NOLO_SERVER || runtimeEnv.BASE_URL,
483
- BASE_URL: runtimeEnv.BASE_URL || runtimeEnv.NOLO_SERVER || runtimeEnv.NOLO_SERVER_URL,
484
- AUTH_TOKEN: runtimeEnv.AUTH_TOKEN || runtimeEnv.AUTH || runtimeEnv.NOLO_MACHINE_API_KEY,
485
- NOLO_MACHINE_API_KEY: runtimeEnv.NOLO_MACHINE_API_KEY || runtimeEnv.AUTH_TOKEN || runtimeEnv.AUTH,
546
+ NOLO_SERVER: effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.NOLO_SERVER_URL || effectiveRuntimeEnv.BASE_URL,
547
+ NOLO_SERVER_URL: effectiveRuntimeEnv.NOLO_SERVER_URL || effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.BASE_URL,
548
+ BASE_URL: effectiveRuntimeEnv.BASE_URL || effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.NOLO_SERVER_URL,
549
+ AUTH_TOKEN: effectiveRuntimeEnv.AUTH_TOKEN || effectiveRuntimeEnv.AUTH || effectiveRuntimeEnv.NOLO_MACHINE_API_KEY,
550
+ NOLO_MACHINE_API_KEY: effectiveRuntimeEnv.NOLO_MACHINE_API_KEY || effectiveRuntimeEnv.AUTH_TOKEN || effectiveRuntimeEnv.AUTH,
486
551
  },
487
552
  }).finally(() => clearInterval(heartbeat));
488
553
  logConnectorRun("agent.run.cli.result", {
@@ -518,13 +583,13 @@ export async function handleConnectorRunMessage(
518
583
  }));
519
584
  return;
520
585
  }
521
- if (!requestsLocalWorkspaceRuntime(runtimePolicy)) {
586
+ if (!requestsLocalWorkspaceRuntime(runtimePolicy) && !isMachineBoundLocalCustomProvider(agentConfig)) {
522
587
  throw new Error("Connector can only execute non-CLI agents when runtimeToolPolicySnapshot requests a local workspace runtime.");
523
588
  }
524
589
  baseSha = await readConnectorGitHead(cwd);
525
590
  const result = await runConnectorLocalRuntimeAgent({
526
591
  parsed,
527
- runtimeEnv,
592
+ runtimeEnv: withForwardedUserAuthToken(runtimeEnv, parsed),
528
593
  cwd,
529
594
  fetchImpl,
530
595
  onProgress: sendProgress,