@brandon_9527/tcode 1.0.8 → 1.0.10
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/dist/python-src/.env +1 -1
- package/dist/python-src/README.md +48 -1
- package/dist/python-src/_workspace/.autodev/config.json +12 -0
- package/dist/python-src/_workspace/.autodev/cron/jobs.json +4 -0
- package/dist/python-src/entry.py +21 -1
- package/dist/python-src/main.py +763 -42
- package/dist/python-src/pyproject.toml +1 -0
- package/dist/python-src/run.sh +9 -0
- package/dist/python-src/src/agents/token_tracker.py +4 -4
- package/dist/python-src/src/claw/bus/queue.py +1 -1
- package/dist/python-src/src/claw/channels/__init__.py +2 -2
- package/dist/python-src/src/claw/channels/base.py +2 -2
- package/dist/python-src/src/claw/channels/feishu.py +57 -16
- package/dist/python-src/src/claw/channels/manager.py +2 -2
- package/dist/python-src/src/claw/config/__init__.py +3 -0
- package/dist/python-src/src/claw/config/loader.py +38 -0
- package/dist/python-src/src/claw/config/schema.py +14 -29
- package/dist/python-src/src/claw/cron/__init__.py +3 -0
- package/dist/python-src/src/claw/cron/service.py +171 -0
- package/dist/python-src/src/claw/cron/types_.py +14 -0
- package/dist/python-src/src/claw/heartbeat/__init__.py +2 -0
- package/dist/python-src/src/claw/heartbeat/service.py +55 -0
- package/dist/python-src/src/claw/run.py +82 -0
- package/dist/python-src/src/claw/tools/base.py +23 -0
- package/dist/python-src/src/claw/tools/channel.py +0 -0
- package/dist/python-src/src/claw/tools/cron.py +138 -0
- package/dist/python-src/src/claw/utils/__init__.py +2 -0
- package/dist/python-src/src/claw/utils/helpers.py +27 -0
- package/dist/python-src/src/core/context.py +158 -0
- package/dist/python-src/src/managers/manager_agent.py +9 -9
- package/dist/python-src/src/managers/manager_command.py +62 -0
- package/dist/python-src/src/managers/manager_context.py +1 -1
- package/dist/python-src/src/managers/manager_instruction.py +7 -7
- package/dist/python-src/src/managers/manager_skill.py +3 -3
- package/dist/python-src/src/managers/sandbox.py +3 -3
- package/dist/python-src/src/middlewares/dynamic_content.py +2 -2
- package/dist/python-src/src/middlewares/hitl.py +3 -3
- package/dist/python-src/src/middlewares/memory.py +2 -2
- package/dist/python-src/src/middlewares/subagents.py +4 -4
- package/dist/python-src/src/middlewares/summary.py +37 -37
- package/dist/python-src/src/stream/file_write_parser.py +3 -3
- package/dist/python-src/src/stream/formatter.py +19 -19
- package/dist/python-src/src/stream/handler.py +4 -4
- package/dist/python-src/src/stream/handler_with_tracker.py +10 -10
- package/dist/python-src/src/trackers/token/pricing.py +2 -2
- package/dist/python-src/src/trackers/token/report.py +4 -4
- package/dist/python-src/src/trackers/token/tracker.py +8 -8
- package/dist/python-src/src/tui/chatui.py +10 -10
- package/dist/python-src/src/tui/clawtui.py +230 -0
- package/dist/python-src/src/tui/commands/__init__.py +3 -0
- package/dist/python-src/src/tui/commands/base.py +6 -0
- package/dist/python-src/src/tui/commands/instruction.py +5 -0
- package/dist/python-src/src/tui/components/tlist.py +7 -7
- package/dist/python-src/src/tui/components/tscroll_panel.py +73 -44
- package/dist/python-src/src/tui/components/tscroll_panel_old.py +58 -0
- package/dist/python-src/src/tui/utils/trender.py +21 -21
- package/dist/python-src/uv.lock +1969 -1958
- package/package.json +1 -1
package/dist/python-src/main.py
CHANGED
|
@@ -11,7 +11,8 @@ import asyncio
|
|
|
11
11
|
import json
|
|
12
12
|
import os
|
|
13
13
|
|
|
14
|
-
from src.tui.chatui import LiveChatUI
|
|
14
|
+
# from src.tui.chatui import LiveChatUI
|
|
15
|
+
from src.tui.clawtui import LiveChatUI
|
|
15
16
|
from src.middlewares.hitl import HumanInTheLoopMiddleware
|
|
16
17
|
|
|
17
18
|
_ = load_dotenv(find_dotenv())
|
|
@@ -23,18 +24,33 @@ import warnings
|
|
|
23
24
|
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
24
25
|
warnings.filterwarnings("ignore", message="Pydantic serializer warnings")
|
|
25
26
|
|
|
27
|
+
from src.claw.config.loader import load_config, get_data_dir
|
|
28
|
+
from src.claw.bus.queue import MessageBus, InboundMessage, OutboundMessage
|
|
29
|
+
from src.claw.channels.manager import ChannelManager
|
|
30
|
+
from src.claw.cron.service import CronService
|
|
31
|
+
from src.claw.cron.types_ import CronJob
|
|
32
|
+
from src.claw.heartbeat.service import HeartbeatService
|
|
26
33
|
|
|
34
|
+
from src.claw.tools.base import AgentContext
|
|
35
|
+
from pathlib import Path
|
|
27
36
|
|
|
37
|
+
from src.middlewares.skill import SkillMiddleware
|
|
38
|
+
from src.core.deepagents import create_deep_agent, get_default_model
|
|
39
|
+
from src.core.context import build_system_prompt
|
|
28
40
|
|
|
29
|
-
# # ========== 关键修改1:配置logging,让INFO级别日志能输出 ==========
|
|
30
|
-
# import logging
|
|
31
|
-
# logging.basicConfig(
|
|
32
|
-
# level=logging.CRITICAL, # 设置日志级别为WARNING(显示WARNING/ERROR等)
|
|
33
|
-
# format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", # 日志格式(可选,更易读)
|
|
34
|
-
# handlers=[logging.StreamHandler()] # 输出到控制台
|
|
35
|
-
# )
|
|
36
41
|
|
|
37
|
-
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# ========== 关键修改1:配置logging,让INFO级别日志能输出 ==========
|
|
46
|
+
import logging
|
|
47
|
+
logging.basicConfig(
|
|
48
|
+
level=logging.CRITICAL, # 设置日志级别为WARNING(显示WARNING/ERROR等)
|
|
49
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", # 日志格式(可选,更易读)
|
|
50
|
+
handlers=[logging.StreamHandler()] # 输出到控制台
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
logger = logging.getLogger(__name__)
|
|
38
54
|
|
|
39
55
|
|
|
40
56
|
|
|
@@ -66,26 +82,30 @@ def get_weather(city: str) -> str:
|
|
|
66
82
|
|
|
67
83
|
|
|
68
84
|
|
|
69
|
-
llm = ChatOpenAI(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
# llm = ChatOpenAI(
|
|
86
|
+
# model=os.getenv("DEFAULT_MODEL"),
|
|
87
|
+
# base_url=os.getenv("OPENAI_API_BASE"),
|
|
88
|
+
# api_key=os.getenv("OPENAI_API_KEY"),
|
|
89
|
+
# streaming=True,
|
|
90
|
+
# temperature=0.7,
|
|
91
|
+
# # 开启百炼的 thinking 模式
|
|
92
|
+
# # 新版 LangChain 推荐用 extra_body 直接作为参数(而非嵌套在 model_kwargs)
|
|
93
|
+
# # extra_body = {
|
|
94
|
+
# # "enable_thinking": True,
|
|
95
|
+
# # "thinking_budget": 1000, # 增大预算,适配 Agent 多步思考
|
|
96
|
+
# # },
|
|
97
|
+
# model_kwargs={
|
|
98
|
+
# # 使流式返回的最后一个数据包包含Token消耗信息
|
|
99
|
+
# "stream_options": {"include_usage": True}
|
|
100
|
+
# }
|
|
101
|
+
# )
|
|
102
|
+
|
|
103
|
+
# llm = get_default_model(streaming=True)
|
|
86
104
|
|
|
87
105
|
async def agent_ui():
|
|
88
106
|
|
|
107
|
+
llm = get_default_model(streaming=True)
|
|
108
|
+
|
|
89
109
|
agent = create_agent(
|
|
90
110
|
model=llm,
|
|
91
111
|
tools=[get_weather],
|
|
@@ -179,7 +199,7 @@ async def asingle_agent():
|
|
|
179
199
|
"""
|
|
180
200
|
|
|
181
201
|
saver = InMemorySaver()
|
|
182
|
-
|
|
202
|
+
llm = get_default_model(streaming=True)
|
|
183
203
|
agent = create_agent(
|
|
184
204
|
model=llm,
|
|
185
205
|
tools=tools,
|
|
@@ -311,11 +331,17 @@ async def team_main():
|
|
|
311
331
|
agents_conf = agent_manager.get_all_conf()
|
|
312
332
|
|
|
313
333
|
toolkits = {
|
|
314
|
-
"
|
|
315
|
-
"
|
|
334
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
335
|
+
"edit": [ edit, write_file],
|
|
336
|
+
"search": [ web_search, web_fetch],
|
|
337
|
+
"bash": [ shell],
|
|
338
|
+
"web": [ web_search, web_fetch],
|
|
316
339
|
} if run_mode == "sandbox" else {
|
|
317
|
-
"
|
|
318
|
-
"
|
|
340
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
341
|
+
"edit": [ edit, write_file],
|
|
342
|
+
"search": [ web_search, web_fetch],
|
|
343
|
+
"bash": [ bash ],
|
|
344
|
+
"web": [ web_search, web_fetch],
|
|
319
345
|
}
|
|
320
346
|
|
|
321
347
|
context = SkillAgentContext(
|
|
@@ -362,7 +388,7 @@ async def team_main():
|
|
|
362
388
|
agents.append(agent)
|
|
363
389
|
|
|
364
390
|
tools = []
|
|
365
|
-
for tool_name in ["
|
|
391
|
+
for tool_name in ["read-only", "edit", "search", "bash", "web"]:
|
|
366
392
|
tools.extend([tool for tool in toolkits.get(tool_name, [])])
|
|
367
393
|
|
|
368
394
|
team = create_deep_agent(
|
|
@@ -376,7 +402,8 @@ async def team_main():
|
|
|
376
402
|
# prompt_name="leader_",
|
|
377
403
|
# WORKSPACE=workspace
|
|
378
404
|
# ),
|
|
379
|
-
system_prompt=apply_prompt(leader, WORKSPACE=workspace),
|
|
405
|
+
# system_prompt=apply_prompt(leader, WORKSPACE=workspace),
|
|
406
|
+
system_prompt=build_system_prompt(),
|
|
380
407
|
checkpointer=saver
|
|
381
408
|
).with_config({"recursion_limit": recursion_limit})
|
|
382
409
|
|
|
@@ -386,7 +413,7 @@ async def team_main():
|
|
|
386
413
|
workspace = os.getcwd()
|
|
387
414
|
run_mode = "local"
|
|
388
415
|
session_id = "1"
|
|
389
|
-
|
|
416
|
+
llm = get_default_model(streaming=True)
|
|
390
417
|
# agents_conf, toolkits, context, saver, instruction_manager
|
|
391
418
|
agents_config, toolkits, context, saver, instruction_manager = _prepare(workspace, run_mode, session_id)
|
|
392
419
|
agent = _build_team(
|
|
@@ -476,11 +503,17 @@ def build_team():
|
|
|
476
503
|
agents_conf = agent_manager.get_all_conf()
|
|
477
504
|
|
|
478
505
|
toolkits = {
|
|
479
|
-
"
|
|
480
|
-
"
|
|
506
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
507
|
+
"edit": [ edit, write_file],
|
|
508
|
+
"search": [ web_search, web_fetch],
|
|
509
|
+
"bash": [ shell],
|
|
510
|
+
"web": [ web_search, web_fetch],
|
|
481
511
|
} if run_mode == "sandbox" else {
|
|
482
|
-
"
|
|
483
|
-
"
|
|
512
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
513
|
+
"edit": [ edit, write_file],
|
|
514
|
+
"search": [ web_search, web_fetch],
|
|
515
|
+
"bash": [ bash ],
|
|
516
|
+
"web": [ web_search, web_fetch],
|
|
484
517
|
}
|
|
485
518
|
|
|
486
519
|
context = SkillAgentContext(
|
|
@@ -526,7 +559,7 @@ def build_team():
|
|
|
526
559
|
agents.append(agent)
|
|
527
560
|
|
|
528
561
|
tools = []
|
|
529
|
-
for tool_name in ["
|
|
562
|
+
for tool_name in ["read-only", "edit", "search", "bash", "web"]:
|
|
530
563
|
tools.extend([tool for tool in toolkits.get(tool_name, [])])
|
|
531
564
|
|
|
532
565
|
team = create_deep_agent(
|
|
@@ -543,7 +576,8 @@ def build_team():
|
|
|
543
576
|
middleware=[
|
|
544
577
|
DynamicContentMiddleware(),
|
|
545
578
|
],
|
|
546
|
-
system_prompt=apply_prompt(leader, WORKSPACE=workspace),
|
|
579
|
+
# system_prompt=apply_prompt(leader, WORKSPACE=workspace),
|
|
580
|
+
system_prompt=build_system_prompt(),
|
|
547
581
|
checkpointer=saver
|
|
548
582
|
).with_config({"recursion_limit": recursion_limit})
|
|
549
583
|
|
|
@@ -553,7 +587,7 @@ def build_team():
|
|
|
553
587
|
workspace = os.getcwd()
|
|
554
588
|
run_mode = "local"
|
|
555
589
|
session_id = "1"
|
|
556
|
-
|
|
590
|
+
llm = get_default_model(streaming=True)
|
|
557
591
|
# agents_conf, toolkits, context, saver, instruction_manager
|
|
558
592
|
agents_config, toolkits, context, saver, instruction_manager = _prepare(workspace, run_mode, session_id)
|
|
559
593
|
agent = _build_team(
|
|
@@ -653,18 +687,705 @@ async def run_once(prompt:str = None, verbose: bool=True):
|
|
|
653
687
|
|
|
654
688
|
finally:
|
|
655
689
|
pass
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
def claw_main():
|
|
693
|
+
""" 以 claw mode 运行 """
|
|
694
|
+
|
|
695
|
+
from functools import partial
|
|
696
|
+
from pathlib import Path
|
|
697
|
+
import asyncio
|
|
698
|
+
import sys
|
|
699
|
+
import os
|
|
700
|
+
|
|
701
|
+
from src.claw.config.loader import load_config, get_data_dir
|
|
702
|
+
from src.claw.bus.queue import MessageBus, InboundMessage, OutboundMessage
|
|
703
|
+
from src.claw.channels.manager import ChannelManager
|
|
704
|
+
from src.claw.cron.service import CronService
|
|
705
|
+
from src.claw.cron.types_ import CronJob
|
|
706
|
+
from src.claw.heartbeat.service import HeartbeatService
|
|
707
|
+
|
|
708
|
+
from src.claw.tools.base import AgentContext
|
|
709
|
+
from src.claw.tools.cron import (
|
|
710
|
+
add_cron_job,
|
|
711
|
+
list_cron_jobs,
|
|
712
|
+
remove_cron_job
|
|
713
|
+
)
|
|
714
|
+
from src.tools.tools import (
|
|
715
|
+
SkillAgentContext,
|
|
716
|
+
shell,
|
|
717
|
+
bash,
|
|
718
|
+
write_file,
|
|
719
|
+
read_file,
|
|
720
|
+
list_dir,
|
|
721
|
+
glob,
|
|
722
|
+
grep,
|
|
723
|
+
edit
|
|
724
|
+
)
|
|
725
|
+
|
|
726
|
+
from src.tools.web import (
|
|
727
|
+
web_search,
|
|
728
|
+
web_fetch
|
|
729
|
+
)
|
|
730
|
+
|
|
731
|
+
from src.managers.sandbox import Container
|
|
732
|
+
|
|
733
|
+
from dotenv import load_dotenv, find_dotenv
|
|
734
|
+
from langchain.agents import create_agent
|
|
735
|
+
from langchain_openai import ChatOpenAI
|
|
736
|
+
from langgraph.checkpoint.memory import InMemorySaver
|
|
737
|
+
from langchain_core.tools import BaseTool
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
from src.core.deepagents import create_deep_agent, get_default_model
|
|
741
|
+
from src.managers.manager_context import ContextManager
|
|
742
|
+
from src.utils.prompt import apply_template, apply_prompt
|
|
743
|
+
from src.prompts.prompts import leader
|
|
744
|
+
|
|
745
|
+
from src.tui.clawtui import LiveChatUI
|
|
746
|
+
|
|
747
|
+
_ = load_dotenv(find_dotenv())
|
|
748
|
+
|
|
749
|
+
WORKSPACE = Path.cwd()
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
"""
|
|
753
|
+
"appId": "cli_a909847e1278dcbd",
|
|
754
|
+
"appSecret": "bE0usuE0MKUJVDWOo9olib5X8PKv66pK",
|
|
755
|
+
"""
|
|
756
|
+
channel_conf_path = WORKSPACE / "channel_config.json"
|
|
757
|
+
if not channel_conf_path.exists():
|
|
758
|
+
with open(channel_conf_path, "w") as f:
|
|
759
|
+
data = {
|
|
760
|
+
"channels": {
|
|
761
|
+
"feishu": {
|
|
762
|
+
"enabled": True,
|
|
763
|
+
"appId": "",
|
|
764
|
+
"appSecret": "",
|
|
765
|
+
"encryptKey": "",
|
|
766
|
+
"verificationToken": "",
|
|
767
|
+
"allowFrom": []
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
json.dump(data, f)
|
|
772
|
+
|
|
773
|
+
config = load_config(
|
|
774
|
+
config_path=channel_conf_path
|
|
775
|
+
)
|
|
776
|
+
config.channels.feishu.app_id = os.getenv("APP_ID", "")
|
|
777
|
+
config.channels.feishu.app_secret = os.getenv("APP_SECRET", "")
|
|
778
|
+
|
|
779
|
+
def _prepare(workspace, run_mode, session_id):
|
|
780
|
+
saver = InMemorySaver()
|
|
781
|
+
|
|
782
|
+
# 1. 构建上下文管理器
|
|
783
|
+
dockerfile_path = os.path.join(Path(__file__).parent, "resources", "dockerfiles", "sandbox", "Dockerfile")
|
|
784
|
+
context_manager = ContextManager(
|
|
785
|
+
dockerfile_path=dockerfile_path,
|
|
786
|
+
mode=run_mode
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
context_manager.create_environment(
|
|
790
|
+
session_id=session_id,
|
|
791
|
+
workspace_path=workspace
|
|
792
|
+
)
|
|
793
|
+
|
|
794
|
+
# 2. 指令管理器
|
|
795
|
+
instruction_manager = context_manager.get_instruction_manager(
|
|
796
|
+
session_id=session_id
|
|
797
|
+
)
|
|
798
|
+
|
|
799
|
+
# 3. 代理管理器
|
|
800
|
+
agent_manager = context_manager.get_agent_manager(
|
|
801
|
+
session_id=session_id
|
|
802
|
+
)
|
|
803
|
+
|
|
804
|
+
# 4. 沙箱
|
|
805
|
+
sandbox = context_manager.get_container(
|
|
806
|
+
session_id=session_id
|
|
807
|
+
)
|
|
808
|
+
|
|
809
|
+
# 5. 工具箱
|
|
810
|
+
|
|
811
|
+
toolkits = {
|
|
812
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
813
|
+
"edit": [ edit, write_file],
|
|
814
|
+
"search": [ web_search, web_fetch],
|
|
815
|
+
"bash": [ shell],
|
|
816
|
+
"web": [ web_search, web_fetch],
|
|
817
|
+
} if run_mode == "sandbox" else {
|
|
818
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
819
|
+
"edit": [ edit, write_file],
|
|
820
|
+
"search": [ web_search, web_fetch],
|
|
821
|
+
"bash": [ bash ],
|
|
822
|
+
"web": [ web_search, web_fetch],
|
|
823
|
+
}
|
|
656
824
|
|
|
825
|
+
# 6. 配置
|
|
826
|
+
agents_conf = agent_manager.get_all_conf()
|
|
827
|
+
|
|
828
|
+
context = AgentContext(
|
|
829
|
+
working_directory=workspace,
|
|
830
|
+
sandbox=sandbox,
|
|
831
|
+
channel=None,
|
|
832
|
+
chat_id=None,
|
|
833
|
+
cron_service=None,
|
|
834
|
+
workspace=workspace,
|
|
835
|
+
)
|
|
836
|
+
|
|
837
|
+
return agents_conf, toolkits, context, saver, instruction_manager
|
|
838
|
+
|
|
839
|
+
def _build_team(agents_conf: Dict[str, Any], domain: str, llm: ChatOpenAI, toolkits: Dict[str, List[BaseTool]], workspace: str, saver=None, store=None, recursion_limit=1000):
|
|
840
|
+
|
|
841
|
+
team_conf = agents_conf.setdefault(domain, {"members": {}})
|
|
842
|
+
|
|
843
|
+
agents = []
|
|
844
|
+
for member_name, member in team_conf["members"].items():
|
|
845
|
+
|
|
846
|
+
tools = []
|
|
847
|
+
for tool_name in member["tools"]:
|
|
848
|
+
tools.extend(toolkits.get(tool_name, []))
|
|
849
|
+
|
|
850
|
+
# print(f"Building agent {member_name}")
|
|
851
|
+
# print(f"Tools: {tools}")
|
|
852
|
+
# print(f"Member: {member}")
|
|
853
|
+
# sys.exit()
|
|
854
|
+
|
|
855
|
+
llm_conf = member.get("llm", None)
|
|
856
|
+
model = ChatOpenAI(**llm_conf) if llm_conf else get_default_model(streaming=False)
|
|
857
|
+
|
|
858
|
+
agent = {
|
|
859
|
+
"name": member_name,
|
|
860
|
+
"description": member["description"],
|
|
861
|
+
"system_prompt": apply_template(
|
|
862
|
+
agents_config=agents_conf,
|
|
863
|
+
domain=domain,
|
|
864
|
+
prompt_name=member_name,
|
|
865
|
+
WORKSPACE=workspace
|
|
866
|
+
),
|
|
867
|
+
"context_schema": SkillAgentContext,
|
|
868
|
+
"tools": tools,
|
|
869
|
+
"model": model
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
agents.append(agent)
|
|
873
|
+
|
|
874
|
+
tools = []
|
|
875
|
+
for tool_name in ["read-only", "edit", "search", "bash", "web"]:
|
|
876
|
+
tools.extend([tool for tool in toolkits.get(tool_name, [])])
|
|
877
|
+
|
|
878
|
+
tools.extend([add_cron_job, list_cron_jobs, remove_cron_job])
|
|
879
|
+
|
|
880
|
+
team = create_deep_agent(
|
|
881
|
+
model=llm,
|
|
882
|
+
subagents=agents,
|
|
883
|
+
tools=tools,
|
|
884
|
+
middleware=[SkillMiddleware(workspace=workspace, home_path=str(Path.home()))],
|
|
885
|
+
context_schema=AgentContext,
|
|
886
|
+
system_prompt=apply_prompt(leader, WORKSPACE=workspace),
|
|
887
|
+
# system_prompt=build_system_prompt(),
|
|
888
|
+
checkpointer=saver
|
|
889
|
+
).with_config({"recursion_limit": recursion_limit})
|
|
890
|
+
|
|
891
|
+
return team
|
|
657
892
|
|
|
658
893
|
|
|
894
|
+
workspace = os.getcwd()
|
|
895
|
+
run_mode = "local"
|
|
896
|
+
session_id = "1"
|
|
897
|
+
|
|
898
|
+
llm = get_default_model(streaming=True)
|
|
899
|
+
agents_config, toolkits, context, saver, instruction_manager = _prepare(workspace, run_mode, session_id)
|
|
900
|
+
agent = _build_team(
|
|
901
|
+
agents_conf=agents_config,
|
|
902
|
+
domain="coding",
|
|
903
|
+
llm=llm,
|
|
904
|
+
toolkits=toolkits,
|
|
905
|
+
workspace=workspace,
|
|
906
|
+
saver=saver,
|
|
907
|
+
store=None,
|
|
908
|
+
recursion_limit=1000
|
|
909
|
+
)
|
|
910
|
+
|
|
911
|
+
# 创建事件总线
|
|
912
|
+
bus = MessageBus()
|
|
913
|
+
# 创建周期性任务
|
|
914
|
+
cron_store_path = Path(os.getcwd()) /".autodev"/"cron"/"jobs.json"
|
|
915
|
+
cron_store_path.parent.mkdir(parents=True, exist_ok=True)
|
|
916
|
+
cron = CronService(cron_store_path)
|
|
917
|
+
|
|
918
|
+
# 设置周期回调函数
|
|
919
|
+
async def on_cron_job(job: CronJob) -> str | None:
|
|
920
|
+
""" Execute a cron job through the agent. """
|
|
921
|
+
session_key = f"cron:{job.id}"
|
|
922
|
+
channel = job.payload.channel or "cli"
|
|
923
|
+
chat_id = job.payload.to or "direct"
|
|
924
|
+
response = await agent.ainvoke(
|
|
925
|
+
{"messages": [{"role": "user", "content": job.payload.message}]},
|
|
926
|
+
context=AgentContext(
|
|
927
|
+
working_directory=workspace,
|
|
928
|
+
sandbox=None,
|
|
929
|
+
channel=channel,
|
|
930
|
+
chat_id=chat_id,
|
|
931
|
+
cron_service=cron,
|
|
932
|
+
workspace=workspace
|
|
933
|
+
)
|
|
934
|
+
)
|
|
659
935
|
|
|
936
|
+
resp = response["messages"][-1].content
|
|
937
|
+
|
|
938
|
+
if job.payload.deliver and job.payload.to:
|
|
939
|
+
from src.claw.bus.events import OutboundMessage
|
|
940
|
+
await bus.publish_outbound(
|
|
941
|
+
OutboundMessage(
|
|
942
|
+
channel=channel,
|
|
943
|
+
chat_id=chat_id,
|
|
944
|
+
content=resp or ""
|
|
945
|
+
))
|
|
946
|
+
|
|
947
|
+
return resp
|
|
948
|
+
|
|
949
|
+
cron.on_job = on_cron_job
|
|
950
|
+
|
|
951
|
+
# 创建心跳服务
|
|
952
|
+
async def on_heartbeat(prompt: str) -> str:
|
|
953
|
+
""" Execute a heartbeat through the agent. """
|
|
954
|
+
print(f"execute Heartbeat prompt: {prompt}")
|
|
955
|
+
response = await agent.ainvoke(
|
|
956
|
+
{"messages": [{"role": "user", "content": prompt}]},
|
|
957
|
+
context=AgentContext(
|
|
958
|
+
working_directory=workspace,
|
|
959
|
+
sandbox=None,
|
|
960
|
+
channel="cli",
|
|
961
|
+
chat_id="direct",
|
|
962
|
+
cron_service=cron,
|
|
963
|
+
workspace=workspace,
|
|
964
|
+
)
|
|
965
|
+
)
|
|
966
|
+
|
|
967
|
+
resp = response["messages"][-1].content
|
|
968
|
+
return resp
|
|
969
|
+
|
|
970
|
+
heartbeat = HeartbeatService(
|
|
971
|
+
workspace=Path(workspace),
|
|
972
|
+
on_heartbeat=on_heartbeat,
|
|
973
|
+
interval_s=10,
|
|
974
|
+
enabled=True
|
|
975
|
+
)
|
|
976
|
+
|
|
977
|
+
# 创建渠道管理器
|
|
978
|
+
channels = ChannelManager(
|
|
979
|
+
config,
|
|
980
|
+
bus=bus,
|
|
981
|
+
)
|
|
982
|
+
|
|
983
|
+
ui = LiveChatUI(
|
|
984
|
+
agent=agent,
|
|
985
|
+
saver=saver,
|
|
986
|
+
workspace=str(workspace),
|
|
987
|
+
instruction_manager=instruction_manager,
|
|
988
|
+
channels=channels,
|
|
989
|
+
heartbeat=heartbeat,
|
|
990
|
+
bus=bus,
|
|
991
|
+
cron=cron,
|
|
992
|
+
context=context
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
asyncio.run(ui.alisten())
|
|
996
|
+
|
|
997
|
+
# await ui.alisten()
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
async def _process_message(msg: InboundMessage, agent:Any, bus: MessageBus, cron: CronService) -> OutboundMessage | None:
|
|
1002
|
+
""" """
|
|
1003
|
+
if msg.channel == "system":
|
|
1004
|
+
response = await _process_system_message(msg, agent, cron)
|
|
1005
|
+
await bus.publish_outbound(response)
|
|
1006
|
+
|
|
1007
|
+
print(f"user>{msg.content}")
|
|
1008
|
+
session_key = f"{msg.channel}:{msg.chat_id}"
|
|
1009
|
+
config = {"configurable": {"thread_id": session_key}}
|
|
1010
|
+
|
|
1011
|
+
response = await agent.ainvoke(
|
|
1012
|
+
{"messages": [{"role": "user", "content": msg.content}]},
|
|
1013
|
+
config=config,
|
|
1014
|
+
context=AgentContext(
|
|
1015
|
+
working_directory=Path.cwd(),
|
|
1016
|
+
sandbox=None,
|
|
1017
|
+
channel=msg.channel,
|
|
1018
|
+
chat_id=msg.chat_id,
|
|
1019
|
+
cron_service=cron,
|
|
1020
|
+
workspace=Path.cwd(),
|
|
1021
|
+
)
|
|
1022
|
+
)
|
|
1023
|
+
print(f"Bot>{response['messages'][-1].content}")
|
|
1024
|
+
|
|
1025
|
+
response = OutboundMessage(
|
|
1026
|
+
channel=msg.channel,
|
|
1027
|
+
chat_id=msg.chat_id,
|
|
1028
|
+
content=response["messages"][-1].content,
|
|
1029
|
+
metadata=msg.metadata or {}
|
|
1030
|
+
)
|
|
1031
|
+
|
|
1032
|
+
await bus.publish_outbound(response)
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
async def _process_system_message(msg: InboundMessage, agent: Any, cron: CronService) -> OutboundMessage | None:
|
|
1036
|
+
"""
|
|
1037
|
+
Process a system message (e.g. subagent announce).
|
|
1038
|
+
"""
|
|
1039
|
+
# logger.info(f"Processing system message from {msg.sender_id}")
|
|
1040
|
+
|
|
1041
|
+
# Parse origin from chat_id (format: "channel:chat_id")
|
|
1042
|
+
if ":" in msg.chat_id:
|
|
1043
|
+
parts = msg.chat_id.split(":", 1)
|
|
1044
|
+
origin_channel = parts[0]
|
|
1045
|
+
origin_chat_id = parts[1]
|
|
1046
|
+
else:
|
|
1047
|
+
# Fallback
|
|
1048
|
+
origin_channel = "cli"
|
|
1049
|
+
origin_chat_id = msg.chat_id
|
|
1050
|
+
|
|
1051
|
+
# Use the origin session for context
|
|
1052
|
+
session_key = f"{origin_channel}:{origin_chat_id}"
|
|
1053
|
+
config = {"configurable": {"thread_id": session_key}}
|
|
1054
|
+
response = await agent.ainvoke(
|
|
1055
|
+
{"message": msg.content},
|
|
1056
|
+
config=config,
|
|
1057
|
+
context=AgentContext(
|
|
1058
|
+
working_directory=Path.cwd(),
|
|
1059
|
+
sandbox=None,
|
|
1060
|
+
channel=origin_channel,
|
|
1061
|
+
chat_id=origin_chat_id,
|
|
1062
|
+
cron_service=cron,
|
|
1063
|
+
workspace=Path.cwd(),
|
|
1064
|
+
)
|
|
1065
|
+
)
|
|
1066
|
+
|
|
1067
|
+
return OutboundMessage(
|
|
1068
|
+
channel=origin_channel,
|
|
1069
|
+
chat_id=origin_chat_id,
|
|
1070
|
+
content=response["messages"][-1].content,
|
|
1071
|
+
metadata=msg.metadata or {}
|
|
1072
|
+
)
|
|
1073
|
+
|
|
1074
|
+
def claw_terminal():
|
|
1075
|
+
""" 以 claw mode 运行 """
|
|
1076
|
+
|
|
1077
|
+
from functools import partial
|
|
1078
|
+
from pathlib import Path
|
|
1079
|
+
import asyncio
|
|
1080
|
+
import sys
|
|
1081
|
+
import os
|
|
1082
|
+
|
|
1083
|
+
from src.claw.config.loader import load_config, get_data_dir
|
|
1084
|
+
from src.claw.bus.queue import MessageBus, InboundMessage, OutboundMessage
|
|
1085
|
+
from src.claw.channels.manager import ChannelManager
|
|
1086
|
+
from src.claw.cron.service import CronService
|
|
1087
|
+
from src.claw.cron.types_ import CronJob
|
|
1088
|
+
from src.claw.heartbeat.service import HeartbeatService
|
|
1089
|
+
|
|
1090
|
+
from src.claw.tools.base import AgentContext
|
|
1091
|
+
from src.claw.tools.cron import (
|
|
1092
|
+
add_cron_job,
|
|
1093
|
+
list_cron_jobs,
|
|
1094
|
+
remove_cron_job
|
|
1095
|
+
)
|
|
1096
|
+
from src.tools.tools import (
|
|
1097
|
+
SkillAgentContext,
|
|
1098
|
+
shell,
|
|
1099
|
+
bash,
|
|
1100
|
+
write_file,
|
|
1101
|
+
read_file,
|
|
1102
|
+
list_dir,
|
|
1103
|
+
glob,
|
|
1104
|
+
grep,
|
|
1105
|
+
edit
|
|
1106
|
+
)
|
|
1107
|
+
|
|
1108
|
+
from src.tools.web import (
|
|
1109
|
+
web_search,
|
|
1110
|
+
web_fetch
|
|
1111
|
+
)
|
|
1112
|
+
|
|
1113
|
+
from src.managers.sandbox import Container
|
|
1114
|
+
|
|
1115
|
+
from dotenv import load_dotenv, find_dotenv
|
|
1116
|
+
from langchain.agents import create_agent
|
|
1117
|
+
from langchain_openai import ChatOpenAI
|
|
1118
|
+
from langgraph.checkpoint.memory import InMemorySaver
|
|
1119
|
+
from langchain_core.tools import BaseTool
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
from src.core.deepagents import create_deep_agent, get_default_model
|
|
1123
|
+
from src.managers.manager_context import ContextManager
|
|
1124
|
+
from src.utils.prompt import apply_template, apply_prompt
|
|
1125
|
+
from src.prompts.prompts import leader
|
|
1126
|
+
from functools import partial
|
|
1127
|
+
|
|
1128
|
+
from src.tui.clawtui import LiveChatUI
|
|
1129
|
+
|
|
1130
|
+
_ = load_dotenv(find_dotenv())
|
|
1131
|
+
|
|
1132
|
+
WORKSPACE = Path.cwd()
|
|
1133
|
+
|
|
1134
|
+
conf_path = WORKSPACE / "config.json"
|
|
1135
|
+
if not conf_path.exists():
|
|
1136
|
+
with open(conf_path, "w") as f:
|
|
1137
|
+
data = {
|
|
1138
|
+
"channels": {
|
|
1139
|
+
"feishu": {
|
|
1140
|
+
"enabled": True,
|
|
1141
|
+
"appId": "cli_a909847e1278dcbd",
|
|
1142
|
+
"appSecret": "bE0usuE0MKUJVDWOo9olib5X8PKv66pK",
|
|
1143
|
+
"encryptKey": "",
|
|
1144
|
+
"verificationToken": "",
|
|
1145
|
+
"allowFrom": []
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
json.dump(data, f)
|
|
1150
|
+
|
|
1151
|
+
config = load_config(
|
|
1152
|
+
config_path=conf_path
|
|
1153
|
+
)
|
|
1154
|
+
|
|
1155
|
+
def _prepare(workspace, run_mode, session_id):
|
|
1156
|
+
saver = InMemorySaver()
|
|
1157
|
+
|
|
1158
|
+
# 1. 构建上下文管理器
|
|
1159
|
+
dockerfile_path = os.path.join(Path(__file__).parent, "resources", "dockerfiles", "sandbox", "Dockerfile")
|
|
1160
|
+
context_manager = ContextManager(
|
|
1161
|
+
dockerfile_path=dockerfile_path,
|
|
1162
|
+
mode=run_mode
|
|
1163
|
+
)
|
|
1164
|
+
|
|
1165
|
+
context_manager.create_environment(
|
|
1166
|
+
session_id=session_id,
|
|
1167
|
+
workspace_path=workspace
|
|
1168
|
+
)
|
|
1169
|
+
|
|
1170
|
+
# 2. 指令管理器
|
|
1171
|
+
instruction_manager = context_manager.get_instruction_manager(
|
|
1172
|
+
session_id=session_id
|
|
1173
|
+
)
|
|
1174
|
+
|
|
1175
|
+
# 3. 代理管理器
|
|
1176
|
+
agent_manager = context_manager.get_agent_manager(
|
|
1177
|
+
session_id=session_id
|
|
1178
|
+
)
|
|
1179
|
+
|
|
1180
|
+
# 4. 沙箱
|
|
1181
|
+
sandbox = context_manager.get_container(
|
|
1182
|
+
session_id=session_id
|
|
1183
|
+
)
|
|
1184
|
+
|
|
1185
|
+
# 5. 工具箱
|
|
1186
|
+
toolkits = {
|
|
1187
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
1188
|
+
"edit": [ edit, write_file],
|
|
1189
|
+
"search": [ web_search, web_fetch],
|
|
1190
|
+
"bash": [ shell],
|
|
1191
|
+
"web": [ web_search, web_fetch],
|
|
1192
|
+
} if run_mode == "sandbox" else {
|
|
1193
|
+
"read-only": [ read_file, glob, grep, list_dir],
|
|
1194
|
+
"edit": [ edit, write_file],
|
|
1195
|
+
"search": [ web_search, web_fetch],
|
|
1196
|
+
"bash": [ bash ],
|
|
1197
|
+
"web": [ web_search, web_fetch],
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
# 6. 配置
|
|
1201
|
+
agents_conf = agent_manager.get_all_conf()
|
|
1202
|
+
|
|
1203
|
+
context = AgentContext(
|
|
1204
|
+
working_directory=workspace,
|
|
1205
|
+
sandbox=sandbox,
|
|
1206
|
+
channel=None,
|
|
1207
|
+
chat_id=None,
|
|
1208
|
+
cron_service=None,
|
|
1209
|
+
workspace=workspace,
|
|
1210
|
+
)
|
|
1211
|
+
|
|
1212
|
+
return agents_conf, toolkits, context, saver, instruction_manager
|
|
1213
|
+
|
|
1214
|
+
def _build_team(agents_conf: Dict[str, Any], domain: str, llm: ChatOpenAI, toolkits: Dict[str, List[BaseTool]], workspace: str, saver=None, store=None, recursion_limit=1000):
|
|
1215
|
+
|
|
1216
|
+
team_conf = agents_conf.setdefault(domain, {"members": {}})
|
|
1217
|
+
|
|
1218
|
+
agents = []
|
|
1219
|
+
for member_name, member in team_conf["members"].items():
|
|
1220
|
+
|
|
1221
|
+
tools = []
|
|
1222
|
+
for tool_name in member["tools"]:
|
|
1223
|
+
tools.extend(toolkits.get(tool_name, []))
|
|
1224
|
+
|
|
1225
|
+
llm_conf = member.get("llm", None)
|
|
1226
|
+
model = ChatOpenAI(**llm_conf) if llm_conf else get_default_model(streaming=False)
|
|
1227
|
+
|
|
1228
|
+
agent = {
|
|
1229
|
+
"name": member_name,
|
|
1230
|
+
"description": member["description"],
|
|
1231
|
+
"system_prompt": apply_template(
|
|
1232
|
+
agents_config=agents_conf,
|
|
1233
|
+
domain=domain,
|
|
1234
|
+
prompt_name=member_name,
|
|
1235
|
+
WORKSPACE=workspace
|
|
1236
|
+
),
|
|
1237
|
+
"context_schema": SkillAgentContext,
|
|
1238
|
+
"tools": tools,
|
|
1239
|
+
"model": model
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
agents.append(agent)
|
|
1243
|
+
|
|
1244
|
+
tools = []
|
|
1245
|
+
for tool_name in ["read-only", "edit", "search", "bash", "web"]:
|
|
1246
|
+
tools.extend([tool for tool in toolkits.get(tool_name, [])])
|
|
1247
|
+
|
|
1248
|
+
team = create_deep_agent(
|
|
1249
|
+
model=llm,
|
|
1250
|
+
subagents=agents,
|
|
1251
|
+
tools=tools,
|
|
1252
|
+
context_schema=AgentContext,
|
|
1253
|
+
# system_prompt=apply_prompt(leader, WORKSPACE=workspace),
|
|
1254
|
+
system_prompt=build_system_prompt(),
|
|
1255
|
+
checkpointer=saver
|
|
1256
|
+
).with_config({"recursion_limit": recursion_limit})
|
|
1257
|
+
|
|
1258
|
+
return team
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
workspace = os.getcwd()
|
|
1262
|
+
run_mode = "local"
|
|
1263
|
+
session_id = "1"
|
|
1264
|
+
llm = get_default_model(streaming=True)
|
|
1265
|
+
agents_config, toolkits, context, saver, instruction_manager = _prepare(workspace, run_mode, session_id)
|
|
1266
|
+
agent = _build_team(
|
|
1267
|
+
agents_conf=agents_config,
|
|
1268
|
+
domain="coding",
|
|
1269
|
+
llm=llm,
|
|
1270
|
+
toolkits=toolkits,
|
|
1271
|
+
workspace=workspace,
|
|
1272
|
+
saver=saver,
|
|
1273
|
+
store=None,
|
|
1274
|
+
recursion_limit=1000
|
|
1275
|
+
)
|
|
1276
|
+
|
|
1277
|
+
# 创建事件总线
|
|
1278
|
+
bus = MessageBus()
|
|
1279
|
+
# 创建周期性任务
|
|
1280
|
+
cron_store_path = Path(os.getcwd()) /".autodev"/"cron"/"jobs.json"
|
|
1281
|
+
cron_store_path.parent.mkdir(parents=True, exist_ok=True)
|
|
1282
|
+
cron = CronService(cron_store_path)
|
|
1283
|
+
|
|
1284
|
+
# 设置周期回调函数
|
|
1285
|
+
async def on_cron_job(job: CronJob) -> str | None:
|
|
1286
|
+
""" Execute a cron job through the agent. """
|
|
1287
|
+
session_key = f"cron:{job.id}"
|
|
1288
|
+
channel = job.payload.channel or "cli"
|
|
1289
|
+
chat_id = job.payload.to or "direct"
|
|
1290
|
+
response = await agent.ainvoke(
|
|
1291
|
+
{"messages": [{"role": "user", "content": job.payload.message}]},
|
|
1292
|
+
context=AgentContext(
|
|
1293
|
+
working_directory=workspace,
|
|
1294
|
+
sandbox=None,
|
|
1295
|
+
channel=channel,
|
|
1296
|
+
chat_id=chat_id,
|
|
1297
|
+
cron_service=cron,
|
|
1298
|
+
workspace=workspace
|
|
1299
|
+
)
|
|
1300
|
+
)
|
|
1301
|
+
|
|
1302
|
+
resp = response["messages"][-1].content
|
|
1303
|
+
|
|
1304
|
+
if job.payload.deliver and job.payload.to:
|
|
1305
|
+
from src.claw.bus.events import OutboundMessage
|
|
1306
|
+
await bus.publish_outbound(
|
|
1307
|
+
OutboundMessage(
|
|
1308
|
+
channel=channel,
|
|
1309
|
+
chat_id=chat_id,
|
|
1310
|
+
content=resp or ""
|
|
1311
|
+
))
|
|
1312
|
+
|
|
1313
|
+
return resp
|
|
1314
|
+
|
|
1315
|
+
cron.on_job = on_cron_job
|
|
1316
|
+
|
|
1317
|
+
# 创建心跳服务
|
|
1318
|
+
async def on_heartbeat(prompt: str) -> str:
|
|
1319
|
+
""" Execute a heartbeat through the agent. """
|
|
1320
|
+
print(f"execute Heartbeat prompt: {prompt}")
|
|
1321
|
+
response = await agent.ainvoke(
|
|
1322
|
+
{"messages": [{"role": "user", "content": prompt}]},
|
|
1323
|
+
context=AgentContext(
|
|
1324
|
+
working_directory=workspace,
|
|
1325
|
+
sandbox=None,
|
|
1326
|
+
channel="cli",
|
|
1327
|
+
chat_id="direct",
|
|
1328
|
+
cron_service=cron,
|
|
1329
|
+
workspace=workspace,
|
|
1330
|
+
)
|
|
1331
|
+
)
|
|
1332
|
+
|
|
1333
|
+
resp = response["messages"][-1].content
|
|
1334
|
+
return resp
|
|
1335
|
+
|
|
1336
|
+
heartbeat = HeartbeatService(
|
|
1337
|
+
workspace=Path(workspace),
|
|
1338
|
+
on_heartbeat=on_heartbeat,
|
|
1339
|
+
interval_s=10,
|
|
1340
|
+
enabled=True
|
|
1341
|
+
)
|
|
1342
|
+
|
|
1343
|
+
# 创建渠道管理器
|
|
1344
|
+
channels = ChannelManager(
|
|
1345
|
+
config,
|
|
1346
|
+
bus=bus,
|
|
1347
|
+
)
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
bus.subscribe_inbound("feishu", partial(_process_message, agent=agent, bus=bus, cron=cron))
|
|
1351
|
+
|
|
1352
|
+
async def run():
|
|
1353
|
+
try:
|
|
1354
|
+
await cron.start()
|
|
1355
|
+
await heartbeat.start()
|
|
1356
|
+
await asyncio.gather(
|
|
1357
|
+
bus.dispatch_inbound(),
|
|
1358
|
+
channels.start_all()
|
|
1359
|
+
)
|
|
1360
|
+
except KeyboardInterrupt:
|
|
1361
|
+
print("\nShutting down ...")
|
|
1362
|
+
heartbeat.stop()
|
|
1363
|
+
await cron.stop()
|
|
1364
|
+
await channels.stop_all()
|
|
1365
|
+
bus.stop()
|
|
1366
|
+
|
|
1367
|
+
asyncio.run(run())
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
|
|
660
1376
|
|
|
661
1377
|
if __name__ == "__main__":
|
|
662
1378
|
# pass
|
|
663
|
-
asyncio.run(teminal_chat())
|
|
1379
|
+
# asyncio.run(teminal_chat())
|
|
664
1380
|
# asyncio.run(agent_ui())
|
|
665
1381
|
# asyncio.run(team_main())
|
|
666
1382
|
# asyncio.run(asingle_agent())
|
|
667
1383
|
|
|
1384
|
+
# asyncio.run(claw_main())
|
|
1385
|
+
claw_main()
|
|
1386
|
+
# claw_terminal()
|
|
1387
|
+
|
|
1388
|
+
|
|
668
1389
|
|
|
669
1390
|
|
|
670
1391
|
|