@xagent-ai/cli 1.0.1

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 (537) hide show
  1. package/.eslintrc.js +25 -0
  2. package/.gitmodules +3 -0
  3. package/.prettierrc.json +8 -0
  4. package/CONTRIBUTING.md +167 -0
  5. package/LICENSE +21 -0
  6. package/README.md +280 -0
  7. package/README_CN.md +280 -0
  8. package/dist/agents.d.ts +21 -0
  9. package/dist/agents.d.ts.map +1 -0
  10. package/dist/agents.js +463 -0
  11. package/dist/agents.js.map +1 -0
  12. package/dist/ai-client.d.ts +83 -0
  13. package/dist/ai-client.d.ts.map +1 -0
  14. package/dist/ai-client.js +1280 -0
  15. package/dist/ai-client.js.map +1 -0
  16. package/dist/auth.d.ts +25 -0
  17. package/dist/auth.d.ts.map +1 -0
  18. package/dist/auth.js +573 -0
  19. package/dist/auth.js.map +1 -0
  20. package/dist/cancellation.d.ts +46 -0
  21. package/dist/cancellation.d.ts.map +1 -0
  22. package/dist/cancellation.js +154 -0
  23. package/dist/cancellation.js.map +1 -0
  24. package/dist/checkpoint.d.ts +28 -0
  25. package/dist/checkpoint.d.ts.map +1 -0
  26. package/dist/checkpoint.js +186 -0
  27. package/dist/checkpoint.js.map +1 -0
  28. package/dist/cli.d.ts +3 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +364 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/config.d.ts +49 -0
  33. package/dist/config.d.ts.map +1 -0
  34. package/dist/config.js +205 -0
  35. package/dist/config.js.map +1 -0
  36. package/dist/context-compressor.d.ts +51 -0
  37. package/dist/context-compressor.d.ts.map +1 -0
  38. package/dist/context-compressor.js +231 -0
  39. package/dist/context-compressor.js.map +1 -0
  40. package/dist/conversation.d.ts +34 -0
  41. package/dist/conversation.d.ts.map +1 -0
  42. package/dist/conversation.js +221 -0
  43. package/dist/conversation.js.map +1 -0
  44. package/dist/gui-subagent/action-parser/actionParser.d.ts +19 -0
  45. package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -0
  46. package/dist/gui-subagent/action-parser/actionParser.js +203 -0
  47. package/dist/gui-subagent/action-parser/actionParser.js.map +1 -0
  48. package/dist/gui-subagent/action-parser/constants.d.ts +8 -0
  49. package/dist/gui-subagent/action-parser/constants.d.ts.map +1 -0
  50. package/dist/gui-subagent/action-parser/constants.js +12 -0
  51. package/dist/gui-subagent/action-parser/constants.js.map +1 -0
  52. package/dist/gui-subagent/action-parser/index.d.ts +3 -0
  53. package/dist/gui-subagent/action-parser/index.d.ts.map +1 -0
  54. package/dist/gui-subagent/action-parser/index.js +6 -0
  55. package/dist/gui-subagent/action-parser/index.js.map +1 -0
  56. package/dist/gui-subagent/action-parser/types.d.ts +24 -0
  57. package/dist/gui-subagent/action-parser/types.d.ts.map +1 -0
  58. package/dist/gui-subagent/action-parser/types.js +12 -0
  59. package/dist/gui-subagent/action-parser/types.js.map +1 -0
  60. package/dist/gui-subagent/agent/gui-agent.d.ts +126 -0
  61. package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -0
  62. package/dist/gui-subagent/agent/gui-agent.js +820 -0
  63. package/dist/gui-subagent/agent/gui-agent.js.map +1 -0
  64. package/dist/gui-subagent/agent/index.d.ts +5 -0
  65. package/dist/gui-subagent/agent/index.d.ts.map +1 -0
  66. package/dist/gui-subagent/agent/index.js +5 -0
  67. package/dist/gui-subagent/agent/index.js.map +1 -0
  68. package/dist/gui-subagent/index.d.ts +43 -0
  69. package/dist/gui-subagent/index.d.ts.map +1 -0
  70. package/dist/gui-subagent/index.js +96 -0
  71. package/dist/gui-subagent/index.js.map +1 -0
  72. package/dist/gui-subagent/operator/base-operator.d.ts +108 -0
  73. package/dist/gui-subagent/operator/base-operator.d.ts.map +1 -0
  74. package/dist/gui-subagent/operator/base-operator.js +172 -0
  75. package/dist/gui-subagent/operator/base-operator.js.map +1 -0
  76. package/dist/gui-subagent/operator/browser-operator.d.ts +36 -0
  77. package/dist/gui-subagent/operator/browser-operator.d.ts.map +1 -0
  78. package/dist/gui-subagent/operator/browser-operator.js +306 -0
  79. package/dist/gui-subagent/operator/browser-operator.js.map +1 -0
  80. package/dist/gui-subagent/operator/computer-operator.d.ts +31 -0
  81. package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -0
  82. package/dist/gui-subagent/operator/computer-operator.js +441 -0
  83. package/dist/gui-subagent/operator/computer-operator.js.map +1 -0
  84. package/dist/gui-subagent/operator/desktop-operator.d.ts +55 -0
  85. package/dist/gui-subagent/operator/desktop-operator.d.ts.map +1 -0
  86. package/dist/gui-subagent/operator/desktop-operator.js +527 -0
  87. package/dist/gui-subagent/operator/desktop-operator.js.map +1 -0
  88. package/dist/gui-subagent/operator/index.d.ts +7 -0
  89. package/dist/gui-subagent/operator/index.d.ts.map +1 -0
  90. package/dist/gui-subagent/operator/index.js +6 -0
  91. package/dist/gui-subagent/operator/index.js.map +1 -0
  92. package/dist/gui-subagent/types/actions.d.ts +108 -0
  93. package/dist/gui-subagent/types/actions.d.ts.map +1 -0
  94. package/dist/gui-subagent/types/actions.js +39 -0
  95. package/dist/gui-subagent/types/actions.js.map +1 -0
  96. package/dist/gui-subagent/types/index.d.ts +6 -0
  97. package/dist/gui-subagent/types/index.d.ts.map +1 -0
  98. package/dist/gui-subagent/types/index.js +6 -0
  99. package/dist/gui-subagent/types/index.js.map +1 -0
  100. package/dist/gui-subagent/types/operator.d.ts +95 -0
  101. package/dist/gui-subagent/types/operator.d.ts.map +1 -0
  102. package/dist/gui-subagent/types/operator.js +16 -0
  103. package/dist/gui-subagent/types/operator.js.map +1 -0
  104. package/dist/gui-subagent/utils.d.ts +19 -0
  105. package/dist/gui-subagent/utils.d.ts.map +1 -0
  106. package/dist/gui-subagent/utils.js +42 -0
  107. package/dist/gui-subagent/utils.js.map +1 -0
  108. package/dist/hook.d.ts +73 -0
  109. package/dist/hook.d.ts.map +1 -0
  110. package/dist/hook.js +156 -0
  111. package/dist/hook.js.map +1 -0
  112. package/dist/index.d.ts +19 -0
  113. package/dist/index.d.ts.map +1 -0
  114. package/dist/index.js +19 -0
  115. package/dist/index.js.map +1 -0
  116. package/dist/input-history.d.ts +24 -0
  117. package/dist/input-history.d.ts.map +1 -0
  118. package/dist/input-history.js +94 -0
  119. package/dist/input-history.js.map +1 -0
  120. package/dist/input-processor.d.ts +31 -0
  121. package/dist/input-processor.d.ts.map +1 -0
  122. package/dist/input-processor.js +233 -0
  123. package/dist/input-processor.js.map +1 -0
  124. package/dist/keyboard-manager.d.ts +151 -0
  125. package/dist/keyboard-manager.d.ts.map +1 -0
  126. package/dist/keyboard-manager.js +396 -0
  127. package/dist/keyboard-manager.js.map +1 -0
  128. package/dist/logger.d.ts +75 -0
  129. package/dist/logger.d.ts.map +1 -0
  130. package/dist/logger.js +339 -0
  131. package/dist/logger.js.map +1 -0
  132. package/dist/mcp.d.ts +57 -0
  133. package/dist/mcp.d.ts.map +1 -0
  134. package/dist/mcp.js +483 -0
  135. package/dist/mcp.js.map +1 -0
  136. package/dist/memory.d.ts +25 -0
  137. package/dist/memory.d.ts.map +1 -0
  138. package/dist/memory.js +250 -0
  139. package/dist/memory.js.map +1 -0
  140. package/dist/print-system-prompt.d.ts +2 -0
  141. package/dist/print-system-prompt.d.ts.map +1 -0
  142. package/dist/print-system-prompt.js +40 -0
  143. package/dist/print-system-prompt.js.map +1 -0
  144. package/dist/session-manager.d.ts +41 -0
  145. package/dist/session-manager.d.ts.map +1 -0
  146. package/dist/session-manager.js +234 -0
  147. package/dist/session-manager.js.map +1 -0
  148. package/dist/session.d.ts +77 -0
  149. package/dist/session.d.ts.map +1 -0
  150. package/dist/session.js +1081 -0
  151. package/dist/session.js.map +1 -0
  152. package/dist/skill-invoker.d.ts +177 -0
  153. package/dist/skill-invoker.d.ts.map +1 -0
  154. package/dist/skill-invoker.js +1643 -0
  155. package/dist/skill-invoker.js.map +1 -0
  156. package/dist/skill-loader.d.ts +76 -0
  157. package/dist/skill-loader.d.ts.map +1 -0
  158. package/dist/skill-loader.js +407 -0
  159. package/dist/skill-loader.js.map +1 -0
  160. package/dist/slash-commands.d.ts +60 -0
  161. package/dist/slash-commands.d.ts.map +1 -0
  162. package/dist/slash-commands.js +1021 -0
  163. package/dist/slash-commands.js.map +1 -0
  164. package/dist/smart-approval.d.ts +137 -0
  165. package/dist/smart-approval.d.ts.map +1 -0
  166. package/dist/smart-approval.js +512 -0
  167. package/dist/smart-approval.js.map +1 -0
  168. package/dist/system-prompt-generator.d.ts +35 -0
  169. package/dist/system-prompt-generator.d.ts.map +1 -0
  170. package/dist/system-prompt-generator.js +729 -0
  171. package/dist/system-prompt-generator.js.map +1 -0
  172. package/dist/test-boundary-conditions.d.ts.map +1 -0
  173. package/dist/test-boundary-conditions.js.map +1 -0
  174. package/dist/test-cancellation-fix.d.ts.map +1 -0
  175. package/dist/test-cancellation-fix.js.map +1 -0
  176. package/dist/test-input-history.d.ts.map +1 -0
  177. package/dist/test-input-history.js.map +1 -0
  178. package/dist/test-interaction-flow.d.ts.map +1 -0
  179. package/dist/test-interaction-flow.js.map +1 -0
  180. package/dist/test-quick.d.ts.map +1 -0
  181. package/dist/test-quick.js.map +1 -0
  182. package/dist/test-user-interaction.d.ts.map +1 -0
  183. package/dist/test-user-interaction.js.map +1 -0
  184. package/dist/theme.d.ts +353 -0
  185. package/dist/theme.d.ts.map +1 -0
  186. package/dist/theme.js +383 -0
  187. package/dist/theme.js.map +1 -0
  188. package/dist/tools.d.ts +373 -0
  189. package/dist/tools.d.ts.map +1 -0
  190. package/dist/tools.js +2906 -0
  191. package/dist/tools.js.map +1 -0
  192. package/dist/types.d.ts +180 -0
  193. package/dist/types.d.ts.map +1 -0
  194. package/dist/types.js +23 -0
  195. package/dist/types.js.map +1 -0
  196. package/dist/unified-session.d.ts +42 -0
  197. package/dist/unified-session.d.ts.map +1 -0
  198. package/dist/unified-session.js +271 -0
  199. package/dist/unified-session.js.map +1 -0
  200. package/dist/update.d.ts +30 -0
  201. package/dist/update.d.ts.map +1 -0
  202. package/dist/update.js +211 -0
  203. package/dist/update.js.map +1 -0
  204. package/dist/workflow.d.ts +53 -0
  205. package/dist/workflow.d.ts.map +1 -0
  206. package/dist/workflow.js +405 -0
  207. package/dist/workflow.js.map +1 -0
  208. package/docs/architecture/mcp-integration-guide.md +131 -0
  209. package/docs/architecture/overview.md +93 -0
  210. package/docs/architecture/tool-system-design.md +89 -0
  211. package/docs/cli/commands.md +189 -0
  212. package/docs/smart-mode.md +257 -0
  213. package/docs/third-party-models.md +449 -0
  214. package/package.json +85 -0
  215. package/scripts/init-skills-path.js +58 -0
  216. package/skills/.claude-plugin/marketplace.json +45 -0
  217. package/skills/README.md +94 -0
  218. package/skills/THIRD_PARTY_NOTICES.md +405 -0
  219. package/skills/skills/algorithmic-art/LICENSE.txt +202 -0
  220. package/skills/skills/algorithmic-art/SKILL.md +405 -0
  221. package/skills/skills/algorithmic-art/templates/generator_template.js +223 -0
  222. package/skills/skills/algorithmic-art/templates/viewer.html +599 -0
  223. package/skills/skills/brand-guidelines/LICENSE.txt +202 -0
  224. package/skills/skills/brand-guidelines/SKILL.md +73 -0
  225. package/skills/skills/canvas-design/LICENSE.txt +202 -0
  226. package/skills/skills/canvas-design/SKILL.md +130 -0
  227. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  228. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  229. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  230. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
  231. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  232. package/skills/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
  233. package/skills/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  234. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  235. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  236. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  237. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  238. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  239. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  240. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  241. package/skills/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
  242. package/skills/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  243. package/skills/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
  244. package/skills/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  245. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  246. package/skills/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
  247. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  248. package/skills/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
  249. package/skills/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  250. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  251. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  252. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  253. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  254. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  255. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  256. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  257. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  258. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  259. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  260. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  261. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  262. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  263. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  264. package/skills/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
  265. package/skills/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  266. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  267. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  268. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  269. package/skills/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  270. package/skills/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  271. package/skills/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
  272. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  273. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  274. package/skills/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  275. package/skills/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  276. package/skills/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  277. package/skills/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  278. package/skills/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  279. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  280. package/skills/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
  281. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  282. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  283. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  284. package/skills/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  285. package/skills/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  286. package/skills/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  287. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  288. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
  289. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
  290. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  291. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  292. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
  293. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  294. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
  295. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  296. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  297. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
  298. package/skills/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  299. package/skills/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  300. package/skills/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  301. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  302. package/skills/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  303. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  304. package/skills/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
  305. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  306. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  307. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  308. package/skills/skills/doc-coauthoring/SKILL.md +375 -0
  309. package/skills/skills/docx/LICENSE.txt +30 -0
  310. package/skills/skills/docx/SKILL.md +197 -0
  311. package/skills/skills/docx/docx-js.md +350 -0
  312. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  313. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  314. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  315. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  316. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  317. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  318. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  319. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  320. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  321. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  322. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  323. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  324. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  325. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  326. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  327. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  328. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  329. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  330. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  331. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  332. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  333. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  334. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  335. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  336. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  337. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  338. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  339. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  340. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  341. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  342. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  343. package/skills/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  344. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  345. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  346. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  347. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  348. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  349. package/skills/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  350. package/skills/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  351. package/skills/skills/docx/ooxml/scripts/pack.py +159 -0
  352. package/skills/skills/docx/ooxml/scripts/unpack.py +29 -0
  353. package/skills/skills/docx/ooxml/scripts/validate.py +69 -0
  354. package/skills/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  355. package/skills/skills/docx/ooxml/scripts/validation/base.py +951 -0
  356. package/skills/skills/docx/ooxml/scripts/validation/docx.py +274 -0
  357. package/skills/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  358. package/skills/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  359. package/skills/skills/docx/ooxml.md +610 -0
  360. package/skills/skills/docx/scripts/__init__.py +1 -0
  361. package/skills/skills/docx/scripts/document.py +1276 -0
  362. package/skills/skills/docx/scripts/templates/comments.xml +3 -0
  363. package/skills/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  364. package/skills/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  365. package/skills/skills/docx/scripts/templates/commentsIds.xml +3 -0
  366. package/skills/skills/docx/scripts/templates/people.xml +3 -0
  367. package/skills/skills/docx/scripts/utilities.py +374 -0
  368. package/skills/skills/frontend-design/LICENSE.txt +177 -0
  369. package/skills/skills/frontend-design/SKILL.md +42 -0
  370. package/skills/skills/internal-comms/LICENSE.txt +202 -0
  371. package/skills/skills/internal-comms/SKILL.md +32 -0
  372. package/skills/skills/internal-comms/examples/3p-updates.md +47 -0
  373. package/skills/skills/internal-comms/examples/company-newsletter.md +65 -0
  374. package/skills/skills/internal-comms/examples/faq-answers.md +30 -0
  375. package/skills/skills/internal-comms/examples/general-comms.md +16 -0
  376. package/skills/skills/mcp-builder/LICENSE.txt +202 -0
  377. package/skills/skills/mcp-builder/SKILL.md +236 -0
  378. package/skills/skills/mcp-builder/reference/evaluation.md +602 -0
  379. package/skills/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  380. package/skills/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  381. package/skills/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  382. package/skills/skills/mcp-builder/scripts/connections.py +151 -0
  383. package/skills/skills/mcp-builder/scripts/evaluation.py +373 -0
  384. package/skills/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  385. package/skills/skills/mcp-builder/scripts/requirements.txt +2 -0
  386. package/skills/skills/pdf/LICENSE.txt +30 -0
  387. package/skills/skills/pdf/SKILL.md +294 -0
  388. package/skills/skills/pdf/forms.md +205 -0
  389. package/skills/skills/pdf/reference.md +612 -0
  390. package/skills/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  391. package/skills/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  392. package/skills/skills/pdf/scripts/check_fillable_fields.py +12 -0
  393. package/skills/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  394. package/skills/skills/pdf/scripts/create_validation_image.py +41 -0
  395. package/skills/skills/pdf/scripts/extract_form_field_info.py +152 -0
  396. package/skills/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  397. package/skills/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  398. package/skills/skills/pptx/LICENSE.txt +30 -0
  399. package/skills/skills/pptx/SKILL.md +484 -0
  400. package/skills/skills/pptx/html2pptx.md +625 -0
  401. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  402. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  403. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  404. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  405. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  406. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  407. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  408. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  409. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  410. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  411. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  412. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  413. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  414. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  415. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  416. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  417. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  418. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  419. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  420. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  421. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  422. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  423. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  424. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  425. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  426. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  427. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  428. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  429. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  430. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  431. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  432. package/skills/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  433. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  434. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  435. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  436. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  437. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  438. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  439. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  440. package/skills/skills/pptx/ooxml/scripts/pack.py +159 -0
  441. package/skills/skills/pptx/ooxml/scripts/unpack.py +29 -0
  442. package/skills/skills/pptx/ooxml/scripts/validate.py +69 -0
  443. package/skills/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  444. package/skills/skills/pptx/ooxml/scripts/validation/base.py +951 -0
  445. package/skills/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  446. package/skills/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  447. package/skills/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  448. package/skills/skills/pptx/ooxml.md +427 -0
  449. package/skills/skills/pptx/scripts/html2pptx.js +979 -0
  450. package/skills/skills/pptx/scripts/inventory.py +1020 -0
  451. package/skills/skills/pptx/scripts/rearrange.py +231 -0
  452. package/skills/skills/pptx/scripts/replace.py +385 -0
  453. package/skills/skills/pptx/scripts/thumbnail.py +450 -0
  454. package/skills/skills/skill-creator/LICENSE.txt +202 -0
  455. package/skills/skills/skill-creator/SKILL.md +356 -0
  456. package/skills/skills/skill-creator/references/output-patterns.md +82 -0
  457. package/skills/skills/skill-creator/references/workflows.md +28 -0
  458. package/skills/skills/skill-creator/scripts/init_skill.py +303 -0
  459. package/skills/skills/skill-creator/scripts/package_skill.py +110 -0
  460. package/skills/skills/skill-creator/scripts/quick_validate.py +95 -0
  461. package/skills/skills/slack-gif-creator/LICENSE.txt +202 -0
  462. package/skills/skills/slack-gif-creator/SKILL.md +254 -0
  463. package/skills/skills/slack-gif-creator/core/easing.py +234 -0
  464. package/skills/skills/slack-gif-creator/core/frame_composer.py +176 -0
  465. package/skills/skills/slack-gif-creator/core/gif_builder.py +269 -0
  466. package/skills/skills/slack-gif-creator/core/validators.py +136 -0
  467. package/skills/skills/slack-gif-creator/requirements.txt +4 -0
  468. package/skills/skills/theme-factory/LICENSE.txt +202 -0
  469. package/skills/skills/theme-factory/SKILL.md +59 -0
  470. package/skills/skills/theme-factory/theme-showcase.pdf +0 -0
  471. package/skills/skills/theme-factory/themes/arctic-frost.md +19 -0
  472. package/skills/skills/theme-factory/themes/botanical-garden.md +19 -0
  473. package/skills/skills/theme-factory/themes/desert-rose.md +19 -0
  474. package/skills/skills/theme-factory/themes/forest-canopy.md +19 -0
  475. package/skills/skills/theme-factory/themes/golden-hour.md +19 -0
  476. package/skills/skills/theme-factory/themes/midnight-galaxy.md +19 -0
  477. package/skills/skills/theme-factory/themes/modern-minimalist.md +19 -0
  478. package/skills/skills/theme-factory/themes/ocean-depths.md +19 -0
  479. package/skills/skills/theme-factory/themes/sunset-boulevard.md +19 -0
  480. package/skills/skills/theme-factory/themes/tech-innovation.md +19 -0
  481. package/skills/skills/web-artifacts-builder/LICENSE.txt +202 -0
  482. package/skills/skills/web-artifacts-builder/SKILL.md +74 -0
  483. package/skills/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
  484. package/skills/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -0
  485. package/skills/skills/webapp-testing/LICENSE.txt +202 -0
  486. package/skills/skills/webapp-testing/SKILL.md +96 -0
  487. package/skills/skills/webapp-testing/examples/console_logging.py +35 -0
  488. package/skills/skills/webapp-testing/examples/element_discovery.py +40 -0
  489. package/skills/skills/webapp-testing/examples/static_html_automation.py +33 -0
  490. package/skills/skills/webapp-testing/scripts/with_server.py +106 -0
  491. package/skills/skills/xlsx/LICENSE.txt +30 -0
  492. package/skills/skills/xlsx/SKILL.md +289 -0
  493. package/skills/skills/xlsx/recalc.py +178 -0
  494. package/skills/spec/agent-skills-spec.md +3 -0
  495. package/skills/template/SKILL.md +6 -0
  496. package/src/agents.ts +504 -0
  497. package/src/ai-client.ts +1456 -0
  498. package/src/auth.ts +648 -0
  499. package/src/cancellation.ts +176 -0
  500. package/src/checkpoint.ts +219 -0
  501. package/src/cli.ts +384 -0
  502. package/src/config.ts +248 -0
  503. package/src/context-compressor.ts +290 -0
  504. package/src/conversation.ts +288 -0
  505. package/src/gui-subagent/action-parser/actionParser.ts +312 -0
  506. package/src/gui-subagent/action-parser/constants.ts +12 -0
  507. package/src/gui-subagent/action-parser/index.ts +6 -0
  508. package/src/gui-subagent/action-parser/types.ts +31 -0
  509. package/src/gui-subagent/agent/gui-agent.ts +982 -0
  510. package/src/gui-subagent/agent/index.ts +5 -0
  511. package/src/gui-subagent/index.ts +139 -0
  512. package/src/gui-subagent/operator/base-operator.ts +246 -0
  513. package/src/gui-subagent/operator/computer-operator.ts +520 -0
  514. package/src/gui-subagent/operator/index.ts +7 -0
  515. package/src/gui-subagent/types/actions.ts +263 -0
  516. package/src/gui-subagent/types/index.ts +6 -0
  517. package/src/gui-subagent/types/operator.ts +106 -0
  518. package/src/gui-subagent/utils.ts +51 -0
  519. package/src/index.ts +18 -0
  520. package/src/input-processor.ts +282 -0
  521. package/src/logger.ts +438 -0
  522. package/src/mcp.ts +563 -0
  523. package/src/memory.ts +303 -0
  524. package/src/session-manager.ts +308 -0
  525. package/src/session.ts +1280 -0
  526. package/src/skill-invoker.ts +1888 -0
  527. package/src/skill-loader.ts +476 -0
  528. package/src/slash-commands.ts +1150 -0
  529. package/src/smart-approval.ts +595 -0
  530. package/src/system-prompt-generator.ts +786 -0
  531. package/src/theme.ts +455 -0
  532. package/src/tools.ts +3398 -0
  533. package/src/types.ts +198 -0
  534. package/src/update.ts +270 -0
  535. package/src/workflow.ts +508 -0
  536. package/tsconfig.json +22 -0
  537. package/vitest.config.ts +19 -0
