@agentunion/kite 1.4.0 → 1.6.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 (718) 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/CHANGELOG.md +102 -0
  23. package/cli.js +78 -5
  24. package/core/dependency_checker.py +250 -0
  25. package/core/env_checker.py +586 -0
  26. package/dependencies_lock.json +128 -0
  27. 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
  28. package/docs/ACP/345/215/217/350/256/256/345/205/274/345/256/271/346/226/271/346/241/210.md +138 -0
  29. 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
  30. package/docs/CLI/345/274/200/345/217/221/350/256/241/345/210/222.md +595 -0
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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
  36. package/docs/Evol/346/250/241/345/235/227/350/256/276/350/256/241/346/226/271/346/241/210.md +1154 -0
  37. 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
  38. 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
  39. package/docs/HTTP-RPC/350/277/201/347/247/273/345/210/260WebSocket/350/256/241/345/210/222.md +318 -0
  40. package/docs/INDEX.md +388 -0
  41. package/docs/KITE_DOCS_GUIDE.md +33 -0
  42. 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
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/README.md +46 -0
  59. package/docs/Kite/347/263/273/347/273/237/345/220/257/345/212/250/346/265/201/347/250/213.md +567 -0
  60. package/docs/Launcher/345/220/257/345/212/250/345/231/250/346/226/207/346/241/243.md +745 -0
  61. 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
  62. 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
  63. 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
  64. 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
  65. 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
  66. package/docs/Watchdog/350/265/204/346/272/220/347/233/221/346/216/247/347/255/226/347/225/245.md +92 -0
  67. 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
  68. 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
  69. package/docs/WebSocket/350/277/236/346/216/245/351/237/247/346/200/247/346/226/271/346/241/210.md +169 -0
  70. 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
  71. 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
  72. 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
  73. package/docs/audit-api-guide.md +68 -0
  74. package/docs/audit-module-design.md +315 -0
  75. package/docs/audit-module-implementation-summary.md +149 -0
  76. package/docs/llm-context-design.md +52 -0
  77. package/docs/llm-test-enhancement-plan.md +970 -0
  78. package/docs/logs-api-guide.md +42 -0
  79. 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
  80. 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
  81. 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
  82. 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
  83. package/docs//344/272/213/344/273/266/345/244/204/347/220/206/346/234/272/345/210/266.md +388 -0
  84. package/docs//344/272/213/344/273/266/345/244/204/347/220/206/350/247/204/350/214/203.md +113 -0
  85. 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
  86. 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
  87. 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
  88. 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
  89. 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
  90. package/docs//344/274/230/351/233/205/351/200/200/345/207/272/350/247/204/350/214/203.md +362 -0
  91. package/docs//344/276/235/350/265/226/347/256/241/347/220/206/350/257/264/346/230/216.md +141 -0
  92. 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
  93. package/docs//345/210/240/351/231/244kernel-client-example/345/256/214/346/210/220.md +309 -0
  94. package/docs//345/210/240/351/231/244ws-management/345/256/214/346/210/220.md +418 -0
  95. package/docs//345/220/257/345/212/250/344/274/230/345/214/226/346/226/271/346/241/210.md +522 -0
  96. 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
  97. 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
  98. 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
  99. package/docs//345/256/236/347/216/260/350/247/204/345/210/222.md +195 -0
  100. 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
  101. 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
  102. package/docs//346/217/241/346/211/213/350/256/244/350/257/201/346/226/271/346/241/210.md +908 -0
  103. package/docs//346/226/207/346/241/243/346/233/264/346/226/260/346/270/205/345/215/225.md +83 -0
  104. 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
  105. 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
  106. package/docs//346/236/266/346/236/204/345/200/237/351/211/264/346/214/207/345/215/227.md +977 -0
  107. 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
  108. 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
  109. 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
  110. 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
  111. package/docs//346/250/241/345/235/227/345/274/200/345/217/221/346/214/207/345/215/227.md +1824 -0
  112. package/docs//346/250/241/345/235/227/347/203/255/346/233/264/346/226/260.md +89 -0
  113. 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
  114. 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
  115. 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
  116. 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
  117. 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
  118. 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
  119. 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
  120. 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
  121. 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
  122. 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
  123. 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
  124. 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
  125. package/docs//350/277/234/347/250/213/346/250/241/345/235/227/350/256/276/350/256/241.md +451 -0
  126. package/docs//351/207/215/346/236/204/346/234/272/345/210/266/346/270/205/345/215/225.md +192 -0
  127. package/docs//351/223/276/350/267/257/350/277/275/350/270/252/346/226/271/346/241/210.md +242 -0
  128. 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
  129. package/extensions/agents/assistant/entry.py +113 -14
  130. package/extensions/agents/assistant/module.md +27 -22
  131. package/extensions/agents/assistant/server.py +308 -106
  132. package/extensions/channels/acp_channel/entry.py +114 -16
  133. package/extensions/channels/acp_channel/module.md +4 -0
  134. package/extensions/channels/acp_channel/server.py +412 -105
  135. package/extensions/channels/phone_channel/__init__.py +1 -0
  136. package/extensions/channels/phone_channel/entry.py +503 -0
  137. package/extensions/channels/phone_channel/module.md +31 -0
  138. package/extensions/channels/phone_channel/server.py +686 -0
  139. package/extensions/event_hub_bench/entry.py +55 -12
  140. package/extensions/event_hub_bench/module.md +27 -27
  141. package/extensions/services/audit/README.md +134 -0
  142. package/extensions/services/audit/collector.py +73 -0
  143. package/extensions/services/audit/entry.py +444 -0
  144. package/extensions/services/audit/module.md +66 -0
  145. package/extensions/services/audit/query_audit.py +111 -0
  146. package/extensions/services/audit/routes/__init__.py +1 -0
  147. package/extensions/services/audit/routes/routes_audit.py +113 -0
  148. package/extensions/services/audit/schemas/__init__.py +5 -0
  149. package/extensions/services/audit/schemas/audit_event.py +92 -0
  150. package/extensions/services/audit/server.py +542 -0
  151. package/extensions/services/audit/storage.py +95 -0
  152. package/extensions/services/auth/entry.py +1054 -0
  153. package/extensions/services/auth/module.md +31 -0
  154. package/extensions/services/auth/token_store.py +185 -0
  155. package/extensions/services/auth/verifiers/evol_account.py +101 -0
  156. package/extensions/services/auth/verifiers/kite_token.py +38 -0
  157. package/extensions/services/auth/verifiers/pairing_code.py +71 -0
  158. package/extensions/services/backup/entry.py +505 -201
  159. package/extensions/services/backup/module.md +4 -2
  160. package/extensions/services/dataclaw/api/__init__.py +0 -0
  161. package/extensions/services/dataclaw/api/admin.py +367 -0
  162. package/extensions/services/dataclaw/api/copyright.py +175 -0
  163. package/extensions/services/dataclaw/api/credits.py +177 -0
  164. package/extensions/services/dataclaw/api/data.py +179 -0
  165. package/extensions/services/dataclaw/api/demands.py +269 -0
  166. package/extensions/services/dataclaw/api/feeds.py +262 -0
  167. package/extensions/services/dataclaw/api/identity.py +505 -0
  168. package/extensions/services/dataclaw/api/notifications.py +104 -0
  169. package/extensions/services/dataclaw/api/reviews.py +138 -0
  170. package/extensions/services/dataclaw/api/search.py +153 -0
  171. package/extensions/services/dataclaw/api/subscriptions.py +157 -0
  172. package/extensions/services/dataclaw/config.json5 +96 -0
  173. package/extensions/services/dataclaw/core/__init__.py +0 -0
  174. package/extensions/services/dataclaw/core/auth.py +95 -0
  175. package/extensions/services/dataclaw/core/config.py +50 -0
  176. package/extensions/services/dataclaw/core/database.py +70 -0
  177. package/extensions/services/dataclaw/entry.py +416 -0
  178. 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
  179. package/extensions/services/dataclaw/migrate.py +283 -0
  180. package/extensions/services/dataclaw/models/__init__.py +0 -0
  181. package/extensions/services/dataclaw/module.md +49 -0
  182. package/extensions/services/dataclaw/requirements.txt +18 -0
  183. package/extensions/services/dataclaw/server.py +759 -0
  184. package/extensions/services/dataclaw/services/__init__.py +0 -0
  185. package/extensions/services/dataclaw/services/agent_service.py +132 -0
  186. package/extensions/services/dataclaw/services/credit_service.py +235 -0
  187. package/extensions/services/dataclaw/services/email_service.py +140 -0
  188. package/extensions/services/dataclaw/services/feed_service.py +259 -0
  189. package/extensions/services/dataclaw/services/notification_service.py +209 -0
  190. package/extensions/services/dataclaw/services/oauth_service.py +275 -0
  191. package/extensions/services/dataclaw/services/pricing.py +102 -0
  192. package/extensions/services/dataclaw/services/quality.py +79 -0
  193. package/extensions/services/dataclaw/services/reputation.py +142 -0
  194. package/extensions/services/dataclaw/services/sms_service.py +174 -0
  195. package/extensions/services/dataclaw/static/css/common.css +853 -0
  196. package/extensions/services/dataclaw/static/css/themes/blue.css +42 -0
  197. package/extensions/services/dataclaw/static/css/themes/dark.css +42 -0
  198. package/extensions/services/dataclaw/static/css/themes/light.css +35 -0
  199. package/extensions/services/dataclaw/static/js/api.js +103 -0
  200. package/extensions/services/dataclaw/static/js/common.js +321 -0
  201. package/extensions/services/dataclaw/static/js/i18n.js +95 -0
  202. package/extensions/services/dataclaw/static/js/pages/admin.js +152 -0
  203. package/extensions/services/dataclaw/static/js/pages/dashboard.js +82 -0
  204. package/extensions/services/dataclaw/static/js/pages/feed-detail.js +180 -0
  205. package/extensions/services/dataclaw/static/js/pages/feed-manage.js +158 -0
  206. package/extensions/services/dataclaw/static/js/theme.js +46 -0
  207. package/extensions/services/dataclaw/static/locales/en-US.json +464 -0
  208. package/extensions/services/dataclaw/static/locales/ja-JP.json +464 -0
  209. package/extensions/services/dataclaw/static/locales/zh-CN.json +464 -0
  210. package/extensions/services/dataclaw/templates/admin/index.html +90 -0
  211. package/extensions/services/dataclaw/templates/base.html +136 -0
  212. package/extensions/services/dataclaw/templates/credits/balance.html +106 -0
  213. package/extensions/services/dataclaw/templates/credits/deposit.html +164 -0
  214. package/extensions/services/dataclaw/templates/credits/history.html +90 -0
  215. package/extensions/services/dataclaw/templates/dashboard.html +52 -0
  216. package/extensions/services/dataclaw/templates/demands/create.html +78 -0
  217. package/extensions/services/dataclaw/templates/demands/detail.html +136 -0
  218. package/extensions/services/dataclaw/templates/demands/list.html +94 -0
  219. package/extensions/services/dataclaw/templates/feeds/create.html +95 -0
  220. package/extensions/services/dataclaw/templates/feeds/detail.html +110 -0
  221. package/extensions/services/dataclaw/templates/feeds/list.html +110 -0
  222. package/extensions/services/dataclaw/templates/feeds/manage.html +88 -0
  223. package/extensions/services/dataclaw/templates/index.html +185 -0
  224. package/extensions/services/dataclaw/templates/login.html +246 -0
  225. package/extensions/services/dataclaw/templates/register.html +164 -0
  226. package/extensions/services/dataclaw/templates/settings/notifications.html +96 -0
  227. package/extensions/services/dataclaw/templates/settings/profile.html +167 -0
  228. package/extensions/services/dataclaw/templates/subscriptions/list.html +64 -0
  229. package/extensions/services/dataclaw/tests/__init__.py +0 -0
  230. package/extensions/services/dataclaw/tests/conftest.py +68 -0
  231. package/extensions/services/dataclaw/tests/integration/__init__.py +0 -0
  232. package/extensions/services/dataclaw/tests/integration/test_workflows.py +239 -0
  233. package/extensions/services/dataclaw/tests/unit/__init__.py +0 -0
  234. package/extensions/services/dataclaw/tests/unit/test_admin.py +70 -0
  235. package/extensions/services/dataclaw/tests/unit/test_copyright.py +63 -0
  236. package/extensions/services/dataclaw/tests/unit/test_credits.py +80 -0
  237. package/extensions/services/dataclaw/tests/unit/test_data.py +98 -0
  238. package/extensions/services/dataclaw/tests/unit/test_demands.py +106 -0
  239. package/extensions/services/dataclaw/tests/unit/test_feeds.py +98 -0
  240. package/extensions/services/dataclaw/tests/unit/test_identity.py +88 -0
  241. package/extensions/services/dataclaw/tests/unit/test_notifications.py +36 -0
  242. package/extensions/services/dataclaw/tests/unit/test_reviews.py +68 -0
  243. package/extensions/services/dataclaw/tests/unit/test_search.py +64 -0
  244. package/extensions/services/dataclaw/tests/unit/test_subscriptions.py +65 -0
  245. package/extensions/services/dataclaw/tests/unit/test_system.py +106 -0
  246. package/extensions/services/dataclaw/utils/__init__.py +0 -0
  247. package/extensions/services/dataclaw/utils/crypto.py +38 -0
  248. package/extensions/services/dataclaw/utils/id_generator.py +52 -0
  249. package/extensions/services/dataclaw/ws/__init__.py +0 -0
  250. package/extensions/services/dataclaw/ws/handler.py +163 -0
  251. 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
  252. 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
  253. package/extensions/services/evol/__init__.py +1 -0
  254. package/extensions/services/evol/async_http.py +551 -0
  255. package/extensions/services/evol/auth_manager.py +602 -0
  256. package/extensions/services/evol/config.json5 +16 -0
  257. package/extensions/services/evol/config_loader.py +117 -0
  258. package/extensions/services/evol/entry.py +568 -0
  259. package/extensions/services/evol/evol_api.py +969 -0
  260. package/extensions/services/evol/evol_config.json5 +29 -0
  261. package/extensions/services/evol/mfa_totp.py +77 -0
  262. package/extensions/services/evol/migrate_tokens.py +122 -0
  263. package/extensions/services/evol/module.md +150 -0
  264. package/extensions/services/evol/nonce_pool.py +113 -0
  265. package/extensions/services/evol/oauth_manager.py +223 -0
  266. package/extensions/services/evol/pairing.py +251 -0
  267. package/extensions/services/evol/pairing_codes.jsonl +2 -0
  268. package/extensions/services/evol/relay.py +1031 -0
  269. package/extensions/services/evol/relay_config.json5 +85 -0
  270. package/extensions/services/evol/routes/__init__.py +1 -0
  271. package/extensions/services/evol/routes/routes_llm.py +231 -0
  272. package/extensions/services/evol/routes/routes_rpc.py +90 -0
  273. package/extensions/services/evol/routes/routes_test.py +68 -0
  274. package/extensions/services/evol/server.py +2426 -0
  275. package/extensions/services/evol/static/assets/CommissionView-Cs_ys6Gm.js +1 -0
  276. package/extensions/services/evol/static/assets/CommissionView-DACet_Oo.css +1 -0
  277. package/extensions/services/evol/static/assets/IframePage-DbO11U9G.js +1 -0
  278. package/extensions/services/evol/static/assets/IframePage-c572lT8i.css +1 -0
  279. package/extensions/services/evol/static/assets/TeamDetailView-DULrGD7k.css +1 -0
  280. package/extensions/services/evol/static/assets/TeamDetailView-gy_MBEqG.js +139 -0
  281. package/extensions/services/evol/static/assets/element-plus-Bd7pZkkM.js +63 -0
  282. package/extensions/services/evol/static/assets/index-CmMONKzG.css +1 -0
  283. package/extensions/services/evol/static/assets/index-D44bBe__.js +2 -0
  284. package/extensions/services/evol/static/assets/vue-vendor-DtF-__I4.js +29 -0
  285. package/extensions/services/evol/static/index.html +16 -0
  286. package/extensions/services/evol/static/logo.png +0 -0
  287. package/extensions/services/evol/stats_manager.py +243 -0
  288. package/extensions/services/evol/web/README.md +89 -0
  289. package/extensions/services/evol/web/build.bat +44 -0
  290. package/extensions/services/evol/web/index.html +13 -0
  291. package/extensions/services/evol/web/package-lock.json +1718 -0
  292. package/extensions/services/evol/web/package.json +26 -0
  293. package/extensions/services/evol/web/public/logo.png +0 -0
  294. package/extensions/services/evol/web/src/App.vue +7 -0
  295. package/extensions/services/evol/web/src/components/layout/AppHeader.vue +202 -0
  296. package/extensions/services/evol/web/src/components/layout/AppLayout.vue +61 -0
  297. package/extensions/services/evol/web/src/components/layout/AppSidebar.vue +115 -0
  298. package/extensions/services/evol/web/src/components/login/LoginPage.vue +271 -0
  299. package/extensions/services/evol/web/src/components/team/AddMemberModal.vue +181 -0
  300. package/extensions/services/evol/web/src/components/team/GroupTreeNode.vue +156 -0
  301. package/extensions/services/evol/web/src/components/team/TeamAlertConfig.vue +221 -0
  302. package/extensions/services/evol/web/src/components/team/TeamBillModal.vue +165 -0
  303. package/extensions/services/evol/web/src/components/team/TeamMembersAndGroups.vue +499 -0
  304. package/extensions/services/evol/web/src/components/team/TeamStatsPanel.vue +907 -0
  305. package/extensions/services/evol/web/src/components/team/TreeNode.vue +331 -0
  306. package/extensions/services/evol/web/src/components/team/stats/StatsExportProgress.vue +44 -0
  307. package/extensions/services/evol/web/src/components/team/stats/StatsHeader.vue +89 -0
  308. package/extensions/services/evol/web/src/components/team/stats/StatsMemberDetail.vue +415 -0
  309. package/extensions/services/evol/web/src/components/team/stats/StatsSummary.vue +42 -0
  310. package/extensions/services/evol/web/src/components/team/stats/helpers.ts +195 -0
  311. package/extensions/services/evol/web/src/components/team/stats/stats.css +741 -0
  312. package/extensions/services/evol/web/src/components/team/stats/useStatsApi.ts +114 -0
  313. package/extensions/services/evol/web/src/components/team/stats/useStatsCharts.ts +242 -0
  314. package/extensions/services/evol/web/src/components/team/stats/useStatsExport.ts +232 -0
  315. package/extensions/services/evol/web/src/composables/useFormatters.ts +42 -0
  316. package/extensions/services/evol/web/src/composables/useTheme.ts +52 -0
  317. package/extensions/services/evol/web/src/env.d.ts +7 -0
  318. package/extensions/services/evol/web/src/i18n/en.ts +361 -0
  319. package/extensions/services/evol/web/src/i18n/index.ts +36 -0
  320. package/extensions/services/evol/web/src/i18n/zh.ts +379 -0
  321. package/extensions/services/evol/web/src/main.ts +21 -0
  322. package/extensions/services/evol/web/src/router/index.ts +81 -0
  323. package/extensions/services/evol/web/src/services/kernel-client.ts +406 -0
  324. package/extensions/services/evol/web/src/stores/auth.ts +189 -0
  325. package/extensions/services/evol/web/src/stores/connection.ts +134 -0
  326. package/extensions/services/evol/web/src/stores/pages.ts +79 -0
  327. package/extensions/services/evol/web/src/styles/base.css +213 -0
  328. package/extensions/services/evol/web/src/styles/variables.css +138 -0
  329. package/extensions/services/evol/web/src/types/rpc.ts +35 -0
  330. package/extensions/services/evol/web/src/types/token.ts +87 -0
  331. package/extensions/services/evol/web/src/views/AccountView.vue +1532 -0
  332. package/extensions/services/evol/web/src/views/AiServiceView.vue +219 -0
  333. package/extensions/services/evol/web/src/views/CommissionView.vue +1220 -0
  334. package/extensions/services/evol/web/src/views/CreditsView.vue +131 -0
  335. package/extensions/services/evol/web/src/views/EndpointView.vue +163 -0
  336. package/extensions/services/evol/web/src/views/IframePage.vue +120 -0
  337. package/extensions/services/evol/web/src/views/TeamDetailView.vue +473 -0
  338. package/extensions/services/evol/web/src/views/TeamView.vue +332 -0
  339. package/extensions/services/evol/web/tsconfig.json +31 -0
  340. package/extensions/services/evol/web/tsconfig.node.json +10 -0
  341. package/extensions/services/evol/web/vite.config.ts +49 -0
  342. package/extensions/services/evolmem/__init__.py +0 -0
  343. package/extensions/services/evolmem/entry.py +387 -0
  344. package/extensions/services/evolmem/hooks/__init__.py +0 -0
  345. package/extensions/services/evolmem/hooks/assistant_stop.py +228 -0
  346. package/extensions/services/evolmem/hooks/common.py +76 -0
  347. package/extensions/services/evolmem/hooks/pre_tool_use.py +56 -0
  348. package/extensions/services/evolmem/hooks/session_end.py +133 -0
  349. package/extensions/services/evolmem/hooks/session_start.py +229 -0
  350. package/extensions/services/evolmem/hooks/user_prompt.py +122 -0
  351. package/extensions/services/evolmem/module.md +48 -0
  352. package/extensions/services/evolmem/prompts/00-server-info.md +28 -0
  353. package/extensions/services/evolmem/prompts/01-behavior.md +46 -0
  354. package/extensions/services/evolmem/prompts/02-summary-format.md +112 -0
  355. package/extensions/services/evolmem/prompts/03-file-query.md +92 -0
  356. package/extensions/services/evolmem/prompts/04-topic-stats.md +11 -0
  357. package/extensions/services/evolmem/prompts/05-recent-topics.md +84 -0
  358. package/extensions/services/evolmem/scripts/__init__.py +0 -0
  359. package/extensions/services/evolmem/scripts/extract_keywords.py +40 -0
  360. package/extensions/services/evolmem/scripts/search_topics.py +91 -0
  361. package/extensions/services/evolmem/server.py +641 -0
  362. package/extensions/services/gateway/entry.py +964 -0
  363. package/extensions/services/gateway/module.md +29 -0
  364. package/extensions/services/gateway/nonce_pool.py +65 -0
  365. package/extensions/services/gateway/relay.py +133 -0
  366. package/extensions/services/gateway/ws_server.py +285 -0
  367. package/extensions/services/kite_console/auth_manager.py +603 -0
  368. package/extensions/services/kite_console/config.json5 +19 -0
  369. package/extensions/services/kite_console/config_loader.py +117 -0
  370. package/extensions/services/kite_console/entry.py +528 -0
  371. package/extensions/services/kite_console/evol_api.py +179 -0
  372. package/extensions/services/kite_console/evol_config.json5 +29 -0
  373. package/extensions/services/kite_console/mfa_totp.py +77 -0
  374. package/extensions/services/kite_console/migrate_tokens.py +122 -0
  375. package/extensions/services/kite_console/module.md +37 -0
  376. package/extensions/services/kite_console/nonce_pool.py +113 -0
  377. package/extensions/services/kite_console/oauth_manager.py +223 -0
  378. package/extensions/services/kite_console/pairing.py +280 -0
  379. package/extensions/services/kite_console/pairing_codes.jsonl +2 -0
  380. package/extensions/services/kite_console/relay.py +1350 -0
  381. package/extensions/services/kite_console/relay_config.json5 +96 -0
  382. package/extensions/services/kite_console/routes/__init__.py +1 -0
  383. package/extensions/services/kite_console/routes/routes_llm.py +231 -0
  384. package/extensions/services/kite_console/routes/routes_proxy.py +115 -0
  385. package/extensions/services/kite_console/routes/routes_rpc.py +89 -0
  386. package/extensions/services/kite_console/routes/routes_test.py +68 -0
  387. package/extensions/services/kite_console/server.py +1742 -0
  388. package/extensions/services/kite_console/static/css/style.css +1854 -0
  389. package/extensions/services/kite_console/static/index.html +1524 -0
  390. package/extensions/services/kite_console/static/js/dialog.js +292 -0
  391. package/extensions/services/kite_console/static/js/evol-app.js +7740 -0
  392. package/extensions/services/kite_console/static/js/evol-app.js.backup +2777 -0
  393. package/extensions/services/kite_console/static/js/kernel-client.js +560 -0
  394. package/extensions/services/kite_console/static/js/kernel-client.js.backup +434 -0
  395. package/extensions/services/kite_console/static/js/registry-tests.js +592 -0
  396. package/extensions/services/kite_console/static/js/tests/ARCHITECTURE.md +67 -0
  397. package/extensions/services/kite_console/static/js/tests/README.md +140 -0
  398. package/extensions/services/kite_console/static/js/tests/index.js +161 -0
  399. package/extensions/services/kite_console/static/js/tests/integration/auth.js +120 -0
  400. package/extensions/services/kite_console/static/js/tests/integration/channel-interaction.js +188 -0
  401. package/extensions/services/kite_console/static/js/tests/integration/elastic-connection.js +115 -0
  402. package/extensions/services/kite_console/static/js/tests/integration/full-workflow.js +43 -0
  403. package/extensions/services/kite_console/static/js/tests/integration/multi-instance.js +304 -0
  404. package/extensions/services/kite_console/static/js/tests/integration/nested-rpc.js +266 -0
  405. package/extensions/services/kite_console/static/js/tests/integration/pingpong.js +25 -0
  406. package/extensions/services/kite_console/static/js/tests/integration/redis.js +227 -0
  407. package/extensions/services/kite_console/static/js/tests/integration/registry-core.js +52 -0
  408. package/extensions/services/kite_console/static/js/tests/integration/remote-deploy.js +85 -0
  409. package/extensions/services/kite_console/static/js/tests/integration/require-init.js +96 -0
  410. package/extensions/services/kite_console/static/js/tests/integration/scaling-control.js +193 -0
  411. package/extensions/services/kite_console/static/js/tests/integration/trace.js +109 -0
  412. package/extensions/services/kite_console/static/js/tests/modules/acp_channel.js +339 -0
  413. package/extensions/services/kite_console/static/js/tests/modules/auth.js +96 -0
  414. package/extensions/services/kite_console/static/js/tests/modules/backup.js +49 -0
  415. package/extensions/services/kite_console/static/js/tests/modules/gateway.js +41 -0
  416. package/extensions/services/kite_console/static/js/tests/modules/kernel.js +90 -0
  417. package/extensions/services/kite_console/static/js/tests/modules/launcher.js +75 -0
  418. package/extensions/services/kite_console/static/js/tests/modules/multi_instance.js +129 -0
  419. package/extensions/services/kite_console/static/js/tests/modules/phone_channel.js +364 -0
  420. package/extensions/services/kite_console/static/js/tests/modules/redis.js +178 -0
  421. package/extensions/services/kite_console/static/js/tests/modules/watchdog.js +60 -0
  422. package/extensions/services/kite_console/static/js/tests/modules/web.js +70 -0
  423. package/extensions/services/kite_console/static/js/tests/test-runner.js +123 -0
  424. package/extensions/services/kite_console/static/js/virtual-list.js +200 -0
  425. package/extensions/services/kite_console/static/pairing.html +248 -0
  426. package/extensions/services/kite_console/static/test_kernel_client_token.html +352 -0
  427. package/extensions/services/kite_console/static/test_registry.html +262 -0
  428. package/extensions/services/kite_console/static/test_relay.html +462 -0
  429. package/extensions/services/kite_console/stats_manager.py +247 -0
  430. package/extensions/services/logs/README.md +215 -0
  431. package/extensions/services/logs/api_logger.py +37 -0
  432. package/extensions/services/logs/baseline.py +121 -0
  433. package/extensions/services/logs/cleaner.py +76 -0
  434. package/extensions/services/logs/entry.py +449 -0
  435. package/extensions/services/logs/formatter.py +129 -0
  436. package/extensions/services/logs/module.md +38 -0
  437. package/extensions/services/logs/quick_diagnostic.py +128 -0
  438. package/extensions/services/logs/routes/__init__.py +1 -0
  439. package/extensions/services/logs/routes/routes_logs.py +218 -0
  440. package/extensions/services/logs/routes/routes_logs.py.backup +173 -0
  441. package/extensions/services/logs/scanner.py +100 -0
  442. package/extensions/services/logs/searcher.py +263 -0
  443. package/extensions/services/logs/server.py +553 -0
  444. package/extensions/services/logs.zip +0 -0
  445. package/extensions/services/model_service/config.json5 +30 -0
  446. package/extensions/services/model_service/entry.py +633 -162
  447. package/extensions/services/model_service/module.md +11 -2
  448. package/extensions/services/proxy/.claude/settings.local.json +13 -0
  449. package/extensions/services/proxy/__init__.py +0 -0
  450. package/extensions/services/proxy/agentcp/LICENCE +178 -0
  451. package/extensions/services/proxy/agentcp/README copy.md +85 -0
  452. package/extensions/services/proxy/agentcp/README.md +260 -0
  453. package/extensions/services/proxy/agentcp/__init__.py +16 -0
  454. package/extensions/services/proxy/agentcp/agent.py +4 -0
  455. package/extensions/services/proxy/agentcp/agentcp.py +2494 -0
  456. package/extensions/services/proxy/agentcp/agentprofile.json +89 -0
  457. package/extensions/services/proxy/agentcp/ap/__init__.py +16 -0
  458. package/extensions/services/proxy/agentcp/ap/ap_client.py +316 -0
  459. package/extensions/services/proxy/agentcp/assets/images/wechat_qr.png +0 -0
  460. package/extensions/services/proxy/agentcp/backup/metrics.json +31 -0
  461. package/extensions/services/proxy/agentcp/base/__init__.py +20 -0
  462. package/extensions/services/proxy/agentcp/base/auth_client.py +257 -0
  463. package/extensions/services/proxy/agentcp/base/client.py +112 -0
  464. package/extensions/services/proxy/agentcp/base/env.py +34 -0
  465. package/extensions/services/proxy/agentcp/base/html_util.py +336 -0
  466. package/extensions/services/proxy/agentcp/base/log.py +98 -0
  467. package/extensions/services/proxy/agentcp/ca/__init__.py +17 -0
  468. package/extensions/services/proxy/agentcp/ca/ca_client.py +414 -0
  469. package/extensions/services/proxy/agentcp/ca/ca_root.py +74 -0
  470. package/extensions/services/proxy/agentcp/context/__init__.py +20 -0
  471. package/extensions/services/proxy/agentcp/context/context.py +73 -0
  472. package/extensions/services/proxy/agentcp/context/exceptions.py +114 -0
  473. package/extensions/services/proxy/agentcp/create_profile.py +125 -0
  474. package/extensions/services/proxy/agentcp/create_profile_weather.py +125 -0
  475. package/extensions/services/proxy/agentcp/db/__init__.py +15 -0
  476. package/extensions/services/proxy/agentcp/db/db_mananger.py +550 -0
  477. package/extensions/services/proxy/agentcp/docs/UDP_HEARTBEAT_FIX_REPORT.md +265 -0
  478. package/extensions/services/proxy/agentcp/docs/heartbeat_issue_analysis.md +291 -0
  479. package/extensions/services/proxy/agentcp/file/__init__.py +16 -0
  480. package/extensions/services/proxy/agentcp/file/file_client.py +141 -0
  481. package/extensions/services/proxy/agentcp/file/wss_binary_message.py +137 -0
  482. package/extensions/services/proxy/agentcp/hcp.py +299 -0
  483. package/extensions/services/proxy/agentcp/heartbeat/__init__.py +16 -0
  484. package/extensions/services/proxy/agentcp/heartbeat/heartbeat_client.py +360 -0
  485. package/extensions/services/proxy/agentcp/improved_scheduler.py +498 -0
  486. package/extensions/services/proxy/agentcp/llm_agent_utils.py +249 -0
  487. package/extensions/services/proxy/agentcp/llm_server.py +172 -0
  488. package/extensions/services/proxy/agentcp/mermaid.py +210 -0
  489. package/extensions/services/proxy/agentcp/message.py +149 -0
  490. package/extensions/services/proxy/agentcp/metrics.py +256 -0
  491. package/extensions/services/proxy/agentcp/monitoring/__init__.py +20 -0
  492. package/extensions/services/proxy/agentcp/monitoring/global_monitor.py +27 -0
  493. package/extensions/services/proxy/agentcp/monitoring/metrics_store.py +325 -0
  494. package/extensions/services/proxy/agentcp/monitoring/monitoring_service.py +269 -0
  495. package/extensions/services/proxy/agentcp/monitoring/sliding_window.py +222 -0
  496. package/extensions/services/proxy/agentcp/monitoring/standalone_reader.py +224 -0
  497. package/extensions/services/proxy/agentcp/msg/__init__.py +21 -0
  498. package/extensions/services/proxy/agentcp/msg/connection_manager.py +456 -0
  499. package/extensions/services/proxy/agentcp/msg/message_client.py +2058 -0
  500. package/extensions/services/proxy/agentcp/msg/message_serialize.py +263 -0
  501. package/extensions/services/proxy/agentcp/msg/open_ai_message.py +88 -0
  502. package/extensions/services/proxy/agentcp/msg/session_manager.py +1062 -0
  503. package/extensions/services/proxy/agentcp/msg/stream_client.py +267 -0
  504. package/extensions/services/proxy/agentcp/msg/websocket_file_receiver.py +89 -0
  505. package/extensions/services/proxy/agentcp/msg/ws_logger.py +685 -0
  506. package/extensions/services/proxy/agentcp/msg/wss_binary_message.py +137 -0
  507. package/extensions/services/proxy/agentcp/requirements.txt +7 -0
  508. package/extensions/services/proxy/agentcp/samples/agent_graph/README.md +37 -0
  509. package/extensions/services/proxy/agentcp/samples/agent_graph/agentprofile.json +89 -0
  510. package/extensions/services/proxy/agentcp/samples/agent_graph/create_profile.py +138 -0
  511. package/extensions/services/proxy/agentcp/samples/agent_graph/main.py +164 -0
  512. package/extensions/services/proxy/agentcp/samples/agent_use/create_profile.py +123 -0
  513. package/extensions/services/proxy/agentcp/samples/agent_use/llm/create_profile.py +129 -0
  514. package/extensions/services/proxy/agentcp/samples/agent_use/llm/env.json +5 -0
  515. package/extensions/services/proxy/agentcp/samples/agent_use/llm/main.py +146 -0
  516. package/extensions/services/proxy/agentcp/samples/agent_use/main.py +123 -0
  517. package/extensions/services/proxy/agentcp/samples/agent_use/readme.md +379 -0
  518. package/extensions/services/proxy/agentcp/samples/agent_use/search/create_profile.py +129 -0
  519. package/extensions/services/proxy/agentcp/samples/agent_use/search/main.py +28 -0
  520. package/extensions/services/proxy/agentcp/samples/agent_use/tool/create_profile.py +129 -0
  521. package/extensions/services/proxy/agentcp/samples/agent_use/tool/main.py +20 -0
  522. package/extensions/services/proxy/agentcp/samples/ali_amap/README.md +97 -0
  523. package/extensions/services/proxy/agentcp/samples/ali_amap/amap_agent.py +88 -0
  524. package/extensions/services/proxy/agentcp/samples/ali_amap/create_profile.py +125 -0
  525. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/powershell.py +228 -0
  526. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/software.py +63 -0
  527. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/tools.py +36 -0
  528. package/extensions/services/proxy/agentcp/samples/compute_agent/browser_user.py +41 -0
  529. package/extensions/services/proxy/agentcp/samples/deepseek/README.md +79 -0
  530. package/extensions/services/proxy/agentcp/samples/deepseek/create_profile.py +126 -0
  531. package/extensions/services/proxy/agentcp/samples/deepseek/deepseek.py +42 -0
  532. package/extensions/services/proxy/agentcp/samples/dify_chat/README.md +78 -0
  533. package/extensions/services/proxy/agentcp/samples/dify_chat/create_profile.py +126 -0
  534. package/extensions/services/proxy/agentcp/samples/dify_chat/dify_chat.py +47 -0
  535. package/extensions/services/proxy/agentcp/samples/dify_workflow/README.md +78 -0
  536. package/extensions/services/proxy/agentcp/samples/dify_workflow/create_profile.py +126 -0
  537. package/extensions/services/proxy/agentcp/samples/dify_workflow/dify_workflow.py +46 -0
  538. package/extensions/services/proxy/agentcp/samples/executor/README.md +44 -0
  539. package/extensions/services/proxy/agentcp/samples/executor/agentprofile.json +89 -0
  540. package/extensions/services/proxy/agentcp/samples/executor/create_profile.py +139 -0
  541. package/extensions/services/proxy/agentcp/samples/executor/main.py +160 -0
  542. package/extensions/services/proxy/agentcp/samples/filereader/README.md +45 -0
  543. package/extensions/services/proxy/agentcp/samples/filereader/agentprofile.json +90 -0
  544. package/extensions/services/proxy/agentcp/samples/filereader/create_profile.py +137 -0
  545. package/extensions/services/proxy/agentcp/samples/filereader/main.py +253 -0
  546. package/extensions/services/proxy/agentcp/samples/filewriter/README.md +38 -0
  547. package/extensions/services/proxy/agentcp/samples/filewriter/agentprofile.json +91 -0
  548. package/extensions/services/proxy/agentcp/samples/filewriter/create_profile.py +138 -0
  549. package/extensions/services/proxy/agentcp/samples/filewriter/main.py +289 -0
  550. package/extensions/services/proxy/agentcp/samples/hcp/README.md +85 -0
  551. package/extensions/services/proxy/agentcp/samples/hcp/acp_weather_agent.zip +0 -0
  552. package/extensions/services/proxy/agentcp/samples/hcp/create_profile.py +125 -0
  553. package/extensions/services/proxy/agentcp/samples/hcp/hcp.py +237 -0
  554. package/extensions/services/proxy/agentcp/samples/helloworld/README.md +68 -0
  555. package/extensions/services/proxy/agentcp/samples/helloworld/hello_world.py +40 -0
  556. package/extensions/services/proxy/agentcp/samples/llm_agent/MEADME.md +117 -0
  557. package/extensions/services/proxy/agentcp/samples/llm_agent/create_profile.py +125 -0
  558. package/extensions/services/proxy/agentcp/samples/llm_agent/qwen_agent.py +136 -0
  559. package/extensions/services/proxy/agentcp/samples/local_llm_agent/README.md +90 -0
  560. package/extensions/services/proxy/agentcp/samples/local_llm_agent/create_profile.py +125 -0
  561. package/extensions/services/proxy/agentcp/samples/local_llm_agent/main.py +49 -0
  562. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/README.md +55 -0
  563. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/create_profile.py +125 -0
  564. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/main.py +23 -0
  565. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/README.md +103 -0
  566. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/create_profile.py +125 -0
  567. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/main.py +69 -0
  568. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/README.md +58 -0
  569. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/create_profile.py +125 -0
  570. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/main.py +25 -0
  571. package/extensions/services/proxy/agentcp/samples/qwen3/README.md +71 -0
  572. package/extensions/services/proxy/agentcp/samples/qwen3/create_profile.py +126 -0
  573. package/extensions/services/proxy/agentcp/samples/qwen3/qwen3.py +37 -0
  574. package/extensions/services/proxy/agentcp/samples/qwen3_tools/README.md +133 -0
  575. package/extensions/services/proxy/agentcp/samples/qwen3_tools/create_profile.py +126 -0
  576. package/extensions/services/proxy/agentcp/samples/qwen3_tools/qwen3_tools.py +98 -0
  577. package/extensions/services/proxy/agentcp/samples/search/create_profile_qwen.py +125 -0
  578. package/extensions/services/proxy/agentcp/samples/search/create_profile_search.py +125 -0
  579. package/extensions/services/proxy/agentcp/samples/search/qwen_agent.py +136 -0
  580. package/extensions/services/proxy/agentcp/samples/search/search_agent.py +170 -0
  581. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/README.md +89 -0
  582. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/create_profile.py +125 -0
  583. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/main.py +44 -0
  584. package/extensions/services/proxy/agentcp/utils/__init__.py +15 -0
  585. package/extensions/services/proxy/agentcp/utils/file_util.py +117 -0
  586. package/extensions/services/proxy/agentcp/utils/proxy_bypass.py +99 -0
  587. package/extensions/services/proxy/agentcp/workflow.py +203 -0
  588. package/extensions/services/proxy/aid_manager.py +419 -0
  589. package/extensions/services/proxy/auth_bridge.py +182 -0
  590. package/extensions/services/proxy/config_store.py +79 -0
  591. package/extensions/services/proxy/entry.py +528 -0
  592. package/extensions/services/proxy/evol/__init__.py +1 -0
  593. package/extensions/services/proxy/evol/config.py +37 -0
  594. package/extensions/services/proxy/evol/http/__init__.py +1 -0
  595. package/extensions/services/proxy/evol/http/async_http.py +551 -0
  596. package/extensions/services/proxy/evol/log.py +28 -0
  597. package/extensions/services/proxy/evol/presenter/__init__.py +2 -0
  598. package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +1031 -0
  599. package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +96 -0
  600. package/extensions/services/proxy/evol/presenter/configPresenter.py +234 -0
  601. package/extensions/services/proxy/evol/presenter/userPresenter.py +71 -0
  602. package/extensions/services/proxy/evol/server/__init__.py +1 -0
  603. package/extensions/services/proxy/evol/server/claude_proxy_async.py +3434 -0
  604. package/extensions/services/proxy/evol/server/openclaw_proxy.py +1861 -0
  605. package/extensions/services/proxy/evol/server/proxy_config.py +15 -0
  606. package/extensions/services/proxy/evol/server/proxy_engine.py +501 -0
  607. package/extensions/services/proxy/evol/version.py +24 -0
  608. package/extensions/services/proxy/module.md +151 -0
  609. package/extensions/services/proxy/server.py +952 -0
  610. package/extensions/services/redis/ALIGNMENT_CHECKLIST.md +121 -0
  611. package/extensions/services/redis/ALIGNMENT_STATUS.md +548 -0
  612. package/extensions/services/redis/config.json5 +8 -0
  613. package/extensions/services/redis/entry.py +1509 -0
  614. package/extensions/services/redis/entry.py.backup +405 -0
  615. package/extensions/services/redis/module.md +48 -0
  616. package/extensions/services/redis/redis_builtin.py +332 -0
  617. package/extensions/services/redis/redis_external.py +164 -0
  618. package/extensions/services/testUi/entry.py +446 -0
  619. package/extensions/services/testUi/module.md +18 -0
  620. package/extensions/services/testUi/ui/cards.html +131 -0
  621. package/extensions/services/testUi/ui/index.html +22 -0
  622. package/extensions/services/testUi/ui/particles.html +143 -0
  623. package/extensions/services/watchdog/entry.py +1258 -767
  624. package/extensions/services/watchdog/module.md +3 -0
  625. package/extensions/services/watchdog/monitor.py +483 -75
  626. package/extensions/services/web/auth_manager.py +602 -0
  627. package/extensions/services/web/config.json5 +11 -0
  628. package/extensions/services/web/entry.py +598 -478
  629. package/extensions/services/web/mfa_totp.py +77 -0
  630. package/extensions/services/web/module.md +17 -14
  631. package/extensions/services/web/nonce_pool.py +113 -0
  632. package/extensions/services/web/oauth_manager.py +223 -0
  633. package/extensions/services/web/pairing.py +3 -2
  634. package/extensions/services/web/pairing_codes.jsonl +1 -0
  635. package/extensions/services/web/relay.py +442 -63
  636. package/extensions/services/web/relay_config.json5 +1 -2
  637. package/extensions/services/web/routes/routes_rpc.py +6 -6
  638. package/extensions/services/web/server.py +380 -181
  639. package/extensions/services/web/static/index.html +1752 -1738
  640. package/extensions/services/web/static/js/app.js +32 -0
  641. package/extensions/services/web/static/js/kernel-client.js +48 -9
  642. package/extensions/services/web/static/js/token-manager.js +10 -10
  643. package/extensions/services/web/vendor/bluetooth/audio.py +1 -1
  644. package/extensions/services/web/vendor/config.py +2 -2
  645. package/extensions/services/web/vendor/storage/identity.py +1 -1
  646. package/kernel/entry.py +77 -23
  647. package/kernel/event_hub.py +1122 -74
  648. package/kernel/module.md +26 -1
  649. package/kernel/registry_store.py +209 -36
  650. package/kernel/rpc_router.py +1400 -465
  651. package/kernel/server.py +1084 -108
  652. package/kite_cli/builders/__init__.py +4 -0
  653. package/kite_cli/builders/base.py +67 -0
  654. package/kite_cli/builders/custom.py +31 -0
  655. package/kite_cli/builders/detector.py +56 -0
  656. package/kite_cli/builders/go.py +34 -0
  657. package/kite_cli/builders/gradle.py +41 -0
  658. package/kite_cli/builders/maven.py +36 -0
  659. package/kite_cli/builders/npm.py +44 -0
  660. package/kite_cli/builders/python.py +37 -0
  661. package/kite_cli/commands/BUILD_GUIDE.md +109 -0
  662. package/kite_cli/commands/build.py +142 -0
  663. package/kite_cli/commands/check.py +60 -0
  664. package/kite_cli/commands/config.py +156 -0
  665. package/kite_cli/commands/deps.py +58 -0
  666. package/kite_cli/commands/deps_install.py +67 -0
  667. package/kite_cli/commands/disable.py +162 -0
  668. package/kite_cli/commands/enable.py +162 -0
  669. package/kite_cli/commands/env_check.py +45 -0
  670. package/kite_cli/commands/export.py +96 -0
  671. package/kite_cli/commands/import_cmd.py +110 -0
  672. package/kite_cli/commands/install.py +50 -23
  673. package/kite_cli/commands/install_skill.py +107 -0
  674. package/kite_cli/commands/list.py +128 -31
  675. package/kite_cli/commands/outdated.py +202 -0
  676. package/kite_cli/commands/prepare.py +49 -0
  677. package/kite_cli/commands/search.py +33 -17
  678. package/kite_cli/commands/update.py +115 -2
  679. package/kite_cli/commands/venv_setup.py +56 -0
  680. package/kite_cli/commands/why.py +48 -0
  681. package/kite_cli/core/config_manager.py +145 -0
  682. package/kite_cli/core/downloader.py +32 -2
  683. package/kite_cli/main.py +179 -5
  684. package/kite_cli/utils/colors.py +153 -0
  685. package/kite_cli/utils/dependency_graph.py +209 -0
  686. package/kite_cli/utils/process.py +55 -0
  687. package/kite_cli/utils/progress.py +207 -0
  688. package/kite_cli/utils/table.py +101 -0
  689. package/launcher/count_lines.py +192 -43
  690. package/launcher/entry.py +4543 -2517
  691. package/launcher/logging_setup.py +54 -1
  692. package/launcher/module.md +37 -2
  693. package/launcher/module_scanner.py +103 -20
  694. package/launcher/process_manager.py +355 -76
  695. package/main.py +10 -1
  696. package/package.json +11 -1
  697. package/python_version.json +4 -0
  698. package/requirements.txt +41 -0
  699. package/scripts/auto-fix-deps.py +128 -0
  700. package/scripts/env-manager.js +351 -0
  701. package/scripts/final-test.js +78 -0
  702. package/scripts/python-env.js +79 -0
  703. package/scripts/scan_dependencies.py +461 -0
  704. package/scripts/setup-python-env.js +700 -0
  705. package/scripts/test-alluser.js +48 -0
  706. package/scripts/test-different-version.js +86 -0
  707. package/scripts/test-direct.js +63 -0
  708. package/scripts/test-extract-installer.js +28 -0
  709. package/scripts/test-install-log.js +54 -0
  710. package/scripts/test-installer.js +39 -0
  711. package/scripts/test-integration.js +250 -0
  712. package/scripts/test-real-install.js +210 -0
  713. package/scripts/test-targetdir.js +49 -0
  714. package/scripts/test-venv-real.js +47 -0
  715. package/scripts/test-venv-simple.js +57 -0
  716. package/scripts/test-wait.js +49 -0
  717. package/scripts/test-with-log.js +63 -0
  718. package/extensions/services/web/config.yaml +0 -149
