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,117 @@
1
+ export type ShellCommandPolicyVerdict = "allowed" | "forbidden";
2
+
3
+ export type ShellCommandPolicyResult =
4
+ | {
5
+ verdict: "allowed";
6
+ }
7
+ | {
8
+ verdict: "forbidden";
9
+ code: "destructive_action_requires_confirmation";
10
+ reason: string;
11
+ policy: {
12
+ capability: "destructive_action";
13
+ target: "shell_command";
14
+ detail: string;
15
+ };
16
+ };
17
+
18
+ const DESTRUCTIVE_NEGATION_PATTERNS = [
19
+ "别删",
20
+ "别删除",
21
+ "不要删",
22
+ "不要删除",
23
+ "别乱删",
24
+ "别动",
25
+ "不要动",
26
+ "不要清理",
27
+ "不要清空",
28
+ "不要重置",
29
+ "don't delete",
30
+ "do not delete",
31
+ "don't remove",
32
+ "do not remove",
33
+ "without deleting",
34
+ ] as const;
35
+
36
+ const EXPLICIT_DESTRUCTIVE_REQUEST_PATTERNS = [
37
+ "删除",
38
+ "删掉",
39
+ "移除",
40
+ "清理",
41
+ "清空",
42
+ "重置",
43
+ "drop",
44
+ "delete",
45
+ "remove",
46
+ "erase",
47
+ "clean up",
48
+ "reset",
49
+ ] as const;
50
+
51
+ const SHELL_DESTRUCTIVE_PATTERNS = [
52
+ /\brm\s+(-[^\n\r]*\s+)?/i,
53
+ /\bremove-item\b/i,
54
+ /\bdel\s+\/?[a-z]*\s+/i,
55
+ /\berase\s+/i,
56
+ /\brmdir\s+/i,
57
+ /\brd\s+\/s\b/i,
58
+ /\bgit\s+reset\s+(--hard\b|--merge\b|--keep\b)/i,
59
+ /\bgit\s+clean\s+-[^\n\r]*f/i,
60
+ /\bgit\s+checkout\s+--\b/i,
61
+ /\bgit\s+restore\s+--source=/i,
62
+ ] as const;
63
+
64
+ const normalizeUserInput = (value: unknown): string =>
65
+ typeof value === "string" ? value.trim().toLowerCase() : "";
66
+
67
+ const containsAny = (text: string, patterns: readonly string[]): boolean =>
68
+ patterns.some((pattern) => text.includes(pattern));
69
+
70
+ const hasExplicitDestructivePermission = (userInput: unknown): boolean => {
71
+ const normalized = normalizeUserInput(userInput);
72
+ if (!normalized) return false;
73
+ if (containsAny(normalized, DESTRUCTIVE_NEGATION_PATTERNS)) return false;
74
+ return containsAny(normalized, EXPLICIT_DESTRUCTIVE_REQUEST_PATTERNS);
75
+ };
76
+
77
+ const buildCombinedShellInput = (args: {
78
+ command?: unknown;
79
+ input?: unknown;
80
+ }): string =>
81
+ [
82
+ typeof args.command === "string" ? args.command : "",
83
+ typeof args.input === "string" ? args.input : "",
84
+ ]
85
+ .filter(Boolean)
86
+ .join("\n");
87
+
88
+ export function isDestructiveShellCommand(args: {
89
+ command?: unknown;
90
+ input?: unknown;
91
+ }): boolean {
92
+ const combined = buildCombinedShellInput(args);
93
+ if (!combined.trim()) return false;
94
+ return SHELL_DESTRUCTIVE_PATTERNS.some((pattern) => pattern.test(combined));
95
+ }
96
+
97
+ export function evaluateShellCommandPolicy(args: {
98
+ command?: unknown;
99
+ input?: unknown;
100
+ userInput?: unknown;
101
+ }): ShellCommandPolicyResult {
102
+ if (isDestructiveShellCommand(args) && !hasExplicitDestructivePermission(args.userInput)) {
103
+ return {
104
+ verdict: "forbidden",
105
+ code: "destructive_action_requires_confirmation",
106
+ reason:
107
+ "当前运行默认禁止自动执行可能删除用户内容的 shell 命令。只有当用户在当前请求里明确要求删除/清理时,才能继续;否则请停止并先说明限制。",
108
+ policy: {
109
+ capability: "destructive_action",
110
+ target: "shell_command",
111
+ detail: "execShell destructive command",
112
+ },
113
+ };
114
+ }
115
+
116
+ return { verdict: "allowed" };
117
+ }
@@ -0,0 +1,38 @@
1
+ import { canonicalizeToolName } from "../ai/tools/toolNameAliases";
2
+
3
+ export type RuntimeToolGateDecision =
4
+ | { allowed: true; toolName: string }
5
+ | { allowed: false; toolName: string; reason: string };
6
+
7
+ function normalizeExposedToolNames(toolNames?: string[]): Set<string> {
8
+ return new Set(
9
+ (toolNames ?? [])
10
+ .map((toolName) => canonicalizeToolName(String(toolName ?? "").replace(/^functions\./, "").trim()))
11
+ .filter(Boolean),
12
+ );
13
+ }
14
+
15
+ export function resolveRuntimeToolGate(args: {
16
+ toolName: string;
17
+ exposedToolNames?: string[];
18
+ forbiddenReason?: string;
19
+ }): RuntimeToolGateDecision {
20
+ const toolName = canonicalizeToolName(args.toolName.replace(/^functions\./, "").trim());
21
+ if (!toolName) {
22
+ return {
23
+ allowed: false,
24
+ toolName,
25
+ reason: "Tool name is required.",
26
+ };
27
+ }
28
+
29
+ if (normalizeExposedToolNames(args.exposedToolNames).has(toolName)) {
30
+ return { allowed: true, toolName };
31
+ }
32
+
33
+ return {
34
+ allowed: false,
35
+ toolName,
36
+ reason: args.forbiddenReason ?? `${toolName} is not exposed by this runtime turn.`,
37
+ };
38
+ }
@@ -17,7 +17,7 @@ export async function runAgentReadCommand(
17
17
  const output = deps.output ?? process.stdout;
18
18
  const agentInput = args[0]?.trim();
19
19
  if (!agentInput || agentInput === "--help" || agentInput === "-h") {
20
- output.write("Usage: nolo agent read <agent>\n");
20
+ output.write("Usage: nolo agent read <agent> [--server <url>]\n");
21
21
  return agentInput ? 0 : 1;
22
22
  }
23
23
 
@@ -3,6 +3,7 @@ import { resolveCliAgentKeyInput } from "./agentAliases";
3
3
  import type { CliKvDb } from "./client/hybridRecordStore";
4
4
  import { buildLocalAgentLookupKeys, shouldReadAgentKeyRemotely } from "./client/localAgentRecords";
5
5
  import {
6
+ hasExplicitServerOverride,
6
7
  parseUserIdFromAuthToken,
7
8
  readOption,
8
9
  resolveAuthToken,
@@ -270,27 +271,13 @@ export async function resolveAgentRecordFromHybridStore(args: {
270
271
  }) {
271
272
  const agentKey = resolveCliAgentKeyInput(args.agentInput);
272
273
  const authToken = resolveAuthToken(args.cliArgs ?? [], args.env);
273
- const defaultServerUrl = resolveServerUrl(args.cliArgs ?? [], args.env);
274
+ const cliArgs = args.cliArgs ?? [];
275
+ const defaultServerUrl = resolveServerUrl(cliArgs, args.env);
276
+ const serverCandidates = resolveServerCandidates(cliArgs, args.env, defaultServerUrl);
277
+ const preferRemote = hasExplicitServerOverride(cliArgs);
274
278
 
275
- for (const key of buildLocalAgentLookupKeys({
276
- agentRef: agentKey,
277
- userId: parseUserIdFromAuthToken(authToken) || "local",
278
- })) {
279
- try {
280
- const record = await args.db.get(key);
281
- if (record && typeof record === "object") {
282
- return {
283
- agentKey: key,
284
- record,
285
- source: record?.serverOrigin ? "remote-cache" : "local-cache",
286
- } as const;
287
- }
288
- } catch {
289
- // local miss
290
- }
291
-
292
- if (!shouldReadAgentKeyRemotely(key)) continue;
293
- for (const serverUrl of resolveServerCandidates(args.cliArgs ?? [], args.env, defaultServerUrl)) {
279
+ const readRemoteRecord = async (key: string) => {
280
+ for (const serverUrl of serverCandidates) {
294
281
  try {
295
282
  const remoteRecord = await readAgentRecord({
296
283
  agentKey: key,
@@ -310,6 +297,34 @@ export async function resolveAgentRecordFromHybridStore(args: {
310
297
  // try next
311
298
  }
312
299
  }
300
+ return null;
301
+ };
302
+
303
+ for (const key of buildLocalAgentLookupKeys({
304
+ agentRef: agentKey,
305
+ userId: parseUserIdFromAuthToken(authToken) || "local",
306
+ })) {
307
+ if (preferRemote && shouldReadAgentKeyRemotely(key)) {
308
+ const remoteFirst = await readRemoteRecord(key);
309
+ if (remoteFirst) return remoteFirst;
310
+ }
311
+
312
+ try {
313
+ const record = await args.db.get(key);
314
+ if (record && typeof record === "object") {
315
+ return {
316
+ agentKey: key,
317
+ record,
318
+ source: record?.serverOrigin ? "remote-cache" : "local-cache",
319
+ } as const;
320
+ }
321
+ } catch {
322
+ // local miss
323
+ }
324
+
325
+ if (!shouldReadAgentKeyRemotely(key)) continue;
326
+ const remoteFallback = await readRemoteRecord(key);
327
+ if (remoteFallback) return remoteFallback;
313
328
  }
314
329
 
315
330
  return null;
@@ -1,6 +1,10 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { extname, resolve } from "node:path";
3
3
 
4
+ import {
5
+ buildAgentRunDialogLineageFields,
6
+ normalizeAgentRunDialogLineage,
7
+ } from "./ai/agent/agentRunDialogLineage";
4
8
  import { parseSkillDocProtocol, type WorkflowReferenceConfig } from "./ai/skills/skillDocProtocol";
5
9
 
6
10
  import { resolveCliAgentKeyInput } from "./agentAliases";
@@ -168,7 +172,10 @@ export function parseAgentRunArgs(
168
172
  if (!agentKey || !rawMessage.trim()) return null;
169
173
  const message = rawMessage.trim();
170
174
  const runtimeMode = runtimeModeFromArgs(args);
171
- const continueDialogId = readFlagValue(args, "--continue") ?? readFlagValue(args, "--dialog");
175
+ const rawContinueDialogId = readFlagValue(args, "--continue") ?? readFlagValue(args, "--dialog");
176
+ const continueDialogId = normalizeAgentRunDialogLineage({
177
+ continueDialogId: rawContinueDialogId,
178
+ }).continueDialogId;
172
179
  const spaceId = readFlagValue(args, "--space");
173
180
  const category = readFlagValue(args, "--category");
174
181
  const inheritedFromDialog = readFlagValue(args, "--inherit-from-dialog");
@@ -219,11 +226,17 @@ export function parseAgentRunArgs(
219
226
  background: args.includes("--bg"),
220
227
  noStream: args.includes("--no-stream"),
221
228
  noDefaultTestRoot,
222
- ...(continueDialogId ? { continueDialogId } : {}),
229
+ ...buildAgentRunDialogLineageFields({
230
+ continueDialogId,
231
+ inheritedFromDialogKey: inheritedRef?.dialogKey,
232
+ parentDialogId: inheritedRef?.dialogId,
233
+ }),
223
234
  ...(!continueDialogId && spaceId ? { spaceId } : {}),
224
- ...(category ? { category } : !continueDialogId && !noDefaultTestRoot ? { category: DEFAULT_TEST_DIALOG_CATEGORY_ID } : {}),
225
- ...(inheritedRef?.dialogKey ? { inheritedFromDialogKey: inheritedRef.dialogKey } : {}),
226
- ...(inheritedRef?.dialogId ? { parentDialogId: inheritedRef.dialogId } : {}),
235
+ ...(category
236
+ ? { category }
237
+ : !continueDialogId && !noDefaultTestRoot
238
+ ? { category: DEFAULT_TEST_DIALOG_CATEGORY_ID }
239
+ : {}),
227
240
  ...(cwd ? { cwd } : {}),
228
241
  ...(typeof maxToolRounds === "number" ? { maxToolRounds } : {}),
229
242
  ...(typeof timeoutMs === "number" ? { timeoutMs } : {}),
@@ -1,7 +1,9 @@
1
1
  export {
2
+ createHostRuntimeConfig,
2
3
  buildOpenAiCompatibleChatCompletionRequest,
3
4
  buildPlatformChatCompletionRequest,
4
5
  canUsePlatformChatProvider,
6
+ createHostRuntimeCapabilities,
5
7
  hasDirectOpenAiCompatibleProvider,
6
8
  createHybridRecordStore,
7
9
  executeLocalToolWithPolicy,
@@ -16,9 +18,12 @@ export {
16
18
  parsePlatformChatCompletionData,
17
19
  parsePlatformChatCompletionResponse,
18
20
  resolveAgentRuntimeConfigFromRecord,
21
+ resolveHostRuntimeConfigFromEnv,
22
+ resolveHostRuntimeCapabilitiesFromEnv,
19
23
  resolvePlatformChatProviderConfig,
20
24
  resolveLocalToolPolicy,
21
25
  resolveOpenAiCompatibleProviderConfig,
26
+ resolveRequestedRuntimeToolNames,
22
27
  shouldUsePlatformChatProvider,
23
28
  shouldCacheHybridRemoteRecord,
24
29
  shouldFetchAgentRuntimeRecordRemotely,
@@ -27,6 +32,7 @@ export { runLocalAgentTurn } from "./agent-runtime/localLoop";
27
32
  export {
28
33
  buildLocalWorkspaceOpenAiTools,
29
34
  buildLocalWorkspacePolicyToolNames,
35
+ resolveLocalWorkspaceShellToolExposure,
30
36
  buildLocalWorkspaceToolset,
31
37
  createLocalWorkspaceToolExecutors,
32
38
  } from "./agent-runtime/localWorkspaceTools";
@@ -35,6 +41,10 @@ export type {
35
41
  AgentRuntimeHostAdapter,
36
42
  AgentRuntimeRequestedMode,
37
43
  AgentRuntimeSaveTurnInput,
44
+ HostRuntimeConfig,
45
+ HostRuntimeCapabilities,
46
+ HostRuntimeSurface,
47
+ HostRuntimeWorkspaceBinding,
38
48
  HybridRecordKvDb,
39
49
  HybridRecordStore,
40
50
  LocalToolPolicyDecision,
@@ -0,0 +1,56 @@
1
+ export type AgentRunDialogLineageInput = {
2
+ continueDialogId?: string | null;
3
+ inheritedFromDialogKey?: string | null;
4
+ parentDialogId?: string | null;
5
+ };
6
+
7
+ export type NormalizedAgentRunDialogLineage = {
8
+ continueDialogId?: string;
9
+ inheritedFromDialogKey?: string;
10
+ parentDialogId?: string;
11
+ hasAuthoritativeContinueDialog: boolean;
12
+ hasConflictingLineage: boolean;
13
+ };
14
+
15
+ function pickOptionalString(value: unknown) {
16
+ if (typeof value !== "string") return undefined;
17
+ const normalized = value.trim();
18
+ return normalized.length > 0 ? normalized : undefined;
19
+ }
20
+
21
+ export function hasAuthoritativeContinueDialogId(value: unknown) {
22
+ return pickOptionalString(value) !== undefined;
23
+ }
24
+
25
+ export function normalizeAgentRunDialogLineage(
26
+ input: AgentRunDialogLineageInput
27
+ ): NormalizedAgentRunDialogLineage {
28
+ const continueDialogId = pickOptionalString(input.continueDialogId);
29
+ const inheritedFromDialogKey = pickOptionalString(input.inheritedFromDialogKey);
30
+ const parentDialogId = pickOptionalString(input.parentDialogId);
31
+ const hasAuthoritativeContinueDialog = hasAuthoritativeContinueDialogId(continueDialogId);
32
+
33
+ return {
34
+ continueDialogId,
35
+ inheritedFromDialogKey: hasAuthoritativeContinueDialog ? undefined : inheritedFromDialogKey,
36
+ parentDialogId: hasAuthoritativeContinueDialog ? undefined : parentDialogId,
37
+ hasAuthoritativeContinueDialog,
38
+ hasConflictingLineage:
39
+ hasAuthoritativeContinueDialog && Boolean(inheritedFromDialogKey || parentDialogId),
40
+ };
41
+ }
42
+
43
+ export function buildAgentRunDialogLineageFields(
44
+ input: AgentRunDialogLineageInput
45
+ ): Pick<AgentRunDialogLineageInput, "continueDialogId" | "inheritedFromDialogKey" | "parentDialogId"> {
46
+ const normalized = normalizeAgentRunDialogLineage(input);
47
+ return {
48
+ ...(hasAuthoritativeContinueDialogId(normalized.continueDialogId)
49
+ ? { continueDialogId: normalized.continueDialogId }
50
+ : {}),
51
+ ...(normalized.inheritedFromDialogKey
52
+ ? { inheritedFromDialogKey: normalized.inheritedFromDialogKey }
53
+ : {}),
54
+ ...(normalized.parentDialogId ? { parentDialogId: normalized.parentDialogId } : {}),
55
+ };
56
+ }
@@ -79,6 +79,24 @@ const normalizeAgentReferences = (references: any[]): ReferenceItem[] => {
79
79
  }));
80
80
  };
81
81
 
82
+ const isLocalProviderUrl = (value: unknown) => {
83
+ const normalized = typeof value === "string" ? value.trim() : "";
84
+ if (!normalized) return false;
85
+ try {
86
+ const hostname = new URL(normalized).hostname.toLowerCase();
87
+ return hostname === "127.0.0.1" || hostname === "localhost" || hostname === "::1";
88
+ } catch {
89
+ return false;
90
+ }
91
+ };
92
+
93
+ const shouldPersistMachineBinding = (args: {
94
+ apiSource?: string;
95
+ customProviderUrl?: unknown;
96
+ }) =>
97
+ args.apiSource === "cli" ||
98
+ (args.apiSource === "custom" && isLocalProviderUrl(args.customProviderUrl));
99
+
82
100
  /**
83
101
  * 创建场景:表单数据 -> 持久化数据(全量)
84
102
  */
@@ -104,7 +122,10 @@ const processAgentCreateForm = (formData: AgentFormData, userId: string) => {
104
122
  };
105
123
 
106
124
  delete result.machineId;
107
- if (formData.apiSource === "cli" && machineId) {
125
+ if (machineId && shouldPersistMachineBinding({
126
+ apiSource: formData.apiSource,
127
+ customProviderUrl: formData.customProviderUrl,
128
+ })) {
108
129
  const binding: AgentRuntimeBinding = {
109
130
  ...(result.runtimeBinding && typeof result.runtimeBinding === "object"
110
131
  ? result.runtimeBinding
@@ -165,14 +186,22 @@ const processAgentUpdateChanges = (
165
186
  }
166
187
  if ("machineId" in data) {
167
188
  const machineId = String((data as any).machineId ?? "").trim();
168
-
169
- // Determine effective apiSource: prefer data.apiSource, fall back to previousAgent.apiSource
189
+
190
+ // Determine effective runtime source: prefer form data, fall back to previous agent config
170
191
  const effectiveApiSource = data.apiSource ?? previousAgent?.apiSource;
171
-
192
+ const effectiveCustomProviderUrl =
193
+ data.customProviderUrl ?? previousAgent?.customProviderUrl;
194
+
172
195
  if (machineId) {
173
- // Persist runtimeBinding when effective apiSource is 'cli' or undefined
174
- // undefined = tool/legacy partial update without apiSource context → preserve backward compatibility
175
- if (effectiveApiSource === "cli" || effectiveApiSource === undefined) {
196
+ // Persist runtimeBinding for CLI agents and localhost custom providers.
197
+ // undefined apiSource keeps backward compatibility for legacy partial updates.
198
+ if (
199
+ effectiveApiSource === undefined ||
200
+ shouldPersistMachineBinding({
201
+ apiSource: effectiveApiSource,
202
+ customProviderUrl: effectiveCustomProviderUrl,
203
+ })
204
+ ) {
176
205
  const binding: AgentRuntimeBinding = {
177
206
  ...((changes.runtimeBinding && typeof changes.runtimeBinding === "object")
178
207
  ? changes.runtimeBinding
@@ -182,10 +211,16 @@ const processAgentUpdateChanges = (
182
211
  };
183
212
  changes.runtimeBinding = binding;
184
213
  }
185
- // If apiSource is explicitly non-cli and machineId is supplied, do not create binding
214
+ // If apiSource is explicitly incompatible with machine binding, do not create binding
186
215
  } else {
187
- // CLEAR branch: clear runtimeBinding when effectiveApiSource is 'cli' or undefined (backward-compatible)
188
- if (effectiveApiSource === "cli" || effectiveApiSource === undefined) {
216
+ // CLEAR branch: clear runtimeBinding when the effective runtime shape can be machine-bound.
217
+ if (
218
+ effectiveApiSource === undefined ||
219
+ shouldPersistMachineBinding({
220
+ apiSource: effectiveApiSource,
221
+ customProviderUrl: effectiveCustomProviderUrl,
222
+ })
223
+ ) {
189
224
  changes.runtimeBinding = null;
190
225
  }
191
226
  }
@@ -12,7 +12,7 @@ export function resolveAvatarUrl(
12
12
  avatarFileId: string | undefined | null,
13
13
  server: string | undefined | null
14
14
  ): string | null {
15
- if (!avatarFileId) return null;
15
+ if (!avatarFileId || avatarFileId === "briefcase") return null;
16
16
  if (avatarFileId.startsWith("http") || avatarFileId.startsWith("blob:")) {
17
17
  return avatarFileId;
18
18
  }
@@ -98,8 +98,7 @@ const AGENT_ORCHESTRATION_INSTRUCTIONS = `--- Agent 编排与协作 ---
98
98
  你所在的系统支持多个子 Agent 和工作流工具,请把自己视为"总协调者":
99
99
 
100
100
  1)子 Agent 协作
101
- - 如果目标 Agent 记录已经声明 delegation.serverBase / runtimeServerBase,工具会自动路由到对应 nolo server;你不需要重复填写 serverBase。
102
- - 如果用户明确给了另一个可访问的 server origin(例如 Windows 机器的 Cloudflare 域名),可以在工具参数里传 serverBase 覆盖自动路由;不要臆造地址,也不要把普通 localhost 当成远端机器。
101
+ - 如果用户明确给了另一个可访问的 server origin(例如 Windows 机器的 Cloudflare 域名),可以在工具参数里显式传 serverBase 把调用发到那台 server;不要臆造地址,也不要把普通 localhost 当成远端机器。
103
102
  - 当用户需要多视角分析或辩论时,你可以:
104
103
  - 先用 callAgent 依次询问多个 Agent 对同一问题的看法;
105
104
  - 在最后一条回复中,用你自己的话帮用户总结这些观点的异同,并给出综合结论。