@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.
- package/CHANGELOG.md +102 -0
- package/cli.js +44 -5
- package/core/dependency_checker.py +250 -0
- package/core/env_checker.py +490 -0
- package/dependencies_lock.json +128 -0
- package/extensions/agents/assistant/server.py +33 -17
- package/extensions/channels/acp_channel/server.py +33 -17
- package/extensions/services/backup/entry.py +23 -16
- 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 +23 -1
- 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 +42 -16
- package/extensions/services/watchdog/module.md +1 -0
- package/extensions/services/watchdog/monitor.py +34 -4
- package/extensions/services/web/module.md +1 -1
- package/extensions/services/web/server.py +30 -18
- package/extensions/services/web/static/js/token-manager.js +10 -10
- package/kernel/entry.py +1 -1
- package/kernel/module.md +25 -1
- package/kernel/registry_store.py +2 -26
- package/kernel/rpc_router.py +36 -10
- package/kernel/server.py +106 -17
- package/kite_cli/commands/deps_install.py +67 -0
- package/kite_cli/commands/env_check.py +45 -0
- package/kite_cli/commands/prepare.py +49 -0
- package/kite_cli/commands/venv_setup.py +56 -0
- package/kite_cli/main.py +29 -1
- package/launcher/entry.py +306 -21
- package/launcher/module.md +9 -0
- package/launcher/module_scanner.py +11 -1
- package/main.py +4 -1
- package/package.json +8 -1
- package/python_version.json +4 -0
- package/requirements.txt +38 -0
- package/scripts/env-manager.js +328 -0
- package/scripts/python-env.js +79 -0
- package/scripts/scan_dependencies.py +461 -0
- package/scripts/setup-python-env.js +191 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import agentcp
|
|
2
|
+
import Agently
|
|
3
|
+
import os
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
load_dotenv()
|
|
6
|
+
|
|
7
|
+
if __name__ == "__main__":
|
|
8
|
+
agent_id = 'your_agent_id_from_profile'
|
|
9
|
+
acp = agentcp.AgentCP('.', seed_password='')
|
|
10
|
+
aid = acp.load_aid(agent_id)
|
|
11
|
+
openai_api_key = os.getenv("OPENAI_API_KEY")
|
|
12
|
+
model_url = os.getenv("BASE_URL")
|
|
13
|
+
model_name = os.getenv("MODEL")
|
|
14
|
+
agent = (
|
|
15
|
+
Agently.create_agent()
|
|
16
|
+
.set_settings("current_model", "OAIClient")
|
|
17
|
+
.set_settings("model.OAIClient.auth", {'api_key': openai_api_key})
|
|
18
|
+
.set_settings("model.OAIClient.url", model_url)
|
|
19
|
+
.set_settings("model.OAIClient.options", {'model': model_name})
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
@aid.message_handler() #消息处理函数
|
|
23
|
+
async def sync_message_handler(msg):
|
|
24
|
+
receiver = aid.get_receiver_from_message(msg) # 获取接收者
|
|
25
|
+
if aid.id not in receiver:
|
|
26
|
+
return
|
|
27
|
+
session_id = aid.get_session_id_from_message(msg)
|
|
28
|
+
sender = aid.get_sender_from_message(msg) # 获取发送者
|
|
29
|
+
sender_content = aid.get_content_from_message(msg)
|
|
30
|
+
result = (
|
|
31
|
+
agent
|
|
32
|
+
.general("输出规定", "必须使用中文进行输出")
|
|
33
|
+
.role({
|
|
34
|
+
"姓名": "ACP小助手",
|
|
35
|
+
"任务": "使用自己的知识为用户解答常见问题",
|
|
36
|
+
})
|
|
37
|
+
.input(sender_content)
|
|
38
|
+
.instruct(["你需要根据用户的问题提供相关的回答", "你可以适当的有点幽默"])
|
|
39
|
+
.start()
|
|
40
|
+
)
|
|
41
|
+
aid.send_message_content(to_aid_list=[sender], session_id=session_id, llm_content=result)
|
|
42
|
+
return True
|
|
43
|
+
aid.online()
|
|
44
|
+
acp.serve_forever()
|
|
@@ -0,0 +1,15 @@
|
|
|
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 . import file_util
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import os
|
|
3
|
+
def get_file_info(file_path: str) -> dict:
|
|
4
|
+
"""
|
|
5
|
+
通过文件路径读取文件信息
|
|
6
|
+
|
|
7
|
+
Args:
|
|
8
|
+
file_path (str): 文件的完整路径
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
dict: 包含文件信息的字典,格式为:
|
|
12
|
+
{
|
|
13
|
+
'file_name': str, # 文件名
|
|
14
|
+
'file_size': int, # 文件大小(字节)
|
|
15
|
+
'file_type': str, # 文件类型/扩展名
|
|
16
|
+
'exists': bool, # 文件是否存在
|
|
17
|
+
'error': str # 错误信息(如果有)
|
|
18
|
+
}
|
|
19
|
+
"""
|
|
20
|
+
try:
|
|
21
|
+
# 检查文件是否存在
|
|
22
|
+
if not os.path.exists(file_path):
|
|
23
|
+
return {
|
|
24
|
+
'file_name': '',
|
|
25
|
+
'file_size': 0,
|
|
26
|
+
'file_type': '',
|
|
27
|
+
'exists': False,
|
|
28
|
+
'error': '文件不存在'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# 检查是否为文件(而不是目录)
|
|
32
|
+
if not os.path.isfile(file_path):
|
|
33
|
+
return {
|
|
34
|
+
'file_name': '',
|
|
35
|
+
'file_size': 0,
|
|
36
|
+
'file_type': '',
|
|
37
|
+
'exists': False,
|
|
38
|
+
'error': '路径不是文件'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# 获取文件信息
|
|
42
|
+
file_stats = os.stat(file_path)
|
|
43
|
+
file_name = os.path.basename(file_path)
|
|
44
|
+
file_size = file_stats.st_size
|
|
45
|
+
|
|
46
|
+
# 获取文件扩展名作为文件类型
|
|
47
|
+
file_type = os.path.splitext(file_path)[1].lower()
|
|
48
|
+
if file_type.startswith('.'):
|
|
49
|
+
file_type = file_type[1:] # 移除开头的点
|
|
50
|
+
|
|
51
|
+
# 如果没有扩展名,尝试根据文件内容判断类型
|
|
52
|
+
if not file_type:
|
|
53
|
+
file_type = _detect_file_type(file_path)
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
'file_name': file_name,
|
|
57
|
+
'file_size': file_size,
|
|
58
|
+
'file_type': file_type,
|
|
59
|
+
'exists': True,
|
|
60
|
+
'error': ''
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
except PermissionError:
|
|
64
|
+
return {
|
|
65
|
+
'file_name': '',
|
|
66
|
+
'file_size': 0,
|
|
67
|
+
'file_type': '',
|
|
68
|
+
'exists': False,
|
|
69
|
+
'error': '没有权限访问文件'
|
|
70
|
+
}
|
|
71
|
+
except Exception as e:
|
|
72
|
+
return {
|
|
73
|
+
'file_name': '',
|
|
74
|
+
'file_size': 0,
|
|
75
|
+
'file_type': '',
|
|
76
|
+
'exists': False,
|
|
77
|
+
'error': f'读取文件信息时发生错误: {str(e)}'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
def _detect_file_type(file_path: str) -> str:
|
|
81
|
+
"""
|
|
82
|
+
当文件没有扩展名时,尝试检测文件类型
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
file_path (str): 文件路径
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
str: 检测到的文件类型
|
|
89
|
+
"""
|
|
90
|
+
try:
|
|
91
|
+
with open(file_path, 'rb') as f:
|
|
92
|
+
# 读取文件头部字节来判断文件类型
|
|
93
|
+
header = f.read(16)
|
|
94
|
+
|
|
95
|
+
# 常见文件类型的魔数检测
|
|
96
|
+
if header.startswith(b'\x89PNG\r\n\x1a\n'):
|
|
97
|
+
return 'png'
|
|
98
|
+
elif header.startswith(b'\xff\xd8\xff'):
|
|
99
|
+
return 'jpg'
|
|
100
|
+
elif header.startswith(b'GIF8'):
|
|
101
|
+
return 'gif'
|
|
102
|
+
elif header.startswith(b'%PDF'):
|
|
103
|
+
return 'pdf'
|
|
104
|
+
elif header.startswith(b'PK\x03\x04'):
|
|
105
|
+
return 'zip'
|
|
106
|
+
elif header.startswith(b'\x50\x4b\x03\x04'):
|
|
107
|
+
return 'zip'
|
|
108
|
+
else:
|
|
109
|
+
# 尝试作为文本文件读取
|
|
110
|
+
try:
|
|
111
|
+
f.seek(0)
|
|
112
|
+
f.read().decode('utf-8')
|
|
113
|
+
return 'txt'
|
|
114
|
+
except UnicodeDecodeError:
|
|
115
|
+
return 'binary'
|
|
116
|
+
except Exception:
|
|
117
|
+
return 'unknown'
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import os
|
|
3
|
+
from contextlib import contextmanager
|
|
4
|
+
from urllib.parse import urlparse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
_LOCAL_HOSTS = ("localhost", "127.0.0.1", "::1", "0.0.0.0")
|
|
8
|
+
_LOCAL_NO_PROXY = "localhost,127.0.0.1,::1"
|
|
9
|
+
LOCAL_NO_PROXY_LIST = ["localhost", "127.0.0.1", "::1"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def ensure_no_proxy_for_local_env() -> None:
|
|
13
|
+
"""Ensure NO_PROXY/no_proxy includes localhost, as a safety net against global proxies."""
|
|
14
|
+
for key in ("NO_PROXY", "no_proxy"):
|
|
15
|
+
existing = (os.environ.get(key) or "").strip()
|
|
16
|
+
if not existing:
|
|
17
|
+
os.environ[key] = _LOCAL_NO_PROXY
|
|
18
|
+
continue
|
|
19
|
+
|
|
20
|
+
existing_parts = [p.strip() for p in existing.replace(";", ",").split(",") if p.strip()]
|
|
21
|
+
existing_lower = {p.lower() for p in existing_parts}
|
|
22
|
+
for host in _LOCAL_NO_PROXY.split(","):
|
|
23
|
+
if host.lower() not in existing_lower:
|
|
24
|
+
existing_parts.append(host)
|
|
25
|
+
os.environ[key] = ",".join(existing_parts)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def is_local_url(url: str) -> bool:
|
|
29
|
+
"""Return True when URL hostname is localhost/loopback."""
|
|
30
|
+
try:
|
|
31
|
+
parsed = urlparse(url)
|
|
32
|
+
host = parsed.hostname
|
|
33
|
+
if not host:
|
|
34
|
+
return False
|
|
35
|
+
host = host.strip("[]").lower()
|
|
36
|
+
return host in _LOCAL_HOSTS
|
|
37
|
+
except Exception:
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_requests_proxies(use_system_proxy: bool, url: str):
|
|
42
|
+
"""
|
|
43
|
+
For requests:
|
|
44
|
+
- {} disables proxy
|
|
45
|
+
- None uses env/system proxy
|
|
46
|
+
"""
|
|
47
|
+
return {}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_trust_env(use_system_proxy: bool, url: str) -> bool:
|
|
51
|
+
"""For httpx/aiohttp trust_env: never trust env proxy for any URL."""
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def pop_proxy_env():
|
|
56
|
+
"""Remove proxy env vars and return the saved mapping for restoration."""
|
|
57
|
+
keys = (
|
|
58
|
+
"HTTP_PROXY",
|
|
59
|
+
"HTTPS_PROXY",
|
|
60
|
+
"ALL_PROXY",
|
|
61
|
+
"FTP_PROXY",
|
|
62
|
+
"SOCKS_PROXY",
|
|
63
|
+
"http_proxy",
|
|
64
|
+
"https_proxy",
|
|
65
|
+
"all_proxy",
|
|
66
|
+
"ftp_proxy",
|
|
67
|
+
"socks_proxy",
|
|
68
|
+
)
|
|
69
|
+
saved = {k: os.environ.get(k) for k in keys}
|
|
70
|
+
for k in keys:
|
|
71
|
+
os.environ.pop(k, None)
|
|
72
|
+
return saved
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def restore_proxy_env(saved) -> None:
|
|
76
|
+
if not saved:
|
|
77
|
+
return
|
|
78
|
+
for k, v in saved.items():
|
|
79
|
+
if v is None:
|
|
80
|
+
os.environ.pop(k, None)
|
|
81
|
+
else:
|
|
82
|
+
os.environ[k] = v
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@contextmanager
|
|
86
|
+
def without_proxy_env(enabled: bool = True):
|
|
87
|
+
"""
|
|
88
|
+
Temporarily remove proxy env vars (HTTP(S)_PROXY/ALL_PROXY and lowercase variants).
|
|
89
|
+
Useful for websocket libraries that consult env proxies.
|
|
90
|
+
"""
|
|
91
|
+
if not enabled:
|
|
92
|
+
yield
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
saved = pop_proxy_env()
|
|
96
|
+
try:
|
|
97
|
+
yield
|
|
98
|
+
finally:
|
|
99
|
+
restore_proxy_env(saved)
|
|
@@ -0,0 +1,203 @@
|
|
|
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
|
+
"""
|
|
17
|
+
我们来详细实现Workflow:
|
|
18
|
+
1.Mermaid类是mermaid语法的解析器,类构造实例的时候传入mermaid语法的文本,得到流程图的节点和边.目前只支持graph
|
|
19
|
+
2.Workflow类是用来处理任意工作流,在构造实例的时候传入一个Mermaid的实例作为整个工作流参考的基础
|
|
20
|
+
3.各节点类通过装饰器output_port和input_port来定义节点的输入输出端口
|
|
21
|
+
4.节点通过Workflow的addnode方法加入工作流,工作流在调用start方法的时候,根据mermaid的节点和边的关系建立各节点实例输入输出端口之间的绑定关系
|
|
22
|
+
5.在定义Agent的时候, 不同的Agent需要有不同Agent的类
|
|
23
|
+
6.每个Agent类, 他有具体的输入输出端口, 这些输入输出端口是通过装饰器来定义
|
|
24
|
+
7.装饰器做两件事:
|
|
25
|
+
1.完成参数的传递
|
|
26
|
+
2.完成端口函数名字和端口注解的绑定(可以在函数定义里面的注释部分来描述这个端口是做什么用的,
|
|
27
|
+
他应该与mermaid里面的流程里面的描述词一样)
|
|
28
|
+
8.通过workflow.start的时候, 首先将已经通过addmode加入的节点之间, 让输入输出端口之间根据描述词建立绑定关系.
|
|
29
|
+
这样, 当一个输出端口执行完毕后, 将自动开始调用其指向的下一个Agent的输入端口函数
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
# 引入acp的库
|
|
33
|
+
# import time
|
|
34
|
+
import threading
|
|
35
|
+
|
|
36
|
+
from inspect import iscoroutinefunction
|
|
37
|
+
import asyncio
|
|
38
|
+
|
|
39
|
+
from .mermaid import Mermaid
|
|
40
|
+
from functools import wraps
|
|
41
|
+
from collections import defaultdict
|
|
42
|
+
|
|
43
|
+
from agentcp.base.log import log_error, log_info, log_warning
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Workflow:
|
|
47
|
+
_workflow_lock = threading.Lock()
|
|
48
|
+
_workflow_storage = dict()
|
|
49
|
+
|
|
50
|
+
def output_port(description: str):
|
|
51
|
+
"""
|
|
52
|
+
输出端口的函数参数定义无限制,只要他的调用者(通常就是当前节点自己的输入端口函数中)正确的传递参数即可
|
|
53
|
+
输入端口的函数参数定义,是一个字符串,其实原则上也是没有限制的,只要调用者参数传递争取即可
|
|
54
|
+
|
|
55
|
+
:return:
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
# 输出端口的函数定义是随便的,只要他的调用者正确的传递参数即可
|
|
59
|
+
#
|
|
60
|
+
def decorator(func):
|
|
61
|
+
func.is_output_port = True
|
|
62
|
+
func.output_port_desc = description
|
|
63
|
+
|
|
64
|
+
@wraps(func)
|
|
65
|
+
def wrapper(self, *args, **kwargs):
|
|
66
|
+
try:
|
|
67
|
+
result = func(self, *args, **kwargs)
|
|
68
|
+
|
|
69
|
+
workflow = self._workflow
|
|
70
|
+
|
|
71
|
+
output_port_name = f"{self.__class__.__name__}:{func.__name__}"
|
|
72
|
+
target_port, target_port_name = workflow.port_mapping.get(output_port_name, (None, None))
|
|
73
|
+
if target_port:
|
|
74
|
+
# 判断是否为异步方法并处理
|
|
75
|
+
if iscoroutinefunction(target_port):
|
|
76
|
+
# 获取或创建事件循环
|
|
77
|
+
try:
|
|
78
|
+
loop = asyncio.get_running_loop()
|
|
79
|
+
except RuntimeError:
|
|
80
|
+
loop = asyncio.new_event_loop()
|
|
81
|
+
asyncio.set_event_loop(loop)
|
|
82
|
+
# 异步调用(支持同步/异步上下文)
|
|
83
|
+
loop.run_until_complete(target_port(result))
|
|
84
|
+
else:
|
|
85
|
+
# 同步调用
|
|
86
|
+
target_port(result)
|
|
87
|
+
else:
|
|
88
|
+
log_error(f"{output_port_name}没有找到绑定的输入端口")
|
|
89
|
+
|
|
90
|
+
return result
|
|
91
|
+
except Exception as e:
|
|
92
|
+
log_error(f"Error in output port {func.__name__}: {e}")
|
|
93
|
+
raise
|
|
94
|
+
|
|
95
|
+
return wrapper
|
|
96
|
+
|
|
97
|
+
return decorator
|
|
98
|
+
|
|
99
|
+
def input_port(param: str):
|
|
100
|
+
def decorator(func):
|
|
101
|
+
func.is_input_port = True
|
|
102
|
+
func.input_port_desc = param
|
|
103
|
+
|
|
104
|
+
@wraps(func)
|
|
105
|
+
def wrapper(self, *args, **kwargs):
|
|
106
|
+
try:
|
|
107
|
+
return func(self, *args, **kwargs)
|
|
108
|
+
except Exception as e:
|
|
109
|
+
log_error(f"输入端口异常 {func.__name__}: {e}")
|
|
110
|
+
raise
|
|
111
|
+
|
|
112
|
+
return wrapper
|
|
113
|
+
|
|
114
|
+
return decorator
|
|
115
|
+
|
|
116
|
+
def __init__(self, mermaid: Mermaid):
|
|
117
|
+
self.nodes = {}
|
|
118
|
+
self.port_mapping = defaultdict()
|
|
119
|
+
self.mermaid = mermaid # 保存 Mermaid 实例
|
|
120
|
+
|
|
121
|
+
def addnode(self, agent, node_name):
|
|
122
|
+
agent._workflow = self
|
|
123
|
+
self.nodes[node_name] = agent
|
|
124
|
+
return self # 返回 self 以支持链式调用
|
|
125
|
+
|
|
126
|
+
@classmethod
|
|
127
|
+
def getstorage(cls, key=None, default=None, caller: str = "") -> dict:
|
|
128
|
+
# 不同的工作流调用者得到不同的存储对象,默认是一个线程一个对象
|
|
129
|
+
if not caller or len(caller) == 0:
|
|
130
|
+
threadid = threading.get_ident()
|
|
131
|
+
caller = f"workflow_caller_{threadid}"
|
|
132
|
+
with cls._workflow_lock:
|
|
133
|
+
if caller not in cls._workflow_storage:
|
|
134
|
+
cls._workflow_storage[caller] = dict()
|
|
135
|
+
|
|
136
|
+
storage = cls._workflow_storage[caller]
|
|
137
|
+
if key:
|
|
138
|
+
return storage.setdefault(key, default)
|
|
139
|
+
return storage
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
def clearstorage(cls, caller: str = "") -> None:
|
|
143
|
+
"""
|
|
144
|
+
清除指定调用者的存储数据
|
|
145
|
+
|
|
146
|
+
:param caller: 调用者标识,默认为当前线程生成的标识
|
|
147
|
+
"""
|
|
148
|
+
if not caller or len(caller) == 0:
|
|
149
|
+
threadid = threading.get_ident()
|
|
150
|
+
caller = f"workflow_caller_{threadid}"
|
|
151
|
+
with cls._workflow_lock:
|
|
152
|
+
if caller in cls._workflow_storage:
|
|
153
|
+
del cls._workflow_storage[caller]
|
|
154
|
+
|
|
155
|
+
def start(self):
|
|
156
|
+
self._build_port_mapping()
|
|
157
|
+
|
|
158
|
+
def _build_port_mapping(self):
|
|
159
|
+
mermaid_edges = self.mermaid.edges # 从 Mermaid 实例获取边数据
|
|
160
|
+
for edge in mermaid_edges:
|
|
161
|
+
source_node, description, target_node = edge
|
|
162
|
+
source_node_desc = self.mermaid.node_dict.get(source_node, "")
|
|
163
|
+
target_node_desc = self.mermaid.node_dict.get(target_node, "")
|
|
164
|
+
source_agent = self.nodes.get(source_node_desc, None)
|
|
165
|
+
target_agent = self.nodes.get(target_node_desc, None)
|
|
166
|
+
if not source_agent:
|
|
167
|
+
log_warning(
|
|
168
|
+
f'"{source_node} -->|{description}|{target_node}"\t{source_node}[{source_node_desc}]没有找到'
|
|
169
|
+
)
|
|
170
|
+
if not target_agent:
|
|
171
|
+
log_warning(
|
|
172
|
+
f'"{source_node} -->|{description}|{target_node}"\t{target_node}[{target_node_desc}]没有找到'
|
|
173
|
+
)
|
|
174
|
+
if source_agent and target_agent:
|
|
175
|
+
output_port = self._find_output_port(source_agent, description)
|
|
176
|
+
input_port = self._find_input_port(target_agent, description)
|
|
177
|
+
if not output_port:
|
|
178
|
+
log_warning(f'"{source_node_desc}"没有发现输出端口:{description}')
|
|
179
|
+
if not input_port:
|
|
180
|
+
log_warning(f'"{target_node_desc}"没有发现输入端口:{description}')
|
|
181
|
+
if input_port and output_port:
|
|
182
|
+
self.port_mapping[f"{source_agent.__class__.__name__}:{output_port.__name__}"] = (
|
|
183
|
+
input_port,
|
|
184
|
+
f"{target_agent.__class__.__name__}:{input_port.__name__}",
|
|
185
|
+
)
|
|
186
|
+
log_info(
|
|
187
|
+
f"[{source_node_desc} -> |{description}| {target_node_desc}]"
|
|
188
|
+
f"\n\t调用链: {source_agent.__class__.__name__}:{output_port.__name__} >> {target_agent.__class__.__name__}:{input_port.__name__}"
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
def _find_output_port(self, agent, desc):
|
|
192
|
+
for method_name in dir(agent):
|
|
193
|
+
method = getattr(agent, method_name)
|
|
194
|
+
if hasattr(method, "is_output_port") and method.output_port_desc == desc:
|
|
195
|
+
return method
|
|
196
|
+
return None
|
|
197
|
+
|
|
198
|
+
def _find_input_port(self, agent, desc):
|
|
199
|
+
for method_name in dir(agent):
|
|
200
|
+
method = getattr(agent, method_name)
|
|
201
|
+
if hasattr(method, "is_input_port") and method.input_port_desc == desc:
|
|
202
|
+
return method
|
|
203
|
+
return None
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""
|
|
2
|
+
console_auth.py - 控制台认证交互模块
|
|
3
|
+
|
|
4
|
+
提供控制台交互式登录功能:
|
|
5
|
+
1. 检查本地 token 是否有效(fsss2 文件修改时间 < 7天)
|
|
6
|
+
2. 控制台输入手机号 + 验证码完成登录
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import os
|
|
11
|
+
import time
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def check_token_valid() -> bool:
|
|
15
|
+
"""
|
|
16
|
+
检查本地 token 是否有效
|
|
17
|
+
|
|
18
|
+
判断逻辑:
|
|
19
|
+
1. 读取 ~/.evol/default/fsss2 文件
|
|
20
|
+
2. 如果文件存在且内容非空
|
|
21
|
+
3. 检查文件修改时间距今是否 < 7天
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
bool: True 表示 token 有效,False 表示需要重新登录
|
|
25
|
+
"""
|
|
26
|
+
from evol.presenter.configPresenter import configPresenter
|
|
27
|
+
|
|
28
|
+
token = configPresenter.get_token()
|
|
29
|
+
if not token:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
# 检查 fsss2 文件的修改时间
|
|
33
|
+
fsss2_path = configPresenter.get_fsss2_file_path()
|
|
34
|
+
|
|
35
|
+
if not os.path.exists(fsss2_path):
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
mtime = os.path.getmtime(fsss2_path)
|
|
40
|
+
days_since_modified = (time.time() - mtime) / (60 * 60 * 24)
|
|
41
|
+
|
|
42
|
+
if days_since_modified >= 7:
|
|
43
|
+
print(f"Token 已过期({days_since_modified:.1f} 天前更新),需要重新登录")
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
print(f"Token 有效({days_since_modified:.1f} 天前更新)")
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
except OSError:
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
async def console_login():
|
|
54
|
+
"""
|
|
55
|
+
控制台交互式登录
|
|
56
|
+
|
|
57
|
+
流程:
|
|
58
|
+
1. 提示输入手机号
|
|
59
|
+
2. 调用 send_sms_code 发送验证码
|
|
60
|
+
3. 提示输入验证码
|
|
61
|
+
4. 调用 sms_login 完成登录
|
|
62
|
+
"""
|
|
63
|
+
from evol.presenter.userPresenter import userPresenter
|
|
64
|
+
|
|
65
|
+
print("\n" + "=" * 50)
|
|
66
|
+
print(" Evol Sample Backend - 用户登录")
|
|
67
|
+
print("=" * 50)
|
|
68
|
+
|
|
69
|
+
while True:
|
|
70
|
+
phone = input("\n请输入手机号: ").strip()
|
|
71
|
+
if not phone:
|
|
72
|
+
print("手机号不能为空,请重新输入")
|
|
73
|
+
continue
|
|
74
|
+
if len(phone) != 11 or not phone.isdigit():
|
|
75
|
+
print("请输入有效的11位手机号")
|
|
76
|
+
continue
|
|
77
|
+
break
|
|
78
|
+
|
|
79
|
+
# 发送验证码
|
|
80
|
+
print(f"\n正在向 {phone[:3]}****{phone[7:]} 发送验证码...")
|
|
81
|
+
sms_result = await userPresenter.send_sms_code(phone)
|
|
82
|
+
|
|
83
|
+
if sms_result.get("status") != "success":
|
|
84
|
+
print(f"发送验证码失败: {sms_result.get('error', '未知错误')}")
|
|
85
|
+
raise SystemExit(1)
|
|
86
|
+
|
|
87
|
+
print("验证码已发送,请查收短信")
|
|
88
|
+
|
|
89
|
+
# 输入验证码
|
|
90
|
+
while True:
|
|
91
|
+
code = input("请输入验证码: ").strip()
|
|
92
|
+
if not code:
|
|
93
|
+
print("验证码不能为空,请重新输入")
|
|
94
|
+
continue
|
|
95
|
+
if len(code) != 6 or not code.isdigit():
|
|
96
|
+
print("请输入6位数字验证码")
|
|
97
|
+
continue
|
|
98
|
+
break
|
|
99
|
+
|
|
100
|
+
# 登录
|
|
101
|
+
print("\n正在登录...")
|
|
102
|
+
login_result = await userPresenter.sms_login(phone, code)
|
|
103
|
+
|
|
104
|
+
if login_result.get("status") != "success":
|
|
105
|
+
print(f"登录失败: {login_result.get('error', '未知错误')}")
|
|
106
|
+
raise SystemExit(1)
|
|
107
|
+
|
|
108
|
+
print("登录成功!")
|
|
109
|
+
return True
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
全局配置文件
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
APP_ENV = "dev"
|
|
7
|
+
|
|
8
|
+
# ============ API 配置 ============
|
|
9
|
+
# SSL证书配置:
|
|
10
|
+
# - 当前已禁用SSL验证(AsyncHttpClient.VERIFY_SSL = False)
|
|
11
|
+
# - 如需启用验证,修改 evol/http/async_http.py 中的 VERIFY_SSL = True
|
|
12
|
+
|
|
13
|
+
API_BASE_URL = "https://api.evolai.cn:8550"
|
|
14
|
+
# API_BASE_URL = "http://localhost:8550"
|
|
15
|
+
PRICE_AID = "evol_price_1.aid.pub"
|
|
16
|
+
# 备用API地址:
|
|
17
|
+
# API_BASE_URL = "http://api.agentcp.cn:8550" # HTTP方式
|
|
18
|
+
# API_BASE_URL = "http://localhost:8080" # 本地开发
|
|
19
|
+
# API_BASE_URL = "https://www.agentcp.cn" # 标准443端口
|
|
20
|
+
|
|
21
|
+
# ============ 其他配置 ============
|
|
22
|
+
|
|
23
|
+
REPORT_AID = "llmstat.acp.internal" if APP_ENV == "test" else "llmstat.aid.pub"
|
|
24
|
+
COLLECTOR_URL = (
|
|
25
|
+
"http://trace.acp.internal/api/v1/monitor/add" if APP_ENV == "test" else "https://trace.aid.pub/api/v1/monitor/add"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# ============ 日志配置 ============
|
|
29
|
+
# 日志文件开关配置
|
|
30
|
+
# 设置为 True 启用日志文件记录,False 禁用
|
|
31
|
+
ENABLE_MCP_SERVER_LOG = False # MCP服务器启动日志
|
|
32
|
+
ENABLE_CLAUDE_PROXY_LOG = False # Claude代理请求日志
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Config:
|
|
36
|
+
def __init__(self) -> None:
|
|
37
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|