nolo-cli 0.1.39 → 0.1.41

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 (438) hide show
  1. package/README.md +4 -4
  2. package/agent-runtime/dialogWritePlan.ts +39 -0
  3. package/agent-runtime/hostAdapter.ts +4 -0
  4. package/agent-runtime/hybridRecordStore.ts +5 -3
  5. package/agent-runtime/index.ts +15 -0
  6. package/agent-runtime/localLoop.ts +87 -7
  7. package/agent-runtime/localToolPolicy.ts +2 -13
  8. package/agent-runtime/localWorkspaceTools.ts +42 -110
  9. package/agent-runtime/runtimeToolPolicy.ts +2 -11
  10. package/agent-runtime/runtimeToolSurface.ts +198 -0
  11. package/agent-runtime/types.ts +1 -0
  12. package/agentAliases.ts +2 -1
  13. package/agentRunCommand.ts +10 -32
  14. package/agentRuntimeLocal.ts +1 -0
  15. package/ai/agent/_executeModel.ts +146 -0
  16. package/ai/agent/agentSlice.ts +556 -1
  17. package/ai/agent/appWorkingMemory.ts +126 -0
  18. package/ai/agent/buildEditingContext.ts +378 -0
  19. package/ai/agent/buildSystemPrompt.ts +585 -0
  20. package/ai/agent/canvasEditingContext.ts +49 -0
  21. package/ai/agent/cleanAgentMessages.ts +140 -0
  22. package/ai/agent/cliChatClient.ts +153 -0
  23. package/ai/agent/cliExecutor.ts +314 -40
  24. package/ai/agent/contextCompiler.ts +107 -0
  25. package/ai/agent/contextLayerContract.ts +44 -0
  26. package/ai/agent/createAgentSchema.ts +272 -0
  27. package/ai/agent/currentTimeContext.ts +65 -0
  28. package/ai/agent/executeToolCall.ts +58 -0
  29. package/ai/agent/fetchAgentContexts.ts +42 -0
  30. package/ai/agent/generatePrompt.ts +3 -0
  31. package/ai/agent/getFullChatContextKeys.ts +168 -0
  32. package/ai/agent/guidedCreation/capabilities.ts +84 -0
  33. package/ai/agent/guidedCreation/types.ts +38 -0
  34. package/ai/agent/isLiveAudioOnlyAgent.ts +26 -0
  35. package/ai/agent/liveAudioModel.ts +2 -0
  36. package/ai/agent/pageBuilderHandoffRules.ts +75 -0
  37. package/ai/agent/persistMessageWithFixedId.ts +37 -0
  38. package/ai/agent/planSlice.ts +259 -0
  39. package/ai/agent/referenceUtils.ts +229 -0
  40. package/ai/agent/runAgentBackground.ts +310 -0
  41. package/ai/agent/runAgentClientLoop.ts +164 -0
  42. package/ai/agent/runtimeGuidance.ts +116 -0
  43. package/ai/agent/serverOrigin.ts +7 -0
  44. package/ai/agent/startParallelAgentStreams.ts +424 -0
  45. package/ai/agent/startupProtocol.ts +53 -0
  46. package/ai/agent/streamAgentChatTurn.ts +2001 -0
  47. package/ai/agent/streamAgentChatTurnUtils.ts +860 -0
  48. package/ai/agent/toolFailureGuard.ts +99 -0
  49. package/ai/agent/types.ts +73 -0
  50. package/ai/agent/utils/imageOutput.ts +37 -0
  51. package/ai/agent/utils/publicImageAgentMode.ts +26 -0
  52. package/ai/ai.locale.ts +1095 -0
  53. package/ai/chat/accumulateToolCallChunks.ts +126 -0
  54. package/ai/chat/fetchUtils.ts +143 -0
  55. package/ai/chat/inlineImageUrlsForCustomProvider.ts +117 -0
  56. package/ai/chat/parseApiError.ts +67 -0
  57. package/ai/chat/parseMultilineSSE.ts +95 -0
  58. package/ai/chat/sendOpenAICompletionsRequest.ts +897 -0
  59. package/ai/chat/sendOpenAIResponseRequest.ts +720 -0
  60. package/ai/chat/serverProxyRetry.ts +102 -0
  61. package/ai/chat/shouldUseServerProxy.ts +18 -0
  62. package/ai/chat/streamRetry.ts +46 -0
  63. package/ai/chat/updateTotalUsage.ts +89 -0
  64. package/ai/context/buildReferenceContext.ts +437 -0
  65. package/ai/context/retention.ts +165 -0
  66. package/ai/context/tokenUtils.ts +78 -0
  67. package/ai/llm/agentCapabilities.ts +74 -0
  68. package/ai/llm/deepinfra.ts +79 -0
  69. package/ai/llm/fireworks.ts +68 -0
  70. package/ai/llm/generateRequestBody.ts +165 -0
  71. package/ai/llm/getModelContextWindow.ts +93 -0
  72. package/ai/llm/getPricing.ts +252 -0
  73. package/ai/llm/imagePricing.ts +66 -0
  74. package/ai/llm/isResponseAPIModel.ts +13 -0
  75. package/ai/llm/kimi.ts +23 -0
  76. package/ai/llm/mimo.ts +99 -0
  77. package/ai/llm/mistral.ts +21 -0
  78. package/ai/llm/models.ts +45 -0
  79. package/ai/llm/openrouterModels.ts +6 -0
  80. package/ai/llm/providers.ts +313 -0
  81. package/ai/llm/reasoningModels.ts +27 -0
  82. package/ai/llm/types.ts +82 -0
  83. package/ai/llm/usageRequestOptions.ts +59 -0
  84. package/ai/memory/queryShared.ts +161 -0
  85. package/ai/memory/recentRelationshipRecap.ts +247 -0
  86. package/ai/memory/remember.ts +167 -0
  87. package/ai/memory/store.ts +20 -0
  88. package/ai/memory/storeShared.ts +76 -0
  89. package/ai/memory/types.ts +46 -0
  90. package/ai/memory/understanding.ts +349 -0
  91. package/ai/memory/understandingGreeting.ts +264 -0
  92. package/ai/policy/personalizationDialog.ts +333 -0
  93. package/ai/policy/runtimePolicy.ts +454 -0
  94. package/ai/policy/selfUpdateFields.ts +48 -0
  95. package/ai/policy/types.ts +64 -0
  96. package/ai/skills/referenceRuntime.ts +274 -0
  97. package/ai/skills/skillDiagnostics.ts +251 -0
  98. package/ai/skills/skillDocBuilder.ts +139 -0
  99. package/ai/skills/skillSummaryMarker.ts +26 -0
  100. package/ai/token/calculatePrice.ts +576 -0
  101. package/ai/token/missingUsageEstimate.ts +42 -0
  102. package/ai/token/normalizeUsage.ts +124 -0
  103. package/ai/token/openaiImageGenerationUsage.ts +56 -0
  104. package/ai/token/prepareTokenUsageData.ts +93 -0
  105. package/ai/token/resolveBillingTarget.ts +52 -0
  106. package/ai/token/saveTokenRecord.ts +53 -0
  107. package/ai/token/types.ts +103 -0
  108. package/ai/tools/agent/agentTools.ts +235 -0
  109. package/ai/tools/agent/agentUpdateShared.ts +311 -0
  110. package/ai/tools/agent/callAgentTool.ts +139 -0
  111. package/ai/tools/agent/createAgentTool.ts +512 -0
  112. package/ai/tools/agent/createDialogTool.ts +69 -0
  113. package/ai/tools/agent/createSkillAgentTool.ts +62 -0
  114. package/ai/tools/agent/parallelBudget.ts +221 -0
  115. package/ai/tools/agent/prepareAgentDraftTool.ts +159 -0
  116. package/ai/tools/agent/presets/appBuilderPreset.ts +154 -0
  117. package/ai/tools/agent/runLlmTool.ts +96 -0
  118. package/ai/tools/agent/runStreamingAgentTool.ts +73 -0
  119. package/ai/tools/agent/skillAgentArgs.ts +106 -0
  120. package/ai/tools/agent/startAgentDialogTool.ts +53 -0
  121. package/ai/tools/agent/streamParallelAgentsTool.ts +123 -0
  122. package/ai/tools/agent/updateAgentTool.ts +96 -0
  123. package/ai/tools/agent/updateSelfTool.ts +113 -0
  124. package/ai/tools/amazonProductScraperTool.ts +86 -0
  125. package/ai/tools/apifyActorClient.ts +45 -0
  126. package/ai/tools/appEditGuard.ts +372 -0
  127. package/ai/tools/appReadSnapshot.ts +153 -0
  128. package/ai/tools/appTools.ts +1549 -0
  129. package/ai/tools/applyEditTool.ts +259 -0
  130. package/ai/tools/applyLineEditsTool.ts +315 -0
  131. package/ai/tools/browserTools/click.ts +33 -0
  132. package/ai/tools/browserTools/closeSession.ts +29 -0
  133. package/ai/tools/browserTools/common.ts +27 -0
  134. package/ai/tools/browserTools/openSession.ts +48 -0
  135. package/ai/tools/browserTools/readContent.ts +38 -0
  136. package/ai/tools/browserTools/selectOption.ts +46 -0
  137. package/ai/tools/browserTools/typeText.ts +42 -0
  138. package/ai/tools/category/createCategoryTool.ts +66 -0
  139. package/ai/tools/category/queryContentsByCategoryTool.ts +69 -0
  140. package/ai/tools/category/updateContentCategoryTool.ts +75 -0
  141. package/ai/tools/cfBrowserTools.ts +319 -0
  142. package/ai/tools/cfSpeechToTextTool.ts +49 -0
  143. package/ai/tools/checkEnvTool.ts +102 -0
  144. package/ai/tools/cloudflareCrawlTool.ts +289 -0
  145. package/ai/tools/codeSearchTool.ts +123 -0
  146. package/ai/tools/codeTools.ts +101 -0
  147. package/ai/tools/convertMarxistsBookTool.ts +103 -0
  148. package/ai/tools/createDocTool.ts +132 -0
  149. package/ai/tools/createSkillDocTool.ts +155 -0
  150. package/ai/tools/createWorkflowTool.ts +154 -0
  151. package/ai/tools/delayTool.ts +31 -0
  152. package/ai/tools/deleteSpacesTool.ts +325 -0
  153. package/ai/tools/deleteSpacesToolModel.ts +159 -0
  154. package/ai/tools/devReloadUtils.ts +29 -0
  155. package/ai/tools/dialogMessageSearch.ts +137 -0
  156. package/ai/tools/doctorSkillTool.ts +72 -0
  157. package/ai/tools/ecommerceScraperTool.ts +86 -0
  158. package/ai/tools/emailTools.ts +549 -0
  159. package/ai/tools/evalSkillTool.ts +92 -0
  160. package/ai/tools/exaSearchTool.ts +63 -0
  161. package/ai/tools/execShellTool.ts +266 -0
  162. package/ai/tools/executeSqlTool.ts +192 -0
  163. package/ai/tools/fetchWebpageSupport.ts +333 -0
  164. package/ai/tools/fetchWebpageTool.ts +97 -0
  165. package/ai/tools/geminiImagePreviewTool.ts +386 -0
  166. package/ai/tools/generateDocxTool.ts +215 -0
  167. package/ai/tools/googleSearchScraperTool.ts +106 -0
  168. package/ai/tools/importDataTool.ts +133 -0
  169. package/ai/tools/importSkillTool.ts +162 -0
  170. package/ai/tools/index.ts +2308 -0
  171. package/ai/tools/jdProductScraperTool.ts +821 -0
  172. package/ai/tools/listUserSpacesTool.ts +113 -0
  173. package/ai/tools/localFilesTool.ts +276 -0
  174. package/ai/tools/marxistsOfflineBook.ts +253 -0
  175. package/ai/tools/modelUsageTools.ts +206 -0
  176. package/ai/tools/noloWorkspaceReadTools.ts +467 -0
  177. package/ai/tools/olmOcrTool.ts +33 -0
  178. package/ai/tools/openaiImageTool.ts +267 -0
  179. package/ai/tools/prepareTools.ts +23 -0
  180. package/ai/tools/readDocTool.ts +88 -0
  181. package/ai/tools/readFileTool.ts +214 -0
  182. package/ai/tools/readTool.ts +194 -0
  183. package/ai/tools/readXPostTool.ts +229 -0
  184. package/ai/tools/readXhsProfileTool.ts +627 -0
  185. package/ai/tools/rememberMemoryTool.ts +84 -0
  186. package/ai/tools/remotionVideoTool.ts +151 -0
  187. package/ai/tools/searchDialogMessagesTool.ts +222 -0
  188. package/ai/tools/searchWorkspaceTool.ts +259 -0
  189. package/ai/tools/skillFollowup.ts +86 -0
  190. package/ai/tools/surfWeatherTool.ts +169 -0
  191. package/ai/tools/table/addTableRowTool.ts +217 -0
  192. package/ai/tools/table/createTableTool.ts +315 -0
  193. package/ai/tools/table/rowTools.ts +386 -0
  194. package/ai/tools/table/schemaTools.ts +244 -0
  195. package/ai/tools/table/shareTableTool.ts +148 -0
  196. package/ai/tools/table/toolShared.ts +129 -0
  197. package/ai/tools/taobaoTmallProductScraperTool.ts +49 -0
  198. package/ai/tools/toolApiClient.ts +279 -0
  199. package/ai/tools/toolResultError.ts +42 -0
  200. package/ai/tools/toolRunSlice.ts +303 -0
  201. package/ai/tools/toolSchemaCompatibility.ts +53 -0
  202. package/ai/tools/uiAskChoiceTool.ts +104 -0
  203. package/ai/tools/updateContentTitleTool.ts +84 -0
  204. package/ai/tools/updateDocTool.ts +105 -0
  205. package/ai/tools/updateUserPreferenceProfileTool.ts +153 -0
  206. package/ai/tools/wereadGatewayTool.ts +152 -0
  207. package/ai/tools/whisperTool.ts +76 -0
  208. package/ai/tools/writeFileTool.ts +213 -0
  209. package/ai/tools/youtubeScraperTool.ts +116 -0
  210. package/ai/tools/ziweiChartTool.ts +678 -0
  211. package/ai/types.ts +55 -0
  212. package/ai/workflow/workflowExecutor.ts +323 -0
  213. package/ai/workflow/workflowSlice.ts +73 -0
  214. package/ai/workflow/workflowTypes.ts +106 -0
  215. package/app/actions/syncAppRecord.ts +73 -0
  216. package/app/constants/animationSets.ts +21 -0
  217. package/app/constants/appEditor.ts +99 -0
  218. package/app/favorite/favoriteSlice.ts +690 -0
  219. package/app/favorite/type.ts +43 -0
  220. package/app/hooks/deleteDbKey.ts +233 -0
  221. package/app/i18n/client.ts +13 -0
  222. package/app/i18n/i18n.base.ts +14 -0
  223. package/app/i18n/i18n.config.ts +77 -0
  224. package/app/i18n/index.ts +15 -0
  225. package/app/i18n/mapLanguage.ts +11 -0
  226. package/app/i18n/translations/appBuilder.locale.ts +453 -0
  227. package/app/i18n/translations/error.locale.ts +246 -0
  228. package/app/i18n/translations/interface.locale.ts +2174 -0
  229. package/app/i18n/translations/pricing.locale.ts +397 -0
  230. package/app/i18n/translations/privacy.locale.ts +168 -0
  231. package/app/i18n/translations/seo.locale.ts +129 -0
  232. package/app/i18n/translations/terms.locale.ts +124 -0
  233. package/app/i18n/types.ts +6 -0
  234. package/app/notifications/model.ts +77 -0
  235. package/app/notifications/notificationSlice.ts +141 -0
  236. package/app/reducer.ts +36 -0
  237. package/app/settings/dbActionThunks.ts +34 -0
  238. package/app/settings/defaultSpacePreference.ts +87 -0
  239. package/app/settings/settingSlice.tsx +1212 -0
  240. package/app/settings/settingsRecord.ts +8 -0
  241. package/app/stateViews/runtime.ts +90 -0
  242. package/app/store.ts +55 -0
  243. package/app/theme/colors.ts +280 -0
  244. package/app/theme/fontPreference.ts +77 -0
  245. package/app/theme/theme.config.ts +120 -0
  246. package/app/theme/themeModeBootstrap.ts +123 -0
  247. package/app/types/appSummary.ts +114 -0
  248. package/app/types.ts +358 -0
  249. package/app/utils/appKeys.ts +55 -0
  250. package/app/utils/async.ts +28 -0
  251. package/app/utils/desktopAgentRuntimeTurnClient.ts +73 -0
  252. package/app/utils/env.ts +17 -0
  253. package/app/utils/fileUtils.ts +229 -0
  254. package/app/utils/imageUtils.ts +274 -0
  255. package/app/utils/myContentItems.ts +289 -0
  256. package/app/utils/retryAfter.ts +36 -0
  257. package/app/utils/retryFetch.ts +61 -0
  258. package/app/utils/toast.ts +3 -0
  259. package/auth/action/signUpAction.ts +227 -0
  260. package/auth/adminPermissions.ts +18 -0
  261. package/auth/authSlice.ts +531 -0
  262. package/auth/client/loginRequest.ts +14 -0
  263. package/auth/resetAuthScopedClientState.ts +27 -0
  264. package/auth/routes.ts +178 -0
  265. package/auth/token.ts +63 -0
  266. package/auth/types.ts +40 -0
  267. package/chat/chat.locale.ts +813 -0
  268. package/chat/dialog/actions/addCybotAction.ts +52 -0
  269. package/chat/dialog/actions/addReferenceKeysAction.ts +62 -0
  270. package/chat/dialog/actions/builtinDialogLlm.ts +35 -0
  271. package/chat/dialog/actions/cleanupCliSession.ts +40 -0
  272. package/chat/dialog/actions/createDialogAction.ts +379 -0
  273. package/chat/dialog/actions/createScheduledTaskAction.ts +78 -0
  274. package/chat/dialog/actions/handleSendMessageAction.ts +197 -0
  275. package/chat/dialog/actions/handleSendMessageResolver.ts +27 -0
  276. package/chat/dialog/actions/removeCybotAction.ts +6 -0
  277. package/chat/dialog/actions/removeDialogAgentAction.ts +44 -0
  278. package/chat/dialog/actions/replacePrimaryCybotAction.ts +6 -0
  279. package/chat/dialog/actions/setPrimaryDialogAgentAction.ts +52 -0
  280. package/chat/dialog/actions/updateDialogSummaryAction.ts +430 -0
  281. package/chat/dialog/actions/updateDialogTitleAction.ts +151 -0
  282. package/chat/dialog/actions/updateDialogTitlePolicy.ts +30 -0
  283. package/chat/dialog/actions/updateTokensAction.ts +233 -0
  284. package/chat/dialog/dialogAgents.ts +72 -0
  285. package/chat/dialog/dialogSlice.ts +872 -0
  286. package/chat/dialog/dialogTitle.ts +81 -0
  287. package/chat/dialog/dialogTokenStats.ts +12 -0
  288. package/chat/dialog/dialogUrl.ts +6 -0
  289. package/chat/dialog/goal.ts +108 -0
  290. package/chat/dialog/objectAssistantRegistry.ts +286 -0
  291. package/chat/dialog/schedule.ts +17 -0
  292. package/chat/messages/fetchAndCacheMessages.ts +119 -0
  293. package/chat/messages/fetchConvMsgs.ts +51 -0
  294. package/chat/messages/fileUrl.ts +13 -0
  295. package/chat/messages/messageAgent.ts +8 -0
  296. package/chat/messages/messageContent.ts +199 -0
  297. package/chat/messages/messageContract.ts +88 -0
  298. package/chat/messages/messageSlice.ts +1367 -0
  299. package/chat/messages/toolThunks.ts +625 -0
  300. package/cli/agentAliases.ts +2 -1
  301. package/cli/agentRunCommand.ts +10 -32
  302. package/cli/agentRuntimeLocal.ts +1 -0
  303. package/cli/client/agentRun.ts +67 -95
  304. package/cli/client/localRuntimeAdapter.ts +323 -54
  305. package/cli/commandRegistry.ts +2 -2
  306. package/cli/machineWsRunDispatch.ts +51 -6
  307. package/cli/offlineMarxistsAgentCommand.ts +6 -4
  308. package/client/agentConfigResolver.test.ts +2 -2
  309. package/client/agentRun.test.ts +175 -57
  310. package/client/agentRun.ts +67 -95
  311. package/client/localRuntimeAdapter.test.ts +682 -37
  312. package/client/localRuntimeAdapter.ts +323 -54
  313. package/client/localRuntimeDryRun.test.ts +23 -9
  314. package/client/localToolPolicy.test.ts +4 -4
  315. package/commandRegistry.ts +2 -2
  316. package/core/builtinAgents.ts +209 -0
  317. package/core/config.ts +15 -0
  318. package/core/crypto.ts +51 -0
  319. package/core/generateKeyPairFromSeedV1.ts +15 -0
  320. package/core/generateMainKey.ts +22 -0
  321. package/core/init.ts +41 -0
  322. package/core/localOrigins.ts +8 -0
  323. package/core/password.ts +13 -0
  324. package/core/prefix.ts +23 -0
  325. package/create/editor/transforms/fromMarkdown/index.ts +260 -0
  326. package/create/editor/transforms/fromMarkdown/inline.ts +285 -0
  327. package/create/editor/transforms/fromMarkdown/table.ts +130 -0
  328. package/create/editor/transforms/markdownToSlate.ts +24 -0
  329. package/create/editor/transforms/slateToRenderMarkdown.ts +218 -0
  330. package/create/editor/transforms/slateToSimplifiedMarkdown.ts +224 -0
  331. package/create/editor/transforms/slateToText.ts +33 -0
  332. package/create/editor/utils/slateUtils.ts +233 -0
  333. package/create/space/addSpaceAction.ts +193 -0
  334. package/create/space/category/categoryActions.ts +427 -0
  335. package/create/space/changeSpaceAction.ts +36 -0
  336. package/create/space/constants.ts +8 -0
  337. package/create/space/content/addContentAction.ts +116 -0
  338. package/create/space/content/contentThunks.ts +90 -0
  339. package/create/space/content/deleteContentFromSpaceAction.ts +187 -0
  340. package/create/space/content/deleteMultipleContentAction.ts +112 -0
  341. package/create/space/content/moveContentAction.ts +285 -0
  342. package/create/space/content/updateContentCategoryAction.ts +154 -0
  343. package/create/space/content/updateContentTitleAction.ts +151 -0
  344. package/create/space/content/uploadAndAddFileToSpaceAction.ts +98 -0
  345. package/create/space/contentKeyUtils.ts +117 -0
  346. package/create/space/deleteSpaceAction.ts +276 -0
  347. package/create/space/fetchSpaceAction.ts +70 -0
  348. package/create/space/fetchSpaceSidebarStateAction.ts +26 -0
  349. package/create/space/loadDefaultSpaceAction.ts +57 -0
  350. package/create/space/member/addMemberAction.ts +79 -0
  351. package/create/space/member/fetchUserSpaceMembershipsAction.ts +386 -0
  352. package/create/space/member/memberThunks.ts +47 -0
  353. package/create/space/member/removeMemberAction.ts +67 -0
  354. package/create/space/resolvePreferredSpaceId.ts +113 -0
  355. package/create/space/sidebarVisibleTypes.ts +241 -0
  356. package/create/space/space.locale.ts +1087 -0
  357. package/create/space/spaceAccess.ts +182 -0
  358. package/create/space/spaceCollapsedState.ts +54 -0
  359. package/create/space/spaceKeys.ts +65 -0
  360. package/create/space/spaceSlice.ts +328 -0
  361. package/create/space/spaceThunks.ts +410 -0
  362. package/create/space/types.ts +27 -0
  363. package/create/space/updateSpaceAction.ts +107 -0
  364. package/create/space/utils/permissions.ts +47 -0
  365. package/create/types.ts +21 -0
  366. package/database/actions/agentReadResolution.ts +33 -0
  367. package/database/actions/common.ts +243 -0
  368. package/database/actions/deleteFile.ts +40 -0
  369. package/database/actions/fileContent.ts +125 -0
  370. package/database/actions/patch.ts +155 -0
  371. package/database/actions/read.ts +358 -0
  372. package/database/actions/readAndWait.ts +260 -0
  373. package/database/actions/readRequestManager.ts +120 -0
  374. package/database/actions/readResolution.ts +125 -0
  375. package/database/actions/remove.ts +94 -0
  376. package/database/actions/replication.ts +477 -0
  377. package/database/actions/upload.ts +186 -0
  378. package/database/actions/upsert.ts +56 -0
  379. package/database/actions/write.ts +146 -0
  380. package/database/authority/ownerKey.ts +80 -0
  381. package/database/authority/recordAuthority.ts +67 -0
  382. package/database/authority/userAuthorityRegistry.ts +54 -0
  383. package/database/client/fetchUserData.ts +61 -0
  384. package/database/dbActionThunks.ts +1 -0
  385. package/database/dbSlice.ts +149 -0
  386. package/database/fileRing.ts +51 -0
  387. package/database/fileStorage.ts +232 -0
  388. package/database/fileUrl.ts +34 -0
  389. package/database/keys.ts +767 -0
  390. package/database/queryPrefixes.ts +14 -0
  391. package/database/requests.ts +443 -0
  392. package/database/runtimeServerContext.ts +54 -0
  393. package/database/server/levelAuthorityStore.ts +20 -1
  394. package/database/tenantPlacement.ts +57 -0
  395. package/database/userPreferenceRegister.ts +131 -0
  396. package/database/utils/ulid.ts +1 -0
  397. package/integrations/anthropic/anthropicModels.ts +47 -0
  398. package/integrations/deepseek/models.ts +37 -0
  399. package/integrations/google/models.ts +341 -0
  400. package/integrations/openai/chatCompletionStreamMode.ts +10 -0
  401. package/integrations/openai/filterAndCleanMessages.ts +284 -0
  402. package/integrations/openai/flexTier.ts +102 -0
  403. package/integrations/openai/generateOpenAIRequestBody.ts +274 -0
  404. package/integrations/openai/generateResponseRequestBody.ts +77 -0
  405. package/integrations/openai/models.ts +271 -0
  406. package/integrations/openai/providerBodyCompatibility.ts +23 -0
  407. package/integrations/openai/responsesHelpers.ts +297 -0
  408. package/integrations/x-reader/types.ts +109 -0
  409. package/integrations/xai/models.ts +13 -0
  410. package/integrations/xhs-reader/analyze/profileAnalyzer.ts +205 -0
  411. package/integrations/xhs-reader/backends/playwrightProfileCollector.ts +624 -0
  412. package/integrations/xhs-reader/bridge/readXhsProfileWithBridge.ts +227 -0
  413. package/integrations/xhs-reader/client/xhsWebApiClient.ts +229 -0
  414. package/integrations/xhs-reader/normalize.ts +390 -0
  415. package/integrations/xhs-reader/orchestrator.ts +178 -0
  416. package/integrations/xhs-reader/redaction.ts +68 -0
  417. package/integrations/xhs-reader/types.ts +244 -0
  418. package/integrations/xhs-reader/url.ts +57 -0
  419. package/machineWsRunDispatch.ts +51 -6
  420. package/offlineMarxistsAgentCommand.ts +6 -4
  421. package/package.json +430 -3
  422. package/render/page/createPageAction.ts +183 -0
  423. package/render/page/docSlice.ts +468 -0
  424. package/render/page/types.ts +17 -0
  425. package/render/table/createTableAction.ts +270 -0
  426. package/render/table/deleteTableAction.ts +193 -0
  427. package/render/table/fetchAndCacheTableRows.ts +174 -0
  428. package/render/table/tableSlice.ts +1106 -0
  429. package/render/table/toolValueUtils.ts +363 -0
  430. package/render/table/types.ts +252 -0
  431. package/render/table/utils/tableSerialization.ts +50 -0
  432. package/server/handlers/agentRun/types.ts +104 -0
  433. package/share/action.ts +225 -0
  434. package/share/helpers.ts +302 -0
  435. package/share/keys.ts +243 -0
  436. package/share/publicSharePolicy.ts +27 -0
  437. package/share/shareSlice.ts +53 -0
  438. package/share/types.ts +100 -0