@@ -15,6 +15,7 @@ from datetime import datetime, timezone
15
15
  import asyncio
16
16
  import traceback
17
17
  import uuid
18
+ import random
18
19
 
19
20
  import websockets
20
21
 
@@ -25,6 +26,7 @@ SYSTEM_BROADCAST_EVENTS = {
25
26
  "module.crashed", "module.exiting", "module.offline",
26
27
  "module.shutdown.ack", "module.shutdown.ready",
27
28
  "system.ready", "registry.updated",
29
+ "system.instance.started", "system.instance.stopped",
28
30
  }
29
31
 
30
32
 
@@ -129,6 +131,12 @@ def _load_module_config() -> dict:
129
131
  if "advertise_ip" in fm:
130
132
  result["advertise_ip"] = str(fm["advertise_ip"])
131
133
 
134
+ # max_connections(弹性连接上限)
135
+ try:
136
+ result["max_connections"] = max(1, min(10, int(fm.get("max_connections", 1))))
137
+ except (ValueError, TypeError):
138
+ result["max_connections"] = 1
139
+
132
140
  except SystemExit:
133
141
  raise # Re-raise exit to prevent catching by outer except
134
142
  except Exception as e:
@@ -381,6 +389,14 @@ _ws_global = None
381
389
  _shutting_down = False
