Skip to content

Commit 34ecbe5

Browse files
authored
Merge pull request #584 from NA-Wen/main
Enable OpenClaw Integration with ChatDev Backend Workflow Support
2 parents fea7091 + 036fb6e commit 34ecbe5

17 files changed

Lines changed: 1083 additions & 735 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dev: ## Run both backend and frontend development servers
1010
.PHONY: server
1111
server: ## Start the backend server in the background
1212
@echo "Starting server in background..."
13-
@uv run python server_main.py --port 6400 --reload &
13+
@uv run python server_main.py --port 6400 &
1414

1515
.PHONY: client
1616
client: ## Start the frontend development server

README-zh.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,33 @@ make dev
170170
```
171171
检查所有 YAML 文件的语法与 schema 错误。
172172

173+
### 🦞 使用 OpenClaw 运行
174+
175+
OpenClaw 可以与 ChatDev 集成,通过 **调用已有的 agent 团队**,或在 ChatDev 中 **动态创建新的 agent 团队** 来完成任务。
176+
177+
开始使用:
178+
179+
1. 启动 ChatDev 2.0 后端。
180+
2. 为你的 OpenClaw 实例安装所需的技能:
181+
182+
```bash
183+
clawdhub install chatdev
184+
```
185+
186+
3. 让 OpenClaw 创建一个 ChatDev 工作流。例如:
187+
188+
* **自动化信息收集与内容发布**
189+
190+
```
191+
创建一个 ChatDev 工作流,用于自动收集热点信息,生成一篇小红书文案,并发布该内容
192+
```
193+
194+
* **多智能体地缘政治模拟**
195+
196+
```
197+
创建一个 ChatDev 工作流,构建多个 agent,用于模拟中东局势未来可能的发展
198+
```
199+
173200

174201
### 🐳 使用 Docker 运行
175202
你也可以通过 Docker Compose 运行整个应用。该方式可简化依赖管理,并提供一致的运行环境。

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,29 @@ make dev
182182
```
183183
Checks all YAML files for syntax and schema errors.
184184

185+
### 🦞 Run with OpenClaw
186+
OpenClaw can integrate with ChatDev by invoking existing agent teams or dynamically creating new agent teams within ChatDev.
187+
To get started:
188+
1. Start the ChatDev 2.0 backend.
189+
2. Install the required skills for your OpenClaw instance:
190+
```bash
191+
clawdhub install chatdev
192+
```
193+
194+
3. Ask your OpenClaw to create a ChatDev workflow. For example:
195+
196+
* **Automated information collection and content publishing**
197+
198+
```
199+
Create a ChatDev workflow to automatically collect trending information, generate a Xiaohongshu post, and publish it.
200+
```
201+
202+
* **Multi-agent geopolitical simulation**
203+
```
204+
Create a ChatDev workflow with multiple agents to simulate possible future developments of the Middle East situation.
205+
```
206+
207+
185208
### 🐳 Run with Docker
186209
Alternatively, you can run the entire application using Docker Compose. This method simplifies dependency management and provides a consistent environment.
187210

entity/configs/node/tooling.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ class McpRemoteConfig(BaseConfig):
312312
server: str
313313
headers: Dict[str, str] = field(default_factory=dict)
314314
timeout: float | None = None
315+
cache_ttl: float = 0.0
316+
tool_sources: List[str] | None = None
315317

316318
FIELD_SPECS = {
317319
"server": ConfigFieldSpec(
@@ -337,6 +339,22 @@ class McpRemoteConfig(BaseConfig):
337339
description="Per-request timeout in seconds",
338340
advance=True,
339341
),
342+
"cache_ttl": ConfigFieldSpec(
343+
name="cache_ttl",
344+
display_name="Tool Cache TTL",
345+
type_hint="float",
346+
required=False,
347+
description="Seconds to cache MCP tool list; 0 disables cache for hot updates",
348+
advance=True,
349+
),
350+
"tool_sources": ConfigFieldSpec(
351+
name="tool_sources",
352+
display_name="Tool Sources Filter",
353+
type_hint="list[str]",
354+
required=False,
355+
description="Only include MCP tools whose meta.source is in this list; omit to default to ['mcp_tools'].",
356+
advance=True,
357+
),
340358
}
341359

