nolo-cli 0.1.10 → 0.1.12

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 (232) hide show
  1. package/README.md +0 -32
  2. package/agentRuntimeCommands.ts +1 -1
  3. package/client/compactDialog.ts +2 -5
  4. package/commandRegistry.ts +2 -2
  5. package/machineCommands.ts +28 -3
  6. package/package.json +5 -25
  7. package/ai/agent/_executeModel.ts +0 -118
  8. package/ai/agent/agentSlice.ts +0 -525
  9. package/ai/agent/appWorkingMemory.ts +0 -126
  10. package/ai/agent/avatarUtils.ts +0 -24
  11. package/ai/agent/buildEditingContext.ts +0 -373
  12. package/ai/agent/buildSystemPrompt.ts +0 -532
  13. package/ai/agent/cleanAgentMessages.ts +0 -140
  14. package/ai/agent/cliChatClient.ts +0 -119
  15. package/ai/agent/contextCompiler.ts +0 -107
  16. package/ai/agent/contextLayerContract.ts +0 -44
  17. package/ai/agent/createAgentSchema.ts +0 -234
  18. package/ai/agent/executeToolCall.ts +0 -58
  19. package/ai/agent/fetchAgentContexts.ts +0 -42
  20. package/ai/agent/generatePrompt.ts +0 -3
  21. package/ai/agent/getFullChatContextKeys.ts +0 -168
  22. package/ai/agent/hooks/fetchPublicAgents.ts +0 -133
  23. package/ai/agent/hooks/useAgentConfig.ts +0 -61
  24. package/ai/agent/hooks/useAgentDialog.ts +0 -35
  25. package/ai/agent/hooks/useAgentFormValidation.ts +0 -202
  26. package/ai/agent/hooks/usePublicAgents.ts +0 -473
  27. package/ai/agent/persistMessageWithFixedId.ts +0 -37
  28. package/ai/agent/planSlice.ts +0 -259
  29. package/ai/agent/referenceUtils.ts +0 -229
  30. package/ai/agent/runAgentBackground.ts +0 -238
  31. package/ai/agent/runAgentClientLoop.ts +0 -138
  32. package/ai/agent/runtimeGuidance.ts +0 -97
  33. package/ai/agent/runtimeServerBase.ts +0 -37
  34. package/ai/agent/server/fetchPublicAgents.ts +0 -128
  35. package/ai/agent/startParallelAgentStreams.ts +0 -424
  36. package/ai/agent/startupProtocol.ts +0 -53
  37. package/ai/agent/streamAgentChatTurn.ts +0 -1278
  38. package/ai/agent/streamAgentChatTurnUtils.ts +0 -738
  39. package/ai/agent/types.ts +0 -71
  40. package/ai/agent/utils/imageOutput.ts +0 -33
  41. package/ai/agent/utils/sortUtils.ts +0 -250
  42. package/ai/agent/web/referencePickerUtils.ts +0 -146
  43. package/ai/ai.locale.ts +0 -1079
  44. package/ai/chat/accumulateToolCallChunks.ts +0 -95
  45. package/ai/chat/fetchUtils.native.ts +0 -276
  46. package/ai/chat/fetchUtils.ts +0 -153
  47. package/ai/chat/parseApiError.ts +0 -64
  48. package/ai/chat/parseMultilineSSE.ts +0 -95
  49. package/ai/chat/sendOpenAICompletionsRequest.native.ts +0 -682
  50. package/ai/chat/sendOpenAICompletionsRequest.ts +0 -703
  51. package/ai/chat/sendOpenAIResponseRequest.ts +0 -491
  52. package/ai/chat/shouldUseServerProxy.ts +0 -18
  53. package/ai/chat/sseClient.native.ts +0 -91
  54. package/ai/chat/sseClient.ts +0 -67
  55. package/ai/chat/streamReader.native.ts +0 -31
  56. package/ai/chat/streamReader.ts +0 -62
  57. package/ai/chat/updateTotalUsage.ts +0 -72
  58. package/ai/context/buildReferenceContext.ts +0 -437
  59. package/ai/context/calculateContextUsage.ts +0 -133
  60. package/ai/context/retention.ts +0 -165
  61. package/ai/context/tokenUtils.ts +0 -78
  62. package/ai/index.ts +0 -1
  63. package/ai/llm/calculateGeminiImageTokens.ts +0 -57
  64. package/ai/llm/deepinfra.ts +0 -28
  65. package/ai/llm/fireworks.ts +0 -50
  66. package/ai/llm/generateRequestBody.ts +0 -165
  67. package/ai/llm/getModelContextWindow.ts +0 -84
  68. package/ai/llm/getNoloKey.ts +0 -31
  69. package/ai/llm/getPricing.ts +0 -199
  70. package/ai/llm/hooks/useModelPricing.ts +0 -75
  71. package/ai/llm/imagePricing.ts +0 -40
  72. package/ai/llm/isResponseAPIModel.ts +0 -13
  73. package/ai/llm/mimo.ts +0 -71
  74. package/ai/llm/mistral.ts +0 -22
  75. package/ai/llm/modelAvatar.ts +0 -427
  76. package/ai/llm/models.ts +0 -45
  77. package/ai/llm/openrouterModels.ts +0 -269
  78. package/ai/llm/providers.ts +0 -306
  79. package/ai/llm/reasoningModels.ts +0 -28
  80. package/ai/llm/types.ts +0 -59
  81. package/ai/llm/usageRequestOptions.ts +0 -59
  82. package/ai/memory/capture.ts +0 -148
  83. package/ai/memory/consolidate.ts +0 -104
  84. package/ai/memory/delete.ts +0 -147
  85. package/ai/memory/overlay.ts +0 -84
  86. package/ai/memory/query.ts +0 -38
  87. package/ai/memory/queryShared.ts +0 -160
  88. package/ai/memory/rank.ts +0 -105
  89. package/ai/memory/recentRelationshipRecap.ts +0 -249
  90. package/ai/memory/remember.ts +0 -167
  91. package/ai/memory/runtime.ts +0 -76
  92. package/ai/memory/store.ts +0 -20
  93. package/ai/memory/storeShared.ts +0 -76
  94. package/ai/memory/types.ts +0 -46
  95. package/ai/memory/understanding.ts +0 -349
  96. package/ai/memory/understandingGreeting.ts +0 -264
  97. package/ai/messages/type.ts +0 -20
  98. package/ai/policy/personalizationDialog.ts +0 -333
  99. package/ai/policy/runtimePolicy.ts +0 -440
  100. package/ai/policy/selfUpdateFields.ts +0 -48
  101. package/ai/policy/types.ts +0 -64
  102. package/ai/skills/referenceRuntime.ts +0 -274
  103. package/ai/skills/skillDiagnostics.ts +0 -251
  104. package/ai/skills/skillDocBuilder.ts +0 -139
  105. package/ai/skills/skillDocProtocol.ts +0 -434
  106. package/ai/skills/skillReferenceSummary.ts +0 -63
  107. package/ai/skills/skillSummaryMarker.ts +0 -26
  108. package/ai/token/calculatePrice.ts +0 -544
  109. package/ai/token/db.ts +0 -98
  110. package/ai/token/externalToolCost.ts +0 -330
  111. package/ai/token/hooks/useRecords.ts +0 -65
  112. package/ai/token/missingUsageEstimate.ts +0 -42
  113. package/ai/token/modelUsageQuery.ts +0 -252
  114. package/ai/token/normalizeUsage.ts +0 -84
  115. package/ai/token/openaiImageGenerationUsage.ts +0 -56
  116. package/ai/token/prepareTokenUsageData.ts +0 -88
  117. package/ai/token/query.ts +0 -88
  118. package/ai/token/queryUserTokens.ts +0 -59
  119. package/ai/token/resolveBillingTarget.ts +0 -52
  120. package/ai/token/saveTokenRecord.ts +0 -53
  121. package/ai/token/serverDialogProjection.ts +0 -78
  122. package/ai/token/serverTokenWriter.ts +0 -143
  123. package/ai/token/stats.ts +0 -21
  124. package/ai/token/tokenThunks.ts +0 -24
  125. package/ai/token/types.ts +0 -93
  126. package/ai/tools/agent/agentTools.ts +0 -176
  127. package/ai/tools/agent/agentUpdateShared.ts +0 -311
  128. package/ai/tools/agent/callAgentTool.ts +0 -139
  129. package/ai/tools/agent/createAgentTool.ts +0 -512
  130. package/ai/tools/agent/createDialogTool.ts +0 -69
  131. package/ai/tools/agent/createSkillAgentTool.ts +0 -62
  132. package/ai/tools/agent/parallelBudget.ts +0 -221
  133. package/ai/tools/agent/presets/appBuilderPreset.ts +0 -145
  134. package/ai/tools/agent/runLlmTool.ts +0 -96
  135. package/ai/tools/agent/runStreamingAgentTool.ts +0 -73
  136. package/ai/tools/agent/skillAgentArgs.ts +0 -106
  137. package/ai/tools/agent/skillAgentPreset.ts +0 -89
  138. package/ai/tools/agent/streamParallelAgentsTool.ts +0 -122
  139. package/ai/tools/agent/updateAgentTool.ts +0 -96
  140. package/ai/tools/agent/updateSelfTool.ts +0 -113
  141. package/ai/tools/amazonProductScraperTool.ts +0 -86
  142. package/ai/tools/apifyActorClient.ts +0 -45
  143. package/ai/tools/appEditGuard.ts +0 -372
  144. package/ai/tools/appReadSnapshot.ts +0 -153
  145. package/ai/tools/appTools.ts +0 -1549
  146. package/ai/tools/applyEditTool.ts +0 -256
  147. package/ai/tools/applyLineEditsTool.ts +0 -312
  148. package/ai/tools/browserTools/click.ts +0 -33
  149. package/ai/tools/browserTools/closeSession.ts +0 -29
  150. package/ai/tools/browserTools/common.ts +0 -27
  151. package/ai/tools/browserTools/openSession.ts +0 -48
  152. package/ai/tools/browserTools/readContent.ts +0 -38
  153. package/ai/tools/browserTools/selectOption.ts +0 -46
  154. package/ai/tools/browserTools/typeText.ts +0 -42
  155. package/ai/tools/category/createCategoryTool.ts +0 -66
  156. package/ai/tools/category/queryContentsByCategoryTool.ts +0 -69
  157. package/ai/tools/category/updateContentCategoryTool.ts +0 -75
  158. package/ai/tools/cfBrowserTools.ts +0 -319
  159. package/ai/tools/cfSpeechToTextTool.ts +0 -49
  160. package/ai/tools/checkEnvTool.ts +0 -65
  161. package/ai/tools/cloudflareCrawlTool.ts +0 -289
  162. package/ai/tools/codeSearchTool.ts +0 -111
  163. package/ai/tools/codeTools.ts +0 -101
  164. package/ai/tools/createDocTool.ts +0 -132
  165. package/ai/tools/createPlanTool.ts +0 -999
  166. package/ai/tools/createSkillDocTool.ts +0 -155
  167. package/ai/tools/createWorkflowTool.ts +0 -154
  168. package/ai/tools/deepseekOcrTool.ts +0 -34
  169. package/ai/tools/delayTool.ts +0 -31
  170. package/ai/tools/deleteSpacesTool.ts +0 -325
  171. package/ai/tools/deleteSpacesToolModel.ts +0 -159
  172. package/ai/tools/devReloadUtils.ts +0 -29
  173. package/ai/tools/dialogMessageSearch.ts +0 -137
  174. package/ai/tools/doctorSkillTool.ts +0 -72
  175. package/ai/tools/ecommerceScraperTool.ts +0 -86
  176. package/ai/tools/emailTools.ts +0 -549
  177. package/ai/tools/evalSkillTool.ts +0 -92
  178. package/ai/tools/exaSearchTool.ts +0 -64
  179. package/ai/tools/execBashTool.ts +0 -379
  180. package/ai/tools/executeSqlTool.ts +0 -192
  181. package/ai/tools/fetchWebpageSupport.ts +0 -309
  182. package/ai/tools/fetchWebpageTool.ts +0 -84
  183. package/ai/tools/geminiImagePreviewTool.ts +0 -361
  184. package/ai/tools/generateDocxTool.ts +0 -215
  185. package/ai/tools/googleSearchScraperTool.ts +0 -106
  186. package/ai/tools/importDataTool.ts +0 -133
  187. package/ai/tools/importSkillTool.ts +0 -162
  188. package/ai/tools/index.ts +0 -1858
  189. package/ai/tools/listFilesTool.ts +0 -82
  190. package/ai/tools/listUserSpacesTool.ts +0 -113
  191. package/ai/tools/modelUsageTools.ts +0 -142
  192. package/ai/tools/olmOcrTool.ts +0 -34
  193. package/ai/tools/openaiImageTool.ts +0 -218
  194. package/ai/tools/paddleOcrTool.ts +0 -34
  195. package/ai/tools/prepareTools.ts +0 -23
  196. package/ai/tools/readDocTool.ts +0 -84
  197. package/ai/tools/readFileTool.ts +0 -211
  198. package/ai/tools/readTool.ts +0 -163
  199. package/ai/tools/readXPostTool.ts +0 -233
  200. package/ai/tools/rememberMemoryTool.ts +0 -84
  201. package/ai/tools/remotionVideoTool.ts +0 -151
  202. package/ai/tools/searchDialogMessagesTool.ts +0 -222
  203. package/ai/tools/searchRepoTool.ts +0 -115
  204. package/ai/tools/searchWorkspaceTool.ts +0 -259
  205. package/ai/tools/skillFollowup.ts +0 -86
  206. package/ai/tools/surfWeatherTool.ts +0 -169
  207. package/ai/tools/table/addTableRowTool.ts +0 -217
  208. package/ai/tools/table/createTableTool.ts +0 -315
  209. package/ai/tools/table/rowTools.ts +0 -366
  210. package/ai/tools/table/schemaTools.ts +0 -244
  211. package/ai/tools/table/shareTableTool.ts +0 -148
  212. package/ai/tools/table/toolShared.ts +0 -129
  213. package/ai/tools/toolApiClient.ts +0 -198
  214. package/ai/tools/toolNameAliases.ts +0 -57
  215. package/ai/tools/toolResultError.ts +0 -42
  216. package/ai/tools/toolRunSlice.ts +0 -303
  217. package/ai/tools/toolSchemaCompatibility.ts +0 -53
  218. package/ai/tools/toolVisibility.ts +0 -4
  219. package/ai/tools/types.ts +0 -20
  220. package/ai/tools/uiAskChoiceTool.ts +0 -104
  221. package/ai/tools/updateContentTitleTool.ts +0 -84
  222. package/ai/tools/updateDocTool.ts +0 -105
  223. package/ai/tools/updateUserPreferenceProfileTool.ts +0 -145
  224. package/ai/tools/whisperTool.ts +0 -77
  225. package/ai/tools/writeFileTool.ts +0 -210
  226. package/ai/tools/youtubeScraperTool.ts +0 -116
  227. package/ai/tools/ziweiChartTool.ts +0 -678
  228. package/ai/types.ts +0 -55
  229. package/ai/workflow/workflowExecutor.ts +0 -323
  230. package/ai/workflow/workflowSlice.ts +0 -73
  231. package/ai/workflow/workflowTypes.ts +0 -106
  232. package/connector-experimental/index.ts +0 -5
