feat(agents): Phase 8.4-10.5 built-in plugins, bundled skills, coordinator
This commit is contained in:
484
development-doc/plan/tool-update/phase-t-1-manifest-system.md
Normal file
484
development-doc/plan/tool-update/phase-t-1-manifest-system.md
Normal file
@@ -0,0 +1,484 @@
|
||||
# Phase T.1:Manifest 驱动系统
|
||||
|
||||
日期:2026-04-04
|
||||
状态:待开始
|
||||
依赖:T.0(已完成)
|
||||
|
||||
---
|
||||
|
||||
## 1. 本阶段目的
|
||||
|
||||
建立 Jarvis 的 Manifest 驱动工具系统:
|
||||
|
||||
- 定义工具 Manifest Schema
|
||||
- 实现 Schema 验证
|
||||
- 创建核心工具的 Manifest 文件
|
||||
- 实现配置分离
|
||||
|
||||
---
|
||||
|
||||
## 2. Manifest Schema 设计
|
||||
|
||||
### 2.1 目录结构
|
||||
|
||||
```
|
||||
backend/app/tools/
|
||||
├── manifests/ # 工具 manifest
|
||||
│ ├── file_operator.yaml
|
||||
│ ├── search.yaml
|
||||
│ └── web_fetch.yaml
|
||||
├── schemas/ # Schema 定义
|
||||
│ ├── __init__.py
|
||||
│ ├── manifest.py # Manifest Schema
|
||||
│ ├── tool_call.py # 工具调用 Schema
|
||||
│ └── config.py # 配置 Schema
|
||||
└── configs/ # 配置分离
|
||||
└── .tool.example # 工具配置模板
|
||||
```
|
||||
|
||||
### 2.2 ToolManifest Schema
|
||||
|
||||
```python
|
||||
# tools/schemas/manifest.py
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List, Dict, Any
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class ToolType(str, Enum):
|
||||
"""工具类型"""
|
||||
SYNC = "sync" # 同步执行
|
||||
ASYNC = "async" # 异步执行
|
||||
SERVICE = "service" # 持续服务
|
||||
|
||||
|
||||
class RuntimeType(str, Enum):
|
||||
"""运行时类型"""
|
||||
PYTHON = "python"
|
||||
JAVASCRIPT = "javascript"
|
||||
NATIVE = "native"
|
||||
|
||||
|
||||
class InvocationCommand(BaseModel):
|
||||
"""调用命令定义"""
|
||||
name: str = Field(..., description="命令名称")
|
||||
description: str = Field(..., description="命令描述(给 AI 看)")
|
||||
parameters: Optional[Dict[str, Any]] = Field(
|
||||
default=None,
|
||||
description="参数 JSON Schema"
|
||||
)
|
||||
required: Optional[List[str]] = Field(
|
||||
default=None,
|
||||
description="必需参数列表"
|
||||
)
|
||||
example: Optional[str] = Field(
|
||||
default=None,
|
||||
description="调用示例"
|
||||
)
|
||||
|
||||
|
||||
class ToolManifest(BaseModel):
|
||||
"""工具 Manifest"""
|
||||
manifest_version: str = Field(
|
||||
default="1.0.0",
|
||||
description="Manifest 版本"
|
||||
)
|
||||
name: str = Field(..., description="工具名称(英文,唯一)")
|
||||
display_name: str = Field(..., description="显示名称(中文)")
|
||||
description: str = Field(..., description="工具描述")
|
||||
author: Optional[str] = Field(default=None, description="作者")
|
||||
version: str = Field(default="1.0.0", description="版本号")
|
||||
|
||||
# 执行配置
|
||||
type: ToolType = Field(default=ToolType.SYNC, description="工具类型")
|
||||
runtime: RuntimeType = Field(default=RuntimeType.PYTHON, description="运行时")
|
||||
entry: str = Field(..., description="执行入口(文件路径或命令)")
|
||||
timeout: int = Field(default=30000, description="超时时间(毫秒)")
|
||||
|
||||
# 配置
|
||||
config_schema: Optional[Dict[str, Any]] = Field(
|
||||
default=None,
|
||||
description="配置项 Schema"
|
||||
)
|
||||
|
||||
# 能力
|
||||
commands: List[InvocationCommand] = Field(
|
||||
default_factory=list,
|
||||
description="可用命令列表"
|
||||
)
|
||||
|
||||
# 元数据
|
||||
tags: Optional[List[str]] = Field(default=None, description="标签")
|
||||
dependencies: Optional[List[str]] = Field(default=None, description="依赖工具")
|
||||
enabled: bool = Field(default=True, description="是否启用")
|
||||
|
||||
class Config:
|
||||
use_enum_values = True
|
||||
```
|
||||
|
||||
### 2.3 ToolCall Schema
|
||||
|
||||
```python
|
||||
# tools/schemas/tool_call.py
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, Dict, Any, List
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class ToolCallRequest(BaseModel):
|
||||
"""工具调用请求"""
|
||||
tool_name: str = Field(..., description="工具名称")
|
||||
command: str = Field(..., description="命令名称")
|
||||
parameters: Dict[str, Any] = Field(default_factory=dict, description="参数")
|
||||
timeout: Optional[int] = Field(default=None, description="超时时间")
|
||||
context: Optional[Dict[str, Any]] = Field(
|
||||
default=None,
|
||||
description="上下文信息"
|
||||
)
|
||||
|
||||
|
||||
class ToolCallResponse(BaseModel):
|
||||
"""工具调用响应"""
|
||||
status: str = Field(..., description="状态: success/error")
|
||||
result: Optional[Any] = Field(default=None, description="执行结果")
|
||||
error: Optional[str] = Field(default=None, description="错误信息")
|
||||
message: Optional[str] = Field(default=None, description="AI 友好消息")
|
||||
base64: Optional[str] = Field(default=None, description="Base64 数据")
|
||||
duration_ms: Optional[int] = Field(default=None, description="执行耗时")
|
||||
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
|
||||
class ToolExecutionLog(BaseModel):
|
||||
"""工具执行日志"""
|
||||
id: str
|
||||
tool_name: str
|
||||
command: str
|
||||
parameters: Dict[str, Any]
|
||||
status: str
|
||||
duration_ms: int
|
||||
error: Optional[str]
|
||||
user_id: Optional[str]
|
||||
agent_id: Optional[str]
|
||||
created_at: datetime
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Manifest 示例
|
||||
|
||||
### 3.1 file_operator.yaml
|
||||
|
||||
```yaml
|
||||
manifest_version: "1.0.0"
|
||||
name: file_operator
|
||||
display_name: 文件操作器
|
||||
description: 强大的文件系统操作工具,支持读写、搜索、下载等功能
|
||||
author: Jarvis
|
||||
version: "1.0.0"
|
||||
|
||||
type: sync
|
||||
runtime: python
|
||||
entry: tools/implementations/file_operator.py
|
||||
timeout: 30000
|
||||
|
||||
config_schema:
|
||||
allowed_directories:
|
||||
type: string
|
||||
description: 允许操作的目录列表,逗号分隔
|
||||
default: ""
|
||||
max_file_size:
|
||||
type: integer
|
||||
description: 最大文件大小(字节)
|
||||
default: 10485760
|
||||
|
||||
commands:
|
||||
- name: read_file
|
||||
description: |
|
||||
读取指定路径文件的内容。支持 PDF、DOCX、XLSX 等格式自动解析。
|
||||
参数:
|
||||
- filePath (必需): 文件绝对路径
|
||||
- encoding (可选): 编码格式,默认 utf8
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
filePath:
|
||||
type: string
|
||||
description: 文件绝对路径
|
||||
encoding:
|
||||
type: string
|
||||
default: utf8
|
||||
required: [filePath]
|
||||
|
||||
- name: write_file
|
||||
description: |
|
||||
将内容写入文件。如果文件存在,自动创建新文件避免覆盖。
|
||||
参数:
|
||||
- filePath (必需): 文件绝对路径
|
||||
- content (必需): 文件内容
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
filePath:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
required: [filePath, content]
|
||||
|
||||
- name: list_directory
|
||||
description: |
|
||||
列出目录内容。
|
||||
参数:
|
||||
- directoryPath (必需): 目录绝对路径
|
||||
- showHidden (可选): 是否显示隐藏文件
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
directoryPath:
|
||||
type: string
|
||||
showHidden:
|
||||
type: boolean
|
||||
default: false
|
||||
required: [directoryPath]
|
||||
|
||||
- name: search_files
|
||||
description: |
|
||||
递归搜索匹配模式的文件。
|
||||
参数:
|
||||
- searchPath (必需): 搜索起始目录
|
||||
- pattern (必需): 文件模式,如 *.txt
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
searchPath:
|
||||
type: string
|
||||
pattern:
|
||||
type: string
|
||||
required: [searchPath, pattern]
|
||||
|
||||
tags: [file, system, essential]
|
||||
enabled: true
|
||||
```
|
||||
|
||||
### 3.2 search.yaml
|
||||
|
||||
```yaml
|
||||
manifest_version: "1.0.0"
|
||||
name: web_search
|
||||
display_name: 联网搜索
|
||||
description: 语义级并发搜索引擎,支持多源搜索和结果聚合
|
||||
author: Jarvis
|
||||
version: "1.0.0"
|
||||
|
||||
type: sync
|
||||
runtime: python
|
||||
entry: tools/implementations/web_search.py
|
||||
timeout: 60000
|
||||
|
||||
config_schema:
|
||||
api_key:
|
||||
type: string
|
||||
description: 搜索引擎 API 密钥
|
||||
required: true
|
||||
max_results:
|
||||
type: integer
|
||||
description: 最大返回结果数
|
||||
default: 10
|
||||
|
||||
commands:
|
||||
- name: search
|
||||
description: |
|
||||
执行语义级搜索。
|
||||
参数:
|
||||
- query (必需): 搜索关键词
|
||||
- max_results (可选): 最大结果数
|
||||
- sources (可选): 搜索源列表
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
query:
|
||||
type: string
|
||||
max_results:
|
||||
type: integer
|
||||
default: 10
|
||||
sources:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
required: [query]
|
||||
|
||||
- name: deep_search
|
||||
description: |
|
||||
深度搜索,带摘要生成。
|
||||
参数:
|
||||
- query (必需): 研究主题
|
||||
- keywords (必需): 关键词列表
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
query:
|
||||
type: string
|
||||
keywords:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
required: [query, keywords]
|
||||
|
||||
tags: [search, web, research]
|
||||
enabled: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Schema 验证
|
||||
|
||||
### 4.1 验证器
|
||||
|
||||
```python
|
||||
# tools/schemas/validator.py
|
||||
from pydantic import ValidationError
|
||||
from tools.schemas.manifest import ToolManifest
|
||||
|
||||
|
||||
def validate_manifest(data: dict) -> ToolManifest:
|
||||
"""验证 Manifest 数据"""
|
||||
try:
|
||||
return ToolManifest(**data)
|
||||
except ValidationError as e:
|
||||
raise ManifestValidationError(str(e))
|
||||
|
||||
|
||||
def validate_tool_call(data: dict) -> ToolCallRequest:
|
||||
"""验证工具调用请求"""
|
||||
from tools.schemas.tool_call import ToolCallRequest
|
||||
try:
|
||||
return ToolCallRequest(**data)
|
||||
except ValidationError as e:
|
||||
raise ToolCallValidationError(str(e))
|
||||
|
||||
|
||||
class ManifestValidationError(Exception):
|
||||
"""Manifest 验证错误"""
|
||||
pass
|
||||
|
||||
|
||||
class ToolCallValidationError(Exception):
|
||||
"""工具调用验证错误"""
|
||||
pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 配置分离
|
||||
|
||||
### 5.1 工具配置模板
|
||||
|
||||
```yaml
|
||||
# tools/configs/.tool.example
|
||||
# 文件操作器
|
||||
file_operator:
|
||||
allowed_directories: ""
|
||||
max_file_size: 10485760
|
||||
|
||||
# 联网搜索
|
||||
web_search:
|
||||
api_key: ""
|
||||
max_results: 10
|
||||
```
|
||||
|
||||
### 5.2 配置加载器
|
||||
|
||||
```python
|
||||
# tools/configs/loader.py
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any
|
||||
|
||||
|
||||
class ConfigLoader:
|
||||
"""工具配置加载器"""
|
||||
|
||||
def __init__(self, config_dir: Path):
|
||||
self.config_dir = config_dir
|
||||
self._cache: Dict[str, Any] = {}
|
||||
|
||||
def load(self, tool_name: str) -> Dict[str, Any]:
|
||||
"""加载指定工具的配置"""
|
||||
if tool_name in self._cache:
|
||||
return self._cache[tool_name]
|
||||
|
||||
config_file = self.config_dir / f"{tool_name}.yaml"
|
||||
if not config_file.exists():
|
||||
return {}
|
||||
|
||||
with open(config_file) as f:
|
||||
config = yaml.safe_load(f) or {}
|
||||
|
||||
self._cache[tool_name] = config
|
||||
return config
|
||||
|
||||
def reload(self, tool_name: str) -> Dict[str, Any]:
|
||||
"""重新加载配置"""
|
||||
if tool_name in self._cache:
|
||||
del self._cache[tool_name]
|
||||
return self.load(tool_name)
|
||||
|
||||
def get(self, tool_name: str, key: str, default: Any = None) -> Any:
|
||||
"""获取配置项"""
|
||||
config = self.load(tool_name)
|
||||
return config.get(key, default)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 实现步骤
|
||||
|
||||
| 步骤 | 任务 | 优先级 |
|
||||
|------|------|--------|
|
||||
| 1 | 创建目录结构 | 🟢 高 |
|
||||
| 2 | 实现 ToolManifest Schema | 🟢 高 |
|
||||
| 3 | 实现 ToolCall Schema | 🟢 高 |
|
||||
| 4 | 实现 Schema 验证器 | 🟢 高 |
|
||||
| 5 | 创建配置加载器 | 🟢 高 |
|
||||
| 6 | 创建 file_operator.yaml | 🟢 高 |
|
||||
| 7 | 创建 search.yaml | 🟡 中 |
|
||||
| 8 | 创建其他工具 Manifest | 🟡 中 |
|
||||
| 9 | 单元测试 | 🟡 中 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 核心文件变更
|
||||
|
||||
| 文件 | 变更 |
|
||||
|------|------|
|
||||
| `tools/__init__.py` | 模块初始化 |
|
||||
| `tools/schemas/__init__.py` | Schema 导出 |
|
||||
| `tools/schemas/manifest.py` | 新增 |
|
||||
| `tools/schemas/tool_call.py` | 新增 |
|
||||
| `tools/schemas/validator.py` | 新增 |
|
||||
| `tools/configs/loader.py` | 新增 |
|
||||
| `tools/manifests/file_operator.yaml` | 新增 |
|
||||
| `tools/manifests/search.yaml` | 新增 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 工作量估算
|
||||
|
||||
| 任务 | 工作量 |
|
||||
|------|--------|
|
||||
| Schema 定义 | 1 天 |
|
||||
| 验证器 | 0.5 天 |
|
||||
| 配置加载器 | 0.5 天 |
|
||||
| Manifest 文件 | 0.5 天 |
|
||||
| 单元测试 | 0.5 天 |
|
||||
| **总计** | **3 天** |
|
||||
|
||||
---
|
||||
|
||||
## 9. 验收标准
|
||||
|
||||
- [ ] ToolManifest Schema 可正确验证 Manifest
|
||||
- [ ] ToolCall Schema 可正确验证调用请求
|
||||
- [ ] 配置加载器可正确加载配置
|
||||
- [ ] Manifest 文件格式正确
|
||||
- [ ] Schema 验证器可捕获错误
|
||||
- [ ] 单元测试覆盖核心逻辑
|
||||
Reference in New Issue
Block a user