@@ -0,0 +1,1456 @@
1
+ import axios, { AxiosInstance } from 'axios';
2
+ import { AuthConfig } from './types.js';
3
+
4
+ // Message content block type for Anthropic format
5
+ export interface AnthropicContentBlock {
6
+ type: 'text' | 'tool_use' | 'tool_result' | 'thinking';
7
+ text?: string;
8
+ id?: string;
9
+ name?: string;
10
+ input?: any;
11
+ tool_use_id?: string;
12
+ content?: string;
13
+ thinking?: string;
14
+ }
15
+
16
+ // Markdown渲染辅助函数
17
+ function renderMarkdown(text: string): string {
18
+ // 代码块渲染
19
+ text = text.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => {
20
+ return `\n┌─[${lang || 'code'}]\n${code.trim().split('\n').map((l: string) => '│ ' + l).join('\n')}\n└─\n`;
21
+ });
22
+
23
+ // 行内代码渲染
24
+ text = text.replace(/`([^`]+)`/g, '`$1`');
25
+
26
+ // 粗体渲染
27
+ text = text.replace(/\*\*([^*]+)\*\*/g, '●$1○');
28
+
29
+ // 斜体渲染
30
+ text = text.replace(/\*([^*]+)\*/g, '/$1/');
31
+
32
+ // 列表渲染
33
+ text = text.replace(/^- (.*$)/gm, '○ $1');
34
+ text = text.replace(/^\d+\. (.*$)/gm, '• $1');
35
+
36
+ // 标题渲染
37
+ text = text.replace(/^### (.*$)/gm, '\n━━━ $1 ━━━\n');
38
+ text = text.replace(/^## (.*$)/gm, '\n━━━━━ $1 ━━━━━\n');
39
+ text = text.replace(/^# (.*$)/gm, '\n━━━━━━━ $1 ━━━━━━━\n');
40
+
41
+ // 引用渲染
42
+ text = text.replace(/^> (.*$)/gm, '│ │ $1');
43
+
44
+ // 链接渲染
45
+ text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '[$1]($2)');
46
+
47
+ return text;
48
+ }
49
+
50
+ // 格式化消息内容
51
+ function formatMessageContent(content: string | Array<any>): string {
52
+ if (typeof content === 'string') {
53
+ return renderMarkdown(content);
54
+ }
55
+
56
+ const parts: string[] = [];
57
+ let hasToolUse = false;
58
+
59
+ for (const block of content) {
60
+ if (block.type === 'text') {
61
+ parts.push(renderMarkdown(block.text || ''));
62
+ } else if (block.type === 'tool_use') {
63
+ hasToolUse = true;
64
+ parts.push(`[🔧 TOOL CALL PENDING: ${block.name}]`);
65
+ } else if (block.type === 'tool_result') {
66
+ const result = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
67
+ parts.push(`[✅ TOOL RESULT]\n${result}`);
68
+ } else if (block.type === 'thinking') {
69
+ parts.push(`[🧠 THINKING]\n${block.thinking || ''}`);
70
+ }
71
+ }
72
+
73
+ if (hasToolUse) {
74
+ parts.push('\n[⚠️ Note: Tool calls are executed by the framework, not displayed here]');
75
+ }
76
+
77
+ return parts.join('\n');
78
+ }
79
+
80
+ // 分类展示消息
81
+ function displayMessages(messages: any[], systemPrompt?: string): void {
82
+ const roleColors: Record<string, string> = {
83
+ system: '🟫 SYSTEM',
84
+ user: '👤 USER',
85
+ assistant: '🤖 ASSISTANT',
86
+ tool: '🔧 TOOL'
87
+ };
88
+
89
+ // 先显示system消息(如果有单独的systemPrompt参数)
90
+ if (systemPrompt) {
91
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
92
+ console.log('│ 🟫 SYSTEM │');
93
+ console.log('├─────────────────────────────────────────────────────────────┤');
94
+ console.log(renderMarkdown(systemPrompt).split('\n').map((l: string) => '│ ' + l).join('\n'));
95
+ console.log('└─────────────────────────────────────────────────────────────┘');
96
+ }
97
+
98
+ // 遍历所有消息
99
+ for (let i = 0; i < messages.length; i++) {
100
+ const msg = messages[i];
101
+ const role = msg.role as string;
102
+ const roleLabel = roleColors[role] || `● ${role.toUpperCase()}`;
103
+
104
+ console.log(`\n┌─────────────────────────────────────────────────────────────┐`);
105
+ console.log(`│ ${roleLabel} (${i + 1}/${messages.length}) │`);
106
+ console.log('├─────────────────────────────────────────────────────────────┤');
107
+
108
+ // 显示reasoning_content(如果有)
109
+ if ((msg as any).reasoning_content) {
110
+ console.log('│ 🧠 REASONING:');
111
+ console.log('│ ───────────────────────────────────────────────────────────');
112
+ const reasoningLines = renderMarkdown((msg as any).reasoning_content).split('\n');
113
+ for (const line of reasoningLines.slice(0, 20)) {
114
+ console.log('│ ' + line.slice(0, 62));
115
+ }
116
+ if ((msg as any).reasoning_content.length > 1000) console.log('│ ... (truncated)');
117
+ console.log('│ ───────────────────────────────────────────────────────────');
118
+ }
119
+
120
+ // 显示主要内容
121
+ const content = formatMessageContent(msg.content);
122
+ const lines = content.split('\n');
123
+
124
+ for (const line of lines.slice(0, 50)) {
125
+ console.log('│ ' + line.slice(0, 62));
126
+ }
127
+ if (lines.length > 50) {
128
+ console.log('│ ... (' + (lines.length - 50) + ' more lines)');
129
+ }
130
+
131
+ console.log('└─────────────────────────────────────────────────────────────┘');
132
+ }
133
+ }
134
+
135
+ // 格式化响应内容
136
+ function formatResponseContent(content: string | Array<any>): string {
137
+ if (typeof content === 'string') {
138
+ return renderMarkdown(content);
139
+ }
140
+
141
+ const parts: string[] = [];
142
+ let hasToolUse = false;
143
+
144
+ for (const block of content) {
145
+ if (block.type === 'text') {
146
+ parts.push(renderMarkdown(block.text || ''));
147
+ } else if (block.type === 'tool_use') {
148
+ hasToolUse = true;
149
+ // 工具调用通过 tool_calls 字段处理,不在此显示
150
+ } else if (block.type === 'tool_result') {
151
+ const result = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
152
+ parts.push(`[✅ TOOL RESULT]\n${result}`);
153
+ } else if (block.type === 'thinking') {
154
+ parts.push(`[🧠 THINKING]\n${block.thinking || ''}`);
155
+ } else if (block.type === 'image') {
156
+ parts.push('[IMAGE]');
157
+ }
158
+ }
159
+
160
+ if (hasToolUse) {
161
+ parts.push('\n[⚠️ Note: Tool calls are executed via tool_calls field, not shown here]');
162
+ }
163
+
164
+ return parts.join('\n');
165
+ }
166
+
167
+ export interface Message {
168
+ role: 'system' | 'user' | 'assistant' | 'tool';
169
+ content: string | Array<AnthropicContentBlock | { type: string; text?: string; image_url?: { url: string } }>;
170
+ reasoning_content?: string;
171
+ tool_calls?: any[];
172
+ tool_call_id?: string;
173
+ }
174
+
175
+ export interface ToolDefinition {
176
+ type: 'function';
177
+ function: {
178
+ name: string;
179
+ description: string;
180
+ parameters?: any;
181
+ };
182
+ }
183
+
184
+ export interface ChatCompletionOptions {
185
+ model?: string;
186
+ temperature?: number;
187
+ maxTokens?: number;
188
+ tools?: ToolDefinition[];
189
+ toolChoice?: 'auto' | 'none' | { type: string; function: { name: string } };
190
+ stream?: boolean;
191
+ thinkingTokens?: number;
192
+ }
193
+
194
+ export interface ChatCompletionResponse {
195
+ id: string;
196
+ object: string;
197
+ created: number;
198
+ model: string;
199
+ choices: Array<{
200
+ index: number;
201
+ message: Message;
202
+ finish_reason: string;
203
+ }>;
204
+ usage?: {
205
+ prompt_tokens: number;
206
+ completion_tokens: number;
207
+ total_tokens: number;
208
+ };
209
+ }
210
+
211
+ // 检测是否为 Anthropic 兼容 API(使用 x-api-key 认证头)
212
+ function isAnthropicCompatible(baseUrl: string): boolean {
213
+ return baseUrl.includes('anthropic') ||
214
+ baseUrl.includes('minimaxi.com') ||
215
+ baseUrl.includes('minimax.chat');
216
+ }
217
+
218
+ // MiniMax API 路径检测
219
+ function detectMiniMaxAPI(baseUrl: string): boolean {
220
+ return baseUrl.includes('minimax.chat') ||
221
+ baseUrl.includes('minimaxi.com');
222
+ }
223
+
224
+ // 获取 MiniMax 的正确端点路径
225
+ function getMiniMaxEndpoint(baseUrl: string): { endpoint: string; format: 'anthropic' | 'openai' } {
226
+ // MiniMax Anthropic 格式: https://api.minimax.chat/anthropic + /v1/messages
227
+ if (baseUrl.includes('/anthropic')) {
228
+ return { endpoint: '/v1/messages', format: 'anthropic' };
229
+ }
230
+ // MiniMax OpenAI 格式: https://api.minimaxi.com/v1 + /chat/completions
231
+ if (baseUrl.includes('/v1') && !baseUrl.includes('/anthropic')) {
232
+ return { endpoint: '/chat/completions', format: 'openai' };
233
+ }
234
+ // 默认使用 Anthropic 格式
235
+ return { endpoint: '/v1/messages', format: 'anthropic' };
236
+ }
237
+
238
+ export class AIClient {
239
+ private client: AxiosInstance;
240
+ private authConfig: AuthConfig;
241
+
242
+ constructor(authConfig: AuthConfig) {
243
+ this.authConfig = authConfig;
244
+ const isMiniMax = detectMiniMaxAPI(authConfig.baseUrl || '');
245
+ const isAnthropicOfficial = !isMiniMax && isAnthropicCompatible(authConfig.baseUrl || '');
246
+
247
+ const headers: Record<string, string> = {
248
+ 'Content-Type': 'application/json'
249
+ };
250
+
251
+ if (isMiniMax) {
252
+ // MiniMax: 使用 x-api-key 认证头
253
+ headers['x-api-key'] = authConfig.apiKey || '';
254
+ headers['anthropic-version'] = '2023-06-01';
255
+ } else if (isAnthropicOfficial) {
256
+ // Anthropic 官方: 使用 x-api-key 认证头
257
+ headers['x-api-key'] = authConfig.apiKey || '';
258
+ headers['anthropic-version'] = '2023-06-01';
259
+ headers['anthropic-dangerous-direct-browser-access'] = 'true';
260
+ } else {
261
+ // 其他 OpenAI 兼容: 使用 Bearer token
262
+ headers['Authorization'] = `Bearer ${authConfig.apiKey}`;
263
+ }
264
+
265
+ this.client = axios.create({
266
+ baseURL: authConfig.baseUrl,
267
+ headers,
268
+ timeout: 240000
269
+ });
270
+ }
271
+
272
+ // 将 OpenAI 格式消息转换为 Anthropic 格式
273
+ private convertToAnthropicFormat(
274
+ messages: Message[],
275
+ systemPrompt?: string
276
+ ): { system: string; messages: Array<{ role: string; content: AnthropicContentBlock[] }> } {
277
+ const systemMessages = messages.filter(m => m.role === 'system');
278
+ const otherMessages = messages.filter(m => m.role !== 'system');
279
+
280
+ const systemContent = systemMessages[0]?.content;
281
+ const system = systemPrompt || (typeof systemContent === 'string' ? systemContent : '');
282
+
283
+ const anthropicMessages: Array<{ role: string; content: AnthropicContentBlock[] }> = [];
284
+
285
+ for (const msg of otherMessages) {
286
+ const blocks: AnthropicContentBlock[] = [];
287
+
288
+ if (typeof msg.content === 'string') {
289
+ blocks.push({ type: 'text', text: msg.content });
290
+ } else if (Array.isArray(msg.content)) {
291
+ for (const block of msg.content) {
292
+ if (block.type === 'text' && 'text' in block) {
293
+ blocks.push({ type: 'text', text: (block as any).text });
294
+ } else if (block.type === 'tool_use') {
295
+ blocks.push({
296
+ type: 'tool_use',
297
+ id: (block as any).id,
298
+ name: (block as any).function?.name || (block as any).name,
299
+ input: (block as any).function?.arguments || (block as any).input
300
+ });
301
+ } else if (block.type === 'tool_result') {
302
+ blocks.push({
303
+ type: 'tool_result',
304
+ tool_use_id: (block as any).tool_call_id || (block as any).tool_use_id,
305
+ content: typeof (block as any).content === 'string'
306
+ ? (block as any).content
307
+ : JSON.stringify((block as any).content)
308
+ });
309
+ } else if (block.type === 'thinking') {
310
+ blocks.push({ type: 'thinking', thinking: (block as any).thinking });
311
+ }
312
+ }
313
+ }
314
+
315
+ // 处理 tool_calls (OpenAI 格式)
316
+ if (msg.tool_calls) {
317
+ for (const tc of msg.tool_calls) {
318
+ blocks.push({
319
+ type: 'tool_use',
320
+ id: tc.id,
321
+ name: tc.function?.name,
322
+ input: tc.function?.arguments ? (typeof tc.function.arguments === 'string' ? JSON.parse(tc.function.arguments) : tc.function.arguments) : {}
323
+ });
324
+ }
325
+ }
326
+
327
+ if (blocks.length > 0) {
328
+ anthropicMessages.push({
329
+ role: msg.role === 'tool' ? 'user' : msg.role,
330
+ content: blocks as AnthropicContentBlock[]
331
+ });
332
+ }
333
+ }
334
+
335
+ return { system, messages: anthropicMessages };
336
+ }
337
+
338
+ async chatCompletion(
339
+ messages: Message[],
340
+ options: ChatCompletionOptions = {}
341
+ ): Promise<ChatCompletionResponse> {
342
+ const model = options.model || this.authConfig.modelName || 'gpt-4';
343
+ const isMiniMax = detectMiniMaxAPI(this.authConfig.baseUrl || '');
344
+
345
+ if (isMiniMax) {
346
+ return this.minimaxChatCompletion(messages, options);
347
+ }
348
+
349
+ const isAnthropic = isAnthropicCompatible(this.authConfig.baseUrl || '');
350
+ if (isAnthropic) {
351
+ return this.anthropicNativeChatCompletion(messages, options);
352
+ }
353
+
354
+ // OpenAI 格式请求
355
+ const requestBody: any = {
356
+ model,
357
+ messages,
358
+ temperature: options.temperature ?? 0.7,
359
+ stream: options.stream ?? false
360
+ };
361
+
362
+ if (options.maxTokens && options.maxTokens > 0) {
363
+ requestBody.max_tokens = options.maxTokens;
364
+ }
365
+
366
+ if (options.tools && options.tools.length > 0) {
367
+ requestBody.tools = options.tools;
368
+ requestBody.tool_choice = options.toolChoice || 'auto';
369
+ }
370
+
371
+ if (options.thinkingTokens && options.thinkingTokens > 0) {
372
+ requestBody.max_completion_tokens = options.thinkingTokens;
373
+ }
374
+
375
+ // 调试输出(受showAIDebugInfo配置控制)
376
+ const showDebug = this.authConfig.showAIDebugInfo ?? false;
377
+
378
+ if (showDebug) {
379
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
380
+ console.log('║ AI REQUEST DEBUG ║');
381
+ console.log('╚══════════════════════════════════════════════════════════╝');
382
+ console.log(`📦 Model: ${model}`);
383
+ console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
384
+ console.log(`💬 Total Messages: ${messages.length} 条`);
385
+ if (options.temperature !== undefined) console.log(`🌡️ Temperature: ${options.temperature}`);
386
+ if (options.maxTokens) console.log(`📏 Max Tokens: ${options.maxTokens}`);
387
+ if (options.tools?.length) console.log(`🔧 Tools: ${options.tools.length} 个`);
388
+ if (options.thinkingTokens) console.log(`🧠 Thinking Tokens: ${options.thinkingTokens}`);
389
+ console.log('─'.repeat(60));
390
+
391
+ // 分离system消息
392
+ const systemMsgs = messages.filter(m => m.role === 'system');
393
+ const otherMsgs = messages.filter(m => m.role !== 'system');
394
+
395
+ if (systemMsgs.length > 0) {
396
+ const systemContent = typeof systemMsgs[0].content === 'string'
397
+ ? systemMsgs[0].content
398
+ : formatMessageContent(systemMsgs[0].content);
399
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
400
+ console.log('│ 🟫 SYSTEM │');
401
+ console.log('├─────────────────────────────────────────────────────────────┤');
402
+ console.log(renderMarkdown(systemContent).split('\n').map(l => '│ ' + l).join('\n'));
403
+ console.log('└─────────────────────────────────────────────────────────────┘');
404
+ }
405
+
406
+ displayMessages(otherMsgs);
407
+
408
+ console.log('\n📤 Sending request to API...\n');
409
+ }
410
+
411
+ try {
412
+ const response = await this.client.post('/chat/completions', requestBody);
413
+
414
+ if (showDebug) {
415
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
416
+ console.log('║ AI RESPONSE DEBUG ║');
417
+ console.log('╚══════════════════════════════════════════════════════════╝');
418
+ console.log(`🆔 ID: ${response.data.id}`);
419
+ console.log(`🤖 Model: ${response.data.model}`);
420
+ const usage = response.data.usage;
421
+ if (usage) {
422
+ console.log(`📊 Tokens: ${usage.prompt_tokens} (prompt) + ${usage.completion_tokens} (completion) = ${usage.total_tokens} (total)`);
423
+ }
424
+ const choice = response.data.choices?.[0];
425
+ if (choice) {
426
+ console.log(`🏁 Finish Reason: ${choice.finish_reason}`);
427
+
428
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
429
+ console.log('│ 🤖 ASSISTANT │');
430
+ console.log('├─────────────────────────────────────────────────────────────┤');
431
+
432
+ // 显示reasoning_content(如果有)
433
+ if (choice.message.reasoning_content) {
434
+ console.log('│ 🧠 REASONING:');
435
+ console.log('│ ───────────────────────────────────────────────────────────');
436
+ const reasoningLines = renderMarkdown(choice.message.reasoning_content).split('\n');
437
+ for (const line of reasoningLines.slice(0, 15)) {
438
+ console.log('│ ' + line.slice(0, 62));
439
+ }
440
+ if (choice.message.reasoning_content.length > 800) console.log('│ ... (truncated)');
441
+ console.log('│ ───────────────────────────────────────────────────────────');
442
+ }
443
+
444
+ // 显示主要内容
445
+ const content = formatResponseContent(choice.message.content);
446
+ const lines = content.split('\n');
447
+ console.log('│ 💬 CONTENT:');
448
+ console.log('│ ───────────────────────────────────────────────────────────');
449
+ for (const line of lines.slice(0, 40)) {
450
+ console.log('│ ' + line.slice(0, 62));
451
+ }
452
+ if (lines.length > 40) {
453
+ console.log(`│ ... (${lines.length - 40} more lines)`);
454
+ }
455
+ console.log('└─────────────────────────────────────────────────────────────┘');
456
+ }
457
+ console.log('╔══════════════════════════════════════════════════════════╗');
458
+ console.log('║ RESPONSE ENDED ║');
459
+ console.log('╚══════════════════════════════════════════════════════════╝\n');
460
+ }
461
+
462
+ return response.data;
463
+ } catch (error: any) {
464
+ if (error.response) {
465
+ throw new Error(
466
+ `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`
467
+ );
468
+ } else if (error.request) {
469
+ throw new Error('Network error: No response received from server');
470
+ } else {
471
+ throw new Error(`Request error: ${error.message}`);
472
+ }
473
+ }
474
+ }
475
+
476
+ // Anthropic 官方原生 API(使用 /v1/messages 端点)
477
+ private async anthropicNativeChatCompletion(
478
+ messages: Message[],
479
+ options: ChatCompletionOptions = {}
480
+ ): Promise<ChatCompletionResponse> {
481
+ const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
482
+
483
+ const requestBody: any = {
484
+ model: options.model || this.authConfig.modelName || 'claude-sonnet-4-20250514',
485
+ messages: anthropicMessages,
486
+ temperature: options.temperature ?? 1.0,
487
+ stream: false,
488
+ max_tokens: options.maxTokens || 4096
489
+ };
490
+
491
+ if (system) {
492
+ requestBody.system = system;
493
+ }
494
+
495
+ // Anthropic 原生工具格式
496
+ if (options.tools && options.tools.length > 0) {
497
+ requestBody.tools = options.tools.map(tool => ({
498
+ name: tool.function.name,
499
+ description: tool.function.description,
500
+ input_schema: tool.function.parameters || { type: 'object', properties: {} }
501
+ }));
502
+
503
+ // 转换 tool_choice 从 OpenAI 格式到 Anthropic 格式
504
+ const toolChoice = options.toolChoice;
505
+ if (toolChoice === 'none') {
506
+ requestBody.tool_choice = { type: 'auto' };
507
+ } else if (toolChoice && typeof toolChoice === 'object') {
508
+ if (toolChoice.type === 'function' && toolChoice.function) {
509
+ requestBody.tool_choice = { type: 'tool', tool: { name: toolChoice.function.name } };
510
+ } else {
511
+ requestBody.tool_choice = { type: 'auto' };
512
+ }
513
+ } else {
514
+ requestBody.tool_choice = { type: 'auto' };
515
+ }
516
+ }
517
+
518
+ // Anthropic thinking 模式
519
+ if (options.thinkingTokens && options.thinkingTokens > 0) {
520
+ requestBody.thinking = { type: 'enabled', budget_tokens: options.thinkingTokens };
521
+ }
522
+
523
+ // 调试输出(受showAIDebugInfo配置控制)
524
+ const showDebug = this.authConfig.showAIDebugInfo ?? false;
525
+
526
+ if (showDebug) {
527
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
528
+ console.log('║ AI REQUEST DEBUG (ANTHROPIC) ║');
529
+ console.log('╚══════════════════════════════════════════════════════════╝');
530
+ console.log(`📦 Model: ${requestBody.model}`);
531
+ console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
532
+ console.log(`💬 Total Messages: ${anthropicMessages.length} 条`);
533
+ if (requestBody.temperature) console.log(`🌡️ Temperature: ${requestBody.temperature}`);
534
+ if (requestBody.max_tokens) console.log(`📏 Max Tokens: ${requestBody.max_tokens}`);
535
+ if (requestBody.tools) console.log(`🔧 Tools: ${requestBody.tools.length} 个`);
536
+ if (requestBody.thinking) console.log(`🧠 Thinking Budget: ${requestBody.thinking.budget_tokens}`);
537
+ console.log('─'.repeat(60));
538
+
539
+ // 显示system消息
540
+ if (system) {
541
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
542
+ console.log('│ 🟫 SYSTEM │');
543
+ console.log('├─────────────────────────────────────────────────────────────┤');
544
+ console.log(renderMarkdown(system).split('\n').map(l => '│ ' + l).join('\n'));
545
+ console.log('└─────────────────────────────────────────────────────────────┘');
546
+ }
547
+
548
+ // 显示用户和助手消息
549
+ displayMessages(anthropicMessages);
550
+
551
+ console.log('\n📤 Sending to Anthropic API (v1/messages)...\n');
552
+ }
553
+
554
+ try {
555
+ // 使用 Anthropic 原生端点 /v1/messages
556
+ const response = await this.client.post('/v1/messages', requestBody);
557
+
558
+ if (showDebug) {
559
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
560
+ console.log('║ AI RESPONSE DEBUG (ANTHROPIC) ║');
561
+ console.log('╚══════════════════════════════════════════════════════════╝');
562
+ console.log(`🆔 ID: ${response.data.id}`);
563
+ console.log(`🤖 Model: ${response.data.model}`);
564
+ const usage = response.data.usage;
565
+ if (usage) {
566
+ console.log(`📊 Tokens: ${usage.input_tokens} (input) + ${usage.output_tokens} (output) = ${usage.input_tokens + usage.output_tokens} (total)`);
567
+ }
568
+ console.log(`🏁 Stop Reason: ${response.data.stop_reason}`);
569
+
570
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
571
+ console.log('│ 🤖 ASSISTANT │');
572
+ console.log('├─────────────────────────────────────────────────────────────┤');
573
+
574
+ const content = response.data.content || [];
575
+ const reasoning = content.filter((c: any) => c.type === 'thinking').map((c: any) => c.thinking).join('');
576
+ const textContent = content.filter((c: any) => c.type === 'text').map((c: any) => c.text).join('');
577
+
578
+ // 显示thinking
579
+ if (reasoning) {
580
+ console.log('│ 🧠 REASONING:');
581
+ console.log('│ ───────────────────────────────────────────────────────────');
582
+ const reasoningLines = renderMarkdown(reasoning).split('\n');
583
+ for (const line of reasoningLines.slice(0, 15)) {
584
+ console.log('│ ' + line.slice(0, 62));
585
+ }
586
+ if (reasoning.length > 800) console.log('│ ... (truncated)');
587
+ console.log('│ ───────────────────────────────────────────────────────────');
588
+ }
589
+
590
+ // 显示内容
591
+ console.log('│ 💬 CONTENT:');
592
+ console.log('│ ───────────────────────────────────────────────────────────');
593
+ const lines = renderMarkdown(textContent).split('\n');
594
+ for (const line of lines.slice(0, 40)) {
595
+ console.log('│ ' + line.slice(0, 62));
596
+ }
597
+ if (lines.length > 40) {
598
+ console.log(`│ ... (${lines.length - 40} more lines)`);
599
+ }
600
+ console.log('└─────────────────────────────────────────────────────────────┘');
601
+
602
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
603
+ console.log('║ RESPONSE ENDED ║');
604
+ console.log('╚══════════════════════════════════════════════════════════╝\n');
605
+ }
606
+
607
+ return this.convertFromAnthropicNativeResponse(response.data);
608
+ } catch (error: any) {
609
+ if (error.response) {
610
+ throw new Error(
611
+ `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`
612
+ );
613
+ } else if (error.request) {
614
+ throw new Error('Network error: No response received from server');
615
+ } else {
616
+ throw new Error(`Request error: ${error.message}`);
617
+ }
618
+ }
619
+ }
620
+
621
+ // MiniMax API(根据 baseUrl 自动选择 Anthropic 或 OpenAI 格式)
622
+ private async minimaxChatCompletion(
623
+ messages: Message[],
624
+ options: ChatCompletionOptions = {}
625
+ ): Promise<ChatCompletionResponse> {
626
+ const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
627
+ const { endpoint, format } = getMiniMaxEndpoint(this.authConfig.baseUrl || '');
628
+
629
+ const requestBody: any = {
630
+ model: options.model || this.authConfig.modelName || 'MiniMax-M2',
631
+ messages: format === 'anthropic' ? anthropicMessages : messages,
632
+ temperature: options.temperature ?? 1.0,
633
+ stream: false,
634
+ max_tokens: options.maxTokens || 4096
635
+ };
636
+
637
+ if (system && format === 'anthropic') {
638
+ requestBody.system = system;
639
+ }
640
+
641
+ if (format === 'anthropic') {
642
+ // Anthropic format tools
643
+ if (options.tools && options.tools.length > 0) {
644
+ requestBody.tools = options.tools.map(tool => ({
645
+ name: tool.function.name,
646
+ description: tool.function.description,
647
+ input_schema: tool.function.parameters || { type: 'object', properties: {} }
648
+ }));
649
+
650
+ const toolChoice = options.toolChoice;
651
+ if (toolChoice === 'none') {
652
+ requestBody.tool_choice = { type: 'auto' };
653
+ } else if (toolChoice && typeof toolChoice === 'object') {
654
+ if (toolChoice.type === 'function' && toolChoice.function) {
655
+ requestBody.tool_choice = { type: 'tool', tool: { name: toolChoice.function.name } };
656
+ } else {
657
+ requestBody.tool_choice = { type: 'auto' };
658
+ }
659
+ } else {
660
+ requestBody.tool_choice = { type: 'auto' };
661
+ }
662
+ }
663
+ } else {
664
+ // OpenAI 格式的工具
665
+ if (options.tools && options.tools.length > 0) {
666
+ requestBody.tools = options.tools;
667
+ requestBody.tool_choice = options.toolChoice || 'auto';
668
+ }
669
+ }
670
+
671
+ // 调试输出(受showAIDebugInfo配置控制)
672
+ const showDebug = this.authConfig.showAIDebugInfo ?? false;
673
+
674
+ if (showDebug) {
675
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
676
+ console.log('║ AI REQUEST DEBUG (MINIMAX) ║');
677
+ console.log('╚══════════════════════════════════════════════════════════╝');
678
+ console.log(`📦 Model: ${requestBody.model}`);
679
+ console.log(`🔗 Format: ${format.toUpperCase()} | Endpoint: ${endpoint}`);
680
+ console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
681
+ console.log(`💬 Total Messages: ${requestBody.messages.length} 条`);
682
+ if (requestBody.temperature) console.log(`🌡️ Temperature: ${requestBody.temperature}`);
683
+ if (requestBody.max_tokens) console.log(`📏 Max Tokens: ${requestBody.max_tokens}`);
684
+ if (requestBody.tools) console.log(`🔧 Tools: ${requestBody.tools.length} 个`);
685
+ console.log('─'.repeat(60));
686
+
687
+ // 显示system消息
688
+ if (system && format === 'anthropic') {
689
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
690
+ console.log('│ 🟫 SYSTEM │');
691
+ console.log('├─────────────────────────────────────────────────────────────┤');
692
+ console.log(renderMarkdown(system).split('\n').map(l => '│ ' + l).join('\n'));
693
+ console.log('└─────────────────────────────────────────────────────────────┘');
694
+ }
695
+
696
+ // 显示其他消息
697
+ displayMessages(requestBody.messages);
698
+
699
+ console.log('\n📤 Sending to MiniMax API...\n');
700
+ }
701
+
702
+ try {
703
+ // MiniMax 使用正确的端点
704
+ const response = await this.client.post(endpoint, requestBody);
705
+
706
+ if (showDebug) {
707
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
708
+ console.log('║ AI RESPONSE DEBUG (MINIMAX) ║');
709
+ console.log('╚══════════════════════════════════════════════════════════╝');
710
+ console.log(`🆔 ID: ${response.data.id}`);
711
+ console.log(`🤖 Model: ${response.data.model}`);
712
+ const usage = response.data.usage;
713
+ if (usage) {
714
+ console.log(`📊 Tokens: ${usage.prompt_tokens} (prompt) + ${usage.completion_tokens} (completion) = ${usage.total_tokens} (total)`);
715
+ }
716
+ console.log(`🏁 Stop Reason: ${response.data.stop_reason}`);
717
+
718
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
719
+ console.log('│ 🤖 ASSISTANT │');
720
+ console.log('├─────────────────────────────────────────────────────────────┤');
721
+
722
+ const message = response.data.choices?.[0]?.message;
723
+ const content = typeof message?.content === 'string' ? message.content : JSON.stringify(message?.content);
724
+
725
+ console.log('│ 💬 CONTENT:');
726
+ console.log('│ ───────────────────────────────────────────────────────────');
727
+ const lines = renderMarkdown(content).split('\n');
728
+ for (const line of lines.slice(0, 40)) {
729
+ console.log('│ ' + line.slice(0, 62));
730
+ }
731
+ if (lines.length > 40) {
732
+ console.log(`│ ... (${lines.length - 40} more lines)`);
733
+ }
734
+ console.log('└─────────────────────────────────────────────────────────────┘');
735
+
736
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
737
+ console.log('║ RESPONSE ENDED ║');
738
+ console.log('╚══════════════════════════════════════════════════════════╝\n');
739
+ }
740
+
741
+ if (format === 'anthropic') {
742
+ return this.convertFromAnthropicNativeResponse(response.data);
743
+ } else {
744
+ return this.convertFromMiniMaxResponse(response.data);
745
+ }
746
+ } catch (error: any) {
747
+ if (error.response) {
748
+ throw new Error(
749
+ `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`
750
+ );
751
+ } else if (error.request) {
752
+ throw new Error('Network error: No response received from server');
753
+ } else {
754
+ throw new Error(`Request error: ${error.message}`);
755
+ }
756
+ }
757
+ }
758
+
759
+ // 将 Anthropic 原生响应转换为统一格式
760
+ private convertFromAnthropicNativeResponse(anthropicResponse: any): ChatCompletionResponse {
761
+ const content = anthropicResponse.content || [];
762
+ let textContent = '';
763
+ let reasoningContent = '';
764
+ const toolCalls: any[] = [];
765
+
766
+ for (const block of content) {
767
+ if (block.type === 'text') {
768
+ textContent += block.text || '';
769
+ } else if (block.type === 'thinking') {
770
+ reasoningContent += block.thinking || '';
771
+ } else if (block.type === 'tool_use') {
772
+ toolCalls.push({
773
+ id: block.id,
774
+ type: 'function',
775
+ function: {
776
+ name: block.name,
777
+ arguments: JSON.stringify(block.input || {})
778
+ }
779
+ });
780
+ }
781
+ }
782
+
783
+ return {
784
+ id: anthropicResponse.id || `anthropic-${Date.now()}`,
785
+ object: 'chat.completion',
786
+ created: Math.floor(Date.now() / 1000),
787
+ model: anthropicResponse.model || this.authConfig.modelName || 'claude-sonnet-4-20250514',
788
+ choices: [{
789
+ index: 0,
790
+ message: {
791
+ role: 'assistant',
792
+ content: textContent,
793
+ reasoning_content: reasoningContent || undefined,
794
+ tool_calls: toolCalls.length > 0 ? toolCalls : undefined
795
+ },
796
+ finish_reason: anthropicResponse.stop_reason === 'end_turn' ? 'stop' :
797
+ anthropicResponse.stop_reason === 'max_tokens' ? 'length' : 'stop'
798
+ }],
799
+ usage: anthropicResponse.usage ? {
800
+ prompt_tokens: anthropicResponse.usage.input_tokens || 0,
801
+ completion_tokens: anthropicResponse.usage.output_tokens || 0,
802
+ total_tokens: (anthropicResponse.usage.input_tokens || 0) + (anthropicResponse.usage.output_tokens || 0)
803
+ } : undefined
804
+ };
805
+ }
806
+
807
+ // 将 MiniMax 响应转换为统一格式
808
+ private convertFromMiniMaxResponse(minimaxResponse: any): ChatCompletionResponse {
809
+ const message = minimaxResponse.choices?.[0]?.message;
810
+ const content = message?.content;
811
+ let textContent = '';
812
+ let reasoningContent = '';
813
+ const toolCalls: any[] = [];
814
+
815
+ if (typeof content === 'string') {
816
+ textContent = content.trim();
817
+ } else if (Array.isArray(content)) {
818
+ for (const block of content) {
819
+ if (block.type === 'text') {
820
+ textContent += block.text || '';
821
+ } else if (block.type === 'thinking') {
822
+ reasoningContent += block.thinking || '';
823
+ } else if (block.type === 'tool_use') {
824
+ toolCalls.push({
825
+ id: block.id,
826
+ type: 'function',
827
+ function: {
828
+ name: block.name,
829
+ arguments: JSON.stringify(block.input || {})
830
+ }
831
+ });
832
+ }
833
+ }
834
+ }
835
+
836
+ return {
837
+ id: minimaxResponse.id || `minimax-${Date.now()}`,
838
+ object: 'chat.completion',
839
+ created: Math.floor(Date.now() / 1000),
840
+ model: minimaxResponse.model || this.authConfig.modelName || 'MiniMax-M2',
841
+ choices: [{
842
+ index: 0,
843
+ message: {
844
+ role: 'assistant',
845
+ content: textContent,
846
+ reasoning_content: reasoningContent || undefined,
847
+ tool_calls: toolCalls.length > 0 ? toolCalls : undefined
848
+ },
849
+ finish_reason: minimaxResponse.stop_reason === 'end_turn' ? 'stop' :
850
+ minimaxResponse.stop_reason === 'max_tokens' ? 'length' : 'stop'
851
+ }],
852
+ usage: minimaxResponse.usage
853
+ };
854
+ }
855
+
856
+ async *streamChatCompletion(
857
+ messages: Message[],
858
+ options: ChatCompletionOptions = {}
859
+ ): AsyncGenerator<string, void, unknown> {
860
+ const isMiniMax = detectMiniMaxAPI(this.authConfig.baseUrl || '');
861
+
862
+ if (isMiniMax) {
863
+ yield* this.minimaxStreamChatCompletion(messages, options);
864
+ return;
865
+ }
866
+
867
+ const isAnthropic = isAnthropicCompatible(this.authConfig.baseUrl || '');
868
+ if (isAnthropic) {
869
+ yield* this.anthropicNativeStreamChatCompletion(messages, options);
870
+ return;
871
+ }
872
+
873
+ // OpenAI 流式响应
874
+ const model = options.model || this.authConfig.modelName || 'gpt-4';
875
+
876
+ const requestBody: any = {
877
+ model,
878
+ messages,
879
+ temperature: options.temperature ?? 0.7,
880
+ stream: true
881
+ };
882
+
883
+ if (options.maxTokens && options.maxTokens > 0) {
884
+ requestBody.max_tokens = options.maxTokens;
885
+ }
886
+
887
+ if (options.tools && options.tools.length > 0) {
888
+ requestBody.tools = options.tools;
889
+ requestBody.tool_choice = options.toolChoice || 'auto';
890
+ }
891
+
892
+ if (options.thinkingTokens && options.thinkingTokens > 0) {
893
+ requestBody.max_completion_tokens = options.thinkingTokens;
894
+ }
895
+
896
+ // 调试输出(受showAIDebugInfo配置控制)
897
+ const showDebug = this.authConfig.showAIDebugInfo ?? false;
898
+
899
+ if (showDebug) {
900
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
901
+ console.log('║ AI REQUEST DEBUG (STREAM) ║');
902
+ console.log('╚══════════════════════════════════════════════════════════╝');
903
+ console.log(`📦 Model: ${model}`);
904
+ console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
905
+ console.log(`💬 Total Messages: ${messages.length} 条`);
906
+ if (options.temperature) console.log(`🌡️ Temperature: ${options.temperature}`);
907
+ if (options.maxTokens) console.log(`📏 Max Tokens: ${options.maxTokens}`);
908
+ if (options.tools?.length) console.log(`🔧 Tools: ${options.tools.length} 个`);
909
+ console.log('─'.repeat(60));
910
+
911
+ // 分离并显示消息
912
+ const systemMsgs = messages.filter(m => m.role === 'system');
913
+ const otherMsgs = messages.filter(m => m.role !== 'system');
914
+
915
+ if (systemMsgs.length > 0) {
916
+ const systemContent = typeof systemMsgs[0].content === 'string'
917
+ ? systemMsgs[0].content
918
+ : formatMessageContent(systemMsgs[0].content);
919
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
920
+ console.log('│ 🟫 SYSTEM │');
921
+ console.log('├─────────────────────────────────────────────────────────────┤');
922
+ console.log(renderMarkdown(systemContent).split('\n').map(l => '│ ' + l).join('\n'));
923
+ console.log('└─────────────────────────────────────────────────────────────┘');
924
+ }
925
+
926
+ displayMessages(otherMsgs);
927
+
928
+ console.log('\n📤 Starting stream...\n');
929
+ }
930
+
931
+ try {
932
+ const response = await this.client.post('/chat/completions', requestBody, {
933
+ responseType: 'stream'
934
+ });
935
+
936
+ console.log('📥 Receiving stream chunks...\n');
937
+
938
+ let buffer = '';
939
+ let chunkCount = 0;
940
+ let outputBuffer = '';
941
+
942
+ for await (const chunk of response.data) {
943
+ buffer += chunk.toString();
944
+ const lines = buffer.split('\n');
945
+
946
+ buffer = lines.pop() || '';
947
+
948
+ for (const line of lines) {
949
+ const trimmedLine = line.trim();
950
+ if (!trimmedLine) continue;
951
+
952
+ if (trimmedLine.startsWith('data: ')) {
953
+ const data = trimmedLine.slice(6);
954
+ if (data === '[DONE]') {
955
+ if (showDebug) {
956
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
957
+ console.log('║ STREAM COMPLETED ║');
958
+ console.log('╚══════════════════════════════════════════════════════════╝');
959
+ console.log(`📦 Total chunks: ${chunkCount}`);
960
+ console.log(`📏 Total output: ${outputBuffer.length} chars`);
961
+
962
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
963
+ console.log('│ 🤖 ASSISTANT OUTPUT │');
964
+ console.log('├─────────────────────────────────────────────────────────────┤');
965
+ console.log('│ 💬 CONTENT:');
966
+ console.log('│ ───────────────────────────────────────────────────────────');
967
+ const lines = renderMarkdown(outputBuffer).split('\n');
968
+ for (const line of lines.slice(0, 30)) {
969
+ console.log('│ ' + line.slice(0, 62));
970
+ }
971
+ if (lines.length > 30) {
972
+ console.log(`│ ... (${lines.length - 30} more lines)`);
973
+ }
974
+ console.log('└─────────────────────────────────────────────────────────────┘');
975
+ console.log('');
976
+ }
977
+ return;
978
+ }
979
+
980
+ try {
981
+ const parsed = JSON.parse(data);
982
+ const delta = parsed.choices?.[0]?.delta;
983
+ if (delta?.content) {
984
+ chunkCount++;
985
+ outputBuffer += delta.content;
986
+ yield delta.content;
987
+ } else if (delta?.reasoning_content) {
988
+ chunkCount++;
989
+ outputBuffer += delta.reasoning_content;
990
+ yield delta.reasoning_content;
991
+ }
992
+ } catch (e) {
993
+ // Silently ignore parsing errors
994
+ }
995
+ }
996
+ }
997
+ }
998
+
999
+ if (buffer.trim()) {
1000
+ const trimmedLine = buffer.trim();
1001
+ if (trimmedLine.startsWith('data: ')) {
1002
+ const data = trimmedLine.slice(6);
1003
+ if (data !== '[DONE]') {
1004
+ try {
1005
+ const parsed = JSON.parse(data);
1006
+ const delta = parsed.choices?.[0]?.delta;
1007
+ if (delta?.content) {
1008
+ yield delta.content;
1009
+ } else if (delta?.reasoning_content) {
1010
+ yield delta.reasoning_content;
1011
+ }
1012
+ } catch (e) {
1013
+ // Ignore final parsing errors
1014
+ }
1015
+ }
1016
+ }
1017
+ }
1018
+
1019
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
1020
+ console.log('║ STREAM COMPLETED ║');
1021
+ console.log('╚══════════════════════════════════════════════════════════╝\n');
1022
+ } catch (error: any) {
1023
+ if (error.response) {
1024
+ throw new Error(
1025
+ `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`
1026
+ );
1027
+ } else if (error.request) {
1028
+ throw new Error('Network error: No response received from server');
1029
+ } else {
1030
+ throw new Error(`Request error: ${error.message}`);
1031
+ }
1032
+ }
1033
+ }
1034
+
1035
+ // Anthropic 原生流式响应(/v1/messages 端点)
1036
+ private async *anthropicNativeStreamChatCompletion(
1037
+ messages: Message[],
1038
+ options: ChatCompletionOptions = {}
1039
+ ): AsyncGenerator<string, void, unknown> {
1040
+ const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
1041
+
1042
+ const requestBody: any = {
1043
+ model: options.model || this.authConfig.modelName || 'claude-sonnet-4-20250514',
1044
+ messages: anthropicMessages,
1045
+ temperature: options.temperature ?? 1.0,
1046
+ stream: true,
1047
+ max_tokens: options.maxTokens || 4096
1048
+ };
1049
+
1050
+ if (system) {
1051
+ requestBody.system = system;
1052
+ }
1053
+
1054
+ // Anthropic 原生工具格式
1055
+ if (options.tools && options.tools.length > 0) {
1056
+ requestBody.tools = options.tools.map(tool => ({
1057
+ name: tool.function.name,
1058
+ description: tool.function.description,
1059
+ input_schema: tool.function.parameters || { type: 'object', properties: {} }
1060
+ }));
1061
+
1062
+ const toolChoice = options.toolChoice;
1063
+ if (toolChoice === 'none') {
1064
+ requestBody.tool_choice = { type: 'auto' };
1065
+ } else if (toolChoice && typeof toolChoice === 'object') {
1066
+ if (toolChoice.type === 'function' && toolChoice.function) {
1067
+ requestBody.tool_choice = { type: 'tool', tool: { name: toolChoice.function.name } };
1068
+ } else {
1069
+ requestBody.tool_choice = { type: 'auto' };
1070
+ }
1071
+ } else {
1072
+ requestBody.tool_choice = { type: 'auto' };
1073
+ }
1074
+ }
1075
+
1076
+ if (options.thinkingTokens && options.thinkingTokens > 0) {
1077
+ requestBody.thinking = { type: 'enabled', budget_tokens: options.thinkingTokens };
1078
+ }
1079
+
1080
+ // 调试输出(受showAIDebugInfo配置控制)
1081
+ const showDebug = this.authConfig.showAIDebugInfo ?? false;
1082
+
1083
+ if (showDebug) {
1084
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
1085
+ console.log('║ AI REQUEST DEBUG (ANTHROPIC STREAM) ║');
1086
+ console.log('╚══════════════════════════════════════════════════════════╝');
1087
+ console.log(`📦 Model: ${requestBody.model}`);
1088
+ console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
1089
+ console.log(`💬 Total Messages: ${anthropicMessages.length} 条`);
1090
+ if (requestBody.temperature) console.log(`🌡️ Temperature: ${requestBody.temperature}`);
1091
+ if (requestBody.max_tokens) console.log(`📏 Max Tokens: ${requestBody.max_tokens}`);
1092
+ if (requestBody.thinking) console.log(`🧠 Thinking Budget: ${requestBody.thinking.budget_tokens}`);
1093
+ console.log('─'.repeat(60));
1094
+
1095
+ // 显示system消息
1096
+ if (system) {
1097
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
1098
+ console.log('│ 🟫 SYSTEM │');
1099
+ console.log('├─────────────────────────────────────────────────────────────┤');
1100
+ console.log(renderMarkdown(system).split('\n').map(l => '│ ' + l).join('\n'));
1101
+ console.log('└─────────────────────────────────────────────────────────────┘');
1102
+ }
1103
+
1104
+ displayMessages(anthropicMessages);
1105
+
1106
+ console.log('\n📤 Starting Anthropic stream...\n');
1107
+ }
1108
+
1109
+ try {
1110
+ // Anthropic 原生流式端点 /v1/messages
1111
+ const response = await this.client.post('/v1/messages', requestBody, {
1112
+ responseType: 'stream'
1113
+ });
1114
+
1115
+ console.log('📥 Receiving Anthropic stream chunks...\n');
1116
+
1117
+ let buffer = '';
1118
+ let outputBuffer = '';
1119
+
1120
+ for await (const chunk of response.data) {
1121
+ buffer += chunk.toString();
1122
+ const lines = buffer.split('\n');
1123
+ buffer = lines.pop() || '';
1124
+
1125
+ for (const line of lines) {
1126
+ const trimmedLine = line.trim();
1127
+ if (!trimmedLine) continue;
1128
+
1129
+ // Anthropic 流式格式: data: {"type":"content_block_delta",...}
1130
+ if (trimmedLine.startsWith('data: ')) {
1131
+ const data = trimmedLine.slice(6);
1132
+
1133
+ try {
1134
+ const parsed = JSON.parse(data);
1135
+
1136
+ // Anthropic 事件类型
1137
+ if (parsed.type === 'content_block_delta') {
1138
+ if (parsed.delta?.type === 'text_delta' && parsed.delta.text) {
1139
+ outputBuffer += parsed.delta.text;
1140
+ yield parsed.delta.text;
1141
+ } else if (parsed.delta?.type === 'thinking_delta' && parsed.delta.thinking) {
1142
+ outputBuffer += parsed.delta.thinking;
1143
+ yield parsed.delta.thinking;
1144
+ }
1145
+ } else if (parsed.type === 'message_delta') {
1146
+ if (parsed.delta?.stop_reason) {
1147
+ // 消息结束
1148
+ if (showDebug) {
1149
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
1150
+ console.log('║ STREAM COMPLETED ║');
1151
+ console.log('╚══════════════════════════════════════════════════════════╝');
1152
+ console.log(`📏 Total output: ${outputBuffer.length} chars`);
1153
+
1154
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
1155
+ console.log('│ 🤖 ASSISTANT OUTPUT │');
1156
+ console.log('├─────────────────────────────────────────────────────────────┤');
1157
+ console.log('│ 💬 CONTENT:');
1158
+ console.log('│ ───────────────────────────────────────────────────────────');
1159
+ const lines = renderMarkdown(outputBuffer).split('\n');
1160
+ for (const line of lines.slice(0, 30)) {
1161
+ console.log('│ ' + line.slice(0, 62));
1162
+ }
1163
+ if (lines.length > 30) {
1164
+ console.log(`│ ... (${lines.length - 30} more lines)`);
1165
+ }
1166
+ console.log('└─────────────────────────────────────────────────────────────┘');
1167
+ console.log('');
1168
+ }
1169
+ return;
1170
+ }
1171
+ }
1172
+ } catch (e) {
1173
+ // 忽略解析错误
1174
+ }
1175
+ }
1176
+ }
1177
+ }
1178
+
1179
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
1180
+ console.log('║ STREAM COMPLETED ║');
1181
+ console.log('╚══════════════════════════════════════════════════════════╝\n');
1182
+ } catch (error: any) {
1183
+ if (error.response) {
1184
+ throw new Error(
1185
+ `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`
1186
+ );
1187
+ } else if (error.request) {
1188
+ throw new Error('Network error: No response received from server');
1189
+ } else {
1190
+ throw new Error(`Request error: ${error.message}`);
1191
+ }
1192
+ }
1193
+ }
1194
+
1195
+ // MiniMax 流式响应(根据 baseUrl 自动选择格式)
1196
+ private async *minimaxStreamChatCompletion(
1197
+ messages: Message[],
1198
+ options: ChatCompletionOptions = {}
1199
+ ): AsyncGenerator<string, void, unknown> {
1200
+ const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
1201
+ const { endpoint, format } = getMiniMaxEndpoint(this.authConfig.baseUrl || '');
1202
+
1203
+ const requestBody: any = {
1204
+ model: options.model || this.authConfig.modelName || 'MiniMax-M2',
1205
+ messages: format === 'anthropic' ? anthropicMessages : messages,
1206
+ temperature: options.temperature ?? 1.0,
1207
+ stream: true,
1208
+ max_tokens: options.maxTokens || 4096
1209
+ };
1210
+
1211
+ if (system && format === 'anthropic') {
1212
+ requestBody.system = system;
1213
+ }
1214
+
1215
+ if (format === 'anthropic') {
1216
+ // Anthropic 格式的工具
1217
+ if (options.tools && options.tools.length > 0) {
1218
+ requestBody.tools = options.tools.map(tool => ({
1219
+ name: tool.function.name,
1220
+ description: tool.function.description,
1221
+ input_schema: tool.function.parameters || { type: 'object', properties: {} }
1222
+ }));
1223
+
1224
+ const toolChoice = options.toolChoice;
1225
+ if (toolChoice === 'none') {
1226
+ requestBody.tool_choice = { type: 'auto' };
1227
+ } else if (toolChoice && typeof toolChoice === 'object') {
1228
+ if (toolChoice.type === 'function' && toolChoice.function) {
1229
+ requestBody.tool_choice = { type: 'tool', tool: { name: toolChoice.function.name } };
1230
+ } else {
1231
+ requestBody.tool_choice = { type: 'auto' };
1232
+ }
1233
+ } else {
1234
+ requestBody.tool_choice = { type: 'auto' };
1235
+ }
1236
+ }
1237
+ } else {
1238
+ // OpenAI 格式的工具
1239
+ if (options.tools && options.tools.length > 0) {
1240
+ requestBody.tools = options.tools;
1241
+ requestBody.tool_choice = options.toolChoice || 'auto';
1242
+ }
1243
+ }
1244
+
1245
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
1246
+ console.log('║ AI REQUEST DEBUG (MINIMAX STREAM) ║');
1247
+ console.log('╚══════════════════════════════════════════════════════════╝');
1248
+ console.log(`📦 Model: ${requestBody.model}`);
1249
+ console.log(`🔗 Format: ${format.toUpperCase()} | Endpoint: ${endpoint}`);
1250
+ console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
1251
+ console.log(`💬 Total Messages: ${requestBody.messages.length} 条`);
1252
+ if (requestBody.temperature) console.log(`🌡️ Temperature: ${requestBody.temperature}`);
1253
+ if (requestBody.max_tokens) console.log(`📏 Max Tokens: ${requestBody.max_tokens}`);
1254
+ console.log('─'.repeat(60));
1255
+
1256
+ // 显示system消息
1257
+ if (system && format === 'anthropic') {
1258
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
1259
+ console.log('│ 🟫 SYSTEM │');
1260
+ console.log('├─────────────────────────────────────────────────────────────┤');
1261
+ console.log(renderMarkdown(system).split('\n').map(l => '│ ' + l).join('\n'));
1262
+ console.log('└─────────────────────────────────────────────────────────────┘');
1263
+ }
1264
+
1265
+ displayMessages(requestBody.messages);
1266
+
1267
+ console.log('\n📤 Starting MiniMax stream...\n');
1268
+
1269
+ try {
1270
+ // MiniMax uses correct endpoint
1271
+ const response = await this.client.post(endpoint, requestBody, {
1272
+ responseType: 'stream'
1273
+ });
1274
+
1275
+ console.log('📥 Receiving MiniMax stream chunks...\n');
1276
+
1277
+ let buffer = '';
1278
+ let outputBuffer = '';
1279
+
1280
+ for await (const chunk of response.data) {
1281
+ buffer += chunk.toString();
1282
+ const lines = buffer.split('\n');
1283
+ buffer = lines.pop() || '';
1284
+
1285
+ for (const line of lines) {
1286
+ const trimmedLine = line.trim();
1287
+ if (!trimmedLine) continue;
1288
+
1289
+ // 根据格式解析不同的流式响应
1290
+ if (format === 'anthropic') {
1291
+ // Anthropic SSE 格式: data: {"type":"content_block_delta",...}
1292
+ if (trimmedLine.startsWith('data: ')) {
1293
+ const data = trimmedLine.slice(6);
1294
+
1295
+ try {
1296
+ const parsed = JSON.parse(data);
1297
+
1298
+ if (parsed.type === 'content_block_delta') {
1299
+ if (parsed.delta?.type === 'text_delta' && parsed.delta.text) {
1300
+ yield parsed.delta.text;
1301
+ } else if (parsed.delta?.type === 'thinking_delta' && parsed.delta.thinking) {
1302
+ yield parsed.delta.thinking;
1303
+ }
1304
+ } else if (parsed.type === 'message_delta') {
1305
+ if (parsed.delta?.stop_reason) {
1306
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
1307
+ console.log('║ STREAM COMPLETED ║');
1308
+ console.log('╚══════════════════════════════════════════════════════════╝');
1309
+ console.log(`📏 Total output: ${outputBuffer.length} chars`);
1310
+
1311
+ console.log('\n┌─────────────────────────────────────────────────────────────┐');
1312
+ console.log('│ 🤖 ASSISTANT OUTPUT │');
1313
+ console.log('├─────────────────────────────────────────────────────────────┤');
1314
+ console.log('│ 💬 CONTENT:');
1315
+ console.log('│ ───────────────────────────────────────────────────────────');
1316
+ const lines = renderMarkdown(outputBuffer).split('\n');
1317
+ for (const line of lines.slice(0, 30)) {
1318
+ console.log('│ ' + line.slice(0, 62));
1319
+ }
1320
+ if (lines.length > 30) {
1321
+ console.log(`│ ... (${lines.length - 30} more lines)`);
1322
+ }
1323
+ console.log('└─────────────────────────────────────────────────────────────┘');
1324
+ console.log('');
1325
+ return;
1326
+ }
1327
+ }
1328
+ } catch (e) {
1329
+ // 忽略解析错误
1330
+ }
1331
+ }
1332
+ } else {
1333
+ // OpenAI SSE 格式: data: {...}
1334
+ if (trimmedLine.startsWith('data: ')) {
1335
+ const data = trimmedLine.slice(6);
1336
+ if (data === '[DONE]') continue;
1337
+
1338
+ try {
1339
+ const parsed = JSON.parse(data);
1340
+ const delta = parsed.choices?.[0]?.delta;
1341
+ if (delta?.content) {
1342
+ outputBuffer += delta.content;
1343
+ yield delta.content;
1344
+ } else if (delta?.reasoning_content) {
1345
+ outputBuffer += delta.reasoning_content;
1346
+ yield delta.reasoning_content;
1347
+ }
1348
+ } catch (e) {
1349
+ // 忽略解析错误
1350
+ }
1351
+ }
1352
+ }
1353
+ }
1354
+ }
1355
+
1356
+ console.log('\n╔══════════════════════════════════════════════════════════╗');
1357
+ console.log('║ STREAM COMPLETED ║');
1358
+ console.log('╚══════════════════════════════════════════════════════════╝\n');
1359
+ } catch (error: any) {
1360
+ if (error.response) {
1361
+ throw new Error(
1362
+ `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`
1363
+ );
1364
+ } else if (error.request) {
1365
+ throw new Error('Network error: No response received from server');
1366
+ } else {
1367
+ throw new Error(`Request error: ${error.message}`);
1368
+ }
1369
+ }
1370
+ }
1371
+
1372
+ async listModels(): Promise<any[]> {
1373
+ try {
1374
+ const response = await this.client.get('/models');
1375
+ return response.data.data || [];
1376
+ } catch (error: any) {
1377
+ console.error('Failed to list models:', error);
1378
+ return [];
1379
+ }
1380
+ }
1381
+
1382
+ updateAuthConfig(authConfig: AuthConfig): void {
1383
+ this.authConfig = authConfig;
1384
+ this.client.defaults.baseURL = authConfig.baseUrl;
1385
+
1386
+ const isMiniMax = detectMiniMaxAPI(authConfig.baseUrl || '');
1387
+ const isAnthropic = !isMiniMax && isAnthropicCompatible(authConfig.baseUrl || '');
1388
+
1389
+ if (isMiniMax || isAnthropic) {
1390
+ // MiniMax/Anthropic: Use x-api-key auth header
1391
+ this.client.defaults.headers['x-api-key'] = authConfig.apiKey || '';
1392
+ this.client.defaults.headers['anthropic-version'] = '2023-06-01';
1393
+ // Clear Bearer header
1394
+ delete this.client.defaults.headers['Authorization'];
1395
+ } else {
1396
+ // OpenAI compatible: Use Bearer token
1397
+ this.client.defaults.headers['Authorization'] = `Bearer ${authConfig.apiKey}`;
1398
+ // Clear x-api-key header
1399
+ delete this.client.defaults.headers['x-api-key'];
1400
+ delete this.client.defaults.headers['anthropic-version'];
1401
+ }
1402
+ }
1403
+
1404
+ getAuthConfig(): AuthConfig {
1405
+ return { ...this.authConfig };
1406
+ }
1407
+
1408
+ // Check if messages contain tool calls
1409
+ hasToolCalls(messages: Message[]): boolean {
1410
+ return messages.some(msg => {
1411
+ if (msg.tool_calls && msg.tool_calls.length > 0) return true;
1412
+ if (Array.isArray(msg.content)) {
1413
+ return msg.content.some(block =>
1414
+ block.type === 'tool_use' ||
1415
+ (block as any).type === 'tool_result'
1416
+ );
1417
+ }
1418
+ return false;
1419
+ });
1420
+ }
1421
+ }
1422
+
1423
+ export function detectThinkingKeywords(text: string): 'none' | 'normal' | 'hard' | 'mega' | 'ultra' {
1424
+ const ultraKeywords = ['super think', 'extreme think', 'deep think', 'full think', 'ultra think', 'careful think',
1425
+ 'ultrathink', 'think really super hard', 'think intensely'];
1426
+ const megaKeywords = ['strong think', 'powerful think', 'think hard', 'try hard to think', 'think well', 'think carefully',
1427
+ 'megathink', 'think really hard', 'think a lot'];
1428
+ const hardKeywords = ['think again', 'think more', 'think clearly', 'think thoroughly', 'consider carefully',
1429
+ 'think about it', 'think more', 'think harder'];
1430
+ const normalKeywords = ['think', 'think', 'consider', 'think'];
1431
+
1432
+ const lowerText = text.toLowerCase();
1433
+
1434
+ if (ultraKeywords.some(keyword => lowerText.includes(keyword.toLowerCase()))) {
1435
+ return 'ultra';
1436
+ } else if (megaKeywords.some(keyword => lowerText.includes(keyword.toLowerCase()))) {
1437
+ return 'mega';
1438
+ } else if (hardKeywords.some(keyword => lowerText.includes(keyword.toLowerCase()))) {
1439
+ return 'hard';
1440
+ } else if (normalKeywords.some(keyword => lowerText.includes(keyword.toLowerCase()))) {
1441
+ return 'normal';
1442
+ }
1443
+
1444
+ return 'none';
1445
+ }
1446
+
1447
+ export function getThinkingTokens(mode: 'none' | 'normal' | 'hard' | 'mega' | 'ultra'): number {
1448
+ const tokensMap = {
1449
+ none: 0,
1450
+ normal: 2000,
1451
+ hard: 4000,
1452
+ mega: 10000,
1453
+ ultra: 32000
1454
+ };
1455
+ return tokensMap[mode];
1456
+ }