nolo-cli 0.1.10 → 0.1.11

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 (240) hide show
  1. package/README.md +0 -32
  2. package/agentRuntimeCommands.ts +3 -3
  3. package/commandRegistry.ts +2 -2
  4. package/machineCommands.ts +31 -6
  5. package/package.json +6 -22
  6. package/ai/agent/_executeModel.ts +0 -118
  7. package/ai/agent/agentSlice.ts +0 -525
  8. package/ai/agent/appWorkingMemory.ts +0 -126
  9. package/ai/agent/avatarUtils.ts +0 -24
  10. package/ai/agent/buildEditingContext.ts +0 -373
  11. package/ai/agent/buildSystemPrompt.ts +0 -532
  12. package/ai/agent/cleanAgentMessages.ts +0 -140
  13. package/ai/agent/cliChatClient.ts +0 -119
  14. package/ai/agent/cliExecutor.ts +0 -733
  15. package/ai/agent/cliPrompt.ts +0 -10
  16. package/ai/agent/contextCompiler.ts +0 -107
  17. package/ai/agent/contextLayerContract.ts +0 -44
  18. package/ai/agent/createAgentSchema.ts +0 -234
  19. package/ai/agent/executeToolCall.ts +0 -58
  20. package/ai/agent/fetchAgentContexts.ts +0 -42
  21. package/ai/agent/generatePrompt.ts +0 -3
  22. package/ai/agent/getFullChatContextKeys.ts +0 -168
  23. package/ai/agent/hooks/fetchPublicAgents.ts +0 -133
  24. package/ai/agent/hooks/useAgentConfig.ts +0 -61
  25. package/ai/agent/hooks/useAgentDialog.ts +0 -35
  26. package/ai/agent/hooks/useAgentFormValidation.ts +0 -202
  27. package/ai/agent/hooks/usePublicAgents.ts +0 -473
  28. package/ai/agent/machineRunPermissions.ts +0 -95
  29. package/ai/agent/persistMessageWithFixedId.ts +0 -37
  30. package/ai/agent/planSlice.ts +0 -259
  31. package/ai/agent/referenceUtils.ts +0 -229
  32. package/ai/agent/runAgentBackground.ts +0 -238
  33. package/ai/agent/runAgentClientLoop.ts +0 -138
  34. package/ai/agent/runtimeGuidance.ts +0 -97
  35. package/ai/agent/runtimeServerBase.ts +0 -37
  36. package/ai/agent/server/fetchPublicAgents.ts +0 -128
  37. package/ai/agent/startParallelAgentStreams.ts +0 -424
  38. package/ai/agent/startupProtocol.ts +0 -53
  39. package/ai/agent/streamAgentChatTurn.ts +0 -1278
  40. package/ai/agent/streamAgentChatTurnUtils.ts +0 -738
  41. package/ai/agent/types.ts +0 -71
  42. package/ai/agent/utils/imageOutput.ts +0 -33
  43. package/ai/agent/utils/sortUtils.ts +0 -250
  44. package/ai/agent/web/referencePickerUtils.ts +0 -146
  45. package/ai/ai.locale.ts +0 -1079
  46. package/ai/chat/accumulateToolCallChunks.ts +0 -95
  47. package/ai/chat/fetchUtils.native.ts +0 -276
  48. package/ai/chat/fetchUtils.ts +0 -153
  49. package/ai/chat/parseApiError.ts +0 -64
  50. package/ai/chat/parseMultilineSSE.ts +0 -95
  51. package/ai/chat/sendOpenAICompletionsRequest.native.ts +0 -682
  52. package/ai/chat/sendOpenAICompletionsRequest.ts +0 -703
  53. package/ai/chat/sendOpenAIResponseRequest.ts +0 -491
  54. package/ai/chat/shouldUseServerProxy.ts +0 -18
  55. package/ai/chat/sseClient.native.ts +0 -91
  56. package/ai/chat/sseClient.ts +0 -67
  57. package/ai/chat/streamReader.native.ts +0 -31
  58. package/ai/chat/streamReader.ts +0 -62
  59. package/ai/chat/updateTotalUsage.ts +0 -72
  60. package/ai/context/buildReferenceContext.ts +0 -437
  61. package/ai/context/calculateContextUsage.ts +0 -133
  62. package/ai/context/retention.ts +0 -165
  63. package/ai/context/tokenUtils.ts +0 -78
  64. package/ai/index.ts +0 -1
  65. package/ai/llm/calculateGeminiImageTokens.ts +0 -57
  66. package/ai/llm/deepinfra.ts +0 -28
  67. package/ai/llm/fireworks.ts +0 -50
  68. package/ai/llm/generateRequestBody.ts +0 -165
  69. package/ai/llm/getModelContextWindow.ts +0 -84
  70. package/ai/llm/getNoloKey.ts +0 -31
  71. package/ai/llm/getPricing.ts +0 -199
  72. package/ai/llm/hooks/useModelPricing.ts +0 -75
  73. package/ai/llm/imagePricing.ts +0 -40
  74. package/ai/llm/isResponseAPIModel.ts +0 -13
  75. package/ai/llm/mimo.ts +0 -71
  76. package/ai/llm/mistral.ts +0 -22
  77. package/ai/llm/modelAvatar.ts +0 -427
  78. package/ai/llm/models.ts +0 -45
  79. package/ai/llm/openrouterModels.ts +0 -269
  80. package/ai/llm/providers.ts +0 -306
  81. package/ai/llm/reasoningModels.ts +0 -28
  82. package/ai/llm/types.ts +0 -59
  83. package/ai/llm/usageRequestOptions.ts +0 -59
  84. package/ai/memory/capture.ts +0 -148
  85. package/ai/memory/consolidate.ts +0 -104
  86. package/ai/memory/delete.ts +0 -147
  87. package/ai/memory/overlay.ts +0 -84
  88. package/ai/memory/query.ts +0 -38
  89. package/ai/memory/queryShared.ts +0 -160
  90. package/ai/memory/rank.ts +0 -105
  91. package/ai/memory/recentRelationshipRecap.ts +0 -249
  92. package/ai/memory/remember.ts +0 -167
  93. package/ai/memory/runtime.ts +0 -76
  94. package/ai/memory/store.ts +0 -20
  95. package/ai/memory/storeShared.ts +0 -76
  96. package/ai/memory/types.ts +0 -46
  97. package/ai/memory/understanding.ts +0 -349
  98. package/ai/memory/understandingGreeting.ts +0 -264
  99. package/ai/messages/type.ts +0 -20
  100. package/ai/policy/personalizationDialog.ts +0 -333
  101. package/ai/policy/runtimePolicy.ts +0 -440
  102. package/ai/policy/selfUpdateFields.ts +0 -48
  103. package/ai/policy/types.ts +0 -64
  104. package/ai/skills/referenceRuntime.ts +0 -274
  105. package/ai/skills/skillDiagnostics.ts +0 -251
  106. package/ai/skills/skillDocBuilder.ts +0 -139
  107. package/ai/skills/skillDocProtocol.ts +0 -434
  108. package/ai/skills/skillReferenceSummary.ts +0 -63
  109. package/ai/skills/skillSummaryMarker.ts +0 -26
  110. package/ai/token/calculatePrice.ts +0 -544
  111. package/ai/token/db.ts +0 -98
  112. package/ai/token/externalToolCost.ts +0 -330
  113. package/ai/token/hooks/useRecords.ts +0 -65
  114. package/ai/token/missingUsageEstimate.ts +0 -42
  115. package/ai/token/modelUsageQuery.ts +0 -252
  116. package/ai/token/normalizeUsage.ts +0 -84
  117. package/ai/token/openaiImageGenerationUsage.ts +0 -56
  118. package/ai/token/prepareTokenUsageData.ts +0 -88
  119. package/ai/token/query.ts +0 -88
  120. package/ai/token/queryUserTokens.ts +0 -59
  121. package/ai/token/resolveBillingTarget.ts +0 -52
  122. package/ai/token/saveTokenRecord.ts +0 -53
  123. package/ai/token/serverDialogProjection.ts +0 -78
  124. package/ai/token/serverTokenWriter.ts +0 -143
  125. package/ai/token/stats.ts +0 -21
  126. package/ai/token/tokenThunks.ts +0 -24
  127. package/ai/token/types.ts +0 -93
  128. package/ai/tools/agent/agentTools.ts +0 -176
  129. package/ai/tools/agent/agentUpdateShared.ts +0 -311
  130. package/ai/tools/agent/callAgentTool.ts +0 -139
  131. package/ai/tools/agent/createAgentTool.ts +0 -512
  132. package/ai/tools/agent/createDialogTool.ts +0 -69
  133. package/ai/tools/agent/createSkillAgentTool.ts +0 -62
  134. package/ai/tools/agent/parallelBudget.ts +0 -221
  135. package/ai/tools/agent/presets/appBuilderPreset.ts +0 -145
  136. package/ai/tools/agent/runLlmTool.ts +0 -96
  137. package/ai/tools/agent/runStreamingAgentTool.ts +0 -73
  138. package/ai/tools/agent/skillAgentArgs.ts +0 -106
  139. package/ai/tools/agent/skillAgentPreset.ts +0 -89
  140. package/ai/tools/agent/streamParallelAgentsTool.ts +0 -122
  141. package/ai/tools/agent/updateAgentTool.ts +0 -96
  142. package/ai/tools/agent/updateSelfTool.ts +0 -113
  143. package/ai/tools/amazonProductScraperTool.ts +0 -86
  144. package/ai/tools/apifyActorClient.ts +0 -45
  145. package/ai/tools/appEditGuard.ts +0 -372
  146. package/ai/tools/appReadSnapshot.ts +0 -153
  147. package/ai/tools/appTools.ts +0 -1549
  148. package/ai/tools/applyEditTool.ts +0 -256
  149. package/ai/tools/applyLineEditsTool.ts +0 -312
  150. package/ai/tools/browserTools/click.ts +0 -33
  151. package/ai/tools/browserTools/closeSession.ts +0 -29
  152. package/ai/tools/browserTools/common.ts +0 -27
  153. package/ai/tools/browserTools/openSession.ts +0 -48
  154. package/ai/tools/browserTools/readContent.ts +0 -38
  155. package/ai/tools/browserTools/selectOption.ts +0 -46
  156. package/ai/tools/browserTools/typeText.ts +0 -42
  157. package/ai/tools/category/createCategoryTool.ts +0 -66
  158. package/ai/tools/category/queryContentsByCategoryTool.ts +0 -69
  159. package/ai/tools/category/updateContentCategoryTool.ts +0 -75
  160. package/ai/tools/cfBrowserTools.ts +0 -319
  161. package/ai/tools/cfSpeechToTextTool.ts +0 -49
  162. package/ai/tools/checkEnvTool.ts +0 -65
  163. package/ai/tools/cloudflareCrawlTool.ts +0 -289
  164. package/ai/tools/codeSearchTool.ts +0 -111
  165. package/ai/tools/codeTools.ts +0 -101
  166. package/ai/tools/createDocTool.ts +0 -132
  167. package/ai/tools/createPlanTool.ts +0 -999
  168. package/ai/tools/createSkillDocTool.ts +0 -155
  169. package/ai/tools/createWorkflowTool.ts +0 -154
  170. package/ai/tools/deepseekOcrTool.ts +0 -34
  171. package/ai/tools/delayTool.ts +0 -31
  172. package/ai/tools/deleteSpacesTool.ts +0 -325
  173. package/ai/tools/deleteSpacesToolModel.ts +0 -159
  174. package/ai/tools/devReloadUtils.ts +0 -29
  175. package/ai/tools/dialogMessageSearch.ts +0 -137
  176. package/ai/tools/doctorSkillTool.ts +0 -72
  177. package/ai/tools/ecommerceScraperTool.ts +0 -86
  178. package/ai/tools/emailTools.ts +0 -549
  179. package/ai/tools/evalSkillTool.ts +0 -92
  180. package/ai/tools/exaSearchTool.ts +0 -64
  181. package/ai/tools/execBashTool.ts +0 -379
  182. package/ai/tools/executeSqlTool.ts +0 -192
  183. package/ai/tools/fetchWebpageSupport.ts +0 -309
  184. package/ai/tools/fetchWebpageTool.ts +0 -84
  185. package/ai/tools/geminiImagePreviewTool.ts +0 -361
  186. package/ai/tools/generateDocxTool.ts +0 -215
  187. package/ai/tools/googleSearchScraperTool.ts +0 -106
  188. package/ai/tools/importDataTool.ts +0 -133
  189. package/ai/tools/importSkillTool.ts +0 -162
  190. package/ai/tools/index.ts +0 -1858
  191. package/ai/tools/listFilesTool.ts +0 -82
  192. package/ai/tools/listUserSpacesTool.ts +0 -113
  193. package/ai/tools/modelUsageTools.ts +0 -142
  194. package/ai/tools/olmOcrTool.ts +0 -34
  195. package/ai/tools/openaiImageTool.ts +0 -218
  196. package/ai/tools/paddleOcrTool.ts +0 -34
  197. package/ai/tools/prepareTools.ts +0 -23
  198. package/ai/tools/readDocTool.ts +0 -84
  199. package/ai/tools/readFileTool.ts +0 -211
  200. package/ai/tools/readTool.ts +0 -163
  201. package/ai/tools/readXPostTool.ts +0 -233
  202. package/ai/tools/rememberMemoryTool.ts +0 -84
  203. package/ai/tools/remotionVideoTool.ts +0 -151
  204. package/ai/tools/searchDialogMessagesTool.ts +0 -222
  205. package/ai/tools/searchRepoTool.ts +0 -115
  206. package/ai/tools/searchWorkspaceTool.ts +0 -259
  207. package/ai/tools/skillFollowup.ts +0 -86
  208. package/ai/tools/surfWeatherTool.ts +0 -169
  209. package/ai/tools/table/addTableRowTool.ts +0 -217
  210. package/ai/tools/table/createTableTool.ts +0 -315
  211. package/ai/tools/table/rowTools.ts +0 -366
  212. package/ai/tools/table/schemaTools.ts +0 -244
  213. package/ai/tools/table/shareTableTool.ts +0 -148
  214. package/ai/tools/table/toolShared.ts +0 -129
  215. package/ai/tools/toolApiClient.ts +0 -198
  216. package/ai/tools/toolNameAliases.ts +0 -57
  217. package/ai/tools/toolResultError.ts +0 -42
  218. package/ai/tools/toolRunSlice.ts +0 -303
  219. package/ai/tools/toolSchemaCompatibility.ts +0 -53
  220. package/ai/tools/toolVisibility.ts +0 -4
  221. package/ai/tools/types.ts +0 -20
  222. package/ai/tools/uiAskChoiceTool.ts +0 -104
  223. package/ai/tools/updateContentTitleTool.ts +0 -84
  224. package/ai/tools/updateDocTool.ts +0 -105
  225. package/ai/tools/updateUserPreferenceProfileTool.ts +0 -145
  226. package/ai/tools/whisperTool.ts +0 -77
  227. package/ai/tools/writeFileTool.ts +0 -210
  228. package/ai/tools/youtubeScraperTool.ts +0 -116
  229. package/ai/tools/ziweiChartTool.ts +0 -678
  230. package/ai/types.ts +0 -55
  231. package/ai/workflow/workflowExecutor.ts +0 -323
  232. package/ai/workflow/workflowSlice.ts +0 -73
  233. package/ai/workflow/workflowTypes.ts +0 -106
  234. package/client/compactDialog.ts +0 -222
  235. package/connector-experimental/capabilities.ts +0 -73
  236. package/connector-experimental/codexBinary.ts +0 -41
  237. package/connector-experimental/heartbeatLoop.ts +0 -22
  238. package/connector-experimental/index.ts +0 -5
  239. package/connector-experimental/machineInfo.ts +0 -46
  240. package/connector-experimental/protocol.ts +0 -54
