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
@@ -0,0 +1,267 @@
1
+ import { callToolApi } from "./toolApiClient";
2
+ import { selectCurrentSpaceId } from "../../create/space/spaceSlice";
3
+ import { selectUserId } from "../../auth/authSlice";
4
+ import { selectCurrentServer } from "../../app/settings/settingSlice";
5
+ import { selectCurrentDialogKey } from "../../chat/dialog/dialogSlice";
6
+ import { addContentAction } from "../../create/space/content/addContentAction";
7
+ import { ContentType } from "../../app/types";
8
+ import { fileKey } from "../../database/keys";
9
+ import { buildDatabaseFileContentUrl } from "../../database/fileUrl";
10
+ import { extractCustomId } from "../../core/prefix";
11
+
12
+ const DEFAULT_OPENAI_IMAGE_MODEL = "gpt-image-1.5" as const;
13
+ const DEFAULT_OPENAI_IMAGE_MODEL_V2 = "gpt-image-2" as const;
14
+
15
+ type OpenAIImageInput = {
16
+ data: string;
17
+ mimeType?: string;
18
+ };
19
+
20
+ type OpenAIImageArgs = {
21
+ prompt: string;
22
+ operation?: "generate" | "edit";
23
+ images?: OpenAIImageInput[];
24
+ mask?: OpenAIImageInput;
25
+ size?: "1024x1024" | "1024x1536" | "1536x1024" | "auto";
26
+ quality?: "low" | "medium" | "high" | "auto";
27
+ background?: "transparent" | "opaque" | "auto";
28
+ outputFormat?: "png" | "jpeg" | "webp";
29
+ outputCompression?: number;
30
+ moderation?: "low" | "auto";
31
+ n?: number;
32
+ };
33
+
34
+ const buildOpenAIImageLlmContext = ({
35
+ result,
36
+ userId,
37
+ currentServer,
38
+ }: {
39
+ result: any;
40
+ userId?: string | null;
41
+ currentServer?: string | null;
42
+ }): string | undefined => {
43
+ const files = Array.isArray(result?.files) ? result.files : [];
44
+ if (files.length === 0) return undefined;
45
+
46
+ const lines = [
47
+ "The image generation tool produced the following reusable images.",
48
+ "If you mention, embed, or tabulate these images later, reuse these exact references and never invent placeholder URLs.",
49
+ ];
50
+
51
+ for (let index = 0; index < files.length; index += 1) {
52
+ const file = files[index];
53
+ const bareFileId =
54
+ typeof file?.fileId === "string" && file.fileId.trim()
55
+ ? file.fileId.trim()
56
+ : "";
57
+ const fileDbKey =
58
+ userId && bareFileId ? fileKey.single(userId, bareFileId) : "";
59
+ const fileUrl = buildDatabaseFileContentUrl(
60
+ currentServer,
61
+ fileDbKey || bareFileId
62
+ );
63
+ const originalName =
64
+ typeof file?.metadata?.originalName === "string"
65
+ ? file.metadata.originalName.trim()
66
+ : "";
67
+
68
+ lines.push(`image ${index + 1}:`);
69
+ if (bareFileId) lines.push(`- fileId: ${bareFileId}`);
70
+ if (fileDbKey) lines.push(`- fileDbKey: ${fileDbKey}`);
71
+ if (fileUrl) lines.push(`- url: ${fileUrl}`);
72
+ if (originalName) lines.push(`- name: ${originalName}`);
73
+ }
74
+
75
+ return lines.join("\n");
76
+ };
77
+
78
+ export const openAIGptImageFunctionSchema = {
79
+ name: "openAIGptImage",
80
+ description: [
81
+ "使用 OpenAI GPT Image 1.5 生成或编辑图片。",
82
+ "",
83
+ "使用建议(面向模型):",
84
+ "1. 当用户要为当前项目生成插画、封面、配图、海报、Logo 草图、背景素材时,优先使用本工具。",
85
+ "2. 如果用户提供了现有图片并要求改图、延展、换背景、加元素,也使用本工具,并在 images 中显式传入相关图片。",
86
+ "3. 这是单轮图片生成/编辑工具;如果只是分析图片内容,不要调用它。",
87
+ "",
88
+ "关于 images:",
89
+ "- 不传 images:文生图。",
90
+ "- 传 images:走图片编辑接口。",
91
+ "- images[*].data 支持 Base64、data URL、或 http(s) URL。",
92
+ ].join("\n"),
93
+ parameters: {
94
+ type: "object",
95
+ properties: {
96
+ prompt: {
97
+ type: "string",
98
+ description: "生成或编辑图片的提示词。",
99
+ },
100
+ images: {
101
+ type: "array",
102
+ description: "可选输入图片。传入后会按图片编辑模式处理。",
103
+ items: {
104
+ type: "object",
105
+ properties: {
106
+ data: {
107
+ type: "string",
108
+ description: "图片数据,可为 Base64、data URL、或 http(s) URL。",
109
+ },
110
+ mimeType: {
111
+ type: "string",
112
+ description: "可选 MIME 类型,例如 image/png 或 image/jpeg。",
113
+ },
114
+ },
115
+ required: ["data"],
116
+ },
117
+ },
118
+ size: {
119
+ type: "string",
120
+ description:
121
+ '输出尺寸,可选 "1024x1024"、"1024x1536"、"1536x1024"、"auto"。',
122
+ },
123
+ quality: {
124
+ type: "string",
125
+ description:
126
+ '输出质量,可选 "low"、"medium"、"high"、"auto"。',
127
+ },
128
+ background: {
129
+ type: "string",
130
+ description:
131
+ '背景,可选 "transparent"、"opaque"、"auto"。',
132
+ },
133
+ outputFormat: {
134
+ type: "string",
135
+ description: '输出格式,可选 "png"、"jpeg"、"webp"。',
136
+ },
137
+ outputCompression: {
138
+ type: "number",
139
+ description: "JPEG/WebP 输出压缩率,0-100。",
140
+ },
141
+ moderation: {
142
+ type: "string",
143
+ description: '内容过滤级别,可选 "low" 或 "auto"。',
144
+ },
145
+ n: {
146
+ type: "number",
147
+ description: "一次生成的图片数量。",
148
+ },
149
+ },
150
+ required: ["prompt"],
151
+ },
152
+ };
153
+
154
+ export const openAIGptImageGenerateFunctionSchema = {
155
+ ...openAIGptImageFunctionSchema,
156
+ name: "openAIGptImageGenerate",
157
+ description:
158
+ "使用 OpenAI GPT Image 2 生成新图片。适合文生图,以及把参考图作为灵感来源生成新画面。GPT Image 2 当前不支持 transparent background,默认传 background: \"opaque\"。如果 outputFormat 是 png(或未显式改成 jpeg/webp),不要传 outputCompression。",
159
+ };
160
+
161
+ export const openAIGptImageEditFunctionSchema = {
162
+ ...openAIGptImageFunctionSchema,
163
+ name: "openAIGptImageEdit",
164
+ description:
165
+ "使用 OpenAI GPT Image 2 编辑现有图片。适合单图编辑、多图参考合成,以及带 mask 的精确修改。优先复用用户已上传的原始 http(s) 图片 URL,不要自己手写 data URL 或重编码缩略图。GPT Image 2 当前不支持 transparent background,默认传 background: \"opaque\"。如果 outputFormat 是 png(或未显式改成 jpeg/webp),不要传 outputCompression。",
166
+ };
167
+
168
+ const runOpenAIImageTool = async (
169
+ args: OpenAIImageArgs,
170
+ thunkApi: any,
171
+ model: string
172
+ ): Promise<{ rawData: any; displayData: string; llmContext?: string }> => {
173
+ const trimmedPrompt = args.prompt?.trim();
174
+ if (!trimmedPrompt) {
175
+ throw new Error("prompt 不能为空");
176
+ }
177
+
178
+ const state = thunkApi.getState();
179
+ const currentDialogKey = selectCurrentDialogKey(state);
180
+ const dialogId = currentDialogKey
181
+ ? extractCustomId(currentDialogKey)
182
+ : undefined;
183
+
184
+ const result = await callToolApi(
185
+ thunkApi,
186
+ "/api/openai-image",
187
+ {
188
+ prompt: trimmedPrompt,
189
+ operation: args.operation,
190
+ images: Array.isArray(args.images) ? args.images : [],
191
+ mask: args.mask,
192
+ size: args.size,
193
+ quality: args.quality,
194
+ background: args.background,
195
+ outputFormat: args.outputFormat,
196
+ outputCompression: args.outputCompression,
197
+ moderation: args.moderation,
198
+ n: args.n,
199
+ model,
200
+ dialogId,
201
+ },
202
+ { withAuth: true }
203
+ );
204
+
205
+ const spaceId = selectCurrentSpaceId(state);
206
+ const userId = selectUserId(state);
207
+ const currentServer = selectCurrentServer(state);
208
+
209
+ if (spaceId && userId && result?.files?.length) {
210
+ for (let i = 0; i < result.files.length; i += 1) {
211
+ const file = result.files[i];
212
+ if (!file?.fileId) continue;
213
+ const contentKey = fileKey.single(userId, file.fileId);
214
+ const title = file.metadata?.originalName || `OpenAI Image ${i + 1}`;
215
+ try {
216
+ await addContentAction(
217
+ { spaceId, contentKey, title, type: ContentType.IMAGE },
218
+ { dispatch: thunkApi.dispatch, getState: thunkApi.getState }
219
+ );
220
+ } catch (error) {
221
+ console.warn("[openAIGptImageFunc] Failed to add image to space:", error);
222
+ }
223
+ }
224
+ }
225
+
226
+ const llmContext = buildOpenAIImageLlmContext({
227
+ result,
228
+ userId,
229
+ currentServer,
230
+ });
231
+
232
+ return {
233
+ rawData: result,
234
+ displayData:
235
+ result?.text || "已使用 OpenAI GPT Image 生成新的图片资源。",
236
+ llmContext,
237
+ };
238
+ };
239
+
240
+ export const openAIGptImageGenerateFunc = async (
241
+ args: OpenAIImageArgs,
242
+ thunkApi: any
243
+ ): Promise<{ rawData: any; displayData: string; llmContext?: string }> => {
244
+ return runOpenAIImageTool(
245
+ { ...args, operation: "generate" },
246
+ thunkApi,
247
+ DEFAULT_OPENAI_IMAGE_MODEL_V2
248
+ );
249
+ };
250
+
251
+ export const openAIGptImageEditFunc = async (
252
+ args: OpenAIImageArgs,
253
+ thunkApi: any
254
+ ): Promise<{ rawData: any; displayData: string; llmContext?: string }> => {
255
+ return runOpenAIImageTool(
256
+ { ...args, operation: "edit" },
257
+ thunkApi,
258
+ DEFAULT_OPENAI_IMAGE_MODEL_V2
259
+ );
260
+ };
261
+
262
+ export const openAIGptImageFunc = async (
263
+ args: OpenAIImageArgs,
264
+ thunkApi: any
265
+ ): Promise<{ rawData: any; displayData: string; llmContext?: string }> => {
266
+ return runOpenAIImageTool(args, thunkApi, DEFAULT_OPENAI_IMAGE_MODEL);
267
+ };
@@ -0,0 +1,23 @@
1
+ import {
2
+ toolRegistry,
3
+ toolDefinitionsByName,
4
+ findToolExecutor,
5
+ ToolBehavior,
6
+ } from ".";
7
+ import { canonicalizeToolNames } from "./toolNameAliases";
8
+ import { sanitizeToolForProvider } from "./toolSchemaCompatibility";
9
+
10
+ export const prepareTools = (
11
+ toolNames: string[],
12
+ options?: { provider?: string; disabledToolNames?: string[] }
13
+ ) => {
14
+ // logic moved to mergeAgentToolsWithRuntime for better tiered capabilities
15
+ const disabledToolNames = new Set(
16
+ canonicalizeToolNames(options?.disabledToolNames ?? [])
17
+ );
18
+ return canonicalizeToolNames(toolNames)
19
+ .filter((toolName) => !disabledToolNames.has(toolName))
20
+ .map((toolName: string) => toolRegistry[toolName])
21
+ .map((tool) => sanitizeToolForProvider(tool, options?.provider))
22
+ .filter(Boolean); // 过滤掉未找到的工具
23
+ };
@@ -0,0 +1,88 @@
1
+ // 文件路径: ai/tools/readDocTool.ts
2
+
3
+ import { slateToSimplifiedMarkdown } from "../../create/editor/transforms/slateToSimplifiedMarkdown";
4
+ import type { PageData } from "../../render/page/types";
5
+
6
+ export interface ReadPageToolArgs {
7
+ id?: string; // 对应 dbKey,例如 "page-xxx"
8
+ doc?: string;
9
+ docKey?: string;
10
+ pageKey?: string;
11
+ key?: string;
12
+ }
13
+
14
+ /**
15
+ * [Schema] 定义了 'readDoc' 工具的结构。
16
+ */
17
+ export const readDocFunctionSchema = {
18
+ name: "readDoc",
19
+ description: [
20
+ "读取指定页面的内容,并将结构化的数据转换为 Markdown 格式返回。",
21
+ "如果你拿到了页面的 dbKey(如 page-xxx),请使用此工具查看页面内容。",
22
+ ].join("\n"),
23
+ parameters: {
24
+ type: "object",
25
+ properties: {
26
+ id: {
27
+ type: "string",
28
+ description: "页面/文档的数据库键(dbKey),例如 page-xxx。",
29
+ },
30
+ },
31
+ required: ["id"],
32
+ },
33
+ } as const;
34
+
35
+ export const readPageFunctionSchema = {
36
+ ...readDocFunctionSchema,
37
+ name: "readPage",
38
+ } as const;
39
+
40
+ export const buildReadDocResult = (
41
+ pageData: PageData
42
+ ): { rawData: unknown; displayData: string } => {
43
+ const markdownContent = slateToSimplifiedMarkdown(pageData.slateData || []);
44
+
45
+ const rawData = {
46
+ success: true,
47
+ id: pageData.dbKey,
48
+ title: pageData.title,
49
+ content: markdownContent,
50
+ metadata: {
51
+ spaceId: pageData.spaceId,
52
+ created: pageData.created,
53
+ },
54
+ };
55
+
56
+ const displayData = `已成功读取页面《${pageData.title}》。\n\n内容如下:\n\n${markdownContent}`;
57
+ return { rawData, displayData };
58
+ };
59
+
60
+ /**
61
+ * [Executor] 'readDoc' 工具的执行函数。
62
+ */
63
+ export async function readDocFunc(
64
+ args: ReadPageToolArgs,
65
+ thunkApi: any
66
+ ): Promise<{ rawData: unknown; displayData: string }> {
67
+ const id = args.id ?? args.doc ?? args.docKey ?? args.pageKey ?? args.key;
68
+
69
+ if (!id || !id.toLowerCase().startsWith("page-")) {
70
+ throw new Error(`无效的页面 ID: ${id}。页面 ID 通常以 "page-" 开头。`);
71
+ }
72
+
73
+ try {
74
+ // 1. 从数据库读取原始数据
75
+ const { readAction } = await import("../../database/actions/read");
76
+ const pageData = (await readAction({ dbKey: id }, thunkApi)) as PageData;
77
+
78
+ if (!pageData) {
79
+ throw new Error(`未找到 ID 为 ${id} 的页面。`);
80
+ }
81
+
82
+ return buildReadDocResult(pageData);
83
+ } catch (error: any) {
84
+ throw new Error(`读取页面时出错: ${error.message || String(error)}`);
85
+ }
86
+ }
87
+
88
+ export const readPageFunc = readDocFunc;
@@ -0,0 +1,214 @@
1
+ // 文件路径: packages/ai/tools/readFileTool.ts
2
+
3
+ import { buildToolRequestHeaders, getToolBaseUrl } from "./toolApiClient";
4
+
5
+ // ---- Types ----
6
+
7
+ export type ReadFileArgs = {
8
+ /**
9
+ * 目标文件相对项目根目录(bun-nolo)的路径,例如:
10
+ * - packages/chat/src/messages/web/ToolMessageContent.tsx
11
+ * - packages/server/entry.ts
12
+ */
13
+ filePath: string;
14
+ /**
15
+ * 可选:从该行开始读取(1-based,包含)。
16
+ */
17
+ startLine?: number;
18
+ /**
19
+ * 可选:读取到该行结束(1-based,包含)。
20
+ */
21
+ endLine?: number;
22
+ };
23
+
24
+ // ---- 工具 Schema,供 LLM 调用 ----
25
+
26
+ export const readFileFunctionSchema = {
27
+ name: "readFile",
28
+ description: [
29
+ "从后端服务器读取一个文本文件的完整内容,并辅助行级编辑工具获取精确的行号信息。",
30
+ "",
31
+ "适用场景:",
32
+ "- 在修改文件之前,先获取当前文件的完整内容用于分析。",
33
+ "- 在需要理解某个模块实现时,请求查看对应源文件。",
34
+ "- 在使用 applyLineEdits 按行号修改文件前,先读取文件并基于返回的 lines / lineCount 计算行号。",
35
+ "- 如果使用 startLine/endLine 只读取部分内容:",
36
+ " - lines[0] 对应的真实行号为 lineOffset;",
37
+ " - 全文件总行数为 totalLineCount;",
38
+ " - 计算绝对行号时,请用 lineOffset + index。",
39
+ "- 为 applyLineEdits 提供 originalSnippet:",
40
+ " - 对 replaceRange/deleteRange:从 lines 中取出将要修改的那几行,用 \\n 拼接,作为 originalSnippet 传给 applyLineEdits;",
41
+ " - 对 insertBefore/insertAfter:从 lines 中取出插入点附近的一行原始代码,作为 originalSnippet 传给 applyLineEdits;",
42
+ "",
43
+ "行为约定:",
44
+ "- 当目标文件存在:返回文件的完整文本内容。",
45
+ "- 当目标文件不存在:返回错误信息。",
46
+ "",
47
+ "返回数据约定(rawData 中):",
48
+ "- content:文件完整内容,统一使用 \\n 作为换行符。",
49
+ "- lines:按行拆分后的字符串数组;若使用 startLine/endLine,则 lines[0] 对应 lineOffset。",
50
+ "- lineCount:全文件总行数(即最大可用行号)。",
51
+ "- lineOffset:当使用 startLine/endLine 时,lines[0] 对应的真实行号。",
52
+ "- totalLineCount:全文件总行数(与 lineCount 相同,便于兼容)。",
53
+ "",
54
+ "注意:",
55
+ "- filePath 必须是相对项目根目录(bun-nolo)的相对路径,且不能越出项目根目录。",
56
+ "- 仅适用于文本文件,二进制文件的内容会被当作 UTF-8 文本读取,可能出现乱码。",
57
+ ].join("\n"),
58
+ parameters: {
59
+ type: "object",
60
+ properties: {
61
+ filePath: {
62
+ type: "string",
63
+ description:
64
+ "目标文件相对项目根目录(bun-nolo)的路径,例如: packages/chat/src/messages/web/ToolMessageContent.tsx",
65
+ },
66
+ startLine: {
67
+ type: "number",
68
+ description:
69
+ "可选:从该行开始读取(1-based,包含)。与 endLine 搭配可只读局部内容。",
70
+ },
71
+ endLine: {
72
+ type: "number",
73
+ description:
74
+ "可选:读取到该行结束(1-based,包含)。与 startLine 搭配可只读局部内容。",
75
+ },
76
+ },
77
+ required: ["filePath"],
78
+ },
79
+ };
80
+
81
+ // ---- 预览执行:不读文件,只展示信息 ----
82
+
83
+ export async function readFilePreviewFunc(
84
+ args: ReadFileArgs,
85
+ _thunkApi: any
86
+ ): Promise<{ rawData: any; displayData?: string }> {
87
+ const { filePath, startLine, endLine } = args;
88
+
89
+ if (!filePath || typeof filePath !== "string") {
90
+ throw new Error("readFile 预览失败:必须提供有效的 filePath 字符串。");
91
+ }
92
+
93
+ return {
94
+ rawData: {
95
+ previewOnly: true,
96
+ filePath,
97
+ startLine,
98
+ endLine,
99
+ },
100
+ displayData: `⏸️ 文件读取预览: ${filePath}`,
101
+ };
102
+ }
103
+
104
+ // ---- 真正执行:POST 到后端 /api/read-file ----
105
+
106
+ export async function readFileFunc(
107
+ args: ReadFileArgs,
108
+ thunkApi: any,
109
+ context?: { parentMessageId?: string; signal?: AbortSignal; agentKey?: string }
110
+ ): Promise<{ rawData: any; displayData?: string }> {
111
+ const { filePath, startLine, endLine } = args;
112
+
113
+ if (!filePath || typeof filePath !== "string") {
114
+ throw new Error("读取文件失败:必须提供有效的 filePath 字符串。");
115
+ }
116
+
117
+ try {
118
+ const baseUrl = getToolBaseUrl(thunkApi);
119
+
120
+ if (!baseUrl) {
121
+ throw new Error("读取文件失败:无法获取 readFile 服务器地址。");
122
+ }
123
+
124
+ const apiUrl = `${baseUrl.replace(/\/+$/, "")}/api/read-file`;
125
+
126
+ const response = await fetch(apiUrl, {
127
+ method: "POST",
128
+ headers: buildToolRequestHeaders(thunkApi, {
129
+ withAuth: true,
130
+ agentKey: context?.agentKey,
131
+ }),
132
+ signal: context?.signal,
133
+ body: JSON.stringify({ filePath, startLine, endLine }),
134
+ });
135
+
136
+ const textBody = await response.text();
137
+ let data: any = {};
138
+ try {
139
+ data = textBody ? JSON.parse(textBody) : {};
140
+ } catch {
141
+ // 非 JSON 的情况忽略解析错误
142
+ }
143
+
144
+ if (!response.ok || data?.error) {
145
+ const errMsg =
146
+ data?.error ||
147
+ `readFile API 请求失败,状态码: ${response.status}. 响应: ${textBody}`;
148
+ console.error("readFile API Error:", errMsg);
149
+ throw new Error(errMsg);
150
+ }
151
+
152
+ // 统一换行符为 \n,保证与行级编辑逻辑一致
153
+ const serverContent: string =
154
+ typeof data?.content === "string" ? data.content : "";
155
+ const normalizedContent =
156
+ serverContent.indexOf("\r\n") >= 0
157
+ ? serverContent.replace(/\r\n/g, "\n")
158
+ : serverContent;
159
+
160
+ const lines =
161
+ normalizedContent === "" ? [] : normalizedContent.split("\n");
162
+
163
+ const lineOffset: number =
164
+ typeof data?.lineOffset === "number" ? data.lineOffset : 1;
165
+
166
+ const totalLineCount: number =
167
+ typeof data?.totalLineCount === "number"
168
+ ? data.totalLineCount
169
+ : typeof data?.lineCount === "number"
170
+ ? data.lineCount
171
+ : lines.length;
172
+
173
+ const rangeStart: number =
174
+ typeof data?.rangeStart === "number"
175
+ ? data.rangeStart
176
+ : lines.length
177
+ ? lineOffset
178
+ : 1;
179
+ const rangeEnd: number =
180
+ typeof data?.rangeEnd === "number"
181
+ ? data.rangeEnd
182
+ : lines.length
183
+ ? lineOffset + lines.length - 1
184
+ : 0;
185
+
186
+ const returnedLineCount = lines.length;
187
+
188
+ const rangeInfo =
189
+ totalLineCount === 0
190
+ ? "0 行"
191
+ : rangeStart === 1 && rangeEnd === totalLineCount
192
+ ? `${totalLineCount} 行`
193
+ : `${rangeStart}-${rangeEnd} 行 / 共 ${totalLineCount} 行`;
194
+
195
+ return {
196
+ rawData: {
197
+ applied: true,
198
+ filePath,
199
+ lines,
200
+ totalLineCount,
201
+ lineOffset,
202
+ rangeStart,
203
+ rangeEnd,
204
+ returnedLineCount,
205
+ },
206
+ displayData: `📖 已读取文件: ${filePath}(${rangeInfo})`,
207
+ };
208
+ } catch (error: any) {
209
+ console.error("执行 readFile 时发生错误:", error);
210
+ throw new Error(
211
+ `读取文件 (${filePath}) 失败:${error?.message || String(error)}`
212
+ );
213
+ }
214
+ }