@@ -1,532 +0,0 @@
1
- // 文件路径: ai/agent/buildSystemPrompt.ts
2
- // 平台通用 Agent System Prompt 生成器
3
- // 所有模型调用的 system prompt 均由此函数构建
4
-
5
- import { mapLanguage } from "app/i18n/mapLanguage";
6
- import { Agent } from "app/types";
7
- import { buildSkillGuidancePromptBlock } from "ai/skills/referenceRuntime";
8
- import { buildRuntimeGuidanceBlocks } from "ai/agent/runtimeGuidance";
9
- import { canonicalizeToolNames } from "ai/tools/toolNameAliases";
10
- import { compileContextLayers, type CompiledContext } from "./contextCompiler";
11
- import { Contexts } from "../types";
12
-
13
- // ============================================================================
14
- // 参考资料使用说明(对所有 Agent 注入)
15
- // ============================================================================
16
-
17
- const CONTEXT_USAGE_INSTRUCTIONS = `参考资料使用说明:
18
- - 下方提供的资料是你的主要权威信息来源。
19
- - 回答问题时,应优先依赖这些资料。它们按优先级从高到低排列。
20
- - 使用其中的事实、数据和名称时,要保持精准。
21
- - 如果资料中没有包含答案,应说明这一点,然后再使用你的通用知识进行回答。
22
- - 如果你在资料中发现相互矛盾的信息,也要在回答中指出这一点。
23
- - 当通用指令与更具体的"按 Agent / 按文档"的规则发生冲突时,必须优先遵守更具体、优先级更高的规则。`;
24
-
25
- // ============================================================================
26
- // 交互说明(有 ui_ask_choice 工具时注入)
27
- // ============================================================================
28
-
29
- const MENU_USAGE_INSTRUCTIONS = `--- 交互说明(菜单与快捷入口) ---
30
- 在这个系统里,无论用户是手动输入文字,还是点击某个按钮/菜单,最终你只会收到一条普通的自然语言消息(就像用户直接键入的一样)。
31
-
32
- 对你来说:
33
- - 不要假设或讨论用户点击了哪些按钮、使用了什么菜单,也不要在回复中提到"按钮""菜单""界面""第几个选项"等字样。
34
- - 把所有收到的消息都当作用户刚刚输入的一句话,根据这句话的内容直接理解和回答即可。
35
- - 当你希望用户在几个互斥选项之间做选择时,可以调用 ui_ask_choice 工具;用户的选择会以一条新的自然语言消息的形式出现在后续对话中。`;
36
-
37
- // ============================================================================
38
- // 网页访问(有 exa_search 工具时注入)
39
- // ============================================================================
40
-
41
- const WEBPAGE_ACCESS_INSTRUCTIONS = `--- 网页访问能力 (Web Access) ---
42
- 你拥有访问互联网的强大能力。在需要获取外部信息时,请遵循以下由简入繁的策略:
43
-
44
- 0. **如果用户已经给了明确 URL,先直接抓这些 URL**
45
- - 不要先搜索,不要先猜备用网址,不要忽略用户给的链接。
46
- - 用户明确给出的 URL,默认就是本次任务的最高优先级网页真值来源。
47
- - 如果 URL 是 X/Twitter status 链接(例如 \`x.com/.../status/...\` 或 \`twitter.com/.../status/...\`),并且你拥有 \`read_x_post\` 工具,应优先调用 \`read_x_post\`,不要先用搜索、镜像站或通用网页抓取替代。
48
- - 如果任务是“根据这些网页更新代码 / 文档 / 配置”,先逐个 fetch,再基于抓到的内容提取字段。
49
- - 只要这些 URL 能正常抓取,就不要再调用 exa_search 搜索“更权威”的来源,也不要自行切换到其他站点或镜像页。
50
- - 只有在用户给的 URL 抓取失败、页面明显缺字段、或页面内容与任务不匹配时,才允许额外搜索;如果发生这种降级,最终回复里要明确说明原因。
51
-
52
- 1. **优先使用 exa_search (Exa.ai)**
53
- - 适用于:用户没有给明确 URL 时,搜索互联网信息、寻找教程、获取最新动态。
54
- - 对陌生的文档站或你还不确定具体页面路径的 docs 站点,优先先用它发现权威入口,而不是直接猜 docs 子路径。
55
- - 优点:它是专为 AI 设计的神经网络搜索引擎,能直接返回高质量、结构化的内容(包含正文),无需再去爬取。
56
- - *Always try this FIRST for searches.*
57
-
58
- 2. **其次使用 fetchWebpage (全渲染)**
59
- - 适用于:你已经有了明确的 URL,需要获取该页面的完整内容(含 JS 渲染、动态内容、SPA)。
60
- - 底层走 Cloudflare Browser Rendering,支持 JS 执行,返回渲染后的正文。
61
- - 对于 \`docs.*\` 文档站,fetchWebpage 会自动检查 \`/llms.txt\` 和 \`/llms-full.txt\`,并把你推测的文档 URL 规范化为权威页面。
62
- - 如果你不确定 docs 站里有哪些页面,先用 exa_search 做发现;如果你只是大致猜到了 docs 子路径,可以直接交给 fetchWebpage 去规范化并抓取。
63
- - 优点:一次调用即可获取完整页面内容,无需手动操控浏览器。
64
-
65
- 3. **仅当需要复杂交互时使用 browser_openSession**
66
- - 仅当需要登录、填表、多步点击等复杂操作时使用。
67
- - 适用于:需要登录的站点、需要填写表单、需要连续交互的场景。
68
- - 流程:先 openSession -> 拿到 ID -> 再 typeText / click / readContent。
69
-
70
-
71
- 3. **精准数据抓取 (Scrapers)**
72
- - 如果用户明确需要 YouTube 视频信息、亚马逊商品数据、Google 搜索结果,请直接使用对应的专用 Scraper 工具 (youtubeScraper, amazonProductScraper 等),效果比自己去爬网页更好。`;
73
-
74
- // ============================================================================
75
- // Agent 编排协作(有 callAgent / runStreamingAgent 工具时注入)
76
- // ============================================================================
77
-
78
- const AGENT_ORCHESTRATION_INSTRUCTIONS = `--- Agent 编排与协作 ---
79
- 你所在的系统支持多个子 Agent 和工作流工具,请把自己视为"总协调者":
80
-
81
- 1)子 Agent 协作
82
- - 使用 callAgent 工具,可以让其它 Agent 作为"专家顾问"分别给出意见或完成子任务。
83
- - 使用 runStreamingAgent 工具,可以把后续对话完全交给某个专用 Agent(例如代码助手、翻译助手)。
84
- - 使用 streamParallelAgents 工具,可以并行询问多个 Agent,再由你继续综合共识和分歧。
85
- - 如果目标 Agent 记录已经声明 delegation.serverBase / runtimeServerBase,工具会自动路由到对应 nolo server;你不需要重复填写 serverBase。
86
- - 如果用户明确给了另一个可访问的 server origin(例如 Windows 机器的 Cloudflare 域名),可以在工具参数里传 serverBase 覆盖自动路由;不要臆造地址,也不要把普通 localhost 当成远端机器。
87
- - 当用户需要多视角分析或辩论时,你可以:
88
- - 先用 callAgent 依次询问多个 Agent 对同一问题的看法;
89
- - 在最后一条回复中,用你自己的话帮用户总结这些观点的异同,并给出综合结论。
90
-
91
- 2)工作流 / Workflow 工具
92
- - 对于需要多步骤、顺序依赖或批量工具调用的复杂任务,应优先考虑使用 createWorkflow 这类工作流工具。
93
- - 调用工作流工具时,你负责:
94
- - 清楚描述目标和约束;
95
- - 在工作流执行过程中关注其输出的中间结果和最终结果;
96
- - 当你认为任务足够完成,或用户要求总结时,对整个过程和结果进行总结,指出可能的错误或风险。
97
-
98
- 3)危险 / 不可逆操作
99
- - 涉及不可逆操作时(修改文件、删除数据、发送消息、生成正式文件、执行交易等),请优先预览或向用户确认。
100
- - 当工具返回"预览"或"待确认"状态时,请暂停进一步自动修改,等待用户明确确认或反馈后再继续。不要在用户未确认前连续发出多次破坏性修改。`;
101
-
102
- // ============================================================================
103
- // 知识管理(有 createDoc / updateDoc / read 工具时注入)
104
- // 仅包含页面级知识管理,不含自我更新能力
105
- // ============================================================================
106
-
107
- const KNOWLEDGE_MANAGEMENT_INSTRUCTIONS = `--- 知识管理 ---
108
- 你拥有 read / createDoc / updateDoc 能力,应主动管理知识,而不是每次重新推理。
109
-
110
- ## 三层知识决策
111
-
112
- **1. 直接写进 prompt**(需要 updateAgent 权限)
113
- - 极短、每次必用的规则(角色定义、回复风格、固定限制)
114
- - 标准:去掉它你就不知道自己是谁
115
-
116
- **2. references 挂载知识(每次对话自动加载)**
117
- - Agent 配置里的 references 会在每次对话开始时自动展开注入到 system prompt
118
- - type=instruction:高优先级,注入到 system prompt 顶部,适合行为规则、操作指南
119
- - type=knowledge:作为参考资料注入,适合领域知识、背景资料
120
- - 支持挂载:page / dialog / table(内容完整展开)
121
- - **page 里的 @mention 只展开元信息(标题+dbKey),不递归展开内容本身**
122
-
123
- **3. createDoc 创建文档(按需 read 加载)**
124
- - 总知识页(索引):跨会话的决策规则、路由表,用 @[page:PAGE-xxx|标题] mention 指向细分页
125
- - 细分知识页(内容):具体领域内容、任务结果,通过总知识索引
126
- - mention 只是指针,要获取细分页内容必须显式调用 read({ dbKey })
127
-
128
- ## 读取路径
129
- 1. prompt / references 有答案 → 直接用(自动加载,最快)
130
- 2. 没有 → read({ dbKey: 总知识索引页 }) 找到细分页 dbKey
131
- 3. 找到 dbKey → read({ dbKey: 细分页 }) 获取完整内容
132
-
133
- ## 何时主动创建/更新知识
134
- - 用户提供了值得复用的信息 → createDoc 记录,再用 updateAgent 把该页加入 references
135
- - 完成有价值的调研/分析 → createDoc 保存结论
136
- - 总知识索引缺入口 → updateDoc 补充 @mention
137
- - **不要**把临时性、一次性的内容写成知识页`;
138
-
139
- // ============================================================================
140
- // 长期记忆(有 rememberMemory 工具时注入)
141
- // ============================================================================
142
-
143
- const MEMORY_CAPTURE_INSTRUCTIONS = `--- 长期记忆 ---
144
- 你拥有 rememberMemory 能力,可以在必要时把值得长期保留的信息写成一条 episodic memory。
145
-
146
- ## 何时记录
147
- - 当你识别到对未来协作明显有帮助、且相对稳定的用户偏好、判断标准、信息组织偏好或场景化抉择模式时,可以记录
148
- - 当对话里形成了后续还会反复用到的空间共识、协作约定或团队规则时,可以记录
149
-
150
- ## 何时不要记录
151
- - 一次性的当前任务细节
152
- - 当前对话里显而易见、很快就会过期的事实
153
- - 只是为了“多记一点”而勉强抽出来的内容
154
-
155
- ## 记录方式
156
- - 优先写成简短、可复用的抽象表达,例如“这个用户在什么场景下通常怎么选 / 怎么协作”
157
- - 不要复制整段对话,也不要把临时上下文原样塞进去
158
- - 只有当前 dialog 明确绑定了 space,且这条信息确实属于共享协作共识时,才传 scope=space;否则保持默认 auto
159
- - 默认静默执行;除非用户正在讨论记忆本身,或需要用户感知这件事,否则不要专门宣布“我正在记忆”
160
- - 如果这条信息对未来帮助不明显,就不要调用 rememberMemory`;
161
-
162
- // ============================================================================
163
- // 自我更新能力(仅在 Agent 拥有 updateSelf 工具时注入)
164
- // ============================================================================
165
-
166
- const SELF_UPDATE_INSTRUCTIONS = `--- Agent 自我更新能力 ---
167
- 你拥有 updateSelf 权限,可以修改自己的配置。请谨慎、精准地使用。
168
-
169
- ## 何时更新自己
170
- - 重要决策/进度变化 → updateDoc 写回状态页
171
- - 值得复用的知识 → createDoc 建细分页,再按需要更新自己的 references / greeting / introduction
172
- - 小幅体验优化 → updateSelf 调整 greeting / introduction / tags
173
-
174
- ## 更新原则
175
- - 优先形成最小、可解释的变更,不要为了“显得在进化”而频繁改自己
176
- - 低风险沉淀优先写入 memory / doc;只有当这些知识需要长期改变你的行为方式时,再考虑 updateSelf
177
- - prompt / references / tools / model 这类高影响字段,默认按需要确认来处理,不要静默大改
178
- - 如果工具返回 policy limit / ask / reject,不要重复尝试,应先向用户解释或等待更高权限确认
179
- - 没有发生实际更新时,不要在回复末尾额外汇报“未更新”状态`;
180
-
181
- const GENERIC_AGENT_UPDATE_INSTRUCTIONS = `--- Agent 维护能力 ---
182
- 你拥有 updateAgent 权限,可以更新指定的 Agent。
183
-
184
- ## 何时更新别的 Agent
185
- - 用户明确要求你维护、修复或批量调整另一个 Agent
186
- - 你需要修改的目标不是当前正在运行的自己
187
-
188
- ## 更新原则
189
- - 默认把 updateAgent 当成高风险维护操作,优先最小改动
190
- - 修改前先确认目标 Agent 是否正确,避免误改
191
- - 如果工具返回需要确认,不要绕过确认流程`;
192
-
193
- const CODE_EDITING_FIDELITY_INSTRUCTIONS = `--- 代码编辑真值规则 ---
194
- 当任务涉及 readFile / writeFile / applyEdit / applyLineEdits 等代码编辑工具时,必须遵守以下规则:
195
-
196
- - 先读取目标文件的最新内容,再决定修改。
197
- - 如果用户提供了 URL、文档页或产品页,且你需要据此改代码,必须先抓取这些网页,再开始编辑。
198
- - 如果用户已经提供可用 URL,就不要再搜索替代来源;只有这些 URL 无法满足任务时,才允许降级到搜索,并在最终回复中说明。
199
- - 网页中直接出现的模型名、价格、上下文窗口、发布日期、能力描述、是否支持 function calling / vision 等字段,视为本次修改的权威来源。
200
- - 如果用户提供了精确代码块、对象字面量、字段值、补丁片段或“唯一真值”,必须逐字使用这些内容,不得自行润色、改写数值、替换描述或补全你记忆里的“更合理版本”。
201
- - 对价格、上下文窗口、模型能力、布尔字段、枚举值这类结构化配置,禁止凭记忆推断。
202
- - 如果网页没有明确给出某个字段,不要编造。优先保留文件中已有的相邻风格与安全默认值,或只填写网页能直接支持的字段。
203
- - 保守默认值规则:
204
- - 对“新加模型条目”,recommended 必须默认 false。只有用户明确要求“设为推荐/高亮”,才允许写成 true。网页里的营销词(如 flagship、strong default、best-in-class)不构成 recommended=true 的证据。
205
- - deprecated 默认 false,除非网页明确写了废弃、停用、legacy、sunset。
206
- - supportReasoning 默认 false,除非网页明确说明该模型支持 reasoning / thinking / reasoning tokens。
207
- - supportVision 只有在网页明确出现 image input / multimodal / vision 支持时才设为 true。
208
- - supportTool 只有在网页明确出现 function calling / tool calling / tools 支持时才设为 true。
209
- - 最终汇报必须以“实际写入后的文件内容”或 applyEdit / writeFile 的返回结果为准,不要汇报没有真正落盘的字段值。
210
- - 编辑完成后,最终回复只做简短结果汇报:说清改了哪些条目、依据了哪些 URL、是否还有缺失字段。不要长篇复述网页正文。`;
211
-
212
- const TABLE_SHARE_INSTRUCTIONS = `--- 表格创建与分享 ---
213
- 当用户要你整理结构化信息时,可以先用 createTable 建表,再用 addTableRow / addTableRows 填充内容。
214
-
215
- 如果用户明确要求“社区分享 / 公开分享 / 分享链接”,并且你有 shareTable 工具:
216
- - 优先调用 shareTable;
217
- - 传入表的 dbKey,或 tenantId + tableId;
218
- - 完成后直接返回 /share/... 链接。`;
219
-
220
- // ============================================================================
221
- // 无 prompt 时的澄清模式
222
- // ============================================================================
223
-
224
- const CLARIFICATION_MODE_INSTRUCTIONS = `在你还不了解用户意图时,通过提问来澄清需求,而不是仓促给出答案。`;
225
-
226
- const isBrowser = typeof window !== "undefined";
227
-
228
- // ============================================================================
229
- // 工具函数
230
- // ============================================================================
231
-
232
- /** 创建一个上下文 section,如果 content 为空则返回空字符串 */
233
- const createContextSection = (
234
- title: string,
235
- description: string,
236
- content?: string | null
237
- ): string =>
238
- content ? `### ${title} \n${description} \n\n${content} ` : "";
239
-
240
- /** 获取当前 UTC 时间(精确到天) */
241
- const getCurrentTimeString = (): string => {
242
- return new Date().toLocaleDateString("en-US", { timeZone: "UTC" });
243
- };
244
-
245
- /** 根据屏幕宽度生成响应式布局建议 */
246
- const buildResponseGuidelines = (isMobile: boolean): string => {
247
- if (isMobile) {
248
- return `-- - 响应展示指南-- -
249
- 请为移动端进行优化:
250
- - 使用更短的段落和简洁的项目符号列表。
251
- - 避免过宽的表格或代码块,以免产生横向滚动。
252
- - 优先采用垂直排布,而不是左右并排的布局。`;
253
- }
254
- return `-- - 响应展示指南-- -
255
- 你的回复将显示在大屏幕上。你可以:
256
- - 提供更丰富的推理过程说明和更有层次的结构。
257
- - 在合适的场景下使用宽屏优势,例如更宽的表格、并排对比展示、更长的代码块等。`;
258
- };
259
-
260
- /** 构建参考资料区块 */
261
- const buildReferenceMaterialsBlock = (contexts: Contexts): string => {
262
- const sections = [
263
- createContextSection(
264
- "说明性文档(Instructional Documents)",
265
- "(最高优先级:具体规则与流程)",
266
- contexts.botInstructionsContext
267
- ),
268
- createContextSection(
269
- "当前输入上下文(Current Input Context)",
270
- "(高优先级:来自用户本次输入)",
271
- contexts.currentInputContext
272
- ),
273
- createContextSection(
274
- "会话历史引用(Conversation History References)",
275
- "(中等优先级:来自过往消息)",
276
- contexts.historyContext
277
- ),
278
- createContextSection(
279
- "知识库文档(Knowledge Base Documents)",
280
- "(参考优先级:用于通用查阅)",
281
- contexts.botKnowledgeContext
282
- ),
283
- ].filter(Boolean);
284
-
285
- if (sections.length === 0) {
286
- return "";
287
- }
288
-
289
- return [
290
- "--- 参考资料 ---",
291
- CONTEXT_USAGE_INSTRUCTIONS,
292
- "",
293
- sections.join("\n\n"),
294
- ].join("\n");
295
- };
296
-
297
- /** 构建「当前编辑上下文」区块 */
298
- const buildEditingContextBlock = (contexts: Contexts): string => {
299
- if (!contexts.editingContext) return "";
300
-
301
- return [
302
- "--- 当前编辑上下文 ---",
303
- "下面是用户当前正在查看或编辑的对象描述,请在涉及修改、建议或结构性操作时优先参考这里:",
304
- "",
305
- contexts.editingContext,
306
- ].join("\n");
307
- };
308
-
309
- const buildAppWorkingMemoryBlock = (contexts: Contexts): string => {
310
- if (!contexts.appWorkingMemory) return "";
311
-
312
- return [
313
- "--- 最近应用工作记忆 ---",
314
- "下面是从当前对话最近的应用相关工具调用中提炼出的真值。即使用户没有打开右侧应用侧栏,只要他说“刚才那个 app / 那个网站 / 那个项目”,也优先参考这里:",
315
- "",
316
- contexts.appWorkingMemory,
317
- ].join("\n");
318
- };
319
-
320
- /** 构建「当前 Space 环境」区块 */
321
- const buildSpaceContextBlock = (contexts: Contexts): string => {
322
- if (!contexts.spaceContext) return "";
323
-
324
- return [
325
- "--- 当前空间环境 (Current Space Context) ---",
326
- contexts.spaceContext,
327
- "",
328
- "重要指令 (Space Awareness):",
329
- "- 你正处于上述工作空间中。如果用户的问题涉及到该空间的内容、文件或知识:",
330
- " - 使用 `read` 工具查阅普通数据记录或数据表项。",
331
- "- 如果你在对话中产出了值得保存的重要信息(如总结、方案、代码片段等),请主动询问用户或使用 `createDoc` 工具将其保存为新页面,以便作为长期记忆留存。",
332
- "",
333
- "跨空间导航 (Cross-Space Navigation):",
334
- "- 使用 `listUserSpaces` 工具可获取用户所有可访问的 Space 列表(ID 和名称)。",
335
- "- 使用 `read({ dbKey: \"space-{spaceId}\" })` 可获取指定 Space 的完整数据,包括:",
336
- " - categories: 分类字典,key 是分类 ID,value 包含 name 和 order",
337
- " - contents: 内容字典,每项包含 contentKey(dbKey)、title、type、categoryId",
338
- ].join("\n");
339
- };
340
-
341
- const buildUserPolicyBlock = (contexts: Contexts): string => {
342
- if (!contexts.userPolicyContext) return "";
343
-
344
- return [
345
- "--- 用户偏好与自动化边界 ---",
346
- contexts.userPolicyContext,
347
- ].join("\n");
348
- };
349
-
350
- const buildSkillGuidanceBlock = (agentConfig: Agent): string => {
351
- const recommendedSkillHints = Array.isArray((agentConfig as any).recommendedSkillHints)
352
- ? ((agentConfig as any).recommendedSkillHints as string[]).filter(Boolean)
353
- : [];
354
- const skillPromptPatches = Array.isArray((agentConfig as any).skillPromptPatches)
355
- ? ((agentConfig as any).skillPromptPatches as string[]).filter(Boolean)
356
- : [];
357
-
358
- if (recommendedSkillHints.length === 0 && skillPromptPatches.length === 0) {
359
- return "";
360
- }
361
-
362
- return buildSkillGuidancePromptBlock({
363
- title: "--- 技能提示 ---",
364
- recommendedSkillHints,
365
- skillPromptPatches,
366
- });
367
- };
368
-
369
- // ============================================================================
370
- // 主函数
371
- // ============================================================================
372
-
373
- export const buildSystemPrompt = (options: {
374
- agentConfig: Agent;
375
- language?: string;
376
- contexts?: Contexts;
377
- viewport?: { width: number; height: number };
378
- mobileBreakpoint?: number;
379
- }): string => buildSystemPromptContext(options).content;
380
-
381
- export const buildSystemPromptContext = (options: {
382
- agentConfig: Agent;
383
- language?: string;
384
- contexts?: Contexts;
385
- viewport?: { width: number; height: number };
386
- mobileBreakpoint?: number;
387
- }): CompiledContext => {
388
- const {
389
- agentConfig,
390
- contexts = {},
391
- viewport,
392
- mobileBreakpoint = 768,
393
- } = options;
394
-
395
- const safeLanguage =
396
- options.language ??
397
- (typeof navigator !== "undefined" ? navigator.language : "en");
398
-
399
- const { name, prompt: mainPrompt, dbKey } = agentConfig;
400
- const mappedLanguage = mapLanguage(safeLanguage);
401
-
402
- const identitySection = [
403
- "--- 身份信息 ---",
404
- name ? `名称: ${name} ` : "",
405
- dbKey ? `ID: ${dbKey} ` : "",
406
- mappedLanguage ? `回复语言: ${mappedLanguage} ` : "",
407
- `当前时间: ${getCurrentTimeString()} `,
408
- ]
409
- .filter(Boolean)
410
- .join("\n");
411
-
412
- const corePersonaSection = mainPrompt
413
- ? `-- - 核心角色与任务-- -\n${mainPrompt}`
414
- : "";
415
-
416
- const agentTools = canonicalizeToolNames(agentConfig.tools ?? []);
417
-
418
- // 按工具能力条件注入各指令块
419
- const agentOrchestrationSection = agentTools.some((t) =>
420
- ["callAgent", "runStreamingAgent", "streamParallelAgents"].includes(t)
421
- )
422
- ? AGENT_ORCHESTRATION_INSTRUCTIONS
423
- : "";
424
-
425
- const menuUsageSection = agentTools.includes("ui_ask_choice")
426
- ? MENU_USAGE_INSTRUCTIONS
427
- : "";
428
-
429
- const webAccessSection = agentTools.some((t) =>
430
- ["exa_search", "fetchWebpage", "browser_openSession", "read_x_post"].includes(t)
431
- )
432
- ? WEBPAGE_ACCESS_INSTRUCTIONS
433
- : "";
434
- const tableShareSection = agentTools.some((t) =>
435
- ["createTable", "shareTable", "addTableRow", "addTableRows"].includes(t)
436
- )
437
- ? TABLE_SHARE_INSTRUCTIONS
438
- : "";
439
-
440
- // 知识管理:有页面读写工具时注入通用知识管理说明
441
- const knowledgeManagementSection = agentTools.some((t) =>
442
- ["createDoc", "updateDoc", "read", "readDoc", "readPage"].includes(t)
443
- )
444
- ? KNOWLEDGE_MANAGEMENT_INSTRUCTIONS
445
- : "";
446
-
447
- const memoryCaptureSection = agentTools.includes("rememberMemory")
448
- ? MEMORY_CAPTURE_INSTRUCTIONS
449
- : "";
450
-
451
- const selfUpdateSection = agentTools.includes("updateSelf")
452
- ? SELF_UPDATE_INSTRUCTIONS
453
- : "";
454
-
455
- const genericAgentUpdateSection = agentTools.includes("updateAgent")
456
- ? GENERIC_AGENT_UPDATE_INSTRUCTIONS
457
- : "";
458
-
459
- const codeEditingFidelitySection = agentTools.some((t) =>
460
- ["readFile", "writeFile", "applyEdit", "applyLineEdits"].includes(t)
461
- )
462
- ? CODE_EDITING_FIDELITY_INSTRUCTIONS
463
- : "";
464
-
465
- const {
466
- startupProtocol,
467
- contextLayerContract,
468
- emailRegistrationWorkflow,
469
- } =
470
- buildRuntimeGuidanceBlocks(agentTools);
471
-
472
- const clarifyingSection = !mainPrompt ? CLARIFICATION_MODE_INSTRUCTIONS : "";
473
-
474
- const userGlobalPromptSection = contexts.userGlobalPrompt?.trim()
475
- ? `-- - 用户全局偏好-- -\n${contexts.userGlobalPrompt.trim()} `
476
- : "";
477
-
478
- const isMobile =
479
- (viewport?.width ?? (isBrowser ? window.innerWidth : 1440)) <
480
- mobileBreakpoint;
481
-
482
- const responseGuidelinesSection = buildResponseGuidelines(isMobile);
483
- const editingContextSection = buildEditingContextBlock(contexts);
484
- const appWorkingMemorySection = buildAppWorkingMemoryBlock(contexts);
485
- const spaceContextSection = buildSpaceContextBlock(contexts);
486
- const userPolicySection = buildUserPolicyBlock(contexts);
487
- const skillGuidanceSection = buildSkillGuidanceBlock(agentConfig);
488
- const referenceMaterialsSection = buildReferenceMaterialsBlock(contexts);
489
-
490
- const dialogSummarySection = contexts.dialogSummary?.trim()
491
- ? `--- 历史对话摘要 ---\n以下是此前对话轮次的压缩摘要(精确细节可能有简化,请优先参考最近的消息原文):\n\n${contexts.dialogSummary.trim()}`
492
- : "";
493
-
494
- const proactiveSummarySection = contexts.proactiveSummary?.trim()
495
- ? `--- 阶段工作摘要 ---\n以下是系统主动整理的近期工作摘要,原始消息仍在近期上下文中;如有冲突,请优先参考最近的消息原文:\n\n${contexts.proactiveSummary.trim()}`
496
- : "";
497
-
498
- return compileContextLayers([
499
- { id: "identity", owner: "platform", content: identitySection },
500
- { id: "core-persona", owner: "agent", content: corePersonaSection },
501
- { id: "agent-orchestration", owner: "platform", content: agentOrchestrationSection },
502
- { id: "web-access", owner: "platform", content: webAccessSection },
503
- { id: "table-share", owner: "platform", content: tableShareSection },
504
- { id: "menu-usage", owner: "platform", content: menuUsageSection },
505
- { id: "clarification-mode", owner: "platform", content: clarifyingSection },
506
- { id: "knowledge-management", owner: "platform", content: knowledgeManagementSection },
507
- { id: "memory-capture", owner: "platform", content: memoryCaptureSection },
508
- { id: "self-update", owner: "platform", content: selfUpdateSection },
509
- { id: "generic-agent-update", owner: "platform", content: genericAgentUpdateSection },
510
- { id: "code-editing-fidelity", owner: "platform", content: codeEditingFidelitySection },
511
- { id: "startup-protocol", owner: "platform", content: startupProtocol },
512
- { id: "context-layer-contract", owner: "platform", content: contextLayerContract },
513
- {
514
- id: "email-registration-workflow",
515
- owner: "platform",
516
- content: emailRegistrationWorkflow,
517
- },
518
- { id: "user-global-prompt", owner: "user", content: userGlobalPromptSection },
519
- { id: "response-guidelines", owner: "platform", content: responseGuidelinesSection },
520
- { id: "skill-guidance", owner: "runtime", content: skillGuidanceSection },
521
- { id: "dialog-summary", owner: "runtime", content: dialogSummarySection },
522
- { id: "proactive-summary", owner: "runtime", content: proactiveSummarySection },
523
- { id: "space-context", owner: "runtime", content: spaceContextSection },
524
- { id: "user-policy", owner: "user", content: userPolicySection },
525
- { id: "reference-materials", owner: "agent", content: referenceMaterialsSection },
526
- { id: "app-working-memory", owner: "runtime", content: appWorkingMemorySection },
527
- { id: "editing-context", owner: "runtime", content: editingContextSection },
528
- ]);
529
- };
530
-
531
- // 向后兼容:旧名称重新导出
532
- export const generatePrompt = buildSystemPrompt;
@@ -1,140 +0,0 @@
1
- // 文件路径: ai/agent/cleanAgentMessages.ts
2
-
3
- import type { Message } from "chat/messages/types";
4
-
5
- /**
6
- * 判断消息的文本内容是否“为空”(对人没意义)
7
- */
8
- const isEmptyContent = (content: unknown): boolean => {
9
- if (content == null) return true;
10
-
11
- if (typeof content === "string") {
12
- return content.trim().length === 0;
13
- }
14
-
15
- if (Array.isArray(content)) {
16
- return content.length === 0;
17
- }
18
-
19
- return false;
20
- };
21
-
22
- /**
23
- * 为指定 Agent 构造“安全”的消息视图:
24
- *
25
- * 分层目标:
26
- * - 这一层是「对话视角清洗」,不直接关心 OpenAI/Azure 精确协议,只关心:
27
- * 1)当前 Agent 能看到什么历史;
28
- * 2)哪些内部 plumbing 信息需要隐藏。
29
- *
30
- * 约定:
31
- * - 所有 Agent:
32
- * - 丢弃「assistant 且 content 为空 且 没有 tool 调用」的消息(通常是 streaming 占位,没实际内容)
33
- *
34
- * - 当前 Agent(cybotKey 匹配):
35
- * - user / assistant / tool 消息:原样保留(保证自己工具链完整)
36
- * - 特别地:即使 assistant 只有 tool 调用、没有文本,也要保留
37
- *
38
- * - 其它 Agent:
39
- * - assistant 消息:
40
- * - 删除所有 tool 调用字段(tool_calls / toolCalls),避免跨 Agent 的 call_id 冲突;
41
- * - 使用 agentName 作为前缀,生成可读文本:
42
- * - 有原始文本:`【AgentName】 原文...`
43
- * - 没有原始文本:`【AgentName】(使用了工具生成回复)`
44
- * - tool 消息:直接丢弃(内部 plumbing,对当前 Agent 没意义)
45
- *
46
- * - 其它角色(system 等):原样保留
47
- */
48
- export const buildAgentViewMessages = (
49
- allMessages: Message[],
50
- currentCybotKey: string
51
- ): Message[] => {
52
- const result: Message[] = [];
53
-
54
- for (const msg of allMessages) {
55
- if (!msg) continue;
56
-
57
- const role = (msg as any).role;
58
- if (!role) continue;
59
-
60
- // 同时兼容内部字段 toolCalls 和 OpenAI 标准字段 tool_calls
61
- const hasToolCalls =
62
- (Array.isArray((msg as any).tool_calls) &&
63
- (msg as any).tool_calls.length > 0) ||
64
- (Array.isArray((msg as any).toolCalls) &&
65
- (msg as any).toolCalls.length > 0);
66
-
67
- const empty = isEmptyContent((msg as any).content);
68
-
69
- // 1. 统一丢弃“空 assistant 且没有 tool 调用”的消息
70
- // - 对所有 Agent 一视同仁,这类通常是 streaming 中途写入的占位,没实际内容
71
- if (role === "assistant" && empty && !hasToolCalls) {
72
- continue;
73
- }
74
-
75
- const isCurrentAgent = (msg as any).cybotKey === currentCybotKey;
76
-
77
- // ---- 用户消息:所有 Agent 都需要完整历史 ----
78
- if (role === "user") {
79
- result.push(msg);
80
- continue;
81
- }
82
-
83
- // ---- 助手消息 ----
84
- if (role === "assistant") {
85
- if (isCurrentAgent) {
86
- // 当前 Agent 自己的历史回复:原样保留(包含 toolCalls / tool_calls)
87
- result.push(msg);
88
- } else {
89
- // 其它 Agent 的回复:降级为纯文本 + 前缀,不再携带任何 tool 调用字段
90
- const cloned: Message = { ...(msg as any) } as Message;
91
-
92
- // 删掉所有工具调用字段,避免跨 Agent 的 call_id 污染
93
- if ((cloned as any).tool_calls) {
94
- delete (cloned as any).tool_calls;
95
- }
96
- if ((cloned as any).toolCalls) {
97
- delete (cloned as any).toolCalls;
98
- }
99
-
100
- const rawAgentName = (cloned as any).agentName;
101
- const agentName =
102
- rawAgentName && String(rawAgentName).trim()
103
- ? String(rawAgentName).trim()
104
- : "其他 Agent";
105
-
106
- if (typeof cloned.content === "string") {
107
- const trimmed = cloned.content.trim();
108
- if (trimmed) {
109
- cloned.content = `【${agentName}】 ${trimmed}`;
110
- } else {
111
- cloned.content = `【${agentName}】(使用了工具生成回复)`;
112
- }
113
- } else {
114
- // 非字符串内容(理论上很少见),同样给一个占位说明
115
- cloned.content = `【${agentName}】(使用了工具生成回复)`;
116
- }
117
-
118
- result.push(cloned);
119
- }
120
- continue;
121
- }
122
-
123
- // ---- 工具消息 ----
124
- if (role === "tool") {
125
- if (isCurrentAgent) {
126
- // 当前 Agent 自己的 tool 消息:保留,保证工具调用链可用
127
- result.push(msg);
128
- } else {
129
- // 其它 Agent 的 tool 消息:全部丢弃,避免跨 Agent / 跨 provider 的 call_id 冲突
130
- continue;
131
- }
132
- continue;
133
- }
134
-
135
- // ---- 其它角色(system 等) ----
136
- result.push(msg);
137
- }
138
-
139
- return result;
140
- };