nolo-cli 0.1.40 → 0.1.42

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 (482) hide show
  1. package/README.md +27 -12
  2. package/agent-runtime/agentThread.ts +222 -0
  3. package/agent-runtime/agentThreadAdmission.ts +74 -0
  4. package/agent-runtime/dialogWritePlan.ts +42 -0
  5. package/agent-runtime/hostAdapter.ts +1 -0
  6. package/agent-runtime/hybridRecordStore.ts +5 -3
  7. package/agent-runtime/index.ts +43 -0
  8. package/agent-runtime/localLoop.ts +31 -2
  9. package/agent-runtime/localToolPolicy.ts +1 -0
  10. package/agent-runtime/localWorkspaceTools.ts +1258 -78
  11. package/agent-runtime/noloWorkspaceTools.ts +20 -1
  12. package/agent-runtime/runtimeToolPolicy.ts +1 -5
  13. package/agent-runtime/runtimeToolSurface.ts +1 -0
  14. package/agentAliases.ts +29 -9
  15. package/agentInternalCommandEntries.ts +11 -3
  16. package/agentMachineCommands.ts +1 -0
  17. package/agentRecordCommands.ts +2 -2
  18. package/agentRecordHelpers.ts +59 -6
  19. package/agentRunCommand.ts +84 -19
  20. package/ai/agent/_executeModel.ts +146 -0
  21. package/ai/agent/agentSlice.ts +556 -1
  22. package/ai/agent/appWorkingMemory.ts +126 -0
  23. package/ai/agent/buildEditingContext.ts +378 -0
  24. package/ai/agent/buildSystemPrompt.ts +599 -0
  25. package/ai/agent/canvasEditingContext.ts +49 -0
  26. package/ai/agent/cleanAgentMessages.ts +140 -0
  27. package/ai/agent/cliChatClient.ts +153 -0
  28. package/ai/agent/cliExecutor.ts +264 -46
  29. package/ai/agent/contextCompiler.ts +107 -0
  30. package/ai/agent/contextLayerContract.ts +44 -0
  31. package/ai/agent/createAgentSchema.ts +272 -0
  32. package/ai/agent/currentTimeContext.ts +65 -0
  33. package/ai/agent/executeToolCall.ts +58 -0
  34. package/ai/agent/fetchAgentContexts.ts +42 -0
  35. package/ai/agent/generatePrompt.ts +3 -0
  36. package/ai/agent/getFullChatContextKeys.ts +168 -0
  37. package/ai/agent/guidedCreation/capabilities.ts +84 -0
  38. package/ai/agent/guidedCreation/types.ts +38 -0
  39. package/ai/agent/isLiveAudioOnlyAgent.ts +26 -0
  40. package/ai/agent/liveAudioModel.ts +2 -0
  41. package/ai/agent/pageBuilderHandoffRules.ts +75 -0
  42. package/ai/agent/persistMessageWithFixedId.ts +37 -0
  43. package/ai/agent/planSlice.ts +259 -0
  44. package/ai/agent/referenceUtils.ts +229 -0
  45. package/ai/agent/runAgentBackground.ts +310 -0
  46. package/ai/agent/runAgentClientLoop.ts +164 -0
  47. package/ai/agent/runtimeGuidance.ts +116 -0
  48. package/ai/agent/serverOrigin.ts +7 -0
  49. package/ai/agent/startParallelAgentStreams.ts +424 -0
  50. package/ai/agent/startupProtocol.ts +53 -0
  51. package/ai/agent/streamAgentChatTurn.ts +2135 -0
  52. package/ai/agent/streamAgentChatTurnUtils.ts +923 -0
  53. package/ai/agent/toolFailureGuard.ts +99 -0
  54. package/ai/agent/types.ts +73 -0
  55. package/ai/agent/utils/imageOutput.ts +37 -0
  56. package/ai/agent/utils/publicImageAgentMode.ts +26 -0
  57. package/ai/ai.locale.ts +1165 -0
  58. package/ai/chat/accumulateToolCallChunks.ts +126 -0
  59. package/ai/chat/fetchUtils.ts +143 -0
  60. package/ai/chat/inlineImageUrlsForCustomProvider.ts +122 -0
  61. package/ai/chat/parseApiError.ts +67 -0
  62. package/ai/chat/parseMultilineSSE.ts +95 -0
  63. package/ai/chat/sendOpenAICompletionsRequest.ts +921 -0
  64. package/ai/chat/sendOpenAIResponseRequest.ts +720 -0
  65. package/ai/chat/serverProxyRetry.ts +102 -0
  66. package/ai/chat/shouldUseServerProxy.ts +18 -0
  67. package/ai/chat/streamRetry.ts +46 -0
  68. package/ai/chat/updateTotalUsage.ts +89 -0
  69. package/ai/context/buildReferenceContext.ts +437 -0
  70. package/ai/context/retention.ts +165 -0
  71. package/ai/context/tokenUtils.ts +78 -0
  72. package/ai/llm/agentCapabilities.ts +74 -0
  73. package/ai/llm/deepinfra.ts +79 -0
  74. package/ai/llm/fireworks.ts +68 -0
  75. package/ai/llm/generateRequestBody.ts +165 -0
  76. package/ai/llm/getModelContextWindow.ts +93 -0
  77. package/ai/llm/getPricing.ts +252 -0
  78. package/ai/llm/imagePricing.ts +66 -0
  79. package/ai/llm/isResponseAPIModel.ts +13 -0
  80. package/ai/llm/kimi.ts +22 -0
  81. package/ai/llm/mimo.ts +99 -0
  82. package/ai/llm/mistral.ts +21 -0
  83. package/ai/llm/models.ts +45 -0
  84. package/ai/llm/openrouterModels.ts +31 -0
  85. package/ai/llm/providers.ts +313 -0
  86. package/ai/llm/reasoningModels.ts +27 -0
  87. package/ai/llm/types.ts +82 -0
  88. package/ai/llm/usageRequestOptions.ts +59 -0
  89. package/ai/memory/policy.ts +49 -0
  90. package/ai/memory/queryShared.ts +167 -0
  91. package/ai/memory/recentRelationshipRecap.ts +251 -0
  92. package/ai/memory/remember.ts +111 -0
  93. package/ai/memory/scope.ts +74 -0
  94. package/ai/memory/store.ts +20 -0
  95. package/ai/memory/storeShared.ts +76 -0
  96. package/ai/memory/types.ts +52 -0
  97. package/ai/memory/understanding.ts +341 -0
  98. package/ai/memory/understandingGreeting.ts +264 -0
  99. package/ai/policy/personalizationDialog.ts +333 -0
  100. package/ai/policy/runtimePolicy.ts +526 -0
  101. package/ai/policy/selfUpdateFields.ts +48 -0
  102. package/ai/policy/types.ts +64 -0
  103. package/ai/skills/referenceRuntime.ts +274 -0
  104. package/ai/skills/skillDiagnostics.ts +251 -0
  105. package/ai/skills/skillDocBuilder.ts +139 -0
  106. package/ai/skills/skillSummaryMarker.ts +26 -0
  107. package/ai/token/calculatePrice.ts +576 -0
  108. package/ai/token/missingUsageEstimate.ts +42 -0
  109. package/ai/token/normalizeUsage.ts +124 -0
  110. package/ai/token/openaiImageGenerationUsage.ts +56 -0
  111. package/ai/token/prepareTokenUsageData.ts +93 -0
  112. package/ai/token/resolveBillingTarget.ts +52 -0
  113. package/ai/token/saveTokenRecord.ts +53 -0
  114. package/ai/token/types.ts +103 -0
  115. package/ai/tools/agent/agentTools.ts +214 -0
  116. package/ai/tools/agent/agentUpdateShared.ts +311 -0
  117. package/ai/tools/agent/callAgentTool.ts +139 -0
  118. package/ai/tools/agent/createAgentTool.ts +512 -0
  119. package/ai/tools/agent/createDialogTool.ts +69 -0
  120. package/ai/tools/agent/createSkillAgentTool.ts +62 -0
  121. package/ai/tools/agent/parallelBudget.ts +221 -0
  122. package/ai/tools/agent/prepareAgentDraftTool.ts +159 -0
  123. package/ai/tools/agent/presets/appBuilderPreset.ts +154 -0
  124. package/ai/tools/agent/runLlmTool.ts +96 -0
  125. package/ai/tools/agent/runStreamingAgentTool.ts +73 -0
  126. package/ai/tools/agent/skillAgentArgs.ts +106 -0
  127. package/ai/tools/agent/startAgentDialogTool.ts +54 -0
  128. package/ai/tools/agent/streamParallelAgentsTool.ts +123 -0
  129. package/ai/tools/agent/updateAgentTool.ts +96 -0
  130. package/ai/tools/agent/updateSelfTool.ts +113 -0
  131. package/ai/tools/amazonProductScraperTool.ts +86 -0
  132. package/ai/tools/apifyActorClient.ts +45 -0
  133. package/ai/tools/appEditGuard.ts +372 -0
  134. package/ai/tools/appReadSnapshot.ts +153 -0
  135. package/ai/tools/appTools.ts +1549 -0
  136. package/ai/tools/applyEditTool.ts +259 -0
  137. package/ai/tools/applyLineEditsTool.ts +315 -0
  138. package/ai/tools/browserTools/click.ts +33 -0
  139. package/ai/tools/browserTools/closeSession.ts +29 -0
  140. package/ai/tools/browserTools/common.ts +27 -0
  141. package/ai/tools/browserTools/openSession.ts +48 -0
  142. package/ai/tools/browserTools/readContent.ts +38 -0
  143. package/ai/tools/browserTools/selectOption.ts +46 -0
  144. package/ai/tools/browserTools/typeText.ts +42 -0
  145. package/ai/tools/category/createCategoryTool.ts +66 -0
  146. package/ai/tools/category/queryContentsByCategoryTool.ts +69 -0
  147. package/ai/tools/category/updateContentCategoryTool.ts +75 -0
  148. package/ai/tools/cfBrowserTools.ts +319 -0
  149. package/ai/tools/cfSpeechToTextTool.ts +49 -0
  150. package/ai/tools/checkEnvTool.ts +102 -0
  151. package/ai/tools/cloudflareCrawlTool.ts +289 -0
  152. package/ai/tools/codeSearchTool.ts +123 -0
  153. package/ai/tools/codeTools.ts +101 -0
  154. package/ai/tools/convertMarxistsBookTool.ts +103 -0
  155. package/ai/tools/createDocTool.ts +132 -0
  156. package/ai/tools/createSkillDocTool.ts +155 -0
  157. package/ai/tools/createWorkflowTool.ts +154 -0
  158. package/ai/tools/delayTool.ts +31 -0
  159. package/ai/tools/deleteSpacesTool.ts +325 -0
  160. package/ai/tools/deleteSpacesToolModel.ts +159 -0
  161. package/ai/tools/devReloadUtils.ts +29 -0
  162. package/ai/tools/dialogMessageSearch.ts +137 -0
  163. package/ai/tools/doctorSkillTool.ts +72 -0
  164. package/ai/tools/ecommerceScraperTool.ts +86 -0
  165. package/ai/tools/emailTools.ts +549 -0
  166. package/ai/tools/evalSkillTool.ts +92 -0
  167. package/ai/tools/exaSearchTool.ts +63 -0
  168. package/ai/tools/execShellTool.ts +266 -0
  169. package/ai/tools/executeSqlTool.ts +192 -0
  170. package/ai/tools/fetchWebpageSupport.ts +333 -0
  171. package/ai/tools/fetchWebpageTool.ts +97 -0
  172. package/ai/tools/geminiImagePreviewTool.ts +386 -0
  173. package/ai/tools/generateDocxTool.ts +215 -0
  174. package/ai/tools/googleSearchScraperTool.ts +106 -0
  175. package/ai/tools/importDataTool.ts +133 -0
  176. package/ai/tools/importSkillTool.ts +162 -0
  177. package/ai/tools/index.ts +2290 -0
  178. package/ai/tools/jdProductScraperTool.ts +821 -0
  179. package/ai/tools/listUserSpacesTool.ts +113 -0
  180. package/ai/tools/localFilesTool.ts +276 -0
  181. package/ai/tools/marxistsOfflineBook.ts +253 -0
  182. package/ai/tools/modelUsageTools.ts +206 -0
  183. package/ai/tools/noloWorkspaceReadTools.ts +467 -0
  184. package/ai/tools/olmOcrTool.ts +33 -0
  185. package/ai/tools/openaiImageTool.ts +267 -0
  186. package/ai/tools/prepareTools.ts +193 -0
  187. package/ai/tools/readDocTool.ts +88 -0
  188. package/ai/tools/readFileTool.ts +214 -0
  189. package/ai/tools/readTool.ts +194 -0
  190. package/ai/tools/readXPostTool.ts +229 -0
  191. package/ai/tools/readXhsProfileTool.ts +638 -0
  192. package/ai/tools/rememberMemoryTool.ts +84 -0
  193. package/ai/tools/remotionVideoTool.ts +151 -0
  194. package/ai/tools/searchDialogMessagesTool.ts +222 -0
  195. package/ai/tools/searchWorkspaceTool.ts +259 -0
  196. package/ai/tools/skillFollowup.ts +86 -0
  197. package/ai/tools/surfWeatherTool.ts +169 -0
  198. package/ai/tools/table/addTableRowTool.ts +217 -0
  199. package/ai/tools/table/createTableTool.ts +326 -0
  200. package/ai/tools/table/rowTools.ts +386 -0
  201. package/ai/tools/table/schemaTools.ts +244 -0
  202. package/ai/tools/table/shareTableTool.ts +148 -0
  203. package/ai/tools/table/toolShared.ts +129 -0
  204. package/ai/tools/taobaoTmallProductScraperTool.ts +49 -0
  205. package/ai/tools/toolApiClient.ts +279 -0
  206. package/ai/tools/toolPacks.ts +19 -0
  207. package/ai/tools/toolResultError.ts +42 -0
  208. package/ai/tools/toolRunSlice.ts +303 -0
  209. package/ai/tools/toolSchemaCompatibility.ts +53 -0
  210. package/ai/tools/uiAskChoiceTool.ts +104 -0
  211. package/ai/tools/updateContentTitleTool.ts +84 -0
  212. package/ai/tools/updateDocTool.ts +105 -0
  213. package/ai/tools/updateUserPreferenceProfileTool.ts +153 -0
  214. package/ai/tools/wereadGatewayTool.ts +152 -0
  215. package/ai/tools/whisperTool.ts +76 -0
  216. package/ai/tools/writeFileTool.ts +213 -0
  217. package/ai/tools/youtubeScraperTool.ts +116 -0
  218. package/ai/tools/ziweiChartTool.ts +678 -0
  219. package/ai/types.ts +58 -0
  220. package/ai/workflow/workflowExecutor.ts +323 -0
  221. package/ai/workflow/workflowSlice.ts +73 -0
  222. package/ai/workflow/workflowTypes.ts +106 -0
  223. package/app/actions/syncAppRecord.ts +73 -0
  224. package/app/constants/animationSets.ts +21 -0
  225. package/app/constants/appEditor.ts +99 -0
  226. package/app/favorite/deletedFavoriteProjection.ts +31 -0
  227. package/app/favorite/favoriteSlice.ts +690 -0
  228. package/app/favorite/type.ts +43 -0
  229. package/app/hooks/deleteDbKey.ts +254 -0
  230. package/app/i18n/client.ts +13 -0
  231. package/app/i18n/i18n.base.ts +14 -0
  232. package/app/i18n/i18n.config.ts +77 -0
  233. package/app/i18n/index.ts +15 -0
  234. package/app/i18n/mapLanguage.ts +11 -0
  235. package/app/i18n/translations/appBuilder.locale.ts +453 -0
  236. package/app/i18n/translations/error.locale.ts +246 -0
  237. package/app/i18n/translations/interface.locale.ts +2206 -0
  238. package/app/i18n/translations/pricing.locale.ts +397 -0
  239. package/app/i18n/translations/privacy.locale.ts +168 -0
  240. package/app/i18n/translations/seo.locale.ts +129 -0
  241. package/app/i18n/translations/terms.locale.ts +124 -0
  242. package/app/i18n/types.ts +6 -0
  243. package/app/notifications/model.ts +77 -0
  244. package/app/notifications/notificationSlice.ts +141 -0
  245. package/app/reducer.ts +36 -0
  246. package/app/settings/dbActionThunks.ts +34 -0
  247. package/app/settings/defaultSpacePreference.ts +87 -0
  248. package/app/settings/settingSlice.tsx +1212 -0
  249. package/app/settings/settingsRecord.ts +8 -0
  250. package/app/stateViews/runtime.ts +90 -0
  251. package/app/store.ts +55 -0
  252. package/app/theme/colors.ts +280 -0
  253. package/app/theme/fontPreference.ts +77 -0
  254. package/app/theme/theme.config.ts +120 -0
  255. package/app/theme/themeModeBootstrap.ts +123 -0
  256. package/app/types/appSummary.ts +118 -0
  257. package/app/types.ts +358 -0
  258. package/app/utils/appKeys.ts +55 -0
  259. package/app/utils/async.ts +28 -0
  260. package/app/utils/desktopAgentRuntimeTurnClient.ts +75 -0
  261. package/app/utils/env.ts +17 -0
  262. package/app/utils/fileUtils.ts +229 -0
  263. package/app/utils/imageUtils.ts +274 -0
  264. package/app/utils/myContentItems.ts +289 -0
  265. package/app/utils/retryAfter.ts +36 -0
  266. package/app/utils/retryFetch.ts +61 -0
  267. package/app/utils/toast.ts +3 -0
  268. package/auth/action/signUpAction.ts +227 -0
  269. package/auth/adminPermissions.ts +78 -0
  270. package/auth/authSlice.ts +531 -0
  271. package/auth/client/loginRequest.ts +14 -0
  272. package/auth/resetAuthScopedClientState.ts +27 -0
  273. package/auth/routes.ts +183 -0
  274. package/auth/token.ts +63 -0
  275. package/auth/types.ts +40 -0
  276. package/chat/chat.locale.ts +817 -0
  277. package/chat/dialog/actions/addCybotAction.ts +52 -0
  278. package/chat/dialog/actions/addReferenceKeysAction.ts +62 -0
  279. package/chat/dialog/actions/builtinDialogLlm.ts +35 -0
  280. package/chat/dialog/actions/cleanupCliSession.ts +40 -0
  281. package/chat/dialog/actions/createDialogAction.ts +379 -0
  282. package/chat/dialog/actions/createScheduledTaskAction.ts +78 -0
  283. package/chat/dialog/actions/handleSendMessageAction.ts +202 -0
  284. package/chat/dialog/actions/handleSendMessageResolver.ts +27 -0
  285. package/chat/dialog/actions/removeCybotAction.ts +6 -0
  286. package/chat/dialog/actions/removeDialogAgentAction.ts +44 -0
  287. package/chat/dialog/actions/replacePrimaryCybotAction.ts +6 -0
  288. package/chat/dialog/actions/setPrimaryDialogAgentAction.ts +52 -0
  289. package/chat/dialog/actions/updateDialogSummaryAction.ts +430 -0
  290. package/chat/dialog/actions/updateDialogTitleAction.ts +151 -0
  291. package/chat/dialog/actions/updateDialogTitlePolicy.ts +30 -0
  292. package/chat/dialog/actions/updateTokensAction.ts +233 -0
  293. package/chat/dialog/dialogAgents.ts +72 -0
  294. package/chat/dialog/dialogAttachmentCleanup.ts +135 -0
  295. package/chat/dialog/dialogSlice.ts +985 -0
  296. package/chat/dialog/dialogTitle.ts +81 -0
  297. package/chat/dialog/dialogTokenStats.ts +12 -0
  298. package/chat/dialog/dialogUrl.ts +6 -0
  299. package/chat/dialog/goal.ts +108 -0
  300. package/chat/dialog/objectAssistantRegistry.ts +286 -0
  301. package/chat/dialog/schedule.ts +17 -0
  302. package/chat/messages/activityCompletion.ts +97 -0
  303. package/chat/messages/fetchAndCacheMessages.ts +119 -0
  304. package/chat/messages/fetchConvMsgs.ts +51 -0
  305. package/chat/messages/fileUrl.ts +13 -0
  306. package/chat/messages/imagePayloadPersistence.ts +22 -0
  307. package/chat/messages/messageAgent.ts +8 -0
  308. package/chat/messages/messageContent.ts +203 -0
  309. package/chat/messages/messageContract.ts +88 -0
  310. package/chat/messages/messageSlice.ts +1386 -0
  311. package/chat/messages/toolThunks.ts +646 -0
  312. package/chat/messages/types.ts +8 -1
  313. package/chat/messages/web/toolDisplayName.ts +686 -0
  314. package/cli/agentAliases.ts +29 -9
  315. package/cli/agentInternalCommandEntries.ts +11 -3
  316. package/cli/agentMachineCommands.ts +1 -0
  317. package/cli/agentRecordCommands.ts +2 -2
  318. package/cli/agentRecordHelpers.ts +59 -6
  319. package/cli/agentRunCommand.ts +84 -19
  320. package/cli/client/agentRun.ts +92 -261
  321. package/cli/client/localRuntimeAdapter.ts +292 -50
  322. package/cli/commandRegistry.ts +7 -4
  323. package/cli/dialogAttachmentCleanup.ts +151 -0
  324. package/cli/dialogCommands.ts +163 -61
  325. package/cli/dialogInternalCommandEntries.ts +1 -1
  326. package/cli/docCreateCommands.ts +345 -0
  327. package/cli/docInternalCommandEntries.ts +11 -0
  328. package/cli/docPageHelpers.ts +80 -0
  329. package/cli/docSkillHelpers.ts +67 -0
  330. package/cli/docSpaceHelpers.ts +46 -0
  331. package/cli/internalCommandEntries.ts +4 -0
  332. package/cli/machineCommands.ts +18 -34
  333. package/cli/memoryCommands.ts +253 -0
  334. package/cli/memoryInternalCommandEntries.ts +9 -0
  335. package/cli/qoderUsageProbe.ts +252 -0
  336. package/cli/scriptCommandEntries.ts +0 -3
  337. package/cli/secretScan.ts +31 -0
  338. package/cli/tableCommands.ts +248 -13
  339. package/cli/workflowInternalCommandEntries.ts +2 -3
  340. package/client/agentRun.test.ts +119 -83
  341. package/client/agentRun.ts +92 -261
  342. package/client/localRuntimeAdapter.test.ts +894 -32
  343. package/client/localRuntimeAdapter.ts +292 -50
  344. package/commandRegistry.ts +7 -4
  345. package/connector-experimental/capabilities.ts +10 -9
  346. package/core/builtinAgents.ts +209 -0
  347. package/core/config.ts +15 -0
  348. package/core/crypto.ts +51 -0
  349. package/core/generateKeyPairFromSeedV1.ts +15 -0
  350. package/core/generateMainKey.ts +22 -0
  351. package/core/init.ts +41 -0
  352. package/core/localOrigins.ts +8 -0
  353. package/core/password.ts +13 -0
  354. package/core/prefix.ts +23 -0
  355. package/create/editor/transforms/fromMarkdown/index.ts +260 -0
  356. package/create/editor/transforms/fromMarkdown/inline.ts +285 -0
  357. package/create/editor/transforms/fromMarkdown/table.ts +130 -0
  358. package/create/editor/transforms/markdownToSlate.ts +24 -0
  359. package/create/editor/transforms/slateToRenderMarkdown.ts +218 -0
  360. package/create/editor/transforms/slateToSimplifiedMarkdown.ts +224 -0
  361. package/create/editor/transforms/slateToText.ts +33 -0
  362. package/create/editor/utils/slateUtils.ts +233 -0
  363. package/create/space/addSpaceAction.ts +193 -0
  364. package/create/space/category/categoryActions.ts +427 -0
  365. package/create/space/changeSpaceAction.ts +36 -0
  366. package/create/space/constants.ts +8 -0
  367. package/create/space/content/addContentAction.ts +116 -0
  368. package/create/space/content/contentThunks.ts +90 -0
  369. package/create/space/content/deleteContentFromSpaceAction.ts +187 -0
  370. package/create/space/content/deleteMultipleContentAction.ts +112 -0
  371. package/create/space/content/moveContentAction.ts +285 -0
  372. package/create/space/content/updateContentCategoryAction.ts +154 -0
  373. package/create/space/content/updateContentTitleAction.ts +151 -0
  374. package/create/space/content/uploadAndAddFileToSpaceAction.ts +98 -0
  375. package/create/space/contentKeyUtils.ts +117 -0
  376. package/create/space/deleteSpaceAction.ts +276 -0
  377. package/create/space/fetchSpaceAction.ts +70 -0
  378. package/create/space/fetchSpaceSidebarStateAction.ts +26 -0
  379. package/create/space/loadDefaultSpaceAction.ts +57 -0
  380. package/create/space/member/addMemberAction.ts +79 -0
  381. package/create/space/member/fetchUserSpaceMembershipsAction.ts +386 -0
  382. package/create/space/member/memberThunks.ts +47 -0
  383. package/create/space/member/removeMemberAction.ts +67 -0
  384. package/create/space/resolvePreferredSpaceId.ts +113 -0
  385. package/create/space/sidebarVisibleTypes.ts +260 -0
  386. package/create/space/space.locale.ts +1087 -0
  387. package/create/space/spaceAccess.ts +182 -0
  388. package/create/space/spaceCollapsedState.ts +54 -0
  389. package/create/space/spaceKeys.ts +65 -0
  390. package/create/space/spaceSlice.ts +328 -0
  391. package/create/space/spaceThunks.ts +410 -0
  392. package/create/space/types.ts +27 -0
  393. package/create/space/updateSpaceAction.ts +107 -0
  394. package/create/space/utils/permissions.ts +47 -0
  395. package/create/types.ts +21 -0
  396. package/database/actions/agentReadResolution.ts +33 -0
  397. package/database/actions/common.ts +243 -0
  398. package/database/actions/deleteFile.ts +40 -0
  399. package/database/actions/fileContent.ts +125 -0
  400. package/database/actions/patch.ts +155 -0
  401. package/database/actions/read.ts +358 -0
  402. package/database/actions/readAndWait.ts +260 -0
  403. package/database/actions/readRequestManager.ts +120 -0
  404. package/database/actions/readResolution.ts +125 -0
  405. package/database/actions/remove.ts +94 -0
  406. package/database/actions/replication.ts +477 -0
  407. package/database/actions/upload.ts +186 -0
  408. package/database/actions/upsert.ts +56 -0
  409. package/database/actions/write.ts +146 -0
  410. package/database/authority/ownerKey.ts +80 -0
  411. package/database/authority/recordAuthority.ts +67 -0
  412. package/database/authority/userAuthorityRegistry.ts +54 -0
  413. package/database/client/fetchUserData.ts +61 -0
  414. package/database/dbActionThunks.ts +1 -0
  415. package/database/dbSlice.ts +149 -0
  416. package/database/fileRing.ts +51 -0
  417. package/database/fileStorage.ts +232 -0
  418. package/database/fileUrl.ts +34 -0
  419. package/database/keys.ts +767 -0
  420. package/database/queryPrefixes.ts +14 -0
  421. package/database/requests.ts +443 -0
  422. package/database/runtimeServerContext.ts +54 -0
  423. package/database/tenantPlacement.ts +57 -0
  424. package/database/userPreferenceRegister.ts +131 -0
  425. package/database/utils/ulid.ts +1 -0
  426. package/dialogAttachmentCleanup.ts +151 -0
  427. package/dialogCommands.ts +163 -61
  428. package/dialogInternalCommandEntries.ts +1 -1
  429. package/docCreateCommands.ts +345 -0
  430. package/docInternalCommandEntries.ts +11 -0
  431. package/docPageHelpers.ts +80 -0
  432. package/docSkillHelpers.ts +67 -0
  433. package/docSpaceHelpers.ts +46 -0
  434. package/integrations/anthropic/anthropicModels.ts +47 -0
  435. package/integrations/deepseek/models.ts +37 -0
  436. package/integrations/google/models.ts +341 -0
  437. package/integrations/openai/chatCompletionStreamMode.ts +10 -0
  438. package/integrations/openai/filterAndCleanMessages.ts +284 -0
  439. package/integrations/openai/flexTier.ts +102 -0
  440. package/integrations/openai/generateOpenAIRequestBody.ts +271 -0
  441. package/integrations/openai/generateResponseRequestBody.ts +77 -0
  442. package/integrations/openai/models.ts +271 -0
  443. package/integrations/openai/providerBodyCompatibility.ts +23 -0
  444. package/integrations/openai/responsesHelpers.ts +297 -0
  445. package/integrations/x-reader/types.ts +109 -0
  446. package/integrations/xai/models.ts +13 -0
  447. package/integrations/xhs-reader/redaction.ts +68 -0
  448. package/integrations/xhs-reader/types.ts +277 -0
  449. package/integrations/xhs-reader/url.ts +80 -0
  450. package/internalCommandEntries.ts +4 -0
  451. package/machineCommands.ts +18 -34
  452. package/memoryCommands.ts +253 -0
  453. package/memoryInternalCommandEntries.ts +9 -0
  454. package/package.json +454 -9
  455. package/qoderUsageProbe.ts +252 -0
  456. package/render/contentIcon/types.ts +167 -0
  457. package/render/page/createPageAction.ts +183 -0
  458. package/render/page/docSlice.ts +495 -0
  459. package/render/page/types.ts +19 -0
  460. package/render/table/createTableAction.ts +274 -0
  461. package/render/table/deleteTableAction.ts +193 -0
  462. package/render/table/fetchAndCacheTableRows.ts +174 -0
  463. package/render/table/tableSlice.ts +1167 -0
  464. package/render/table/toolValueUtils.ts +363 -0
  465. package/render/table/types.ts +262 -0
  466. package/render/table/utils/tableSerialization.ts +50 -0
  467. package/scriptCommandEntries.ts +0 -3
  468. package/secretScan.ts +31 -0
  469. package/server/handlers/agentRun/types.ts +105 -0
  470. package/share/action.ts +225 -0
  471. package/share/helpers.ts +302 -0
  472. package/share/keys.ts +243 -0
  473. package/share/publicSharePolicy.ts +27 -0
  474. package/share/shareSlice.ts +53 -0
  475. package/share/types.ts +100 -0
  476. package/tableCommands.ts +248 -13
  477. package/workflowInternalCommandEntries.ts +2 -3
  478. package/ai/tools/agent/taskRunTool.ts +0 -112
  479. package/cli/client/taskRunPrompt.ts +0 -27
  480. package/cli/taskRunCommand.ts +0 -265
  481. package/client/taskRunPrompt.ts +0 -27
  482. package/taskRunCommand.ts +0 -265
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * CLI Executor - 通过命令行工具执行 AI 任务
3
3
  *
