sa2kit 1.6.60 → 1.6.62

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 (297) hide show
  1. package/dist/UniversalFileService-C3WQAFOV.js +15 -0
  2. package/dist/{UniversalFileService-J6ET6KZK.js.map → UniversalFileService-C3WQAFOV.js.map} +1 -1
  3. package/dist/UniversalFileService-O3IEROBN.mjs +6 -0
  4. package/dist/{UniversalFileService-336GFY6N.mjs.map → UniversalFileService-O3IEROBN.mjs.map} +1 -1
  5. package/dist/ai/llm/index.d.mts +70 -0
  6. package/dist/ai/llm/index.d.ts +70 -0
  7. package/dist/ai/llm/index.js +54 -0
  8. package/dist/ai/llm/index.js.map +1 -0
  9. package/dist/ai/llm/index.mjs +5 -0
  10. package/dist/ai/llm/index.mjs.map +1 -0
  11. package/dist/ai/llm/ui/electron/index.d.mts +5 -0
  12. package/dist/ai/llm/ui/electron/index.d.ts +5 -0
  13. package/dist/ai/llm/ui/electron/index.js +21 -0
  14. package/dist/ai/llm/ui/electron/index.js.map +1 -0
  15. package/dist/ai/llm/ui/electron/index.mjs +8 -0
  16. package/dist/ai/llm/ui/electron/index.mjs.map +1 -0
  17. package/dist/ai/llm/ui/miniapp/index.d.mts +9 -0
  18. package/dist/ai/llm/ui/miniapp/index.d.ts +9 -0
  19. package/dist/ai/llm/ui/miniapp/index.js +107 -0
  20. package/dist/ai/llm/ui/miniapp/index.js.map +1 -0
  21. package/dist/ai/llm/ui/miniapp/index.mjs +101 -0
  22. package/dist/ai/llm/ui/miniapp/index.mjs.map +1 -0
  23. package/dist/ai/llm/ui/rn/index.d.mts +9 -0
  24. package/dist/ai/llm/ui/rn/index.d.ts +9 -0
  25. package/dist/ai/llm/ui/rn/index.js +249 -0
  26. package/dist/ai/llm/ui/rn/index.js.map +1 -0
  27. package/dist/ai/llm/ui/rn/index.mjs +243 -0
  28. package/dist/ai/llm/ui/rn/index.mjs.map +1 -0
  29. package/dist/ai/llm/ui/web/index.d.mts +15 -0
  30. package/dist/ai/llm/ui/web/index.d.ts +15 -0
  31. package/dist/ai/llm/ui/web/index.js +21 -0
  32. package/dist/ai/llm/ui/web/index.js.map +1 -0
  33. package/dist/ai/llm/ui/web/index.mjs +8 -0
  34. package/dist/ai/llm/ui/web/index.mjs.map +1 -0
  35. package/dist/ar/index.d.mts +7 -0
  36. package/dist/ar/index.d.ts +7 -0
  37. package/dist/ar/index.js +17 -0
  38. package/dist/ar/index.js.map +1 -0
  39. package/dist/ar/index.mjs +4 -0
  40. package/dist/ar/index.mjs.map +1 -0
  41. package/dist/auth/index.js +22 -22
  42. package/dist/auth/index.mjs +2 -2
  43. package/dist/auth/legacy/db/index.d.mts +5 -0
  44. package/dist/auth/legacy/db/index.d.ts +5 -0
  45. package/dist/auth/legacy/db/index.js +34 -0
  46. package/dist/auth/legacy/db/index.js.map +1 -0
  47. package/dist/auth/legacy/db/index.mjs +5 -0
  48. package/dist/auth/legacy/db/index.mjs.map +1 -0
  49. package/dist/auth/legacy/index.d.mts +51 -0
  50. package/dist/auth/legacy/index.d.ts +51 -0
  51. package/dist/auth/legacy/index.js +146 -0
  52. package/dist/auth/legacy/index.js.map +1 -0
  53. package/dist/auth/legacy/index.mjs +13 -0
  54. package/dist/auth/legacy/index.mjs.map +1 -0
  55. package/dist/auth/legacy/logic/index.d.mts +9 -0
  56. package/dist/auth/legacy/logic/index.d.ts +9 -0
  57. package/dist/auth/legacy/logic/index.js +18 -0
  58. package/dist/auth/legacy/logic/index.js.map +1 -0
  59. package/dist/auth/legacy/logic/index.mjs +5 -0
  60. package/dist/auth/legacy/logic/index.mjs.map +1 -0
  61. package/dist/auth/legacy/routes/index.d.mts +50 -0
  62. package/dist/auth/legacy/routes/index.d.ts +50 -0
  63. package/dist/auth/legacy/routes/index.js +34 -0
  64. package/dist/auth/legacy/routes/index.js.map +1 -0
  65. package/dist/auth/legacy/routes/index.mjs +5 -0
  66. package/dist/auth/legacy/routes/index.mjs.map +1 -0
  67. package/dist/auth/legacy/schema/index.d.mts +401 -0
  68. package/dist/auth/legacy/schema/index.d.ts +401 -0
  69. package/dist/auth/legacy/schema/index.js +29 -0
  70. package/dist/auth/legacy/schema/index.js.map +1 -0
  71. package/dist/auth/legacy/schema/index.mjs +4 -0
  72. package/dist/auth/legacy/schema/index.mjs.map +1 -0
  73. package/dist/auth/legacy/server/index.d.mts +15 -0
  74. package/dist/auth/legacy/server/index.d.ts +15 -0
  75. package/dist/auth/legacy/server/index.js +65 -0
  76. package/dist/auth/legacy/server/index.js.map +1 -0
  77. package/dist/auth/legacy/server/index.mjs +8 -0
  78. package/dist/auth/legacy/server/index.mjs.map +1 -0
  79. package/dist/auth/legacy/services/index.d.mts +40 -0
  80. package/dist/auth/legacy/services/index.d.ts +40 -0
  81. package/dist/auth/legacy/services/index.js +14 -0
  82. package/dist/auth/legacy/services/index.js.map +1 -0
  83. package/dist/auth/legacy/services/index.mjs +5 -0
  84. package/dist/auth/legacy/services/index.mjs.map +1 -0
  85. package/dist/auth/legacy/ui/miniapp/index.d.mts +10 -0
  86. package/dist/auth/legacy/ui/miniapp/index.d.ts +10 -0
  87. package/dist/auth/legacy/ui/miniapp/index.js +23 -0
  88. package/dist/auth/legacy/ui/miniapp/index.js.map +1 -0
  89. package/dist/auth/legacy/ui/miniapp/index.mjs +6 -0
  90. package/dist/auth/legacy/ui/miniapp/index.mjs.map +1 -0
  91. package/dist/auth/legacy/ui/web/index.d.mts +22 -0
  92. package/dist/auth/legacy/ui/web/index.d.ts +22 -0
  93. package/dist/auth/legacy/ui/web/index.js +31 -0
  94. package/dist/auth/legacy/ui/web/index.js.map +1 -0
  95. package/dist/auth/legacy/ui/web/index.mjs +6 -0
  96. package/dist/auth/legacy/ui/web/index.mjs.map +1 -0
  97. package/dist/calendar/index.d.mts +390 -237
  98. package/dist/calendar/index.d.ts +390 -237
  99. package/dist/calendar/index.js +3825 -3785
  100. package/dist/calendar/index.js.map +1 -1
  101. package/dist/calendar/index.mjs +3730 -3696
  102. package/dist/calendar/index.mjs.map +1 -1
  103. package/dist/calendar/routes/index.js +30 -327
  104. package/dist/calendar/routes/index.js.map +1 -1
  105. package/dist/calendar/routes/index.mjs +1 -323
  106. package/dist/calendar/routes/index.mjs.map +1 -1
  107. package/dist/calendar/server.d.mts +6 -0
  108. package/dist/calendar/server.d.ts +6 -0
  109. package/dist/calendar/server.js +41 -13
  110. package/dist/calendar/server.js.map +1 -1
  111. package/dist/calendar/server.mjs +2 -2
  112. package/dist/calendar/server.mjs.map +1 -1
  113. package/dist/chunk-24F7KUED.js +263 -0
  114. package/dist/chunk-24F7KUED.js.map +1 -0
  115. package/dist/{chunk-YMS6BPXS.js → chunk-27IUMDDK.js} +3 -3
  116. package/dist/{chunk-YMS6BPXS.js.map → chunk-27IUMDDK.js.map} +1 -1
  117. package/dist/chunk-37M6NZIF.js +279 -0
  118. package/dist/chunk-37M6NZIF.js.map +1 -0
  119. package/dist/chunk-3JMUNOUT.js +144 -0
  120. package/dist/chunk-3JMUNOUT.js.map +1 -0
  121. package/dist/chunk-3PFCOTJP.mjs +256 -0
  122. package/dist/chunk-3PFCOTJP.mjs.map +1 -0
  123. package/dist/{chunk-NZZZUMMX.mjs → chunk-57MVE5LL.mjs} +3 -3
  124. package/dist/{chunk-NZZZUMMX.mjs.map → chunk-57MVE5LL.mjs.map} +1 -1
  125. package/dist/{chunk-622Y6LTH.mjs → chunk-5BLZEVWK.mjs} +196 -468
  126. package/dist/chunk-5BLZEVWK.mjs.map +1 -0
  127. package/dist/{chunk-YN4MJFIG.js → chunk-5LCGOCKG.js} +5 -5
  128. package/dist/{chunk-YN4MJFIG.js.map → chunk-5LCGOCKG.js.map} +1 -1
  129. package/dist/chunk-6XUQ2B4K.js +219 -0
  130. package/dist/chunk-6XUQ2B4K.js.map +1 -0
  131. package/dist/{chunk-NCOXT7SK.js → chunk-77UEPWVQ.js} +4 -4
  132. package/dist/{chunk-NCOXT7SK.js.map → chunk-77UEPWVQ.js.map} +1 -1
  133. package/dist/chunk-CFM56MGO.mjs +35 -0
  134. package/dist/chunk-CFM56MGO.mjs.map +1 -0
  135. package/dist/chunk-CPSFYP34.mjs +140 -0
  136. package/dist/chunk-CPSFYP34.mjs.map +1 -0
  137. package/dist/chunk-D22QBOCM.mjs +336 -0
  138. package/dist/chunk-D22QBOCM.mjs.map +1 -0
  139. package/dist/chunk-DA4QV64P.mjs +35 -0
  140. package/dist/chunk-DA4QV64P.mjs.map +1 -0
  141. package/dist/chunk-EKDLZND6.js +275 -0
  142. package/dist/chunk-EKDLZND6.js.map +1 -0
  143. package/dist/chunk-EKQPFZXQ.js +12 -0
  144. package/dist/chunk-EKQPFZXQ.js.map +1 -0
  145. package/dist/chunk-ERAAB5VG.js +324 -0
  146. package/dist/chunk-ERAAB5VG.js.map +1 -0
  147. package/dist/chunk-ESLY72VI.mjs +175 -0
  148. package/dist/chunk-ESLY72VI.mjs.map +1 -0
  149. package/dist/chunk-FGQGWW73.js +38 -0
  150. package/dist/chunk-FGQGWW73.js.map +1 -0
  151. package/dist/chunk-FXQOXLDE.js +120 -0
  152. package/dist/chunk-FXQOXLDE.js.map +1 -0
  153. package/dist/chunk-FZELCJR7.mjs +19 -0
  154. package/dist/chunk-FZELCJR7.mjs.map +1 -0
  155. package/dist/{chunk-HHVDOIPV.js → chunk-H3P2PGZL.js} +3 -3
  156. package/dist/{chunk-HHVDOIPV.js.map → chunk-H3P2PGZL.js.map} +1 -1
  157. package/dist/chunk-HBQMN5QM.mjs +10 -0
  158. package/dist/chunk-HBQMN5QM.mjs.map +1 -0
  159. package/dist/chunk-ITRIXMXF.mjs +862 -0
  160. package/dist/chunk-ITRIXMXF.mjs.map +1 -0
  161. package/dist/chunk-IUWSCUDC.js +4 -0
  162. package/dist/chunk-IUWSCUDC.js.map +1 -0
  163. package/dist/chunk-JCKCKRC2.js +50 -0
  164. package/dist/chunk-JCKCKRC2.js.map +1 -0
  165. package/dist/chunk-L7GQNY54.mjs +286 -0
  166. package/dist/chunk-L7GQNY54.mjs.map +1 -0
  167. package/dist/{chunk-ZRWED7Q6.js → chunk-LDVJ7URJ.js} +235 -520
  168. package/dist/chunk-LDVJ7URJ.js.map +1 -0
  169. package/dist/{chunk-CYTXGBP2.js → chunk-MLP74E3O.js} +573 -1607
  170. package/dist/chunk-MLP74E3O.js.map +1 -0
  171. package/dist/chunk-NAX4TUT7.js +182 -0
  172. package/dist/chunk-NAX4TUT7.js.map +1 -0
  173. package/dist/chunk-NW4EN4YI.mjs +213 -0
  174. package/dist/chunk-NW4EN4YI.mjs.map +1 -0
  175. package/dist/chunk-P3QMT3AY.mjs +44 -0
  176. package/dist/chunk-P3QMT3AY.mjs.map +1 -0
  177. package/dist/chunk-PJ4KYAQZ.mjs +631 -0
  178. package/dist/chunk-PJ4KYAQZ.mjs.map +1 -0
  179. package/dist/chunk-PLSEAREM.js +345 -0
  180. package/dist/chunk-PLSEAREM.js.map +1 -0
  181. package/dist/{chunk-EGJPS7OL.mjs → chunk-QZU4UJZG.mjs} +3 -3
  182. package/dist/{chunk-EGJPS7OL.mjs.map → chunk-QZU4UJZG.mjs.map} +1 -1
  183. package/dist/chunk-RJVR33ME.mjs +3 -0
  184. package/dist/chunk-RJVR33ME.mjs.map +1 -0
  185. package/dist/chunk-SYBHDB2D.js +650 -0
  186. package/dist/chunk-SYBHDB2D.js.map +1 -0
  187. package/dist/chunk-TVKVM7JT.js +21 -0
  188. package/dist/chunk-TVKVM7JT.js.map +1 -0
  189. package/dist/{chunk-PONZPO3U.mjs → chunk-UTB72ZJ7.mjs} +414 -1448
  190. package/dist/chunk-UTB72ZJ7.mjs.map +1 -0
  191. package/dist/chunk-V7EVKD5G.mjs +116 -0
  192. package/dist/chunk-V7EVKD5G.mjs.map +1 -0
  193. package/dist/chunk-VGPR3KLR.js +872 -0
  194. package/dist/chunk-VGPR3KLR.js.map +1 -0
  195. package/dist/chunk-VS7WATQD.js +255 -0
  196. package/dist/chunk-VS7WATQD.js.map +1 -0
  197. package/dist/chunk-VSP7XJT5.mjs +272 -0
  198. package/dist/chunk-VSP7XJT5.mjs.map +1 -0
  199. package/dist/{chunk-CSDIPQQO.mjs → chunk-VTKAIOP5.mjs} +5 -5
  200. package/dist/{chunk-CSDIPQQO.mjs.map → chunk-VTKAIOP5.mjs.map} +1 -1
  201. package/dist/chunk-VULJUXTF.mjs +267 -0
  202. package/dist/chunk-VULJUXTF.mjs.map +1 -0
  203. package/dist/chunk-XAHM6B3V.js +44 -0
  204. package/dist/chunk-XAHM6B3V.js.map +1 -0
  205. package/dist/chunk-YSF5YISM.mjs +248 -0
  206. package/dist/chunk-YSF5YISM.mjs.map +1 -0
  207. package/dist/{chunk-OFYBMMWT.mjs → chunk-YYJEVAJI.mjs} +3 -3
  208. package/dist/{chunk-OFYBMMWT.mjs.map → chunk-YYJEVAJI.mjs.map} +1 -1
  209. package/dist/components/index.d.mts +1 -0
  210. package/dist/components/index.d.ts +1 -0
  211. package/dist/components/index.js +182 -181
  212. package/dist/components/index.mjs +4 -3
  213. package/dist/index-DNKZ7-R_.d.mts +184 -0
  214. package/dist/index-DNKZ7-R_.d.ts +184 -0
  215. package/dist/index.d.mts +4 -1
  216. package/dist/index.d.ts +4 -1
  217. package/dist/index.js +285 -229
  218. package/dist/index.js.map +1 -1
  219. package/dist/index.mjs +15 -10
  220. package/dist/index.mjs.map +1 -1
  221. package/dist/mikuFusionGame/index.js +3 -3
  222. package/dist/mikuFusionGame/index.mjs +2 -2
  223. package/dist/mmd/index.d.mts +67 -9
  224. package/dist/mmd/index.d.ts +67 -9
  225. package/dist/mmd/index.js +969 -625
  226. package/dist/mmd/index.js.map +1 -1
  227. package/dist/mmd/index.mjs +969 -628
  228. package/dist/mmd/index.mjs.map +1 -1
  229. package/dist/portfolio/index.js +10 -9
  230. package/dist/portfolio/index.mjs +5 -4
  231. package/dist/qqbot/index.d.mts +2 -0
  232. package/dist/qqbot/index.d.ts +2 -0
  233. package/dist/qqbot/index.js +21 -0
  234. package/dist/qqbot/index.js.map +1 -0
  235. package/dist/qqbot/index.mjs +4 -0
  236. package/dist/qqbot/index.mjs.map +1 -0
  237. package/dist/qqbot/server/index.d.mts +91 -0
  238. package/dist/qqbot/server/index.d.ts +91 -0
  239. package/dist/qqbot/server/index.js +21 -0
  240. package/dist/qqbot/server/index.js.map +1 -0
  241. package/dist/qqbot/server/index.mjs +4 -0
  242. package/dist/qqbot/server/index.mjs.map +1 -0
  243. package/dist/qqbot/ui/web/index.d.mts +10 -0
  244. package/dist/qqbot/ui/web/index.d.ts +10 -0
  245. package/dist/qqbot/ui/web/index.js +105 -0
  246. package/dist/qqbot/ui/web/index.js.map +1 -0
  247. package/dist/qqbot/ui/web/index.mjs +99 -0
  248. package/dist/qqbot/ui/web/index.mjs.map +1 -0
  249. package/dist/screenReceiver/index.d.mts +78 -0
  250. package/dist/screenReceiver/index.d.ts +78 -0
  251. package/dist/screenReceiver/index.js +17 -0
  252. package/dist/screenReceiver/index.js.map +1 -0
  253. package/dist/screenReceiver/index.mjs +4 -0
  254. package/dist/screenReceiver/index.mjs.map +1 -0
  255. package/dist/screenReceiver/server/index.d.mts +36 -0
  256. package/dist/screenReceiver/server/index.d.ts +36 -0
  257. package/dist/screenReceiver/server/index.js +160 -0
  258. package/dist/screenReceiver/server/index.js.map +1 -0
  259. package/dist/screenReceiver/server/index.mjs +157 -0
  260. package/dist/screenReceiver/server/index.mjs.map +1 -0
  261. package/dist/showmasterpiece/db/index.js +42 -42
  262. package/dist/showmasterpiece/db/index.mjs +1 -1
  263. package/dist/showmasterpiece/index.js +52 -41
  264. package/dist/showmasterpiece/index.js.map +1 -1
  265. package/dist/showmasterpiece/index.mjs +15 -4
  266. package/dist/showmasterpiece/index.mjs.map +1 -1
  267. package/dist/showmasterpiece/server/index.js +42 -42
  268. package/dist/showmasterpiece/server/index.mjs +1 -1
  269. package/dist/showmasterpiece/ui/miniapp/index.d.mts +2 -0
  270. package/dist/showmasterpiece/ui/miniapp/index.d.ts +2 -0
  271. package/dist/showmasterpiece/ui/miniapp/index.js +83 -55
  272. package/dist/showmasterpiece/ui/miniapp/index.js.map +1 -1
  273. package/dist/showmasterpiece/ui/miniapp/index.mjs +83 -55
  274. package/dist/showmasterpiece/ui/miniapp/index.mjs.map +1 -1
  275. package/dist/showmasterpiece/ui/web/index.js +43 -32
  276. package/dist/showmasterpiece/ui/web/index.mjs +15 -4
  277. package/dist/testYourself/index.js +13 -13
  278. package/dist/testYourself/index.mjs +2 -2
  279. package/dist/types-B-hOccQw.d.mts +122 -0
  280. package/dist/types-B8rGXc4e.d.mts +38 -0
  281. package/dist/types-Cg89HGz2.d.ts +38 -0
  282. package/dist/types-CvKvpyN8.d.mts +48 -0
  283. package/dist/types-CvKvpyN8.d.ts +48 -0
  284. package/dist/types-Dy6x2gJW.d.ts +122 -0
  285. package/dist/universalFile/server/index.js +11 -11
  286. package/dist/universalFile/server/index.mjs +4 -4
  287. package/package.json +101 -1
  288. package/dist/UniversalFileService-336GFY6N.mjs +0 -6
  289. package/dist/UniversalFileService-J6ET6KZK.js +0 -15
  290. package/dist/chunk-622Y6LTH.mjs.map +0 -1
  291. package/dist/chunk-CYTXGBP2.js.map +0 -1
  292. package/dist/chunk-GVVS4IMM.mjs +0 -302
  293. package/dist/chunk-GVVS4IMM.mjs.map +0 -1
  294. package/dist/chunk-PONZPO3U.mjs.map +0 -1
  295. package/dist/chunk-WC5QFO3T.js +0 -314
  296. package/dist/chunk-WC5QFO3T.js.map +0 -1
  297. package/dist/chunk-ZRWED7Q6.js.map +0 -1
