ChatDev Ability Units
Ability units represent capability units. You can browse what's available, inspect
required args, run them, or upload new ones. Use these endpoints when you need to
invoke a predefined ability unit (e.g., paper review, data visualization) via the
local API.
Run ability units via the local API and return final_message from the JSON response.
API endpoints
- Browse ability units
- Get ability unit raw content
- Get ability unit args
- Run ability unit
-
Method: POST
-
URL: http://127.0.0.1:6400/api/workflow/run
-
Content-Type: application/json
-
SSE support: set Accept: text/event-stream to stream events (started, log,
completed, error). Omit the header to get the normal JSON response.
-
Output: parse JSON and return final_message. If missing, report failure and
include any error fields. After you get output_dir, move it to your working
directory.
-
Available ability units:
- Paper Review
- Data Visualization
- yaml_file:
yaml_instance/data_visualization_basic.yaml
- task_prompt: dataset description + analysis goals.
- attachments: absolute paths to CSV files.
- Purpose: profile, clean, plan 4-6 charts, iterate visualizations.
- Example:
curl --noproxy 127.0.0.1 -v -X POST http://127.0.0.1:6400/api/workflow/run \
-H "Content-Type: application/json" \
-d '{
"yaml_file": "yaml_instance/data_visualization_basic.yaml",
"task_prompt": "please analyze and visualize the data",
"attachments": ["/Users/yufan/Projects/bugfix/ChatDev/sample_sales.csv"]
}'
- Upload ability unit
- Method: POST
- URL: http://127.0.0.1:6400/api/workflows/upload/content
- Content-Type: application/json
- Format notes:
filename should end with .yaml; content must be a valid YAML
string that includes version, vars, and a graph with id, start,
nodes, and edges (as in the example).
- Tip: if uploads keep failing with format errors, call the "get ability unit raw content" endpoint to inspect
an existing ability unit's structure and copy its format.
- Example:
curl --noproxy 127.0.0.1 -v -X POST \
http://127.0.0.1:6400/api/workflows/upload/content \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
"filename": "test.yaml",
"content": "version: 0.4.0\nvars: {}\ngraph:\n id: paper_review\n description: Three agents collaboratively review academic papers from different perspectives. Input can be an arxiv URL or paper title.\n is_majority_voting: false\n start:\n - Paper Fetcher\n nodes:\n - id: Paper Fetcher\n type: agent\n config:\n name: gpt-4o\n provider: openai\n role: |\n You are a paper content fetcher.\n base_url: ${BASE_URL}\n api_key: ${API_KEY}\n description: Fetches paper content from arxiv\n context_window: 0\n edges: []"
}
EOF
- Update ability unit
- Method: PUT
- URL: http://127.0.0.1:6400/api/workflows/<filename>/update
- Content-Type: application/json
- Format notes: same payload as upload (
filename + YAML content string).
- Example:
curl --noproxy 127.0.0.1 -v -X PUT \
http://127.0.0.1:6400/api/workflows/test.yaml/update \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
"filename": "test.yaml",
"content": "version: 0.4.0\nvars: {}\ngraph:\n id: paper_review\n description: Update example.\n is_majority_voting: false\n start:\n - Paper Fetcher\n nodes:\n - id: Paper Fetcher\n type: agent\n config:\n name: gpt-4o\n provider: openai\n role: |\n You are a paper content fetcher.\n base_url: ${BASE_URL}\n api_key: ${API_KEY}\n description: Fetches paper content from arxiv\n context_window: 0\n edges: []"
}
EOF
- Rename ability unit
- Copy ability unit
- Delete ability unit
- List local tools (function_calling)
Tools hot updates
Local function tools are managed via the same backend (port 6400).
Endpoints:
- List local tools:
GET http://127.0.0.1:6400/api/tools/local
- Create/overwrite local tool file:
POST http://127.0.0.1:6400/api/tools/local
Create example:
curl --noproxy 127.0.0.1 -X POST http://127.0.0.1:6400/api/tools/local \
-H "Content-Type: application/json" \
-d '{
"filename": "add.py",
"content": "def add(a: int, b: int) -> dict:\n return {\"result\": a + b}\n",
"overwrite": true
}'
YAML example (local function_calling):
tooling:
- type: function
config:
tools:
- name: add
Common scenarios and tool suggestions
- If the agent needs to search the web, use
web_search.
- If the agent needs to fetch a URL's content, use
read_webpage_content.
- If the agent needs to inspect local files, use
describe_available_files and list_directory.
- If the agent needs to read a file snippet, use
read_text_file_snippet or read_file_segment.
- If the agent needs to write output files, use
save_file.
Advanced Workflow Templates
Below are advanced YAML templates you can copy and adapt. They cover debate loops,
subgraph reuse, conditional edges, and selective payload routing.
1) Two-Agent Debate Loop with Judge Stop Criteria
version: 0.4.0
vars: {}
graph:
id: debate_loop
description: Two agents debate until the judge outputs "Verdict: STOP".
is_majority_voting: false
start:
- Topic
nodes:
- id: Topic
type: passthrough
config: {}
- id: Pro
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
You are the PRO debater. Respond with arguments and counterpoints.
- id: Con
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
You are the CON debater. Respond with arguments and counterpoints.
- id: Judge
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
Evaluate the debate. Output:
Score: <0-1>
Notes: <brief>
Verdict: CONTINUE|STOP
- id: Final
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
Produce the final summary of the debate and recommendation.
edges:
- from: Topic
to: Pro
keep_message: true
- from: Topic
to: Con
keep_message: true
- from: Pro
to: Judge
- from: Con
to: Judge
- from: Judge
to: Pro
condition: need_reflection_loop
- from: Judge
to: Con
condition: need_reflection_loop
- from: Judge
to: Final
condition: should_stop_loop
2) Subgraph Reuse + Selective Payload Passing
version: 0.4.0
vars: {}
graph:
id: parent_with_subgraph
description: Uses a subgraph and only forwards the "Summary" section.
start:
- Request
nodes:
- id: Request
type: passthrough
config: {}
- id: ResearchSubgraph
type: subgraph
config:
type: file
config:
path: "subgraphs/deep_research_executor_sub.yaml"
- id: Writer
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
Write the final report using only the provided Summary.
edges:
- from: Request
to: ResearchSubgraph
keep_message: true
- from: ResearchSubgraph
to: Writer
process:
type: regex_extract
config:
pattern: "Summary:\\s*(.*)"
group: 1
multiline: true
dotall: true
on_no_match: pass
3) Conditional Routing + Minimal Payload
version: 0.4.0
vars: {}
graph:
id: router_with_conditions
description: Route to different nodes based on tags; forward only CONTENT block.
start:
- Router
nodes:
- id: Router
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
Decide the route. Output exactly:
ROUTE: QA|REPORT
CONTENT: <payload to forward>
- id: QA
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
Answer the question concisely.
- id: REPORT
type: agent
config:
provider: openai
base_url: ${BASE_URL}
api_key: ${API_KEY}
name: gpt-4o
role: |
Write a structured report.
edges:
- from: Router
to: QA
condition:
type: keyword
config:
any: ["ROUTE: QA"]
process:
type: regex_extract
config:
pattern: "CONTENT:\\s*(.*)"
group: 1
dotall: true
on_no_match: drop
- from: Router
to: REPORT
condition:
type: keyword
config:
any: ["ROUTE: REPORT"]
process:
type: regex_extract
config:
pattern: "CONTENT:\\s*(.*)"
group: 1
dotall: true
on_no_match: drop
Tips