@agentunion/kite 1.5.0 → 1.6.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 (574) hide show
  1. package/.claude/skills/kite/checklists/feature-checklist.md +496 -0
  2. package/.claude/skills/kite/references/event-patterns.md +180 -0
  3. package/.claude/skills/kite/references/health-check.md +202 -0
  4. package/.claude/skills/kite/references/http-service.md +199 -0
  5. package/.claude/skills/kite/references/module-md-spec.md +172 -0
  6. package/.claude/skills/kite/references/multi-connection.md +147 -0
  7. package/.claude/skills/kite/references/rpc-patterns.md +199 -0
  8. package/.claude/skills/kite/references/shutdown-sequence.md +146 -0
  9. package/.claude/skills/kite/references/stdin-protocol.md +147 -0
  10. package/.claude/skills/kite/references/test-center-integration.md +178 -0
  11. package/.claude/skills/kite/references/ws-lifecycle.md +301 -0
  12. package/.claude/skills/kite/skill.md +272 -0
  13. package/.claude/skills/kite/templates/go/README.md +20 -0
  14. package/.claude/skills/kite/templates/node/entry.js +134 -0
  15. package/.claude/skills/kite/templates/node/module.md +16 -0
  16. package/.claude/skills/kite/templates/node/server.js +351 -0
  17. package/.claude/skills/kite/templates/node/server_http.js +90 -0
  18. package/.claude/skills/kite/templates/python/entry.py +425 -0
  19. package/.claude/skills/kite/templates/python/module.md +26 -0
  20. package/.claude/skills/kite/templates/python/server.py +447 -0
  21. package/.claude/skills/kite/templates/python/server_http.py +433 -0
  22. package/cli.js +38 -4
  23. package/core/env_checker.py +96 -0
  24. package/docs/05-/347/237/255/344/277/241/350/256/244/350/257/201/344/270/216/347/224/250/346/210/267/344/277/241/346/201/257/346/216/245/345/217/243/346/226/207/346/241/243.md +507 -0
  25. package/docs/ACP/345/215/217/350/256/256/345/205/274/345/256/271/346/226/271/346/241/210.md +138 -0
  26. package/docs/CI/344/270/216AI/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/346/226/271/346/241/210.md +75 -0
  27. package/docs/CLI/345/274/200/345/217/221/350/256/241/345/210/222.md +595 -0
  28. package/docs/ClaudeCode/350/277/234/347/250/213/345/215/217/344/275/234/347/263/273/347/273/237-/346/212/200/346/234/257/350/257/204/344/274/260.md +535 -0
  29. package/docs/ClaudeCode/350/277/234/347/250/213/345/215/217/344/275/234/347/263/273/347/273/237/350/256/276/350/256/241.md +631 -0
  30. package/docs/Evol-App/344/275/277/347/224/250KernelClient/346/224/271/351/200/240/345/256/214/346/210/220.md +342 -0
  31. package/docs/Evol/346/216/247/345/210/266/345/217/260/346/217/222/344/273/266/345/214/226/346/236/266/346/236/204/346/246/202/350/246/201.md +604 -0
  32. package/docs/Evol/346/216/247/345/210/266/345/217/260/346/217/222/344/273/266/345/214/226/346/236/266/346/236/204/350/256/276/350/256/241.md +1708 -0
  33. package/docs/Evol/346/250/241/345/235/227/350/256/276/350/256/241/346/226/271/346/241/210.md +1154 -0
  34. package/docs/Evol/351/241/265/351/235/242/346/217/222/344/273/266/345/214/226-Evol/346/250/241/345/235/227/345/256/236/346/226/275/346/214/207/345/215/227.md +403 -0
  35. package/docs/Evol/351/241/265/351/235/242/346/217/222/344/273/266/345/214/226-/345/244/226/351/203/250/346/250/241/345/235/227/346/216/245/345/205/245/346/214/207/345/215/227.md +468 -0
  36. package/docs/HTTP-RPC/350/277/201/347/247/273/345/210/260WebSocket/350/256/241/345/210/222.md +318 -0
  37. package/docs/INDEX.md +388 -0
  38. package/docs/KITE_DOCS_GUIDE.md +33 -0
  39. package/docs/Kernel-Client-Kite-Token/346/224/257/346/214/201/345/256/236/346/226/275/345/256/214/346/210/220.md +330 -0
  40. package/docs/Kernel/344/270/273/345/212/250Ping/346/234/272/345/210/266-/346/255/243/347/241/256/345/256/236/347/216/260.md +235 -0
  41. package/docs/Kernel/344/270/273/345/212/250Ping/346/234/272/345/210/266/345/256/236/346/226/275/346/200/273/347/273/223.md +204 -0
  42. package/docs/Kite/345/256/211/350/243/205/351/227/256/351/242/230/350/247/243/345/206/263/346/226/271/346/241/210.md +362 -0
  43. package/docs/Kite/346/216/247/345/210/266/345/217/260/346/217/222/344/273/266/345/214/226/346/236/266/346/236/204/350/256/276/350/256/241-/347/273/210/346/236/201/347/233/256/346/240/207.md +721 -0
  44. package/docs/Kite/346/216/247/345/210/266/345/217/260/347/273/237/344/270/200WebSocket/346/224/271/351/200/240/346/226/271/346/241/210.md +821 -0
  45. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/01-/346/241/206/346/236/266/345/256/232/344/275/215.md +12 -0
  46. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/02-/346/240/270/345/277/203/346/246/202/345/277/265.md +341 -0
  47. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/03-/347/263/273/347/273/237/346/236/266/346/236/204.md +257 -0
  48. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/04-/346/250/241/345/235/227/350/247/204/350/214/203.md +263 -0
  49. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/05-/346/240/270/345/277/203/346/265/201/347/250/213-/346/226/260/347/211/210.md +267 -0
  50. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/05-/346/240/270/345/277/203/346/265/201/347/250/213.md +149 -0
  51. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/06-/347/233/256/345/275/225/347/273/223/346/236/204.md +231 -0
  52. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/07-/346/225/260/346/215/256/346/250/241/345/236/213.md +68 -0
  53. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/08-/346/211/251/345/261/225/346/200/247.md +34 -0
  54. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/09-/344/270/216/345/205/267/344/275/223/345/272/224/347/224/250/347/232/204/345/205/263/347/263/273.md +22 -0
  55. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/README.md +46 -0
  56. package/docs/Kite/347/263/273/347/273/237/345/220/257/345/212/250/346/265/201/347/250/213.md +567 -0
  57. package/docs/Launcher/345/220/257/345/212/250/345/231/250/346/226/207/346/241/243.md +745 -0
  58. package/docs/Polyglot/350/277/220/350/241/214/346/227/266/344/270/216Clawdbot/345/205/274/345/256/271/346/200/247/350/256/276/350/256/241.md +321 -0
  59. package/docs/Redis/344/270/216/346/250/241/345/235/227/345/244/232/345/256/236/344/276/213/346/226/271/346/241/210.md +438 -0
  60. package/docs/Relay-Kite-Token/350/256/244/350/257/201/345/256/236/346/226/275/345/256/214/346/210/220.md +178 -0
  61. package/docs/Relay-Token/346/235/203/351/231/220/351/205/215/347/275/256/351/252/214/350/257/201.md +113 -0
  62. package/docs/Watchdog/345/201/245/345/272/267/346/243/200/346/237/245/344/270/216WebSocket-Ping/346/234/272/345/210/266/345/210/206/346/236/220.md +367 -0
  63. package/docs/Watchdog/350/265/204/346/272/220/347/233/221/346/216/247/347/255/226/347/225/245.md +92 -0
  64. package/docs/WebSocket/346/216/245/346/224/266/345/276/252/347/216/257/346/255/273/351/224/201/351/230/262/350/214/203/350/247/204/350/214/203.md +357 -0
  65. package/docs/WebSocket/350/277/236/346/216/245/351/237/247/346/200/247/344/270/216/351/207/215/350/277/236/346/234/272/345/210/266/345/256/214/346/225/264/346/226/271/346/241/210.md +531 -0
  66. package/docs/WebSocket/350/277/236/346/216/245/351/237/247/346/200/247/346/226/271/346/241/210.md +169 -0
  67. package/docs/WebSocket/351/207/215/350/277/236/346/234/272/345/210/266/346/265/213/350/257/225/346/212/245/345/221/212.md +169 -0
  68. package/docs/WebSocket/351/207/215/350/277/236/351/200/200/351/201/277/346/234/272/345/210/266/346/226/271/346/241/210.md +394 -0
  69. package/docs/Web/346/250/241/345/235/227/344/270/216Evol/346/250/241/345/235/227/351/207/215/346/236/204/345/210/206/346/236/220.md +521 -0
  70. package/docs/audit-api-guide.md +68 -0
  71. package/docs/audit-module-design.md +315 -0
  72. package/docs/audit-module-implementation-summary.md +149 -0
  73. package/docs/llm-context-design.md +52 -0
  74. package/docs/llm-test-enhancement-plan.md +970 -0
  75. package/docs/logs-api-guide.md +42 -0
  76. package/docs/npm/345/214/205Python/347/216/257/345/242/203/347/256/241/347/220/206/346/226/271/346/241/210.md +302 -0
  77. package/docs/npm/345/217/221/345/270/203/344/270/216CLI/344/275/277/347/224/250/346/214/207/345/215/227.md +245 -0
  78. package/docs/stdio/344/270/216/347/253/257/345/217/243/345/217/221/347/216/260/351/207/215/346/236/204.md +480 -0
  79. package/docs/web/346/250/241/345/235/227/344/270/255/350/275/254/346/234/215/345/212/241/350/256/276/350/256/241/346/226/271/346/241/210.md +449 -0
  80. package/docs//344/272/213/344/273/266/345/244/204/347/220/206/346/234/272/345/210/266.md +388 -0
  81. package/docs//344/272/213/344/273/266/345/244/204/347/220/206/350/247/204/350/214/203.md +113 -0
  82. package/docs//344/272/213/344/273/266/350/256/242/351/230/205/351/200/232/351/205/215/347/254/246/350/247/204/350/214/203.md +256 -0
  83. package/docs//344/272/213/344/273/266/351/230/237/345/210/227/345/274/271/346/200/247/347/256/241/347/220/206.md +449 -0
  84. package/docs//344/272/244/344/272/222/345/274/217/347/273/210/347/253/257/346/216/247/345/210/266/346/226/271/346/241/210.md +301 -0
  85. package/docs//344/273/243/347/220/206/345/220/257/345/212/250/345/231/250/344/270/216/345/256/271/345/231/250/345/214/226.md +140 -0
  86. package/docs//344/273/243/347/240/201/347/273/237/350/256/241/345/267/245/345/205/267/344/275/277/347/224/250/350/257/264/346/230/216.md +217 -0
  87. package/docs//344/274/230/351/233/205/351/200/200/345/207/272/350/247/204/350/214/203.md +362 -0
  88. package/docs//344/276/235/350/265/226/347/256/241/347/220/206/350/257/264/346/230/216.md +141 -0
  89. package/docs//344/277/256/345/244/215/346/235/203/351/231/220/351/227/256/351/242/230-evol-RPC/346/235/203/351/231/220.md +268 -0
  90. package/docs//345/210/240/351/231/244kernel-client-example/345/256/214/346/210/220.md +309 -0
  91. package/docs//345/210/240/351/231/244ws-management/345/256/214/346/210/220.md +418 -0
  92. package/docs//345/220/257/345/212/250/344/274/230/345/214/226/346/226/271/346/241/210.md +522 -0
  93. package/docs//345/220/257/345/212/250/344/276/235/350/265/226/344/270/216/346/216/222/345/272/217.md +105 -0
  94. package/docs//345/256/211/350/243/205/350/204/232/346/234/254/345/274/200/345/217/221/346/226/207/346/241/243.md +643 -0
  95. package/docs//345/256/214/346/225/264/345/220/257/345/212/250/346/265/201/347/250/213/350/256/276/350/256/241.md +452 -0
  96. package/docs//345/256/236/347/216/260/350/247/204/345/210/222.md +195 -0
  97. package/docs//345/277/203/350/267/263/346/234/272/345/210/266/351/207/215/346/236/204/346/200/273/347/273/223.md +166 -0
  98. package/docs//346/217/241/346/211/213/350/256/244/350/257/201/346/226/271/346/241/210-/345/256/211/345/205/250/345/256/241/346/237/245.md +176 -0
  99. package/docs//346/217/241/346/211/213/350/256/244/350/257/201/346/226/271/346/241/210.md +908 -0
  100. package/docs//346/226/207/346/241/243/346/233/264/346/226/260/346/270/205/345/215/225.md +83 -0
  101. package/docs//346/227/245/345/277/227/344/270/216/345/274/202/345/270/270/345/244/204/347/220/206/350/247/204/350/214/203.md +829 -0
  102. package/docs//346/227/245/345/277/227/350/260/203/350/257/225/345/256/236/346/210/230/346/214/207/345/215/227.md +25 -0
  103. package/docs//346/236/266/346/236/204/345/200/237/351/211/264/346/214/207/345/215/227.md +977 -0
  104. package/docs//346/236/266/346/236/204/346/224/271/351/200/240-/345/256/214/346/210/220/346/200/273/347/273/223.md +440 -0
  105. package/docs//346/236/266/346/236/204/347/216/260/347/212/266/344/270/216/347/273/210/346/236/201/347/233/256/346/240/207/345/257/271/346/257/224/345/210/206/346/236/220.md +508 -0
  106. package/docs//346/250/241/345/235/227/345/244/232/350/277/236/346/216/245/346/216/247/345/210/266/347/255/226/347/225/245.md +220 -0
  107. package/docs//346/250/241/345/235/227/345/256/211/350/243/205/346/234/272/345/210/266/350/256/276/350/256/241.md +500 -0
  108. package/docs//346/250/241/345/235/227/345/274/200/345/217/221/346/214/207/345/215/227.md +1824 -0
  109. package/docs//346/250/241/345/235/227/347/203/255/346/233/264/346/226/260.md +89 -0
  110. package/docs//346/250/241/345/235/227/350/277/234/347/250/213/351/203/250/347/275/262/345/274/200/345/217/221/350/247/204/350/214/203.md +460 -0
  111. package/docs//346/250/241/345/235/227/351/200/200/345/207/272/346/234/272/345/210/266/345/256/214/346/225/264/346/226/271/346/241/210.md +303 -0
  112. package/docs//346/250/241/345/235/227/351/205/215/347/275/256/345/212/240/350/275/275/344/270/216/347/203/255/351/207/215/350/275/275/350/247/204/350/214/203.md +369 -0
  113. package/docs//346/265/213/350/257/225/344/270/255/345/277/203/346/267/273/345/212/240/346/250/241/345/235/227/346/265/213/350/257/225/346/214/207/345/215/227.md +147 -0
  114. package/docs//347/211/210/346/234/254/351/224/201/345/256/232/347/216/257/345/242/203/347/256/241/347/220/206/346/226/271/346/241/210.md +331 -0
  115. package/docs//347/216/257/345/242/203/345/217/230/351/207/217/344/270/216/350/277/220/350/241/214/346/227/266/347/233/256/345/275/225/350/256/276/350/256/241.md +499 -0
  116. package/docs//347/216/257/345/242/203/347/256/241/347/220/206/345/256/214/346/225/264/346/226/271/346/241/210.md +334 -0
  117. package/docs//350/231/232/346/213/237/346/250/241/345/235/227/344/270/255/350/275/254/346/234/215/345/212/241/345/256/214/346/225/264/350/256/276/350/256/241.md +1496 -0
  118. package/docs//350/231/232/346/213/237/347/216/257/345/242/203/345/267/245/344/275/234/345/216/237/347/220/206.md +163 -0
  119. package/docs//350/256/241/345/210/222/347/256/241/347/220/206/345/231/250/344/275/277/347/224/250/346/214/207/345/215/227.md +196 -0
  120. package/docs//350/256/244/350/257/201/346/250/241/345/235/227/344/270/216Gateway/350/256/276/350/256/241/346/226/271/346/241/210.md +765 -0
  121. package/docs//350/277/234/347/250/213/346/250/241/345/235/227/350/256/276/350/256/241-/346/227/247/347/211/210.md +1117 -0
  122. package/docs//350/277/234/347/250/213/346/250/241/345/235/227/350/256/276/350/256/241.md +451 -0
  123. package/docs//351/207/215/346/236/204/346/234/272/345/210/266/346/270/205/345/215/225.md +192 -0
  124. package/docs//351/223/276/350/267/257/350/277/275/350/270/252/346/226/271/346/241/210.md +242 -0
  125. package/docs//351/231/215/347/272/247/347/255/226/347/225/245/350/256/276/350/256/241/346/226/271/346/241/210.md +618 -0
  126. package/extensions/agents/assistant/entry.py +113 -14
  127. package/extensions/agents/assistant/module.md +27 -22
  128. package/extensions/agents/assistant/server.py +291 -105
  129. package/extensions/channels/acp_channel/entry.py +114 -16
  130. package/extensions/channels/acp_channel/module.md +4 -0
  131. package/extensions/channels/acp_channel/server.py +396 -105
  132. package/extensions/channels/phone_channel/__init__.py +1 -0
  133. package/extensions/channels/phone_channel/entry.py +503 -0
  134. package/extensions/channels/phone_channel/module.md +31 -0
  135. package/extensions/channels/phone_channel/server.py +686 -0
  136. package/extensions/event_hub_bench/entry.py +55 -12
  137. package/extensions/event_hub_bench/module.md +27 -27
  138. package/extensions/services/audit/README.md +134 -0
  139. package/extensions/services/audit/collector.py +73 -0
  140. package/extensions/services/audit/entry.py +444 -0
  141. package/extensions/services/audit/module.md +66 -0
  142. package/extensions/services/audit/query_audit.py +111 -0
  143. package/extensions/services/audit/routes/__init__.py +1 -0
  144. package/extensions/services/audit/routes/routes_audit.py +113 -0
  145. package/extensions/services/audit/schemas/__init__.py +5 -0
  146. package/extensions/services/audit/schemas/audit_event.py +92 -0
  147. package/extensions/services/audit/server.py +542 -0
  148. package/extensions/services/audit/storage.py +95 -0
  149. package/extensions/services/auth/entry.py +1054 -0
  150. package/extensions/services/auth/module.md +31 -0
  151. package/extensions/services/auth/token_store.py +185 -0
  152. package/extensions/services/auth/verifiers/evol_account.py +101 -0
  153. package/extensions/services/auth/verifiers/kite_token.py +38 -0
  154. package/extensions/services/auth/verifiers/pairing_code.py +71 -0
  155. package/extensions/services/backup/entry.py +494 -197
  156. package/extensions/services/backup/module.md +4 -2
  157. package/extensions/services/dataclaw/api/__init__.py +0 -0
  158. package/extensions/services/dataclaw/api/admin.py +367 -0
  159. package/extensions/services/dataclaw/api/copyright.py +175 -0
  160. package/extensions/services/dataclaw/api/credits.py +177 -0
  161. package/extensions/services/dataclaw/api/data.py +179 -0
  162. package/extensions/services/dataclaw/api/demands.py +269 -0
  163. package/extensions/services/dataclaw/api/feeds.py +262 -0
  164. package/extensions/services/dataclaw/api/identity.py +505 -0
  165. package/extensions/services/dataclaw/api/notifications.py +104 -0
  166. package/extensions/services/dataclaw/api/reviews.py +138 -0
  167. package/extensions/services/dataclaw/api/search.py +153 -0
  168. package/extensions/services/dataclaw/api/subscriptions.py +157 -0
  169. package/extensions/services/dataclaw/config.json5 +96 -0
  170. package/extensions/services/dataclaw/core/__init__.py +0 -0
  171. package/extensions/services/dataclaw/core/auth.py +95 -0
  172. package/extensions/services/dataclaw/core/config.py +50 -0
  173. package/extensions/services/dataclaw/core/database.py +70 -0
  174. package/extensions/services/dataclaw/entry.py +416 -0
  175. package/extensions/services/dataclaw/gofeed/351/241/271/347/233/256/346/211/200/346/234/211/346/235/203/350/275/254/347/247/273/346/265/201/347/250/213/350/257/264/346/230/216.md +309 -0
  176. package/extensions/services/dataclaw/migrate.py +283 -0
  177. package/extensions/services/dataclaw/models/__init__.py +0 -0
  178. package/extensions/services/dataclaw/module.md +49 -0
  179. package/extensions/services/dataclaw/requirements.txt +18 -0
  180. package/extensions/services/dataclaw/server.py +759 -0
  181. package/extensions/services/dataclaw/services/__init__.py +0 -0
  182. package/extensions/services/dataclaw/services/agent_service.py +132 -0
  183. package/extensions/services/dataclaw/services/credit_service.py +235 -0
  184. package/extensions/services/dataclaw/services/email_service.py +140 -0
  185. package/extensions/services/dataclaw/services/feed_service.py +259 -0
  186. package/extensions/services/dataclaw/services/notification_service.py +209 -0
  187. package/extensions/services/dataclaw/services/oauth_service.py +275 -0
  188. package/extensions/services/dataclaw/services/pricing.py +102 -0
  189. package/extensions/services/dataclaw/services/quality.py +79 -0
  190. package/extensions/services/dataclaw/services/reputation.py +142 -0
  191. package/extensions/services/dataclaw/services/sms_service.py +174 -0
  192. package/extensions/services/dataclaw/static/css/common.css +853 -0
  193. package/extensions/services/dataclaw/static/css/themes/blue.css +42 -0
  194. package/extensions/services/dataclaw/static/css/themes/dark.css +42 -0
  195. package/extensions/services/dataclaw/static/css/themes/light.css +35 -0
  196. package/extensions/services/dataclaw/static/js/api.js +103 -0
  197. package/extensions/services/dataclaw/static/js/common.js +321 -0
  198. package/extensions/services/dataclaw/static/js/i18n.js +95 -0
  199. package/extensions/services/dataclaw/static/js/pages/admin.js +152 -0
  200. package/extensions/services/dataclaw/static/js/pages/dashboard.js +82 -0
  201. package/extensions/services/dataclaw/static/js/pages/feed-detail.js +180 -0
  202. package/extensions/services/dataclaw/static/js/pages/feed-manage.js +158 -0
  203. package/extensions/services/dataclaw/static/js/theme.js +46 -0
  204. package/extensions/services/dataclaw/static/locales/en-US.json +464 -0
  205. package/extensions/services/dataclaw/static/locales/ja-JP.json +464 -0
  206. package/extensions/services/dataclaw/static/locales/zh-CN.json +464 -0
  207. package/extensions/services/dataclaw/templates/admin/index.html +90 -0
  208. package/extensions/services/dataclaw/templates/base.html +136 -0
  209. package/extensions/services/dataclaw/templates/credits/balance.html +106 -0
  210. package/extensions/services/dataclaw/templates/credits/deposit.html +164 -0
  211. package/extensions/services/dataclaw/templates/credits/history.html +90 -0
  212. package/extensions/services/dataclaw/templates/dashboard.html +52 -0
  213. package/extensions/services/dataclaw/templates/demands/create.html +78 -0
  214. package/extensions/services/dataclaw/templates/demands/detail.html +136 -0
  215. package/extensions/services/dataclaw/templates/demands/list.html +94 -0
  216. package/extensions/services/dataclaw/templates/feeds/create.html +95 -0
  217. package/extensions/services/dataclaw/templates/feeds/detail.html +110 -0
  218. package/extensions/services/dataclaw/templates/feeds/list.html +110 -0
  219. package/extensions/services/dataclaw/templates/feeds/manage.html +88 -0
  220. package/extensions/services/dataclaw/templates/index.html +185 -0
  221. package/extensions/services/dataclaw/templates/login.html +246 -0
  222. package/extensions/services/dataclaw/templates/register.html +164 -0
  223. package/extensions/services/dataclaw/templates/settings/notifications.html +96 -0
  224. package/extensions/services/dataclaw/templates/settings/profile.html +167 -0
  225. package/extensions/services/dataclaw/templates/subscriptions/list.html +64 -0
  226. package/extensions/services/dataclaw/tests/__init__.py +0 -0
  227. package/extensions/services/dataclaw/tests/conftest.py +68 -0
  228. package/extensions/services/dataclaw/tests/integration/__init__.py +0 -0
  229. package/extensions/services/dataclaw/tests/integration/test_workflows.py +239 -0
  230. package/extensions/services/dataclaw/tests/unit/__init__.py +0 -0
  231. package/extensions/services/dataclaw/tests/unit/test_admin.py +70 -0
  232. package/extensions/services/dataclaw/tests/unit/test_copyright.py +63 -0
  233. package/extensions/services/dataclaw/tests/unit/test_credits.py +80 -0
  234. package/extensions/services/dataclaw/tests/unit/test_data.py +98 -0
  235. package/extensions/services/dataclaw/tests/unit/test_demands.py +106 -0
  236. package/extensions/services/dataclaw/tests/unit/test_feeds.py +98 -0
  237. package/extensions/services/dataclaw/tests/unit/test_identity.py +88 -0
  238. package/extensions/services/dataclaw/tests/unit/test_notifications.py +36 -0
  239. package/extensions/services/dataclaw/tests/unit/test_reviews.py +68 -0
  240. package/extensions/services/dataclaw/tests/unit/test_search.py +64 -0
  241. package/extensions/services/dataclaw/tests/unit/test_subscriptions.py +65 -0
  242. package/extensions/services/dataclaw/tests/unit/test_system.py +106 -0
  243. package/extensions/services/dataclaw/utils/__init__.py +0 -0
  244. package/extensions/services/dataclaw/utils/crypto.py +38 -0
  245. package/extensions/services/dataclaw/utils/id_generator.py +52 -0
  246. package/extensions/services/dataclaw/ws/__init__.py +0 -0
  247. package/extensions/services/dataclaw/ws/handler.py +163 -0
  248. package/extensions/services/dataclaw//345/215/217/350/256/2561-/351/241/271/347/233/256/346/235/241/344/273/266/346/216/210/346/235/203/344/270/216/350/202/241/346/235/203/345/257/271/344/273/267/345/215/217/350/256/256.md +243 -0
  249. package/extensions/services/dataclaw//345/215/217/350/256/2562-/351/241/271/347/233/256/350/264/255/344/271/260/346/235/203/344/270/216/345/244/226/345/214/205/345/247/224/346/211/230/345/274/200/345/217/221/345/215/217/350/256/256.md +434 -0
  250. package/extensions/services/evol/__init__.py +1 -0
  251. package/extensions/services/evol/async_http.py +551 -0
  252. package/extensions/services/evol/auth_manager.py +602 -443
  253. package/extensions/services/evol/config.json5 +16 -0
  254. package/extensions/services/evol/entry.py +568 -406
  255. package/extensions/services/evol/evol_api.py +969 -173
  256. package/extensions/services/evol/mfa_totp.py +77 -0
  257. package/extensions/services/evol/module.md +150 -32
  258. package/extensions/services/evol/nonce_pool.py +113 -0
  259. package/extensions/services/evol/oauth_manager.py +223 -0
  260. package/extensions/services/evol/pairing.py +3 -2
  261. package/extensions/services/evol/pairing_codes.jsonl +1 -0
  262. package/extensions/services/evol/relay.py +1031 -682
  263. package/extensions/services/evol/relay_config.json5 +85 -67
  264. package/extensions/services/evol/routes/routes_llm.py +231 -0
  265. package/extensions/services/evol/routes/routes_rpc.py +90 -89
  266. package/extensions/services/evol/routes/routes_test.py +11 -4
  267. package/extensions/services/evol/server.py +2426 -875
  268. package/extensions/services/evol/static/assets/CommissionView-Cs_ys6Gm.js +1 -0
  269. package/extensions/services/evol/static/assets/CommissionView-DACet_Oo.css +1 -0
  270. package/extensions/services/evol/static/assets/IframePage-DbO11U9G.js +1 -0
  271. package/extensions/services/evol/static/assets/IframePage-c572lT8i.css +1 -0
  272. package/extensions/services/evol/static/assets/TeamDetailView-DULrGD7k.css +1 -0
  273. package/extensions/services/evol/static/assets/TeamDetailView-gy_MBEqG.js +139 -0
  274. package/extensions/services/evol/static/assets/element-plus-Bd7pZkkM.js +63 -0
  275. package/extensions/services/evol/static/assets/index-CmMONKzG.css +1 -0
  276. package/extensions/services/evol/static/assets/index-D44bBe__.js +2 -0
  277. package/extensions/services/evol/static/assets/vue-vendor-DtF-__I4.js +29 -0
  278. package/extensions/services/evol/static/index.html +16 -781
  279. package/extensions/services/evol/static/logo.png +0 -0
  280. package/extensions/services/evol/stats_manager.py +243 -240
  281. package/extensions/services/evol/web/README.md +89 -0
  282. package/extensions/services/evol/web/build.bat +44 -0
  283. package/extensions/services/evol/web/index.html +13 -0
  284. package/extensions/services/evol/web/package-lock.json +1718 -0
  285. package/extensions/services/evol/web/package.json +26 -0
  286. package/extensions/services/evol/web/public/logo.png +0 -0
  287. package/extensions/services/evol/web/src/App.vue +7 -0
  288. package/extensions/services/evol/web/src/components/layout/AppHeader.vue +202 -0
  289. package/extensions/services/evol/web/src/components/layout/AppLayout.vue +61 -0
  290. package/extensions/services/evol/web/src/components/layout/AppSidebar.vue +115 -0
  291. package/extensions/services/evol/web/src/components/login/LoginPage.vue +271 -0
  292. package/extensions/services/evol/web/src/components/team/AddMemberModal.vue +181 -0
  293. package/extensions/services/evol/web/src/components/team/GroupTreeNode.vue +156 -0
  294. package/extensions/services/evol/web/src/components/team/TeamAlertConfig.vue +221 -0
  295. package/extensions/services/evol/web/src/components/team/TeamBillModal.vue +165 -0
  296. package/extensions/services/evol/web/src/components/team/TeamMembersAndGroups.vue +499 -0
  297. package/extensions/services/evol/web/src/components/team/TeamStatsPanel.vue +907 -0
  298. package/extensions/services/evol/web/src/components/team/TreeNode.vue +331 -0
  299. package/extensions/services/evol/web/src/components/team/stats/StatsExportProgress.vue +44 -0
  300. package/extensions/services/evol/web/src/components/team/stats/StatsHeader.vue +89 -0
  301. package/extensions/services/evol/web/src/components/team/stats/StatsMemberDetail.vue +415 -0
  302. package/extensions/services/evol/web/src/components/team/stats/StatsSummary.vue +42 -0
  303. package/extensions/services/evol/web/src/components/team/stats/helpers.ts +195 -0
  304. package/extensions/services/evol/web/src/components/team/stats/stats.css +741 -0
  305. package/extensions/services/evol/web/src/components/team/stats/useStatsApi.ts +114 -0
  306. package/extensions/services/evol/web/src/components/team/stats/useStatsCharts.ts +242 -0
  307. package/extensions/services/evol/web/src/components/team/stats/useStatsExport.ts +232 -0
  308. package/extensions/services/evol/web/src/composables/useFormatters.ts +42 -0
  309. package/extensions/services/evol/web/src/composables/useTheme.ts +52 -0
  310. package/extensions/services/evol/web/src/env.d.ts +7 -0
  311. package/extensions/services/evol/web/src/i18n/en.ts +361 -0
  312. package/extensions/services/evol/web/src/i18n/index.ts +36 -0
  313. package/extensions/services/evol/web/src/i18n/zh.ts +379 -0
  314. package/extensions/services/evol/web/src/main.ts +21 -0
  315. package/extensions/services/evol/web/src/router/index.ts +81 -0
  316. package/extensions/services/evol/web/src/services/kernel-client.ts +406 -0
  317. package/extensions/services/evol/web/src/stores/auth.ts +189 -0
  318. package/extensions/services/evol/web/src/stores/connection.ts +134 -0
  319. package/extensions/services/evol/web/src/stores/pages.ts +79 -0
  320. package/extensions/services/evol/web/src/styles/base.css +213 -0
  321. package/extensions/services/evol/web/src/styles/variables.css +138 -0
  322. package/extensions/services/evol/web/src/types/rpc.ts +35 -0
  323. package/extensions/services/evol/web/src/types/token.ts +87 -0
  324. package/extensions/services/evol/web/src/views/AccountView.vue +1532 -0
  325. package/extensions/services/evol/web/src/views/AiServiceView.vue +219 -0
  326. package/extensions/services/evol/web/src/views/CommissionView.vue +1220 -0
  327. package/extensions/services/evol/web/src/views/CreditsView.vue +131 -0
  328. package/extensions/services/evol/web/src/views/EndpointView.vue +163 -0
  329. package/extensions/services/evol/web/src/views/IframePage.vue +120 -0
  330. package/extensions/services/evol/web/src/views/TeamDetailView.vue +473 -0
  331. package/extensions/services/evol/web/src/views/TeamView.vue +332 -0
  332. package/extensions/services/evol/web/tsconfig.json +31 -0
  333. package/extensions/services/evol/web/tsconfig.node.json +10 -0
  334. package/extensions/services/evol/web/vite.config.ts +49 -0
  335. package/extensions/services/evolmem/__init__.py +0 -0
  336. package/extensions/services/evolmem/entry.py +387 -0
  337. package/extensions/services/evolmem/hooks/__init__.py +0 -0
  338. package/extensions/services/evolmem/hooks/assistant_stop.py +228 -0
  339. package/extensions/services/evolmem/hooks/common.py +76 -0
  340. package/extensions/services/evolmem/hooks/pre_tool_use.py +56 -0
  341. package/extensions/services/evolmem/hooks/session_end.py +133 -0
  342. package/extensions/services/evolmem/hooks/session_start.py +229 -0
  343. package/extensions/services/evolmem/hooks/user_prompt.py +122 -0
  344. package/extensions/services/evolmem/module.md +48 -0
  345. package/extensions/services/evolmem/prompts/00-server-info.md +28 -0
  346. package/extensions/services/evolmem/prompts/01-behavior.md +46 -0
  347. package/extensions/services/evolmem/prompts/02-summary-format.md +112 -0
  348. package/extensions/services/evolmem/prompts/03-file-query.md +92 -0
  349. package/extensions/services/evolmem/prompts/04-topic-stats.md +11 -0
  350. package/extensions/services/evolmem/prompts/05-recent-topics.md +84 -0
  351. package/extensions/services/evolmem/scripts/__init__.py +0 -0
  352. package/extensions/services/evolmem/scripts/extract_keywords.py +40 -0
  353. package/extensions/services/evolmem/scripts/search_topics.py +91 -0
  354. package/extensions/services/evolmem/server.py +641 -0
  355. package/extensions/services/gateway/entry.py +964 -0
  356. package/extensions/services/gateway/module.md +29 -0
  357. package/extensions/services/gateway/nonce_pool.py +65 -0
  358. package/extensions/services/gateway/relay.py +133 -0
  359. package/extensions/services/gateway/ws_server.py +285 -0
  360. package/extensions/services/kite_console/auth_manager.py +603 -0
  361. package/extensions/services/kite_console/config.json5 +19 -0
  362. package/extensions/services/kite_console/config_loader.py +117 -0
  363. package/extensions/services/kite_console/entry.py +528 -0
  364. package/extensions/services/kite_console/evol_api.py +179 -0
  365. package/extensions/services/kite_console/evol_config.json5 +29 -0
  366. package/extensions/services/kite_console/mfa_totp.py +77 -0
  367. package/extensions/services/kite_console/migrate_tokens.py +122 -0
  368. package/extensions/services/kite_console/module.md +37 -0
  369. package/extensions/services/kite_console/nonce_pool.py +113 -0
  370. package/extensions/services/kite_console/oauth_manager.py +223 -0
  371. package/extensions/services/kite_console/pairing.py +280 -0
  372. package/extensions/services/kite_console/pairing_codes.jsonl +2 -0
  373. package/extensions/services/kite_console/relay.py +1350 -0
  374. package/extensions/services/kite_console/relay_config.json5 +96 -0
  375. package/extensions/services/kite_console/routes/__init__.py +1 -0
  376. package/extensions/services/kite_console/routes/routes_llm.py +231 -0
  377. package/extensions/services/kite_console/routes/routes_proxy.py +115 -0
  378. package/extensions/services/kite_console/routes/routes_rpc.py +89 -0
  379. package/extensions/services/kite_console/routes/routes_test.py +68 -0
  380. package/extensions/services/kite_console/server.py +1742 -0
  381. package/extensions/services/{evol → kite_console}/static/css/style.css +656 -2
  382. package/extensions/services/kite_console/static/index.html +1524 -0
  383. package/extensions/services/{evol → kite_console}/static/js/dialog.js +11 -4
  384. package/extensions/services/kite_console/static/js/evol-app.js +7740 -0
  385. package/extensions/services/{evol/static/js/evol-app.js → kite_console/static/js/evol-app.js.backup} +2777 -1949
  386. package/extensions/services/kite_console/static/js/kernel-client.js +560 -0
  387. package/extensions/services/{evol/static/js/kernel-client.js → kite_console/static/js/kernel-client.js.backup} +41 -3
  388. package/extensions/services/{evol → kite_console}/static/js/registry-tests.js +7 -0
  389. package/extensions/services/kite_console/static/js/tests/ARCHITECTURE.md +67 -0
  390. package/extensions/services/kite_console/static/js/tests/README.md +140 -0
  391. package/extensions/services/kite_console/static/js/tests/index.js +161 -0
  392. package/extensions/services/kite_console/static/js/tests/integration/auth.js +120 -0
  393. package/extensions/services/kite_console/static/js/tests/integration/channel-interaction.js +188 -0
  394. package/extensions/services/kite_console/static/js/tests/integration/elastic-connection.js +115 -0
  395. package/extensions/services/kite_console/static/js/tests/integration/full-workflow.js +43 -0
  396. package/extensions/services/kite_console/static/js/tests/integration/multi-instance.js +304 -0
  397. package/extensions/services/kite_console/static/js/tests/integration/nested-rpc.js +266 -0
  398. package/extensions/services/kite_console/static/js/tests/integration/pingpong.js +25 -0
  399. package/extensions/services/kite_console/static/js/tests/integration/redis.js +227 -0
  400. package/extensions/services/kite_console/static/js/tests/integration/registry-core.js +52 -0
  401. package/extensions/services/kite_console/static/js/tests/integration/remote-deploy.js +85 -0
  402. package/extensions/services/kite_console/static/js/tests/integration/require-init.js +96 -0
  403. package/extensions/services/kite_console/static/js/tests/integration/scaling-control.js +193 -0
  404. package/extensions/services/kite_console/static/js/tests/integration/trace.js +109 -0
  405. package/extensions/services/kite_console/static/js/tests/modules/acp_channel.js +339 -0
  406. package/extensions/services/kite_console/static/js/tests/modules/auth.js +96 -0
  407. package/extensions/services/kite_console/static/js/tests/modules/backup.js +49 -0
  408. package/extensions/services/kite_console/static/js/tests/modules/gateway.js +41 -0
  409. package/extensions/services/kite_console/static/js/tests/modules/kernel.js +90 -0
  410. package/extensions/services/kite_console/static/js/tests/modules/launcher.js +75 -0
  411. package/extensions/services/kite_console/static/js/tests/modules/multi_instance.js +129 -0
  412. package/extensions/services/kite_console/static/js/tests/modules/phone_channel.js +364 -0
  413. package/extensions/services/kite_console/static/js/tests/modules/redis.js +178 -0
  414. package/extensions/services/kite_console/static/js/tests/modules/watchdog.js +60 -0
  415. package/extensions/services/kite_console/static/js/tests/modules/web.js +70 -0
  416. package/extensions/services/kite_console/static/js/tests/test-runner.js +123 -0
  417. package/extensions/services/kite_console/static/js/virtual-list.js +200 -0
  418. package/extensions/services/kite_console/static/test_kernel_client_token.html +352 -0
  419. package/extensions/services/kite_console/stats_manager.py +247 -0
  420. package/extensions/services/logs/README.md +215 -0
  421. package/extensions/services/logs/api_logger.py +37 -0
  422. package/extensions/services/logs/baseline.py +121 -0
  423. package/extensions/services/logs/cleaner.py +76 -0
  424. package/extensions/services/logs/entry.py +449 -0
  425. package/extensions/services/logs/formatter.py +129 -0
  426. package/extensions/services/logs/module.md +38 -0
  427. package/extensions/services/logs/quick_diagnostic.py +128 -0
  428. package/extensions/services/logs/routes/__init__.py +1 -0
  429. package/extensions/services/logs/routes/routes_logs.py +218 -0
  430. package/extensions/services/logs/routes/routes_logs.py.backup +173 -0
  431. package/extensions/services/logs/scanner.py +100 -0
  432. package/extensions/services/logs/searcher.py +263 -0
  433. package/extensions/services/logs/server.py +553 -0
  434. package/extensions/services/logs.zip +0 -0
  435. package/extensions/services/model_service/config.json5 +30 -0
  436. package/extensions/services/model_service/entry.py +620 -171
  437. package/extensions/services/model_service/module.md +11 -2
  438. package/extensions/services/proxy/__init__.py +0 -0
  439. package/extensions/services/proxy/aid_manager.py +419 -0
  440. package/extensions/services/proxy/auth_bridge.py +182 -0
  441. package/extensions/services/proxy/config_store.py +79 -0
  442. package/extensions/services/proxy/entry.py +528 -0
  443. package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +2 -2
  444. package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +18 -28
  445. package/extensions/services/proxy/evol/presenter/configPresenter.py +80 -1127
  446. package/extensions/services/proxy/evol/presenter/userPresenter.py +71 -477
  447. package/extensions/services/proxy/evol/server/claude_proxy_async.py +11 -7
  448. package/extensions/services/proxy/module.md +151 -0
  449. package/extensions/services/proxy/server.py +952 -271
  450. package/extensions/services/redis/ALIGNMENT_CHECKLIST.md +121 -0
  451. package/extensions/services/redis/ALIGNMENT_STATUS.md +548 -0
  452. package/extensions/services/redis/config.json5 +8 -0
  453. package/extensions/services/redis/entry.py +1509 -0
  454. package/extensions/services/redis/entry.py.backup +405 -0
  455. package/extensions/services/redis/module.md +48 -0
  456. package/extensions/services/redis/redis_builtin.py +332 -0
  457. package/extensions/services/redis/redis_external.py +164 -0
  458. package/extensions/services/testUi/entry.py +446 -0
  459. package/extensions/services/testUi/module.md +18 -0
  460. package/extensions/services/testUi/ui/cards.html +131 -0
  461. package/extensions/services/testUi/ui/index.html +22 -0
  462. package/extensions/services/testUi/ui/particles.html +143 -0
  463. package/extensions/services/watchdog/entry.py +1258 -793
  464. package/extensions/services/watchdog/module.md +2 -0
  465. package/extensions/services/watchdog/monitor.py +465 -87
  466. package/extensions/services/web/auth_manager.py +602 -0
  467. package/extensions/services/web/config.json5 +11 -0
  468. package/extensions/services/web/entry.py +598 -478
  469. package/extensions/services/web/mfa_totp.py +77 -0
  470. package/extensions/services/web/module.md +16 -13
  471. package/extensions/services/web/nonce_pool.py +113 -0
  472. package/extensions/services/web/oauth_manager.py +223 -0
  473. package/extensions/services/web/pairing.py +3 -2
  474. package/extensions/services/web/pairing_codes.jsonl +1 -0
  475. package/extensions/services/web/relay.py +442 -63
  476. package/extensions/services/web/relay_config.json5 +1 -2
  477. package/extensions/services/web/routes/routes_rpc.py +6 -6
  478. package/extensions/services/web/server.py +360 -173
  479. package/extensions/services/web/static/index.html +1752 -1738
  480. package/extensions/services/web/static/js/app.js +32 -0
  481. package/extensions/services/web/static/js/kernel-client.js +48 -9
  482. package/extensions/services/web/vendor/bluetooth/audio.py +1 -1
  483. package/extensions/services/web/vendor/config.py +2 -2
  484. package/extensions/services/web/vendor/storage/identity.py +1 -1
  485. package/kernel/entry.py +77 -23
  486. package/kernel/event_hub.py +1122 -74
  487. package/kernel/module.md +2 -1
  488. package/kernel/registry_store.py +208 -11
  489. package/kernel/rpc_router.py +1400 -491
  490. package/kernel/server.py +1021 -134
  491. package/kite_cli/__init__.py +9 -1
  492. package/kite_cli/builders/__init__.py +4 -0
  493. package/kite_cli/builders/base.py +67 -0
  494. package/kite_cli/builders/custom.py +31 -0
  495. package/kite_cli/builders/detector.py +56 -0
  496. package/kite_cli/builders/go.py +34 -0
  497. package/kite_cli/builders/gradle.py +41 -0
  498. package/kite_cli/builders/maven.py +36 -0
  499. package/kite_cli/builders/npm.py +44 -0
  500. package/kite_cli/builders/python.py +37 -0
  501. package/kite_cli/commands/BUILD_GUIDE.md +109 -0
  502. package/kite_cli/commands/build.py +142 -0
  503. package/kite_cli/commands/check.py +60 -0
  504. package/kite_cli/commands/config.py +156 -0
  505. package/kite_cli/commands/deps.py +58 -0
  506. package/kite_cli/commands/deps_install.py +7 -7
  507. package/kite_cli/commands/disable.py +162 -0
  508. package/kite_cli/commands/enable.py +162 -0
  509. package/kite_cli/commands/export.py +96 -0
  510. package/kite_cli/commands/import_cmd.py +110 -0
  511. package/kite_cli/commands/install.py +50 -23
  512. package/kite_cli/commands/install_skill.py +107 -0
  513. package/kite_cli/commands/list.py +128 -31
  514. package/kite_cli/commands/outdated.py +202 -0
  515. package/kite_cli/commands/search.py +33 -17
  516. package/kite_cli/commands/update.py +115 -2
  517. package/kite_cli/commands/venv_setup.py +6 -6
  518. package/kite_cli/commands/why.py +48 -0
  519. package/kite_cli/core/config_manager.py +145 -0
  520. package/kite_cli/core/downloader.py +32 -2
  521. package/kite_cli/main.py +153 -7
  522. package/kite_cli/utils/colors.py +153 -0
  523. package/kite_cli/utils/dependency_graph.py +209 -0
  524. package/kite_cli/utils/process.py +55 -0
  525. package/kite_cli/utils/progress.py +207 -0
  526. package/kite_cli/utils/table.py +101 -0
  527. package/launcher/count_lines.py +192 -43
  528. package/launcher/entry.py +4543 -2802
  529. package/launcher/logging_setup.py +54 -1
  530. package/launcher/module.md +32 -6
  531. package/launcher/module_scanner.py +93 -20
  532. package/launcher/process_manager.py +355 -76
  533. package/main.py +6 -0
  534. package/package.json +4 -1
  535. package/requirements.txt +41 -38
  536. package/scripts/auto-fix-deps.py +128 -0
  537. package/scripts/env-manager.js +25 -2
  538. package/scripts/final-test.js +78 -0
  539. package/scripts/setup-python-env.js +700 -191
  540. package/scripts/test-alluser.js +48 -0
  541. package/scripts/test-different-version.js +86 -0
  542. package/scripts/test-direct.js +63 -0
  543. package/scripts/test-extract-installer.js +28 -0
  544. package/scripts/test-install-log.js +54 -0
  545. package/scripts/test-installer.js +39 -0
  546. package/scripts/test-integration.js +250 -0
  547. package/scripts/test-real-install.js +210 -0
  548. package/scripts/test-targetdir.js +49 -0
  549. package/scripts/test-venv-real.js +47 -0
  550. package/scripts/test-venv-simple.js +57 -0
  551. package/scripts/test-wait.js +49 -0
  552. package/scripts/test-with-log.js +63 -0
  553. package/extensions/services/evol/config.yaml +0 -149
  554. package/extensions/services/evol/routes/routes_management_ws.py +0 -127
  555. package/extensions/services/evol/static/index_evol.html +0 -14
  556. package/extensions/services/evol/static/js/app.js +0 -6304
  557. package/extensions/services/evol/static/js/auth.js +0 -326
  558. package/extensions/services/evol/static/js/evol-app-fixed.js +0 -50
  559. package/extensions/services/evol/static/js/evol-app.js.bak +0 -1800
  560. package/extensions/services/evol/static/js/kernel-client-example.js +0 -228
  561. package/extensions/services/evol/static/js/main.js +0 -141
  562. package/extensions/services/evol/static/js/stats.js +0 -217
  563. package/extensions/services/evol/static/js/token-manager.js +0 -175
  564. package/extensions/services/proxy/CHANGELOG_20260308.md +0 -258
  565. package/extensions/services/proxy/_fix_prints.py +0 -133
  566. package/extensions/services/proxy/_fix_prints2.py +0 -87
  567. package/extensions/services/proxy/console_auth.py +0 -109
  568. package/extensions/services/proxy/logs/websocket.log +0 -260
  569. package/extensions/services/proxy/main.py +0 -240
  570. package/extensions/services/proxy/requirements.txt +0 -13
  571. package/extensions/services/web/config.yaml +0 -149
  572. /package/extensions/services/{evol → kite_console}/static/pairing.html +0 -0
  573. /package/extensions/services/{evol → kite_console}/static/test_registry.html +0 -0
  574. /package/extensions/services/{evol → kite_console}/static/test_relay.html +0 -0
