nolo-cli 0.1.13 → 0.1.15

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 (321) hide show
  1. package/README.md +9 -2
  2. package/agent-runtime/hostAdapter.ts +53 -0
  3. package/agent-runtime/index.ts +28 -0
  4. package/agent-runtime/localLoop.ts +62 -0
  5. package/agent-runtime/runtimeDecision.ts +70 -0
  6. package/agent-runtime/types.ts +87 -0
  7. package/agentRunCommand.ts +104 -0
  8. package/agentRuntimeCommands.ts +139 -22
  9. package/agentRuntimeLocal.ts +7 -0
  10. package/ai/agent/_executeModel.ts +118 -0
  11. package/ai/agent/agentSlice.ts +544 -1
  12. package/ai/agent/appWorkingMemory.ts +126 -0
  13. package/ai/agent/avatarUtils.ts +24 -0
  14. package/ai/agent/buildEditingContext.ts +373 -0
  15. package/ai/agent/buildSystemPrompt.ts +532 -0
  16. package/ai/agent/cleanAgentMessages.ts +140 -0
  17. package/ai/agent/cliChatClient.ts +119 -0
  18. package/ai/agent/contextCompiler.ts +107 -0
  19. package/ai/agent/contextLayerContract.ts +44 -0
  20. package/ai/agent/createAgentSchema.ts +234 -0
  21. package/ai/agent/executeToolCall.ts +58 -0
  22. package/ai/agent/fetchAgentContexts.ts +42 -0
  23. package/ai/agent/generatePrompt.ts +3 -0
  24. package/ai/agent/getFullChatContextKeys.ts +168 -0
  25. package/ai/agent/hooks/fetchPublicAgents.ts +133 -0
  26. package/ai/agent/hooks/useAgentConfig.ts +61 -0
  27. package/ai/agent/hooks/useAgentDialog.ts +35 -0
  28. package/ai/agent/hooks/useAgentFormValidation.ts +202 -0
  29. package/ai/agent/hooks/usePublicAgents.ts +473 -0
  30. package/ai/agent/persistMessageWithFixedId.ts +37 -0
  31. package/ai/agent/planSlice.ts +259 -0
  32. package/ai/agent/referenceUtils.ts +229 -0
  33. package/ai/agent/runAgentBackground.ts +238 -0
  34. package/ai/agent/runAgentClientLoop.ts +138 -0
  35. package/ai/agent/runtimeGuidance.ts +97 -0
  36. package/ai/agent/runtimeServerBase.ts +37 -0
  37. package/ai/agent/server/fetchPublicAgents.ts +128 -0
  38. package/ai/agent/startParallelAgentStreams.ts +424 -0
  39. package/ai/agent/startupProtocol.ts +53 -0
  40. package/ai/agent/streamAgentChatTurn.ts +1299 -0
  41. package/ai/agent/streamAgentChatTurnUtils.ts +738 -0
  42. package/ai/agent/types.ts +71 -0
  43. package/ai/agent/utils/imageOutput.ts +39 -0
  44. package/ai/agent/utils/publicImageAgentMode.ts +26 -0
  45. package/ai/agent/utils/sortUtils.ts +250 -0
  46. package/ai/agent/web/referencePickerUtils.ts +146 -0
  47. package/ai/ai.locale.ts +1083 -0
  48. package/ai/chat/accumulateToolCallChunks.ts +95 -0
  49. package/ai/chat/fetchUtils.native.ts +276 -0
  50. package/ai/chat/fetchUtils.ts +153 -0
  51. package/ai/chat/inlineImageUrlsForCustomProvider.ts +117 -0
  52. package/ai/chat/parseApiError.ts +64 -0
  53. package/ai/chat/parseMultilineSSE.ts +95 -0
  54. package/ai/chat/sendOpenAICompletionsRequest.native.ts +682 -0
  55. package/ai/chat/sendOpenAICompletionsRequest.ts +712 -0
  56. package/ai/chat/sendOpenAIResponseRequest.ts +512 -0
  57. package/ai/chat/shouldUseServerProxy.ts +18 -0
  58. package/ai/chat/sseClient.native.ts +91 -0
  59. package/ai/chat/sseClient.ts +67 -0
  60. package/ai/chat/streamReader.native.ts +31 -0
  61. package/ai/chat/streamReader.ts +62 -0
  62. package/ai/chat/updateTotalUsage.ts +72 -0
  63. package/ai/context/buildReferenceContext.ts +437 -0
  64. package/ai/context/calculateContextUsage.ts +133 -0
  65. package/ai/context/retention.ts +165 -0
  66. package/ai/context/tokenUtils.ts +78 -0
  67. package/ai/index.ts +1 -1
  68. package/ai/llm/agentCapabilities.ts +74 -0
  69. package/ai/llm/calculateGeminiImageTokens.ts +57 -0
  70. package/ai/llm/deepinfra.ts +28 -0
  71. package/ai/llm/fireworks.ts +68 -0
  72. package/ai/llm/generateRequestBody.ts +165 -0
  73. package/ai/llm/getModelContextWindow.ts +84 -0
  74. package/ai/llm/getNoloKey.ts +37 -0
  75. package/ai/llm/getPricing.ts +232 -0
  76. package/ai/llm/hooks/useModelPricing.ts +75 -0
  77. package/ai/llm/imagePricing.ts +66 -0
  78. package/ai/llm/isResponseAPIModel.ts +13 -0
  79. package/ai/llm/kimi.ts +18 -0
  80. package/ai/llm/mimo.ts +71 -0
  81. package/ai/llm/mistral.ts +22 -0
  82. package/ai/llm/modelAvatar.ts +427 -0
  83. package/ai/llm/models.ts +45 -0
  84. package/ai/llm/openrouterModels.ts +141 -0
  85. package/ai/llm/providers.ts +307 -0
  86. package/ai/llm/reasoningModels.ts +28 -0
  87. package/ai/llm/types.ts +59 -0
  88. package/ai/llm/usageRequestOptions.ts +59 -0
  89. package/ai/memory/capture.ts +148 -0
  90. package/ai/memory/consolidate.ts +104 -0
  91. package/ai/memory/delete.ts +147 -0
  92. package/ai/memory/overlay.ts +84 -0
  93. package/ai/memory/query.ts +38 -0
  94. package/ai/memory/queryShared.ts +160 -0
  95. package/ai/memory/rank.ts +105 -0
  96. package/ai/memory/recentRelationshipRecap.ts +247 -0
  97. package/ai/memory/remember.ts +167 -0
  98. package/ai/memory/runtime.ts +76 -0
  99. package/ai/memory/store.ts +20 -0
  100. package/ai/memory/storeShared.ts +76 -0
  101. package/ai/memory/types.ts +46 -0
  102. package/ai/memory/understanding.ts +349 -0
  103. package/ai/memory/understandingGreeting.ts +264 -0
  104. package/ai/messages/type.ts +20 -0
  105. package/ai/policy/personalizationDialog.ts +333 -0
  106. package/ai/policy/runtimePolicy.ts +440 -0
  107. package/ai/policy/selfUpdateFields.ts +48 -0
  108. package/ai/policy/types.ts +64 -0
  109. package/ai/skills/referenceRuntime.ts +274 -0
  110. package/ai/skills/skillDiagnostics.ts +251 -0
  111. package/ai/skills/skillDocBuilder.ts +139 -0
  112. package/ai/skills/skillDocProtocol.ts +434 -0
  113. package/ai/skills/skillReferenceSummary.ts +63 -0
  114. package/ai/skills/skillSummaryMarker.ts +26 -0
  115. package/ai/token/calculatePrice.ts +546 -0
  116. package/ai/token/db.ts +98 -0
  117. package/ai/token/externalToolCost.ts +321 -0
  118. package/ai/token/hooks/useRecords.ts +65 -0
  119. package/ai/token/missingUsageEstimate.ts +42 -0
  120. package/ai/token/modelUsageQuery.ts +252 -0
  121. package/ai/token/normalizeUsage.ts +84 -0
  122. package/ai/token/openaiImageGenerationUsage.ts +56 -0
  123. package/ai/token/prepareTokenUsageData.ts +88 -0
  124. package/ai/token/query.ts +88 -0
  125. package/ai/token/queryUserTokens.ts +59 -0
  126. package/ai/token/resolveBillingTarget.ts +52 -0
  127. package/ai/token/saveTokenRecord.ts +53 -0
  128. package/ai/token/serverDialogProjection.ts +78 -0
  129. package/ai/token/serverTokenWriter.ts +143 -0
  130. package/ai/token/stats.ts +21 -0
  131. package/ai/token/tokenThunks.ts +24 -0
  132. package/ai/token/types.ts +93 -0
  133. package/ai/tools/agent/agentTools.ts +176 -0
  134. package/ai/tools/agent/agentUpdateShared.ts +311 -0
  135. package/ai/tools/agent/callAgentTool.ts +139 -0
  136. package/ai/tools/agent/createAgentTool.ts +512 -0
  137. package/ai/tools/agent/createDialogTool.ts +69 -0
  138. package/ai/tools/agent/createSkillAgentTool.ts +62 -0
  139. package/ai/tools/agent/parallelBudget.ts +221 -0
  140. package/ai/tools/agent/presets/appBuilderPreset.ts +147 -0
  141. package/ai/tools/agent/runLlmTool.ts +96 -0
  142. package/ai/tools/agent/runStreamingAgentTool.ts +73 -0
  143. package/ai/tools/agent/skillAgentArgs.ts +106 -0
  144. package/ai/tools/agent/skillAgentPreset.ts +89 -0
  145. package/ai/tools/agent/streamParallelAgentsTool.ts +122 -0
  146. package/ai/tools/agent/updateAgentTool.ts +96 -0
  147. package/ai/tools/agent/updateSelfTool.ts +113 -0
  148. package/ai/tools/amazonProductScraperTool.ts +86 -0
  149. package/ai/tools/apifyActorClient.ts +45 -0
  150. package/ai/tools/appEditGuard.ts +372 -0
  151. package/ai/tools/appReadSnapshot.ts +153 -0
  152. package/ai/tools/appTools.ts +1549 -0
  153. package/ai/tools/applyEditTool.ts +256 -0
  154. package/ai/tools/applyLineEditsTool.ts +312 -0
  155. package/ai/tools/browserTools/click.ts +33 -0
  156. package/ai/tools/browserTools/closeSession.ts +29 -0
  157. package/ai/tools/browserTools/common.ts +27 -0
  158. package/ai/tools/browserTools/openSession.ts +48 -0
  159. package/ai/tools/browserTools/readContent.ts +38 -0
  160. package/ai/tools/browserTools/selectOption.ts +46 -0
  161. package/ai/tools/browserTools/typeText.ts +42 -0
  162. package/ai/tools/category/createCategoryTool.ts +66 -0
  163. package/ai/tools/category/queryContentsByCategoryTool.ts +69 -0
  164. package/ai/tools/category/updateContentCategoryTool.ts +75 -0
  165. package/ai/tools/cfBrowserTools.ts +319 -0
  166. package/ai/tools/cfSpeechToTextTool.ts +49 -0
  167. package/ai/tools/checkEnvTool.ts +65 -0
  168. package/ai/tools/cloudflareCrawlTool.ts +289 -0
  169. package/ai/tools/codeSearchTool.ts +111 -0
  170. package/ai/tools/codeTools.ts +101 -0
  171. package/ai/tools/createDocTool.ts +132 -0
  172. package/ai/tools/createPlanTool.ts +999 -0
  173. package/ai/tools/createSkillDocTool.ts +155 -0
  174. package/ai/tools/createWorkflowTool.ts +154 -0
  175. package/ai/tools/deepseekOcrTool.ts +34 -0
  176. package/ai/tools/delayTool.ts +31 -0
  177. package/ai/tools/deleteSpacesTool.ts +325 -0
  178. package/ai/tools/deleteSpacesToolModel.ts +159 -0
  179. package/ai/tools/devReloadUtils.ts +29 -0
  180. package/ai/tools/dialogMessageSearch.ts +137 -0
  181. package/ai/tools/doctorSkillTool.ts +72 -0
  182. package/ai/tools/ecommerceScraperTool.ts +86 -0
  183. package/ai/tools/emailTools.ts +549 -0
  184. package/ai/tools/evalSkillTool.ts +92 -0
  185. package/ai/tools/exaSearchTool.ts +64 -0
  186. package/ai/tools/execBashTool.ts +379 -0
  187. package/ai/tools/executeSqlTool.ts +192 -0
  188. package/ai/tools/fetchWebpageSupport.ts +309 -0
  189. package/ai/tools/fetchWebpageTool.ts +84 -0
  190. package/ai/tools/geminiImagePreviewTool.ts +361 -0
  191. package/ai/tools/generateDocxTool.ts +215 -0
  192. package/ai/tools/googleSearchScraperTool.ts +106 -0
  193. package/ai/tools/importDataTool.ts +133 -0
  194. package/ai/tools/importSkillTool.ts +162 -0
  195. package/ai/tools/index.ts +1927 -0
  196. package/ai/tools/listFilesTool.ts +82 -0
  197. package/ai/tools/listUserSpacesTool.ts +113 -0
  198. package/ai/tools/modelUsageTools.ts +199 -0
  199. package/ai/tools/olmOcrTool.ts +34 -0
  200. package/ai/tools/openaiImageTool.ts +267 -0
  201. package/ai/tools/prepareTools.ts +23 -0
  202. package/ai/tools/readDocTool.ts +84 -0
  203. package/ai/tools/readFileTool.ts +211 -0
  204. package/ai/tools/readTool.ts +163 -0
  205. package/ai/tools/readXPostTool.ts +233 -0
  206. package/ai/tools/rememberMemoryTool.ts +84 -0
  207. package/ai/tools/remotionVideoTool.ts +151 -0
  208. package/ai/tools/searchDialogMessagesTool.ts +222 -0
  209. package/ai/tools/searchRepoTool.ts +115 -0
  210. package/ai/tools/searchWorkspaceTool.ts +259 -0
  211. package/ai/tools/skillFollowup.ts +86 -0
  212. package/ai/tools/surfWeatherTool.ts +169 -0
  213. package/ai/tools/table/addTableRowTool.ts +217 -0
  214. package/ai/tools/table/createTableTool.ts +315 -0
  215. package/ai/tools/table/rowTools.ts +366 -0
  216. package/ai/tools/table/schemaTools.ts +244 -0
  217. package/ai/tools/table/shareTableTool.ts +148 -0
  218. package/ai/tools/table/toolShared.ts +129 -0
  219. package/ai/tools/toolApiClient.ts +198 -0
  220. package/ai/tools/toolNameAliases.ts +57 -0
  221. package/ai/tools/toolResultError.ts +42 -0
  222. package/ai/tools/toolRunSlice.ts +303 -0
  223. package/ai/tools/toolSchemaCompatibility.ts +53 -0
  224. package/ai/tools/toolVisibility.ts +4 -0
  225. package/ai/tools/types.ts +20 -0
  226. package/ai/tools/uiAskChoiceTool.ts +104 -0
  227. package/ai/tools/updateContentTitleTool.ts +84 -0
  228. package/ai/tools/updateDocTool.ts +105 -0
  229. package/ai/tools/updateUserPreferenceProfileTool.ts +145 -0
  230. package/ai/tools/whisperTool.ts +77 -0
  231. package/ai/tools/writeFileTool.ts +210 -0
  232. package/ai/tools/youtubeScraperTool.ts +116 -0
  233. package/ai/tools/ziweiChartTool.ts +678 -0
  234. package/ai/types.ts +55 -0
  235. package/ai/workflow/workflowExecutor.ts +323 -0
  236. package/ai/workflow/workflowSlice.ts +73 -0
  237. package/ai/workflow/workflowTypes.ts +106 -0
  238. package/client/agentRun.test.ts +240 -0
  239. package/client/agentRun.ts +182 -19
  240. package/client/compactDialog.test.ts +238 -0
  241. package/client/localRuntimeAdapter.test.ts +135 -0
  242. package/client/localRuntimeAdapter.ts +244 -0
  243. package/client/profileConfig.test.ts +40 -0
  244. package/client/streamingOutput.test.ts +22 -0
  245. package/client/streamingOutput.ts +38 -0
  246. package/commandRegistry.ts +11 -2
  247. package/connector-experimental/index.ts +5 -0
  248. package/database/actions/cacheMergedUserData.ts +64 -0
  249. package/database/actions/common.ts +242 -0
  250. package/database/actions/deleteFile.ts +40 -0
  251. package/database/actions/fetchUserData.ts +16 -0
  252. package/database/actions/fileContent.ts +125 -0
  253. package/database/actions/patch.ts +155 -0
  254. package/database/actions/read.ts +337 -0
  255. package/database/actions/readAndWait.ts +224 -0
  256. package/database/actions/readRequestManager.ts +120 -0
  257. package/database/actions/remove.ts +94 -0
  258. package/database/actions/replication.ts +366 -0
  259. package/database/actions/upload.ts +174 -0
  260. package/database/actions/upsert.ts +56 -0
  261. package/database/actions/write.ts +126 -0
  262. package/database/client/db.native.ts +73 -0
  263. package/database/client/db.ts +51 -0
  264. package/database/client/fetchUserData.ts +61 -0
  265. package/database/client/handleError.ts +19 -0
  266. package/database/client/queryRequest.ts +21 -0
  267. package/database/config.ts +21 -0
  268. package/database/dbActionThunks.ts +1 -0
  269. package/database/dbSlice.ts +149 -0
  270. package/database/email.ts +42 -0
  271. package/database/fileRing.ts +51 -0
  272. package/database/fileSharding.ts +70 -0
  273. package/database/fileStorage.native.ts +92 -0
  274. package/database/fileStorage.ts +232 -0
  275. package/database/fileUrl.ts +34 -0
  276. package/database/hooks/useUserData.ts +489 -0
  277. package/database/index.ts +1 -0
  278. package/database/keys.ts +765 -0
  279. package/database/queryPrefixes.ts +14 -0
  280. package/database/requests.ts +443 -0
  281. package/database/runtimeServerContext.ts +35 -0
  282. package/database/server/MemoryDB.ts +76 -0
  283. package/database/server/actorAccess.ts +76 -0
  284. package/database/server/agentDelegation.ts +124 -0
  285. package/database/server/coreDataOwnership.ts +13 -0
  286. package/database/server/coreDataProxy.ts +76 -0
  287. package/database/server/cybotReadonly.ts +18 -0
  288. package/database/server/dataHandlers.ts +111 -0
  289. package/database/server/db.ts +118 -0
  290. package/database/server/dbPath.ts +20 -0
  291. package/database/server/delete.ts +499 -0
  292. package/database/server/emailRepository.ts +1480 -0
  293. package/database/server/ensureDbOpen.ts +12 -0
  294. package/database/server/fileRead.ts +337 -0
  295. package/database/server/fileService.ts +436 -0
  296. package/database/server/handleTransaction.ts +86 -0
  297. package/database/server/patch.ts +282 -0
  298. package/database/server/query.ts +138 -0
  299. package/database/server/read.ts +325 -0
  300. package/database/server/resourceAccess.ts +211 -0
  301. package/database/server/routes.ts +110 -0
  302. package/database/server/spaceMemberAuthority.ts +67 -0
  303. package/database/server/upload.ts +159 -0
  304. package/database/server/write.ts +494 -0
  305. package/database/server/writeAuthority.ts +133 -0
  306. package/database/sqliteDb.ts +46 -0
  307. package/database/table/deleteTable.ts +120 -0
  308. package/database/tenantPlacement.ts +57 -0
  309. package/database/tombstones.ts +52 -0
  310. package/database/userDataLoadDecision.ts +17 -0
  311. package/database/userDataMerge.ts +95 -0
  312. package/database/userPreferenceRegister.ts +108 -0
  313. package/database/utils/dbPath.ts +47 -0
  314. package/database/utils/ulid.native.ts +6 -0
  315. package/database/utils/ulid.ts +1 -0
  316. package/index.ts +37 -19
  317. package/localRuntimeDb.ts +28 -0
  318. package/package.json +17 -4
  319. package/runtimeModeArgs.ts +33 -0
  320. package/tui/readlineWorkspace.ts +1 -0
  321. package/tui/session.ts +22 -0
