chore: import upstream snapshot with attribution
Validate YAML Workflows / Validate YAML Configuration Files (push) Has been cancelled
Validate YAML Workflows / Validate YAML Configuration Files (push) Has been cancelled
This commit is contained in:
Executable
+47
@@ -0,0 +1,47 @@
|
||||
# Tooling Module Overview
|
||||
|
||||
DevAll currently exposes two tool binding modes for agent nodes:
|
||||
1. **Function Tooling** – call in-repo Python functions from `functions/function_calling/`, with JSON Schema auto-generated from type hints.
|
||||
2. **MCP Tooling** – connect to external services that implement the Model Context Protocol, including FastMCP, Claude Desktop, or any MCP-compatible tool stack.
|
||||
|
||||
All tooling configs hang off `AgentConfig.tooling`:
|
||||
```yaml
|
||||
nodes:
|
||||
- id: solve
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
model: gpt-4o-mini
|
||||
prompt_template: solver
|
||||
tooling:
|
||||
type: function
|
||||
config:
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
auto_load: true
|
||||
timeout: 20
|
||||
```
|
||||
|
||||
## 1. Lifecycle
|
||||
1. **Parse** – `ToolingConfig` selects `FunctionToolConfig`, `McpRemoteConfig`, or `McpLocalConfig` based on `type`. Field definitions live in `entity/configs/tooling.py`.
|
||||
2. **Runtime** – When the LLM chooses a tool, the executor injects `_context` (attachment store, workspace paths, etc.) for Function tools or forwards the request through MCP.
|
||||
3. **Completion** – Tool outputs are appended to the agent message stream and, when relevant, registered as attachments (e.g., `load_file`).
|
||||
|
||||
## 2. Documentation Map
|
||||
- [function.md](function.md) – Function Tooling config, context injection, best practices.
|
||||
- [function_catalog.md](function_catalog.md) – Built-in function list with usage notes.
|
||||
- [mcp.md](mcp.md) – MCP Tooling config, auto-launch, FastMCP example, security guidance.
|
||||
|
||||
## 3. Quick Comparison
|
||||
| Dimension | Function | MCP |
|
||||
| --- | --- | --- |
|
||||
| Deployment | In-process Python functions shipped with the backend. | Remote: call an HTTP MCP endpoint. Local: launch a process and talk over stdio. |
|
||||
| Schemas | Derived from annotations + `ParamMeta`. | Provided by the MCP server's JSON Schema. |
|
||||
| Context | `_context` provides attachments + workspace helpers automatically. | Depends on the MCP server implementation. |
|
||||
| Typical use | File I/O, local scripts, internal APIs. | Third-party tool suites, browsers, database agents. |
|
||||
|
||||
## 4. Security Notes
|
||||
- Function Tooling runs inside the backend process, so keep functions least-privileged and avoid executing arbitrary shell commands without validation.
|
||||
- MCP Tooling now has explicit **remote (HTTP)** and **local (stdio)** modes. Remote only needs an existing server URL; Local launches your binary, so constrain the command/env vars and rely on `wait_for_log` + timeouts to detect readiness.
|
||||
- Tools that mutate attachments or `code_workspace/` should respect the lifecycle described in the [Attachment guide](../../attachments.md) (Chinese for now) to avoid leaking artifacts.
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
# Function Tooling Configuration Guide
|
||||
|
||||
`FunctionToolConfig` lets agent nodes call Python functions defined in the repo. Implementation lives in `entity/configs/tooling.py`, `utils/function_catalog.py`, and `functions/function_calling/`.
|
||||
|
||||
## 1. Config Fields
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `tools` | List of `FunctionToolEntryConfig`. Each entry requires `name`. |
|
||||
| `timeout` | Tool execution timeout (seconds). |
|
||||
|
||||
`FunctionToolEntryConfig` specifics:
|
||||
- `name`: top-level function name in `functions/function_calling/`.
|
||||
|
||||
### Function picker (`module_name:function_name`) & `module_name:All`
|
||||
- The dropdown displays each function as `module_name:function_name`, where `module_name` is the relative Python file under `functions/function_calling/` (without `.py`, nested folders joined by `/`). This preserves semantic grouping for large catalogs.
|
||||
- Every module automatically prepends a `module_name:All` entry, and all `All` entries are sorted lexicographically ahead of concrete functions. Choosing it expands to all functions in that module during config parsing, preserving alphabetical order.
|
||||
- `module_name:All` is strictly for bulk imports; overriding `description`/`parameters`/`auto_fill` alongside it raises a validation error. Customize individual functions after expansion if needed.
|
||||
- Both modules and functions are sorted alphabetically, and YAML still stores the plain function names; `module_name:All` is merely an input shortcut.
|
||||
|
||||
## 2. Function Directory Requirements
|
||||
- Path: `functions/function_calling/` (override with `MAC_FUNCTIONS_DIR`).
|
||||
- Functions must live at module top level.
|
||||
- Provide Python type hints; for enums/descriptions use `typing.Annotated[..., ParamMeta(...)]`.
|
||||
- Parameters beginning with `_` or splats (`*args`/`**kwargs`) are hidden from the agent call.
|
||||
- The docstring’s first paragraph becomes the description (truncated to ~600 chars).
|
||||
- `utils/function_catalog.py` builds JSON Schemas at startup for the frontend/CLI.
|
||||
|
||||
## 3. Context Injection
|
||||
The executor passes `_context` into each function:
|
||||
| Key | Value |
|
||||
| --- | --- |
|
||||
| `attachment_store` | `utils.attachments.AttachmentStore` for querying/registering attachments. |
|
||||
| `python_workspace_root` | Session `code_workspace/` shared by Python nodes. |
|
||||
| `graph_directory` | Session root directory for relative path helpers. |
|
||||
| others | Environment-specific extras (session/node IDs, etc.). |
|
||||
Functions can declare `_context: dict | None = None` and parse it (see `functions/function_calling/file.py`’s `FileToolContext`).
|
||||
|
||||
## 4. Example: Read Text File
|
||||
```python
|
||||
from typing import Annotated
|
||||
from utils.function_catalog import ParamMeta
|
||||
|
||||
|
||||
def read_text_file(
|
||||
path: Annotated[str, ParamMeta(description="workspace-relative path")],
|
||||
*,
|
||||
encoding: str = "utf-8",
|
||||
_context: dict | None = None,
|
||||
) -> str:
|
||||
ctx = FileToolContext(_context)
|
||||
target = ctx.resolve_under_workspace(path)
|
||||
return target.read_text(encoding=encoding)
|
||||
```
|
||||
YAML usage:
|
||||
```yaml
|
||||
nodes:
|
||||
- id: summarize
|
||||
type: agent
|
||||
config:
|
||||
tooling:
|
||||
type: function
|
||||
config:
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: read_text_file
|
||||
```
|
||||
|
||||
## 5. Extension Flow
|
||||
1. Add your function under `functions/function_calling/`.
|
||||
2. Supply type hints + `ParamMeta`; set `auto_fill: false` with custom `parameters` if you need manual JSON Schema.
|
||||
3. If the function needs extra packages, declare them in `pyproject.toml`/`requirements.txt`, or use the bundled `install_python_packages` sparingly.
|
||||
4. Run `python -m tools.export_design_template ...` so the frontend picks up new enums.
|
||||
|
||||
## 6. Debugging
|
||||
- If the frontend/CLI reports function `foo` not found, double-check the name and ensure it resides under `MAC_FUNCTIONS_DIR`.
|
||||
- When `function_catalog` fails to load, `FunctionToolEntryConfig.field_specs()` includes the error—fix syntax or dependencies first.
|
||||
- Tool timeouts bubble up to the agent; raise `timeout` or handle exceptions inside the function for friendlier responses.
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
# Built-in Function Tool Catalog
|
||||
|
||||
This document lists all preset tools in the `functions/function_calling/` directory for Agent nodes to use via Function Tooling.
|
||||
|
||||
## Quick Import
|
||||
|
||||
Reference tools in YAML as follows:
|
||||
|
||||
```yaml
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: file:All # Import entire module
|
||||
- name: save_file # Import single function
|
||||
- name: deep_research:All
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Operations (file.py)
|
||||
|
||||
Tools for file and directory management within `code_workspace/`.
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `describe_available_files` | List available files in attachment store and code_workspace |
|
||||
| `list_directory` | List contents of a directory |
|
||||
| `create_folder` | Create a folder (supports nested directories) |
|
||||
| `delete_path` | Delete a file or directory |
|
||||
| `load_file` | Load a file and register as attachment, supports multimodal (text/image/audio) |
|
||||
| `save_file` | Save text content to a file |
|
||||
| `read_text_file_snippet` | Read text snippet (offset + limit), suitable for large files |
|
||||
| `read_file_segment` | Read file by line range, supports line number metadata |
|
||||
| `apply_text_edits` | Apply multiple text edits while preserving newlines and encoding |
|
||||
| `rename_path` | Rename a file or directory |
|
||||
| `copy_path` | Copy a file or directory tree |
|
||||
| `move_path` | Move a file or directory |
|
||||
| `search_in_files` | Search for text or regex patterns in workspace files |
|
||||
|
||||
**Example YAML**: [ChatDev_v1.yaml](../../../../../yaml_instance/ChatDev_v1.yaml), [file_tool_use_case.yaml](../../../../../yaml_instance/file_tool_use_case.yaml)
|
||||
|
||||
---
|
||||
|
||||
## Python Environment Management (uv_related.py)
|
||||
|
||||
Manage Python environments and dependencies using uv.
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `install_python_packages` | Install Python packages using `uv add` |
|
||||
| `init_python_env` | Initialize Python environment (uv lock + venv) |
|
||||
| `uv_run` | Execute uv run in workspace to run modules or scripts |
|
||||
|
||||
**Example YAML**: [ChatDev_v1.yaml](../../../../../yaml_instance/ChatDev_v1.yaml)
|
||||
|
||||
---
|
||||
|
||||
## Deep Research (deep_research.py)
|
||||
|
||||
Search result management and report generation tools for automated research workflows.
|
||||
|
||||
### Search Result Management
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `search_save_result` | Save or update a search result (URL, title, abstract, details) |
|
||||
| `search_load_all` | Load all saved search results |
|
||||
| `search_load_by_url` | Load a specific search result by URL |
|
||||
| `search_high_light_key` | Save highlighted keywords for a search result |
|
||||
|
||||
### Report Management
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `report_read` | Read full report content |
|
||||
| `report_read_chapter` | Read a specific chapter (supports multi-level paths like `Intro/Background`) |
|
||||
| `report_outline` | Get report outline (header hierarchy) |
|
||||
| `report_create_chapter` | Create a new chapter |
|
||||
| `report_rewrite_chapter` | Rewrite chapter content |
|
||||
| `report_continue_chapter` | Append content to an existing chapter |
|
||||
| `report_reorder_chapters` | Reorder chapters |
|
||||
| `report_del_chapter` | Delete a chapter |
|
||||
| `report_export_pdf` | Export report to PDF |
|
||||
|
||||
**Example YAML**: [deep_research_v1.yaml](../../../../../yaml_instance/deep_research_v1.yaml)
|
||||
|
||||
---
|
||||
|
||||
## Web Tools (web.py)
|
||||
|
||||
Web search and webpage content retrieval.
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `web_search` | Perform web search using Serper.dev, supports pagination and multiple languages |
|
||||
| `read_webpage_content` | Read webpage content using Jina Reader, supports rate limiting |
|
||||
|
||||
**Environment Variables**:
|
||||
- `SERPER_DEV_API_KEY`: Serper.dev API key
|
||||
- `JINA_API_KEY`: Jina API key (optional, auto rate-limited to 20 RPM without key)
|
||||
|
||||
**Example YAML**: [deep_research_v1.yaml](../../../../../yaml_instance/deep_research_v1.yaml)
|
||||
|
||||
---
|
||||
|
||||
## Video Tools (video.py)
|
||||
|
||||
Manim animation rendering and video processing.
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `render_manim` | Render Manim script, auto-detects scene class and outputs video |
|
||||
| `concat_videos` | Concatenate multiple video files using FFmpeg |
|
||||
|
||||
**Example YAML**: [teach_video.yaml](../../../../../yaml_instance/teach_video.yaml), [teach_video.yaml](../../../../../yaml_instance/teach_video.yaml)
|
||||
|
||||
---
|
||||
|
||||
## Code Execution (code_executor.py)
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `execute_code` | Execute Python code string, returns stdout and stderr |
|
||||
|
||||
> ⚠️ **Security Note**: This tool has elevated privileges and should only be used in trusted workflows.
|
||||
|
||||
---
|
||||
|
||||
## User Interaction (user.py)
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `call_user` | Send instructions to the user and get a response, for scenarios requiring human input |
|
||||
|
||||
---
|
||||
|
||||
## Weather Query (weather.py)
|
||||
|
||||
Demo tools to illustrate Function Calling workflow.
|
||||
|
||||
| Function | Description |
|
||||
|----------|-------------|
|
||||
| `get_city_num` | Return city code (hardcoded example) |
|
||||
| `get_weather` | Return weather info by city code (hardcoded example) |
|
||||
|
||||
---
|
||||
|
||||
## Adding Custom Tools
|
||||
|
||||
1. Create a Python file in `functions/function_calling/` directory
|
||||
2. Define parameters using type annotations:
|
||||
|
||||
```python
|
||||
from typing import Annotated
|
||||
from utils.function_catalog import ParamMeta
|
||||
|
||||
def my_tool(
|
||||
param1: Annotated[str, ParamMeta(description="Parameter description")],
|
||||
*,
|
||||
_context: dict | None = None, # Optional, auto-injected by system
|
||||
) -> str:
|
||||
"""Function description (shown to LLM)"""
|
||||
return "result"
|
||||
```
|
||||
|
||||
3. Restart the backend server
|
||||
4. Reference in Agent node via `name: my_tool` or `name: my_module:All`
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
# MCP Tooling Guide
|
||||
|
||||
MCP tooling is split into two explicit modes: **Remote (HTTP)** and **Local (stdio)**. They map to `tooling.type: mcp_remote` and `tooling.type: mcp_local`. The legacy `type: mcp` schema is no longer supported.
|
||||
|
||||
## 1. Mode overview
|
||||
| Mode | Tooling type | When to use | Key fields |
|
||||
| --- | --- | --- | --- |
|
||||
| Remote | `mcp_remote` | A hosted HTTP(S) MCP server (FastMCP, Claude Desktop Connector, custom gateways) | `server`, `headers`, `timeout` |
|
||||
| Local | `mcp_local` | A local executable that speaks MCP over stdio (Blender MCP, CLI tools, etc.) | `command`, `args`, `cwd`, `env`, timeouts |
|
||||
|
||||
## 2. `McpRemoteConfig`
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `server` | Required. MCP HTTP(S) endpoint, e.g. `https://api.example.com/mcp`. |
|
||||
| `headers` | Optional. Extra HTTP headers such as `Authorization`. |
|
||||
| `timeout` | Optional per-request timeout (seconds). |
|
||||
|
||||
**YAML example**
|
||||
```yaml
|
||||
nodes:
|
||||
- id: remote_mcp
|
||||
type: agent
|
||||
config:
|
||||
tooling:
|
||||
type: mcp_remote
|
||||
config:
|
||||
server: https://mcp.mycompany.com/mcp
|
||||
headers:
|
||||
Authorization: Bearer ${MY_MCP_TOKEN}
|
||||
timeout: 15
|
||||
```
|
||||
DevAll connects to the URL for each list/call request and passes `headers`. If the server is unreachable, an error is raised immediately—there is no local fallback.
|
||||
|
||||
## 3. `McpLocalConfig` fields
|
||||
`mcp_local` declares the process arguments directly under `config`:
|
||||
- `command` / `args`: executable and arguments (e.g., `uvx blender-mcp`).
|
||||
- `cwd`: optional working directory.
|
||||
- `env` / `inherit_env`: environment overrides.
|
||||
- `startup_timeout`: max seconds to wait for `wait_for_log`.
|
||||
- `wait_for_log`: regex matched against stdout to mark readiness.
|
||||
|
||||
**YAML example**
|
||||
```yaml
|
||||
nodes:
|
||||
- id: local_mcp
|
||||
type: agent
|
||||
config:
|
||||
tooling:
|
||||
type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
cwd: ${REPO_ROOT}
|
||||
wait_for_log: "MCP ready"
|
||||
startup_timeout: 8
|
||||
```
|
||||
DevAll keeps the process alive and relays MCP frames over stdio.
|
||||
|
||||
## 4. FastMCP sample server
|
||||
`mcp_example/mcp_server.py`:
|
||||
```python
|
||||
from fastmcp import FastMCP
|
||||
import random
|
||||
|
||||
mcp = FastMCP("Company Simple MCP Server", debug=True)
|
||||
|
||||
@mcp.tool
|
||||
def rand_num(a: int, b: int) -> int:
|
||||
return random.randint(a, b)
|
||||
|
||||
if __name__ == "__main__":
|
||||
mcp.run()
|
||||
```
|
||||
Launch:
|
||||
```bash
|
||||
uv run fastmcp run mcp_example/mcp_server.py --transport streamable-http --port 8010
|
||||
```
|
||||
- Remote mode: set `server` to `http://127.0.0.1:8010/mcp`.
|
||||
- Local mode: run the script with `transport=stdio` and point `command` to that invocation.
|
||||
|
||||
## 5. Security & operations
|
||||
- **Network exposure**: Remote mode should sit behind HTTPS + ACL/API keys. Local mode still has access to the host filesystem, so keep the script sandboxed.
|
||||
- **Resource cleanup**: Local mode processes are terminated by DevAll; make sure they gracefully handle SIGTERM/SIGKILL.
|
||||
- **Logs**: Emit a clear readiness line that matches `wait_for_log` to debug startup issues.
|
||||
- **Auth**: Remote mode handles tokens via `headers`; Local mode can receive secrets via `env` (never commit them).
|
||||
- **Multi-session**: If the MCP server is single-tenant, cap concurrency (e.g., `max_concurrency=1`) and share the same YAML config.
|
||||
|
||||
## 6. Debugging checklist
|
||||
1. Remote: ping the HTTP endpoint via curl or `fastmcp client`. Local: run the binary manually and confirm the readiness log.
|
||||
2. Start DevAll (optionally with `--reload`) and observe backend logs for tool discovery.
|
||||
3. When calls fail, inspect the Web UI tool traces or the structured logs under `logs/`.
|
||||
Reference in New Issue
Block a user