382
390
  _exit_code = 0 # Exit code for main() to use
383
391
 
392
+ # 弹性多连接
393
+ _extra_ws: dict = {} # slot → WebSocket(附加连接)
394
+ _extra_ws_tasks: dict = {} # slot → recv loop Task
395
+ _kernel_port = "" # 缓存 kernel_port,供 offer handler 使用
396
+ _pending_rpc: dict[str, asyncio.Future] = {} # rpc_id → Future(等待响应)
397
+
398
+ _has_registered = False
399
+
384
400
 
385
401
  def _is_auth_failure(e: Exception) -> bool:
386
402
  """Check if a WebSocket exception indicates authentication failure."""
@@ -392,224 +408,262 @@ def _is_auth_failure(e: Exception) -> bool:
392
408
 
393
409
  async def main():
394
410
  global _ws_global, _shutting_down
395
- # Initialize log file paths
396
- global _log_dir, _log_latest_path, _crash_log_path
397
- module_data = os.environ.get("KITE_MODULE_DATA")
398
- if module_data:
399
- _log_dir = os.path.join(module_data, "log")
400
- os.makedirs(_log_dir, exist_ok=True)
401
- suffix = os.environ.get("KITE_INSTANCE_SUFFIX", "")
402
-
403
- _log_latest_path = os.path.join(_log_dir, f"latest{suffix}.log")
404
- try:
405
- with open(_log_latest_path, "w", encoding="utf-8") as f:
406
- pass
407
- except Exception:
408
- _log_latest_path = None
409
-
410
- _crash_log_path = os.path.join(_log_dir, f"crashes{suffix}.jsonl")
411
- try:
412
- with open(_crash_log_path, "w", encoding="utf-8") as f:
413
- pass
414
- except Exception:
415
- _crash_log_path = None
416
-
417
- _resolve_daily_log_path()
418
-
419
- _setup_exception_hooks()
420
-
421
- _t0 = time.monotonic()
422
-
423
- # Read boot_info from stdin (only token)
424
- token = ""
425
- try:
426
- line = sys.stdin.readline().strip()
427
- if line:
428
- boot_info = json.loads(line)
429
- token = boot_info.get("token", "")
430
- except Exception:
431
- pass
432
-
433
- # Read kernel_port: env first (fast path), stdin fallback (parallel start)
434
- kernel_port = int(os.environ.get("KITE_KERNEL_PORT", "0"))
435
- if not kernel_port:
436
- msg = _read_stdin_kite_message("kernel_port", timeout=10)
437
- if msg:
438
- kernel_port = int(msg.get("kernel_port", 0))
439
-
440
- if not token or not kernel_port:
441
- print("[backup] ERROR: Missing token or kernel_port")
442
- sys.exit(1)
443
-
444
- print(f"[backup] Token received ({len(token)} chars), kernel port: {kernel_port} ({_fmt_elapsed(_t0)})")
445
-
446
- # Start reconnect loop
447
- await _ws_loop(token, kernel_port, _t0)
411
+ if _startup_config.get("mode") == "remote":
412
+ await _remote_mode_loop(_startup_config["gateway_url"], _startup_config["kite_token"], _startup_config["t0"])
413
+ else:
414
+ await _ws_loop(_startup_config["token"], _startup_config["kernel_port"], _startup_config["t0"])
448
415
 