4
- * 设计为可扩展:当前支持 Copilot CLI、Gemini CLI、Codex CLI、Claude CLI 与 Antigravity CLI。
4
+ * 设计为可扩展:当前支持 Copilot CLI、Gemini CLI、Codex CLI、Claude CLI、Antigravity CLI 与 Qoder CLI。
5
5
  *
6
6
  * 注意:
7
7
  * - CLI provider 与普通 model 路由共享 prompt / model / 最近文本上下文这些能力面
@@ -18,13 +18,14 @@ import { randomUUID } from "node:crypto";
18
18
  import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
19
19
  import { isAbsolute, join, resolve } from "node:path";
20
20
  import { tmpdir } from "node:os";
21
+ import { StringDecoder } from "node:string_decoder";
21
22
  import { resolveLaunchableCodexCommand } from "../../connector-experimental/codexBinary";
22
23
  import { buildCliPrompt } from "./cliPrompt";
23
24
 
24
25
  // ── 类型定义 ──────────────────────────────────────────────────────────────────
25
26
 
26
27
  /** 已支持的 CLI 工具。新增时在此联合类型追加,并在 EXECUTORS 里注册实现 */
27
- export type CliProvider = "copilot" | "gemini" | "codex" | "claude" | "agy";
28
+ export type CliProvider = "copilot" | "gemini" | "codex" | "claude" | "agy" | "qoder";
28
29
 
