@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,125 @@
1
+ from datetime import datetime, timezone
2
+ import agentcp
3
+ from pathlib import Path # 新增导入
4
+ import json
5
+ def create_financial_analyzer_json(publisherInfo):
6
+ """创建智能体能力、权限描述"""
7
+ profile_json_data = {
8
+ "publisherInfo": publisherInfo,
9
+ "avaUrl": "https://img0.baidu.com/it/u=727206602,4114969606&fm=253&fmt=auto&app=138&f=JPEG?w=285&h=285",
10
+ "version": "1.0.0",
11
+ "lastUpdated": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
12
+ "name": "智能体搜索",
13
+ "description": "搜索网络中存在的各种能力的智能体",
14
+ "capabilities": {
15
+ "core": ["搜索智能体"],
16
+ "extended": []
17
+ },
18
+ "llm":{
19
+ "model":"qwen-plus", #模型名称,或使用aid
20
+ "num_parameters":"", #模型参数量(如"7B"表示70亿参数)
21
+ "quantization_bits":"", #量化位数(如Q4表示4位量化)
22
+ "context_length":"", #上下文长度(如"4096"表示4096个token)
23
+ },
24
+ "references": {
25
+ "knowledgeBases": [""],
26
+ "tools": [""],
27
+ "companyInfo": [""],
28
+ "productInfo": [""]
29
+ },
30
+ "authorization": {
31
+ "modes": ["free"],
32
+ "fee": {},
33
+ "description": "当前智能体免费使用,无费用",
34
+ "sla": {}
35
+ },
36
+ "input": {
37
+ "types": ["content"], # 目前支持"content", "search", "reasoning_content", "error", 'file',后续会支持语音视频流
38
+ "formats": ["json"], # 详细类型
39
+ "examples": {
40
+ "type": "content",
41
+ "format": "text",
42
+ "content": "搜索智能体:xxx"
43
+ },
44
+ "semantics": [""],
45
+ "compatibleAids": ["*"]
46
+ },
47
+ "output": {
48
+ "types": ["content"],
49
+ "formats": ["markdown"],
50
+ "examples": {
51
+ "type": "content",
52
+ "format": "markdown",
53
+ "content": ""
54
+ },
55
+ "semantics": [""],
56
+ "compatibleAids": [""]
57
+ },
58
+ "supportStream": True, # False代表当前智能体不支持流式输出
59
+ "supportAsync": True,
60
+ "permission": ["*"]
61
+ }
62
+ return profile_json_data
63
+
64
+ def write_agent_profile_json(json_data):
65
+ try:
66
+ import os
67
+ json_path = Path(__file__).resolve()
68
+ json_dir = json_path.parent
69
+ json_file = os.path.join(json_dir, 'agentprofile.json')
70
+ with open(json_file, 'w', encoding='utf-8') as f:
71
+ json.dump(json_data, f, ensure_ascii=False, indent=2)
72
+ print("智能体描述文件已保存至当前目录下agentprofile.json")
73
+ except Exception as e:
74
+ print(f"文件写入失败: {str(e)}")
75
+ exit(1)
76
+
77
+
78
+ if __name__ == "__main__":
79
+ # 创建JSON数据
80
+ # 将加密种子修改为自己的加密种子,可以是随机字符串,也可以是固定字符串,只要保证一致即可。
81
+ acp = agentcp.AgentCP(".",seed_password="888777",debug=False)
82
+ agentid_list = acp.get_aid_list()
83
+ agentid:agentcp.AgentID = None
84
+ while agentid is None:
85
+ print("请选择一个身份(aid):")
86
+ for i, agentid in enumerate(agentid_list):
87
+ print(f"{i+1}. {agentid}")
88
+ print(f"{len(agentid_list)+1}. 创建一个新的身份(aid)")
89
+ choice = input("请输入数字选择一个身份(aid): ")
90
+ try:
91
+ choice = int(choice) - 1
92
+ if choice < 0 or choice > len(agentid_list):
93
+ raise ValueError
94
+ if choice == len(agentid_list):
95
+ aid = input("请输入名称: ")
96
+ agentid = acp.create_aid("agentunion.cn",aid)
97
+ if agentid is None:
98
+ print("创建身份(aid)失败,请打开日志查看原因")
99
+ exit(1)
100
+ agentid_list = acp.get_aid_list()
101
+ else:
102
+ agentid = acp.load_aid(agentid_list[choice])
103
+ if agentid is None:
104
+ print("加载身份(aid)失败,请打开日志查看原因")
105
+ exit(1)
106
+ except ValueError:
107
+ print("无效的选择,请重新输入。")
108
+ print(f"当前选择的身份(aid)是: {str(agentid)}")
109
+ agentid.init_ap_client()
110
+ json_data = create_financial_analyzer_json(agentid.get_publisher_info())
111
+ write_agent_profile_json(json_data)
112
+ select_result = input("是否将文件拷贝到agent公有数据目录下(Y/N): ")
113
+ if select_result.upper() != "Y":
114
+ print("程序运行结束")
115
+ exit(1)
116
+ agentid.create_agent_profile(json_data)
117
+ select_result = input("拷贝成功,是否同步到接入服务器(Y/N): ")
118
+ if select_result.upper() != "Y":
119
+ print("程序运行结束")
120
+ exit(1)
121
+ result = agentid.sync_public_files()
122
+ if result:
123
+ print("文件同步成功!")
124
+ else:
125
+ print("文件同步失败,请初始化ACP时打开日志查看")
@@ -0,0 +1,136 @@
1
+ import os
2
+ import json
3
+ from openai import OpenAI
4
+ import time
5
+ import agentcp
6
+ class QwenClient:
7
+ def __init__(self):
8
+ self.openai_api_key = None
9
+ self.base_url = None
10
+ self.model = None
11
+ self.client = None
12
+ self.acp = agentcp.AgentCP(".",seed_password="888777",debug=True)
13
+ self.agentid:agentcp.AgentID = None
14
+
15
+ def init_ai_client(self,json_data):
16
+ # 从环境变量中获取 API Key 和 Base URL
17
+ self.openai_api_key = json_data.get("OPENAI_API_KEY","")
18
+ self.base_url = json_data.get("BASE_URL","")
19
+ self.model = json_data.get("MODEL","")
20
+ self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url)
21
+
22
+ async def async_message_handler(self, message_data):
23
+ try:
24
+ receiver = message_data.get("receiver")
25
+ sender = message_data.get("sender","") # 获取工具信息
26
+ if self.agentid.id not in receiver:
27
+ print("不是发给我的消息,不处理")
28
+ return
29
+ message_array = self.agentid.get_content_array_from_message(message_data)
30
+ if len(message_array) == 0:
31
+ print("消息内容为空,不处理")
32
+ return
33
+ llm_content = self.agentid.get_content_from_message(message_data)
34
+ stream = message_array[0].get("stream",False) # 获取stream信息
35
+ tools = message_array[0].get("tools",[]) # 获取工具信息
36
+ rolesetting = message_array[0].get("prompt","") # 获取工具信息
37
+ if rolesetting!="" and rolesetting!=None:
38
+ messages = [{"role": "system", "content": rolesetting},{"role": "user", "content": llm_content}]
39
+ else:
40
+ messages = [{"role": "user", "content": llm_content}]
41
+ print(f"\n[处理消息: {sender} : {llm_content}]\n")
42
+ await self.stream_process_query(message_data,messages,sender,stream,tools) #添加await关键字
43
+ except Exception as e:
44
+ import traceback
45
+ print(f"处理消息时发生错误: {e}\n完整堆栈跟踪:\n{traceback.format_exc()}")
46
+
47
+ def send_message_tools_call(self, session_id,sender,llm_content: str,funcallback):
48
+ to_aid_list = [sender]
49
+ msg_block = {
50
+ "type": "tool_call",
51
+ "status": "success",
52
+ "timestamp": int(time.time() * 1000),
53
+ "content": llm_content,
54
+ }
55
+ self.agentid.add_message_handler(funcallback,session_id)
56
+ self.agentid.send_message(session_id,to_aid_list, msg_block)
57
+
58
+ async def stream_process_query(self, message_data:dict, messages: list, sender:str,stream: bool,user_tools:list):
59
+ if user_tools is None:
60
+ user_tools = [] # 确保tools是一个列表,即使它为空
61
+ if len(user_tools) > 0:
62
+ response = self.client.chat.completions.create(
63
+ model=self.model,
64
+ messages=messages,
65
+ stream=stream,
66
+ tools = user_tools
67
+ )
68
+ else:
69
+ response = self.client.chat.completions.create(
70
+ model=self.model,
71
+ messages=messages,
72
+ stream=stream
73
+ )
74
+ session_id = message_data.get("session_id","") # 获取session_id
75
+ content = response.choices[0]
76
+ if content.finish_reason == "tool_calls":
77
+ tool_call = content.message.tool_calls[0]
78
+ tool_name = tool_call.function.name
79
+ tool_args = json.loads(tool_call.function.arguments)
80
+ print(f"\n[Calling tool {tool_name} with args {tool_args}]\n")
81
+ async def funcallback(result_content):
82
+ self.agentid.remove_message_handler(funcallback,session_id)
83
+ messages.append(content.message.model_dump())
84
+ messages.append({
85
+ "role": "tool",
86
+ "content": self.agentid.get_content_from_message(result_content),
87
+ "tool_call_id": tool_call.id,
88
+ })
89
+ await self.stream_process_query(message_data,messages,sender,stream,user_tools)
90
+ tool_content = {
91
+ 'tool_name':tool_name,
92
+ 'tool_args':tool_args,
93
+ }
94
+ self.send_message_tools_call(session_id,sender,json.dumps(tool_content),funcallback)
95
+ return
96
+ if stream:
97
+ await self.agentid.send_stream_message(message_data.get("session_id"),[sender] , response) # 确保正确调用
98
+ else:
99
+ return self.agentid.reply_message(message_data, content.message.content)
100
+
101
+ def main():
102
+ client = QwenClient()
103
+ print("欢迎使用阿里千问 AGENT!")
104
+ try:
105
+ client.agentid = client.acp.load_aid("your_aid")
106
+ @client.agentid.message_handler()
107
+ async def sync_message_handler(msg):
108
+ await client.async_message_handler(msg) # 添加await关键字
109
+ return True
110
+ print("开始在线...")
111
+ env_path = os.path.join(client.agentid.get_agent_private_path(), "data", "env.json")
112
+ # 新增文件读取逻辑
113
+ try:
114
+ with open(env_path, 'r', encoding='utf-8') as f:
115
+ env_data = json.load(f)
116
+ client.init_ai_client(env_data)
117
+ print(f"成功加载配置文件: {env_path}")
118
+ except FileNotFoundError:
119
+ print(f"配置文件 {env_path} 未找到")
120
+ exit(1)
121
+ except json.JSONDecodeError:
122
+ print(f"配置文件 {env_path} 格式错误")
123
+ exit(1)
124
+ except Exception as e:
125
+ print(f"加载配置失败: {str(e)}")
126
+ exit(1)
127
+ client.agentid.online() # 确保self.agentid不为None
128
+ private_path = client.agentid.get_agent_private_path() # 获取私钥路径
129
+ print("开始监听消息...")
130
+ client.acp.serve_forever()
131
+ except Exception as e:
132
+ import traceback
133
+ print(f"\n⚠️ 发生错误: {traceback.format_exc()}") # 添加堆栈信息打印
134
+
135
+ if __name__ == "__main__":
136
+ main()
@@ -0,0 +1,170 @@
1
+ import asyncio
2
+ import json
3
+ import time
4
+ import agentcp
5
+ from pathlib import Path # 新增导入
6
+ class SearchClient:
7
+ def __init__(self):
8
+ agent_data_path = "."
9
+ self.acp = agentcp.AgentCP(agent_data_path,seed_password="888777")
10
+ self.agentid = None
11
+ self.agent_public_data = []
12
+
13
+ async def async_message_handler(self, message_data):
14
+ try:
15
+ receiver = message_data.get("receiver")
16
+ session_id = message_data.get("session_id") # 获取session_id
17
+ message_id = message_data.get("message_id") # 获取message_id
18
+ print(f"收到消息数据: {session_id} {message_id} {receiver}")
19
+ if self.agentid.id not in receiver:
20
+ print("不是发给我的消息,不处理")
21
+ return
22
+ sender = message_data.get("sender")
23
+ #解析内容
24
+ llm_content = self.agentid.get_content_from_message(message_data)
25
+ print("llm 内容:", llm_content)
26
+ self.send_message(sender,session_id,message_id,"qwenlwj1.agentunion.cn","text",llm_content)
27
+ except json.JSONDecodeError as e:
28
+ import traceback
29
+ print(f"JSON解析错误: {e}\n原始数据: {message_data}\n完整堆栈跟踪:\n{traceback.format_exc()}")
30
+ except Exception as e:
31
+ import traceback
32
+ print(f"处理消息时发生错误: {e}\n完整堆栈跟踪:\n{traceback.format_exc()}")
33
+
34
+ def get_aid_list(self):
35
+ """获取所有 aid 列表"""
36
+ return self.acp.get_aid_list()
37
+
38
+ async def fetch_and_write_public_data(self):
39
+ """每 5 分钟获取公共数据并写入文件"""
40
+ while True:
41
+ try:
42
+ agent_public_data = self.agentid.get_all_public_data()
43
+ aids = ""
44
+ for item in agent_public_data:
45
+ aids+=";"+item['agent_id']
46
+ data=self.agentid.get_online_status(aids)
47
+ # 将 online 为 true 的数据放在前面
48
+ online_items = []
49
+ for item in agent_public_data:
50
+ for item2 in data:
51
+ if item['agent_id'] == item2['agent_id']:
52
+ item['online'] = item2['online']
53
+ if item['online']:
54
+ online_items.append(item)
55
+ self.agent_public_data = online_items
56
+ except Exception as e:
57
+ print(f"获取或写入公共数据时发生错误: {e}")
58
+ await asyncio.sleep(300) # 等待 5 分钟
59
+
60
+
61
+ def send_message_reply(self, session_id,to_aid,type,llm_content: str):
62
+ to_aid_list = []
63
+
64
+ # 我本地的千问agent身份
65
+ to_aid_list.append(to_aid)
66
+ # 修改为直接传递字典而不是对象
67
+ msg_block = {
68
+ "type": type,
69
+ "status": "success",
70
+ "timestamp": int(time.time() * 1000),
71
+ "content": llm_content
72
+ }
73
+ self.agentid.send_message(session_id,to_aid_list, msg_block)
74
+
75
+ def __build_agent_des_prompt(self):
76
+ prompt = """
77
+ # 角色
78
+ 你是一个智能体发现的小助手,你能够根据用户的问题,找到最适合的的一个或多个agent_id,然后返回agent_id字典,key为agent_id,value为agent_id的描述。
79
+ ## 技能
80
+ """
81
+ for item in self.agent_public_data:
82
+ public_data = json.loads(item.get('public_data', "{}"))
83
+ if item['online']:
84
+ prompt += f"""
85
+ ### 技能 {item['agent_id']}: 处理 {public_data['description']} 的查询
86
+ - 当用户询问与 {public_data['description']} 相关的问题时,返回 {item['agent_id']}。
87
+ """
88
+ return prompt + """
89
+ ## 限制
90
+ - 如果找不到合适的技能,返回不知道。
91
+ - 不要做无关agent_id的回复
92
+ """
93
+
94
+ def send_message(self, sender,session_id,message_id,to_aid,type,llm_content: str):
95
+ to_aid_list = []
96
+ async def async_func_session_handler(message):
97
+ # 在这里编写你的异步函数逻辑
98
+ print("异步函数执行中...")
99
+ print("message:",message)
100
+ self.agentid.remove_message_handler(async_func_session_handler,message["session_id"])
101
+ self.send_message_reply(session_id,sender,"content",self.agentid.get_content_from_message(message))
102
+ # 我本地的千问agent身份
103
+ to_aid_list.append(to_aid)
104
+ new_session_id = self.agentid.create_session("临时问题","无")
105
+ self.agentid.invite_member(new_session_id,to_aid)
106
+ # 修改为直接传递字典而不是对象
107
+ msg_block = {
108
+ "type": type,
109
+ "status": "success",
110
+ "timestamp": int(time.time() * 1000),
111
+ "content": llm_content,
112
+ "prompt": self.__build_agent_des_prompt()
113
+ }
114
+ self.agentid.add_message_handler(async_func_session_handler,new_session_id)
115
+ print(f"发送消息: {session_id} {message_id} {new_session_id}")
116
+ self.agentid.send_message(new_session_id,to_aid_list, msg_block)
117
+
118
+ async def main():
119
+ client = SearchClient()
120
+ print("欢迎使用搜索 AGENT!")
121
+ agentid_list = client.acp.get_aid_list()
122
+
123
+ while client.agentid is None:
124
+ print("请选择一个身份(aid):")
125
+ for i, agentid in enumerate(agentid_list):
126
+ print(f"{i+1}. {agentid}")
127
+ print(f"{len(agentid_list)+1}. 创建一个新的身份(aid)")
128
+ choice = input("请输入数字选择一个身份(aid): ")
129
+ try:
130
+ choice = int(choice) - 1
131
+ if choice < 0 or choice > len(agentid_list):
132
+ raise ValueError
133
+ if choice == len(agentid_list):
134
+ aid = input("请输入name: ")
135
+ client.agentid = client.acp.create_aid("agentunion.cn",aid)
136
+ agentid_list = client.acp.get_aid_list()
137
+ else:
138
+ client.agentid = client.acp.load_aid(agentid_list[choice])
139
+ except ValueError:
140
+ print("无效的选择,请重新输入。")
141
+
142
+ try:
143
+ if client.agentid is None:
144
+ print("load error,please check your agentid")
145
+ return None # 确保返回None而不是继续执行
146
+
147
+ # @client.agentid.message_handler
148
+ async def sync_message_handler(msg):
149
+ #print(f"收到消息数据: {msg}")
150
+ await client.async_message_handler(msg) # 添加await关键字
151
+ return True
152
+
153
+ try:
154
+ print("开始在线...")
155
+ client.agentid.online() # 确保self.agentid不为None
156
+ asyncio.create_task(client.fetch_and_write_public_data()) # 启动定时任务
157
+ client.agentid.add_message_handler(sync_message_handler)
158
+ print("开始监听消息...")
159
+ while True:
160
+ await asyncio.sleep(1)
161
+ except AttributeError as e:
162
+ print(f"AgentID未正确初始化: {e}")
163
+ return None
164
+ except Exception as e:
165
+ import traceback
166
+ print(f"\n⚠️ 发生错误: {traceback.format_exc()}") # 添加堆栈信息打印
167
+
168
+ if __name__ == "__main__":
169
+ import sys
170
+ asyncio.run(main())
@@ -0,0 +1,89 @@
1
+
2
+ ## 使用指南
3
+ ### 1、环境要求
4
+ - Python 3.8+
5
+ - [AgentCP SDK](https://pypi.org/project/agentcp/)
6
+ - [Agently SDK](https://pypi.org/project/Agently/)
7
+
8
+ ### 2、安装依赖
9
+ 确保安装以下必要库, ✅ 建议使用 python-dotenv 来加载 .env 文件管理密钥和配置。
10
+ ```bash
11
+ pip install agentcp agently python-dotenv
12
+ ```
13
+ ### 3、创建身份ID
14
+ ```bash
15
+ python create_profile.py
16
+ ```
17
+ ### 4、修改main.py文件
18
+ 将seed_password、agent_id修改为上一步创建的身份信息
19
+
20
+ ### 5、配置.env文件
21
+ 创建.env文件并添加以下信息,并替换为您的实际配置:
22
+ ```json
23
+ {
24
+ "OPENAI_API_KEY": "your_api_key",
25
+ "BASE_URL": "https://api.example.com/v1",
26
+ "MODEL": "model_name"
27
+ }
28
+ ```
29
+
30
+ ### 6、执行main.py代码
31
+ ```bash
32
+ python main.py
33
+ ```
34
+
35
+ ## 功能简介
36
+ 该 Agent 结合了 `agentcp` 和 `agently` 两个库,具备以下核心能力:
37
+
38
+ - 接收并处理外部消息请求
39
+ - 调用大语言模型生成自然语言响应
40
+ - 异步发送处理结果给消息发送者
41
+ - 适用于快速构建具备 智能问答能力 的服务型 Agent。
42
+
43
+ ## 完整示例代码
44
+ ```python
45
+ import agentcp
46
+ import Agently
47
+ import os
48
+ from dotenv import load_dotenv
49
+ load_dotenv()
50
+
51
+ if __name__ == "__main__":
52
+ agent_id = 'your_agent_id_from_profile'
53
+ acp = agentcp.AgentCP('.', seed_password='')
54
+ aid = acp.load_aid(agent_id)
55
+ openai_api_key = os.getenv("OPENAI_API_KEY")
56
+ model_url = os.getenv("BASE_URL")
57
+ model_name = os.getenv("MODEL")
58
+ agent = (
59
+ Agently.create_agent()
60
+ .set_settings("current_model", "OAIClient")
61
+ .set_settings("model.OAIClient.auth", {'api_key': openai_api_key})
62
+ .set_settings("model.OAIClient.url", model_url)
63
+ .set_settings("model.OAIClient.options", {'model': model_name})
64
+ )
65
+
66
+ @aid.message_handler() #消息处理函数
67
+ async def sync_message_handler(msg):
68
+ receiver = aid.get_receiver_from_message(msg) # 获取接收者
69
+ if aid.id not in receiver:
70
+ return
71
+ session_id = aid.get_session_id_from_message(msg)
72
+ sender = aid.get_sender_from_message(msg) # 获取发送者
73
+ sender_content = aid.get_content_from_message(msg)
74
+ result = (
75
+ agent
76
+ .general("输出规定", "必须使用中文进行输出")
77
+ .role({
78
+ "姓名": "ACP小助手",
79
+ "任务": "使用自己的知识为用户解答常见问题",
80
+ })
81
+ .input(sender_content)
82
+ .instruct(["你需要根据用户的问题提供相关的回答", "你可以适当的有点幽默"])
83
+ .start()
84
+ )
85
+ aid.send_message_content(to_aid_list=[sender], session_id=session_id, llm_content=result)
86
+ return True
87
+ aid.online()
88
+ acp.serve_forever()
89
+ ```
@@ -0,0 +1,125 @@
1
+ from datetime import datetime, timezone
2
+ import agentcp
3
+ from pathlib import Path # 新增导入
4
+ import json
5
+ def create_financial_analyzer_json(publisherInfo):
6
+ """创建智能体能力、权限描述"""
7
+ profile_json_data = {
8
+ "publisherInfo": publisherInfo,
9
+ "avaUrl": "https://img0.baidu.com/it/u=727206602,4114969606&fm=253&fmt=auto&app=138&f=JPEG?w=285&h=285",
10
+ "version": "1.0.0",
11
+ "lastUpdated": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
12
+ "name": "Agently封装Agent",
13
+ "description": "使用Agently封装Agent",
14
+ "capabilities": {
15
+ "core": ["聊天智能体"],
16
+ "extended": []
17
+ },
18
+ "llm":{
19
+ "model":"", #模型名称,或使用aid
20
+ "num_parameters":"", #模型参数量(如"7B"表示70亿参数)
21
+ "quantization_bits":"", #量化位数(如Q4表示4位量化)
22
+ "context_length":"", #上下文长度(如"4096"表示4096个token)
23
+ },
24
+ "references": {
25
+ "knowledgeBases": [""],
26
+ "tools": [""],
27
+ "companyInfo": [""],
28
+ "productInfo": [""]
29
+ },
30
+ "authorization": {
31
+ "modes": ["free"],
32
+ "fee": {},
33
+ "description": "当前智能体免费使用,无费用",
34
+ "sla": {}
35
+ },
36
+ "input": {
37
+ "types": ["content"], # 目前支持"content", "search", "reasoning_content", "error", 'file',后续会支持语音视频流
38
+ "formats": ["json"], # 详细类型
39
+ "examples": {
40
+ "type": "content",
41
+ "format": "text",
42
+ "content": "搜索智能体:xxx"
43
+ },
44
+ "semantics": [""],
45
+ "compatibleAids": ["*"]
46
+ },
47
+ "output": {
48
+ "types": ["content"],
49
+ "formats": ["markdown"],
50
+ "examples": {
51
+ "type": "content",
52
+ "format": "markdown",
53
+ "content": ""
54
+ },
55
+ "semantics": [""],
56
+ "compatibleAids": [""]
57
+ },
58
+ "supportStream": True, # False代表当前智能体不支持流式输出
59
+ "supportAsync": True,
60
+ "permission": ["*"]
61
+ }
62
+ return profile_json_data
63
+
64
+ def write_agent_profile_json(json_data):
65
+ try:
66
+ import os
67
+ json_path = Path(__file__).resolve()
68
+ json_dir = json_path.parent
69
+ json_file = os.path.join(json_dir, 'agentprofile.json')
70
+ with open(json_file, 'w', encoding='utf-8') as f:
71
+ json.dump(json_data, f, ensure_ascii=False, indent=2)
72
+ print("智能体描述文件已保存至当前目录下agentprofile.json")
73
+ except Exception as e:
74
+ print(f"文件写入失败: {str(e)}")
75
+ exit(1)
76
+
77
+
78
+ if __name__ == "__main__":
79
+ # 创建JSON数据
80
+ # 将加密种子修改为自己的加密种子,可以是随机字符串,也可以是固定字符串,只要保证一致即可。
81
+ acp = agentcp.AgentCP(".", seed_password='')
82
+ agentid_list = acp.get_aid_list()
83
+ agentid:agentcp.AgentID = None
84
+ while agentid is None:
85
+ print("请选择一个身份(aid):")
86
+ for i, agentid in enumerate(agentid_list):
87
+ print(f"{i+1}. {agentid}")
88
+ print(f"{len(agentid_list)+1}. 创建一个新的身份(aid)")
89
+ choice = input("请输入数字选择一个身份(aid): ")
90
+ try:
91
+ choice = int(choice) - 1
92
+ if choice < 0 or choice > len(agentid_list):
93
+ raise ValueError
94
+ if choice == len(agentid_list):
95
+ aid = input("请输入名称: ")
96
+ agentid = acp.create_aid("agentunion.cn",aid)
97
+ if agentid is None:
98
+ print("创建身份(aid)失败,请打开日志查看原因")
99
+ exit(1)
100
+ agentid_list = acp.get_aid_list()
101
+ else:
102
+ agentid = acp.load_aid(agentid_list[choice])
103
+ if agentid is None:
104
+ print("加载身份(aid)失败,请打开日志查看原因")
105
+ exit(1)
106
+ except ValueError:
107
+ print("无效的选择,请重新输入。")
108
+ print(f"当前选择的身份(aid)是: {str(agentid)}")
109
+ agentid.init_ap_client()
110
+ json_data = create_financial_analyzer_json(agentid.get_publisher_info())
111
+ write_agent_profile_json(json_data)
112
+ select_result = input("是否将文件拷贝到agent公有数据目录下(Y/N): ")
113
+ if select_result.upper() != "Y":
114
+ print("程序运行结束")
115
+ exit(1)
116
+ agentid.create_agent_profile(json_data)
117
+ select_result = input("拷贝成功,是否同步到接入服务器(Y/N): ")
118
+ if select_result.upper() != "Y":
119
+ print("程序运行结束")
120
+ exit(1)
121
+ result = agentid.sync_public_files()
122
+ if result:
123
+ print("文件同步成功!")
124
+ else:
125
+ print("文件同步失败,请初始化ACP时打开日志查看")