449
416
 
450
417
  async def _ws_loop(token: str, kernel_port: int, _t0: float):
451
418
  """Connect to Kernel with exponential backoff reconnection."""
452
419
  global _shutting_down, _exit_code
453
- retry_delay = 0.3
454
- max_delay = 5.0
455
- max_retries = 10
420
+ retry_delay = 0.5
421
+ max_delay = 10.0
456
422
  attempt = 0
423
+ cooldown_attempts = 0
424
+
457
425
  while not _shutting_down:
458
426
  try:
459
427
  await _ws_connect(token, kernel_port, _t0)
460
- retry_delay = 0.3
428
+ retry_delay = 0.5
461
429
  attempt = 0
430
+ cooldown_attempts = 0
462
431
  except asyncio.CancelledError:
463
432
  return
464
433
  except Exception as e:
465
- attempt += 1
466
- if _is_auth_failure(e):
467
- print(f"[backup] Kernel 认证失败,退出")
468
- _exit_code = 1
469
- _shutting_down = True
434
+ if _shutting_down:
470
435
  return
471
- if attempt >= max_retries:
472
- print(f"[backup] 重连失败 {max_retries} 次,退出")
436
+
437
+ code = _get_close_code(e)
438
+
439
+ # never: 永不重连
440
+ if code in (4001, 4003, 4004, 1008, 4010):
441
+ print(f"[backup] 致命错误 (code {code}),退出")
473
442
  _exit_code = 1