29
30
  /**
30
31
  * CLI provider 图片输入。
@@ -41,7 +42,7 @@ export interface CliImageInput {
41
42
 
42
43
  export interface CliExecuteOptions {
43
44
  model?: string;
44
- timeout?: number; // ms,默认 120_000
45
+ timeout?: number; // ms;各 CLI executor 可按任务类型设置自己的默认值
45
46
  cwd?: string;
46
47
  env?: Record<string, string | undefined>;
47
48
  yolo?: boolean; // 允许所有工具,默认 true(后台任务常用)
@@ -70,6 +71,18 @@ type CliSessionMessage = {
70
71
  content: string;
71
72
  };
72
73
 
74
+ const DEFAULT_AGY_TIMEOUT_MS = 600_000;
75
+ const BUFFERED_STREAMING_PROVIDERS = new Set<CliProvider>([
76
+ "codex",
77
+ "claude",
78
+ "agy",
79
+ "qoder",
80
+ ]);
81
+
82
+ export function isBufferedCliStreamingProvider(provider: CliProvider): boolean {
83
+ return BUFFERED_STREAMING_PROVIDERS.has(provider);
84
+ }
85
+
73
86
  export interface CliSessionHandle {
74
87
  sessionId: string;
75
88
  provider: CliProvider;
@@ -157,12 +170,39 @@ function normalizeProxyEnv(env: Record<string, string | undefined>): Record<stri
157
170
  }
158
171
 
159
172
  function buildCliProcessEnv(extraEnv?: Record<string, string | undefined>) {
173
+ const baseEnv = {
174
+ ...process.env,
175
+ ...extraEnv,
176
+ NO_COLOR: "1",
177
+ };
178
+
179
+ // Enhance PATH on macOS so GUI-launched app can find brew/local tools
180
+ if (process.platform === "darwin") {
181
+ const defaultMacPaths = [
182
+ `${process.env.HOME || ""}/.local/bin`,
183
+ "/opt/homebrew/bin",
184
+ "/opt/homebrew/sbin",
185
+ "/usr/local/bin",
186
+ "/usr/local/sbin",
187
+ `${process.env.HOME || ""}/.bun/bin`,
188
+ `${process.env.HOME || ""}/Library/pnpm`,
189
+ `${process.env.HOME || ""}/.npm-global/bin`,
190
+ `${process.env.HOME || ""}/bin`,
191
+ ];
192
+ const existingPath = baseEnv.PATH || "/usr/bin:/bin:/usr/sbin:/sbin";
193
+ const paths = existingPath.split(":");
194
+ for (const p of defaultMacPaths) {
195
+ if (p && !paths.includes(p)) {
196
+ paths.unshift(p); // Put brew/local paths at the front
197
+ }
198
+ }
199
+ baseEnv.PATH = paths.join(":");
200
+ }
201
+
160
202
  return Object.fromEntries(
161
- Object.entries(normalizeProxyEnv({
162
- ...process.env,
163
- ...extraEnv,
164
- NO_COLOR: "1",
165
- })).filter((entry): entry is [string, string] => typeof entry[1] === "string")
203
+ Object.entries(normalizeProxyEnv(baseEnv)).filter(
204
+ (entry): entry is [string, string] => typeof entry[1] === "string"
205
+ )
166
206
  );
167
207
  }
168
208
 
@@ -176,6 +216,8 @@ function getCliProviderLabel(provider: CliProvider): string {
176
216
  return "Copilot CLI";
177
217
  case "agy":
178
218
  return "Antigravity CLI";
219
+ case "qoder":
220
+ return "Qoder CLI";
179
221
  case "gemini":
180
222
  return "Gemini CLI";
181
223
  }
@@ -192,7 +234,7 @@ function supportsModel(provider: CliProvider): boolean {
192
234
  }
193
235
 
194
236
  function supportsReasoningEffort(provider: CliProvider): boolean {
195
- return provider === "claude" || provider === "copilot";
237
+ return provider === "claude" || provider === "copilot" || provider === "qoder";
196
238
  }
197
239
 
198
240
  function shouldPassClaudeModel(options: CliExecuteOptions): boolean {
@@ -624,8 +666,8 @@ function executeCodex(
624
666
  env: buildCliProcessEnv(options.env),
625
667
  stdio: ["ignore", "pipe", "pipe"],
626
668
  });
627
- let stdout = "";
628
- let stderr = "";
669
+ const stdout = createUtf8Collector();
670
+ const stderr = createUtf8Collector();
629
671
  let timer: ReturnType<typeof setTimeout> | undefined;
630
672
 
631
673
  if (timeout > 0) {
@@ -636,22 +678,24 @@ function executeCodex(
636
678
  }
637
679
 
638
680
  proc.stdout.on("data", (data: Buffer) => {
639
- stdout += data.toString();
681
+ stdout.write(data);
640
682
  });
641
683
 
642
684
  proc.stderr.on("data", (data: Buffer) => {
643
- stderr += data.toString();
685
+ stderr.write(data);
644
686
  });
645
687
 
646
688
  proc.on("close", (code) => {
647
689
  if (timer) clearTimeout(timer);
690
+ const stdoutText = stdout.end();
691
+ const stderrText = stderr.end();
648
692
  if (code !== 0 && code !== null) {
649
693
  rmSync(tempDir, { recursive: true, force: true });
650
- reject(new Error(`Codex CLI exited with code ${code}\nstderr: ${stderr}`));
694
+ reject(new Error(`Codex CLI exited with code ${code}\nstderr: ${stderrText}`));
651
695
  return;
652
696
  }
653
697
 
654
- let text = stdout.trim();
698
+ let text = stdoutText.trim();
655
699
  try {
656
700
  const lastMessage = readFileSync(outputFile, "utf8").trim();
657
701
  if (lastMessage) text = lastMessage;
@@ -663,7 +707,7 @@ function executeCodex(
663
707
 
664
708
  resolve({
665
709
  text,
666
- raw: stdout,
710
+ raw: stdoutText,
667
711
  elapsed: Date.now() - start,
668
712
  });
669
713
  });
@@ -714,8 +758,8 @@ function executeClaude(
714
758
  env: buildCliProcessEnv(options.env),
715
759
  stdio: ["ignore", "pipe", "pipe"],
716
760
  });
717
- let stdout = "";
718
- let stderr = "";
761
+ const stdout = createUtf8Collector();
762
+ const stderr = createUtf8Collector();
719
763
  let timer: ReturnType<typeof setTimeout> | undefined;
720
764
 
721
765
  if (timeout > 0) {
@@ -726,23 +770,25 @@ function executeClaude(
726
770
  }
727
771
 
728
772
  proc.stdout.on("data", (data: Buffer) => {
729
- stdout += data.toString();
773
+ stdout.write(data);
730
774
  });
731
775
 
732
776
  proc.stderr.on("data", (data: Buffer) => {
733
- stderr += data.toString();
777
+ stderr.write(data);
734
778
  });
735
779
 
736
780
  proc.on("close", (code) => {
737
781
  if (timer) clearTimeout(timer);
782
+ const stdoutText = stdout.end();
783
+ const stderrText = stderr.end();
738
784
  if (code !== 0 && code !== null) {
739
- reject(new Error(`Claude CLI exited with code ${code}\nstderr: ${stderr}`));
785
+ reject(new Error(`Claude CLI exited with code ${code}\nstderr: ${stderrText}`));
740
786
  return;
741
787
  }
742
788
 
743
789
  resolve({
744
- text: stdout.trim(),
745
- raw: stdout,
790
+ text: stdoutText.trim(),
791
+ raw: stdoutText,
746
792
  elapsed: Date.now() - start,
747
793
  });
748
794
  });
@@ -758,12 +804,78 @@ function formatCliTimeout(timeoutMs: number) {
758
804
  return `${Math.max(1, Math.ceil(timeoutMs / 1000))}s`;
759
805
  }
760
806
 
807
+ function tailText(value: string, maxChars = 1200): string {
808
+ if (value.length <= maxChars) return value;
809
+ return value.slice(value.length - maxChars);
810
+ }
811
+
812
+ function createUtf8Collector() {
813
+ const decoder = new StringDecoder("utf8");
814
+ let text = "";
815
+ let ended = false;
816
+ const finish = () => {
817
+ if (ended) return "";
818
+ ended = true;
819
+ const chunk = decoder.end();
820
+ if (chunk) text += chunk;
821
+ return chunk;
822
+ };
823
+ return {
824
+ write(data: Buffer): string {
825
+ if (ended) return "";
826
+ const chunk = decoder.write(data);
827
+ text += chunk;
828
+ return chunk;
829
+ },
830
+ finish,
831
+ end(): string {
832
+ finish();
833
+ return text;
834
+ },
835
+ get text() {
836
+ return text;
837
+ },
838
+ };
839
+ }
840
+
841
+ function terminateCliProcessGroup(
842
+ proc: ReturnType<typeof spawn>,
843
+ signal: NodeJS.Signals
844
+ ) {
845
+ const pid = typeof proc.pid === "number" ? proc.pid : 0;
846
+ if (pid > 0 && process.platform !== "win32") {
847
+ try {
848
+ process.kill(-pid, signal);
849
+ return;
850
+ } catch {
851
+ // Fall back to the child process if the group is unavailable.
852
+ }
853
+ }
854
+ try {
855
+ proc.kill(signal);
856
+ } catch {
857
+ // Best effort cleanup only.
858
+ }
859
+ }
860
+
861
+ function buildAgyTimeoutError(timeout: number, stdout: string, stderr: string) {
862
+ const parts = [
863
+ `Antigravity CLI timed out after ${timeout}ms.`,
864
+ "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.",
865
+ ];
866
+ const stdoutTail = tailText(stdout).trim();
867
+ const stderrTail = tailText(stderr).trim();
868
+ if (stdoutTail) parts.push(`stdout tail:\n${stdoutTail}`);
869
+ if (stderrTail) parts.push(`stderr tail:\n${stderrTail}`);
870
+ return new Error(parts.join("\n"));
871
+ }
872
+
761
873
  function executeAgy(
762
874
  prompt: string,
763
875
  options: CliExecuteOptions
764
876
  ): Promise<CliExecuteResult> {
765
877
  const {
766
- timeout = 120_000,
878
+ timeout = DEFAULT_AGY_TIMEOUT_MS,
767
879
  cwd = process.cwd(),
768
880
  yolo = true,
769
881
  } = options;
@@ -786,42 +898,142 @@ function executeAgy(
786
898
  cwd,
787
899
  env: buildCliProcessEnv(options.env),
788
900
  stdio: ["ignore", "pipe", "pipe"],
901
+ detached: process.platform !== "win32",
789
902
  });
790
- let stdout = "";
791
- let stderr = "";
903
+ const stdout = createUtf8Collector();
904
+ const stderr = createUtf8Collector();
792
905
  let timer: ReturnType<typeof setTimeout> | undefined;
906
+ let forceTimer: ReturnType<typeof setTimeout> | undefined;
907
+ let settled = false;
908
+
909
+ const clearTimers = () => {
910
+ if (timer) clearTimeout(timer);
911
+ if (forceTimer) clearTimeout(forceTimer);
912
+ };
793
913
 
794
914
  if (timeout > 0) {
795
915
  timer = setTimeout(() => {
796
- proc.kill("SIGTERM");
797
- reject(new Error(`Antigravity CLI timed out after ${timeout}ms`));
916
+ if (settled) return;
917
+ settled = true;
918
+ terminateCliProcessGroup(proc, "SIGTERM");
919
+ forceTimer = setTimeout(() => {
920
+ terminateCliProcessGroup(proc, "SIGKILL");
921
+ }, 3_000);
922
+ reject(buildAgyTimeoutError(timeout, stdout.end(), stderr.end()));
798
923
  }, timeout + 1_000);
799
924
  }
800
925
 
801
926
  proc.stdout.on("data", (data: Buffer) => {
802
- stdout += data.toString();
927
+ stdout.write(data);
928
+ });
929
+
930
+ proc.stderr.on("data", (data: Buffer) => {
931
+ stderr.write(data);
932
+ });
933
+
934
+ proc.on("close", (code) => {
935
+ if (settled) {
936
+ clearTimers();
937
+ return;
938
+ }
939
+ settled = true;
940
+ clearTimers();
941
+ const stdoutText = stdout.end();
942
+ const stderrText = stderr.end();
943
+ if (code !== 0 && code !== null) {
944
+ console.error("[cliExecutor] agy process exited with non-zero code:", code, "stderr:", stderrText);
945
+ reject(new Error(`Antigravity CLI exited with code ${code}\nstderr: ${stderrText}`));
946
+ return;
947
+ }
948
+
949
+ resolve({
950
+ text: stdoutText.trim(),
951
+ raw: stdoutText,
952
+ elapsed: Date.now() - start,
953
+ });
954
+ });
955
+
956
+ proc.on("error", (err) => {
957
+ if (settled) return;
958
+ settled = true;
959
+ clearTimers();
960
+ console.error("[cliExecutor] agy process error event:", err);
961
+ reject(err);
962
+ });
963
+ });
964
+ }
965
+
966
+ function executeQoder(
967
+ prompt: string,
968
+ options: CliExecuteOptions
969
+ ): Promise<CliExecuteResult> {
970
+ const {
971
+ model,
972
+ reasoningEffort,
973
+ timeout = 120_000,
974
+ cwd = process.cwd(),
975
+ yolo = true,
976
+ } = options;
977
+
978
+ return new Promise((resolve, reject) => {
979
+ const args = ["-p", prompt, "--cwd", cwd];
980
+ if (model) {
981
+ args.push("--model");
982
+ args.push(model);
983
+ }
984
+ if (reasoningEffort) {
985
+ args.push("--reasoning-effort");
986
+ args.push(reasoningEffort);
987
+ }
988
+ if (yolo) {
989
+ args.push("--dangerously-skip-permissions");
990
+ }
991
+
992
+ const start = Date.now();
993
+ const proc = spawn("qoder", args, {
994
+ cwd,
995
+ env: buildCliProcessEnv(options.env),
996
+ stdio: ["ignore", "pipe", "pipe"],
997
+ });
998
+ const stdout = createUtf8Collector();
999
+ const stderr = createUtf8Collector();
1000
+ let timer: ReturnType<typeof setTimeout> | undefined;
1001
+
1002
+ if (timeout > 0) {
1003
+ timer = setTimeout(() => {
1004
+ proc.kill("SIGTERM");
1005
+ reject(new Error(`Qoder CLI timed out after ${timeout}ms`));
1006
+ }, timeout);
1007
+ }
1008
+
1009
+ proc.stdout.on("data", (data: Buffer) => {
1010
+ stdout.write(data);
803
1011
  });
804
1012
 
805
1013
  proc.stderr.on("data", (data: Buffer) => {
806
- stderr += data.toString();
1014
+ stderr.write(data);
807
1015
  });
808
1016
 
809
1017
  proc.on("close", (code) => {
810
1018
  if (timer) clearTimeout(timer);
1019
+ const stdoutText = stdout.end();
1020
+ const stderrText = stderr.end();
811
1021
  if (code !== 0 && code !== null) {
812
- reject(new Error(`Antigravity CLI exited with code ${code}\nstderr: ${stderr}`));
1022
+ console.error("[cliExecutor] qoder process exited with non-zero code:", code, "stderr:", stderrText);
1023
+ reject(new Error(`Qoder CLI exited with code ${code}\nstderr: ${stderrText}`));
813
1024
  return;
814
1025
  }
815
1026
 
816
1027
  resolve({
817
- text: stdout.trim(),
818
- raw: stdout,
1028
+ text: stdoutText.trim(),
1029
+ raw: stdoutText,
819
1030
  elapsed: Date.now() - start,
820
1031
  });
821
1032
  });
822
1033
 
823
1034
  proc.on("error", (err) => {
824
1035
  if (timer) clearTimeout(timer);
1036
+ console.error("[cliExecutor] qoder process error event:", err);
825
1037
  reject(err);
826
1038
  });
827
1039
  });
@@ -838,6 +1050,7 @@ const EXECUTORS: Record<
838
1050
  codex: executeCodex,
839
1051
  claude: executeClaude,
840
1052
  agy: executeAgy,
1053
+ qoder: executeQoder,
841
1054
  };
842
1055
 
843
1056
  function formatCliSessionTask(messages: CliSessionMessage[]): string {
@@ -874,7 +1087,7 @@ function getCliSessionOrThrow(sessionId: string): CliSessionState {
874
1087
  /**
875
1088
  * 执行 CLI 任务
876
1089
  *
877
- * @param provider CLI 工具类型(如 "copilot" | "gemini" | "codex" | "claude" | "agy")
1090
+ * @param provider CLI 工具类型(如 "copilot" | "gemini" | "codex" | "claude" | "agy" | "qoder")
878
1091
  * @param prompt 完整 prompt(system prompt 已由调用方拼好)
879
1092
  * @param options 执行选项
880
1093
  */