@@ -0,0 +1,82 @@
1
+ // 文件路径: packages/ai/tools/listFilesTool.ts
2
+
3
+ import { getToolBaseUrl } from "./toolApiClient";
4
+
5
+ // ---- Types ----
6
+
7
+ export type ListFilesArgs = {
8
+ path?: string;
9
+ maxFiles?: number;
10
+ ignore?: string[];
11
+ };
12
+
13
+ // ---- 工具 Schema ----
14
+
15
+ export const listFilesFunctionSchema = {
16
+ name: "list_files",
17
+ description: [
18
+ "列出项目中的文件和目录结构。",
19
+ "当你初次进入项目,或需要了解特定目录下的文件列表以便进行下一步搜索或读取时,请使用此工具。",
20
+ "它会自动忽略常见的非源码目录(如 node_modules),并支持深度递归(受 maxFiles 限制)。",
21
+ ].join("\n"),
22
+ parameters: {
23
+ type: "object",
24
+ properties: {
25
+ path: {
26
+ type: "string",
27
+ description: "可选:要列出的目录路径,默认 '.'(项目根目录)。",
28
+ },
29
+ maxFiles: {
30
+ type: "number",
31
+ description: "可选:返回文件的最大数量,默认 300。",
32
+ },
33
+ ignore: {
34
+ type: "array",
35
+ items: { type: "string" },
36
+ description: "可选:要额外忽略的模式或目录名。",
37
+ },
38
+ },
39
+ },
40
+ };
41
+
42
+ // ---- 执行函数 ----
43
+
44
+ export async function listFilesFunc(
45
+ args: ListFilesArgs,
46
+ thunkApi: any,
47
+ context?: { signal?: AbortSignal }
48
+ ): Promise<{ rawData: any; displayData?: string }> {
49
+ try {
50
+ const baseUrl = getToolBaseUrl(thunkApi);
51
+ const apiUrl = `${baseUrl}/api/list-files`;
52
+
53
+ const response = await fetch(apiUrl, {
54
+ method: "POST",
55
+ headers: { "Content-Type": "application/json" },
56
+ signal: context?.signal,
57
+ body: JSON.stringify(args),
58
+ });
59
+
60
+ const data = (await response.json()) as { ok?: boolean; error?: string; files?: any[]; totalFiles?: number; truncated?: boolean };
61
+
62
+ if (!response.ok || data?.error) {
63
+ throw new Error(data?.error || `列出文件失败: ${response.status}`);
64
+ }
65
+
66
+ const files = data.files || [];
67
+ const count = files.length;
68
+ const displayData = `📁 文件列表: 找到 ${data.totalFiles} 个文件${data.truncated ? ' (已截断)' : ''}`;
69
+
70
+ return {
71
+ rawData: {
72
+ ok: true,
73
+ files,
74
+ totalFiles: data.totalFiles,
75
+ truncated: data.truncated
76
+ },
77
+ displayData,
78
+ };
79
+ } catch (error: any) {
80
+ throw new Error(`列出文件失败:${error?.message || String(error)}`);
81
+ }
82
+ }
@@ -0,0 +1,113 @@
1
+ // 文件路径: ai/tools/listUserSpacesTool.ts
2
+
3
+ /**
4
+ * listUserSpaces 工具
5
+ *
6
+ * 用于 AI 获取当前用户可访问的所有 Space 列表(概览)。
7
+ * 只返回 Space 名称和 ID,不返回详细内容,避免 Token 爆炸。
8
+ *
9
+ * 使用场景:
10
+ * - 用户询问"我有哪些空间"
11
+ * - AI 需要确定要查询哪个 Space
12
+ * - 跨 Space 导航
13
+ */
14
+
15
+ import type { RootState } from "app/store";
16
+ import { selectAllMemberSpaces } from "create/space/spaceSlice";
17
+
18
+ // ---- Types ----
19
+
20
+ export type ListUserSpacesArgs = {
21
+ /**
22
+ * 是否只返回用户拥有的 Space(角色为 owner)
23
+ */
24
+ ownedOnly?: boolean;
25
+ };
26
+
27
+ // ---- 工具 Schema,供 LLM 调用 ----
28
+
29
+ export const listUserSpacesFunctionSchema = {
30
+ name: "listUserSpaces",
31
+ description: [
32
+ "获取当前用户可访问的所有 Space(工作空间)列表。",
33
+ "",
34
+ "返回内容:",
35
+ "- 每个 Space 的 ID 和名称",
36
+ "- 用户在该 Space 的角色(owner/member)",
37
+ "",
38
+ "使用场景:",
39
+ "- 用户询问'我有哪些空间'",
40
+ "- 需要确定要查询哪个 Space",
41
+ "- 跨 Space 导航",
42
+ "",
43
+ "注意:只返回概览信息,如需查看 Space 详细内容,使用 listSpaceContent 工具。",
44
+ ].join("\n"),
45
+ parameters: {
46
+ type: "object",
47
+ properties: {
48
+ ownedOnly: {
49
+ type: "boolean",
50
+ description: "是否只返回用户拥有的 Space。默认 false(返回所有可访问的 Space)。",
51
+ default: false,
52
+ },
53
+ },
54
+ required: [],
55
+ },
56
+ };
57
+
58
+ // ---- 执行函数 ----
59
+
60
+ export async function listUserSpacesFunc(
61
+ args: ListUserSpacesArgs,
62
+ thunkApi: any,
63
+ context?: { parentMessageId?: string; signal?: AbortSignal }
64
+ ): Promise<{ rawData: any; displayData?: string }> {
65
+ const { ownedOnly = false } = args || {};
66
+
67
+ try {
68
+ const { getState } = thunkApi;
69
+ const state: RootState = getState();
70
+
71
+ let memberSpaces = selectAllMemberSpaces(state);
72
+
73
+ if (ownedOnly) {
74
+ memberSpaces = memberSpaces.filter((ms) => ms.role === "owner");
75
+ }
76
+
77
+ if (memberSpaces.length === 0) {
78
+ return {
79
+ rawData: { spaces: [] },
80
+ displayData: ownedOnly
81
+ ? "当前用户没有拥有任何 Space。"
82
+ : "当前用户没有可访问的 Space。",
83
+ };
84
+ }
85
+
86
+ // 格式化输出
87
+ let resultText = `=== 用户可访问的 Space 列表 (${memberSpaces.length}) ===\n\n`;
88
+
89
+ const spacesData = memberSpaces.map((ms, index) => {
90
+ const roleLabel = ms.role === "owner" ? "👑 Owner" : "👤 Member";
91
+ resultText += `${index + 1}. ${ms.spaceName || ms.spaceId}\n`;
92
+ resultText += ` ID: ${ms.spaceId} | Role: ${roleLabel}\n`;
93
+
94
+ return {
95
+ spaceId: ms.spaceId,
96
+ name: ms.spaceName || ms.spaceId,
97
+ role: ms.role,
98
+ };
99
+ });
100
+
101
+ resultText += `\n提示:使用 listSpaceContent(spaceId) 可查看指定 Space 的详细内容。`;
102
+
103
+ return {
104
+ rawData: { spaces: spacesData },
105
+ displayData: resultText,
106
+ };
107
+ } catch (error: any) {
108
+ console.error("执行 listUserSpaces 工具时发生错误:", error);
109
+ throw new Error(
110
+ `获取用户 Space 列表失败:${error?.message || String(error)}`
111
+ );
112
+ }
113
+ }
@@ -0,0 +1,199 @@
1
+ export const queryModelUsageFunctionSchema = {
2
+ name: "queryModelUsage",
3
+ description:
4
+ "查询模型/API 用量与费用。普通用户只能查自己的用量;系统管理员可以查指定用户或全站。费用默认返回 credits,也可附带 USD 换算。",
5
+ parameters: {
6
+ type: "object",
7
+ properties: {
8
+ scope: {
9
+ type: "string",
10
+ enum: ["user", "all", "space"],
11
+ description:
12
+ "查询范围。user 为个人,all 为全站管理员查询,space 预留给空间范围。",
13
+ default: "user",
14
+ },
15
+ userId: {
16
+ type: "string",
17
+ description: "管理员查询指定用户时使用;普通用户不允许指定他人。",
18
+ },
19
+ spaceId: {
20
+ type: "string",
21
+ description: "空间范围查询预留字段,当前版本会返回未实现。",
22
+ },
23
+ provider: {
24
+ type: "string",
25
+ description: "可选 provider 过滤,例如 google、openai、anthropic。",
26
+ },
27
+ model: {
28
+ type: "string",
29
+ description: "可选模型过滤,例如 gemini-2.5-flash。",
30
+ },
31
+ serviceTier: {
32
+ type: "string",
33
+ description: "可选计费档位过滤,例如 standard、flex。",
34
+ },
35
+ startDate: {
36
+ type: "string",
37
+ description: "开始日期,YYYY-MM-DD。默认今天。",
38
+ },
39
+ endDate: {
40
+ type: "string",
41
+ description: "结束日期,YYYY-MM-DD。默认等于 startDate。",
42
+ },
43
+ currency: {
44
+ type: "string",
45
+ description: "展示货币/单位标签。默认 CREDITS;可填 USD、CNY 等。",
46
+ default: "CREDITS",
47
+ },
48
+ creditsPerUsd: {
49
+ type: "number",
50
+ description: "credits 与 USD 的换算比例,默认 8 credits = 1 USD。",
51
+ default: 8,
52
+ },
53
+ thresholdCredits: {
54
+ type: "number",
55
+ description: "可选阈值,单位 credits;返回 threshold.exceeded。",
56
+ },
57
+ thresholdUsd: {
58
+ type: "number",
59
+ description: "可选阈值,单位 USD;会按 creditsPerUsd 换算。",
60
+ },
61
+ },
62
+ },
63
+ };
64
+
65
+ export const createScheduledTaskFunctionSchema = {
66
+ name: "createScheduledTask",
67
+ description:
68
+ "创建一个每日/周期性后台任务。适合让 agent 按 cron 定时检查用量、生成报告或执行提醒;可选择创建后立刻试运行一次。",
69
+ parameters: {
70
+ type: "object",
71
+ properties: {
72
+ title: {
73
+ type: "string",
74
+ description: "任务标题。",
75
+ },
76
+ taskPrompt: {
77
+ type: "string",
78
+ description:
79
+ "定时任务每次执行时交给 agent 的完整任务描述,应包含检查条件和通知方式。",
80
+ },
81
+ schedule: {
82
+ type: "string",
83
+ description: "cron 表达式,例如每天 09:00 执行为 0 9 * * *。",
84
+ },
85
+ agentKey: {
86
+ type: "string",
87
+ description: "执行该任务的 agentKey。默认使用当前 agent。",
88
+ },
89
+ spaceId: {
90
+ type: "string",
91
+ description: "可选空间 ID;任务对话会归属到该空间。",
92
+ },
93
+ runOnceNow: {
94
+ type: "boolean",
95
+ description: "创建后是否立即执行一次,用来验证任务会产生什么结果。",
96
+ default: false,
97
+ },
98
+ },
99
+ required: ["schedule", "taskPrompt"],
100
+ },
101
+ };
102
+
103
+ export const createDialogGoalFunctionSchema = {
104
+ name: "createDialogGoal",
105
+ description:
106
+ "为当前对话创建或替换一个轻量目标,可选设置 token 预算。目标会持久化到当前 dialog。",
107
+ parameters: {
108
+ type: "object",
109
+ properties: {
110
+ objective: {
111
+ type: "string",
112
+ description: "目标描述,应该是可完成的具体任务。",
113
+ },
114
+ tokenBudget: {
115
+ type: "number",
116
+ description: "可选 token 预算。用于报告 used / remaining,不会自动中断运行。",
117
+ },
118
+ dialogId: {
119
+ type: "string",
120
+ description: "可选 dialogId。默认使用当前运行中的对话。",
121
+ },
122
+ },
123
+ required: ["objective"],
124
+ },
125
+ };
126
+
127
+ export const getDialogGoalFunctionSchema = {
128
+ name: "getDialogGoal",
129
+ description:
130
+ "读取当前或指定对话的 goal 状态,并返回 token 使用与剩余预算报告。",
131
+ parameters: {
132
+ type: "object",
133
+ properties: {
134
+ dialogId: {
135
+ type: "string",
136
+ description: "可选 dialogId。默认使用当前运行中的对话。",
137
+ },
138
+ },
139
+ },
140
+ };
141
+
142
+ export const completeDialogGoalFunctionSchema = {
143
+ name: "completeDialogGoal",
144
+ description:
145
+ "将当前或指定对话的 goal 标记为 complete,并持久化完成时间。",
146
+ parameters: {
147
+ type: "object",
148
+ properties: {
149
+ dialogId: {
150
+ type: "string",
151
+ description: "可选 dialogId。默认使用当前运行中的对话。",
152
+ },
153
+ },
154
+ },
155
+ };
156
+
157
+ export const notifyUserFunctionSchema = {
158
+ name: "notifyUser",
159
+ description:
160
+ "发送一条站内通知给当前用户。第一版只支持站内通知,后续可扩展邮件、桌面端、网页和移动端通知。",
161
+ parameters: {
162
+ type: "object",
163
+ properties: {
164
+ title: {
165
+ type: "string",
166
+ description: "通知标题。",
167
+ },
168
+ message: {
169
+ type: "string",
170
+ description: "通知正文。",
171
+ },
172
+ severity: {
173
+ type: "string",
174
+ enum: ["info", "warning", "critical"],
175
+ description: "通知级别。",
176
+ default: "info",
177
+ },
178
+ href: {
179
+ type: "string",
180
+ description: "可选跳转链接。",
181
+ },
182
+ },
183
+ required: ["title", "message"],
184
+ },
185
+ };
186
+
187
+ const serverOnlyResult = (toolName: string) => ({
188
+ rawData: {
189
+ error: `${toolName} must run on the server-side agent runtime.`,
190
+ },
191
+ displayData: `${toolName} 需要在服务端 agent runtime 中执行。`,
192
+ });
193
+
194
+ export const queryModelUsageFunc = async () => serverOnlyResult("queryModelUsage");
195
+ export const createScheduledTaskFunc = async () => serverOnlyResult("createScheduledTask");
196
+ export const createDialogGoalFunc = async () => serverOnlyResult("createDialogGoal");
197
+ export const getDialogGoalFunc = async () => serverOnlyResult("getDialogGoal");
198
+ export const completeDialogGoalFunc = async () => serverOnlyResult("completeDialogGoal");
199
+ export const notifyUserFunc = async () => serverOnlyResult("notifyUser");
@@ -0,0 +1,34 @@
1
+ import { ToolDefinition } from ".";
2
+ import { callToolApi } from "./toolApiClient";
3
+
4
+ export const olmOcrSchema = {
5
+ name: "olm_ocr",
6
+ description: "使用 allenai/olmOCR-2-7B-1025 模型进行光学字符识别 (OCR)。适合文档、论文等结构化文本的高质量识别。",
7
+ parameters: {
8
+ type: "object",
9
+ properties: {
10
+ imageUrl: {
11
+ type: "string",
12
+ description: "要进行 OCR 的图片 URL、base64 编码的图片数据,或者内部文件 ID (如 'file-...')。",
13
+ },
14
+ prompt: {
15
+ type: "string",
16
+ description: "可选的提示词,用于指导模型如何提取信息(例如:'提取所有表格数据' 或 '识别图片中的所有文字')。默认为 '识别图片中的所有文字'。",
17
+ default: "识别图片中的所有文字"
18
+ }
19
+ },
20
+ required: ["imageUrl"],
21
+ },
22
+ };
23
+
24
+ export const olmOcrFunc: ToolDefinition["executor"] = async (input: any, thunkApi) => {
25
+ const { imageUrl, prompt = "识别图片中的所有文字" } = input;
26
+
27
+ const data = await callToolApi(thunkApi, "/api/olm-ocr", { imageUrl, prompt }, { withAuth: true });
28
+
29
+ return {
30
+ summary: "OCR processing completed",
31
+ text: data.choices?.[0]?.message?.content || "No text detected",
32
+ rawData: data
33
+ };
34
+ };
@@ -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
+ };