@@ -0,0 +1,140 @@
1
+ import { NextResponse } from 'next/server';
2
+
3
+ // src/qqbot/server/client.ts
4
+ var NapCatClient = class {
5
+ constructor(config) {
6
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
7
+ this.accessToken = config.accessToken;
8
+ this.timeoutMs = config.timeoutMs ?? 12e3;
9
+ }
10
+ async callApi(action, params) {
11
+ const controller = new AbortController();
12
+ const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
13
+ try {
14
+ const response = await fetch(`${this.baseUrl}/${action}`, {
15
+ method: "POST",
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ ...this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}
19
+ },
20
+ body: JSON.stringify(params ?? {}),
21
+ signal: controller.signal
22
+ });
23
+ if (!response.ok) {
24
+ return {
25
+ status: "failed",
26
+ retcode: response.status,
27
+ message: `NapCat HTTP ${response.status}`
28
+ };
29
+ }
30
+ const payload = await response.json();
31
+ return payload;
32
+ } catch (error) {
33
+ return {
34
+ status: "failed",
35
+ retcode: -1,
36
+ message: error instanceof Error ? error.message : "Unknown NapCat request error"
37
+ };
38
+ } finally {
39
+ clearTimeout(timeout);
40
+ }
41
+ }
42
+ async sendGroupMessage(payload) {
43
+ return this.callApi("send_group_msg", payload);
44
+ }
45
+ async sendPrivateMessage(payload) {
46
+ return this.callApi("send_private_msg", payload);
47
+ }
48
+ async getGroupList() {
49
+ return this.callApi("get_group_list");
50
+ }
51
+ async getFriendList() {
52
+ return this.callApi("get_friend_list");
53
+ }
54
+ };
55
+
56
+ // src/qqbot/server/webApi.ts
57
+ function json(status, body) {
58
+ return {
59
+ status,
60
+ headers: { "Content-Type": "application/json" },
61
+ body
62
+ };
63
+ }
64
+ function createNapCatWebApi(client, options = {}) {
65
+ return async function handle(request) {
66
+ const method = request.method.toUpperCase();
67
+ if (method === "GET" && request.path === "/health") {
68
+ return json(200, { ok: true, data: { service: "qqbot-napcat-bridge" } });
69
+ }
70
+ if (method === "POST" && request.path === "/send/group") {
71
+ const result = await client.sendGroupMessage(request.body ?? {});
72
+ return json(result.status === "ok" ? 200 : 502, {
73
+ ok: result.status === "ok",
74
+ data: result.data,
75
+ error: result.message
76
+ });
77
+ }
78
+ if (method === "POST" && request.path === "/send/private") {
79
+ const result = await client.sendPrivateMessage(request.body ?? {});
80
+ return json(result.status === "ok" ? 200 : 502, {
81
+ ok: result.status === "ok",
82
+ data: result.data,
83
+ error: result.message
84
+ });
85
+ }
86
+ if (method === "POST" && request.path === "/groups") {
87
+ const result = await client.getGroupList();
88
+ return json(result.status === "ok" ? 200 : 502, {
89
+ ok: result.status === "ok",
90
+ data: result.data,
91
+ error: result.message
92
+ });
93
+ }
94
+ if (method === "POST" && request.path === "/friends") {
95
+ const result = await client.getFriendList();
96
+ return json(result.status === "ok" ? 200 : 502, {
97
+ ok: result.status === "ok",
98
+ data: result.data,
99
+ error: result.message
100
+ });
101
+ }
102
+ if (method === "POST" && request.path.startsWith("/action/")) {
103
+ const action = request.path.replace("/action/", "");
104
+ const result = await client.callApi(action, request.body ?? {});
105
+ return json(result.status === "ok" ? 200 : 502, {
106
+ ok: result.status === "ok",
107
+ data: result.data,
108
+ error: result.message
109
+ });
110
+ }
111
+ if (method === "POST" && request.path === "/webhook/event") {
112
+ const event = request.body ?? {};
113
+ await options.onWebhookEvent?.(event);
114
+ return json(200, { ok: true });
115
+ }
116
+ return json(404, { ok: false, error: `Route not found: ${method} ${request.path}` });
117
+ };
118
+ }
119
+ function createNextNapCatRouteHandler(config) {
120
+ const basePath = config.basePath ?? "/api/qqbot";
121
+ const handle = createNapCatWebApi(config.client, {
122
+ onWebhookEvent: config.onWebhookEvent
123
+ });
124
+ return async function handler(request) {
125
+ const url = new URL(request.url);
126
+ const path = url.pathname.startsWith(basePath) ? url.pathname.slice(basePath.length) || "/" : url.pathname;
127
+ const body = request.method.toUpperCase() === "GET" ? void 0 : await request.json().catch(() => void 0);
128
+ const payload = {
129
+ method: request.method,
130
+ path,
131
+ body
132
+ };
133
+ const result = await handle(payload);
134
+ return NextResponse.json(result.body, { status: result.status, headers: result.headers });
135
+ };
136
+ }
137
+
138
+ export { NapCatClient, createNapCatWebApi, createNextNapCatRouteHandler };
139
+ //# sourceMappingURL=chunk-CPSFYP34.mjs.map
140
+ //# sourceMappingURL=chunk-CPSFYP34.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/qqbot/server/client.ts","../src/qqbot/server/webApi.ts","../src/qqbot/server/nextRouteAdapter.ts"],"names":[],"mappings":"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","file":"chunk-CPSFYP34.mjs","sourcesContent":["import {\n NapCatConfig,\n OneBotActionResponse,\n OneBotFriendInfo,\n OneBotGroupInfo,\n SendGroupMessagePayload,\n SendPrivateMessagePayload,\n} from '../types';\n\nexport class NapCatClient {\n private readonly baseUrl: string;\n private readonly accessToken?: string;\n private readonly timeoutMs: number;\n\n constructor(config: NapCatConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.accessToken = config.accessToken;\n this.timeoutMs = config.timeoutMs ?? 12000;\n }\n\n async callApi<TData = unknown>(action: string, params?: Record<string, unknown>): Promise<OneBotActionResponse<TData>> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(`${this.baseUrl}/${action}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}),\n },\n body: JSON.stringify(params ?? {}),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n return {\n status: 'failed',\n retcode: response.status,\n message: `NapCat HTTP ${response.status}`,\n };\n }\n\n const payload = (await response.json()) as OneBotActionResponse<TData>;\n return payload;\n } catch (error) {\n return {\n status: 'failed',\n retcode: -1,\n message: error instanceof Error ? error.message : 'Unknown NapCat request error',\n };\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async sendGroupMessage(payload: SendGroupMessagePayload) {\n return this.callApi<{ message_id: number }>('send_group_msg', payload as unknown as Record<string, unknown>);\n }\n\n async sendPrivateMessage(payload: SendPrivateMessagePayload) {\n return this.callApi<{ message_id: number }>('send_private_msg', payload as unknown as Record<string, unknown>);\n }\n\n async getGroupList() {\n return this.callApi<OneBotGroupInfo[]>('get_group_list');\n }\n\n async getFriendList() {\n return this.callApi<OneBotFriendInfo[]>('get_friend_list');\n }\n}\n","import { NapCatWebhookEvent, NapCatWebApiResponse } from '../types';\nimport { NapCatClient } from './client';\n\nexport interface HttpLikeRequest {\n method: string;\n path: string;\n body?: unknown;\n}\n\nexport interface HttpLikeResponse {\n status: number;\n headers?: Record<string, string>;\n body: NapCatWebApiResponse<unknown>;\n}\n\nexport interface NapCatWebApiOptions {\n onWebhookEvent?: (event: NapCatWebhookEvent) => Promise<void> | void;\n}\n\nfunction json(status: number, body: NapCatWebApiResponse<unknown>): HttpLikeResponse {\n return {\n status,\n headers: { 'Content-Type': 'application/json' },\n body,\n };\n}\n\nexport function createNapCatWebApi(client: NapCatClient, options: NapCatWebApiOptions = {}) {\n return async function handle(request: HttpLikeRequest): Promise<HttpLikeResponse> {\n const method = request.method.toUpperCase();\n\n if (method === 'GET' && request.path === '/health') {\n return json(200, { ok: true, data: { service: 'qqbot-napcat-bridge' } });\n }\n\n if (method === 'POST' && request.path === '/send/group') {\n const result = await client.sendGroupMessage((request.body ?? {}) as any);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/send/private') {\n const result = await client.sendPrivateMessage((request.body ?? {}) as any);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/groups') {\n const result = await client.getGroupList();\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/friends') {\n const result = await client.getFriendList();\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path.startsWith('/action/')) {\n const action = request.path.replace('/action/', '');\n const result = await client.callApi(action, (request.body ?? {}) as Record<string, unknown>);\n return json(result.status === 'ok' ? 200 : 502, {\n ok: result.status === 'ok',\n data: result.data,\n error: result.message,\n });\n }\n\n if (method === 'POST' && request.path === '/webhook/event') {\n const event = (request.body ?? {}) as NapCatWebhookEvent;\n await options.onWebhookEvent?.(event);\n return json(200, { ok: true });\n }\n\n return json(404, { ok: false, error: `Route not found: ${method} ${request.path}` });\n };\n}\n","import { NextRequest, NextResponse } from 'next/server';\nimport { HttpLikeRequest, createNapCatWebApi } from './webApi';\nimport { NapCatClient } from './client';\n\nexport interface NextNapCatRouteConfig {\n client: NapCatClient;\n basePath?: string;\n onWebhookEvent?: (event: Record<string, unknown>) => Promise<void> | void;\n}\n\nexport function createNextNapCatRouteHandler(config: NextNapCatRouteConfig) {\n const basePath = config.basePath ?? '/api/qqbot';\n const handle = createNapCatWebApi(config.client, {\n onWebhookEvent: config.onWebhookEvent,\n });\n\n return async function handler(request: NextRequest) {\n const url = new URL(request.url);\n const path = url.pathname.startsWith(basePath) ? url.pathname.slice(basePath.length) || '/' : url.pathname;\n\n const body = request.method.toUpperCase() === 'GET' ? undefined : await request.json().catch(() => undefined);\n\n const payload: HttpLikeRequest = {\n method: request.method,\n path,\n body,\n };\n\n const result = await handle(payload);\n return NextResponse.json(result.body, { status: result.status, headers: result.headers });\n };\n}\n"]}
@@ -0,0 +1,336 @@
1
+ import { applyPromptTemplate } from './chunk-V7EVKD5G.mjs';
2
+
3
+ // src/ai/llm/client/request.ts
4
+ var requestJson = async (options) => {
5
+ const { url, method = "POST", headers = {}, body, timeoutMs, requestAdapter } = options;
6
+ if (requestAdapter) {
7
+ return requestAdapter.request({
8
+ url,
9
+ method,
10
+ headers,
11
+ body
12
+ });
13
+ }
14
+ const controller = timeoutMs ? new AbortController() : void 0;
15
+ const timeoutId = timeoutMs ? setTimeout(() => {
16
+ controller?.abort();
17
+ }, timeoutMs) : void 0;
18
+ try {
19
+ const response = await fetch(url, {
20
+ method,
21
+ headers,
22
+ body: body ? JSON.stringify(body) : void 0,
23
+ signal: controller?.signal
24
+ });
25
+ const text = await response.text();
26
+ let data = null;
27
+ if (text) {
28
+ try {
29
+ data = JSON.parse(text);
30
+ } catch {
31
+ data = text;
32
+ }
33
+ }
34
+ if (!response.ok) {
35
+ const errorMessage = data?.error?.message || data?.error || data?.message || `Request failed with status ${response.status}`;
36
+ const error = new Error(errorMessage);
37
+ error.status = response.status;
38
+ error.data = data;
39
+ throw error;
40
+ }
41
+ return data;
42
+ } finally {
43
+ if (timeoutId) {
44
+ clearTimeout(timeoutId);
45
+ }
46
+ }
47
+ };
48
+
49
+ // src/ai/llm/providers/openai-compatible.ts
50
+ var DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
51
+ var DEFAULT_OPENAI_MODEL = "gpt-3.5-turbo";
52
+ var joinUrl = (base, path) => {
53
+ const trimmedBase = base.replace(/\/+$/, "");
54
+ const trimmedPath = path.replace(/^\/+/, "");
55
+ return `${trimmedBase}/${trimmedPath}`;
56
+ };
57
+ var normalizeToolCalls = (toolCalls) => {
58
+ if (!toolCalls || !toolCalls.length) {
59
+ return void 0;
60
+ }
61
+ return toolCalls.map((call, index) => ({
62
+ id: call?.id ?? String(index),
63
+ type: "function",
64
+ function: {
65
+ name: call?.function?.name ?? "",
66
+ arguments: call?.function?.arguments ?? ""
67
+ }
68
+ }));
69
+ };
70
+ var normalizeUsage = (usage) => {
71
+ if (!usage) {
72
+ return void 0;
73
+ }
74
+ return {
75
+ promptTokens: usage.prompt_tokens,
76
+ completionTokens: usage.completion_tokens,
77
+ totalTokens: usage.total_tokens
78
+ };
79
+ };
80
+ var mapMessage = (message) => {
81
+ const mapped = {
82
+ role: message.role,
83
+ content: message.content
84
+ };
85
+ if (message.name) {
86
+ mapped.name = message.name;
87
+ }
88
+ if (message.toolCallId) {
89
+ mapped.tool_call_id = message.toolCallId;
90
+ }
91
+ if (message.toolCalls?.length) {
92
+ mapped.tool_calls = message.toolCalls.map((call) => ({
93
+ id: call.id,
94
+ type: call.type,
95
+ function: {
96
+ name: call.function.name,
97
+ arguments: call.function.arguments
98
+ }
99
+ }));
100
+ }
101
+ return mapped;
102
+ };
103
+ var createOpenAICompatibleProvider = () => {
104
+ return {
105
+ id: "openai-compatible",
106
+ sendChat: async (request, config) => {
107
+ if (request.stream) {
108
+ throw new Error("Streaming is not supported in sendChat. Use streamChat when available.");
109
+ }
110
+ const model = request.model ?? config.model ?? DEFAULT_OPENAI_MODEL;
111
+ if (!model) {
112
+ throw new Error("Model is required for chat completion requests.");
113
+ }
114
+ const payload = {
115
+ model,
116
+ messages: request.messages.map(mapMessage)
117
+ };
118
+ if (request.temperature !== void 0) {
119
+ payload.temperature = request.temperature;
120
+ }
121
+ if (request.maxTokens !== void 0) {
122
+ payload.max_tokens = request.maxTokens;
123
+ }
124
+ if (request.topP !== void 0) {
125
+ payload.top_p = request.topP;
126
+ }
127
+ if (request.stop !== void 0) {
128
+ payload.stop = request.stop;
129
+ }
130
+ if (request.tools) {
131
+ payload.tools = request.tools;
132
+ }
133
+ if (request.toolChoice) {
134
+ payload.tool_choice = request.toolChoice;
135
+ }
136
+ const url = joinUrl(config.baseUrl || DEFAULT_OPENAI_BASE_URL, "chat/completions");
137
+ const response = await requestJson({
138
+ url,
139
+ method: "POST",
140
+ headers: config.headers,
141
+ body: payload,
142
+ timeoutMs: config.timeoutMs,
143
+ requestAdapter: config.requestAdapter
144
+ });
145
+ const firstMessage = response.choices?.[0]?.message;
146
+ const toolCalls = normalizeToolCalls(firstMessage?.tool_calls);
147
+ const content = firstMessage?.content ?? "";
148
+ const assistantMessage = {
149
+ role: "assistant",
150
+ content,
151
+ toolCalls
152
+ };
153
+ return {
154
+ id: response.id ?? "",
155
+ content,
156
+ message: assistantMessage,
157
+ usage: normalizeUsage(response.usage),
158
+ toolCalls,
159
+ raw: response
160
+ };
161
+ }
162
+ };
163
+ };
164
+
165
+ // src/ai/llm/client/createAiClient.ts
166
+ var DEFAULT_TIMEOUT_MS = 6e4;
167
+ var resolveApiKey = async (config) => {
168
+ if (config.apiKey) {
169
+ return config.apiKey;
170
+ }
171
+ if (config.getApiKey) {
172
+ return await config.getApiKey();
173
+ }
174
+ return void 0;
175
+ };
176
+ var hasAuthorizationHeader = (headers) => {
177
+ return Object.keys(headers).some((key) => key.toLowerCase() === "authorization");
178
+ };
179
+ var resolveHeaders = async (config) => {
180
+ const headers = {
181
+ "Content-Type": "application/json",
182
+ ...config.headers ?? {}
183
+ };
184
+ if (!hasAuthorizationHeader(headers)) {
185
+ const apiKey = await resolveApiKey(config);
186
+ if (apiKey) {
187
+ headers.Authorization = `Bearer ${apiKey}`;
188
+ }
189
+ }
190
+ return headers;
191
+ };
192
+ var resolveClientConfig = async (config) => {
193
+ const headers = await resolveHeaders(config);
194
+ return {
195
+ ...config,
196
+ baseUrl: config.baseUrl ?? "https://api.openai.com/v1",
197
+ headers,
198
+ timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS
199
+ };
200
+ };
201
+ var resolveProvider = (provider) => {
202
+ return provider ?? createOpenAICompatibleProvider();
203
+ };
204
+ var createAiClient = (config) => {
205
+ const provider = resolveProvider(config.provider);
206
+ const sendChat = async (request) => {
207
+ const resolvedConfig = await resolveClientConfig(config);
208
+ config.logger?.debug?.("ai.sendChat", {
209
+ model: request.model ?? resolvedConfig.model,
210
+ messageCount: request.messages.length
211
+ });
212
+ try {
213
+ return await provider.sendChat(request, resolvedConfig);
214
+ } catch (error) {
215
+ config.logger?.error?.("ai.sendChat.error", error);
216
+ throw error;
217
+ }
218
+ };
219
+ const sendMessage = async (content, options) => {
220
+ const resolvedOptions = options ?? {};
221
+ const { systemPrompt, ...requestOptions } = resolvedOptions;
222
+ const messages = [];
223
+ if (systemPrompt) {
224
+ messages.push({ role: "system", content: systemPrompt });
225
+ }
226
+ messages.push({ role: "user", content });
227
+ return sendChat({
228
+ messages,
229
+ ...requestOptions
230
+ });
231
+ };
232
+ return {
233
+ sendChat,
234
+ sendMessage
235
+ };
236
+ };
237
+
238
+ // src/ai/llm/client/createChatSession.ts
239
+ var buildBaseMessages = (systemPrompt, initialMessages) => {
240
+ const baseMessages = [];
241
+ if (systemPrompt) {
242
+ baseMessages.push({ role: "system", content: systemPrompt });
243
+ }
244
+ if (initialMessages?.length) {
245
+ baseMessages.push(...initialMessages);
246
+ }
247
+ return baseMessages;
248
+ };
249
+ var createChatSession = (options) => {
250
+ let systemPrompt = options.systemPrompt;
251
+ let messages = buildBaseMessages(systemPrompt, options.initialMessages);
252
+ const reset = () => {
253
+ messages = buildBaseMessages(systemPrompt, options.initialMessages);
254
+ };
255
+ const setSystemPrompt = (prompt) => {
256
+ systemPrompt = prompt;
257
+ reset();
258
+ };
259
+ const sendMessage = async (input, requestOptions = {}) => {
260
+ const { template, variables, ...chatOptions } = requestOptions;
261
+ const activeTemplate = template ?? options.template;
262
+ const mergedVariables = { input, ...variables ?? {} };
263
+ const content = activeTemplate ? applyPromptTemplate(activeTemplate, mergedVariables) : input;
264
+ const userMessage = { role: "user", content };
265
+ const nextMessages = [...messages, userMessage];
266
+ const response = await options.client.sendChat({
267
+ messages: nextMessages,
268
+ ...chatOptions
269
+ });
270
+ const assistantMessage = response.message ?? {
271
+ role: "assistant",
272
+ content: response.content,
273
+ toolCalls: response.toolCalls
274
+ };
275
+ messages = [...nextMessages, assistantMessage];
276
+ return response;
277
+ };
278
+ return {
279
+ getMessages: () => messages,
280
+ setSystemPrompt,
281
+ reset,
282
+ sendMessage
283
+ };
284
+ };
285
+
286
+ // src/ai/llm/skills/registry.ts
287
+ var skillToToolDefinition = (skill) => {
288
+ const toolDefinition = {
289
+ type: "function",
290
+ function: {
291
+ name: skill.name,
292
+ description: skill.description
293
+ }
294
+ };
295
+ if (skill.inputSchema) {
296
+ toolDefinition.function.parameters = skill.inputSchema;
297
+ }
298
+ return toolDefinition;
299
+ };
300
+ var InMemorySkillRegistry = class {
301
+ constructor(initialSkills) {
302
+ this.skills = /* @__PURE__ */ new Map();
303
+ initialSkills?.forEach((skill) => {
304
+ this.skills.set(skill.name, skill);
305
+ });
306
+ }
307
+ registerSkill(skill) {
308
+ this.skills.set(skill.name, skill);
309
+ }
310
+ unregisterSkill(name) {
311
+ return this.skills.delete(name);
312
+ }
313
+ getSkill(name) {
314
+ return this.skills.get(name);
315
+ }
316
+ listSkills() {
317
+ return Array.from(this.skills.values());
318
+ }
319
+ async executeSkill(name, input, context) {
320
+ const skill = this.skills.get(name);
321
+ if (!skill) {
322
+ throw new Error(`Skill not found: ${name}`);
323
+ }
324
+ return await skill.execute(input, context);
325
+ }
326
+ toToolDefinitions() {
327
+ return this.listSkills().map(skillToToolDefinition);
328
+ }
329
+ };
330
+ var createSkillRegistry = (initialSkills) => {
331
+ return new InMemorySkillRegistry(initialSkills);
332
+ };
333
+
334
+ export { DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, InMemorySkillRegistry, createAiClient, createChatSession, createOpenAICompatibleProvider, createSkillRegistry, skillToToolDefinition };
335
+ //# sourceMappingURL=chunk-D22QBOCM.mjs.map
336
+ //# sourceMappingURL=chunk-D22QBOCM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ai/llm/client/request.ts","../src/ai/llm/providers/openai-compatible.ts","../src/ai/llm/client/createAiClient.ts","../src/ai/llm/client/createChatSession.ts","../src/ai/llm/skills/registry.ts"],"names":[],"mappings":"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","file":"chunk-D22QBOCM.mjs","sourcesContent":["import type { RequestAdapter } from '../../../request';\n\nexport type JsonRequestOptions = {\n url: string;\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n headers?: Record<string, string>;\n body?: any;\n timeoutMs?: number;\n requestAdapter?: RequestAdapter;\n};\n\nexport const requestJson = async <T>(options: JsonRequestOptions): Promise<T> => {\n const { url, method = 'POST', headers = {}, body, timeoutMs, requestAdapter } = options;\n\n if (requestAdapter) {\n return requestAdapter.request<T>({\n url,\n method,\n headers,\n body,\n });\n }\n\n const controller = timeoutMs ? new AbortController() : undefined;\n const timeoutId = timeoutMs\n ? setTimeout(() => {\n controller?.abort();\n }, timeoutMs)\n : undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller?.signal,\n });\n\n const text = await response.text();\n let data: any = null;\n\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!response.ok) {\n const errorMessage =\n data?.error?.message ||\n data?.error ||\n data?.message ||\n `Request failed with status ${response.status}`;\n const error = new Error(errorMessage);\n (error as any).status = response.status;\n (error as any).data = data;\n throw error;\n }\n\n return data as T;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n};\n","import type {\n AiChatRequest,\n AiChatResponse,\n AiMessage,\n AiToolCall,\n AiUsage,\n ResolvedAiClientConfig,\n} from '../types';\nimport type { AiProvider } from './types';\nimport { requestJson } from '../client/request';\n\nexport const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';\nexport const DEFAULT_OPENAI_MODEL = 'gpt-3.5-turbo';\n\ntype OpenAIToolCall = {\n id?: string;\n type?: string;\n function?: {\n name?: string;\n arguments?: string;\n };\n};\n\ntype OpenAIMessage = {\n role?: string;\n content?: string | null;\n tool_calls?: OpenAIToolCall[];\n};\n\ntype OpenAIChatResponse = {\n id: string;\n choices?: Array<{\n message?: OpenAIMessage;\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n };\n};\n\nconst joinUrl = (base: string, path: string): string => {\n const trimmedBase = base.replace(/\\/+$/, '');\n const trimmedPath = path.replace(/^\\/+/, '');\n return `${trimmedBase}/${trimmedPath}`;\n};\n\nconst normalizeToolCalls = (toolCalls?: OpenAIToolCall[]): AiToolCall[] | undefined => {\n if (!toolCalls || !toolCalls.length) {\n return undefined;\n }\n\n return toolCalls.map((call, index) => ({\n id: call?.id ?? String(index),\n type: 'function',\n function: {\n name: call?.function?.name ?? '',\n arguments: call?.function?.arguments ?? '',\n },\n }));\n};\n\nconst normalizeUsage = (usage?: OpenAIChatResponse['usage']): AiUsage | undefined => {\n if (!usage) {\n return undefined;\n }\n\n return {\n promptTokens: usage.prompt_tokens,\n completionTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n };\n};\n\nconst mapMessage = (message: AiMessage): Record<string, any> => {\n const mapped: Record<string, any> = {\n role: message.role,\n content: message.content,\n };\n\n if (message.name) {\n mapped.name = message.name;\n }\n if (message.toolCallId) {\n mapped.tool_call_id = message.toolCallId;\n }\n if (message.toolCalls?.length) {\n mapped.tool_calls = message.toolCalls.map((call) => ({\n id: call.id,\n type: call.type,\n function: {\n name: call.function.name,\n arguments: call.function.arguments,\n },\n }));\n }\n\n return mapped;\n};\n\nexport const createOpenAICompatibleProvider = (): AiProvider => {\n return {\n id: 'openai-compatible',\n sendChat: async (request: AiChatRequest, config: ResolvedAiClientConfig): Promise<AiChatResponse> => {\n if (request.stream) {\n throw new Error('Streaming is not supported in sendChat. Use streamChat when available.');\n }\n\n const model = request.model ?? config.model ?? DEFAULT_OPENAI_MODEL;\n if (!model) {\n throw new Error('Model is required for chat completion requests.');\n }\n\n const payload: Record<string, any> = {\n model,\n messages: request.messages.map(mapMessage),\n };\n\n if (request.temperature !== undefined) {\n payload.temperature = request.temperature;\n }\n if (request.maxTokens !== undefined) {\n payload.max_tokens = request.maxTokens;\n }\n if (request.topP !== undefined) {\n payload.top_p = request.topP;\n }\n if (request.stop !== undefined) {\n payload.stop = request.stop;\n }\n if (request.tools) {\n payload.tools = request.tools;\n }\n if (request.toolChoice) {\n payload.tool_choice = request.toolChoice;\n }\n\n const url = joinUrl(config.baseUrl || DEFAULT_OPENAI_BASE_URL, 'chat/completions');\n const response = await requestJson<OpenAIChatResponse>({\n url,\n method: 'POST',\n headers: config.headers,\n body: payload,\n timeoutMs: config.timeoutMs,\n requestAdapter: config.requestAdapter,\n });\n\n const firstMessage = response.choices?.[0]?.message;\n const toolCalls = normalizeToolCalls(firstMessage?.tool_calls);\n const content = firstMessage?.content ?? '';\n const assistantMessage: AiMessage = {\n role: 'assistant',\n content,\n toolCalls,\n };\n\n return {\n id: response.id ?? '',\n content,\n message: assistantMessage,\n usage: normalizeUsage(response.usage),\n toolCalls,\n raw: response,\n };\n },\n };\n};\n","import type {\n AiChatRequest,\n AiChatRequestOptions,\n AiChatResponse,\n AiClient,\n AiClientConfig,\n AiMessage,\n ResolvedAiClientConfig,\n} from '../types';\nimport type { AiProvider } from '../providers/types';\nimport { createOpenAICompatibleProvider } from '../providers/openai-compatible';\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\nconst resolveApiKey = async (config: AiClientConfig): Promise<string | undefined> => {\n if (config.apiKey) {\n return config.apiKey;\n }\n if (config.getApiKey) {\n return await config.getApiKey();\n }\n return undefined;\n};\n\nconst hasAuthorizationHeader = (headers: Record<string, string>): boolean => {\n return Object.keys(headers).some((key) => key.toLowerCase() === 'authorization');\n};\n\nconst resolveHeaders = async (config: AiClientConfig): Promise<Record<string, string>> => {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(config.headers ?? {}),\n };\n\n if (!hasAuthorizationHeader(headers)) {\n const apiKey = await resolveApiKey(config);\n if (apiKey) {\n headers.Authorization = `Bearer ${apiKey}`;\n }\n }\n\n return headers;\n};\n\nconst resolveClientConfig = async (config: AiClientConfig): Promise<ResolvedAiClientConfig> => {\n const headers = await resolveHeaders(config);\n\n return {\n ...config,\n baseUrl: config.baseUrl ?? 'https://api.openai.com/v1',\n headers,\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n};\n\nconst resolveProvider = (provider?: AiProvider): AiProvider => {\n return provider ?? createOpenAICompatibleProvider();\n};\n\nexport const createAiClient = (config: AiClientConfig): AiClient => {\n const provider = resolveProvider(config.provider);\n\n const sendChat = async (request: AiChatRequest): Promise<AiChatResponse> => {\n const resolvedConfig = await resolveClientConfig(config);\n config.logger?.debug?.('ai.sendChat', {\n model: request.model ?? resolvedConfig.model,\n messageCount: request.messages.length,\n });\n try {\n return await provider.sendChat(request, resolvedConfig);\n } catch (error) {\n config.logger?.error?.('ai.sendChat.error', error);\n throw error;\n }\n };\n\n type SendMessageOptions = AiChatRequestOptions & { systemPrompt?: string };\n\n const sendMessage = async (\n content: string,\n options?: SendMessageOptions\n ): Promise<AiChatResponse> => {\n const resolvedOptions: SendMessageOptions = options ?? {};\n const { systemPrompt, ...requestOptions } = resolvedOptions;\n\n const messages: AiMessage[] = [];\n if (systemPrompt) {\n messages.push({ role: 'system', content: systemPrompt });\n }\n messages.push({ role: 'user', content });\n\n return sendChat({\n messages,\n ...requestOptions,\n });\n };\n\n return {\n sendChat,\n sendMessage,\n };\n};\n","import { applyPromptTemplate } from '../prompt/template';\nimport type { AiChatInputOptions, AiChatResponse, AiChatSession, AiChatSessionOptions, AiMessage } from '../types';\n\nconst buildBaseMessages = (systemPrompt?: string, initialMessages?: AiMessage[]): AiMessage[] => {\n const baseMessages: AiMessage[] = [];\n if (systemPrompt) {\n baseMessages.push({ role: 'system', content: systemPrompt });\n }\n if (initialMessages?.length) {\n baseMessages.push(...initialMessages);\n }\n return baseMessages;\n};\n\nexport const createChatSession = (options: AiChatSessionOptions): AiChatSession => {\n let systemPrompt = options.systemPrompt;\n let messages = buildBaseMessages(systemPrompt, options.initialMessages);\n\n const reset = () => {\n messages = buildBaseMessages(systemPrompt, options.initialMessages);\n };\n\n const setSystemPrompt = (prompt?: string) => {\n systemPrompt = prompt;\n reset();\n };\n\n const sendMessage = async (\n input: string,\n requestOptions: AiChatInputOptions = {}\n ): Promise<AiChatResponse> => {\n const { template, variables, ...chatOptions } = requestOptions;\n const activeTemplate = template ?? options.template;\n const mergedVariables = { input, ...(variables ?? {}) };\n const content = activeTemplate ? applyPromptTemplate(activeTemplate, mergedVariables) : input;\n\n const userMessage: AiMessage = { role: 'user', content };\n const nextMessages = [...messages, userMessage];\n\n const response = await options.client.sendChat({\n messages: nextMessages,\n ...chatOptions,\n });\n\n const assistantMessage: AiMessage =\n response.message ?? {\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n };\n\n messages = [...nextMessages, assistantMessage];\n\n return response;\n };\n\n return {\n getMessages: () => messages,\n setSystemPrompt,\n reset,\n sendMessage,\n };\n};\n","import type { AiToolDefinition } from '../types';\nimport type { SkillDefinition, SkillExecutionContext, SkillRegistry } from './types';\n\nexport const skillToToolDefinition = (skill: SkillDefinition): AiToolDefinition => {\n const toolDefinition: AiToolDefinition = {\n type: 'function',\n function: {\n name: skill.name,\n description: skill.description,\n },\n };\n\n if (skill.inputSchema) {\n toolDefinition.function.parameters = skill.inputSchema;\n }\n\n return toolDefinition;\n};\n\nexport class InMemorySkillRegistry implements SkillRegistry {\n private skills = new Map<string, SkillDefinition>();\n\n constructor(initialSkills?: SkillDefinition[]) {\n initialSkills?.forEach((skill) => {\n this.skills.set(skill.name, skill);\n });\n }\n\n registerSkill(skill: SkillDefinition): void {\n this.skills.set(skill.name, skill);\n }\n\n unregisterSkill(name: string): boolean {\n return this.skills.delete(name);\n }\n\n getSkill(name: string): SkillDefinition | undefined {\n return this.skills.get(name);\n }\n\n listSkills(): SkillDefinition[] {\n return Array.from(this.skills.values());\n }\n\n async executeSkill(name: string, input: any, context?: SkillExecutionContext): Promise<any> {\n const skill = this.skills.get(name);\n if (!skill) {\n throw new Error(`Skill not found: ${name}`);\n }\n return await skill.execute(input, context);\n }\n\n toToolDefinitions(): AiToolDefinition[] {\n return this.listSkills().map(skillToToolDefinition);\n }\n}\n\nexport const createSkillRegistry = (initialSkills?: SkillDefinition[]): InMemorySkillRegistry => {\n return new InMemorySkillRegistry(initialSkills);\n};\n"]}
@@ -0,0 +1,35 @@
1
+ // src/auth/legacy/utils/authUtils.ts
2
+ function validatePhoneNumber(phone) {
3
+ return /^1[3-9]\d{9}$/.test(phone);
4
+ }
5
+ function validatePassword(password) {
6
+ if (!password) {
7
+ return { valid: false, message: "\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A" };
8
+ }
9
+ if (password.length < 6) {
10
+ return { valid: false, message: "\u5BC6\u7801\u957F\u5EA6\u81F3\u5C116\u4F4D" };
11
+ }
12
+ return { valid: true };
13
+ }
14
+ function generateSessionToken() {
15
+ return Math.random().toString(36).substring(2) + Date.now().toString(36) + Math.random().toString(36).substring(2);
16
+ }
17
+ function isAdmin(user) {
18
+ return user?.role === "admin";
19
+ }
20
+ function isActiveUser(user) {
21
+ return user?.isActive === true;
22
+ }
23
+ function getUserDisplayName(user) {
24
+ return user.name || user.phone || "\u672A\u77E5\u7528\u6237";
25
+ }
26
+ function calculateSessionExpiry(days = 30) {
27
+ return new Date(Date.now() + days * 24 * 60 * 60 * 1e3);
28
+ }
29
+ function isSessionExpired(expiresAt) {
30
+ return /* @__PURE__ */ new Date() > new Date(expiresAt);
31
+ }
32
+
33
+ export { calculateSessionExpiry, generateSessionToken, getUserDisplayName, isActiveUser, isAdmin, isSessionExpired, validatePassword, validatePhoneNumber };
34
+ //# sourceMappingURL=chunk-DA4QV64P.mjs.map
35
+ //# sourceMappingURL=chunk-DA4QV64P.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/legacy/utils/authUtils.ts"],"names":[],"mappings":";AAKO,SAAS,oBAAoB,KAAA,EAAwB;AAC1D,EAAA,OAAO,eAAA,CAAgB,KAAK,KAAK,CAAA;AACnC;AAKO,SAAS,iBAAiB,QAAA,EAAwD;AACvF,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,sCAAA,EAAS;AAAA,EAC3C;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,6CAAA,EAAW;AAAA,EAC7C;AAEA,EAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AACvB;AAKO,SAAS,oBAAA,GAA+B;AAE7C,EAAA,OAAO,IAAA,CAAK,QAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAC,CAAA,GACtC,IAAA,CAAK,GAAA,GAAM,QAAA,CAAS,EAAE,IACtB,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAC,CAAA;AAC/C;AAKO,SAAS,QAAQ,IAAA,EAA4B;AAClD,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AAKO,SAAS,aAAa,IAAA,EAA4B;AACvD,EAAA,OAAO,MAAM,QAAA,KAAa,IAAA;AAC5B;AAKO,SAAS,mBAAmB,IAAA,EAAoB;AACrD,EAAA,OAAO,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,KAAA,IAAS,0BAAA;AACpC;AAKO,SAAS,sBAAA,CAAuB,OAAe,EAAA,EAAU;AAC9D,EAAA,OAAO,IAAI,KAAK,IAAA,CAAK,GAAA,KAAQ,IAAA,GAAO,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAI,CAAA;AACzD;AAKO,SAAS,iBAAiB,SAAA,EAA0B;AACzD,EAAA,uBAAO,IAAI,IAAA,EAAK,GAAI,IAAI,KAAK,SAAS,CAAA;AACxC","file":"chunk-DA4QV64P.mjs","sourcesContent":["import type { User } from '../types';\n\n/**\n * 验证手机号格式\n */\nexport function validatePhoneNumber(phone: string): boolean {\n return /^1[3-9]\\d{9}$/.test(phone);\n}\n\n/**\n * 验证密码强度(可扩展)\n */\nexport function validatePassword(password: string): { valid: boolean; message?: string } {\n if (!password) {\n return { valid: false, message: '密码不能为空' };\n }\n \n if (password.length < 6) {\n return { valid: false, message: '密码长度至少6位' };\n }\n \n return { valid: true };\n}\n\n/**\n * 生成安全的会话令牌\n */\nexport function generateSessionToken(): string {\n // 在实际环境中,应该使用更安全的随机数生成\n return Math.random().toString(36).substring(2) + \n Date.now().toString(36) + \n Math.random().toString(36).substring(2);\n}\n\n/**\n * 检查用户是否为管理员\n */\nexport function isAdmin(user: User | null): boolean {\n return user?.role === 'admin';\n}\n\n/**\n * 检查用户是否处于活跃状态\n */\nexport function isActiveUser(user: User | null): boolean {\n return user?.isActive === true;\n}\n\n/**\n * 格式化用户显示名称\n */\nexport function getUserDisplayName(user: User): string {\n return user.name || user.phone || '未知用户';\n}\n\n/**\n * 计算会话过期时间\n */\nexport function calculateSessionExpiry(days: number = 30): Date {\n return new Date(Date.now() + days * 24 * 60 * 60 * 1000);\n}\n\n/**\n * 检查会话是否过期\n */\nexport function isSessionExpired(expiresAt: Date): boolean {\n return new Date() > new Date(expiresAt);\n} "]}