474
443
  _shutting_down = True
475
444
  return
445
+
446
+ # cooldown: 速率限制
447
+ if code == 4020:
448
+ cooldown_attempts += 1
449
+ if cooldown_attempts >= 5:
450
+ print(f"[backup] 速率限制重试 5 次,退出")
451
+ _exit_code = 1
452
+ _shutting_down = True
453
+ return
454
+ print(f"[backup] 速率限制,10.0s 后重试 ({cooldown_attempts}/5)")
455
+ await asyncio.sleep(10.0)
456
+ continue
457
+
458
+ # standard: 指数退避 + jitter
459
+ attempt += 1
460
+ jitter = retry_delay * 0.2 * random.random()
461
+ sleep_time = retry_delay + jitter
476
462
  _write_crash(type(e), e, e.__traceback__, severity="error", handled=True)
477
- print(f"[backup] 连接错误: {e}, {retry_delay:.1f}s 后重试 ({attempt}/{max_retries})")
463
+ print(f"[backup] 连接错误: {e}, {sleep_time:.1f}s 后重试 (attempt {attempt})")
464
+
478
465
  _ws_global_clear()
479
466
  if _shutting_down:
480
467
  return
481
- await asyncio.sleep(retry_delay)
468
+ await asyncio.sleep(sleep_time if 'sleep_time' in locals() else retry_delay)
482
469
  retry_delay = min(retry_delay * 2, max_delay)
