@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
|
@@ -485,7 +485,7 @@ async def _ws_connect(token: str, kernel_port: int, _t0: float):
|
|
|
485
485
|
ws_url = f"ws://127.0.0.1:{kernel_port}/ws?token={token}&id=model_service"
|
|
486
486
|
print(f"[model_service] Connecting to Kernel: {ws_url}")
|
|
487
487
|
|
|
488
|
-
async with websockets.connect(ws_url, open_timeout=5, ping_interval=
|
|
488
|
+
async with websockets.connect(ws_url, open_timeout=5, ping_interval=None, close_timeout=10) as ws:
|
|
489
489
|
_ws_global = ws
|
|
490
490
|
print(f"[model_service] Connected to Kernel ({_fmt_elapsed(_t0)})")
|
|
491
491
|
|
|
@@ -518,12 +518,14 @@ async def _ws_connect(token: str, kernel_port: int, _t0: float):
|
|
|
518
518
|
|
|
519
519
|
# Publish module.ready (every reconnect)
|
|
520
520
|
if not _shutting_down:
|
|
521
|
+
startup_time = time.monotonic() - _t0
|
|
521
522
|
await _rpc_call(ws, "event.publish", {
|
|
522
523
|
"event_id": str(uuid.uuid4()),
|
|
523
524
|
"event": "module.ready",
|
|
524
525
|
"data": {
|
|
525
526
|
"module_id": "model_service",
|
|
526
527
|
"graceful_shutdown": True,
|
|
528
|
+
"startup_time": startup_time,
|
|
527
529
|
},
|
|
528
530
|
})
|
|
529
531
|
print(f"[model_service] module.ready published ({_fmt_elapsed(_t0)})")
|
|
@@ -575,12 +577,32 @@ async def _publish_event(ws, event: dict):
|
|
|
575
577
|
})
|
|
576
578
|
|
|
577
579
|
|
|
580
|
+
async def _handle_ping_event(data: dict):
|
|
581
|
+
"""Handle system.ping event and reply with system.pong."""
|
|
582
|
+
t1 = data.get("ping_time")
|
|
583
|
+
t2 = time.time()
|
|
584
|
+
|
|
585
|
+
await _publish_event(_ws_global, {
|
|
586
|
+
"event": "system.pong",
|
|
587
|
+
"data": {
|
|
588
|
+
"module_id": MODULE_NAME,
|
|
589
|
+
"ping_time": t1,
|
|
590
|
+
"pong_time": t2,
|
|
591
|
+
},
|
|
592
|
+
})
|
|
593
|
+
|
|
594
|
+
|
|
578
595
|
async def _handle_event_notification(msg: dict):
|
|
579
596
|
"""Handle an event notification (JSON-RPC 2.0 Notification with method='event')."""
|
|
580
597
|
params = msg.get("params", {})
|
|
581
598
|
event_type = params.get("event", "")
|
|
582
599
|
data = params.get("data", {})
|
|
583
600
|
|
|
601
|
+
# Handle system.ping event
|
|
602
|
+
if event_type == "system.ping":
|
|
603
|
+
await _handle_ping_event(data)
|
|
604
|
+
return
|
|
605
|
+
|
|
584
606
|
# Special handling for module.shutdown
|
|
585
607
|
if event_type == "module.shutdown":
|
|
586
608
|
target = data.get("module_id", "")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(echo agentcp not found directly:*)",
|
|
5
|
+
"Bash(grep:*)",
|
|
6
|
+
"Bash(head:*)",
|
|
7
|
+
"Bash(find H:\\\\project\\\\evol_main\\\\evol-electron-app\\\\python_sample_backend:*)",
|
|
8
|
+
"Bash(python3:*)",
|
|
9
|
+
"Bash(python:*)",
|
|
10
|
+
"Bash(cd H:\\\\project\\\\evol_main\\\\evol-electron-app\\\\python_sample_backend:*)"
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Evol Proxy 服务修改说明
|
|
2
|
+
|
|
3
|
+
## 修改日期
|
|
4
|
+
2026-03-08
|
|
5
|
+
|
|
6
|
+
## 修改内容
|
|
7
|
+
|
|
8
|
+
### 1. 端口改为系统自动分配
|
|
9
|
+
|
|
10
|
+
**修改文件:**
|
|
11
|
+
- `main.py`
|
|
12
|
+
- `server.py`
|
|
13
|
+
|
|
14
|
+
**改动说明:**
|
|
15
|
+
|
|
16
|
+
原来使用固定端口 12655,容易导致端口冲突。现在改为:
|
|
17
|
+
- 使用 `port=0` 让系统自动分配可用端口
|
|
18
|
+
- 在启动前先获取一个可用端口
|
|
19
|
+
- 启动后显示实际使用的端口号
|
|
20
|
+
|
|
21
|
+
**实现方式:**
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
# 获取系统分配的可用端口
|
|
25
|
+
import socket
|
|
26
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
27
|
+
sock.bind(('', 0))
|
|
28
|
+
actual_port = sock.getsockname()[1]
|
|
29
|
+
sock.close()
|
|
30
|
+
|
|
31
|
+
# 使用该端口启动服务器
|
|
32
|
+
await run_server(port=actual_port)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. 登录后自动拉取模型列表和用户信息
|
|
36
|
+
|
|
37
|
+
**修改文件:**
|
|
38
|
+
- `main.py`
|
|
39
|
+
|
|
40
|
+
**新增功能:**
|
|
41
|
+
|
|
42
|
+
在 AID 上线成功后,自动执行以下操作:
|
|
43
|
+
|
|
44
|
+
1. **拉取模型列表**
|
|
45
|
+
- 调用 `get_models_list()` 获取可用模型
|
|
46
|
+
- 显示模型数量和前 5 个模型名称
|
|
47
|
+
- 示例输出:
|
|
48
|
+
```
|
|
49
|
+
[Models] Found 15 available models:
|
|
50
|
+
- gpt-4
|
|
51
|
+
- gpt-3.5-turbo
|
|
52
|
+
- claude-3-opus
|
|
53
|
+
- claude-3-sonnet
|
|
54
|
+
- gemini-pro
|
|
55
|
+
... and 10 more
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
2. **获取用户信息**
|
|
59
|
+
- 调用 `userPresenter.get_user_info()` 获取用户信息
|
|
60
|
+
- 显示手机号和用户 ID
|
|
61
|
+
- 示例输出:
|
|
62
|
+
```
|
|
63
|
+
[User] Logged in as: 138****1234
|
|
64
|
+
[User] User ID: user_abc123
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**代码位置:**
|
|
68
|
+
|
|
69
|
+
在 `async_main()` 函数中,Step 3.6 部分:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
# Step 3.6: 拉取模型列表和用户信息
|
|
73
|
+
print("\n[Info] Fetching models and user info...")
|
|
74
|
+
try:
|
|
75
|
+
# 拉取模型列表
|
|
76
|
+
from evol.server.openclaw_proxy import get_models_list
|
|
77
|
+
models_data = get_models_list()
|
|
78
|
+
model_count = len(models_data.get("data", []))
|
|
79
|
+
print(f"[Models] Found {model_count} available models:")
|
|
80
|
+
for model in models_data.get("data", [])[:5]:
|
|
81
|
+
print(f" - {model.get('id', 'unknown')}")
|
|
82
|
+
if model_count > 5:
|
|
83
|
+
print(f" ... and {model_count - 5} more")
|
|
84
|
+
|
|
85
|
+
# 获取用户信息
|
|
86
|
+
from evol.presenter.userPresenter import userPresenter
|
|
87
|
+
user_info = userPresenter.get_user_info()
|
|
88
|
+
if user_info:
|
|
89
|
+
print(f"[User] Logged in as: {user_info.get('phone', 'unknown')}")
|
|
90
|
+
print(f"[User] User ID: {user_info.get('id', 'unknown')}")
|
|
91
|
+
|
|
92
|
+
except Exception as e:
|
|
93
|
+
print(f"[Info] Warning: 获取信息失败: {e}")
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 启动流程变化
|
|
97
|
+
|
|
98
|
+
### 修改前
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
1. 初始化配置目录
|
|
102
|
+
2. 检查本地 token
|
|
103
|
+
3. 若无有效 token → 控制台登录
|
|
104
|
+
4. 同步用户信息 & AID 上线
|
|
105
|
+
5. 获取 Evol 本地密钥
|
|
106
|
+
6. 启动 FastAPI 服务器(固定端口 12655)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 修改后
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
1. 初始化配置目录
|
|
113
|
+
2. 检查本地 token
|
|
114
|
+
3. 若无有效 token → 控制台登录
|
|
115
|
+
4. 同步用户信息 & AID 上线
|
|
116
|
+
5. 获取 Evol 本地密钥
|
|
117
|
+
6. 拉取模型列表和用户信息 ← 新增
|
|
118
|
+
7. 启动 FastAPI 服务器(系统自动分配端口)← 修改
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 输出示例
|
|
122
|
+
|
|
123
|
+
### 修改前
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
============================================================
|
|
127
|
+
Evol Sample Backend
|
|
128
|
+
Port: 12655
|
|
129
|
+
============================================================
|
|
130
|
+
|
|
131
|
+
[Init] Config dir: C:\Users\xxx\.evol
|
|
132
|
+
[Auth] Token valid, skip login
|
|
133
|
+
[AID] Starting AID login...
|
|
134
|
+
Evol: aid_xxx is online
|
|
135
|
+
[Key] Evol API Key: evol-xxx
|
|
136
|
+
|
|
137
|
+
[Server] Starting on port 12655...
|
|
138
|
+
[Server] ANTHROPIC_BASE_URL = http://127.0.0.1:12655/claude-proxy
|
|
139
|
+
[Server] OPENAI_BASE_URL = http://127.0.0.1:12655/openclaw-proxy/v1
|
|
140
|
+
[Server] Health check = http://127.0.0.1:12655/health
|
|
141
|
+
[Server] Evol API Key = evol-xxx
|
|
142
|
+
|
|
143
|
+
Press Ctrl+C to stop.
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 修改后
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
============================================================
|
|
150
|
+
Evol Sample Backend
|
|
151
|
+
Port: Auto-assigned by system
|
|
152
|
+
============================================================
|
|
153
|
+
|
|
154
|
+
[Init] Config dir: C:\Users\xxx\.evol
|
|
155
|
+
[Auth] Token valid, skip login
|
|
156
|
+
[AID] Starting AID login...
|
|
157
|
+
Evol: aid_xxx is online
|
|
158
|
+
[Key] Evol API Key: evol-xxx
|
|
159
|
+
|
|
160
|
+
[Info] Fetching models and user info...
|
|
161
|
+
[Models] Found 15 available models:
|
|
162
|
+
- gpt-4
|
|
163
|
+
- gpt-3.5-turbo
|
|
164
|
+
- claude-3-opus
|
|
165
|
+
- claude-3-sonnet
|
|
166
|
+
- gemini-pro
|
|
167
|
+
... and 10 more
|
|
168
|
+
[User] Logged in as: 138****1234
|
|
169
|
+
[User] User ID: user_abc123
|
|
170
|
+
|
|
171
|
+
[Server] Starting server...
|
|
172
|
+
|
|
173
|
+
[Server] Server will start on port 54321
|
|
174
|
+
[Server] ANTHROPIC_BASE_URL = http://127.0.0.1:54321/claude-proxy
|
|
175
|
+
[Server] OPENAI_BASE_URL = http://127.0.0.1:54321/openclaw-proxy/v1
|
|
176
|
+
[Server] Health check = http://127.0.0.1:54321/health
|
|
177
|
+
[Server] Evol API Key = evol-xxx
|
|
178
|
+
|
|
179
|
+
Press Ctrl+C to stop.
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 优点
|
|
183
|
+
|
|
184
|
+
### 1. 端口自动分配
|
|
185
|
+
|
|
186
|
+
- **避免端口冲突** - 不会与其他服务冲突
|
|
187
|
+
- **支持多实例** - 可以同时运行多个代理服务
|
|
188
|
+
- **更灵活** - 适应不同的部署环境
|
|
189
|
+
|
|
190
|
+
### 2. 自动拉取信息
|
|
191
|
+
|
|
192
|
+
- **验证登录状态** - 确认模型列表可以正常获取
|
|
193
|
+
- **显示可用模型** - 用户一目了然有哪些模型可用
|
|
194
|
+
- **确认用户身份** - 显示当前登录的用户信息
|
|
195
|
+
- **便于调试** - 启动时就能发现配置问题
|
|
196
|
+
|
|
197
|
+
## 注意事项
|
|
198
|
+
|
|
199
|
+
1. **端口号变化** - 每次启动端口可能不同,需要从启动日志中获取
|
|
200
|
+
2. **防火墙规则** - 如果需要外部访问,需要动态配置防火墙
|
|
201
|
+
3. **错误处理** - 如果拉取模型列表失败,只会显示警告,不会中断启动
|
|
202
|
+
|
|
203
|
+
## 测试建议
|
|
204
|
+
|
|
205
|
+
1. **基本功能测试**
|
|
206
|
+
```bash
|
|
207
|
+
# 启动服务
|
|
208
|
+
python main.py
|
|
209
|
+
|
|
210
|
+
# 查看启动日志,获取实际端口(假设是 54321)
|
|
211
|
+
# 测试健康检查
|
|
212
|
+
curl http://127.0.0.1:54321/health
|
|
213
|
+
|
|
214
|
+
# 测试模型列表
|
|
215
|
+
curl http://127.0.0.1:54321/openclaw-proxy/v1/models \
|
|
216
|
+
-H "Authorization: Bearer evol-xxx"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
2. **多实例测试**
|
|
220
|
+
```bash
|
|
221
|
+
# 同时启动多个实例,验证端口不冲突
|
|
222
|
+
python main.py &
|
|
223
|
+
python main.py &
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
3. **端口冲突测试**
|
|
227
|
+
```bash
|
|
228
|
+
# 验证不会出现端口占用错误
|
|
229
|
+
# 之前固定端口时可能出现的问题现在应该不会发生
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 回滚方案
|
|
233
|
+
|
|
234
|
+
如果需要回滚到固定端口模式,修改 `main.py`:
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
# 改回固定端口
|
|
238
|
+
PORT = 12655 # 或其他固定端口
|
|
239
|
+
|
|
240
|
+
# 恢复端口清理逻辑
|
|
241
|
+
kill_port(PORT)
|
|
242
|
+
|
|
243
|
+
# 直接使用固定端口启动
|
|
244
|
+
await run_server(port=PORT)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## 相关文件
|
|
248
|
+
|
|
249
|
+
- `main.py` - 主程序入口
|
|
250
|
+
- `server.py` - FastAPI 服务器
|
|
251
|
+
- `console_auth.py` - 控制台认证
|
|
252
|
+
- `evol/server/openclaw_proxy.py` - OpenClaw 代理实现
|
|
253
|
+
- `evol/presenter/userPresenter.py` - 用户信息管理
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
**修改者:** Claude (Kite Assistant)
|
|
258
|
+
**审核者:** 待审核
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Temporary script to replace print() with logger calls in openclaw_proxy.py and claude_proxy_async.py.
|
|
3
|
+
Delete this file after running.
|
|
4
|
+
"""
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
def classify_message(msg_text):
|
|
9
|
+
"""Classify a print message into logger level based on content."""
|
|
10
|
+
error_keywords = ['❌', '失败', '异常', 'error', 'Error', '严重错误', '错误']
|
|
11
|
+
warning_keywords = ['⚠️', '警告']
|
|
12
|
+
info_keywords = ['成功', '已初始化', '已启动', '已停止', '已注册', '已禁用', '已清理',
|
|
13
|
+
'刷新完成', '加载成功', '上线', '完成']
|
|
14
|
+
|
|
15
|
+
for kw in error_keywords:
|
|
16
|
+
if kw in msg_text:
|
|
17
|
+
return 'error'
|
|
18
|
+
for kw in warning_keywords:
|
|
19
|
+
if kw in msg_text:
|
|
20
|
+
return 'warning'
|
|
21
|
+
for kw in info_keywords:
|
|
22
|
+
if kw in msg_text:
|
|
23
|
+
return 'info'
|
|
24
|
+
return 'debug'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def remove_emojis(text):
|
|
28
|
+
"""Remove common emoji characters from text."""
|
|
29
|
+
emojis = ['🧹', '🚀', '🛑', '✅', '❌', '⚠️', '✓', '🔧']
|
|
30
|
+
for e in emojis:
|
|
31
|
+
text = text.replace(e, '')
|
|
32
|
+
# Clean up extra spaces left by emoji removal
|
|
33
|
+
text = re.sub(r' +', ' ', text)
|
|
34
|
+
return text
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def process_file(filepath):
|
|
38
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
39
|
+
content = f.read()
|
|
40
|
+
|
|
41
|
+
lines = content.split('\n')
|
|
42
|
+
new_lines = []
|
|
43
|
+
i = 0
|
|
44
|
+
replacements = 0
|
|
45
|
+
|
|
46
|
+
while i < len(lines):
|
|
47
|
+
line = lines[i]
|
|
48
|
+
stripped = line.lstrip()
|
|
49
|
+
indent = line[:len(line) - len(stripped)]
|
|
50
|
+
|
|
51
|
+
# Handle traceback.print_exc()
|
|
52
|
+
if 'traceback.print_exc()' in stripped and stripped.strip() == 'traceback.print_exc()':
|
|
53
|
+
new_lines.append(f'{indent}logger.debug(traceback.format_exc())')
|
|
54
|
+
replacements += 1
|
|
55
|
+
i += 1
|
|
56
|
+
continue
|
|
57
|
+
|
|
58
|
+
# Skip non-print lines
|
|
59
|
+
if not stripped.startswith('print(') and not stripped.startswith('print ('):
|
|
60
|
+
new_lines.append(line)
|
|
61
|
+
i += 1
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
# Gather the full print statement (may span multiple lines)
|
|
65
|
+
full_print = line
|
|
66
|
+
# Count open/close parens to handle multi-line prints
|
|
67
|
+
open_count = full_print.count('(') - full_print.count(')')
|
|
68
|
+
while open_count > 0 and i + 1 < len(lines):
|
|
69
|
+
i += 1
|
|
70
|
+
full_print += '\n' + lines[i]
|
|
71
|
+
open_count = full_print.count('(') - full_print.count(')')
|
|
72
|
+
|
|
73
|
+
# Extract the content inside print(...)
|
|
74
|
+
# Find the print( and matching )
|
|
75
|
+
full_stripped = full_print.lstrip()
|
|
76
|
+
|
|
77
|
+
# Match print(...) - extract inner content
|
|
78
|
+
# Simple approach: replace 'print(' with 'logger.X(' and keep everything else
|
|
79
|
+
|
|
80
|
+
# Determine the level based on content
|
|
81
|
+
level = classify_message(full_stripped)
|
|
82
|
+
|
|
83
|
+
# Clean emojis from the content
|
|
84
|
+
cleaned = remove_emojis(full_print)
|
|
85
|
+
cleaned_stripped = cleaned.lstrip()
|
|
86
|
+
|
|
87
|
+
# Handle special case: print("\n" + "=" * 80) and print("=" * 80 + "\n")
|
|
88
|
+
# These are separator lines - skip them entirely
|
|
89
|
+
if re.match(r'print\(\s*"\\n"\s*\+\s*"="\s*\*\s*\d+\s*\)', cleaned_stripped):
|
|
90
|
+
replacements += 1
|
|
91
|
+
i += 1
|
|
92
|
+
continue
|
|
93
|
+
if re.match(r'print\(\s*"="\s*\*\s*\d+\s*\+\s*"\\n"\s*\)', cleaned_stripped):
|
|
94
|
+
replacements += 1
|
|
95
|
+
i += 1
|
|
96
|
+
continue
|
|
97
|
+
if re.match(r'print\(\s*"="\s*\*\s*\d+\s*\)', cleaned_stripped):
|
|
98
|
+
replacements += 1
|
|
99
|
+
i += 1
|
|
100
|
+
continue
|
|
101
|
+
|
|
102
|
+
# Replace print( with logger.level(
|
|
103
|
+
# Handle the indentation properly for multi-line
|
|
104
|
+
cleaned_lines = cleaned.split('\n')
|
|
105
|
+
first_line = cleaned_lines[0]
|
|
106
|
+
first_stripped = first_line.lstrip()
|
|
107
|
+
first_indent = first_line[:len(first_line) - len(first_stripped)]
|
|
108
|
+
|
|
109
|
+
# Replace print( with logger.level(
|
|
110
|
+
new_first = re.sub(r'^print\s*\(', f'logger.{level}(', first_stripped)
|
|
111
|
+
cleaned_lines[0] = first_indent + new_first
|
|
112
|
+
|
|
113
|
+
for cl in cleaned_lines:
|
|
114
|
+
new_lines.append(cl)
|
|
115
|
+
|
|
116
|
+
replacements += 1
|
|
117
|
+
i += 1
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
result = '\n'.join(new_lines)
|
|
121
|
+
|
|
122
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
123
|
+
f.write(result)
|
|
124
|
+
|
|
125
|
+
return replacements
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# Process both files
|
|
129
|
+
r1 = process_file('evol/server/openclaw_proxy.py')
|
|
130
|
+
print(f"openclaw_proxy.py: {r1} replacements made")
|
|
131
|
+
|
|
132
|
+
r2 = process_file('evol/server/claude_proxy_async.py')
|
|
133
|
+
print(f"claude_proxy_async.py: {r2} replacements made")
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Fix indentation issues caused by the previous script's emoji removal.
|
|
3
|
+
The problem: removing multi-byte emoji chars from lines messes up indentation
|
|
4
|
+
when the emoji is at the start of a string, not in the indentation itself.
|
|
5
|
+
|
|
6
|
+
Actually, the real issue is simpler: the 'remove_emojis' function was applied to
|
|
7
|
+
the ENTIRE line including indentation whitespace, and the `re.sub(r' +', ' ', text)`
|
|
8
|
+
collapsed double spaces in the indentation.
|
|
9
|
+
|
|
10
|
+
This script fixes the indentation by re-reading the current (broken) files and
|
|
11
|
+
fixing any lines where logger.X( has wrong indentation.
|
|
12
|
+
"""
|
|
13
|
+
import re
|
|
14
|
+
|
|
15
|
+
def fix_indentation(filepath):
|
|
16
|
+
"""
|
|
17
|
+
The previous script broke indentation because:
|
|
18
|
+
1. Emojis in Chinese text like '✅' '❌' were removed
|
|
19
|
+
2. The cleanup regex `re.sub(r' +', ' ', text)` collapsed ALL multi-spaces,
|
|
20
|
+
including indentation whitespace
|
|
21
|
+
|
|
22
|
+
Strategy: We can't easily reverse this. Instead, let's look at each logger.X()
|
|
23
|
+
line and infer the correct indentation from its surrounding context.
|
|
24
|
+
"""
|
|
25
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
26
|
+
lines = f.readlines()
|
|
27
|
+
|
|
28
|
+
fixed = 0
|
|
29
|
+
new_lines = []
|
|
30
|
+
|
|
31
|
+
for i, line in enumerate(lines):
|
|
32
|
+
stripped = line.lstrip()
|
|
33
|
+
current_indent = len(line) - len(line.lstrip())
|
|
34
|
+
|
|
35
|
+
# Check if this is a logger line with potentially wrong indentation
|
|
36
|
+
if stripped.startswith('logger.'):
|
|
37
|
+
# Look at the previous non-empty line to determine expected indentation
|
|
38
|
+
expected_indent = None
|
|
39
|
+
for j in range(i - 1, max(0, i - 5), -1):
|
|
40
|
+
prev = lines[j]
|
|
41
|
+
prev_stripped = prev.lstrip()
|
|
42
|
+
if not prev_stripped or prev_stripped.startswith('#'):
|
|
43
|
+
continue
|
|
44
|
+
prev_indent = len(prev) - len(prev.lstrip())
|
|
45
|
+
|
|
46
|
+
# If previous line ends with ':', this line should be indented more
|
|
47
|
+
if prev_stripped.rstrip().endswith(':'):
|
|
48
|
+
expected_indent = prev_indent + 4
|
|
49
|
+
# If previous line is at same block level
|
|
50
|
+
elif prev_stripped.startswith(('logger.', 'log_info', 'log_error',
|
|
51
|
+
'return', 'if ', 'elif ', 'else:', 'try:', 'except', 'finally:',
|
|
52
|
+
'for ', 'while ', 'async ', 'await ', 'with ', 'raise',
|
|
53
|
+
'self.', 'del ', 'pass', 'break', 'continue',
|
|
54
|
+
'result', 'response', 'session', 'error', 'cleanup',
|
|
55
|
+
'old_', 'new_', 'first_', 'aid_', 'evol_', 'agentcp_',
|
|
56
|
+
'remaining', 'time_since', 'current_', 'message', 'proxy_',
|
|
57
|
+
'trace_id', 'model', 'request', 'body', 'api_', 'user_',
|
|
58
|
+
'is_', 'async_session', 'openclaw', 'shared_', '_register',
|
|
59
|
+
'full_rebuild', 'rebuild_thread', 'login_result',
|
|
60
|
+
'fetch_result', 'balance', 'credits', 'users_count',
|
|
61
|
+
'inner_data', 'data', 'api_key', 'cached_key', 'success',
|
|
62
|
+
'stale_trace', 'age_', 'content', 'stream_url', 'openai_',
|
|
63
|
+
'response_body', 'http_status', 'error_message',
|
|
64
|
+
'global ', 'import ', '_rebuild', '_last_full', '_agentcp')):
|
|
65
|
+
expected_indent = prev_indent
|
|
66
|
+
else:
|
|
67
|
+
expected_indent = prev_indent
|
|
68
|
+
break
|
|
69
|
+
|
|
70
|
+
if expected_indent is not None and current_indent != expected_indent:
|
|
71
|
+
# Fix the indentation
|
|
72
|
+
line = ' ' * expected_indent + stripped
|
|
73
|
+
fixed += 1
|
|
74
|
+
|
|
75
|
+
new_lines.append(line)
|
|
76
|
+
|
|
77
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
78
|
+
f.writelines(new_lines)
|
|
79
|
+
|
|
80
|
+
return fixed
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
f1 = fix_indentation('evol/server/openclaw_proxy.py')
|
|
84
|
+
print(f"openclaw_proxy.py: {f1} lines fixed")
|
|
85
|
+
|
|
86
|
+
f2 = fix_indentation('evol/server/claude_proxy_async.py')
|
|
87
|
+
print(f"claude_proxy_async.py: {f2} lines fixed")
|