@agentunion/kite 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/cli.js +44 -5
  3. package/core/dependency_checker.py +250 -0
  4. package/core/env_checker.py +490 -0
  5. package/dependencies_lock.json +128 -0
  6. package/extensions/agents/assistant/server.py +33 -17
  7. package/extensions/channels/acp_channel/server.py +33 -17
  8. package/extensions/services/backup/entry.py +23 -16
  9. package/extensions/services/evol/auth_manager.py +443 -0
  10. package/extensions/services/evol/config.yaml +149 -0
  11. package/extensions/services/evol/config_loader.py +117 -0
  12. package/extensions/services/evol/entry.py +406 -0
  13. package/extensions/services/evol/evol_api.py +173 -0
  14. package/extensions/services/evol/evol_config.json5 +29 -0
  15. package/extensions/services/evol/migrate_tokens.py +122 -0
  16. package/extensions/services/evol/module.md +32 -0
  17. package/extensions/services/evol/pairing.py +250 -0
  18. package/extensions/services/evol/pairing_codes.jsonl +1 -0
  19. package/extensions/services/evol/relay.py +682 -0
  20. package/extensions/services/evol/relay_config.json5 +67 -0
  21. package/extensions/services/evol/routes/__init__.py +1 -0
  22. package/extensions/services/evol/routes/routes_management_ws.py +127 -0
  23. package/extensions/services/evol/routes/routes_rpc.py +89 -0
  24. package/extensions/services/evol/routes/routes_test.py +61 -0
  25. package/extensions/services/evol/server.py +875 -0
  26. package/extensions/services/evol/static/css/style.css +1200 -0
  27. package/extensions/services/evol/static/index.html +781 -0
  28. package/extensions/services/evol/static/index_evol.html +14 -0
  29. package/extensions/services/evol/static/js/app.js +6304 -0
  30. package/extensions/services/evol/static/js/auth.js +326 -0
  31. package/extensions/services/evol/static/js/dialog.js +285 -0
  32. package/extensions/services/evol/static/js/evol-app-fixed.js +50 -0
  33. package/extensions/services/evol/static/js/evol-app.js +1949 -0
  34. package/extensions/services/evol/static/js/evol-app.js.bak +1800 -0
  35. package/extensions/services/evol/static/js/kernel-client-example.js +228 -0
  36. package/extensions/services/evol/static/js/kernel-client.js +396 -0
  37. package/extensions/services/evol/static/js/main.js +141 -0
  38. package/extensions/services/evol/static/js/registry-tests.js +585 -0
  39. package/extensions/services/evol/static/js/stats.js +217 -0
  40. package/extensions/services/evol/static/js/token-manager.js +175 -0
  41. package/extensions/services/evol/static/pairing.html +248 -0
  42. package/extensions/services/evol/static/test_registry.html +262 -0
  43. package/extensions/services/evol/static/test_relay.html +462 -0
  44. package/extensions/services/evol/stats_manager.py +240 -0
  45. package/extensions/services/model_service/entry.py +23 -1
  46. package/extensions/services/proxy/.claude/settings.local.json +13 -0
  47. package/extensions/services/proxy/CHANGELOG_20260308.md +258 -0
  48. package/extensions/services/proxy/_fix_prints.py +133 -0
  49. package/extensions/services/proxy/_fix_prints2.py +87 -0
  50. package/extensions/services/proxy/agentcp/LICENCE +178 -0
  51. package/extensions/services/proxy/agentcp/README copy.md +85 -0
  52. package/extensions/services/proxy/agentcp/README.md +260 -0
  53. package/extensions/services/proxy/agentcp/__init__.py +16 -0
  54. package/extensions/services/proxy/agentcp/agent.py +4 -0
  55. package/extensions/services/proxy/agentcp/agentcp.py +2494 -0
  56. package/extensions/services/proxy/agentcp/agentprofile.json +89 -0
  57. package/extensions/services/proxy/agentcp/ap/__init__.py +16 -0
  58. package/extensions/services/proxy/agentcp/ap/ap_client.py +316 -0
  59. package/extensions/services/proxy/agentcp/assets/images/wechat_qr.png +0 -0
  60. package/extensions/services/proxy/agentcp/backup/metrics.json +31 -0
  61. package/extensions/services/proxy/agentcp/base/__init__.py +20 -0
  62. package/extensions/services/proxy/agentcp/base/auth_client.py +257 -0
  63. package/extensions/services/proxy/agentcp/base/client.py +112 -0
  64. package/extensions/services/proxy/agentcp/base/env.py +34 -0
  65. package/extensions/services/proxy/agentcp/base/html_util.py +336 -0
  66. package/extensions/services/proxy/agentcp/base/log.py +98 -0
  67. package/extensions/services/proxy/agentcp/ca/__init__.py +17 -0
  68. package/extensions/services/proxy/agentcp/ca/ca_client.py +414 -0
  69. package/extensions/services/proxy/agentcp/ca/ca_root.py +74 -0
  70. package/extensions/services/proxy/agentcp/context/__init__.py +20 -0
  71. package/extensions/services/proxy/agentcp/context/context.py +73 -0
  72. package/extensions/services/proxy/agentcp/context/exceptions.py +114 -0
  73. package/extensions/services/proxy/agentcp/create_profile.py +125 -0
  74. package/extensions/services/proxy/agentcp/create_profile_weather.py +125 -0
  75. package/extensions/services/proxy/agentcp/db/__init__.py +15 -0
  76. package/extensions/services/proxy/agentcp/db/db_mananger.py +550 -0
  77. package/extensions/services/proxy/agentcp/docs/UDP_HEARTBEAT_FIX_REPORT.md +265 -0
  78. package/extensions/services/proxy/agentcp/docs/heartbeat_issue_analysis.md +291 -0
  79. package/extensions/services/proxy/agentcp/file/__init__.py +16 -0
  80. package/extensions/services/proxy/agentcp/file/file_client.py +141 -0
  81. package/extensions/services/proxy/agentcp/file/wss_binary_message.py +137 -0
  82. package/extensions/services/proxy/agentcp/hcp.py +299 -0
  83. package/extensions/services/proxy/agentcp/heartbeat/__init__.py +16 -0
  84. package/extensions/services/proxy/agentcp/heartbeat/heartbeat_client.py +360 -0
  85. package/extensions/services/proxy/agentcp/improved_scheduler.py +498 -0
  86. package/extensions/services/proxy/agentcp/llm_agent_utils.py +249 -0
  87. package/extensions/services/proxy/agentcp/llm_server.py +172 -0
  88. package/extensions/services/proxy/agentcp/mermaid.py +210 -0
  89. package/extensions/services/proxy/agentcp/message.py +149 -0
  90. package/extensions/services/proxy/agentcp/metrics.py +256 -0
  91. package/extensions/services/proxy/agentcp/monitoring/__init__.py +20 -0
  92. package/extensions/services/proxy/agentcp/monitoring/global_monitor.py +27 -0
  93. package/extensions/services/proxy/agentcp/monitoring/metrics_store.py +325 -0
  94. package/extensions/services/proxy/agentcp/monitoring/monitoring_service.py +269 -0
  95. package/extensions/services/proxy/agentcp/monitoring/sliding_window.py +222 -0
  96. package/extensions/services/proxy/agentcp/monitoring/standalone_reader.py +224 -0
  97. package/extensions/services/proxy/agentcp/msg/__init__.py +21 -0
  98. package/extensions/services/proxy/agentcp/msg/connection_manager.py +456 -0
  99. package/extensions/services/proxy/agentcp/msg/message_client.py +2058 -0
  100. package/extensions/services/proxy/agentcp/msg/message_serialize.py +263 -0
  101. package/extensions/services/proxy/agentcp/msg/open_ai_message.py +88 -0
  102. package/extensions/services/proxy/agentcp/msg/session_manager.py +1062 -0
  103. package/extensions/services/proxy/agentcp/msg/stream_client.py +267 -0
  104. package/extensions/services/proxy/agentcp/msg/websocket_file_receiver.py +89 -0
  105. package/extensions/services/proxy/agentcp/msg/ws_logger.py +685 -0
  106. package/extensions/services/proxy/agentcp/msg/wss_binary_message.py +137 -0
  107. package/extensions/services/proxy/agentcp/requirements.txt +7 -0
  108. package/extensions/services/proxy/agentcp/samples/agent_graph/README.md +37 -0
  109. package/extensions/services/proxy/agentcp/samples/agent_graph/agentprofile.json +89 -0
  110. package/extensions/services/proxy/agentcp/samples/agent_graph/create_profile.py +138 -0
  111. package/extensions/services/proxy/agentcp/samples/agent_graph/main.py +164 -0
  112. package/extensions/services/proxy/agentcp/samples/agent_use/create_profile.py +123 -0
  113. package/extensions/services/proxy/agentcp/samples/agent_use/llm/create_profile.py +129 -0
  114. package/extensions/services/proxy/agentcp/samples/agent_use/llm/env.json +5 -0
  115. package/extensions/services/proxy/agentcp/samples/agent_use/llm/main.py +146 -0
  116. package/extensions/services/proxy/agentcp/samples/agent_use/main.py +123 -0
  117. package/extensions/services/proxy/agentcp/samples/agent_use/readme.md +379 -0
  118. package/extensions/services/proxy/agentcp/samples/agent_use/search/create_profile.py +129 -0
  119. package/extensions/services/proxy/agentcp/samples/agent_use/search/main.py +28 -0
  120. package/extensions/services/proxy/agentcp/samples/agent_use/tool/create_profile.py +129 -0
  121. package/extensions/services/proxy/agentcp/samples/agent_use/tool/main.py +20 -0
  122. package/extensions/services/proxy/agentcp/samples/ali_amap/README.md +97 -0
  123. package/extensions/services/proxy/agentcp/samples/ali_amap/amap_agent.py +88 -0
  124. package/extensions/services/proxy/agentcp/samples/ali_amap/create_profile.py +125 -0
  125. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/powershell.py +228 -0
  126. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/software.py +63 -0
  127. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/tools.py +36 -0
  128. package/extensions/services/proxy/agentcp/samples/compute_agent/browser_user.py +41 -0
  129. package/extensions/services/proxy/agentcp/samples/deepseek/README.md +79 -0
  130. package/extensions/services/proxy/agentcp/samples/deepseek/create_profile.py +126 -0
  131. package/extensions/services/proxy/agentcp/samples/deepseek/deepseek.py +42 -0
  132. package/extensions/services/proxy/agentcp/samples/dify_chat/README.md +78 -0
  133. package/extensions/services/proxy/agentcp/samples/dify_chat/create_profile.py +126 -0
  134. package/extensions/services/proxy/agentcp/samples/dify_chat/dify_chat.py +47 -0
  135. package/extensions/services/proxy/agentcp/samples/dify_workflow/README.md +78 -0
  136. package/extensions/services/proxy/agentcp/samples/dify_workflow/create_profile.py +126 -0
  137. package/extensions/services/proxy/agentcp/samples/dify_workflow/dify_workflow.py +46 -0
  138. package/extensions/services/proxy/agentcp/samples/executor/README.md +44 -0
  139. package/extensions/services/proxy/agentcp/samples/executor/agentprofile.json +89 -0
  140. package/extensions/services/proxy/agentcp/samples/executor/create_profile.py +139 -0
  141. package/extensions/services/proxy/agentcp/samples/executor/main.py +160 -0
  142. package/extensions/services/proxy/agentcp/samples/filereader/README.md +45 -0
  143. package/extensions/services/proxy/agentcp/samples/filereader/agentprofile.json +90 -0
  144. package/extensions/services/proxy/agentcp/samples/filereader/create_profile.py +137 -0
  145. package/extensions/services/proxy/agentcp/samples/filereader/main.py +253 -0
  146. package/extensions/services/proxy/agentcp/samples/filewriter/README.md +38 -0
  147. package/extensions/services/proxy/agentcp/samples/filewriter/agentprofile.json +91 -0
  148. package/extensions/services/proxy/agentcp/samples/filewriter/create_profile.py +138 -0
  149. package/extensions/services/proxy/agentcp/samples/filewriter/main.py +289 -0
  150. package/extensions/services/proxy/agentcp/samples/hcp/README.md +85 -0
  151. package/extensions/services/proxy/agentcp/samples/hcp/acp_weather_agent.zip +0 -0
  152. package/extensions/services/proxy/agentcp/samples/hcp/create_profile.py +125 -0
  153. package/extensions/services/proxy/agentcp/samples/hcp/hcp.py +237 -0
  154. package/extensions/services/proxy/agentcp/samples/helloworld/README.md +68 -0
  155. package/extensions/services/proxy/agentcp/samples/helloworld/hello_world.py +40 -0
  156. package/extensions/services/proxy/agentcp/samples/llm_agent/MEADME.md +117 -0
  157. package/extensions/services/proxy/agentcp/samples/llm_agent/create_profile.py +125 -0
  158. package/extensions/services/proxy/agentcp/samples/llm_agent/qwen_agent.py +136 -0
  159. package/extensions/services/proxy/agentcp/samples/local_llm_agent/README.md +90 -0
  160. package/extensions/services/proxy/agentcp/samples/local_llm_agent/create_profile.py +125 -0
  161. package/extensions/services/proxy/agentcp/samples/local_llm_agent/main.py +49 -0
  162. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/README.md +55 -0
  163. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/create_profile.py +125 -0
  164. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/main.py +23 -0
  165. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/README.md +103 -0
  166. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/create_profile.py +125 -0
  167. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/main.py +69 -0
  168. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/README.md +58 -0
  169. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/create_profile.py +125 -0
  170. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/main.py +25 -0
  171. package/extensions/services/proxy/agentcp/samples/qwen3/README.md +71 -0
  172. package/extensions/services/proxy/agentcp/samples/qwen3/create_profile.py +126 -0
  173. package/extensions/services/proxy/agentcp/samples/qwen3/qwen3.py +37 -0
  174. package/extensions/services/proxy/agentcp/samples/qwen3_tools/README.md +133 -0
  175. package/extensions/services/proxy/agentcp/samples/qwen3_tools/create_profile.py +126 -0
  176. package/extensions/services/proxy/agentcp/samples/qwen3_tools/qwen3_tools.py +98 -0
  177. package/extensions/services/proxy/agentcp/samples/search/create_profile_qwen.py +125 -0
  178. package/extensions/services/proxy/agentcp/samples/search/create_profile_search.py +125 -0
  179. package/extensions/services/proxy/agentcp/samples/search/qwen_agent.py +136 -0
  180. package/extensions/services/proxy/agentcp/samples/search/search_agent.py +170 -0
  181. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/README.md +89 -0
  182. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/create_profile.py +125 -0
  183. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/main.py +44 -0
  184. package/extensions/services/proxy/agentcp/utils/__init__.py +15 -0
  185. package/extensions/services/proxy/agentcp/utils/file_util.py +117 -0
  186. package/extensions/services/proxy/agentcp/utils/proxy_bypass.py +99 -0
  187. package/extensions/services/proxy/agentcp/workflow.py +203 -0
  188. package/extensions/services/proxy/console_auth.py +109 -0
  189. package/extensions/services/proxy/evol/__init__.py +1 -0
  190. package/extensions/services/proxy/evol/config.py +37 -0
  191. package/extensions/services/proxy/evol/http/__init__.py +1 -0
  192. package/extensions/services/proxy/evol/http/async_http.py +551 -0
  193. package/extensions/services/proxy/evol/log.py +28 -0
  194. package/extensions/services/proxy/evol/presenter/__init__.py +2 -0
  195. package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +1031 -0
  196. package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +106 -0
  197. package/extensions/services/proxy/evol/presenter/configPresenter.py +1281 -0
  198. package/extensions/services/proxy/evol/presenter/userPresenter.py +477 -0
  199. package/extensions/services/proxy/evol/server/__init__.py +1 -0
  200. package/extensions/services/proxy/evol/server/claude_proxy_async.py +3430 -0
  201. package/extensions/services/proxy/evol/server/openclaw_proxy.py +1861 -0
  202. package/extensions/services/proxy/evol/server/proxy_config.py +15 -0
  203. package/extensions/services/proxy/evol/server/proxy_engine.py +501 -0
  204. package/extensions/services/proxy/evol/version.py +24 -0
  205. package/extensions/services/proxy/logs/websocket.log +260 -0
  206. package/extensions/services/proxy/main.py +240 -0
  207. package/extensions/services/proxy/requirements.txt +13 -0
  208. package/extensions/services/proxy/server.py +271 -0
  209. package/extensions/services/watchdog/entry.py +42 -16
  210. package/extensions/services/watchdog/module.md +1 -0
  211. package/extensions/services/watchdog/monitor.py +34 -4
  212. package/extensions/services/web/module.md +1 -1
  213. package/extensions/services/web/server.py +30 -18
  214. package/extensions/services/web/static/js/token-manager.js +10 -10
  215. package/kernel/entry.py +1 -1
  216. package/kernel/module.md +25 -1
  217. package/kernel/registry_store.py +2 -26
  218. package/kernel/rpc_router.py +36 -10
  219. package/kernel/server.py +106 -17
  220. package/kite_cli/commands/deps_install.py +67 -0
  221. package/kite_cli/commands/env_check.py +45 -0
  222. package/kite_cli/commands/prepare.py +49 -0
  223. package/kite_cli/commands/venv_setup.py +56 -0
  224. package/kite_cli/main.py +29 -1
  225. package/launcher/entry.py +306 -21
  226. package/launcher/module.md +9 -0
  227. package/launcher/module_scanner.py +11 -1
  228. package/main.py +4 -1
  229. package/package.json +8 -1
  230. package/python_version.json +4 -0
  231. package/requirements.txt +38 -0
  232. package/scripts/env-manager.js +328 -0
  233. package/scripts/python-env.js +79 -0
  234. package/scripts/scan_dependencies.py +461 -0
  235. package/scripts/setup-python-env.js +191 -0