483
470
 
484
471
 
485
- def _ws_global_clear():
486
- global _ws_global
487
- _ws_global = None
472
+ def _get_close_code(e: Exception) -> int:
473
+ """从 websockets 异常中提取关闭码"""
474
+ if hasattr(e, 'rcvd') and e.rcvd is not None:
475
+ return getattr(e.rcvd, 'code', 0)
476
+ return 0
488
477
 
489
478
 
490
- async def _ws_connect(token: str, kernel_port: int, _t0: float):
491
- """Single WebSocket session: connect → subscribe → register → ready → receive loop."""
479
+ def _ws_global_clear():
492
480
  global _ws_global
481
+ _ws_global = None
493
482
 
494
- ws_url = f"ws://127.0.0.1:{kernel_port}/ws?token={token}&id=backup"
495
- print(f"[backup] Connecting to Kernel: {ws_url}")
496
-
497
- async with websockets.connect(ws_url, open_timeout=5, ping_interval=20, ping_timeout=20, close_timeout=10) as ws:
498
- _ws_global = ws
499
- print(f"[backup] Connected to Kernel ({_fmt_elapsed(_t0)})")
500
483
 
501
- # Subscribe to events
502
- await _rpc_call(ws, "event.subscribe", {
503
- "events": [
504
- "module.started",
505
- "module.stopped",
506
- "module.shutdown",
507
- ],
508
- })
509
- print(f"[backup] Subscribed to events ({_fmt_elapsed(_t0)})")
484
+ async def _do_init(ws):
485
+ """收到 system.require_init 后执行:subscribe + register + module.ready"""
486
+ global _has_registered
487
+ reason = "startup" if not _has_registered else "recovery"
488
+ print(f"[backup] Received system.require_init (reason={reason})")
510
489
 
