mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 05:50:44 +08:00
重构仓库目录为统一的 runtime 分层并清理历史 openclaw 残留。
本次迁移将网关/通道/工具/技能/脚本与协议资源集中到新结构,统一路径常量与脚本转发机制,减少顶层噪音并保证运行与测试行为一致。 Made-with: Cursor
This commit is contained in:
parent
ba3836f00f
commit
4a23b715a2
498 changed files with 2760 additions and 2200 deletions
80
runtime/tools/base.py
Normal file
80
runtime/tools/base.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Callable
|
||||
|
||||
|
||||
ToolHandler = Callable[[dict[str, Any]], Any]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ToolRateLimit:
|
||||
"""Best-effort per-tool rate limiting metadata (enforced by runtime when implemented)."""
|
||||
|
||||
# tokens per window (simple leaky bucket style); None means unlimited.
|
||||
limit: int | None = None
|
||||
window_s: int = 60
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ToolSpec:
|
||||
name: str
|
||||
description: str
|
||||
parameters: dict[str, Any]
|
||||
handler: ToolHandler
|
||||
tags: frozenset[str] = field(default_factory=frozenset)
|
||||
# Contract metadata (non-OpenAI; used by orchestrator/runtime)
|
||||
version: str = "v1"
|
||||
risk_level: str = "low" # low|high (extendable)
|
||||
timeout_s: float | None = None
|
||||
rate_limit: ToolRateLimit | None = None
|
||||
required_permissions: frozenset[str] = field(default_factory=frozenset)
|
||||
execution_mode: str = "in_process" # in_process|subprocess (best-effort)
|
||||
#: If true, may run in parallel with other consecutive read-only tools (cc-mini-style batching).
|
||||
read_only: bool = False
|
||||
|
||||
def is_read_only(self) -> bool:
|
||||
"""Compatibility helper mirroring cc-mini Tool.is_read_only()."""
|
||||
return bool(self.read_only)
|
||||
|
||||
def as_openai_tool(self) -> dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"parameters": self.parameters,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class ToolRegistry:
|
||||
def __init__(self, tools: list[ToolSpec] | None = None):
|
||||
self._tools: dict[str, ToolSpec] = {}
|
||||
self._openai_tools_cache: list[dict[str, Any]] | None = None
|
||||
if tools:
|
||||
for t in tools:
|
||||
self.register(t)
|
||||
|
||||
def register(self, tool: ToolSpec) -> None:
|
||||
self._tools[tool.name] = tool
|
||||
self._openai_tools_cache = None
|
||||
|
||||
def get(self, name: str) -> ToolSpec | None:
|
||||
return self._tools.get(name)
|
||||
|
||||
def list(self) -> list[ToolSpec]:
|
||||
return list(self._tools.values())
|
||||
|
||||
def as_openai_tools(self) -> list[dict[str, Any]]:
|
||||
if self._openai_tools_cache is None:
|
||||
self._openai_tools_cache = [t.as_openai_tool() for t in self.list()]
|
||||
return list(self._openai_tools_cache)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ToolHandler",
|
||||
"ToolRateLimit",
|
||||
"ToolSpec",
|
||||
"ToolRegistry",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue