@agentunion/kite 1.3.2 → 1.5.0

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 (293) hide show
  1. package/CHANGELOG.md +302 -0
  2. package/cli.js +119 -4
  3. package/core/dependency_checker.py +250 -0
  4. package/core/env_checker.py +490 -0
  5. package/dependencies_lock.json +128 -0
  6. package/extensions/agents/assistant/entry.py +111 -1
  7. package/extensions/agents/assistant/server.py +279 -215
  8. package/extensions/channels/acp_channel/entry.py +111 -1
  9. package/extensions/channels/acp_channel/module.md +23 -22
  10. package/extensions/channels/acp_channel/server.py +279 -215
  11. package/extensions/event_hub_bench/entry.py +107 -1
  12. package/extensions/services/backup/entry.py +306 -21
  13. package/extensions/services/backup/module.md +24 -22
  14. package/extensions/services/evol/auth_manager.py +443 -0
  15. package/extensions/services/evol/config.yaml +149 -0
  16. package/extensions/services/evol/config_loader.py +117 -0
  17. package/extensions/services/evol/entry.py +406 -0
  18. package/extensions/services/evol/evol_api.py +173 -0
  19. package/extensions/services/evol/evol_config.json5 +29 -0
  20. package/extensions/services/evol/migrate_tokens.py +122 -0
  21. package/extensions/services/evol/module.md +32 -0
  22. package/extensions/services/evol/pairing.py +250 -0
  23. package/extensions/services/evol/pairing_codes.jsonl +1 -0
  24. package/extensions/services/evol/relay.py +682 -0
  25. package/extensions/services/evol/relay_config.json5 +67 -0
  26. package/extensions/services/evol/routes/__init__.py +1 -0
  27. package/extensions/services/evol/routes/routes_management_ws.py +127 -0
  28. package/extensions/services/evol/routes/routes_rpc.py +89 -0
  29. package/extensions/services/evol/routes/routes_test.py +61 -0
  30. package/extensions/services/evol/server.py +875 -0
  31. package/extensions/services/evol/static/css/style.css +1200 -0
  32. package/extensions/services/evol/static/index.html +781 -0
  33. package/extensions/services/evol/static/index_evol.html +14 -0
  34. package/extensions/services/evol/static/js/app.js +6304 -0
  35. package/extensions/services/evol/static/js/auth.js +326 -0
  36. package/extensions/services/evol/static/js/dialog.js +285 -0
  37. package/extensions/services/evol/static/js/evol-app-fixed.js +50 -0
  38. package/extensions/services/evol/static/js/evol-app.js +1949 -0
  39. package/extensions/services/evol/static/js/evol-app.js.bak +1800 -0
  40. package/extensions/services/evol/static/js/kernel-client-example.js +228 -0
  41. package/extensions/services/evol/static/js/kernel-client.js +396 -0
  42. package/extensions/services/evol/static/js/main.js +141 -0
  43. package/extensions/services/evol/static/js/registry-tests.js +585 -0
  44. package/extensions/services/evol/static/js/stats.js +217 -0
  45. package/extensions/services/evol/static/js/token-manager.js +175 -0
  46. package/extensions/services/evol/static/pairing.html +248 -0
  47. package/extensions/services/evol/static/test_registry.html +262 -0
  48. package/extensions/services/evol/static/test_relay.html +462 -0
  49. package/extensions/services/evol/stats_manager.py +240 -0
  50. package/extensions/services/model_service/entry.py +167 -19
  51. package/extensions/services/model_service/module.md +21 -22
  52. package/extensions/services/proxy/.claude/settings.local.json +13 -0
  53. package/extensions/services/proxy/CHANGELOG_20260308.md +258 -0
  54. package/extensions/services/proxy/_fix_prints.py +133 -0
  55. package/extensions/services/proxy/_fix_prints2.py +87 -0
  56. package/extensions/services/proxy/agentcp/LICENCE +178 -0
  57. package/extensions/services/proxy/agentcp/README copy.md +85 -0
  58. package/extensions/services/proxy/agentcp/README.md +260 -0
  59. package/extensions/services/proxy/agentcp/__init__.py +16 -0
  60. package/extensions/services/proxy/agentcp/agent.py +4 -0
  61. package/extensions/services/proxy/agentcp/agentcp.py +2494 -0
  62. package/extensions/services/proxy/agentcp/agentprofile.json +89 -0
  63. package/extensions/services/proxy/agentcp/ap/__init__.py +16 -0
  64. package/extensions/services/proxy/agentcp/ap/ap_client.py +316 -0
  65. package/extensions/services/proxy/agentcp/assets/images/wechat_qr.png +0 -0
  66. package/extensions/services/proxy/agentcp/backup/metrics.json +31 -0
  67. package/extensions/services/proxy/agentcp/base/__init__.py +20 -0
  68. package/extensions/services/proxy/agentcp/base/auth_client.py +257 -0
  69. package/extensions/services/proxy/agentcp/base/client.py +112 -0
  70. package/extensions/services/proxy/agentcp/base/env.py +34 -0
  71. package/extensions/services/proxy/agentcp/base/html_util.py +336 -0
  72. package/extensions/services/proxy/agentcp/base/log.py +98 -0
  73. package/extensions/services/proxy/agentcp/ca/__init__.py +17 -0
  74. package/extensions/services/proxy/agentcp/ca/ca_client.py +414 -0
  75. package/extensions/services/proxy/agentcp/ca/ca_root.py +74 -0
  76. package/extensions/services/proxy/agentcp/context/__init__.py +20 -0
  77. package/extensions/services/proxy/agentcp/context/context.py +73 -0
  78. package/extensions/services/proxy/agentcp/context/exceptions.py +114 -0
  79. package/extensions/services/proxy/agentcp/create_profile.py +125 -0
  80. package/extensions/services/proxy/agentcp/create_profile_weather.py +125 -0
  81. package/extensions/services/proxy/agentcp/db/__init__.py +15 -0
  82. package/extensions/services/proxy/agentcp/db/db_mananger.py +550 -0
  83. package/extensions/services/proxy/agentcp/docs/UDP_HEARTBEAT_FIX_REPORT.md +265 -0
  84. package/extensions/services/proxy/agentcp/docs/heartbeat_issue_analysis.md +291 -0
  85. package/extensions/services/proxy/agentcp/file/__init__.py +16 -0
  86. package/extensions/services/proxy/agentcp/file/file_client.py +141 -0
  87. package/extensions/services/proxy/agentcp/file/wss_binary_message.py +137 -0
  88. package/extensions/services/proxy/agentcp/hcp.py +299 -0
  89. package/extensions/services/proxy/agentcp/heartbeat/__init__.py +16 -0
  90. package/extensions/services/proxy/agentcp/heartbeat/heartbeat_client.py +360 -0
  91. package/extensions/services/proxy/agentcp/improved_scheduler.py +498 -0
  92. package/extensions/services/proxy/agentcp/llm_agent_utils.py +249 -0
  93. package/extensions/services/proxy/agentcp/llm_server.py +172 -0
  94. package/extensions/services/proxy/agentcp/mermaid.py +210 -0
  95. package/extensions/services/proxy/agentcp/message.py +149 -0
  96. package/extensions/services/proxy/agentcp/metrics.py +256 -0
  97. package/extensions/services/proxy/agentcp/monitoring/__init__.py +20 -0
  98. package/extensions/services/proxy/agentcp/monitoring/global_monitor.py +27 -0
  99. package/extensions/services/proxy/agentcp/monitoring/metrics_store.py +325 -0
  100. package/extensions/services/proxy/agentcp/monitoring/monitoring_service.py +269 -0
  101. package/extensions/services/proxy/agentcp/monitoring/sliding_window.py +222 -0
  102. package/extensions/services/proxy/agentcp/monitoring/standalone_reader.py +224 -0
  103. package/extensions/services/proxy/agentcp/msg/__init__.py +21 -0
  104. package/extensions/services/proxy/agentcp/msg/connection_manager.py +456 -0
  105. package/extensions/services/proxy/agentcp/msg/message_client.py +2058 -0
  106. package/extensions/services/proxy/agentcp/msg/message_serialize.py +263 -0
  107. package/extensions/services/proxy/agentcp/msg/open_ai_message.py +88 -0
  108. package/extensions/services/proxy/agentcp/msg/session_manager.py +1062 -0
  109. package/extensions/services/proxy/agentcp/msg/stream_client.py +267 -0
  110. package/extensions/services/proxy/agentcp/msg/websocket_file_receiver.py +89 -0
  111. package/extensions/services/proxy/agentcp/msg/ws_logger.py +685 -0
  112. package/extensions/services/proxy/agentcp/msg/wss_binary_message.py +137 -0
  113. package/extensions/services/proxy/agentcp/requirements.txt +7 -0
  114. package/extensions/services/proxy/agentcp/samples/agent_graph/README.md +37 -0
  115. package/extensions/services/proxy/agentcp/samples/agent_graph/agentprofile.json +89 -0
  116. package/extensions/services/proxy/agentcp/samples/agent_graph/create_profile.py +138 -0
  117. package/extensions/services/proxy/agentcp/samples/agent_graph/main.py +164 -0
  118. package/extensions/services/proxy/agentcp/samples/agent_use/create_profile.py +123 -0
  119. package/extensions/services/proxy/agentcp/samples/agent_use/llm/create_profile.py +129 -0
  120. package/extensions/services/proxy/agentcp/samples/agent_use/llm/env.json +5 -0
  121. package/extensions/services/proxy/agentcp/samples/agent_use/llm/main.py +146 -0
  122. package/extensions/services/proxy/agentcp/samples/agent_use/main.py +123 -0
  123. package/extensions/services/proxy/agentcp/samples/agent_use/readme.md +379 -0
  124. package/extensions/services/proxy/agentcp/samples/agent_use/search/create_profile.py +129 -0
  125. package/extensions/services/proxy/agentcp/samples/agent_use/search/main.py +28 -0
  126. package/extensions/services/proxy/agentcp/samples/agent_use/tool/create_profile.py +129 -0
  127. package/extensions/services/proxy/agentcp/samples/agent_use/tool/main.py +20 -0
  128. package/extensions/services/proxy/agentcp/samples/ali_amap/README.md +97 -0
  129. package/extensions/services/proxy/agentcp/samples/ali_amap/amap_agent.py +88 -0
  130. package/extensions/services/proxy/agentcp/samples/ali_amap/create_profile.py +125 -0
  131. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/powershell.py +228 -0
  132. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/software.py +63 -0
  133. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/tools.py +36 -0
  134. package/extensions/services/proxy/agentcp/samples/compute_agent/browser_user.py +41 -0
  135. package/extensions/services/proxy/agentcp/samples/deepseek/README.md +79 -0
  136. package/extensions/services/proxy/agentcp/samples/deepseek/create_profile.py +126 -0
  137. package/extensions/services/proxy/agentcp/samples/deepseek/deepseek.py +42 -0
  138. package/extensions/services/proxy/agentcp/samples/dify_chat/README.md +78 -0
  139. package/extensions/services/proxy/agentcp/samples/dify_chat/create_profile.py +126 -0
  140. package/extensions/services/proxy/agentcp/samples/dify_chat/dify_chat.py +47 -0
  141. package/extensions/services/proxy/agentcp/samples/dify_workflow/README.md +78 -0
  142. package/extensions/services/proxy/agentcp/samples/dify_workflow/create_profile.py +126 -0
  143. package/extensions/services/proxy/agentcp/samples/dify_workflow/dify_workflow.py +46 -0
  144. package/extensions/services/proxy/agentcp/samples/executor/README.md +44 -0
  145. package/extensions/services/proxy/agentcp/samples/executor/agentprofile.json +89 -0
  146. package/extensions/services/proxy/agentcp/samples/executor/create_profile.py +139 -0
  147. package/extensions/services/proxy/agentcp/samples/executor/main.py +160 -0
  148. package/extensions/services/proxy/agentcp/samples/filereader/README.md +45 -0
  149. package/extensions/services/proxy/agentcp/samples/filereader/agentprofile.json +90 -0
  150. package/extensions/services/proxy/agentcp/samples/filereader/create_profile.py +137 -0
  151. package/extensions/services/proxy/agentcp/samples/filereader/main.py +253 -0
  152. package/extensions/services/proxy/agentcp/samples/filewriter/README.md +38 -0
  153. package/extensions/services/proxy/agentcp/samples/filewriter/agentprofile.json +91 -0
  154. package/extensions/services/proxy/agentcp/samples/filewriter/create_profile.py +138 -0
  155. package/extensions/services/proxy/agentcp/samples/filewriter/main.py +289 -0
  156. package/extensions/services/proxy/agentcp/samples/hcp/README.md +85 -0
  157. package/extensions/services/proxy/agentcp/samples/hcp/acp_weather_agent.zip +0 -0
  158. package/extensions/services/proxy/agentcp/samples/hcp/create_profile.py +125 -0
  159. package/extensions/services/proxy/agentcp/samples/hcp/hcp.py +237 -0
  160. package/extensions/services/proxy/agentcp/samples/helloworld/README.md +68 -0
  161. package/extensions/services/proxy/agentcp/samples/helloworld/hello_world.py +40 -0
  162. package/extensions/services/proxy/agentcp/samples/llm_agent/MEADME.md +117 -0
  163. package/extensions/services/proxy/agentcp/samples/llm_agent/create_profile.py +125 -0
  164. package/extensions/services/proxy/agentcp/samples/llm_agent/qwen_agent.py +136 -0
  165. package/extensions/services/proxy/agentcp/samples/local_llm_agent/README.md +90 -0
  166. package/extensions/services/proxy/agentcp/samples/local_llm_agent/create_profile.py +125 -0
  167. package/extensions/services/proxy/agentcp/samples/local_llm_agent/main.py +49 -0
  168. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/README.md +55 -0
  169. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/create_profile.py +125 -0
  170. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/main.py +23 -0
  171. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/README.md +103 -0
  172. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/create_profile.py +125 -0
  173. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/main.py +69 -0
  174. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/README.md +58 -0
  175. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/create_profile.py +125 -0
  176. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/main.py +25 -0
  177. package/extensions/services/proxy/agentcp/samples/qwen3/README.md +71 -0
  178. package/extensions/services/proxy/agentcp/samples/qwen3/create_profile.py +126 -0
  179. package/extensions/services/proxy/agentcp/samples/qwen3/qwen3.py +37 -0
  180. package/extensions/services/proxy/agentcp/samples/qwen3_tools/README.md +133 -0
  181. package/extensions/services/proxy/agentcp/samples/qwen3_tools/create_profile.py +126 -0
  182. package/extensions/services/proxy/agentcp/samples/qwen3_tools/qwen3_tools.py +98 -0
  183. package/extensions/services/proxy/agentcp/samples/search/create_profile_qwen.py +125 -0
  184. package/extensions/services/proxy/agentcp/samples/search/create_profile_search.py +125 -0
  185. package/extensions/services/proxy/agentcp/samples/search/qwen_agent.py +136 -0
  186. package/extensions/services/proxy/agentcp/samples/search/search_agent.py +170 -0
  187. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/README.md +89 -0
  188. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/create_profile.py +125 -0
  189. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/main.py +44 -0
  190. package/extensions/services/proxy/agentcp/utils/__init__.py +15 -0
  191. package/extensions/services/proxy/agentcp/utils/file_util.py +117 -0
  192. package/extensions/services/proxy/agentcp/utils/proxy_bypass.py +99 -0
  193. package/extensions/services/proxy/agentcp/workflow.py +203 -0
  194. package/extensions/services/proxy/console_auth.py +109 -0
  195. package/extensions/services/proxy/evol/__init__.py +1 -0
  196. package/extensions/services/proxy/evol/config.py +37 -0
  197. package/extensions/services/proxy/evol/http/__init__.py +1 -0
  198. package/extensions/services/proxy/evol/http/async_http.py +551 -0
  199. package/extensions/services/proxy/evol/log.py +28 -0
  200. package/extensions/services/proxy/evol/presenter/__init__.py +2 -0
  201. package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +1031 -0
  202. package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +106 -0
  203. package/extensions/services/proxy/evol/presenter/configPresenter.py +1281 -0
  204. package/extensions/services/proxy/evol/presenter/userPresenter.py +477 -0
  205. package/extensions/services/proxy/evol/server/__init__.py +1 -0
  206. package/extensions/services/proxy/evol/server/claude_proxy_async.py +3430 -0
  207. package/extensions/services/proxy/evol/server/openclaw_proxy.py +1861 -0
  208. package/extensions/services/proxy/evol/server/proxy_config.py +15 -0
  209. package/extensions/services/proxy/evol/server/proxy_engine.py +501 -0
  210. package/extensions/services/proxy/evol/version.py +24 -0
  211. package/extensions/services/proxy/logs/websocket.log +260 -0
  212. package/extensions/services/proxy/main.py +240 -0
  213. package/extensions/services/proxy/requirements.txt +13 -0
  214. package/extensions/services/proxy/server.py +271 -0
  215. package/extensions/services/watchdog/entry.py +215 -26
  216. package/extensions/services/watchdog/module.md +1 -0
  217. package/extensions/services/watchdog/monitor.py +178 -38
  218. package/extensions/services/web/WEBSOCKET_STATUS.md +143 -0
  219. package/extensions/services/web/config_example.py +35 -0
  220. package/extensions/services/web/config_loader.py +110 -0
  221. package/extensions/services/web/entry.py +114 -26
  222. package/extensions/services/web/module.md +35 -24
  223. package/extensions/services/web/pairing.py +250 -0
  224. package/extensions/services/web/pairing_codes.jsonl +16 -0
  225. package/extensions/services/web/relay.py +643 -0
  226. package/extensions/services/web/relay_config.json5 +67 -0
  227. package/extensions/services/web/routes/routes_management_ws.py +127 -0
  228. package/extensions/services/web/routes/routes_rpc.py +89 -0
  229. package/extensions/services/web/routes/routes_test.py +61 -0
  230. package/extensions/services/web/routes/schemas.py +0 -22
  231. package/extensions/services/web/server.py +434 -99
  232. package/extensions/services/web/static/css/style.css +67 -28
  233. package/extensions/services/web/static/index.html +234 -44
  234. package/extensions/services/web/static/js/app.js +1335 -48
  235. package/extensions/services/web/static/js/kernel-client-example.js +161 -0
  236. package/extensions/services/web/static/js/kernel-client.js +383 -0
  237. package/extensions/services/web/static/js/registry-tests.js +558 -0
  238. package/extensions/services/web/static/js/token-manager.js +175 -0
  239. package/extensions/services/web/static/pairing.html +248 -0
  240. package/extensions/services/web/static/test_registry.html +262 -0
  241. package/extensions/services/web/web_config.json5 +29 -0
  242. package/kernel/entry.py +120 -32
  243. package/kernel/event_hub.py +141 -16
  244. package/kernel/module.md +60 -33
  245. package/kernel/registry_store.py +45 -36
  246. package/kernel/rpc_router.py +152 -59
  247. package/kernel/server.py +322 -26
  248. package/kite_cli/__init__.py +3 -0
  249. package/kite_cli/__main__.py +5 -0
  250. package/kite_cli/commands/__init__.py +1 -0
  251. package/kite_cli/commands/clean.py +101 -0
  252. package/kite_cli/commands/deps_install.py +67 -0
  253. package/kite_cli/commands/doctor.py +35 -0
  254. package/kite_cli/commands/env_check.py +45 -0
  255. package/kite_cli/commands/history.py +111 -0
  256. package/kite_cli/commands/info.py +96 -0
  257. package/kite_cli/commands/install.py +313 -0
  258. package/kite_cli/commands/list.py +143 -0
  259. package/kite_cli/commands/log.py +81 -0
  260. package/kite_cli/commands/prepare.py +49 -0
  261. package/kite_cli/commands/rollback.py +88 -0
  262. package/kite_cli/commands/search.py +73 -0
  263. package/kite_cli/commands/uninstall.py +85 -0
  264. package/kite_cli/commands/update.py +118 -0
  265. package/kite_cli/commands/venv_setup.py +56 -0
  266. package/kite_cli/core/__init__.py +1 -0
  267. package/kite_cli/core/checker.py +142 -0
  268. package/kite_cli/core/dependency.py +229 -0
  269. package/kite_cli/core/downloader.py +209 -0
  270. package/kite_cli/core/install_info.py +40 -0
  271. package/kite_cli/core/tool_installer.py +397 -0
  272. package/kite_cli/core/validator.py +78 -0
  273. package/kite_cli/main.py +317 -0
  274. package/kite_cli/utils/__init__.py +1 -0
  275. package/kite_cli/utils/i18n.py +252 -0
  276. package/kite_cli/utils/interactive.py +63 -0
  277. package/kite_cli/utils/operation_log.py +77 -0
  278. package/kite_cli/utils/paths.py +34 -0
  279. package/kite_cli/utils/version.py +308 -0
  280. package/launcher/entry.py +1124 -178
  281. package/launcher/logging_setup.py +104 -0
  282. package/launcher/module.md +46 -37
  283. package/launcher/module_scanner.py +11 -1
  284. package/main.py +4 -1
  285. package/package.json +9 -1
  286. package/python_version.json +4 -0
  287. package/requirements.txt +38 -0
  288. package/scripts/env-manager.js +328 -0
  289. package/scripts/plan_manager.py +315 -0
  290. package/scripts/python-env.js +79 -0
  291. package/scripts/scan_dependencies.py +461 -0
  292. package/scripts/setup-python-env.js +191 -0
  293. package/extensions/services/web/routes/routes_modules.py +0 -249
