Files
JARVIS/development-doc/plan/tool-update/phase-t-1-manifest-system.md

485 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase T.1Manifest 驱动系统
日期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 验证器可捕获错误
- [ ] 单元测试覆盖核心逻辑