@@ -0,0 +1,759 @@
1
+ """
2
+ DataClaw V2.0 主服务器
3
+ """
4
+ import asyncio
5
+ import json
6
+ import os
7
+ import time
8
+ import uuid
9
+ from contextlib import asynccontextmanager
10
+ from pathlib import Path
11
+ from typing import Optional
12
+
13
+ import uvicorn
14
+ import websockets
15
+ from fastapi import FastAPI, Request, Response
16
+ from fastapi.middleware.cors import CORSMiddleware
17
+ from fastapi.responses import HTMLResponse, JSONResponse
18
+ from fastapi.staticfiles import StaticFiles
19
+ from fastapi.templating import Jinja2Templates
20
+
21
+ _THIS_DIR = Path(__file__).parent
22
+
23
+ # 预导入所有 API routers(避免在 uvicorn 启动时导入)
24
+ import sys
25
+ sys.path.insert(0, str(_THIS_DIR))
26
+
27
+ _api_routers = {}
28
+
29
+ try:
30
+ from api.identity import router as identity_router
31
+ _api_routers['identity'] = identity_router
32
+ except ImportError as e:
33
+ print(f"[dataclaw] WARNING: identity router not loaded: {e}")
34
+
35
+ try:
36
+ from api.feeds import router as feeds_router
37
+ _api_routers['feeds'] = feeds_router
38
+ except ImportError as e:
39
+ print(f"[dataclaw] WARNING: feeds router not loaded: {e}")
40
+
41
+ try:
42
+ from api.data import router as data_router
43
+ _api_routers['data'] = data_router
44
+ except ImportError as e:
45
+ print(f"[dataclaw] WARNING: data router not loaded: {e}")
46
+
47
+ try:
48
+ from api.subscriptions import router as subs_router
49
+ _api_routers['subscriptions'] = subs_router
50
+ except ImportError as e:
51
+ print(f"[dataclaw] WARNING: subscriptions router not loaded: {e}")
52
+
53
+ try:
54
+ from api.search import router as search_router
55
+ _api_routers['search'] = search_router
56
+ except ImportError as e:
57
+ print(f"[dataclaw] WARNING: search router not loaded: {e}")
58
+
59
+ try:
60
+ from api.demands import router as demands_router
61
+ _api_routers['demands'] = demands_router
62
+ except ImportError as e:
63
+ print(f"[dataclaw] WARNING: demands router not loaded: {e}")
64
+
65
+ try:
66
+ from api.credits import router as credits_router
67
+ _api_routers['credits'] = credits_router
68
+ except ImportError as e:
69
+ print(f"[dataclaw] WARNING: credits router not loaded: {e}")
70
+
71
+ try:
72
+ from api.reviews import router as reviews_router
73
+ _api_routers['reviews'] = reviews_router
74
+ except ImportError as e:
75
+ print(f"[dataclaw] WARNING: reviews router not loaded: {e}")
76
+
77
+ try:
78
+ from api.notifications import router as notif_router
79
+ _api_routers['notifications'] = notif_router
80
+ except ImportError as e:
81
+ print(f"[dataclaw] WARNING: notifications router not loaded: {e}")
82
+
83
+ try:
84
+ from api.copyright import router as copyright_router
85
+ _api_routers['copyright'] = copyright_router
86
+ except ImportError as e:
87
+ print(f"[dataclaw] WARNING: copyright router not loaded: {e}")
88
+
89
+ try:
90
+ from api.admin import router as admin_router
91
+ _api_routers['admin'] = admin_router
92
+ except ImportError as e:
93
+ print(f"[dataclaw] WARNING: admin router not loaded: {e}")
94
+
95
+ try:
96
+ from ws.handler import router as ws_router
97
+ _api_routers['ws'] = ws_router
98
+ except ImportError as e:
99
+ print(f"[dataclaw] WARNING: ws router not loaded: {e}")
100
+
101
+ class DataClawServer:
102
+ def __init__(self, token: str, kernel_port: int, advertise_ip: str, port: int, data_dir: str = "", max_connections: int = 1,
103
+ gateway_url: str = "", kite_token: str = "", module_config: dict = None):
104
+ self.token = token
105
+ self.kernel_port = kernel_port
106
+ self.advertise_ip = advertise_ip
107
+ self.port = port
108
+ self.data_dir = data_dir
109
+ self.max_connections = max_connections
110
+ self.module_config = module_config or {}
111
+ self.gateway_url = gateway_url
112
+ self.kite_token = kite_token
113
+ self._ws: Optional[websockets.WebSocketClientProtocol] = None
114
+ self._ws_task: Optional[asyncio.Task] = None
115
+ self._pending_rpc: dict = {}
116
+ self._shutdown = False
117
+ self._exit_code = 0
118
+ self._auth_failed = False
119
+ self._uv_server = None # 由 entry.py 设置,用于优雅退出
120
+ self._config = {}
121
+ self._t0 = time.monotonic()
122
+ self._extra_ws: dict = {} # slot → WebSocket
123
+ self._extra_ws_tasks: dict = {} # slot → recv loop Task
124
+ self._has_registered = False
125
+
126
+ def build_app(self) -> FastAPI:
127
+ @asynccontextmanager
128
+ async def lifespan(app: FastAPI):
129
+ # 启动时
130
+ await self._startup()
131
+ yield
132
+ # 关闭时
133
+ await self._shutdown_cleanup()
134
+
135
+ app = FastAPI(
136
+ title="DataClaw API",
137
+ version="2.0.0",
138
+ description="Agent 数据共享平台 — 一次采集,万次复用",
139
+ lifespan=lifespan,
140
+ docs_url="/docs",
141
+ redoc_url="/redoc",
142
+ openapi_url="/v1/openapi.json",
143
+ )
144
+
145
+ app.add_middleware(
146
+ CORSMiddleware,
147
+ allow_origins=["*"],
148
+ allow_credentials=True,
149
+ allow_methods=["*"],
150
+ allow_headers=["*"],
151
+ )
152
+
153
+ self._register_routes(app)
154
+ return app
155
+
156
+ async def _startup(self):
157
+ """初始化:加载配置、连接数据库、启动 WS 连接 Kernel"""
158
+ from core.config import init_config
159
+ from core.database import init_db
160
+ from core.auth import configure_jwt
161
+
162
+ # 1. 加载配置(通过 module_config 的 business_config)
163
+ self._config = init_config(self.module_config)
164
+
165
+ # 2. 初始化数据库
166
+ db_cfg = self._config.get("database", {})
167
+ init_db(db_cfg)
168
+
169
+ # 3. 配置 JWT
170
+ jwt_cfg = self._config.get("jwt", {})
171
+ configure_jwt(
172
+ secret=jwt_cfg.get("secret_key", "dataclaw-secret"),
173
+ algorithm=jwt_cfg.get("algorithm", "HS256"),
174
+ expire_hours=jwt_cfg.get("access_token_expire_hours", 24),
175
+ )
176
+
177
+ # 4. 连接 Kernel WebSocket(如果有 kernel_port)
178
+ if self.kernel_port:
179
+ self._ws_task = asyncio.create_task(self._ws_loop())
180
+
181
+ elapsed = int((time.monotonic() - self._t0) * 1000)
182
+ print(f"[dataclaw] startup complete in {elapsed}ms")
183
+
184
+ async def _shutdown_cleanup(self):
185
+ self._shutdown = True
186
+ if self._ws_task:
187
+ self._ws_task.cancel()
188
+ # 关闭所有附加连接
189
+ for _s, _w in list(self._extra_ws.items()):
190
+ try:
191
+ await _w.close(code=1000, reason="shutdown")
192
+ except Exception:
193
+ pass
194
+ for _t in self._extra_ws_tasks.values():
195
+ _t.cancel()
196
+ self._extra_ws.clear()
197
+ self._extra_ws_tasks.clear()
198
+ from core.database import close_db
199
+ await close_db()
200
+ print("[dataclaw] shutdown complete")
201
+
202
+ async def _ws_loop(self):
203
+ """维持与 Kernel 的 WebSocket 长连接"""
204
+ ws_url = f"ws://127.0.0.1:{self.kernel_port}/ws?id=dataclaw"
205
+ backoff = 1.0
206
+ conn_refused_count = 0
207
+ while not self._shutdown:
208
+ try:
209
+ async with websockets.connect(
210
+ ws_url,
211
+ ping_interval=30,
212
+ ping_timeout=10,
213
+ close_timeout=5,
214
+ ) as ws:
215
+ self._ws = ws
216
+ backoff = 1.0
217
+ conn_refused_count = 0
218
+ print(f"[dataclaw] connected to kernel at port {self.kernel_port}")
219
+
220
+ # 启动 receiver task,确保连接阶段的 RPC 响应也能被处理
221
+ recv_task = asyncio.create_task(self._receiver_loop(ws))
222
+
223
+ try:
224
+ # 认证
225
+ auth_resp = await self._rpc_call(ws, "auth", {"token": self.token}, timeout=5.0)
226
+ if "error" in auth_resp:
227
+ print(f"[dataclaw] auth failed: {auth_resp['error']}")
228
+ self._auth_failed = True
229
+ self._exit_code = 1
230
+ break
231
+
232
+ # subscribe/register/module.ready 由 _do_init 在收到 system.require_init 后执行
233
+
234
+ # 等待 receiver task 结束(连接断开时自然退出)
235
+ await recv_task
236
+ finally:
237
+ recv_task.cancel()
238
+ # 断连清理:取消所有 pending RPC futures
239
+ for _rid, _fut in self._pending_rpc.items():
240
+ if not _fut.done():
241
+ _fut.cancel()
242
+ self._pending_rpc.clear()
243
+
244
+ except asyncio.CancelledError:
245
+ break
246
+ except (ConnectionRefusedError, ConnectionResetError, OSError) as e:
247
+ # Windows 的 [WinError 1225] 是 OSError 不是 ConnectionRefusedError
248
+ if isinstance(e, OSError) and getattr(e, 'winerror', None) != 1225 and not isinstance(e, (ConnectionRefusedError, ConnectionResetError)):
249
+ raise
250
+ if self._shutdown:
251
+ break
252
+ conn_refused_count += 1
253
+ if conn_refused_count >= 3:
254
+ print(f"[dataclaw] Kernel 持续不可达 ({conn_refused_count} 次),正常退出")
255
+ self._shutdown = True
256
+ break
257
+ print(f"[dataclaw] Kernel 连接失败,{backoff:.0f}s 后重试 ({conn_refused_count}/3)")
258
+ self._ws = None
259
+ await asyncio.sleep(backoff)
260
+ backoff = min(backoff * 2, 30)
261
+ except Exception as e:
262
+ if self._shutdown:
263
+ break
264
+ conn_refused_count += 1
265
+ if conn_refused_count >= 10:
266
+ print(f"[dataclaw] 连续 {conn_refused_count} 次连接失败,正常退出")
267
+ self._shutdown = True
268
+ break
269
+ print(f"[dataclaw] ws disconnected: {e}, retry in {backoff:.0f}s")
270
+ self._ws = None
271
+ await asyncio.sleep(backoff)
272
+ backoff = min(backoff * 2, 30)
273
+
274
+ # ws_loop 退出后,通知 uvicorn 退出
275
+ if self._uv_server:
276
+ self._uv_server.should_exit = True
277
+
278
+ async def _receiver_loop(self, ws):
279
+ """WebSocket 接收循环:分发所有消息到 _handle_ws_msg。"""
280
+ async for raw in ws:
281
+ # 检测 system.require_init 事件,触发注册流程
282
+ try:
283
+ msg = json.loads(raw)
284
+ if "method" in msg and "id" not in msg:
285
+ params = msg.get("params", {})
286
+ event = params.get("event", "")
287
+ if event == "system.require_init":
288
+ asyncio.create_task(self._do_init(ws))
289
+ continue
290
+ except Exception:
291
+ pass
292
+ asyncio.create_task(self._handle_ws_msg(ws, raw))
293
+
294
+ async def _do_init(self, ws):
295
+ """收到 system.require_init 后执行:订阅 + 注册 + module.ready"""
296
+ try:
297
+ reason = "startup" if not self._has_registered else "recovery"
298
+
299
+ # 注册
300
+ await self._rpc_call(ws, "registry.register", {
301
+ "module_id": "dataclaw",
302
+ "module_type": "service",
303
+ "launcher_id": "launcher",
304
+ "base_url": f"http://127.0.0.1:{self.port}",
305
+ "health_path": "/health",
306
+ "display": {
307
+ "urls": {
308
+ "DataClaw 数据共享平台": f"http://127.0.0.1:{self.port}"
309
+ }
310
+ },
311
+ "events_publish": {
312
+ "feed": {
313
+ "created": {"description": "新 Feed 注册"},
314
+ "data_published": {"description": "Feed 数据更新"},
315
+ },
316
+ "demand": {
317
+ "fulfilled": {"description": "需求被满足"},
318
+ },
319
+ },
320
+ "events_subscribe": ["module.exiting", "module.shutdown"],
321
+ }, wait_response=False)
322
+
323
+ # 订阅事件
324
+ await self._rpc_call(ws, "event.subscribe", {
325
+ "events": ["module.ready", "module.shutdown"],
326
+ })
327
+
328
+ # 发布 module.ready
329
+ await self._publish_event(ws, "module.ready", {
330
+ "module_id": "dataclaw",
331
+ "port": self.port,
332
+ "startup_time": round(time.monotonic() - self._t0, 3),
333
+ "graceful_shutdown": True,
334
+ "reason": reason,
335
+ })
336
+ print(f"[dataclaw] module.ready published (reason={reason})")
337
+ self._has_registered = True
338
+
339
+ # module.ready 之后异步检查数据库连通性(不阻塞启动)
340
+ asyncio.create_task(self._check_db_connectivity())
341
+ except Exception as e:
342
+ print(f"[dataclaw] _do_init failed: {e}")
343
+ self._has_registered = False
344
+
345
+ async def _check_db_connectivity(self):
346
+ """module.ready 后异步检查数据库连通性,失败时红色报错"""
347
+ from core.database import check_connection
348
+ db_ok, db_err = await check_connection()
349
+ if not db_ok:
350
+ db_cfg = self._config.get("database", {})
351
+ print(f"\033[31m[dataclaw] ✖ 数据库连接失败: {db_err}\033[0m")
352
+ print(f"\033[31m[dataclaw] 配置: {db_cfg.get('host', '?')}:{db_cfg.get('port', '?')}/{db_cfg.get('database', '?')}\033[0m")
353
+ else:
354
+ print(f"[dataclaw] ✓ 数据库连接正常")
355
+
356
+ async def _rpc_call(self, ws, method: str, params: dict = None,
357
+ wait_response: bool = True, timeout: float = 3.0) -> dict:
358
+ """JSON-RPC 2.0 request。默认等待响应。"""
359
+ rpc_id = str(uuid.uuid4())
360
+ msg = {"jsonrpc": "2.0", "id": rpc_id, "method": method}
361
+ if params:
362
+ msg["params"] = params
363
+ if not wait_response:
364
+ await ws.send(json.dumps(msg))
365
+ return {}
366
+ future = asyncio.get_event_loop().create_future()
367
+ self._pending_rpc[rpc_id] = future
368
+ await ws.send(json.dumps(msg))
369
+ try:
370
+ return await asyncio.wait_for(future, timeout=timeout)
371
+ except asyncio.TimeoutError:
372
+ self._pending_rpc.pop(rpc_id, None)
373
+ return {"error": {"code": -32000, "message": f"RPC timeout: {method} ({timeout}s)"}}
374
+
375
+ def _handle_rpc_response(self, msg: dict):
376
+ """处理 RPC 响应,匹配 pending future。"""
377
+ rpc_id = msg.get("id")
378
+ future = self._pending_rpc.pop(rpc_id, None)
379
+ if future and not future.done():
380
+ future.set_result(msg)
381
+
382
+ async def _publish_event(self, ws, event: str, data: dict = None):
383
+ """Publish event via event.publish RPC (fire-and-forget)."""
384
+ await self._rpc_call(ws, "event.publish", {
385
+ "event_id": str(uuid.uuid4()),
386
+ "event": event,
387
+ "data": data or {},
388
+ }, wait_response=False)
389
+
390
+ async def _handle_ws_msg(self, ws, raw: str):
391
+ try:
392
+ msg = json.loads(raw)
393
+ except Exception:
394
+ return
395
+ rpc_id = msg.get("id")
396
+ method = msg.get("method", "")
397
+
398
+ # Route 1: RPC 响应(有 id,无 method → 是对我们请求的回复)
399
+ if rpc_id and not method:
400
+ self._handle_rpc_response(msg)
401
+ return
402
+
403
+ # Route 2: RPC 请求(有 id + method,且不是事件通知)
404
+ if method and rpc_id and method != "event":
405
+ await self._handle_rpc_request(ws, rpc_id, method, msg.get("params", {}))
406
+ return
407
+
408
+ # Route 3: 事件推送
409
+ if method == "event":
410
+ params = msg.get("params", {})
411
+ event = params.get("event", "")
412
+ data = params.get("data", {})
413
+ if event == "system.ping":
414
+ await self._handle_ping_event(ws, data)
415
+ elif event == "module.shutdown":
416
+ await self._handle_shutdown(ws)
417
+ elif event == "module.exiting":
418
+ print(f"[dataclaw] received module.exiting, shutting down")
419
+ self._shutdown = True
420
+ elif event == "system.connection.offer":
421
+ await self._handle_connection_offer(data)
422
+ elif event == "system.connection.release":
423
+ await self._handle_connection_release(data)
424
+
425
+ async def _handle_rpc_request(self, ws, rpc_id: str, method: str, params: dict):
426
+ """处理来自 kernel 转发的 RPC 请求(如 watchdog 健康检查)。"""
427
+ handlers = {
428
+ "health": self._rpc_health,
429
+ "status": self._rpc_status,
430
+ }
431
+ handler = handlers.get(method)
432
+ if handler:
433
+ try:
434
+ result = await handler(params)
435
+ await ws.send(json.dumps({"jsonrpc": "2.0", "id": rpc_id, "result": result}))
436
+ except Exception as e:
437
+ await ws.send(json.dumps({
438
+ "jsonrpc": "2.0", "id": rpc_id,
439
+ "error": {"code": -32603, "message": str(e)}
440
+ }))
441
+ else:
442
+ await ws.send(json.dumps({
443
+ "jsonrpc": "2.0", "id": rpc_id,
444
+ "error": {"code": -32601, "message": f"Method not found: {method}"}
445
+ }))
446
+
447
+ async def _rpc_health(self, params: dict) -> dict:
448
+ """RPC: health"""
449
+ from core.database import check_connection
450
+ db_ok, db_err = await check_connection()
451
+ result = {
452
+ "status": "healthy" if db_ok else "unhealthy",
453
+ "uptime_seconds": round(time.time() - self._t0),
454
+ }
455
+ if not db_ok:
456
+ result["error"] = db_err
457
+ return result
458
+
459
+ async def _rpc_status(self, params: dict) -> dict:
460
+ """RPC: status"""
461
+ return {
462
+ "module": "dataclaw",
463
+ "status": "running",
464
+ "uptime_seconds": round(time.time() - self._t0),
465
+ }
466
+
467
+ async def _handle_ping_event(self, ws, data: dict):
468
+ """处理 system.ping 事件并回复 system.pong"""
469
+ t1 = data.get("ping_time")
470
+ t2 = time.time()
471
+ await self._publish_event(ws, "system.pong", {
472
+ "module_id": "dataclaw",
473
+ "ping_time": t1,
474
+ "pong_time": t2,
475
+ })
476
+
477
+ async def _handle_connection_offer(self, data):
478
+ """处理 Kernel 下发的 slot token,建立附加连接。"""
479
+ slots = data.get("slots", {})
480
+ for slot_str, info in slots.items():
481
+ slot = int(slot_str)
482
+ token = info.get("token", "")
483
+ if not token or slot in self._extra_ws:
484
+ continue
485
+ asyncio.create_task(self._connect_slot(slot, token))
486
+
487
+ async def _connect_slot(self, slot, token):
488
+ """建立单个 slot 附加连接。"""
489
+ ws_url = f"ws://127.0.0.1:{self.kernel_port}/ws"
490
+ try:
491
+ ws = await websockets.connect(ws_url, open_timeout=5, ping_interval=None, close_timeout=5)
492
+ auth_req = {"jsonrpc": "2.0", "id": f"auth-slot-{slot}", "method": "auth", "params": {"token": token}}
493
+ await ws.send(json.dumps(auth_req))
494
+ resp = json.loads(await asyncio.wait_for(ws.recv(), timeout=5))
495
+ if "error" in resp:
496
+ await ws.close()
497
+ return
498
+ self._extra_ws[slot] = ws
499
+ self._extra_ws_tasks[slot] = asyncio.create_task(self._slot_recv_loop(slot, ws))
500
+ print(f"[dataclaw] Slot {slot} connected")
501
+ except Exception as e:
502
+ print(f"[dataclaw] Slot {slot} connect failed: {e}")
503
+
504
+ async def _slot_recv_loop(self, slot, ws):
505
+ """附加连接的接收循环:与主连接平等处理所有消息。"""
506
+ try:
507
+ async for raw in ws:
508
+ try:
509
+ await self._handle_ws_msg(ws, raw)
510
+ except Exception as e:
511
+ print(f"[dataclaw] Slot {slot} 消息处理异常: {e}")
512
+ except Exception as e:
513
+ print(f"[dataclaw] Slot {slot} 接收循环异常: {e}")
514
+ finally:
515
+ self._extra_ws.pop(slot, None)
516
+ self._extra_ws_tasks.pop(slot, None)
517
+
518
+ async def _handle_connection_release(self, data):
519
+ """Kernel 请求释放 slot,优雅关闭。"""
520
+ for slot in data.get("slots", []):
521
+ ws = self._extra_ws.pop(slot, None)
522
+ task = self._extra_ws_tasks.pop(slot, None)
523
+ if ws:
524
+ try:
525
+ await ws.close(code=1000, reason="release")
526
+ except Exception:
527
+ pass
528
+ if task:
529
+ task.cancel()
530
+
531
+ async def _handle_shutdown(self, ws):
532
+ """Handle module.shutdown: ack → exiting → cleanup → ready → exit."""
533
+ print("[dataclaw] Received module.shutdown")
534
+ self._shutdown = True
535
+
536
+ try:
537
+ # Step 1: Send ack
538
+ await self._publish_event(ws, "module.shutdown.ack", {
539
+ "module_id": "dataclaw", "estimated_cleanup": 2,
540
+ })
541
+ print("[dataclaw] shutdown ack sent")
542
+
543
+ # Step 2: Send module.exiting
544
+ await self._publish_event(ws, "module.exiting", {
545
+ "module_id": "dataclaw", "action": "none",
546
+ })
547
+
548
+ # Step 3: Send shutdown.ready(必须在关闭连接之前发送)
549
+ await self._publish_event(ws, "module.shutdown.ready", {
550
+ "module_id": "dataclaw",
551
+ })
552
+ print("[dataclaw] Shutdown ready sent")
553
+ except Exception as e:
554
+ print(f"[dataclaw] shutdown signal send failed (WS may be closed): {e}")
555
+
556
+ # Step 4: 等待 Kernel 处理 shutdown.ready
557
+ await asyncio.sleep(0.01)
558
+
559
+ # Step 5: Cleanup - 关闭所有附加连接
560
+ for _s, _w in list(self._extra_ws.items()):
561
+ try:
562
+ await _w.close(code=1000, reason="shutdown")
563
+ except Exception:
564
+ pass
565
+ for _t in self._extra_ws_tasks.values():
566
+ _t.cancel()
567
+ self._extra_ws.clear()
568
+ self._extra_ws_tasks.clear()
569
+
570
+ # Step 6: Close main WebSocket
571
+ try:
572
+ await ws.close(code=1000, reason="Graceful shutdown")
573
+ print("[dataclaw] WebSocket closed")
574
+ except Exception as e:
575
+ print(f"[dataclaw] shutdown finalize failed (WS may be closed): {e}")
576
+
577
+ # Step 6: 通知 uvicorn 退出(无论前面是否失败都必须执行)
578
+ if self._uv_server:
579
+ self._uv_server.should_exit = True
580
+
581
+ def _register_routes(self, app: FastAPI):
582
+ """注册所有路由"""
583
+ # ── 服务发现 ──
584
+ @app.get("/.well-known/agent-data-exchange.json", tags=["discovery"])
585
+ async def discovery():
586
+ return {
587
+ "platform": "DataClaw",
588
+ "version": "2.0",
589
+ "description": "Agent 数据共享平台 — 一次采集,万次复用",
590
+ "endpoints": {
591
+ "http_api": f"http://localhost:{self.port}/v1",
592
+ "websocket": f"ws://localhost:{self.port}/ws",
593
+ },
594
+ "api_spec": f"http://localhost:{self.port}/v1/openapi.json",
595
+ "capabilities": [
596
+ "feed_registry", "data_query", "subscription",
597
+ "timeline", "demand_board", "credit_system",
598
+ "search", "review", "copyright", "websocket"
599
+ ],
600
+ "quick_start": {
601
+ "step_1_register": "POST /v1/identity/register",
602
+ "step_2_discover": "GET /v1/search/feeds?q={keyword}",
603
+ "step_3_subscribe": "POST /v1/subscriptions",
604
+ "step_4_consume": "GET /v1/timeline",
605
+ },
606
+ "rate_limits": {"anonymous": "10/min", "authenticated": "600/min"},
607
+ }
608
+
609
+ # ── 健康检查 ──
610
+ @app.get("/health", tags=["system"])
611
+ async def health():
612
+ from core.database import check_connection
613
+ db_ok, db_err = await check_connection()
614
+ result = {
615
+ "ok": db_ok,
616
+ "service": "dataclaw",
617
+ "version": "2.0",
618
+ "database": "ok" if db_ok else "error",
619
+ "uptime_ms": int((time.monotonic() - self._t0) * 1000),
620
+ }
621
+ if not db_ok:
622
+ result["database_error"] = db_err
623
+ return result
624
+
625
+ # ── 注册各模块路由 ──
626
+ self._mount_api_routes(app)
627
+ self._mount_ws_routes(app)
628
+ self._mount_static_and_pages(app)
629
+
630
+ def _mount_api_routes(self, app: FastAPI):
631
+ """挂载所有 /v1 API 路由(使用预导入的 router)"""
632
+ if 'identity' in _api_routers:
633
+ app.include_router(_api_routers['identity'], prefix="/v1/identity", tags=["identity"])
634
+
635
+ if 'feeds' in _api_routers:
636
+ app.include_router(_api_routers['feeds'], prefix="/v1/feeds", tags=["feeds"])
637
+
638
+ if 'data' in _api_routers:
639
+ app.include_router(_api_routers['data'], prefix="/v1/feeds", tags=["data"])
640
+
641
+ if 'subscriptions' in _api_routers:
642
+ app.include_router(_api_routers['subscriptions'], prefix="/v1", tags=["subscriptions"])
643
+
644
+ if 'search' in _api_routers:
645
+ app.include_router(_api_routers['search'], prefix="/v1", tags=["search"])
646
+
647
+ if 'demands' in _api_routers:
648
+ app.include_router(_api_routers['demands'], prefix="/v1/demands", tags=["demands"])
649
+
650
+ if 'credits' in _api_routers:
651
+ app.include_router(_api_routers['credits'], prefix="/v1/credits", tags=["credits"])
652
+
653
+ if 'reviews' in _api_routers:
654
+ app.include_router(_api_routers['reviews'], prefix="/v1/feeds", tags=["reviews"])
655
+
656
+ if 'notifications' in _api_routers:
657
+ app.include_router(_api_routers['notifications'], prefix="/v1/notifications", tags=["notifications"])
658
+
659
+ if 'copyright' in _api_routers:
660
+ app.include_router(_api_routers['copyright'], prefix="/v1/copyright", tags=["copyright"])
661
+
662
+ if 'admin' in _api_routers:
663
+ app.include_router(_api_routers['admin'], prefix="/v1/admin", tags=["admin"])
664
+
665
+ def _mount_ws_routes(self, app: FastAPI):
666
+ """挂载 WebSocket 端点(使用预导入的 router)"""
667
+ if 'ws' in _api_routers:
668
+ app.include_router(_api_routers['ws'])
669
+
670
+ def _mount_static_and_pages(self, app: FastAPI):
671
+ """挂载静态文件和多页面前端"""
672
+ static_dir = _THIS_DIR / "static"
673
+ templates_dir = _THIS_DIR / "templates"
674
+
675
+ if static_dir.exists():
676
+ app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
677
+
678
+ if templates_dir.exists():
679
+ templates = Jinja2Templates(directory=str(templates_dir))
680
+ self._templates = templates
681
+ self._register_page_routes(app, templates)
682
+
683
+ def _register_page_routes(self, app: FastAPI, templates: "Jinja2Templates"):
684
+ """注册多页面路由"""
685
+ @app.get("/", response_class=HTMLResponse, tags=["pages"])
686
+ async def index(request: Request):
687
+ return templates.TemplateResponse("index.html", {"request": request})
688
+
689
+ @app.get("/login", response_class=HTMLResponse, tags=["pages"])
690
+ async def login(request: Request):
691
+ return templates.TemplateResponse("login.html", {"request": request})
692
+
693
+ @app.get("/register", response_class=HTMLResponse, tags=["pages"])
694
+ async def register(request: Request):
695
+ return templates.TemplateResponse("register.html", {"request": request})
696
+
697
+ @app.get("/dashboard", response_class=HTMLResponse, tags=["pages"])
698
+ async def dashboard(request: Request):
699
+ return templates.TemplateResponse("dashboard.html", {"request": request})
700
+
701
+ @app.get("/feeds", response_class=HTMLResponse, tags=["pages"])
702
+ async def feeds_page(request: Request):
703
+ return templates.TemplateResponse("feeds/list.html", {"request": request})
704
+
705
+ @app.get("/feeds/create", response_class=HTMLResponse, tags=["pages"])
706
+ async def feeds_create(request: Request):
707
+ return templates.TemplateResponse("feeds/create.html", {"request": request})
708
+
709
+ @app.get("/feeds/{feed_id}", response_class=HTMLResponse, tags=["pages"])
710
+ async def feed_detail(request: Request, feed_id: str):
711
+ return templates.TemplateResponse("feeds/detail.html", {"request": request, "feed_id": feed_id})
712
+
713
+ @app.get("/feeds/{feed_id}/manage", response_class=HTMLResponse, tags=["pages"])
714
+ async def feed_manage(request: Request, feed_id: str):
715
+ return templates.TemplateResponse("feeds/manage.html", {"request": request, "feed_id": feed_id})
716
+
717
+ @app.get("/subscriptions", response_class=HTMLResponse, tags=["pages"])
718
+ async def subscriptions_page(request: Request):
719
+ return templates.TemplateResponse("subscriptions/list.html", {"request": request})
720
+
721
+ @app.get("/demands", response_class=HTMLResponse, tags=["pages"])
722
+ async def demands_page(request: Request):
723
+ return templates.TemplateResponse("demands/list.html", {"request": request})
724
+
725
+ @app.get("/demands/create", response_class=HTMLResponse, tags=["pages"])
726
+ async def demands_create(request: Request):
727
+ return templates.TemplateResponse("demands/create.html", {"request": request})
728
+
729
+ @app.get("/demands/{demand_id}", response_class=HTMLResponse, tags=["pages"])
730
+ async def demand_detail(request: Request, demand_id: str):
731
+ return templates.TemplateResponse("demands/detail.html", {"request": request, "demand_id": demand_id})
732
+
733
+ @app.get("/credits", response_class=HTMLResponse, tags=["pages"])
734
+ async def credits_page(request: Request):
735
+ return templates.TemplateResponse("credits/balance.html", {"request": request})
736
+
737
+ @app.get("/credits/history", response_class=HTMLResponse, tags=["pages"])
738
+ async def credits_history(request: Request):
739
+ return templates.TemplateResponse("credits/history.html", {"request": request})
740
+
741
+ @app.get("/credits/deposit", response_class=HTMLResponse, tags=["pages"])
742
+ async def credits_deposit(request: Request):
743
+ return templates.TemplateResponse("credits/deposit.html", {"request": request})
744
+
745
+ @app.get("/settings", response_class=HTMLResponse, tags=["pages"])
746
+ async def settings_page(request: Request):
747
+ return templates.TemplateResponse("settings/profile.html", {"request": request})
748
+
749
+ @app.get("/settings/api-keys", response_class=HTMLResponse, tags=["pages"])
750
+ async def settings_api_keys(request: Request):
751
+ return templates.TemplateResponse("settings/profile.html", {"request": request})
752
+
753
+ @app.get("/settings/notifications", response_class=HTMLResponse, tags=["pages"])
754
+ async def settings_notifications(request: Request):
755
+ return templates.TemplateResponse("settings/notifications.html", {"request": request})
756
+
757
+ @app.get("/admin", response_class=HTMLResponse, tags=["pages"])
758
+ async def admin_page(request: Request):
759
+ return templates.TemplateResponse("admin/index.html", {"request": request})