@@ -1,84 +0,0 @@
1
- import { selectCurrentSpaceId } from "create/space/spaceSlice";
2
- import { callToolApi } from "./toolApiClient";
3
- import type { RememberMemoryScope } from "ai/memory/remember";
4
- import type { MemoryKind } from "ai/memory/types";
5
-
6
- export interface RememberMemoryToolArgs {
7
- content: string;
8
- scope?: RememberMemoryScope;
9
- kind?: MemoryKind;
10
- }
11
-
12
- export const rememberMemoryFunctionSchema = {
13
- name: "rememberMemory",
14
- description: [
15
- "当你判断某条用户偏好、纠正、决策习惯或当前 Space 共识值得被长期记住时,调用本工具写入一条 memory。",
16
- "默认先记原始事件,不要把一次性临时要求、当前任务进度或明显短期信息写进去。",
17
- "只有重复出现的可执行流程/排障步骤才传 kind=procedural;一般偏好和事实保持默认 episodic。",
18
- "只有当当前 dialog 明确绑定了一个 Space,且这条内容确实属于共享协作共识时,才应该传 scope=space。",
19
- "优先写成一句简洁、未来仍可理解的话;如无必要,不要频繁调用。",
20
- ].join("\n"),
21
- parameters: {
22
- type: "object",
23
- properties: {
24
- content: {
25
- type: "string",
26
- description:
27
- "要记住的内容。请写成一句未来仍然可理解的简洁描述,例如“这个用户在复杂问题里更喜欢先看结论”。",
28
- },
29
- scope: {
30
- type: "string",
31
- enum: ["auto", "user", "space"],
32
- description:
33
- "记忆范围。默认 auto:优先记到当前用户;若没有用户上下文再退到当前 space。只有当前 dialog 明确绑定了 space,且你明确想写共享协作记忆时才传 space;否则保持 auto。",
34
- },
35
- kind: {
36
- type: "string",
37
- enum: ["episodic", "semantic", "procedural"],
38
- description:
39
- "记忆类型。默认 episodic。只有重复出现的可执行流程、排障步骤或稳定 runbook 才使用 procedural。",
40
- },
41
- },
42
- required: ["content"],
43
- } as const,
44
- };
45
-
46
- export async function rememberMemoryFunc(
47
- args: RememberMemoryToolArgs,
48
- thunkApi: any
49
- ): Promise<{ rawData: unknown; displayData: string }> {
50
- const state = thunkApi.getState();
51
- const spaceId = selectCurrentSpaceId(state) || undefined;
52
- const content = String(args.content ?? "").trim();
53
- const scope = args.scope ?? "auto";
54
- const kind = args.kind ?? "episodic";
55
-
56
- if (!content) {
57
- throw new Error("rememberMemory 需要非空 content。");
58
- }
59
-
60
- const result = await callToolApi<{
61
- success: boolean;
62
- content: string;
63
- requestedScope: RememberMemoryScope;
64
- resolvedScopes: Array<{ ownerType: string; ownerId: string }>;
65
- }>(
66
- thunkApi,
67
- "/api/memory/remember",
68
- {
69
- content,
70
- scope,
71
- kind,
72
- spaceId,
73
- },
74
- { withAuth: true }
75
- );
76
-
77
- const scopeLabel =
78
- result.resolvedScopes?.[0]?.ownerType === "space" ? "当前空间" : "当前用户";
79
-
80
- return {
81
- rawData: result,
82
- displayData: `已记住这条${scopeLabel}记忆。`,
83
- };
84
- }
@@ -1,151 +0,0 @@
1
- import { ContentType } from "app/types";
2
- import { addContentAction } from "create/space/content/addContentAction";
3
- import { selectCurrentSpaceId } from "create/space/spaceSlice";
4
- import { buildDatabaseFileContentUrl } from "database/fileUrl";
5
- import { fileKey } from "database/keys";
6
- import { selectCurrentServer } from "app/settings/settingSlice";
7
- import { selectUserId } from "auth/authSlice";
8
- import { callToolApi } from "./toolApiClient";
9
-
10
- type RemotionRenderVideoArgs = {
11
- template?: "mobile-product" | "landscape-product" | "nolo-mobile-product" | "nolo-landscape-product";
12
- brand?: string;
13
- hook?: string;
14
- headline?: string;
15
- subline?: string;
16
- prompt?: string;
17
- cta?: string;
18
- outputName?: string;
19
- };
20
-
21
- export const remotionRenderVideoFunctionSchema = {
22
- name: "remotionRenderVideo",
23
- description: [
24
- "使用平台内 Remotion 模板渲染产品视频,并保存为可复用 MP4 文件。",
25
- "",
26
- "适用场景:",
27
- "- 用户要生成手机传播视频、产品介绍视频、欢迎页短片、Agent/AI 工作流演示视频。",
28
- "- 需要把文案、标题、输入框示例等参数化后产出 MP4。",
29
- "",
30
- "当前模板:",
31
- "- mobile-product: 9:16 竖版,适合手机传播。",
32
- "- landscape-product: 16:9 横版,适合官网/演示页。",
33
- "- 兼容旧别名 nolo-mobile-product / nolo-landscape-product。",
34
- ].join("\n"),
35
- parameters: {
36
- type: "object",
37
- properties: {
38
- template: {
39
- type: "string",
40
- enum: ["mobile-product", "landscape-product", "nolo-mobile-product", "nolo-landscape-product"],
41
- description: "视频模板。默认 mobile-product。",
42
- },
43
- brand: {
44
- type: "string",
45
- description: "品牌名,例如 Nolo.Chat、你的产品名、店铺名或活动名。",
46
- },
47
- hook: {
48
- type: "string",
49
- description: "竖版视频首屏钩子标题,例如“把一句想法,推进成结果”。",
50
- },
51
- headline: {
52
- type: "string",
53
- description: "横版视频主标题;竖版缺少 hook 时也会作为 hook 使用。",
54
- },
55
- subline: {
56
- type: "string",
57
- description: "横版视频副标题。",
58
- },
59
- prompt: {
60
- type: "string",
61
- description: "手机输入框里逐字打出的示例需求。",
62
- },
63
- cta: {
64
- type: "string",
65
- description: "结尾行动号召,例如“开始体验”。",
66
- },
67
- outputName: {
68
- type: "string",
69
- description: "输出文件名,建议以 .mp4 结尾。",
70
- },
71
- },
72
- },
73
- };
74
-
75
- export const remotionRenderVideoFunc = async (
76
- args: RemotionRenderVideoArgs,
77
- thunkApi: any
78
- ): Promise<{ rawData: any; displayData: string; llmContext?: string }> => {
79
- const result: any = await callToolApi(
80
- thunkApi,
81
- "/api/remotion/render",
82
- {
83
- template: args.template || "mobile-product",
84
- brand: args.brand,
85
- hook: args.hook,
86
- headline: args.headline,
87
- subline: args.subline,
88
- prompt: args.prompt,
89
- cta: args.cta,
90
- outputName: args.outputName,
91
- },
92
- { withAuth: true }
93
- );
94
-
95
- const state = thunkApi.getState();
96
- const userId = selectUserId(state);
97
- const spaceId = selectCurrentSpaceId(state);
98
- const currentServer = selectCurrentServer(state);
99
- const fileId = result?.fileId;
100
- const metadata = result?.metadata || {};
101
- const fileDbKey = userId && fileId ? fileKey.single(userId, fileId) : "";
102
- const url = buildDatabaseFileContentUrl(currentServer, fileDbKey || fileId);
103
-
104
- if (spaceId && fileDbKey) {
105
- try {
106
- await addContentAction(
107
- {
108
- spaceId,
109
- contentKey: fileDbKey,
110
- title: metadata.originalName || "Remotion video.mp4",
111
- type: ContentType.FILE,
112
- fileCategory: "video",
113
- } as any,
114
- { dispatch: thunkApi.dispatch, getState: thunkApi.getState }
115
- );
116
- } catch (error) {
117
- console.warn("[remotionRenderVideoFunc] Failed to add video to space:", error);
118
- }
119
- }
120
-
121
- const displayLines = [
122
- result?.text || "已使用 Remotion 生成视频。",
123
- fileId ? `- fileId: ${fileId}` : "",
124
- fileDbKey ? `- fileDbKey: ${fileDbKey}` : "",
125
- url ? `- url: ${url}` : "",
126
- metadata?.size ? `- size: ${metadata.size} bytes` : "",
127
- result?.template ? `- template: ${result.template}` : "",
128
- ].filter(Boolean);
129
-
130
- const llmContext = [
131
- "The Remotion video tool produced a reusable video file.",
132
- "Reuse these exact references when mentioning or embedding the video:",
133
- fileId ? `- fileId: ${fileId}` : "",
134
- fileDbKey ? `- fileDbKey: ${fileDbKey}` : "",
135
- url ? `- url: ${url}` : "",
136
- metadata?.originalName ? `- name: ${metadata.originalName}` : "",
137
- result?.template ? `- template: ${result.template}` : "",
138
- ]
139
- .filter(Boolean)
140
- .join("\n");
141
-
142
- return {
143
- rawData: {
144
- ...result,
145
- fileDbKey,
146
- url,
147
- },
148
- displayData: displayLines.join("\n"),
149
- llmContext,
150
- };
151
- };
@@ -1,222 +0,0 @@
1
- import { extractCustomId } from "core/prefix";
2
- import { selectRuntimeSnapshot } from "app/stateViews/runtime";
3
- import {
4
- buildDialogMessageSearchResults,
5
- clampDialogSearchNumber,
6
- formatDialogMessageSearchDisplay,
7
- normalizeDialogSearchText,
8
- type DialogMessageSearchRecord,
9
- } from "./dialogMessageSearch";
10
-
11
- type SearchDialogMessagesArgs = {
12
- dialogKey: string;
13
- query: string;
14
- limit?: number;
15
- scanLimit?: number;
16
- contextMessages?: number;
17
- role?: "user" | "assistant" | "tool" | "system";
18
- includeTools?: boolean;
19
- };
20
-
21
- const MAX_LIMIT = 10;
22
- const MAX_CONTEXT_MESSAGES = 3;
23
- const MAX_CONTENT_CHARS = 1800;
24
- const CONTEXT_CONTENT_CHARS = 600;
25
- const SERVER_SCAN_LIMIT = 500;
26
-
27
- const getMessageSortValue = (message: DialogMessageSearchRecord) => {
28
- const createdAt = message.createdAt;
29
- if (typeof createdAt === "number") return createdAt;
30
- if (typeof createdAt === "string") {
31
- const parsed = Date.parse(createdAt);
32
- if (Number.isFinite(parsed)) return parsed;
33
- }
34
- const id = normalizeDialogSearchText(message.id);
35
- return id ? id : normalizeDialogSearchText(message.dbKey);
36
- };
37
-
38
- async function collectDialogMessages(db: any, dialogId: string): Promise<DialogMessageSearchRecord[]> {
39
- if (!db?.iterator) return [];
40
- const prefix = `dialog-${dialogId}-msg-`;
41
- let iterator = db.iterator({
42
- gte: prefix,
43
- lte: `${prefix}\uffff`,
44
- });
45
- if (iterator && typeof iterator.then === "function") {
46
- iterator = await iterator;
47
- }
48
-
49
- const messages: DialogMessageSearchRecord[] = [];
50
- for await (const [key, value] of iterator) {
51
- if (!value || typeof value !== "object") continue;
52
- messages.push({
53
- ...(value as DialogMessageSearchRecord),
54
- dbKey: (value as DialogMessageSearchRecord).dbKey || String(key),
55
- });
56
- }
57
-
58
- return messages.sort((a, b) => {
59
- const left = getMessageSortValue(a);
60
- const right = getMessageSortValue(b);
61
- if (typeof left === "number" && typeof right === "number") return left - right;
62
- return String(left).localeCompare(String(right));
63
- });
64
- }
65
-
66
- async function fetchDialogMessagesFromServer(args: {
67
- serverBase: string;
68
- token?: string;
69
- dialogId: string;
70
- limit: number;
71
- }): Promise<DialogMessageSearchRecord[]> {
72
- const serverBase = args.serverBase.replace(/\/+$/, "");
73
- if (!serverBase || !args.token) return [];
74
-
75
- const response = await fetch(`${serverBase}/rpc/getConvMsgs`, {
76
- method: "POST",
77
- headers: {
78
- Authorization: `Bearer ${args.token}`,
79
- "Content-Type": "application/json",
80
- },
81
- body: JSON.stringify({ dialogId: args.dialogId, limit: args.limit }),
82
- });
83
- if (!response.ok) return [];
84
-
85
- const newestFirst = await response.json();
86
- if (!Array.isArray(newestFirst)) return [];
87
- return [...newestFirst].reverse().map((message) => ({
88
- ...(message as DialogMessageSearchRecord),
89
- dbKey: (message as DialogMessageSearchRecord).dbKey,
90
- }));
91
- }
92
-
93
- async function collectBestAvailableDialogMessages(
94
- db: any,
95
- dialogId: string,
96
- thunkApi: any,
97
- scanLimit: number,
98
- ): Promise<DialogMessageSearchRecord[]> {
99
- const localMessages = await collectDialogMessages(db, dialogId);
100
- const state = thunkApi?.getState?.();
101
- const runtime = state ? selectRuntimeSnapshot(state) : null;
102
- const serverBases = Array.from(new Set([
103
- runtime?.localRuntimeOrigin,
104
- runtime?.currentServer,
105
- ...(Array.isArray(runtime?.syncServers) ? runtime.syncServers : []),
106
- ].filter((base): base is string => typeof base === "string" && base.trim().length > 0)));
107
-
108
- let bestMessages = localMessages;
109
- for (const serverBase of serverBases) {
110
- const serverMessages = await fetchDialogMessagesFromServer({
111
- serverBase,
112
- token: runtime?.currentToken,
113
- dialogId,
114
- limit: scanLimit,
115
- }).catch(() => []);
116
- if (serverMessages.length > bestMessages.length) {
117
- bestMessages = serverMessages;
118
- }
119
- }
120
-
121
- return bestMessages;
122
- }
123
-
124
- export const searchDialogMessagesFunctionSchema = {
125
- name: "searchDialogMessages",
126
- description: [
127
- "Search original messages inside a specific dialog by exact or fuzzy text.",
128
- "Use this when a user asks for an exact old message, original wording, who said what, why a decision was made, early-history detail, failed attempts, files or tool evidence, or comparison with prior work from an attached conversation.",
129
- "Prefer this over answering from a lossy dialog summary when the user needs evidence, provenance, or a specific prior detail.",
130
- "Returns matching message ids, roles, clipped original content, and nearby context without loading the full dialog into the model context.",
131
- ].join(" "),
132
- parameters: {
133
- type: "object",
134
- properties: {
135
- dialogKey: {
136
- type: "string",
137
- description: "Dialog dbKey, for example dialog-userId-01ABC...",
138
- },
139
- query: {
140
- type: "string",
141
- description: "Text to search for in original message content.",
142
- },
143
- limit: {
144
- type: "number",
145
- description: `Maximum matches to return. Capped at ${MAX_LIMIT}.`,
146
- },
147
- scanLimit: {
148
- type: "number",
149
- description: `Maximum messages to scan when fetching from a server. Capped at ${SERVER_SCAN_LIMIT}.`,
150
- },
151
- contextMessages: {
152
- type: "number",
153
- description: `Number of neighboring messages before/after each match. Capped at ${MAX_CONTEXT_MESSAGES}.`,
154
- },
155
- role: {
156
- type: "string",
157
- enum: ["user", "assistant", "tool", "system"],
158
- description: "Optional role filter.",
159
- },
160
- includeTools: {
161
- type: "boolean",
162
- description: "Whether tool messages may match. Defaults to true.",
163
- },
164
- },
165
- required: ["dialogKey", "query"],
166
- },
167
- };
168
-
169
- export async function searchDialogMessagesFunc(
170
- args: SearchDialogMessagesArgs,
171
- _thunkApi: any,
172
- context?: { db?: any }
173
- ) {
174
- const dialogKey = normalizeDialogSearchText(args?.dialogKey);
175
- const query = normalizeDialogSearchText(args?.query);
176
- if (!dialogKey.startsWith("dialog-")) {
177
- throw new Error("searchDialogMessages requires a dialog-* dbKey.");
178
- }
179
- if (!query) {
180
- throw new Error("searchDialogMessages requires a non-empty query.");
181
- }
182
-
183
- const db = context?.db ?? _thunkApi?.extra?.db;
184
- if (!db) {
185
- throw new Error("searchDialogMessages cannot access the local message database.");
186
- }
187
-
188
- const dialogId = extractCustomId(dialogKey) || dialogKey.split("-").at(-1) || "";
189
- const scanLimit = clampDialogSearchNumber(
190
- args.scanLimit,
191
- SERVER_SCAN_LIMIT,
192
- 1,
193
- SERVER_SCAN_LIMIT,
194
- );
195
- const messages = await collectBestAvailableDialogMessages(db, dialogId, _thunkApi, scanLimit);
196
- const limit = clampDialogSearchNumber(args.limit, 5, 1, MAX_LIMIT);
197
- const contextMessages = clampDialogSearchNumber(args.contextMessages, 1, 0, MAX_CONTEXT_MESSAGES);
198
-
199
- const results = buildDialogMessageSearchResults({
200
- messages,
201
- query,
202
- limit,
203
- contextMessages,
204
- role: args.role,
205
- includeTools: args.includeTools,
206
- contentClipChars: MAX_CONTENT_CHARS,
207
- contextClipChars: CONTEXT_CONTENT_CHARS,
208
- });
209
-
210
- const displayData = formatDialogMessageSearchDisplay({ dialogKey, query, results });
211
-
212
- return {
213
- rawData: {
214
- success: true,
215
- dialogKey,
216
- query,
217
- scannedMessages: messages.length,
218
- matches: results,
219
- },
220
- displayData,
221
- };
222
- }
@@ -1,115 +0,0 @@
1
- // 文件路径: packages/ai/tools/searchRepoTool.ts
2
-
3
- import { getToolBaseUrl } from "./toolApiClient";
4
-
5
- // ---- Types ----
6
-
7
- export type SearchRepoArgs = {
8
- query: string;
9
- pathScope?: string;
10
- maxResults?: number;
11
- contextLines?: number;
12
- };
13
-
14
- // ---- 工具 Schema ----
15
-
16
- export const searchRepoFunctionSchema = {
17
- name: "search_repo",
18
- description: [
19
- "在项目的源代码中进行全量文本搜索。",
20
- "当你不知道某个特定的字符串、类名、变量或逻辑在哪个文件中时,请使用此工具。",
21
- "它会返回匹配的文件路径、行号以及代码预览。",
22
- "",
23
- "参数建议:",
24
- "- query: 要搜索的文本(不区分大小写)。",
25
- "- pathScope: 可选,缩小搜索范围(如 'packages/server')。",
26
- "- maxResults: 默认 20。",
27
- ].join("\n"),
28
- parameters: {
29
- type: "object",
30
- properties: {
31
- query: {
32
- type: "string",
33
- description: "要搜索的文本字符串。",
34
- },
35
- pathScope: {
36
- type: "string",
37
- description: "可选:限制搜索在特定目录下,例如 'packages/ai'。",
38
- },
39
- maxResults: {
40
- type: "number",
41
- description: "返回的最大匹配项数量 (默认 20)。",
42
- },
43
- contextLines: {
44
- type: "number",
45
- description: "可选:匹配行前后显示的上下文行数。",
46
- },
47
- },
48
- required: ["query"],
49
- },
50
- };
51
-
52
- function buildSearchRepoDisplayData(
53
- query: string,
54
- hits: Array<{ path?: string; line?: number; preview?: string }>,
55
- totalHits: number | string | undefined,
56
- ): string {
57
- if (!Array.isArray(hits) || hits.length === 0) {
58
- return `🔍 搜索 "${query}": 未找到匹配项`;
59
- }
60
-
61
- const lines = hits.slice(0, 8).map((hit, index) => {
62
- const path = hit.path || "unknown";
63
- const line = typeof hit.line === "number" ? `:${hit.line}` : "";
64
- const preview = typeof hit.preview === "string" && hit.preview.trim()
65
- ? ` — ${hit.preview.trim()}`
66
- : "";
67
- return `${index + 1}. ${path}${line}${preview}`;
68
- });
69
-
70
- const omitted = hits.length > 8 ? `\n… 其余 ${hits.length - 8} 条已省略` : "";
71
- return `🔍 搜索 "${query}": 找到 ${totalHits ?? hits.length} 个匹配项\n${lines.join("\n")}${omitted}`;
72
- }
73
-
74
- // ---- 执行函数 ----
75
-
76
- export async function searchRepoFunc(
77
- args: SearchRepoArgs,
78
- thunkApi: any,
79
- context?: { signal?: AbortSignal }
80
- ): Promise<{ rawData: any; displayData?: string }> {
81
- const { query, pathScope, maxResults, contextLines } = args;
82
-
83
- try {
84
- const baseUrl = getToolBaseUrl(thunkApi);
85
- const apiUrl = `${baseUrl}/api/search-repo`;
86
-
87
- const response = await fetch(apiUrl, {
88
- method: "POST",
89
- headers: { "Content-Type": "application/json" },
90
- signal: context?.signal,
91
- body: JSON.stringify({ query, pathScope, maxResults, contextLines }),
92
- });
93
-
94
- const data = (await response.json()) as { ok?: boolean; error?: string; hits?: any[]; totalHits?: number | string };
95
-
96
- if (!response.ok || data?.error) {
97
- throw new Error(data?.error || `搜索请求失败: ${response.status}`);
98
- }
99
-
100
- const hits = data.hits || [];
101
- const displayData = buildSearchRepoDisplayData(query, hits, data.totalHits);
102
-
103
- return {
104
- rawData: {
105
- ok: true,
106
- query,
107
- hits,
108
- totalHits: data.totalHits,
109
- },
110
- displayData,
111
- };
112
- } catch (error: any) {
113
- throw new Error(`全局搜索 (${query}) 失败:${error?.message || String(error)}`);
114
- }
115
- }