@@ -15,8 +15,8 @@
15
15
 
16
16
  import { exec, execSync, spawn } from "child_process";
17
17
  import { randomUUID } from "node:crypto";
18
- import { mkdtempSync, readFileSync, rmSync } from "node:fs";
19
- import { join } from "node:path";
18
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
19
+ import { isAbsolute, join, resolve } from "node:path";
20
20
  import { tmpdir } from "node:os";
21
21
  import { resolveLaunchableCodexCommand } from "../../connector-experimental/codexBinary";
22
22
  import { buildCliPrompt } from "./cliPrompt";
@@ -26,9 +26,22 @@ import { buildCliPrompt } from "./cliPrompt";
26
26
  /** 已支持的 CLI 工具。新增时在此联合类型追加,并在 EXECUTORS 里注册实现 */
27
27
  export type CliProvider = "copilot" | "gemini" | "codex" | "claude" | "agy";
28
28
 
29
+ /**
30
+ * CLI provider 图片输入。
31
+ *
32
+ * - `source` 是原始输入(本地路径 / data URL / http URL / file URL)
33
+ * - `materializedPath` 是 materialize 后写入磁盘的绝对路径
34
+ * (本地路径保持不变,data URL 写入临时文件,file URL 转换为本地路径)
35
+ * - HTTP/HTTPS URL 目前无法原生传给 CLI,只作为 prompt 引用保留
36
+ */
37
+ export interface CliImageInput {
38
+ source: string;
39
+ materializedPath?: string;
40
+ }
41
+
29
42
  export interface CliExecuteOptions {
30
43
  model?: string;
31
- timeout?: number; // ms,默认 120_000
44
+ timeout?: number; // ms;各 CLI executor 可按任务类型设置自己的默认值
32
45
  cwd?: string;
33
46
  env?: Record<string, string | undefined>;
34
47
  yolo?: boolean; // 允许所有工具,默认 true(后台任务常用)
@@ -41,6 +54,8 @@ export interface CliExecuteOptions {
41
54
  maxTokens?: number;
42
55
  enableThinking?: boolean;
43
56
  thinkingBudget?: number;
57
+ /** 图片输入(本地路径 / data URL / file URL)。materialize 由内部处理。 */
58
+ imageInputs?: CliImageInput[];
44
59
  }
45
60
 
46
61
  export interface CliExecuteResult {
@@ -55,6 +70,8 @@ type CliSessionMessage = {
55
70
  content: string;
56
71
  };
57
72
 
73
+ const DEFAULT_AGY_TIMEOUT_MS = 600_000;
74
+
58
75
  export interface CliSessionHandle {
59
76
  sessionId: string;
60
77
  provider: CliProvider;
@@ -184,6 +201,138 @@ function shouldPassClaudeModel(options: CliExecuteOptions): boolean {
184
201
  return (options.env?.NOLO_CLAUDE_CLI_ALLOW_MODEL ?? process.env.NOLO_CLAUDE_CLI_ALLOW_MODEL) === "1";
185
202
  }
186
203
 
204
+ // ── CLI 图片 materialize ─────────────────────────────────────────────────────
205
+
206
+ const DATA_URL_RE = /^data:image\/([\w.+-]+);base64,([A-Za-z0-9+/=]+)$/;
207
+
208
+ /** data URL extension (without prefix) → 完整扩展名 */
209
+ const MIME_EXT: Record<string, string> = {
210
+ "png": ".png",
211
+ "jpeg": ".jpg",
212
+ "jpg": ".jpg",
213
+ "gif": ".gif",
214
+ "webp": ".webp",
215
+ "svg+xml": ".svg",
216
+ "bmp": ".bmp",
217
+ "tiff": ".tiff",
218
+ "avif": ".avif",
219
+ };
220
+
221
+ function inferExtFromMime(extPart: string): string {
222
+ return MIME_EXT[extPart.toLowerCase().trim()] ?? ".bin";
223
+ }
224
+
225
+ const FILE_URL_RE = /^file:\/\/(.+)$/;
226
+
227
+ /**
228
+ * 将单个 data URL 图片写入临时文件,返回绝对路径。
229
+ * caller 负责在执行完后清理 tempDir。
230
+ */
231
+ function writeDataUrlToTempImage(dataUrl: string, tempDir: string, index: number): string {
232
+ const match = dataUrl.match(DATA_URL_RE);
233
+ if (!match) {
234
+ throw new Error(`Invalid data URL format for image #${index + 1}; expected data:image/<type>;base64,<data>`);
235
+ }
236
+ const [, mimeExt, b64] = match;
237
+ const ext = inferExtFromMime(mimeExt);
238
+ const filePath = join(tempDir, `image-${index + 1}${ext}`);
239
+ writeFileSync(filePath, Buffer.from(b64, "base64"));
240
+ return filePath;
241
+ }
242
+
243
+ /**
244
+ * Materialize image input sources into on-disk paths where possible.
245
+ *
246
+ * - 本地 path / file URL → 解析为绝对路径,无需写临时文件
247
+ * - data:image/...;base64,... → 写入 tempDir 内临时文件
248
+ * - http(s) URL → 不做下载,保留 source 引用;materializedPath 为空
249
+ *
250
+ * 返回 `{ materialized, tempDir }`,caller 需在执行完成后 `rmSync(tempDir, { recursive: true, force: true })`。
251
+ * 当没有任何 data URL 时 tempDir 不会被创建,返回 null。
252
+ */
253
+ export function materializeCliImageInputs(
254
+ imageInputs: CliImageInput[],
255
+ cwd: string,
256
+ ): { materialized: CliImageInput[]; tempDir: string | null } {
257
+ let tempDir: string | null = null;
258
+ const materialized = imageInputs.map((input, index) => {
259
+ const src = input.source.trim();
260
+
261
+ if (src.startsWith("http://") || src.startsWith("https://")) {
262
+ return { ...input, materializedPath: undefined };
263
+ }
264
+
265
+ const fileUrlMatch = src.match(FILE_URL_RE);
266
+ if (fileUrlMatch) {
267
+ const localPath = fileUrlMatch[1];
268
+ return {
269
+ ...input,
270
+ materializedPath: isAbsolute(localPath) ? localPath : resolve(cwd, localPath),
271
+ };
272
+ }
273
+
274
+ if (src.startsWith("data:")) {
275
+ if (!tempDir) {
276
+ tempDir = mkdtempSync(join(tmpdir(), "nolo-cli-assets-"));
277
+ }
278
+ const filePath = writeDataUrlToTempImage(src, tempDir, index);
279
+ return { ...input, materializedPath: filePath };
280
+ }
281
+
282
+ // 本地路径
283
+ return {
284
+ ...input,
285
+ materializedPath: isAbsolute(src) ? src : resolve(cwd, src),
286
+ };
287
+ });
288
+
289
+ return { materialized, tempDir };
290
+ }
291
+
292
+ /**
293
+ * 根据 provider 构建图片降级 prompt 块。
294
+ * Codex 使用原生 `-i` 标志,无需注入 prompt。
295
+ * 其他 provider 使用此函数将图片路径列表注入到 prompt 前面。
296
+ */
297
+ function buildImageReferencePromptBlock(
298
+ provider: CliProvider,
299
+ materialized: CliImageInput[],
300
+ ): { promptSuffix: string; warning: string | null } {
301
+ const label = getCliProviderLabel(provider);
302
+ const localPaths = materialized
303
+ .filter((img) => img.materializedPath)
304
+ .map((img) => img.materializedPath!);
305
+ const httpUrls = materialized
306
+ .filter((img) => !img.materializedPath)
307
+ .map((img) => img.source);
308
+
309
+ const lines: string[] = [];
310
+ if (localPaths.length > 0) {
311
+ lines.push(
312
+ `[User attached image(s) - local file references (accessible at these paths):]`,
313
+ ...localPaths.map((p) => ` - ${p}`),
314
+ `Please read and analyze these image files as part of the user's request.`,
315
+ );
316
+ }
317
+ if (httpUrls.length > 0) {
318
+ lines.push(
319
+ `[User attached image(s) - remote URLs (content not available locally):]`,
320
+ ...httpUrls.map((u) => ` - ${u}`),
321
+ `These remote URLs could not be downloaded automatically. If you cannot access them, describe what you can infer from context.`,
322
+ );
323
+ }
324
+
325
+ const warning =
326
+ materialized.length > 0
327
+ ? `${label} image input is passed as local file references; native image flags are not available in this wrapper.`
328
+ : null;
329
+
330
+ return {
331
+ promptSuffix: lines.length > 0 ? lines.join("\n") + "\n\n" : "",
332
+ warning,
333
+ };
334
+ }
335
+
187
336
  function collectCliCapabilityWarnings(
188
337
  provider: CliProvider,
189
338
  options: CliExecuteOptions
@@ -226,18 +375,51 @@ function resolveCliExecution(
226
375
  provider: CliProvider,
227
376
  prompt: string,
228
377
  options: CliExecuteOptions
229
- ): { prompt: string; options: CliExecuteOptions; warnings: string[] } {
378
+ ): { prompt: string; options: CliExecuteOptions; warnings: string[]; imageTempDir?: string } {
230
379
  const warnings = collectCliCapabilityWarnings(provider, options);
380
+
381
+ // Handle image inputs
382
+ const imageInputs = options.imageInputs ?? [];
383
+ let resolvedPrompt = prompt;
384
+ let resolvedOptions = options;
385
+ let imageTempDir: string | undefined;
386
+
387
+ if (imageInputs.length > 0) {
388
+ const { materialized, tempDir } = materializeCliImageInputs(
389
+ imageInputs,
390
+ options.cwd ?? process.cwd(),
391
+ );
392
+ imageTempDir = tempDir ?? undefined;
393
+
394
+ if (provider === "codex") {
395
+ // Codex uses native -i flags; update options with materialized imageInputs
396
+ resolvedOptions = {
397
+ ...resolvedOptions,
398
+ imageInputs: materialized,
399
+ };
400
+ } else {
401
+ // Non-codex providers: inject image references into prompt
402
+ const block = buildImageReferencePromptBlock(provider, materialized);
403
+ if (block.promptSuffix) {
404
+ resolvedPrompt = block.promptSuffix + resolvedPrompt;
405
+ }
406
+ if (block.warning) {
407
+ warnings.push(block.warning);
408
+ }
409
+ }
410
+ }
411
+
231
412
  if (supportsNativeSystemPrompt(provider) || !options.systemPrompt?.trim()) {
232
- return { prompt, options, warnings };
413
+ return { prompt: resolvedPrompt, options: resolvedOptions, warnings, imageTempDir };
233
414
  }
234
415
  return {
235
- prompt: buildCliPrompt(options.systemPrompt, prompt),
416
+ prompt: buildCliPrompt(options.systemPrompt, resolvedPrompt),
236
417
  options: {
237
- ...options,
418
+ ...resolvedOptions,
238
419
  systemPrompt: undefined,
239
420
  },
240
421
  warnings,
422
+ imageTempDir,
241
423
  };
242
424
  }
243
425
 
@@ -410,6 +592,11 @@ function executeCodex(
410
592
  yolo = true,
411
593
  } = options;
412
594
 
595
+ // Collect materialized image paths from imageInputs
596
+ const imagePaths = (options.imageInputs ?? [])
597
+ .map((img) => img.materializedPath)
598
+ .filter((p): p is string => Boolean(p));
599
+
413
600
  return new Promise((resolve, reject) => {
414
601
  const tempDir = mkdtempSync(join(tmpdir(), "codex-exec-"));
415
602
  const outputFile = join(tempDir, "last-message.txt");
@@ -429,6 +616,10 @@ function executeCodex(
429
616
  args.push("--sandbox");
430
617
  args.push("danger-full-access");
431
618
  }
619
+ // Add image flags for Codex CLI native image support
620
+ for (const imgPath of imagePaths) {
621
+ args.push("-i", imgPath);
622
+ }
432
623
  const start = Date.now();
433
624
  const proc = spawn(executable, [...args, prompt], {
434
625
  cwd,
@@ -569,12 +760,49 @@ function formatCliTimeout(timeoutMs: number) {
569
760
  return `${Math.max(1, Math.ceil(timeoutMs / 1000))}s`;
570
761
  }
571
762
 
763
+ function tailText(value: string, maxChars = 1200): string {
764
+ if (value.length <= maxChars) return value;
765
+ return value.slice(value.length - maxChars);
766
+ }
767
+
768
+ function terminateCliProcessGroup(
769
+ proc: ReturnType<typeof spawn>,
770
+ signal: NodeJS.Signals
771
+ ) {
772
+ const pid = typeof proc.pid === "number" ? proc.pid : 0;
773
+ if (pid > 0 && process.platform !== "win32") {
774
+ try {
775
+ process.kill(-pid, signal);
776
+ return;
777
+ } catch {
778
+ // Fall back to the child process if the group is unavailable.
779
+ }
780
+ }
781
+ try {
782
+ proc.kill(signal);
783
+ } catch {
784
+ // Best effort cleanup only.
785
+ }
786
+ }
787
+
788
+ function buildAgyTimeoutError(timeout: number, stdout: string, stderr: string) {
789
+ const parts = [
790
+ `Antigravity CLI timed out after ${timeout}ms.`,
791
+ "agy print mode is agentic and can keep waiting for the conversation to become fully idle; prefer shorter scoped prompts or split the task into multiple turns.",
792
+ ];
793
+ const stdoutTail = tailText(stdout).trim();
794
+ const stderrTail = tailText(stderr).trim();
795
+ if (stdoutTail) parts.push(`stdout tail:\n${stdoutTail}`);
796
+ if (stderrTail) parts.push(`stderr tail:\n${stderrTail}`);
797
+ return new Error(parts.join("\n"));
798
+ }
799
+
572
800
  function executeAgy(
573
801
  prompt: string,
574
802
  options: CliExecuteOptions
575
803
  ): Promise<CliExecuteResult> {
576
804
  const {
577
- timeout = 120_000,
805
+ timeout = DEFAULT_AGY_TIMEOUT_MS,
578
806
  cwd = process.cwd(),
579
807
  yolo = true,
580
808
  } = options;
@@ -597,15 +825,28 @@ function executeAgy(
597
825
  cwd,
598
826
  env: buildCliProcessEnv(options.env),
599
827
  stdio: ["ignore", "pipe", "pipe"],
828
+ detached: process.platform !== "win32",
600
829
  });
601
830
  let stdout = "";
602
831
  let stderr = "";
603
832
  let timer: ReturnType<typeof setTimeout> | undefined;
833
+ let forceTimer: ReturnType<typeof setTimeout> | undefined;
834
+ let settled = false;
835
+
836
+ const clearTimers = () => {
837
+ if (timer) clearTimeout(timer);
838
+ if (forceTimer) clearTimeout(forceTimer);
839
+ };
604
840
 
605
841
  if (timeout > 0) {
606
842
  timer = setTimeout(() => {
607
- proc.kill("SIGTERM");
608
- reject(new Error(`Antigravity CLI timed out after ${timeout}ms`));
843
+ if (settled) return;
844
+ settled = true;
845
+ terminateCliProcessGroup(proc, "SIGTERM");
846
+ forceTimer = setTimeout(() => {
847
+ terminateCliProcessGroup(proc, "SIGKILL");
848
+ }, 3_000);
849
+ reject(buildAgyTimeoutError(timeout, stdout, stderr));
609
850
  }, timeout + 1_000);
610
851
  }
611
852
 
@@ -618,7 +859,12 @@ function executeAgy(
618
859
  });
619
860
 
620
861
  proc.on("close", (code) => {
621
- if (timer) clearTimeout(timer);
862
+ if (settled) {
863
+ clearTimers();
864
+ return;
865
+ }
866
+ settled = true;
867
+ clearTimers();
622
868
  if (code !== 0 && code !== null) {
623
869
  reject(new Error(`Antigravity CLI exited with code ${code}\nstderr: ${stderr}`));
624
870
  return;
@@ -632,7 +878,9 @@ function executeAgy(
632
878
  });
633
879
 
634
880
  proc.on("error", (err) => {
635
- if (timer) clearTimeout(timer);
881
+ if (settled) return;
882
+ settled = true;
883
+ clearTimers();
636
884
  reject(err);
637
885
  });
638
886
  });
@@ -699,11 +947,17 @@ export async function executeCli(
699
947
  throw new Error(`Unknown CLI provider: "${provider}". Supported: ${Object.keys(EXECUTORS).join(", ")}`);
700
948
  }
701
949
  const resolved = resolveCliExecution(provider, prompt, options);
702
- const result = await executor(resolved.prompt, resolved.options);
703
- return {
704
- ...result,
705
- warnings: [...resolved.warnings, ...(result.warnings ?? [])],
706
- };
950
+ try {
951
+ const result = await executor(resolved.prompt, resolved.options);
952
+ return {
953
+ ...result,
954
+ warnings: [...resolved.warnings, ...(result.warnings ?? [])],
955
+ };
956
+ } finally {
957
+ if (resolved.imageTempDir) {
958
+ rmSync(resolved.imageTempDir, { recursive: true, force: true });
959
+ }
960
+ }
707
961
  }
708
962
 
709
963
  export { buildCliPrompt };
@@ -831,36 +1085,56 @@ export function executeCliStreaming(
831
1085
  ): Promise<CliExecuteResult> {
832
1086
  const resolved = resolveCliExecution(provider, prompt, options);
833
1087
  const executor = EXECUTORS[provider];
1088
+
1089
+ const cleanupImageTempDir = () => {
1090
+ if (resolved.imageTempDir) {
1091
+ rmSync(resolved.imageTempDir, { recursive: true, force: true });
1092
+ }
1093
+ };
1094
+
1095
+ const withCleanup = <T>(promise: Promise<T>): Promise<T> =>
1096
+ promise.finally(cleanupImageTempDir);
1097
+
834
1098
  if (provider === "gemini") {
835
- return executeGeminiStreaming(resolved.prompt, resolved.options as CliExecuteOptions & { onChunk: (chunk: string) => void })
836
- .then((result) => ({ ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] }));
1099
+ return withCleanup(
1100
+ executeGeminiStreaming(resolved.prompt, resolved.options as CliExecuteOptions & { onChunk: (chunk: string) => void })
1101
+ .then((result) => ({ ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] }))
1102
+ );
837
1103
  }
838
1104
  if (provider === "codex") {
839
- return executor(resolved.prompt, resolved.options).then((result) => {
840
- const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
841
- if (merged.text) options.onChunk(merged.text);
842
- return merged;
843
- });
1105
+ return withCleanup(
1106
+ executor(resolved.prompt, resolved.options).then((result) => {
1107
+ const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
1108
+ if (merged.text) options.onChunk(merged.text);
1109
+ return merged;
1110
+ })
1111
+ );
844
1112
  }
845
1113
  if (provider === "claude") {
846
- return executor(resolved.prompt, resolved.options).then((result) => {
847
- const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
848
- if (merged.text) options.onChunk(merged.text);
849
- return merged;
850
- });
1114
+ return withCleanup(
1115
+ executor(resolved.prompt, resolved.options).then((result) => {
1116
+ const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
1117
+ if (merged.text) options.onChunk(merged.text);
1118
+ return merged;
1119
+ })
1120
+ );
851
1121
  }
852
1122
  if (provider === "agy") {
853
- return executor(resolved.prompt, resolved.options).then((result) => {
854
- const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
855
- if (merged.text) options.onChunk(merged.text);
856
- return merged;
857
- });
1123
+ return withCleanup(
1124
+ executor(resolved.prompt, resolved.options).then((result) => {
1125
+ const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
1126
+ if (merged.text) options.onChunk(merged.text);
1127
+ return merged;
1128
+ })
1129
+ );
858
1130
  }
859
1131
  if (provider !== "copilot") {
860
- return executor(resolved.prompt, resolved.options).then((result) => ({
861
- ...result,
862
- warnings: [...resolved.warnings, ...(result.warnings ?? [])],
863
- }));
1132
+ return withCleanup(
1133
+ executor(resolved.prompt, resolved.options).then((result) => ({
1134
+ ...result,
1135
+ warnings: [...resolved.warnings, ...(result.warnings ?? [])],
1136
+ }))
1137
+ );
864
1138
  }
865
1139
 
866
1140
  const {
@@ -871,7 +1145,7 @@ export function executeCliStreaming(
871
1145
  onChunk,
872
1146
  } = resolved.options as CliExecuteOptions & { onChunk: (chunk: string) => void };
873
1147
 
874
- return new Promise((resolve, reject) => {
1148
+ return withCleanup(new Promise<CliExecuteResult>((resolve, reject) => {
875
1149
  const args = [
876
1150
  "copilot", "--",
877
1151
  "-p", resolved.prompt,
@@ -931,7 +1205,7 @@ export function executeCliStreaming(
931
1205
  if (timer) clearTimeout(timer);
932
1206
  reject(err);
933
1207
  });
934
- });
1208
+ }));
935
1209
  }
936
1210
 
937
1211
  function executeGeminiStreaming(
@@ -0,0 +1,107 @@
1
+ // Simple deterministic hash for cache-key purposes (browser + server compatible)
2
+ function createHash(_algo: string) {
3
+ let buf = "";
4
+ return {
5
+ update(s: string) { buf += s; return this; },
6
+ digest(_enc: string) {
7
+ // FNV-1a 32-bit, hex-padded to 8 chars
8
+ let h = 0x811c9dc5;
9
+ for (let i = 0; i < buf.length; i++) {
10
+ h ^= buf.charCodeAt(i);
11
+ h = (h * 0x01000193) >>> 0;
12
+ }
13
+ return h.toString(16).padStart(8, "0");
14
+ },
15
+ };
16
+ }
17
+
18
+ export type ContextLayerOwner =
19
+ | "platform"
20
+ | "agent"
21
+ | "user"
22
+ | "runtime";
23
+
24
+ export type ContextLayerCacheScope = "static" | "session" | "turn";
25
+
26
+ export type ContextLayer = {
27
+ id: string;
28
+ owner: ContextLayerOwner;
29
+ content?: string | null;
30
+ tokenBudget?: number;
31
+ cacheScope?: ContextLayerCacheScope;
32
+ };
33
+
34
+ export type CompiledContextLayer = {
35
+ id: string;
36
+ owner: ContextLayerOwner;
37
+ content: string;
38
+ cacheScope: ContextLayerCacheScope;
39
+ charCount: number;
40
+ estimatedTokens: number;
41
+ tokenBudget?: number;
42
+ budgetStatus?: "within-budget" | "over-budget";
43
+ };
44
+
45
+ export type CompiledContext = {
46
+ content: string;
47
+ layers: CompiledContextLayer[];
48
+ cacheProfile: {
49
+ stablePrefixHash: string;
50
+ stablePrefixLayerIds: string[];
51
+ stablePrefixCharCount: number;
52
+ stablePrefixEstimatedTokens: number;
53
+ };
54
+ };
55
+
56
+ const hasLayerContent = (
57
+ layer: ContextLayer
58
+ ): layer is ContextLayer & { content: string } => Boolean(layer.content);
59
+
60
+ export const estimateContextTokens = (content: string): number =>
61
+ Math.ceil(content.length / 4);
62
+
63
+ export const compileContextLayers = (
64
+ layers: ContextLayer[]
65
+ ): CompiledContext => {
66
+ const compiledLayers = layers
67
+ .filter(hasLayerContent)
68
+ .map((layer): CompiledContextLayer => {
69
+ const estimatedTokens = estimateContextTokens(layer.content);
70
+ return {
71
+ id: layer.id,
72
+ owner: layer.owner,
73
+ content: layer.content,
74
+ cacheScope: layer.cacheScope ?? "turn",
75
+ charCount: layer.content.length,
76
+ estimatedTokens,
77
+ tokenBudget: layer.tokenBudget,
78
+ budgetStatus:
79
+ typeof layer.tokenBudget === "number"
80
+ ? estimatedTokens <= layer.tokenBudget
81
+ ? "within-budget"
82
+ : "over-budget"
83
+ : undefined,
84
+ };
85
+ });
86
+ const stablePrefixLayers: CompiledContextLayer[] = [];
87
+ for (const layer of compiledLayers) {
88
+ if (layer.cacheScope === "turn") break;
89
+ stablePrefixLayers.push(layer);
90
+ }
91
+ const stablePrefixContent = stablePrefixLayers
92
+ .map((layer) => layer.content)
93
+ .join("\n\n");
94
+
95
+ return {
96
+ content: compiledLayers.map((layer) => layer.content).join("\n\n"),
97
+ layers: compiledLayers,
98
+ cacheProfile: {
99
+ stablePrefixHash: createHash("sha256")
100
+ .update(stablePrefixContent)
101
+ .digest("hex"),
102
+ stablePrefixLayerIds: stablePrefixLayers.map((layer) => layer.id),
103
+ stablePrefixCharCount: stablePrefixContent.length,
104
+ stablePrefixEstimatedTokens: estimateContextTokens(stablePrefixContent),
105
+ },
106
+ };
107
+ };
@@ -0,0 +1,44 @@
1
+ type ContextLayerContractOptions = {
2
+ hasRememberMemoryTool?: boolean;
3
+ hasDocTools?: boolean;
4
+ };
5
+
6
+ export const buildContextLayerContractBlock = (
7
+ options: ContextLayerContractOptions = {}
8
+ ): string => {
9
+ const lines = [
10
+ "--- 上下文分层约定 ---",
11
+ "不要把所有信息都塞进同一层。优先利用已有的 memory / knowledge / doc,而不是把它们混成一段长对话。",
12
+ "",
13
+ "层次边界:",
14
+ "1. memory layer:放短到中期、可复用但不必永久挂载的偏好、近期共识和压缩后的经验;要短、可检索、可替换。",
15
+ "2. knowledge layer:放稳定规则、长期有效事实和每轮都会反复依赖的说明;优先通过 prompt / references 自动加载。",
16
+ "3. doc layer:放需要跨轮次持续维护的外部工作台,例如 runbook、mission、incident、checkpoint、idea backlog、experiment log;需要时显式读取和更新。",
17
+ "",
18
+ "写入原则:",
19
+ "- 临时步骤、原始长日志、一次性思路,不要直接写进 memory 或 knowledge。",
20
+ "- 稳定行为规则、长期固定约束,优先沉淀到 knowledge layer。",
21
+ "- 用户偏好、最近形成的协作共识、近期反复有用的经验,优先沉淀到 memory layer。",
22
+ "- 需要跨轮次接力的任务状态、运行手册、事故记录、检查点,优先写入 doc layer。",
23
+ "",
24
+ "读取原则:",
25
+ "- 先用 knowledge layer 解决稳定规则问题。",
26
+ "- 再用 memory layer 补充近期偏好和延续性。",
27
+ "- 需要真实运行现场、任务状态或可共享工作台时,再读 doc layer。",
28
+ "- 当前用户输入始终高于 recent memory;recent memory 高于过旧的 doc 推断。",
29
+ ];
30
+
31
+ if (options.hasRememberMemoryTool) {
32
+ lines.push(
33
+ "- 当某条偏好、近期共识或复用经验对未来明显有帮助时,可以调用 rememberMemory,但要写成简洁可复用的一句话;只有当前 dialog 明确绑定了 space,且内容属于共享协作规则时才写 space memory。"
34
+ );
35
+ }
36
+
37
+ if (options.hasDocTools) {
38
+ lines.push(
39
+ "- 当任务需要 24h 连续运行、跨 dialog 接力或人工与 agent 共读时,优先把 mission / runbook / incident / checkpoint / idea backlog / experiment log 写入 doc layer。"
40
+ );
41
+ }
42
+
43
+ return lines.join("\n");
44
+ };