@@ -1060,7 +1273,7 @@ export function executeCliStreaming(
1060
1273
  })
1061
1274
  );
1062
1275
  }
1063
- if (provider === "agy") {
1276
+ if (provider === "agy" || provider === "qoder") {
1064
1277
  return withCleanup(
1065
1278
  executor(resolved.prompt, resolved.options).then((result) => {
1066
1279
  const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
@@ -1099,10 +1312,10 @@ export function executeCliStreaming(
1099
1312
  const start = Date.now();
1100
1313
  const proc = spawn("gh", args, {
1101
1314
  cwd,
1102
- env: { ...process.env, NO_COLOR: "1" },
1315
+ env: buildCliProcessEnv(resolved.options.env),
1103
1316
  });
1104
1317
 
1105
- let raw = "";
1318
+ const stdout = createUtf8Collector();
1106
1319
  let timer: ReturnType<typeof setTimeout> | undefined;
1107
1320
 
1108
1321
  if (timeout > 0) {
@@ -1113,8 +1326,7 @@ export function executeCliStreaming(
1113
1326
  }
1114
1327
 
1115
1328
  proc.stdout.on("data", (data: Buffer) => {
1116
- const chunk = data.toString();
1117
- raw += chunk;
1329
+ const chunk = stdout.write(data);
1118
1330
  // 过滤噪音行后再推送
1119
1331
  const cleaned = chunk
1120
1332
  .split("\n")
@@ -1125,6 +1337,7 @@ export function executeCliStreaming(
1125
1337
 
1126
1338
  proc.on("close", (code) => {
1127
1339
  if (timer) clearTimeout(timer);
1340
+ const raw = stdout.end();
1128
1341
  if (code !== 0 && code !== null) {
1129
1342
  reject(new Error(`Copilot CLI exited with code ${code}`));
1130
1343
  return;
@@ -1169,11 +1382,14 @@ function executeGeminiStreaming(
1169
1382
  const start = Date.now();
1170
1383
  const proc = spawn("gemini", args, {
1171
1384
  cwd,
1172
- env: { ...process.env, NO_COLOR: "1", NODE_OPTIONS: "--no-deprecation" },
1385
+ env: buildCliProcessEnv({
1386
+ ...options.env,
1387
+ NODE_OPTIONS: "--no-deprecation",
1388
+ }),
1173
1389
  });
1174
1390
 
1175
- let raw = "";
1176
- let stderr = "";
1391
+ const stdout = createUtf8Collector();
1392
+ const stderr = createUtf8Collector();
1177
1393
  let lineBuffer = "";
1178
1394
  let timer: ReturnType<typeof setTimeout> | undefined;
1179
1395
 
@@ -1198,8 +1414,7 @@ function executeGeminiStreaming(
1198
1414
  }
1199
1415
 
1200
1416
  proc.stdout.on("data", (data: Buffer) => {
1201
- const chunk = data.toString();
1202
- raw += chunk;
1417
+ const chunk = stdout.write(data);
1203
1418
  lineBuffer += chunk;
1204
1419
 
1205
1420
  let newlineIndex = lineBuffer.indexOf("\n");
@@ -1220,15 +1435,18 @@ function executeGeminiStreaming(
1220
1435
  });
1221
1436
 
1222
1437
  proc.stderr.on("data", (data: Buffer) => {
1223
- stderr += data.toString();
1438
+ stderr.write(data);
1224
1439
  });
1225
1440
 
1226
1441
  proc.on("close", (code) => {
1227
1442
  if (timer) clearTimeout(timer);
1443
+ lineBuffer += stdout.finish();
1444
+ const raw = stdout.text;
1445
+ const stderrText = stderr.end();
1228
1446
  flushLineBuffer();
1229
1447
 
1230
1448
  if (code !== 0 && code !== null) {
1231
- reject(new Error(`Gemini CLI exited with code ${code}\nstderr: ${stderr}`));
1449
+ reject(new Error(`Gemini CLI exited with code ${code}\nstderr: ${stderrText}`));
1232
1450
  return;
1233
1451
  }
1234
1452
 
@@ -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
+ };