342360
@classmethod
@@ -360,7 +378,40 @@ def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "McpRemoteConfig":
360378
else:
361379
raise ConfigError("timeout must be numeric", extend_path(path, "timeout"))
362380

363-
return cls(server=server, headers=headers, timeout=timeout, path=path)
381+
cache_ttl_value = mapping.get("cache_ttl", 0.0)
382+
if cache_ttl_value is None:
383+
cache_ttl = 0.0
384+
elif isinstance(cache_ttl_value, (int, float)):
385+
cache_ttl = float(cache_ttl_value)
386+
else:
387+
raise ConfigError("cache_ttl must be numeric", extend_path(path, "cache_ttl"))
388+
389+
tool_sources_raw = mapping.get("tool_sources")
390+
tool_sources: List[str] | None = None
391+
if tool_sources_raw is not None:
392+
entries = ensure_list(tool_sources_raw)
393+
normalized: List[str] = []
394+
for idx, entry in enumerate(entries):
395+
if not isinstance(entry, str):
396+
raise ConfigError(
397+
"tool_sources must be a list of strings",
398+
extend_path(path, f"tool_sources[{idx}]"),
399+
)
400+
value = entry.strip()
401+
if value:
402+
normalized.append(value)
403+
tool_sources = normalized
404+
else:
405+
tool_sources = ["mcp_tools"]
406+
407+
return cls(
408+
server=server,
409+
headers=headers,
410+
timeout=timeout,
411+
cache_ttl=cache_ttl,
412+
tool_sources=tool_sources,
413+
path=path,
414+
)
364415

365416
def cache_key(self) -> str:
366417
payload = (
@@ -380,6 +431,7 @@ class McpLocalConfig(BaseConfig):
380431
inherit_env: bool = True
381432
startup_timeout: float = 10.0
382433
wait_for_log: str | None = None
434+
cache_ttl: float = 0.0
383435

384436
FIELD_SPECS = {
385437
"command": ConfigFieldSpec(
@@ -438,6 +490,14 @@ class McpLocalConfig(BaseConfig):
438490
description="Regex that marks readiness when matched against stdout",
439491
advance=True,
440492
),
493+
"cache_ttl": ConfigFieldSpec(
494+
name="cache_ttl",
495+
display_name="Tool Cache TTL",
496+
type_hint="float",
497+
required=False,
498+
description="Seconds to cache MCP tool list; 0 disables cache for hot updates",
499+
advance=True,
500+
),
441501
}
442502

443503
@classmethod
@@ -474,6 +534,13 @@ def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "McpLocalConfig":
474534
raise ConfigError("startup_timeout must be numeric", extend_path(path, "startup_timeout"))
475535

476536
wait_for_log = optional_str(mapping, "wait_for_log", path)
537+
cache_ttl_value = mapping.get("cache_ttl", 0.0)
538+
if cache_ttl_value is None:
539+
cache_ttl = 0.0
540+
elif isinstance(cache_ttl_value, (int, float)):
541+
cache_ttl = float(cache_ttl_value)
542+
else:
543+
raise ConfigError("cache_ttl must be numeric", extend_path(path, "cache_ttl"))
477544
return cls(
478545
command=command,
479546
args=normalized_args,
@@ -482,6 +549,7 @@ def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "McpLocalConfig":
482549
inherit_env=bool(inherit_env),
483550
startup_timeout=startup_timeout,
484551
wait_for_log=wait_for_log,
552+
cache_ttl=cache_ttl,
485553
path=path,
486554
)
487555

frontend/package-lock.json

Lines changed: 4 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)