初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,10 @@
|
||||
"""百工工具运行时领域结构(ToolSpec / ToolResult / ToolInput)。
|
||||
|
||||
工具的实际编排(``ToolRuntime``)与内置工具注册(``builtins``)已迁至
|
||||
``application/tool_runtime/``——它们需要协调沙箱(integrations)、司命(modules)、
|
||||
事件存储(services)等多层,属于应用编排而非纯领域。本目录只保留无 IO 的工具规格数据结构。
|
||||
"""
|
||||
|
||||
from app.modules.tool_runtime.definition import ToolInput, ToolResult, ToolSpec
|
||||
|
||||
__all__ = ["ToolInput", "ToolResult", "ToolSpec"]
|
||||
@@ -0,0 +1,92 @@
|
||||
"""工具定义:ToolSpec 描述工具元数据与请求构造方式,ToolResult 为执行产出。
|
||||
|
||||
字段口径对齐 docs/architecture/service-boundaries.md(工具定义字段、风险分级、
|
||||
权限策略)。工具的实际执行有两条路径:
|
||||
- 沙箱路径:``build_request`` 产出沙箱 ExecRequest,由 SandboxClient 执行(文件/shell 类)。
|
||||
- 直接执行路径:``executor`` 非 None 时由 runtime 注入 http_client、密钥等上下文直接执行
|
||||
(HTTP 类工具如 fetch_url,不走沙箱)。
|
||||
|
||||
本模块是纯领域数据结构(无 IO):``ExecRequest`` 仅在类型注解中引用(``TYPE_CHECKING``),
|
||||
运行时不依赖 ``integrations``;实际 ExecRequest 的构造在 ``application/tool_runtime/``。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING, Any, Protocol
|
||||
|
||||
from app.modules.safety.governor import PermissionPolicy
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# 仅类型注解用:build_request 产出沙箱 ExecRequest,但本模块运行时不依赖 integrations
|
||||
# (保持 modules 零 IO 依赖);实际构造在 application/tool_runtime/builtins。
|
||||
from app.integrations.sandbox.models import ExecRequest
|
||||
|
||||
ToolInput = dict[str, Any]
|
||||
RequestBuilder = Callable[[ToolInput], "ExecRequest"]
|
||||
# 前向引用 ToolResult(定义在下方),避免循环依赖;TYPE_CHECKING 下解析为真实类。
|
||||
ToolExecutor = Callable[[ToolInput, dict[str, Any] | None], Awaitable["ToolResult"]]
|
||||
|
||||
|
||||
class ToolRuntimeLike(Protocol):
|
||||
"""Agent loop 所需的最小工具运行时契约。"""
|
||||
|
||||
async def execute(
|
||||
self,
|
||||
tool: str,
|
||||
input: ToolInput,
|
||||
*,
|
||||
run_id: str | None = None,
|
||||
character_id: str | None = None,
|
||||
trace_id: str | None = None,
|
||||
confirmed: bool = False,
|
||||
context: dict[str, Any] | None = None,
|
||||
) -> ToolResult: ...
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ToolResult:
|
||||
"""工具执行产出(映射沙箱 ExecResponse 或 executor 直接产出)。"""
|
||||
|
||||
ok: bool
|
||||
exit_code: int | None
|
||||
stdout: str
|
||||
stderr: str
|
||||
duration_ms: int
|
||||
timeout: bool
|
||||
truncated: bool
|
||||
trace_id: str
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ToolSpec:
|
||||
"""工具规格:名称、风险、权限策略与请求构造器/执行器。
|
||||
|
||||
执行路径二选一:
|
||||
- ``executor`` 非 None:直接执行,跳过沙箱(HTTP 类工具);``build_request`` 此时可为占位。
|
||||
- ``executor`` 为 None:走沙箱路径,用 ``build_request`` 构造 ExecRequest。
|
||||
"""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
risk_level: str # L0–L4
|
||||
permission_policy: PermissionPolicy
|
||||
build_request: RequestBuilder = field(default_factory=lambda: _placeholder_builder)
|
||||
default_timeout_ms: int = 30_000
|
||||
side_effect: bool = True
|
||||
audit_required: bool = True
|
||||
# 是否按 run/trace 隔离工作目录(文件类工具):runtime 会把 workdir 改写为
|
||||
# ``<workdir>/<run_key>``,防跨 run 信息泄漏与文件名冲突;run_key 经 sanitize 防路径注入。
|
||||
isolated_workspace: bool = False
|
||||
# 非 None 时走直接执行路径(HTTP 类工具),跳过沙箱;context 由 runtime 注入。
|
||||
executor: ToolExecutor | None = None
|
||||
# 工具入参 JSON Schema(供 LLM 生成正确参数),None 表示无参数。
|
||||
input_schema: dict[str, Any] | None = None
|
||||
|
||||
|
||||
def _placeholder_builder(
|
||||
_input: ToolInput,
|
||||
) -> ExecRequest: # pragma: no cover - 仅占位,executor 工具不走此路径
|
||||
"""executor 工具的 build_request 占位:正常不应被调用(runtime 见 executor 非 None 会跳过)。"""
|
||||
raise NotImplementedError("该工具使用 executor 直接执行,不应调用 build_request")
|
||||
Reference in new issue
Block a user