@@ -0,0 +1,122 @@
1
+ """
2
+ 迁移工具:将旧的 token 文件转换为 JSONL 格式
3
+
4
+ 使用方法:
5
+ python migrate_tokens.py
6
+ """
7
+
8
+ import json
9
+ import os
10
+ import sys
11
+
12
+
13
+ def migrate_kite_tokens(data_dir: str):
14
+ """迁移 Kite Token 文件格式"""
15
+ auth_dir = os.path.join(data_dir, "auth")
16
+ old_file = os.path.join(auth_dir, "kite_tokens.json")
17
+ new_file = os.path.join(auth_dir, "kite_tokens.jsonl")
18
+ backup_file = os.path.join(auth_dir, "kite_tokens.json.backup")
19
+
20
+ if not os.path.exists(old_file):
21
+ print(f"Kite tokens 旧文件不存在: {old_file}")
22
+ return False
23
+
24
+ if os.path.exists(new_file):
25
+ print(f"Kite tokens 新文件已存在: {new_file}")
26
+ return False
27
+
28
+ try:
29
+ with open(old_file, "r", encoding="utf-8") as f:
30
+ data = json.load(f)
31
+ tokens = data.get("tokens", [])
32
+ except Exception as e:
33
+ print(f"读取 Kite tokens 旧文件失败: {e}")
34
+ return False
35
+
36
+ if not tokens:
37
+ print("Kite tokens 旧文件中没有记录")
38
+ return False
39
+
40
+ print(f"找到 {len(tokens)} 个 Kite Token 记录")
41
+
42
+ try:
43
+ with open(new_file, "w", encoding="utf-8") as f:
44
+ for token in tokens:
45
+ token["action"] = "migrated"
46
+ token["timestamp"] = token.get("createdAt", 0)
47
+ f.write(json.dumps(token, ensure_ascii=False) + "\n")
48
+ print(f"成功写入 Kite tokens 新文件: {new_file}")
49
+ except Exception as e:
50
+ print(f"写入 Kite tokens 新文件失败: {e}")
51
+ return False
52
+
53
+ try:
54
+ os.rename(old_file, backup_file)
55
+ print(f"Kite tokens 旧文件已备份到: {backup_file}")
56
+ except Exception as e:
57
+ print(f"备份 Kite tokens 旧文件失败: {e}")
58
+
59
+ return True
60
+
61
+
62
+ def migrate_evol_token(data_dir: str):
63
+ """迁移 Evol Token 文件格式"""
64
+ auth_dir = os.path.join(data_dir, "auth")
65
+ old_file = os.path.join(auth_dir, "evol_token.json")
66
+ new_file = os.path.join(auth_dir, "evol_tokens.jsonl")
67
+ backup_file = os.path.join(auth_dir, "evol_token.json.backup")
68
+
69
+ if not os.path.exists(old_file):
70
+ print(f"Evol token 旧文件不存在: {old_file}")
71
+ return False
72
+
73
+ if os.path.exists(new_file):
74
+ print(f"Evol token 新文件已存在: {new_file}")
75
+ return False
76
+
77
+ try:
78
+ with open(old_file, "r", encoding="utf-8") as f:
79
+ record = json.load(f)
80
+ except Exception as e:
81
+ print(f"读取 Evol token 旧文件失败: {e}")
82
+ return False
83
+
84
+ print(f"找到 Evol Token 记录: {record.get('phone', 'unknown')}")
85
+
86
+ try:
87
+ record["action"] = "migrated"
88
+ record["timestamp"] = record.get("obtainedAt", 0)
89
+ record["lastUsedAt"] = record.get("obtainedAt", 0)
90
+
91
+ with open(new_file, "w", encoding="utf-8") as f:
92
+ f.write(json.dumps(record, ensure_ascii=False) + "\n")
93
+ print(f"成功写入 Evol token 新文件: {new_file}")
94
+ except Exception as e:
95
+ print(f"写入 Evol token 新文件失败: {e}")
96
+ return False
97
+
98
+ try:
99
+ os.rename(old_file, backup_file)
100
+ print(f"Evol token 旧文件已备份到: {backup_file}")
101
+ except Exception as e:
102
+ print(f"备份 Evol token 旧文件失败: {e}")
103
+
104
+ return True
105
+
106
+
107
+ if __name__ == "__main__":
108
+ data_dir = os.environ.get("KITE_DATA", os.path.expanduser("~/.kite/data"))
109
+ evol_data_dir = os.path.join(data_dir, "evol")
110
+
111
+ print(f"数据目录: {evol_data_dir}")
112
+ print()
113
+
114
+ kite_ok = migrate_kite_tokens(evol_data_dir)
115
+ print()
116
+ evol_ok = migrate_evol_token(evol_data_dir)
117
+ print()
118
+
119
+ if kite_ok or evol_ok:
120
+ print("迁移完成!")
121
+ else:
122
+ print("没有需要迁移的文件")
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: evol
3
+ display_name: Evol Account Management
4
+ version: '1.0'
5
+ type: service
6
+ state: enabled
7
+ runtime: python
8
+ entry: entry.py
9
+ preferred_port: 18766
10
+ advertise_ip: 0.0.0.0
11
+ display_order: 90
12
+ businesses:
13
+ - name: relay_service
14
+ type: relay
15
+ description: Kernel WebSocket relay service for web clients
16
+ config_file: relay_config.json5
17
+ ---
18
+
19
+ # Evol 模块
20
+
21
+ Evol AI 平台账户管理模块。
22
+
23
+ ## 功能
24
+
25
+ - 手机号短信登录
26
+ - 用户信息查看
27
+ - 积分监控与统计
28
+ - 设备管理
29
+
30
+ ## 端口
31
+
32
+ 默认端口:18766
@@ -0,0 +1,250 @@
1
+ """
2
+ 配对码管理模块
3
+
4
+ 负责配对码的生成、验证、使用和 frontend_token 的管理。
5
+
6
+ 零共享代码依赖 - 此文件可以独立拷贝到其他模块使用。
7
+ """
8
+
9
+ import json
10
+ import os
11
+ import secrets
12
+ import string
13
+ import time
14
+ from datetime import datetime, timezone
15
+ from typing import Optional
16
+
17
+
18
+ class PairingManager:
19
+ """配对码管理器"""
20
+
21
+ def __init__(self, pairing_file: str, code_length: int = 6, token_expiry: int = 2592000):
22
+ """
23
+ 初始化配对码管理器。
24
+
25
+ Args:
26
+ pairing_file: 配对码文件路径(JSONL 格式)
27
+ code_length: 配对码长度(默认 6)
28
+ token_expiry: frontend_token 有效期(秒,默认 30 天)
29
+ """
30
+ self.pairing_file = pairing_file
31
+ self.code_length = code_length
32
+ self.token_expiry = token_expiry
33
+
34
+ # 临时配对码(未持久化)
35
+ self.pending_codes = {} # {code: {"role": "admin", "created_at": timestamp}}
36
+
37
+ # 确保文件存在
38
+ if not os.path.exists(pairing_file):
39
+ os.makedirs(os.path.dirname(pairing_file), exist_ok=True)
40
+
41
+ def generate_pairing_code(self, role: str = "admin") -> str:
42
+ """
43
+ 生成临时配对码(不持久化)。
44
+
45
+ Args:
46
+ role: 用户角色
47
+
48
+ Returns:
49
+ 配对码
50
+ """
51
+ code = self._generate_code()
52
+ self.pending_codes[code] = {
53
+ "role": role,
54
+ "created_at": time.time()
55
+ }
56
+
57
+ # 清理过期的配对码(超过 5 分钟)
58
+ self._cleanup_expired_codes()
59
+
60
+ return code
61
+
62
+ def _cleanup_expired_codes(self):
63
+ """清理过期的临时配对码"""
64
+ now = time.time()
65
+ expired = [
66
+ code for code, info in self.pending_codes.items()
67
+ if now - info["created_at"] > 300 # 5 分钟
68
+ ]
69
+ for code in expired:
70
+ del self.pending_codes[code]
71
+
72
+ def _ensure_active_code(self):
73
+ """确保有 active 状态的配对码,如果没有则生成(已废弃)"""
74
+ pass
75
+
76
+ def _print_pairing_code(self, code: str, is_new: bool):
77
+ """在控制台绿色高亮显示配对码(已废弃,改为通过事件发送给 Launcher)"""
78
+ pass
79
+
80
+ def _create_initial_code(self):
81
+ """创建初始配对码(已废弃,由 _ensure_active_code 替代)"""
82
+ pass
83
+
84
+ def _generate_code(self) -> str:
85
+ """生成随机配对码"""
86
+ chars = string.ascii_uppercase + string.digits
87
+ return ''.join(secrets.choice(chars) for _ in range(self.code_length))
88
+
89
+ def _generate_token(self) -> str:
90
+ """生成 frontend_token"""
91
+ return "tok_" + secrets.token_urlsafe(32)
92
+
93
+ def _read_codes(self) -> list[dict]:
94
+ """读取所有配对码记录"""
95
+ if not os.path.exists(self.pairing_file):
96
+ return []
97
+
98
+ codes = []
99
+ with open(self.pairing_file, "r", encoding="utf-8") as f:
100
+ for line in f:
101
+ line = line.strip()
102
+ if line:
103
+ try:
104
+ codes.append(json.loads(line))
105
+ except json.JSONDecodeError:
106
+ pass
107
+ return codes
108
+
109
+ def _write_code(self, code_record: dict):
110
+ """追加配对码记录"""
111
+ with open(self.pairing_file, "a", encoding="utf-8") as f:
112
+ f.write(json.dumps(code_record, ensure_ascii=False) + "\n")
113
+
114
+ def verify_code(self, code: str) -> Optional[dict]:
115
+ """
116
+ 验证配对码(包括临时配对码和持久化配对码)。
117
+
118
+ Args:
119
+ code: 配对码
120
+
121
+ Returns:
122
+ 如果有效,返回配对码信息(包含 role);否则返回 None
123
+ """
124
+ # 先检查临时配对码
125
+ if code in self.pending_codes:
126
+ info = self.pending_codes[code]
127
+ # 检查是否过期(5 分钟)
128
+ if time.time() - info["created_at"] < 300:
129
+ return {"code": code, "role": info["role"], "status": "pending"}
130
+
131
+ # 再检查持久化配对码(向后兼容)
132
+ codes = self._read_codes()
133
+ for record in reversed(codes):
134
+ if record.get("code") == code and record.get("status") == "active":
135
+ return record
136
+
137
+ return None
138
+
139
+ def pair(self, code: str) -> Optional[dict]:
140
+ """
141
+ 使用配对码进行配对。
142
+
143
+ Args:
144
+ code: 配对码
145
+
146
+ Returns:
147
+ 如果成功,返回 {"token": "...", "role": "..."};否则返回 None
148
+ """
149
+ # 验证配对码
150
+ code_info = self.verify_code(code)
151
+ if not code_info:
152
+ return None
153
+
154
+ # 生成 frontend_token
155
+ token = self._generate_token()
156
+ role = code_info.get("role", "viewer")
157
+
158
+ # 持久化保存 token
159
+ used_record = {
160
+ "code": code,
161
+ "role": role,
162
+ "status": "used",
163
+ "token": token,
164
+ "paired_at": datetime.now(timezone.utc).isoformat(),
165
+ "expires_at": datetime.fromtimestamp(
166
+ time.time() + self.token_expiry, tz=timezone.utc
167
+ ).isoformat()
168
+ }
169
+ self._write_code(used_record)
170
+
171
+ # 从临时配对码中删除
172
+ if code in self.pending_codes:
173
+ del self.pending_codes[code]
174
+
175
+ return {
176
+ "token": token,
177
+ "role": role,
178
+ "expires_at": used_record["expires_at"]
179
+ }
180
+
181
+ def verify_token(self, token: str) -> Optional[dict]:
182
+ """
183
+ 验证 frontend_token。
184
+
185
+ Args:
186
+ token: frontend_token
187
+
188
+ Returns:
189
+ 如果有效,返回 {"role": "...", "expires_at": "..."};否则返回 None
190
+ """
191
+ codes = self._read_codes()
192
+
193
+ # 检查 token 是否被吊销
194
+ for record in reversed(codes):
195
+ if record.get("token") == token and record.get("status") == "revoked":
196
+ return None # Token 已被吊销
197
+
198
+ # 查找 token 对应的记录
199
+ for record in reversed(codes):
200
+ if record.get("token") == token and record.get("status") == "used":
201
+ # 检查是否过期
202
+ expires_at = record.get("expires_at")
203
+ if expires_at:
204
+ expire_time = datetime.fromisoformat(expires_at)
205
+ if datetime.now(timezone.utc) < expire_time:
206
+ return {
207
+ "role": record.get("role", "viewer"),
208
+ "expires_at": expires_at
209
+ }
210
+
211
+ return None
212
+
213
+ def renew_token(self, old_token: str) -> Optional[str]:
214
+ """
215
+ 续期 frontend_token。
216
+
217
+ Args:
218
+ old_token: 旧的 frontend_token
219
+
220
+ Returns:
221
+ 如果成功,返回新的 token;否则返回 None
222
+ """
223
+ # 验证旧 token
224
+ token_info = self.verify_token(old_token)
225
+ if not token_info:
226
+ return None
227
+
228
+ # 生成新 token
229
+ new_token = self._generate_token()
230
+ role = token_info["role"]
231
+
232
+ # 写入新 token 记录
233
+ new_record = {
234
+ "token": new_token,
235
+ "role": role,
236
+ "status": "used",
237
+ "renewed_from": old_token,
238
+ "paired_at": datetime.now(timezone.utc).isoformat(),
239
+ "expires_at": datetime.fromtimestamp(
240
+ time.time() + self.token_expiry, tz=timezone.utc
241
+ ).isoformat()
242
+ }
243
+ self._write_code(new_record)
244
+
245
+ return new_token
246
+
247
+ def get_active_codes(self) -> list[dict]:
248
+ """获取所有 active 状态的配对码"""
249
+ codes = self._read_codes()
250
+ return [c for c in codes if c.get("status") == "active"]
@@ -0,0 +1 @@
1
+ {"code": "EAJU5I", "role": "admin", "status": "used", "token": "tok_eO59UiqTxQZvUXKPMkLzV293iwQR2EfU806I_4wjuqc", "paired_at": "2026-03-08T13:25:35.375089+00:00", "expires_at": "2026-04-07T13:25:35.375099+00:00"}