运行时¶
toolregistry.runtimes 子包提供 PTC(Programmatic Tool Calling,程序化工具调用) 的协议和类型。它允许 LLM 编写 Python 代码直接调用工具,减少往返和 token 消耗。
零 toolregistry 导入
此子包不导入任何 toolregistry 内部模块。它仅使用 callable、dict 和
自身的协议类型——与 executor/ 遵循相同的约束。
CodeResult¶
代码执行的结构化结果。
from toolregistry.runtimes import CodeResult
result = CodeResult(
stdout="42\n",
stderr="",
return_code=0,
error=None,
)
| 字段 | 类型 | 描述 |
|---|---|---|
stdout |
str |
捕获的标准输出 |
stderr |
str |
执行过程中写入 stderr 的内容 |
return_code |
int |
0 = 成功,1 = 异常 |
error |
str \| None |
异常回溯信息,成功时为 None |
CodeResult 是冻结的 dataclass——实例不可变。
ToolProjection¶
定义工具在代码运行时命名空间中如何呈现的协议。
from toolregistry.runtimes import ToolProjection
class MyProjection:
@property
def name(self) -> str:
return "my_tool"
@property
def doc(self) -> str | None:
return "执行某些操作。"
def __call__(self, **kwargs):
return do_something(**kwargs)
assert isinstance(MyProjection(), ToolProjection) # True
| 成员 | 描述 |
|---|---|
name(属性) |
代码命名空间中的工具名称 |
doc(属性) |
用于内省的文档字符串 |
__call__(**kwargs) |
同步调用工具 |
DirectProjection¶
进程内 ToolProjection 实现。以零开销包装裸 callable。
from toolregistry.runtimes import DirectProjection
def add(a: int, b: int) -> int:
return a + b
proj = DirectProjection(name="add", fn=add, doc="两数相加。")
proj(a=3, b=4) # → 7
# 从 Tool 对象构造:
proj = DirectProjection(name=tool.name, fn=tool.fn, doc=tool.description)
- 同步 callable 直接调用。
- 异步 callable 通过
asyncio.run()分发。
asyncio.run() 嵌套
DirectProjection.__call__ 对异步 callable 使用 asyncio.run()。
这不能在运行中的事件循环内调用。如果 CodeRuntime.execute() 在
事件循环内运行,必须处理此问题——例如通过 asyncio.to_thread() 在
单独的线程中运行 exec()。
CodeRuntime¶
代码执行引擎的协议。接受代码字符串和工具命名空间,返回结构化结果。
from toolregistry.runtimes import CodeRuntime, CodeResult, ToolProjection
class MyRuntime:
async def execute(
self,
code: str,
namespace: dict[str, ToolProjection],
*,
timeout: float | None = None,
extra_globals: dict[str, Any] | None = None,
) -> CodeResult:
# 使用可用工具执行代码...
...
assert isinstance(MyRuntime(), CodeRuntime) # True
| 参数 | 类型 | 描述 |
|---|---|---|
code |
str |
要执行的 Python 源代码 |
namespace |
dict[str, ToolProjection] |
注入执行命名空间的工具 |
timeout |
float \| None |
最大执行时间(秒),None = 无限制 |
extra_globals |
dict[str, Any] \| None |
非工具对象(导入、常量等),名称冲突时工具优先 |
validate_namespace¶
检查命名空间键是否与 ToolProjection.name 匹配的辅助函数。
from toolregistry.runtimes import DirectProjection, validate_namespace
ns = {
"add": DirectProjection(name="add", fn=lambda a, b: a + b),
"mul": DirectProjection(name="mul", fn=lambda a, b: a * b),
}
validate_namespace(ns) # 正常
ns_bad = {"wrong": DirectProjection(name="add", fn=lambda a, b: a + b)}
validate_namespace(ns_bad) # 抛出 ValueError