@agentunion/kite 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +302 -0
- package/cli.js +119 -4
- package/core/dependency_checker.py +250 -0
- package/core/env_checker.py +490 -0
- package/dependencies_lock.json +128 -0
- package/extensions/agents/assistant/entry.py +111 -1
- package/extensions/agents/assistant/server.py +279 -215
- package/extensions/channels/acp_channel/entry.py +111 -1
- package/extensions/channels/acp_channel/module.md +23 -22
- package/extensions/channels/acp_channel/server.py +279 -215
- package/extensions/event_hub_bench/entry.py +107 -1
- package/extensions/services/backup/entry.py +306 -21
- package/extensions/services/backup/module.md +24 -22
- package/extensions/services/evol/auth_manager.py +443 -0
- package/extensions/services/evol/config.yaml +149 -0
- package/extensions/services/evol/config_loader.py +117 -0
- package/extensions/services/evol/entry.py +406 -0
- package/extensions/services/evol/evol_api.py +173 -0
- package/extensions/services/evol/evol_config.json5 +29 -0
- package/extensions/services/evol/migrate_tokens.py +122 -0
- package/extensions/services/evol/module.md +32 -0
- package/extensions/services/evol/pairing.py +250 -0
- package/extensions/services/evol/pairing_codes.jsonl +1 -0
- package/extensions/services/evol/relay.py +682 -0
- package/extensions/services/evol/relay_config.json5 +67 -0
- package/extensions/services/evol/routes/__init__.py +1 -0
- package/extensions/services/evol/routes/routes_management_ws.py +127 -0
- package/extensions/services/evol/routes/routes_rpc.py +89 -0
- package/extensions/services/evol/routes/routes_test.py +61 -0
- package/extensions/services/evol/server.py +875 -0
- package/extensions/services/evol/static/css/style.css +1200 -0
- package/extensions/services/evol/static/index.html +781 -0
- package/extensions/services/evol/static/index_evol.html +14 -0
- package/extensions/services/evol/static/js/app.js +6304 -0
- package/extensions/services/evol/static/js/auth.js +326 -0
- package/extensions/services/evol/static/js/dialog.js +285 -0
- package/extensions/services/evol/static/js/evol-app-fixed.js +50 -0
- package/extensions/services/evol/static/js/evol-app.js +1949 -0
- package/extensions/services/evol/static/js/evol-app.js.bak +1800 -0
- package/extensions/services/evol/static/js/kernel-client-example.js +228 -0
- package/extensions/services/evol/static/js/kernel-client.js +396 -0
- package/extensions/services/evol/static/js/main.js +141 -0
- package/extensions/services/evol/static/js/registry-tests.js +585 -0
- package/extensions/services/evol/static/js/stats.js +217 -0
- package/extensions/services/evol/static/js/token-manager.js +175 -0
- package/extensions/services/evol/static/pairing.html +248 -0
- package/extensions/services/evol/static/test_registry.html +262 -0
- package/extensions/services/evol/static/test_relay.html +462 -0
- package/extensions/services/evol/stats_manager.py +240 -0
- package/extensions/services/model_service/entry.py +167 -19
- package/extensions/services/model_service/module.md +21 -22
- package/extensions/services/proxy/.claude/settings.local.json +13 -0
- package/extensions/services/proxy/CHANGELOG_20260308.md +258 -0
- package/extensions/services/proxy/_fix_prints.py +133 -0
- package/extensions/services/proxy/_fix_prints2.py +87 -0
- package/extensions/services/proxy/agentcp/LICENCE +178 -0
- package/extensions/services/proxy/agentcp/README copy.md +85 -0
- package/extensions/services/proxy/agentcp/README.md +260 -0
- package/extensions/services/proxy/agentcp/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/agent.py +4 -0
- package/extensions/services/proxy/agentcp/agentcp.py +2494 -0
- package/extensions/services/proxy/agentcp/agentprofile.json +89 -0
- package/extensions/services/proxy/agentcp/ap/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/ap/ap_client.py +316 -0
- package/extensions/services/proxy/agentcp/assets/images/wechat_qr.png +0 -0
- package/extensions/services/proxy/agentcp/backup/metrics.json +31 -0
- package/extensions/services/proxy/agentcp/base/__init__.py +20 -0
- package/extensions/services/proxy/agentcp/base/auth_client.py +257 -0
- package/extensions/services/proxy/agentcp/base/client.py +112 -0
- package/extensions/services/proxy/agentcp/base/env.py +34 -0
- package/extensions/services/proxy/agentcp/base/html_util.py +336 -0
- package/extensions/services/proxy/agentcp/base/log.py +98 -0
- package/extensions/services/proxy/agentcp/ca/__init__.py +17 -0
- package/extensions/services/proxy/agentcp/ca/ca_client.py +414 -0
- package/extensions/services/proxy/agentcp/ca/ca_root.py +74 -0
- package/extensions/services/proxy/agentcp/context/__init__.py +20 -0
- package/extensions/services/proxy/agentcp/context/context.py +73 -0
- package/extensions/services/proxy/agentcp/context/exceptions.py +114 -0
- package/extensions/services/proxy/agentcp/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/create_profile_weather.py +125 -0
- package/extensions/services/proxy/agentcp/db/__init__.py +15 -0
- package/extensions/services/proxy/agentcp/db/db_mananger.py +550 -0
- package/extensions/services/proxy/agentcp/docs/UDP_HEARTBEAT_FIX_REPORT.md +265 -0
- package/extensions/services/proxy/agentcp/docs/heartbeat_issue_analysis.md +291 -0
- package/extensions/services/proxy/agentcp/file/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/file/file_client.py +141 -0
- package/extensions/services/proxy/agentcp/file/wss_binary_message.py +137 -0
- package/extensions/services/proxy/agentcp/hcp.py +299 -0
- package/extensions/services/proxy/agentcp/heartbeat/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/heartbeat/heartbeat_client.py +360 -0
- package/extensions/services/proxy/agentcp/improved_scheduler.py +498 -0
- package/extensions/services/proxy/agentcp/llm_agent_utils.py +249 -0
- package/extensions/services/proxy/agentcp/llm_server.py +172 -0
- package/extensions/services/proxy/agentcp/mermaid.py +210 -0
- package/extensions/services/proxy/agentcp/message.py +149 -0
- package/extensions/services/proxy/agentcp/metrics.py +256 -0
- package/extensions/services/proxy/agentcp/monitoring/__init__.py +20 -0
- package/extensions/services/proxy/agentcp/monitoring/global_monitor.py +27 -0
- package/extensions/services/proxy/agentcp/monitoring/metrics_store.py +325 -0
- package/extensions/services/proxy/agentcp/monitoring/monitoring_service.py +269 -0
- package/extensions/services/proxy/agentcp/monitoring/sliding_window.py +222 -0
- package/extensions/services/proxy/agentcp/monitoring/standalone_reader.py +224 -0
- package/extensions/services/proxy/agentcp/msg/__init__.py +21 -0
- package/extensions/services/proxy/agentcp/msg/connection_manager.py +456 -0
- package/extensions/services/proxy/agentcp/msg/message_client.py +2058 -0
- package/extensions/services/proxy/agentcp/msg/message_serialize.py +263 -0
- package/extensions/services/proxy/agentcp/msg/open_ai_message.py +88 -0
- package/extensions/services/proxy/agentcp/msg/session_manager.py +1062 -0
- package/extensions/services/proxy/agentcp/msg/stream_client.py +267 -0
- package/extensions/services/proxy/agentcp/msg/websocket_file_receiver.py +89 -0
- package/extensions/services/proxy/agentcp/msg/ws_logger.py +685 -0
- package/extensions/services/proxy/agentcp/msg/wss_binary_message.py +137 -0
- package/extensions/services/proxy/agentcp/requirements.txt +7 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/README.md +37 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/agentprofile.json +89 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/create_profile.py +138 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/main.py +164 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/create_profile.py +123 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/llm/create_profile.py +129 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/llm/env.json +5 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/llm/main.py +146 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/main.py +123 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/readme.md +379 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/search/create_profile.py +129 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/search/main.py +28 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/tool/create_profile.py +129 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/tool/main.py +20 -0
- package/extensions/services/proxy/agentcp/samples/ali_amap/README.md +97 -0
- package/extensions/services/proxy/agentcp/samples/ali_amap/amap_agent.py +88 -0
- package/extensions/services/proxy/agentcp/samples/ali_amap/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/agent/powershell.py +228 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/agent/software.py +63 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/agent/tools.py +36 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/browser_user.py +41 -0
- package/extensions/services/proxy/agentcp/samples/deepseek/README.md +79 -0
- package/extensions/services/proxy/agentcp/samples/deepseek/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/deepseek/deepseek.py +42 -0
- package/extensions/services/proxy/agentcp/samples/dify_chat/README.md +78 -0
- package/extensions/services/proxy/agentcp/samples/dify_chat/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/dify_chat/dify_chat.py +47 -0
- package/extensions/services/proxy/agentcp/samples/dify_workflow/README.md +78 -0
- package/extensions/services/proxy/agentcp/samples/dify_workflow/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/dify_workflow/dify_workflow.py +46 -0
- package/extensions/services/proxy/agentcp/samples/executor/README.md +44 -0
- package/extensions/services/proxy/agentcp/samples/executor/agentprofile.json +89 -0
- package/extensions/services/proxy/agentcp/samples/executor/create_profile.py +139 -0
- package/extensions/services/proxy/agentcp/samples/executor/main.py +160 -0
- package/extensions/services/proxy/agentcp/samples/filereader/README.md +45 -0
- package/extensions/services/proxy/agentcp/samples/filereader/agentprofile.json +90 -0
- package/extensions/services/proxy/agentcp/samples/filereader/create_profile.py +137 -0
- package/extensions/services/proxy/agentcp/samples/filereader/main.py +253 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/README.md +38 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/agentprofile.json +91 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/create_profile.py +138 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/main.py +289 -0
- package/extensions/services/proxy/agentcp/samples/hcp/README.md +85 -0
- package/extensions/services/proxy/agentcp/samples/hcp/acp_weather_agent.zip +0 -0
- package/extensions/services/proxy/agentcp/samples/hcp/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/hcp/hcp.py +237 -0
- package/extensions/services/proxy/agentcp/samples/helloworld/README.md +68 -0
- package/extensions/services/proxy/agentcp/samples/helloworld/hello_world.py +40 -0
- package/extensions/services/proxy/agentcp/samples/llm_agent/MEADME.md +117 -0
- package/extensions/services/proxy/agentcp/samples/llm_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/llm_agent/qwen_agent.py +136 -0
- package/extensions/services/proxy/agentcp/samples/local_llm_agent/README.md +90 -0
- package/extensions/services/proxy/agentcp/samples/local_llm_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/local_llm_agent/main.py +49 -0
- package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/README.md +55 -0
- package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/main.py +23 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/README.md +103 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/main.py +69 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/README.md +58 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/main.py +25 -0
- package/extensions/services/proxy/agentcp/samples/qwen3/README.md +71 -0
- package/extensions/services/proxy/agentcp/samples/qwen3/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/qwen3/qwen3.py +37 -0
- package/extensions/services/proxy/agentcp/samples/qwen3_tools/README.md +133 -0
- package/extensions/services/proxy/agentcp/samples/qwen3_tools/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/qwen3_tools/qwen3_tools.py +98 -0
- package/extensions/services/proxy/agentcp/samples/search/create_profile_qwen.py +125 -0
- package/extensions/services/proxy/agentcp/samples/search/create_profile_search.py +125 -0
- package/extensions/services/proxy/agentcp/samples/search/qwen_agent.py +136 -0
- package/extensions/services/proxy/agentcp/samples/search/search_agent.py +170 -0
- package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/README.md +89 -0
- package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/main.py +44 -0
- package/extensions/services/proxy/agentcp/utils/__init__.py +15 -0
- package/extensions/services/proxy/agentcp/utils/file_util.py +117 -0
- package/extensions/services/proxy/agentcp/utils/proxy_bypass.py +99 -0
- package/extensions/services/proxy/agentcp/workflow.py +203 -0
- package/extensions/services/proxy/console_auth.py +109 -0
- package/extensions/services/proxy/evol/__init__.py +1 -0
- package/extensions/services/proxy/evol/config.py +37 -0
- package/extensions/services/proxy/evol/http/__init__.py +1 -0
- package/extensions/services/proxy/evol/http/async_http.py +551 -0
- package/extensions/services/proxy/evol/log.py +28 -0
- package/extensions/services/proxy/evol/presenter/__init__.py +2 -0
- package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +1031 -0
- package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +106 -0
- package/extensions/services/proxy/evol/presenter/configPresenter.py +1281 -0
- package/extensions/services/proxy/evol/presenter/userPresenter.py +477 -0
- package/extensions/services/proxy/evol/server/__init__.py +1 -0
- package/extensions/services/proxy/evol/server/claude_proxy_async.py +3430 -0
- package/extensions/services/proxy/evol/server/openclaw_proxy.py +1861 -0
- package/extensions/services/proxy/evol/server/proxy_config.py +15 -0
- package/extensions/services/proxy/evol/server/proxy_engine.py +501 -0
- package/extensions/services/proxy/evol/version.py +24 -0
- package/extensions/services/proxy/logs/websocket.log +260 -0
- package/extensions/services/proxy/main.py +240 -0
- package/extensions/services/proxy/requirements.txt +13 -0
- package/extensions/services/proxy/server.py +271 -0
- package/extensions/services/watchdog/entry.py +215 -26
- package/extensions/services/watchdog/module.md +1 -0
- package/extensions/services/watchdog/monitor.py +178 -38
- package/extensions/services/web/WEBSOCKET_STATUS.md +143 -0
- package/extensions/services/web/config_example.py +35 -0
- package/extensions/services/web/config_loader.py +110 -0
- package/extensions/services/web/entry.py +114 -26
- package/extensions/services/web/module.md +35 -24
- package/extensions/services/web/pairing.py +250 -0
- package/extensions/services/web/pairing_codes.jsonl +16 -0
- package/extensions/services/web/relay.py +643 -0
- package/extensions/services/web/relay_config.json5 +67 -0
- package/extensions/services/web/routes/routes_management_ws.py +127 -0
- package/extensions/services/web/routes/routes_rpc.py +89 -0
- package/extensions/services/web/routes/routes_test.py +61 -0
- package/extensions/services/web/routes/schemas.py +0 -22
- package/extensions/services/web/server.py +434 -99
- package/extensions/services/web/static/css/style.css +67 -28
- package/extensions/services/web/static/index.html +234 -44
- package/extensions/services/web/static/js/app.js +1335 -48
- package/extensions/services/web/static/js/kernel-client-example.js +161 -0
- package/extensions/services/web/static/js/kernel-client.js +383 -0
- package/extensions/services/web/static/js/registry-tests.js +558 -0
- package/extensions/services/web/static/js/token-manager.js +175 -0
- package/extensions/services/web/static/pairing.html +248 -0
- package/extensions/services/web/static/test_registry.html +262 -0
- package/extensions/services/web/web_config.json5 +29 -0
- package/kernel/entry.py +120 -32
- package/kernel/event_hub.py +141 -16
- package/kernel/module.md +60 -33
- package/kernel/registry_store.py +45 -36
- package/kernel/rpc_router.py +152 -59
- package/kernel/server.py +322 -26
- package/kite_cli/__init__.py +3 -0
- package/kite_cli/__main__.py +5 -0
- package/kite_cli/commands/__init__.py +1 -0
- package/kite_cli/commands/clean.py +101 -0
- package/kite_cli/commands/deps_install.py +67 -0
- package/kite_cli/commands/doctor.py +35 -0
- package/kite_cli/commands/env_check.py +45 -0
- package/kite_cli/commands/history.py +111 -0
- package/kite_cli/commands/info.py +96 -0
- package/kite_cli/commands/install.py +313 -0
- package/kite_cli/commands/list.py +143 -0
- package/kite_cli/commands/log.py +81 -0
- package/kite_cli/commands/prepare.py +49 -0
- package/kite_cli/commands/rollback.py +88 -0
- package/kite_cli/commands/search.py +73 -0
- package/kite_cli/commands/uninstall.py +85 -0
- package/kite_cli/commands/update.py +118 -0
- package/kite_cli/commands/venv_setup.py +56 -0
- package/kite_cli/core/__init__.py +1 -0
- package/kite_cli/core/checker.py +142 -0
- package/kite_cli/core/dependency.py +229 -0
- package/kite_cli/core/downloader.py +209 -0
- package/kite_cli/core/install_info.py +40 -0
- package/kite_cli/core/tool_installer.py +397 -0
- package/kite_cli/core/validator.py +78 -0
- package/kite_cli/main.py +317 -0
- package/kite_cli/utils/__init__.py +1 -0
- package/kite_cli/utils/i18n.py +252 -0
- package/kite_cli/utils/interactive.py +63 -0
- package/kite_cli/utils/operation_log.py +77 -0
- package/kite_cli/utils/paths.py +34 -0
- package/kite_cli/utils/version.py +308 -0
- package/launcher/entry.py +1124 -178
- package/launcher/logging_setup.py +104 -0
- package/launcher/module.md +46 -37
- package/launcher/module_scanner.py +11 -1
- package/main.py +4 -1
- package/package.json +9 -1
- package/python_version.json +4 -0
- package/requirements.txt +38 -0
- package/scripts/env-manager.js +328 -0
- package/scripts/plan_manager.py +315 -0
- package/scripts/python-env.js +79 -0
- package/scripts/scan_dependencies.py +461 -0
- package/scripts/setup-python-env.js +191 -0
- package/extensions/services/web/routes/routes_modules.py +0 -249
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
import asyncio
|
|
16
|
+
from numbers import Number
|
|
17
|
+
import time
|
|
18
|
+
import requests
|
|
19
|
+
import datetime
|
|
20
|
+
import requests
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
from cryptography import x509
|
|
24
|
+
from cryptography.hazmat.primitives import serialization
|
|
25
|
+
from cryptography.hazmat.primitives import hashes
|
|
26
|
+
import datetime
|
|
27
|
+
from cryptography.hazmat.primitives.asymmetric import ec
|
|
28
|
+
|
|
29
|
+
from agentcp.file.wss_binary_message import *
|
|
30
|
+
import websocket
|
|
31
|
+
from agentcp.base.auth_client import AuthClient
|
|
32
|
+
import ssl
|
|
33
|
+
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
|
34
|
+
import os
|
|
35
|
+
|
|
36
|
+
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
|
37
|
+
|
|
38
|
+
class FileClient:
|
|
39
|
+
def __init__(self, aid_path:str,seed_password:str,agent_id: str, agent_network: str, cert: str = None, key: str = None, agent_id_ref=None):
|
|
40
|
+
"""消息客户端类
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
agent_id: 代理ID
|
|
44
|
+
server_url: 服务器URL
|
|
45
|
+
"""
|
|
46
|
+
self.agent_id = agent_id
|
|
47
|
+
self.agent_network = agent_network
|
|
48
|
+
self.server_url = "https://oss." + agent_network + "/api/oss"
|
|
49
|
+
self.cert = cert
|
|
50
|
+
self.key = key
|
|
51
|
+
self._agent_id_ref = agent_id_ref
|
|
52
|
+
self.auth_client = AuthClient(agent_id, self.server_url, aid_path, seed_password)
|
|
53
|
+
self.ws = None
|
|
54
|
+
self.uploaded_url = ""
|
|
55
|
+
|
|
56
|
+
def _get_proxies(self):
|
|
57
|
+
"""获取代理配置(agentcp 内部本地/远程一律直连)"""
|
|
58
|
+
return {}
|
|
59
|
+
|
|
60
|
+
def sign_in(self):
|
|
61
|
+
"""登录方法"""
|
|
62
|
+
self.auth_client.sign_in()
|
|
63
|
+
|
|
64
|
+
def sign_out(self):
|
|
65
|
+
"""登出方法"""
|
|
66
|
+
self.auth_client.sign_out()
|
|
67
|
+
def get_signature(self):
|
|
68
|
+
return self.auth_client.signature
|
|
69
|
+
|
|
70
|
+
def close(self):
|
|
71
|
+
if self.ws is not None:
|
|
72
|
+
self.ws.close()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
#标准的post方式上传文件,同步阻塞的方式上传文件,需要修改为异步,并处理各种可能失败的情况
|
|
76
|
+
def post_file(self, full_path):
|
|
77
|
+
try:
|
|
78
|
+
if self.auth_client.signature is None:
|
|
79
|
+
self.sign_in()
|
|
80
|
+
if self.auth_client.signature is None:
|
|
81
|
+
print("sign_out failed: signature is None")
|
|
82
|
+
return None
|
|
83
|
+
params = {
|
|
84
|
+
'agent_id': self.agent_id,
|
|
85
|
+
'signature': self.auth_client.signature,
|
|
86
|
+
'file_name': os.path.basename(full_path)
|
|
87
|
+
}
|
|
88
|
+
hb_url = self.server_url + f"/upload_file"
|
|
89
|
+
with open(full_path, 'rb') as file:
|
|
90
|
+
files = {'file': file}
|
|
91
|
+
proxies = self._get_proxies()
|
|
92
|
+
response = requests.post(hb_url, data = params, files=files, verify=False, proxies=proxies)
|
|
93
|
+
if response.status_code == 200:
|
|
94
|
+
print('文件上传成功')
|
|
95
|
+
return response.json()["url"]
|
|
96
|
+
else:
|
|
97
|
+
print(f'文件上传失败,状态码: {response.status_code}')
|
|
98
|
+
return None
|
|
99
|
+
except FileNotFoundError:
|
|
100
|
+
print('文件未找到')
|
|
101
|
+
return None
|
|
102
|
+
except Exception as e:
|
|
103
|
+
print(f'发生错误: {e}')
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
def get_uploaded_url(self):
|
|
107
|
+
return self.uploaded_url
|
|
108
|
+
|
|
109
|
+
#仅是测试代码,同步阻塞的方式下载文件,需要修改为异步,并处理各种可能失败的情况
|
|
110
|
+
def download_file(self, url, save_path):
|
|
111
|
+
try:
|
|
112
|
+
if self.auth_client.signature is None:
|
|
113
|
+
self.sign_in()
|
|
114
|
+
if self.auth_client.signature is None:
|
|
115
|
+
print("sign_out failed: signature is None")
|
|
116
|
+
return None
|
|
117
|
+
hb_url = url + f"?agent_id={self.agent_id}&signature={self.auth_client.signature}"
|
|
118
|
+
try:
|
|
119
|
+
# 发送 GET 请求下载文件
|
|
120
|
+
proxies = self._get_proxies()
|
|
121
|
+
response = requests.get(hb_url, verify=False, stream=True, proxies=proxies)
|
|
122
|
+
response.raise_for_status() # 检查请求是否成功
|
|
123
|
+
|
|
124
|
+
# 打开本地文件以写入二进制数据
|
|
125
|
+
with open(save_path, 'wb') as file:
|
|
126
|
+
# 逐块写入文件,避免一次性加载大文件到内存
|
|
127
|
+
for chunk in response.iter_content(chunk_size=16384):
|
|
128
|
+
if chunk: # 过滤掉保持活动的新块
|
|
129
|
+
file.write(chunk)
|
|
130
|
+
|
|
131
|
+
print(f"文件下载成功,保存路径: {save_path}")
|
|
132
|
+
return hb_url,save_path
|
|
133
|
+
except requests.RequestException as e:
|
|
134
|
+
print(f"下载文件时发生请求错误: {e}")
|
|
135
|
+
return hb_url,None
|
|
136
|
+
except Exception as e:
|
|
137
|
+
print(f"下载文件时发生未知错误: {e}")
|
|
138
|
+
return hb_url,None
|
|
139
|
+
except Exception as e:
|
|
140
|
+
print(f"download_file in exception: {e}")
|
|
141
|
+
|
|
@@ -0,0 +1,137 @@
|
|
|
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
|
+
import struct
|
|
16
|
+
import zlib
|
|
17
|
+
import json
|
|
18
|
+
from dataclasses import dataclass
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class WssBinaryMessage:
|
|
22
|
+
"""
|
|
23
|
+
用于存储 WSS 二进制消息中从 magic_byte1 到 payload 的各个字段的数据类。
|
|
24
|
+
"""
|
|
25
|
+
magic_byte1: int
|
|
26
|
+
magic_byte2: int
|
|
27
|
+
version: int
|
|
28
|
+
flags: int
|
|
29
|
+
msg_type: int
|
|
30
|
+
msg_seq: int
|
|
31
|
+
content_type: int
|
|
32
|
+
compressed: int
|
|
33
|
+
reserved: int
|
|
34
|
+
crc32: int
|
|
35
|
+
payload_length: int
|
|
36
|
+
payload: bytes
|
|
37
|
+
|
|
38
|
+
def encode_wss_binary_message(json_data):
|
|
39
|
+
magic_byte1 = ord('M')
|
|
40
|
+
magic_byte2 = ord('U')
|
|
41
|
+
version = 0x101
|
|
42
|
+
flags = 0
|
|
43
|
+
msg_type = 1
|
|
44
|
+
# 假设 msg_seq 初始为 0,可根据实际情况调整
|
|
45
|
+
msg_seq = 0
|
|
46
|
+
payload = json_data.encode()
|
|
47
|
+
if len(payload) < 512:
|
|
48
|
+
content_type = 1
|
|
49
|
+
compressed = 0
|
|
50
|
+
else:
|
|
51
|
+
content_type = 1
|
|
52
|
+
compressed = 1
|
|
53
|
+
payload = zlib.compress(payload)
|
|
54
|
+
reserved = 0
|
|
55
|
+
crc32 = zlib.crc32(payload)
|
|
56
|
+
payload_length = len(payload)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
header = struct.pack('>BBHIHIBBIII', magic_byte1, magic_byte2, version, flags, msg_type, msg_seq, content_type, compressed, reserved, crc32, payload_length)
|
|
60
|
+
#print(f"Header: {header}")
|
|
61
|
+
#print(f"Payload: {payload}")
|
|
62
|
+
return header + payload
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def decode_wss_binary_message(data):
|
|
66
|
+
try:
|
|
67
|
+
magic_byte1, magic_byte2, version, flags, msg_type, msg_seq, content_type, compressed, reserved, crc32, payload_length = struct.unpack('>BBHIHIBBIII', data[:28])
|
|
68
|
+
if magic_byte1 != ord('M') or magic_byte2 != ord('U'):
|
|
69
|
+
return ""
|
|
70
|
+
payload = data[28:]
|
|
71
|
+
if len(payload) != payload_length:
|
|
72
|
+
return ""
|
|
73
|
+
if zlib.crc32(payload) != crc32:
|
|
74
|
+
return ""
|
|
75
|
+
if compressed != 0 and compressed != 1:
|
|
76
|
+
return ""
|
|
77
|
+
if compressed == 1:
|
|
78
|
+
payload = zlib.decompress(payload)
|
|
79
|
+
return payload.decode()
|
|
80
|
+
except (struct.error, zlib.error):
|
|
81
|
+
return ""
|
|
82
|
+
except Exception:
|
|
83
|
+
return ""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def encode_wss_binary_buffer(payload, msg_header: WssBinaryMessage):
|
|
87
|
+
magic_byte1 = ord('M')
|
|
88
|
+
magic_byte2 = ord('U')
|
|
89
|
+
version = msg_header.version
|
|
90
|
+
flags = msg_header.flags
|
|
91
|
+
msg_type = msg_header.msg_type
|
|
92
|
+
# 假设 msg_seq 初始为 0,可根据实际情况调整
|
|
93
|
+
msg_seq = msg_header.msg_seq
|
|
94
|
+
content_type = msg_header.content_type
|
|
95
|
+
compressed = msg_header.compressed
|
|
96
|
+
reserved = msg_header.reserved
|
|
97
|
+
crc32 = zlib.crc32(payload)
|
|
98
|
+
payload_length = len(payload)
|
|
99
|
+
|
|
100
|
+
header = struct.pack('>BBHIHIBBIII', magic_byte1, magic_byte2, version, flags, msg_type, msg_seq, content_type, compressed, reserved, crc32, payload_length)
|
|
101
|
+
#print(f"Header: {header}")
|
|
102
|
+
#print(f"Payload: {payload}")
|
|
103
|
+
return header + payload
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def decode_wss_binary_buffer(data):
|
|
107
|
+
try:
|
|
108
|
+
magic_byte1, magic_byte2, version, flags, msg_type, msg_seq, content_type, compressed, reserved, crc32, payload_length = struct.unpack('>BBHIHIBBIII', data[:28])
|
|
109
|
+
if magic_byte1 != ord('M') or magic_byte2 != ord('U'):
|
|
110
|
+
return None
|
|
111
|
+
payload = data[28:]
|
|
112
|
+
if len(payload) != payload_length:
|
|
113
|
+
return None
|
|
114
|
+
if zlib.crc32(payload) != crc32:
|
|
115
|
+
return None
|
|
116
|
+
if compressed != 0 and compressed != 1:
|
|
117
|
+
return None
|
|
118
|
+
if compressed == 1:
|
|
119
|
+
payload = zlib.decompress(payload)
|
|
120
|
+
|
|
121
|
+
wss_msg = WssBinaryMessage()
|
|
122
|
+
wss_msg.version = version
|
|
123
|
+
wss_msg.flags = flags
|
|
124
|
+
wss_msg.msg_type = msg_type
|
|
125
|
+
wss_msg.msg_seq = msg_seq
|
|
126
|
+
wss_msg.content_type = content_type
|
|
127
|
+
wss_msg.compressed = compressed
|
|
128
|
+
wss_msg.reserved = reserved
|
|
129
|
+
wss_msg.crc32 = crc32
|
|
130
|
+
wss_msg.payload_length = len(payload)
|
|
131
|
+
wss_msg.payload = payload
|
|
132
|
+
|
|
133
|
+
return wss_msg
|
|
134
|
+
except (struct.error, zlib.error):
|
|
135
|
+
return None
|
|
136
|
+
except Exception:
|
|
137
|
+
return None
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from openai import OpenAI
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
import agentcp
|
|
5
|
+
from pathlib import Path # 新增导入
|
|
6
|
+
import os
|
|
7
|
+
from typing import Dict, List, Literal, Optional
|
|
8
|
+
|
|
9
|
+
import traceback
|
|
10
|
+
# 加载 .env 文件,确保 API Key 受到保护
|
|
11
|
+
load_dotenv()
|
|
12
|
+
|
|
13
|
+
class MCPClient:
|
|
14
|
+
def __init__(self):
|
|
15
|
+
"""初始化 MCP 客户端"""
|
|
16
|
+
self.openai_api_key = os.getenv("OPENAI_API_KEY") # 读取 OpenAI API Key
|
|
17
|
+
self.base_url = os.getenv("BASE_URL") # 读取 BASE YRL
|
|
18
|
+
self.model = os.getenv("MODEL") # 读取 model
|
|
19
|
+
if not self.openai_api_key:
|
|
20
|
+
raise ValueError(" × 未找到 OpenAI API Key,请在 .env 文件中设置 OPENAI_API_KEY")
|
|
21
|
+
self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url)
|
|
22
|
+
# 创建OpenAI client
|
|
23
|
+
self.acp = agentcp.AgentCP(".",seed_password="888777",debug=False)
|
|
24
|
+
self.agentid = None
|
|
25
|
+
self.message_store = dict()
|
|
26
|
+
|
|
27
|
+
def record_message(self, session_id: str, role: str, content: str) -> None:
|
|
28
|
+
"""
|
|
29
|
+
记录消息到对话历史
|
|
30
|
+
|
|
31
|
+
参数:
|
|
32
|
+
session_id: 对话会话ID,用于区分不同对话
|
|
33
|
+
role: 消息角色 ('user', 'assistant', 'system')
|
|
34
|
+
content: 消息内容
|
|
35
|
+
"""
|
|
36
|
+
if session_id not in self.message_store:
|
|
37
|
+
self.message_store[session_id] = []
|
|
38
|
+
#'assistant','user','system'
|
|
39
|
+
message = {"role": role, "content": content}
|
|
40
|
+
self.message_store[session_id].append(message)
|
|
41
|
+
|
|
42
|
+
def get_messages_for_llm(
|
|
43
|
+
self,
|
|
44
|
+
session_id: str,
|
|
45
|
+
max_messages: Optional[int] = None,
|
|
46
|
+
system_message: Optional[str] = None
|
|
47
|
+
) -> List[Dict[str, str]]:
|
|
48
|
+
"""
|
|
49
|
+
构造适合大模型调用的历史消息
|
|
50
|
+
|
|
51
|
+
参数:
|
|
52
|
+
session_id: 对话会话ID
|
|
53
|
+
max_messages: 最大返回消息数量(从最新开始计数)
|
|
54
|
+
system_message: 可选系统消息,会放在消息列表开头
|
|
55
|
+
|
|
56
|
+
返回:
|
|
57
|
+
格式化后的消息列表,可直接用于大模型API调用
|
|
58
|
+
"""
|
|
59
|
+
if session_id not in self.message_store:
|
|
60
|
+
return [{"role": "system", "content": system_message}] if system_message else []
|
|
61
|
+
|
|
62
|
+
messages = self.message_store[session_id].copy()
|
|
63
|
+
|
|
64
|
+
# 限制消息数量
|
|
65
|
+
if max_messages is not None and max_messages > 0:
|
|
66
|
+
messages = messages[-max_messages:]
|
|
67
|
+
|
|
68
|
+
# 添加系统消息(如果提供)
|
|
69
|
+
if system_message:
|
|
70
|
+
# 确保系统消息在最前面
|
|
71
|
+
if messages and messages[0]["role"] == "system":
|
|
72
|
+
messages[0]["content"] = system_message # 更新已有系统消息
|
|
73
|
+
else:
|
|
74
|
+
messages.insert(0, {"role": "system", "content": system_message})
|
|
75
|
+
|
|
76
|
+
return messages
|
|
77
|
+
|
|
78
|
+
def clear_messages(self, session_id: str) -> None:
|
|
79
|
+
"""清除指定会话的消息历史"""
|
|
80
|
+
if session_id in self.message_store:
|
|
81
|
+
del self.message_store[session_id]
|
|
82
|
+
|
|
83
|
+
def get_last_message(self, session_id: str) -> Optional[Dict[str, str]]:
|
|
84
|
+
"""获取指定会话的最后一条消息"""
|
|
85
|
+
if session_id in self.message_store and self.message_store[session_id]:
|
|
86
|
+
return self.message_store[session_id][-1]
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
async def process_query(self, query: str,session_id: str,send_aid: str,messages:list = []):
|
|
90
|
+
print(f"\n[Processing query: {query}]\n")
|
|
91
|
+
from datetime import datetime
|
|
92
|
+
now = datetime.now()
|
|
93
|
+
rolesetting = f"""
|
|
94
|
+
您是一个专业的天气查询助手,能够根据用户提供的地理位置或城市名称,快速准确地查询当前天气状况、未来几天的天气预报以及相关的天气建议。请遵循以下规则:
|
|
95
|
+
1. **意图判断**:
|
|
96
|
+
- 判断是否询问天气有关内容
|
|
97
|
+
--如果不是就简单回复用户的问题(20字以内),并引导用户问询天气有关的问题
|
|
98
|
+
--如果是天气有关的问题:
|
|
99
|
+
--- 如果用户未明确指定位置,请主动询问
|
|
100
|
+
--- 如果用户未明确指定时间,请主动询问,但是如果之前已经问过位置信息,那么时间默认为是今天
|
|
101
|
+
--- 如果用户未明确说明他的年龄,请主动询问
|
|
102
|
+
--- 如果询问后仍然缺失,就再尝试一次
|
|
103
|
+
2. **查询位置范围**:
|
|
104
|
+
- 支持地球上的所有城市,只要是个地方就行
|
|
105
|
+
- 如果用户未明确指定地点,先去会话历史中查看用户是否有提到过:
|
|
106
|
+
-- 如果没有,就请主动询问
|
|
107
|
+
-- 如果有,就以最后提到的位置来回答
|
|
108
|
+
3. **查询时间范围**:
|
|
109
|
+
- 任何绝对时间,如3月15日,2024年5月18日
|
|
110
|
+
- 任何相对时间,如三年前,五天前,一周后,明天,后天,大后天,前天,昨天,今天上午
|
|
111
|
+
- 任何年号记年的时间,如万历十五年三月十八日
|
|
112
|
+
- 如果用户未明确指定时间,先去会话历史中查看用户是否有提到过时间:
|
|
113
|
+
-- 如果没有,就主动询问
|
|
114
|
+
-- 如果有提到,就已最后提到的时间来回答
|
|
115
|
+
4. **查询内容**:
|
|
116
|
+
- 当前天气:温度、湿度、风速、天气状况(晴、雨、雪等)。
|
|
117
|
+
- 未来天气预报:未来 3 天的天气趋势。
|
|
118
|
+
- 过去的天气:猜测的天气情况
|
|
119
|
+
- 天气建议:根据天气状况提供穿衣、出行等建议。
|
|
120
|
+
你如果不清楚,可以随意编写
|
|
121
|
+
|
|
122
|
+
例如:
|
|
123
|
+
- 上海今天晴,气温 15°C,湿度 45%,风速 10 km/h。建议穿薄外套。
|
|
124
|
+
- 南京未来三天天气预报如下:
|
|
125
|
+
明天:多云,气温 18°C - 22°C。
|
|
126
|
+
后天:小雨,气温 16°C - 20°C。
|
|
127
|
+
|
|
128
|
+
5. **交互方式**:
|
|
129
|
+
- 使用简洁明了的语言回复用户。
|
|
130
|
+
- 如果用户提供的地点不明确或无法查询,请友好提示并建议重新输入。
|
|
131
|
+
|
|
132
|
+
6. **示例对话**:
|
|
133
|
+
- 用户:今天北京的天气怎么样?
|
|
134
|
+
Agent:北京今天晴,气温 15°C,湿度 45%,风速 10 km/h。建议穿薄外套。
|
|
135
|
+
- 用户:未来三天上海的天气预报?
|
|
136
|
+
Agent:上海未来三天天气预报如下:
|
|
137
|
+
明天:多云,气温 18°C - 22°C。
|
|
138
|
+
后天:小雨,气温 16°C - 20°C。
|
|
139
|
+
第三天:阴,气温 17°C - 21°C。
|
|
140
|
+
|
|
141
|
+
7. **错误处理**:
|
|
142
|
+
- 如果查询失败,请提示用户检查输入或稍后重试。
|
|
143
|
+
- 如果遇到技术问题,请告知用户并建议联系技术支持。
|
|
144
|
+
8. **当前的系统时间**:
|
|
145
|
+
- {now.strftime("%Y-%m-%d %H:%M:%S")}
|
|
146
|
+
9. **如果用户的问题与天气无关,回答字数不要超过20字**
|
|
147
|
+
10. **必要信息**
|
|
148
|
+
- 性别
|
|
149
|
+
- 年龄
|
|
150
|
+
- 位置
|
|
151
|
+
- 时间
|
|
152
|
+
11. **其他的工具**
|
|
153
|
+
- 如果问题需要的工具无法解决,你可以@其他后备的工具来回答这个问题,后备工具包括:
|
|
154
|
+
-- lunzi.aid.pub
|
|
155
|
+
-- lwj.aid.pub
|
|
156
|
+
-- ll.aid.pub
|
|
157
|
+
请始终保持专业、友好和高效的服务态度!
|
|
158
|
+
"""
|
|
159
|
+
if messages is None or len(messages) == 0:
|
|
160
|
+
self.record_message(session_id,'user',query)
|
|
161
|
+
messages = self.get_messages_for_llm(session_id,20,rolesetting)
|
|
162
|
+
|
|
163
|
+
tools = [{
|
|
164
|
+
"type": "function",
|
|
165
|
+
"function": {
|
|
166
|
+
"name": "user_answer",
|
|
167
|
+
"description": "当用户问题缺少必要信息时,调用此方法,返回为用户补全的必要信息",
|
|
168
|
+
"parameters": {
|
|
169
|
+
"type": "object",
|
|
170
|
+
"properties": {
|
|
171
|
+
"question": {
|
|
172
|
+
"type": "string",
|
|
173
|
+
"description": "为询问用户缺少的必要信息的问题"
|
|
174
|
+
},
|
|
175
|
+
"位置": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"description": "上下文中已经知道的位置信息,还不知道就是空字符串"
|
|
178
|
+
},
|
|
179
|
+
"时间": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"description": "上下文中已经知道的时间信息,还不知道就是空字符串"
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
"required": ["question"]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}]
|
|
188
|
+
response = self.client.chat.completions.create(
|
|
189
|
+
model=self.model,
|
|
190
|
+
messages=messages,
|
|
191
|
+
tools = tools
|
|
192
|
+
)
|
|
193
|
+
# 处理返回的内容
|
|
194
|
+
content = response.choices[0]
|
|
195
|
+
if content.finish_reason == "tool_calls":
|
|
196
|
+
# 如何是需要使用工具,就解析工具
|
|
197
|
+
tool_call = content.message.tool_calls[0]
|
|
198
|
+
tool_name = tool_call.function.name
|
|
199
|
+
tool_args = json.loads(tool_call.function.arguments)
|
|
200
|
+
# 执行工具
|
|
201
|
+
print(f"\n[Calling tool {tool_name} with args {tool_args}]\n")
|
|
202
|
+
#将模型返回的调用哪个工具数据和工具执行完成后的数据都存入messages中
|
|
203
|
+
async def sync_wait_user_answer(answer_message):
|
|
204
|
+
self.agentid.remove_message_handler(sync_wait_user_answer,session_id)
|
|
205
|
+
llm_content = self.agentid.get_content_from_message(answer_message)
|
|
206
|
+
#print(f"收到消息数据: {llm_content}")
|
|
207
|
+
messages.append(content.message.model_dump())
|
|
208
|
+
messages.append({
|
|
209
|
+
"role": "tool",
|
|
210
|
+
"content": llm_content,
|
|
211
|
+
"tool_call_id": tool_call.id,
|
|
212
|
+
})
|
|
213
|
+
await self.process_query("",session_id,send_aid,messages)
|
|
214
|
+
return True
|
|
215
|
+
to_aid_list = [send_aid]
|
|
216
|
+
self.agentid.add_message_handler(sync_wait_user_answer,session_id)
|
|
217
|
+
self.agentid.send_message_content(session_id,to_aid_list,f"[from FC]{tool_args['question']}")
|
|
218
|
+
self.record_message(session_id, 'assistant', f"[from FC]{tool_args['question']}")
|
|
219
|
+
print(f"[from FC]{tool_args['question']}")
|
|
220
|
+
return
|
|
221
|
+
to_aid_list = [send_aid]
|
|
222
|
+
self.agentid.send_message_content(session_id,to_aid_list,f"[from LLM answer]{content.message.content}")
|
|
223
|
+
self.record_message(session_id, 'assistant',f"[from LLM answer]{content.message.content}")
|
|
224
|
+
print(f"[from LLM answer]{content.message.content}")
|
|
225
|
+
return
|
|
226
|
+
|
|
227
|
+
def main():
|
|
228
|
+
client = MCPClient()
|
|
229
|
+
client.agentid = client.acp.load_aid("weather.agentunion.cn")
|
|
230
|
+
@client.agentid.message_handler()
|
|
231
|
+
async def async_message_handler(message_data):
|
|
232
|
+
#print(f"收到消息数据: {message_data}")
|
|
233
|
+
try:
|
|
234
|
+
session_id = client.agentid.get_session_id_from_message(message_data)
|
|
235
|
+
llm_content_str = client.agentid.get_content_from_message(message_data)
|
|
236
|
+
send_aid_str = client.agentid.get_sender_from_message(message_data)
|
|
237
|
+
receive_aid_str = client.agentid.get_receiver_from_message(message_data)
|
|
238
|
+
if client.agentid.id not in receive_aid_str:
|
|
239
|
+
#不是发给我的消息,不处理
|
|
240
|
+
return
|
|
241
|
+
await client.process_query(llm_content_str, session_id, send_aid_str)
|
|
242
|
+
except Exception as e:
|
|
243
|
+
print(f"处理消息时发生错误: {e}\n完整堆栈跟踪:\n{traceback.format_exc()}")
|
|
244
|
+
try:
|
|
245
|
+
client.agentid.online()
|
|
246
|
+
print("欢迎使用HCP聊天机器人 AGENT 客户端!")
|
|
247
|
+
client.acp.serve_forever()
|
|
248
|
+
except Exception as e:
|
|
249
|
+
print(f"\n⚠️ 发生错误: {traceback.format_exc()}") # 添加堆栈信息打印
|
|
250
|
+
|
|
251
|
+
if __name__ == "__main__":
|
|
252
|
+
main()
|
|
253
|
+
fomr_block = {
|
|
254
|
+
type:"form",
|
|
255
|
+
"content":[
|
|
256
|
+
{
|
|
257
|
+
"form_type":"input",
|
|
258
|
+
"id":"",
|
|
259
|
+
"description":"请选择你喜欢的手机",
|
|
260
|
+
"params":""
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"form_type":"single_select",
|
|
264
|
+
"description":"请选择你喜欢的手机",
|
|
265
|
+
"id":"",
|
|
266
|
+
"params":[
|
|
267
|
+
{
|
|
268
|
+
"id":"1",
|
|
269
|
+
"type":"text",
|
|
270
|
+
"content":"window 64g",
|
|
271
|
+
"url":""
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"id":"2",
|
|
275
|
+
"type":"text",
|
|
276
|
+
"content":"window 512g",
|
|
277
|
+
"url":""
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"form_type":"multiple_select",
|
|
283
|
+
"description":"请选择你喜欢的手机",
|
|
284
|
+
"id":"",
|
|
285
|
+
"params":[
|
|
286
|
+
{
|
|
287
|
+
"id":"1",
|
|
288
|
+
"type":"text",
|
|
289
|
+
"content":"window 64g"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"id":"2",
|
|
293
|
+
"type":"text",
|
|
294
|
+
"content":"window 512g"
|
|
295
|
+
}
|
|
296
|
+
]
|
|
297
|
+
}
|
|
298
|
+
]
|
|
299
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
|
|
16
|
+
from . import heartbeat_client
|