511
- # Register to Kernel Registry via RPC
512
- await _rpc_call(ws, "registry.register", {
513
- "module_id": "backup",
514
- "module_type": "service",
515
- "launcher_id": "launcher", # 声明归属的 Launcher
516
- "tools": {
517
- "rpc": {
518
- "module": {
519
- "health": {"method": "health", "description": "健康检查"},
520
- "status": {"method": "status", "description": "状态查询"},
521
- "config": {
522
- "get": {"method": "get_settings", "description": "获取配置"},
523
- "update": {"method": "update_settings", "description": "更新配置"},
524
- "reset": {"method": "reset_settings", "description": "恢复默认配置"},
525
- }
490
+ # 1. Subscribe to events
491
+ await _rpc_call(ws, "event.subscribe", {
492
+ "events": [
493
+ "module.started",
494
+ "module.stopped",
495
+ "module.shutdown",
496
+ ],
497
+ })
498
+ print(f"[backup] Subscribed to events")
499
+
500
+ # 2. Register to Kernel Registry via RPC
501
+ await _rpc_call(ws, "registry.register", {
502
+ "module_id": "backup",
503
+ "module_type": "service",
504
+ "launcher_id": "launcher",
505
+ "tools": {
506
+ "rpc": {
507
+ "module": {
508
+ "health": {"method": "health", "description": "健康检查"},
509
+ "status": {"method": "status", "description": "状态查询"},
510
+ "config": {
511
+ "get": {"method": "get_settings", "description": "获取配置"},
512
+ "update": {"method": "update_settings", "description": "更新配置"},
513
+ "reset": {"method": "reset_settings", "description": "恢复默认配置"},
526
514
  }
527
515
  }
528
- },
529
- "events_publish": {
530
- "backup": {
531
- "test": {"description": "Test event from backup module"},
532
- }
533
- },
534
- "events_subscribe": [
535
- "module.started",
536
- "module.stopped",
537
- "module.shutdown",
538
- ],
516
+ }
517
+ },
518
+ "events_publish": {
519
+ "backup": {
520
+ "test": {"description": "Test event from backup module"},
521
+ }
522
+ },
523
+ "events_subscribe": [
524
+ "module.started",
525
+ "module.stopped",
526
+ "module.shutdown",
527
+ ],
528
+ })
529
+ print(f"[backup] Registered to Kernel")
530
+
531
+ # 3. Publish module.ready
532
+ if not _shutting_down:
533
+ startup_time = time.monotonic() - _start_ts
534
+ await _publish_event(ws, "module.ready", {
535
+ "module_id": "backup",
536
+ "graceful_shutdown": True,
537
+ "startup_time": startup_time,
538
+ "reason": reason,
539
539
  })
540
- print(f"[backup] Registered to Kernel ({_fmt_elapsed(_t0)})")
541
-
542
- # Publish module.ready (every reconnect)
543
- if not _shutting_down:
544
- await _rpc_call(ws, "event.publish", {
545
- "event_id": str(uuid.uuid4()),
546
- "event": "module.ready",
547
- "data": {
548
- "module_id": "backup",
549
- "graceful_shutdown": True,
550
- },
551
- })
552
- print(f"[backup] module.ready published ({_fmt_elapsed(_t0)})")
540
+ print(f"[backup] module.ready published (reason={reason})")
553
541
 
554
- # Start test event loop in background
555
- test_task = asyncio.create_task(_test_event_loop(ws))
542
+ _has_registered = True
556
543
 
557
- # Start heartbeat loop
558
- heartbeat_task = asyncio.create_task(_heartbeat_loop(ws))
544
+ # Start test event loop in background
545
+ asyncio.create_task(_test_event_loop(ws))
559
546
 
560
- # Message loop: handle incoming RPC + events
561
- # CRITICAL: RPC 死锁防范
562
- # - 入站 RPC 请求必须用 create_task() 异步执行,不可 await
563
- # - 原因:如果 handler 内部调用 rpc_call() 发出站请求,出站响应需要本接收循环来分发
564
- # - 如果接收循环被 await handler 阻塞,出站响应永远收不到 → 超时死锁
565
- # - 事件通知和 RPC 响应可以同步处理(它们不会反向调用 rpc_call)
566
- async for raw in ws:
567
- try:
568
- msg = json.loads(raw)
569
- except (json.JSONDecodeError, TypeError):
570
- continue
571
547
 
572
- try:
573
- has_method = "method" in msg
574
- has_id = "id" in msg
548
+ async def _ws_connect(token: str, kernel_port: int, _t0: float):
549
+ """Single WebSocket session: connect → auth → start receiver → wait for system.require_init."""
550
+ global _ws_global, _kernel_port
551
+ _kernel_port = kernel_port
575
552
 
576
- if has_method and not has_id:
577
- # Event Notification
578
- await _handle_event_notification(msg)
579
- elif has_method and has_id:
580
- # Incoming RPC request — run in background to prevent deadlock
581
- asyncio.create_task(_handle_rpc_request(ws, msg))
582
- # Ignore RPC responses (we don't await them in this simple impl)
583
- except Exception as e:
584
- print(f"[backup] 消息处理异常(已忽略): {e}")
553
+ ws_url = f"ws://127.0.0.1:{kernel_port}/ws?id=backup"
554
+ print(f"[backup] Connecting to Kernel: {ws_url}")
585
555
 
556
+ async with websockets.connect(ws_url, open_timeout=5, ping_interval=None, close_timeout=10) as ws:
557
+ # Send auth message first
558
+ auth_req = {
559
+ "jsonrpc": "2.0",
560
+ "id": "auth",
561
+ "method": "auth",
562
+ "params": {"token": token}
563
+ }
564
+ await ws.send(json.dumps(auth_req))
565
+
566
+ # Wait for auth response
567
+ auth_resp_raw = await asyncio.wait_for(ws.recv(), timeout=5)
568
+ auth_resp = json.loads(auth_resp_raw)
569
+ if "error" in auth_resp:
570
+ raise Exception(f"Auth failed: {auth_resp['error']}")
586
571
 
587
- async def _rpc_call(ws, method: str, params: dict = None):
588
- """Send a JSON-RPC 2.0 request (fire-and-forget, no response awaited)."""
589
- msg = {"jsonrpc": "2.0", "id": str(uuid.uuid4()), "method": method}
572
+ _ws_global = ws
573
+ print(f"[backup] Connected to Kernel ({_fmt_elapsed(_t0)})")
574
+
575
+ # Start receiver task — wait for system.require_init to trigger _do_init
576
+ receiver_task = asyncio.create_task(_ws_receiver(ws))
577
+ try:
578
+ # Wait for receiver to finish (connection closed or error)
579
+ await receiver_task
580
+ finally:
581
+ receiver_task.cancel()
582
+ for fut in _pending_rpc.values():
583
+ if not fut.done():
584
+ fut.set_result({"error": {"code": -32001, "message": "Connection lost"}})
585
+ _pending_rpc.clear()
586
+
587
+
588
+ async def _ws_receiver(ws):
589
+ """Main connection receive loop: route events, RPC requests, and RPC responses.
590
+ Detects system.require_init to trigger _do_init."""
591
+ async for raw in ws:
592
+ try:
593
+ msg = json.loads(raw)
594
+ except (json.JSONDecodeError, TypeError):
595
+ continue
596
+
597
+ try:
598
+ has_method = "method" in msg
599
+ has_id = "id" in msg
600
+
601
+ if has_method and not has_id:
602
+ # 检测 system.require_init 事件
603
+ params = msg.get("params", {})
604
+ event_type = params.get("event", "")
605
+ if event_type == "system.require_init":
606
+ asyncio.create_task(_do_init(ws))
607
+ continue
608
+ # Event Notification — run in background to prevent deadlock
609
+ asyncio.create_task(_handle_event_notification(msg))
610
+ elif has_method and has_id:
611
+ # Incoming RPC request — run in background to prevent deadlock
612
+ asyncio.create_task(_handle_rpc_request(ws, msg))
613
+ elif not has_method and has_id:
614
+ _handle_rpc_response(msg)
615
+ except Exception as e:
616
+ print(f"[backup] 消息处理异常(已忽略): {e}")
617
+
618
+
619
+ async def _rpc_call(ws, method: str, params: dict = None,
620
+ wait_response: bool = True, timeout: float = 3.0) -> dict:
621
+ """JSON-RPC 2.0 request。默认等待响应。"""
622
+ rpc_id = str(uuid.uuid4())
623
+ msg = {"jsonrpc": "2.0", "id": rpc_id, "method": method}
590
624
  if params:
591
625
  msg["params"] = params
626
+
627
+ if not wait_response:
628
+ await ws.send(json.dumps(msg))
629
+ return {}
630
+
631
+ future = asyncio.get_event_loop().create_future()
632
+ _pending_rpc[rpc_id] = future
592
633
  await ws.send(json.dumps(msg))
634
+ try:
635
+ return await asyncio.wait_for(future, timeout=timeout)
636
+ except asyncio.TimeoutError:
637
+ _pending_rpc.pop(rpc_id, None)
638
+ return {"error": {"code": -32000, "message": f"RPC timeout: {method} ({timeout}s)"}}
593
639
 
594
640
 
595
- async def _heartbeat_loop(ws):
596
- """Send registry.heartbeat every 30 seconds to prevent TTL expiration."""
597
- while True:
598
- try:
599
- await asyncio.sleep(30)
600
- if not _shutting_down:
601
- await _rpc_call(ws, "registry.heartbeat", {"module_id": "backup"})
602
- except Exception as e:
603
- print(f"[backup] Heartbeat error: {e}")
604
- break
641
+ def _handle_rpc_response(msg: dict):
642
+ """Route JSON-RPC response to pending future."""
643
+ rpc_id = msg.get("id")
644
+ future = _pending_rpc.pop(rpc_id, None)
645
+ if future and not future.done():
646
+ future.set_result(msg)
605
647
 
606
648
 
607
- async def _publish_event(ws, event: dict):
608
- """Publish an event via RPC event.publish."""
649
+ async def _publish_event(ws, event: str, data: dict = None):
650
+ """Publish event via event.publish RPC (fire-and-forget)."""
609
651
  await _rpc_call(ws, "event.publish", {
610
652
  "event_id": str(uuid.uuid4()),
611
- "event": event.get("event", ""),
612
- "data": event.get("data", {}),
653
+ "event": event,
654
+ "data": data or {},
655
+ }, wait_response=False)
656
+
657
+
658
+ async def _handle_ping_event(data: dict):
659
+ """Handle system.ping event and reply with system.pong."""
660
+ t1 = data.get("ping_time")
661
+ t2 = time.time()
662
+
663
+ await _publish_event(_ws_global, "system.pong", {
664
+ "module_id": MODULE_NAME,
665
+ "ping_time": t1,
666
+ "pong_time": t2,
613
667
  })
614
668
 
615
669
 
@@ -619,6 +673,19 @@ async def _handle_event_notification(msg: dict):
619
673
  event_type = params.get("event", "")
620
674
  data = params.get("data", {})
621
675
 
676
+ # Handle system.ping event
677
+ if event_type == "system.ping":
678
+ await _handle_ping_event(data)
679
+ return
680
+
681
+ # 弹性连接 offer/release
682
+ if event_type == "system.connection.offer":
683
+ asyncio.create_task(_handle_connection_offer(data))
684
+ return
685
+ if event_type == "system.connection.release":
686
+ asyncio.create_task(_handle_connection_release(data))
687
+ return
688
+
622
689
  # Special handling for module.shutdown
623
690
  if event_type == "module.shutdown":
624
691
  target = data.get("module_id", "")
@@ -734,7 +801,7 @@ async def _rpc_get_settings(params: dict) -> dict:
734
801
  "events": frontmatter.get("events"),
735
802
  "subscriptions": frontmatter.get("subscriptions"),
736
803
  "depends_on": frontmatter.get("depends_on"),
737
- "has_config": False, # backup 模块暂无 config.yaml
804
+ "has_config": False, # backup 模块暂无业务配置
738
805
  "config": None,
739
806
  }
740
807
 
@@ -751,9 +818,9 @@ async def _rpc_update_settings(params: dict) -> dict:
751
818
  frontmatter[key] = value
752
819
  _write_module_md(frontmatter, body)
753
820
 
754
- # 更新 config.yaml(如果需要)
821
+ # 更新业务配置(如果需要)
755
822
  if config:
756
- # backup 模块暂无 config.yaml,此处预留接口
823
+ # backup 模块暂无业务配置,此处预留接口
757
824
  pass
758
825
 
759
826
  # 返回更新后的完整设置
@@ -792,53 +859,290 @@ async def _rpc_reset_settings(params: dict) -> dict:
792
859
 
793
860
 
794
861
 
862
+ async def _handle_connection_offer(data):
863
+ """处理 Kernel 下发的 slot token,建立附加连接。"""
864
+ slots = data.get("slots", {})
865
+ for slot_str, info in slots.items():
866
+ slot = int(slot_str)
867
+ token = info.get("token", "")
868
+ if not token or slot in _extra_ws:
869
+ continue
870
+ asyncio.create_task(_connect_slot(slot, token))
871
+
872
+
873
+ async def _connect_slot(slot, token):
874
+ """建立单个 slot 附加连接。"""
875
+ ws_url = f"ws://127.0.0.1:{_kernel_port}/ws"
876
+ try:
877
+ ws = await websockets.connect(ws_url, open_timeout=5, ping_interval=None, close_timeout=5)
878
+ auth_req = {"jsonrpc": "2.0", "id": f"auth-slot-{slot}", "method": "auth", "params": {"token": token}}
879
+ await ws.send(json.dumps(auth_req))
880
+ resp = json.loads(await asyncio.wait_for(ws.recv(), timeout=5))
881
+ if "error" in resp:
882
+ await ws.close()
883
+ return
884
+ _extra_ws[slot] = ws
885
+ _extra_ws_tasks[slot] = asyncio.create_task(_slot_recv_loop(slot, ws))
886
+ print(f"[backup] Slot {slot} connected")
887
+ except Exception as e:
888
+ print(f"[backup] Slot {slot} connect failed: {e}")
889
+
890
+
891
+ async def _slot_recv_loop(slot, ws):
892
+ """附加连接的接收循环:与主连接平等处理所有消息。"""
893
+ try:
894
+ async for raw in ws:
895
+ try:
896
+ msg = json.loads(raw)
897
+ except (json.JSONDecodeError, TypeError):
898
+ continue
899
+ try:
900
+ has_method = "method" in msg
901
+ has_id = "id" in msg
902
+
903
+ if has_method and not has_id:
904
+ asyncio.create_task(_handle_event_notification(msg))
905
+ elif has_method and has_id:
906
+ asyncio.create_task(_handle_rpc_request(ws, msg))
907
+ elif not has_method and has_id:
908
+ _handle_rpc_response(msg)
909
+ except Exception as e:
910
+ print(f"[backup] Slot {slot} 消息处理异常(已忽略): {e}")
911
+ except Exception as e:
912
+ print(f"[backup] Slot {slot} 接收循环异常: {e}")
913
+ finally:
914
+ _extra_ws.pop(slot, None)
915
+ _extra_ws_tasks.pop(slot, None)
916
+
917
+
918
+ async def _handle_connection_release(data):
919
+ """Kernel 请求释放 slot,优雅关闭。"""
920
+ for slot in data.get("slots", []):
921
+ ws = _extra_ws.pop(slot, None)
922
+ task = _extra_ws_tasks.pop(slot, None)
923
+ if ws:
924
+ try:
925
+ await ws.close(code=1000, reason="release")
926
+ except Exception:
927
+ pass
928
+ if task:
929
+ task.cancel()
930
+
931
+
795
932
  async def _handle_shutdown():
796
933
  """Handle module.shutdown event — ack → exiting → cleanup → ready → exit."""
797
934
  global _shutting_down
798
935
  print("[backup] Received shutdown request")
799
936
  _shutting_down = True
800
937
  # Step 1: Send ack (立即确认收到)
801
- await _publish_event(_ws_global, {
802
- "event": "module.shutdown.ack",
803
- "data": {"module_id": "backup"},
804
- })
938
+ await _publish_event(_ws_global, "module.shutdown.ack", {"module_id": "backup"})
805
939
  # Step 2: Send module.exiting (开始清理)
806
- await _publish_event(_ws_global, {
807
- "event": "module.exiting",
808
- "data": {
809
- "module_id": "backup",
810
- "type": "passive",
811
- "reason": "shutdown_requested",
812
- "restart": "auto",
813
- "action": "none",
814
- "timeout": 2.0,
815
- "restart_delay": 0.0,
816
- },
940
+ await _publish_event(_ws_global, "module.exiting", {
941
+ "module_id": "backup",
942
+ "type": "passive",
943
+ "reason": "shutdown_requested",
944
+ "restart": "auto",
945
+ "action": "none",
946
+ "timeout": 2.0,
947
+ "restart_delay": 0.0,
817
948
  })
818
949
  # Step 3: Cleanup (nothing to clean up for backup)
950
+ # 关闭所有附加连接
951
+ for _s, _w in list(_extra_ws.items()):
952
+ try:
953
+ await _w.close(code=1000, reason="shutdown")
954
+ except Exception:
955
+ pass
956
+ for _t in _extra_ws_tasks.values():
957
+ _t.cancel()
958
+ _extra_ws.clear()
959
+ _extra_ws_tasks.clear()
819
960
  # Step 4: Send ready (清理完成)
820
- await _publish_event(_ws_global, {
821
- "event": "module.shutdown.ready",
822
- "data": {"module_id": "backup"},
823
- })
961
+ await _publish_event(_ws_global, "module.shutdown.ready", {"module_id": "backup"})
824
962
  print("[backup] Shutdown ready, exiting")
825
- # Step 5: Exit
826
- sys.exit(_exit_code)
963
+
964
+ # 等待 Kernel 处理 shutdown.ready(防止 Close 帧抢先)
965
+ await asyncio.sleep(0.1)
966
+
967
+ # Step 5: Close WebSocket connection gracefully
968
+ if _ws_global:
969
+ try:
970
+ await _ws_global.close(code=1000, reason="Graceful shutdown")
971
+ print("[backup] WebSocket closed")
972
+ except Exception as e:
973
+ print(f"[backup] Failed to close WebSocket: {e}")
974
+
975
+ # Note: Do NOT call sys.exit() in async context
976
+ # Let the event loop naturally complete
827
977
 
828
978
 
829
979
  async def _test_event_loop(ws):
830
980
  """Publish a test event every 10 seconds."""
831
- while True:
832
- await asyncio.sleep(10)
833
- await _publish_event(ws, {
834
- "event": "backup.test",
835
- "data": {
981
+ try:
982
+ while True:
983
+ await asyncio.sleep(10)
984
+ await _publish_event(ws, "backup.test", {
836
985
  "message": "test event from backup",
837
986
  "timestamp": datetime.now(timezone.utc).isoformat(),
838
- },
839
- })
840
- print("[backup] test event published")
987
+ })
988
+ except Exception:
989
+ pass
990
+
991
+
992
+ _startup_config = {} # populated by _validate_and_prepare()
993
+
994
+
995
+ def _validate_and_prepare() -> dict:
996
+ """同步启动验证:日志初始化、读取 token 和 kernel_port。
997
+ 失败直接 sys.exit(1),成功返回启动参数。在 asyncio.run() 之前调用。"""
998
+ t0 = time.monotonic()
999
+ kernel_port = os.environ.get("KITE_KERNEL_PORT")
1000
+ if kernel_port:
1001
+ return _prepare_local_mode(int(kernel_port), t0)
1002
+ config = _load_module_config()
1003
+ gateway_url = config.get("gateway_url") or os.environ.get("KITE_GATEWAY_URL")
1004
+ if gateway_url:
1005
+ return _prepare_remote_mode(gateway_url, t0)
1006
+ print(f"[{MODULE_NAME}] ERROR: No KITE_KERNEL_PORT and no gateway_url")
1007
+ sys.exit(1)
1008
+
1009
+ def _prepare_local_mode(kernel_port: int, t0: float) -> dict:
1010
+ global _log_dir, _log_latest_path, _crash_log_path
1011
+ module_data = os.environ.get("KITE_MODULE_DATA")
1012
+ if module_data:
1013
+ _log_dir = os.path.join(module_data, "log")
1014
+ os.makedirs(_log_dir, exist_ok=True)
1015
+ suffix = os.environ.get("KITE_INSTANCE_SUFFIX", "")
1016
+ _log_latest_path = os.path.join(_log_dir, f"latest{suffix}.log")
1017
+ try:
1018
+ with open(_log_latest_path, "w", encoding="utf-8") as f: pass
1019
+ except Exception: _log_latest_path = None
1020
+ _crash_log_path = os.path.join(_log_dir, f"crashes{suffix}.jsonl")
1021
+ try:
1022
+ with open(_crash_log_path, "w", encoding="utf-8") as f: pass
1023
+ except Exception: _crash_log_path = None
1024
+ _resolve_daily_log_path()
1025
+ _setup_exception_hooks()
1026
+ line = sys.stdin.readline().strip()
1027
+ if not line:
1028
+ print(f"[{MODULE_NAME}] ERROR: stdin closed")
1029
+ sys.exit(1)
1030
+ try: msg = json.loads(line)
1031
+ except json.JSONDecodeError as e:
1032
+ print(f"[{MODULE_NAME}] ERROR: Invalid JSON: {e}")
1033
+ sys.exit(1)
1034
+ if "error" in msg:
1035
+ print(f"[{MODULE_NAME}] 启动失败: {msg.get('message')}")
1036
+ sys.exit(1)
1037
+ token = msg.get("token", "")
1038
+ if not token:
1039
+ print(f"[{MODULE_NAME}] ERROR: No token")
1040
+ sys.exit(1)
1041
+ print(f"[{MODULE_NAME}] Local mode: port={kernel_port}")
1042
+ return {"mode": "local", "token": token, "kernel_port": kernel_port, "t0": t0}
1043
+
1044
+ def _prepare_remote_mode(gateway_url: str, t0: float) -> dict:
1045
+ global _log_dir, _log_latest_path, _crash_log_path
1046
+ home = os.environ.get("HOME") or os.environ.get("USERPROFILE") or os.path.expanduser("~")
1047
+ data_dir = os.path.join(home, ".kite", "remote", MODULE_NAME)
1048
+ os.makedirs(data_dir, exist_ok=True)
1049
+ _log_dir = os.path.join(data_dir, "log")
1050
+ os.makedirs(_log_dir, exist_ok=True)
1051
+ _log_latest_path = os.path.join(_log_dir, "latest.log")
1052
+ try:
1053
+ with open(_log_latest_path, "w", encoding="utf-8") as f: pass
1054
+ except Exception: _log_latest_path = None
1055
+ _crash_log_path = os.path.join(_log_dir, "crashes.jsonl")
1056
+ try:
1057
+ with open(_crash_log_path, "w", encoding="utf-8") as f: pass
1058
+ except Exception: _crash_log_path = None
1059
+ _resolve_daily_log_path()
1060
+ _setup_exception_hooks()
1061
+ kite_token = _get_kite_token(MODULE_NAME, gateway_url)
1062
+ print(f"[{MODULE_NAME}] Remote mode: gateway={gateway_url}")
1063
+ return {"mode": "remote", "gateway_url": gateway_url, "kite_token": kite_token, "t0": t0}
1064
+
1065
+ def _gateway_to_filename(gateway_url: str) -> str:
1066
+ try:
1067
+ from urllib.parse import urlparse
1068
+ parsed = urlparse(gateway_url)
1069
+ host = parsed.hostname or "unknown"
1070
+ port = parsed.port or (443 if parsed.scheme == "wss" else 80)
1071
+ return f"{host}-{port}.json".replace(":", "-").replace("/", "-")
1072
+ except Exception: return "default.json"
1073
+
1074
+ def _load_token_cache(module_name: str, gateway_url: str) -> dict | None:
1075
+ home = os.environ.get("HOME") or os.environ.get("USERPROFILE") or os.path.expanduser("~")
1076
+ token_file = os.path.join(home, ".kite", "remote", module_name, "tokens", _gateway_to_filename(gateway_url))
1077
+ if not os.path.exists(token_file): return None
1078
+ try:
1079
+ with open(token_file, "r") as f: return json.load(f)
1080
+ except Exception: return None
1081
+
1082
+ def _clear_token_cache(module_name: str, gateway_url: str):
1083
+ home = os.environ.get("HOME") or os.environ.get("USERPROFILE") or os.path.expanduser("~")
1084
+ token_file = os.path.join(home, ".kite", "remote", module_name, "tokens", _gateway_to_filename(gateway_url))
1085
+ if os.path.exists(token_file):
1086
+ try: os.remove(token_file)
1087
+ except Exception: pass
1088
+
1089
+ def _get_kite_token(module_name: str, gateway_url: str) -> str:
1090
+ token = os.environ.get("KITE_TOKEN")
1091
+ if token: return token
1092
+ cache = _load_token_cache(module_name, gateway_url)
1093
+ if cache: return cache["token"]
1094
+ print(f"[{module_name}] No token for {gateway_url}")
1095
+ print(f" export KITE_TOKEN=<token>")
1096
+ sys.exit(1)
1097
+
1098
+
1099
+ async def _remote_mode_loop(gateway_url: str, kite_token: str, _t0: float):
1100
+ global _shutting_down, _exit_code
1101
+ retry_count = 0
1102
+ while not _shutting_down and retry_count < 10:
1103
+ try:
1104
+ await _remote_connect(gateway_url, kite_token, _t0)
1105
+ retry_count = 0
1106
+ except asyncio.CancelledError: break
1107
+ except Exception as e:
1108
+ if _shutting_down: break
1109
+ retry_count += 1
1110
+ await asyncio.sleep(min(2 ** retry_count, 60))
1111
+ if retry_count >= 10: _exit_code = 1
1112
+
1113
+ async def _remote_connect(gateway_url: str, kite_token: str, _t0: float):
1114
+ global _ws_global
1115
+ async with websockets.connect(gateway_url, open_timeout=10, ping_interval=30) as ws:
1116
+ challenge = json.loads(await ws.recv())
1117
+ auth_req = {"jsonrpc": "2.0", "id": "auth", "method": "auth.connect",
1118
+ "params": {"nonce": challenge["params"]["nonce"], "module_id": MODULE_NAME,
1119
+ "auth": {"method": "kite_token", "token": kite_token},
1120
+ "client": {"type": "module", "platform": sys.platform}}}
1121
+ await ws.send(json.dumps(auth_req))
1122
+ hello_resp = json.loads(await ws.recv())
1123
+ if "error" in hello_resp:
1124
+ error = hello_resp["error"]
1125
+ if error.get("code") in (4001, 4010, 4011):
1126
+ _clear_token_cache(MODULE_NAME, gateway_url)
1127
+ print(f"[{MODULE_NAME}] Token invalid, re-authenticate")
1128
+ sys.exit(1)
1129
+ raise Exception(f"Connection failed: {error}")
1130
+ print(f"[{MODULE_NAME}] Connected via Gateway")
1131
+ _ws_global = ws
1132
+
1133
+ # Start receiver task — wait for system.require_init to trigger _do_init
1134
+ receiver_task = asyncio.create_task(_ws_receiver(ws))
1135
+ try:
1136
+ await receiver_task
1137
+ finally:
1138
+ receiver_task.cancel()
1139
+ for fut in _pending_rpc.values():
1140
+ if not fut.done():
1141
+ fut.set_result({"error": {"code": -32001, "message": "Connection lost"}})
1142
+ _pending_rpc.clear()
841
1143
 
842
1144
 
843
1145
  if __name__ == "__main__":
1146
+ _startup_config = _validate_and_prepare()
844
1147
  asyncio.run(main())
1148
+ sys.exit(_exit_code)