@@ -0,0 +1,149 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2025 AgentUnion Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ from dataclasses import dataclass
16
+ from typing import Literal, Optional, Union
17
+
18
+ from agentcp.msg.open_ai_message import OpenAIMessage
19
+
20
+
21
+ @dataclass
22
+ class AgentSelectItemBlock:
23
+ type: Literal["text", "image", "video", "audio"]
24
+ id: str
25
+ content: str
26
+
27
+
28
+ @dataclass
29
+ class AgentFormInputItemBlock:
30
+ id: str
31
+ name: str
32
+ description: str
33
+
34
+
35
+ @dataclass
36
+ class AgentFormBlock:
37
+ id: str
38
+ description: str
39
+ params: Optional[Union[list[AgentSelectItemBlock], AgentFormInputItemBlock]]
40
+ form_type: Literal["single_select", "multiple_select", "time", "input"] = "single_select"
41
+ result: Optional[str] = ""
42
+
43
+
44
+ @dataclass
45
+ class AgentFormItemResultBlock:
46
+ id: str
47
+ result: str
48
+
49
+
50
+ @dataclass
51
+ class AgentFormResultBlock:
52
+ result: Optional[list[AgentFormItemResultBlock]] = None
53
+
54
+
55
+ @dataclass
56
+ class AgentAddFriendBlock:
57
+ aid: str
58
+ description: str
59
+
60
+
61
+ @dataclass
62
+ class AgentFileBlock:
63
+ name: str
64
+ url: str
65
+ content: str
66
+ description: str
67
+ type: str
68
+ encode: str
69
+
70
+
71
+ @dataclass
72
+ class AgentCreateOrderBlock:
73
+ total_amount: int
74
+ description: str
75
+ # 发起者aid
76
+ initiator_aid: str
77
+ # 支付人aid,若为空则为发起者支付
78
+ player_aid: str
79
+ # 支付方式,如alipay,wxpay
80
+ payment_method: str
81
+ # 服务周期,单位为秒,如10分钟为600
82
+ service_period: int
83
+
84
+
85
+ @dataclass
86
+ class AgentOrderBlock:
87
+ total_amount: int
88
+ description: str
89
+ # 发起者aid
90
+ initiator_aid: str
91
+ # 支付人aid,若为空则为发起者支付
92
+ player_aid: str
93
+ # 支付方式,如alipay,wxpay
94
+ payment_method: str
95
+ # 服务周期,单位为秒,如10分钟为600
96
+ service_period: int
97
+ # 担保方aid
98
+ guarantor_aid: str
99
+ order_no: str
100
+ status: Literal["success", "pending", "failed", "canceled"]
101
+ order_query_url: str
102
+ qr_code_url: str
103
+
104
+
105
+ @dataclass
106
+ class AssistantMessageBlock:
107
+ type: Literal[
108
+ "llm",
109
+ "content",
110
+ "search",
111
+ "reasoning_content",
112
+ "error",
113
+ "file",
114
+ "image",
115
+ "tool_call",
116
+ "text/event-stream",
117
+ "video",
118
+ "audio",
119
+ "form",
120
+ "form_result",
121
+ "add_agent",
122
+ "create_order",
123
+ "order",
124
+ ]
125
+ status: Literal["success", "loading", "cancel", "error", "reading", "optimizing"]
126
+ timestamp: int
127
+ block_id: Optional[str] = None
128
+ content: Optional[
129
+ Union[
130
+ str,
131
+ AgentCreateOrderBlock,
132
+ AgentOrderBlock,
133
+ OpenAIMessage,
134
+ AgentFormResultBlock,
135
+ AgentAddFriendBlock,
136
+ AgentFileBlock,
137
+ list[AgentFormBlock],
138
+ ]
139
+ ] = None
140
+ type_format: str = ""
141
+ trace_id: Optional[str] = ""
142
+
143
+
144
+ @dataclass
145
+ class AgentInstructionBlock:
146
+ cmd: str
147
+ params: Optional[dict] = None
148
+ description: Optional[str] = None
149
+ model: str = ""
@@ -0,0 +1,256 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ✅ P1-3新增: 消息处理指标收集器
4
+
5
+ 提供详细的消息处理统计和监控指标
6
+ """
7
+
8
+ import threading
9
+ import time
10
+ from typing import Dict, Any, List
11
+
12
+
13
+ class MessageMetrics:
14
+ """消息处理指标收集器
15
+
16
+ 收集以下指标:
17
+ - 消息接收总数
18
+ - 派发成功/失败数
19
+ - Handler 成功/失败数
20
+ - 派发队列大小
21
+ - 平均延迟
22
+ - 延迟直方图(p50, p95, p99)
23
+ """
24
+
25
+ def __init__(self):
26
+ self.lock = threading.Lock()
27
+
28
+ # 基础计数器
29
+ self.received_total = 0
30
+ self.dispatched_success = 0
31
+ self.dispatched_failed = 0
32
+ self.handler_success = 0
33
+ self.handler_failed = 0
34
+ self.dispatch_queue_size = 0 # ✅ 派发队列大小
35
+
36
+ # 延迟统计
37
+ self.dispatch_latencies: List[float] = [] # 毫秒
38
+ self.handler_latencies: List[float] = [] # 毫秒
39
+ self.max_latency_samples = 1000 # 保留最近 1000 个样本
40
+
41
+ # 平均值缓存
42
+ self._avg_dispatch_latency_ms = 0.0
43
+ self._avg_handler_latency_ms = 0.0
44
+
45
+ # 启动时间
46
+ self.start_time = time.time()
47
+
48
+ def record_received(self):
49
+ """记录收到消息"""
50
+ with self.lock:
51
+ self.received_total += 1
52
+
53
+ def record_dispatch_success(self, latency_ms: float):
54
+ """记录派发成功
55
+
56
+ Args:
57
+ latency_ms: 派发延迟(毫秒)
58
+ """
59
+ with self.lock:
60
+ self.dispatched_success += 1
61
+ self.dispatch_latencies.append(latency_ms)
62
+
63
+ # 保持样本数量在限制内
64
+ if len(self.dispatch_latencies) > self.max_latency_samples:
65
+ self.dispatch_latencies.pop(0)
66
+
67
+ # 更新平均值
68
+ self._avg_dispatch_latency_ms = sum(self.dispatch_latencies) / len(self.dispatch_latencies)
69
+
70
+ def record_dispatch_failure(self):
71
+ """记录派发失败"""
72
+ with self.lock:
73
+ self.dispatched_failed += 1
74
+
75
+ def record_handler_success(self, latency_ms: float):
76
+ """记录 Handler 成功
77
+
78
+ Args:
79
+ latency_ms: 处理延迟(毫秒)
80
+ """
81
+ with self.lock:
82
+ self.handler_success += 1
83
+ self.handler_latencies.append(latency_ms)
84
+
85
+ # 保持样本数量在限制内
86
+ if len(self.handler_latencies) > self.max_latency_samples:
87
+ self.handler_latencies.pop(0)
88
+
89
+ # 更新平均值
90
+ self._avg_handler_latency_ms = sum(self.handler_latencies) / len(self.handler_latencies)
91
+
92
+ def record_handler_failure(self):
93
+ """记录 Handler 失败"""
94
+ with self.lock:
95
+ self.handler_failed += 1
96
+
97
+ def update_dispatch_queue_size(self, count: int):
98
+ """更新派发队列计数
99
+
100
+ Args:
101
+ count: 当前派发队列大小
102
+ """
103
+ with self.lock:
104
+ self.dispatch_queue_size = count
105
+
106
+ def get_summary(self) -> Dict[str, Any]:
107
+ """获取指标摘要
108
+
109
+ Returns:
110
+ 包含所有指标的字典
111
+ """
112
+ with self.lock:
113
+ # 计算成功率
114
+ dispatch_rate = 0.0
115
+ if self.received_total > 0:
116
+ dispatch_rate = (self.dispatched_success / self.received_total) * 100
117
+
118
+ handler_rate = 0.0
119
+ if self.dispatched_success > 0:
120
+ handler_rate = (self.handler_success / self.dispatched_success) * 100
121
+
122
+ # 计算百分位数
123
+ dispatch_p50, dispatch_p95, dispatch_p99 = self._calculate_percentiles(
124
+ self.dispatch_latencies
125
+ )
126
+ handler_p50, handler_p95, handler_p99 = self._calculate_percentiles(
127
+ self.handler_latencies
128
+ )
129
+
130
+ # 运行时间
131
+ uptime_seconds = time.time() - self.start_time
132
+
133
+ return {
134
+ # 基础计数
135
+ "received_total": self.received_total,
136
+ "dispatched_success": self.dispatched_success,
137
+ "dispatched_failed": self.dispatched_failed,
138
+ "handler_success": self.handler_success,
139
+ "handler_failed": self.handler_failed,
140
+ "dispatch_queue_size": self.dispatch_queue_size,
141
+
142
+ # 成功率
143
+ "dispatch_success_rate": f"{dispatch_rate:.2f}%",
144
+ "handler_success_rate": f"{handler_rate:.2f}%",
145
+
146
+ # 延迟统计(毫秒)
147
+ "dispatch_latency": {
148
+ "avg_ms": f"{self._avg_dispatch_latency_ms:.2f}",
149
+ "p50_ms": f"{dispatch_p50:.2f}",
150
+ "p95_ms": f"{dispatch_p95:.2f}",
151
+ "p99_ms": f"{dispatch_p99:.2f}",
152
+ },
153
+ "handler_latency": {
154
+ "avg_ms": f"{self._avg_handler_latency_ms:.2f}",
155
+ "p50_ms": f"{handler_p50:.2f}",
156
+ "p95_ms": f"{handler_p95:.2f}",
157
+ "p99_ms": f"{handler_p99:.2f}",
158
+ },
159
+
160
+ # 吞吐量(每秒)
161
+ "throughput": {
162
+ "messages_per_second": f"{self.received_total / max(1, uptime_seconds):.2f}",
163
+ "dispatched_per_second": f"{self.dispatched_success / max(1, uptime_seconds):.2f}",
164
+ },
165
+
166
+ # 运行时间
167
+ "uptime_seconds": f"{uptime_seconds:.0f}",
168
+ }
169
+
170
+ def _calculate_percentiles(self, data: List[float]) -> tuple:
171
+ """计算百分位数
172
+
173
+ Args:
174
+ data: 数据列表
175
+
176
+ Returns:
177
+ (p50, p95, p99) 元组
178
+ """
179
+ if not data:
180
+ return (0.0, 0.0, 0.0)
181
+
182
+ sorted_data = sorted(data)
183
+ n = len(sorted_data)
184
+
185
+ p50_idx = int(n * 0.50)
186
+ p95_idx = int(n * 0.95)
187
+ p99_idx = int(n * 0.99)
188
+
189
+ return (
190
+ sorted_data[min(p50_idx, n - 1)],
191
+ sorted_data[min(p95_idx, n - 1)],
192
+ sorted_data[min(p99_idx, n - 1)],
193
+ )
194
+
195
+ def reset(self):
196
+ """重置所有指标"""
197
+ with self.lock:
198
+ self.received_total = 0
199
+ self.dispatched_success = 0
200
+ self.dispatched_failed = 0
201
+ self.handler_success = 0
202
+ self.handler_failed = 0
203
+ self.dispatch_queue_size = 0 # ✅ 派发队列大小
204
+
205
+ self.dispatch_latencies.clear()
206
+ self.handler_latencies.clear()
207
+
208
+ self._avg_dispatch_latency_ms = 0.0
209
+ self._avg_handler_latency_ms = 0.0
210
+
211
+ self.start_time = time.time()
212
+
213
+ def print_summary(self):
214
+ """打印指标摘要"""
215
+ summary = self.get_summary()
216
+
217
+ print("\n" + "=" * 60)
218
+ print("📊 AgentCP 消息处理指标")
219
+ print("=" * 60)
220
+
221
+ # 基础计数
222
+ print(f"\n📨 消息统计:")
223
+ print(f" 接收总数: {summary['received_total']}")
224
+ print(f" 派发成功: {summary['dispatched_success']}")
225
+ print(f" 派发失败: {summary['dispatched_failed']}")
226
+ print(f" 处理成功: {summary['handler_success']}")
227
+ print(f" 处理失败: {summary['handler_failed']}")
228
+ print(f" 派发队列: {summary['dispatch_queue_size']}")
229
+
230
+ # 成功率
231
+ print(f"\n✅ 成功率:")
232
+ print(f" 派发成功率: {summary['dispatch_success_rate']}")
233
+ print(f" 处理成功率: {summary['handler_success_rate']}")
234
+
235
+ # 延迟
236
+ print(f"\n⏱️ 延迟统计:")
237
+ print(f" 派发延迟 (ms):")
238
+ print(f" 平均: {summary['dispatch_latency']['avg_ms']}")
239
+ print(f" P50: {summary['dispatch_latency']['p50_ms']}")
240
+ print(f" P95: {summary['dispatch_latency']['p95_ms']}")
241
+ print(f" P99: {summary['dispatch_latency']['p99_ms']}")
242
+
243
+ print(f" 处理延迟 (ms):")
244
+ print(f" 平均: {summary['handler_latency']['avg_ms']}")
245
+ print(f" P50: {summary['handler_latency']['p50_ms']}")
246
+ print(f" P95: {summary['handler_latency']['p95_ms']}")
247
+ print(f" P99: {summary['handler_latency']['p99_ms']}")
248
+
249
+ # 吞吐量
250
+ print(f"\n🚀 吞吐量:")
251
+ print(f" 接收速率: {summary['throughput']['messages_per_second']} msg/s")
252
+ print(f" 派发速率: {summary['throughput']['dispatched_per_second']} msg/s")
253
+
254
+ # 运行时间
255
+ print(f"\n⏰ 运行时间: {summary['uptime_seconds']} 秒")
256
+ print("=" * 60 + "\n")
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ AgentCp 监控模块
4
+
5
+ 提供多时间窗口的监控统计、时间序列存储和实时监控服务
6
+ """
7
+
8
+ from .sliding_window import SlidingWindowMetrics, TimeWindow
9
+ from .metrics_store import MetricsStore
10
+ from .monitoring_service import MonitoringService
11
+ from .standalone_reader import StandaloneMonitoringReader, get_standalone_reader
12
+
13
+ __all__ = [
14
+ 'SlidingWindowMetrics',
15
+ 'TimeWindow',
16
+ 'MetricsStore',
17
+ 'MonitoringService',
18
+ 'StandaloneMonitoringReader',
19
+ 'get_standalone_reader',
20
+ ]
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 全局监控服务单例
4
+
5
+ 提供跨模块访问监控服务的能力,支持AgentID进程和Server进程共享监控数据
6
+ """
7
+
8
+ _global_monitoring_service = None
9
+
10
+
11
+ def set_global_monitoring_service(monitoring_service):
12
+ """设置全局监控服务实例
13
+
14
+ Args:
15
+ monitoring_service: MonitoringService 实例
16
+ """
17
+ global _global_monitoring_service
18
+ _global_monitoring_service = monitoring_service
19
+
20
+
21
+ def get_global_monitoring_service():
22
+ """获取全局监控服务实例
23
+
24
+ Returns:
25
+ MonitoringService 实例,如果未设置则返回 None
26
+ """
27
+ return _global_monitoring_service