Initial commit

This commit is contained in:
AuroraCrimsonRose
2026-05-27 15:07:22 -05:00
commit cc64e8d41e
31 changed files with 2354 additions and 0 deletions

93
core/tools/base.py Normal file
View File

@@ -0,0 +1,93 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Protocol
from core.events import bus
# =========================
# TOOL CONTEXT
# =========================
@dataclass
class ToolContext:
user: str | None = None
dry_run: bool = False
# safe mutable metadata container
meta: dict[str, Any] = field(default_factory=dict)
# =========================
# TOOL CONTRACT
# =========================
class Tool(Protocol):
name: str
def execute(self, payload: dict[str, Any], ctx: ToolContext) -> Any:
...
# =========================
# BASE TOOL
# =========================
class BaseTool:
name: str = "base"
# -------------------------
# LIFECYCLE WRAPPER
# -------------------------
def run(self, payload: dict[str, Any], ctx: ToolContext):
bus.log(self.name, "tool_start", "INFO", {"payload": payload})
try:
# attach execution metadata (useful for event graph later)
ctx.meta.setdefault("tool", self.name)
ctx.meta.setdefault("dry_run", ctx.dry_run)
if ctx.dry_run:
result = self.preview(payload, ctx)
else:
result = self.execute(payload, ctx)
bus.log(
self.name,
"tool_success",
"SUCCESS",
{
"result_type": type(result).__name__,
"result": repr(result)[:500] # prevent log explosion
}
)
return result
except Exception as e:
bus.log(
self.name,
"tool_error",
"ERROR",
{
"error_type": type(e).__name__,
"error": str(e)
}
)
raise
# -------------------------
# OVERRIDABLE
# -------------------------
def execute(self, payload: dict[str, Any], ctx: ToolContext):
raise NotImplementedError("Tool must implement execute()")
def preview(self, payload: dict[str, Any], ctx: ToolContext):
return {
"dry_run": True,
"tool": self.name,
"payload": payload
}

124
core/tools/registry.py Normal file
View File

@@ -0,0 +1,124 @@
from __future__ import annotations
from typing import Any
from core.tools.base import BaseTool, ToolContext
from core.events import bus
# =========================
# TOOL REGISTRY
# =========================
class ToolRegistry:
def __init__(self):
self._tools: dict[str, BaseTool] = {}
# -------------------------
# REGISTER
# -------------------------
def register(self, tool: BaseTool):
self._tools[tool.name] = tool
bus.log(
"REGISTRY",
"tool_registered",
"INFO",
{
"tool": tool.name
}
)
# -------------------------
# RESOLVE
# -------------------------
def get(self, name: str) -> BaseTool:
tool = self._tools.get(name)
if tool is None:
bus.log(
"REGISTRY",
"tool_not_found",
"ERROR",
{"tool": name}
)
raise ValueError(f"Tool not found: {name}")
return tool
# -------------------------
# EXECUTE
# -------------------------
def run(
self,
name: str,
payload: dict[str, Any],
ctx: ToolContext
):
tool = self.get(name)
# registry metadata
ctx.meta.setdefault("registry", True)
ctx.meta.setdefault("tool_name", name)
bus.log(
"REGISTRY",
"tool_dispatch",
"INFO",
{
"tool": name,
"dry_run": ctx.dry_run,
}
)
try:
result = tool.run(payload, ctx)
bus.log(
"REGISTRY",
"tool_completed",
"SUCCESS",
{
"tool": name,
"result_type": type(result).__name__
}
)
return result
except Exception as e:
bus.log(
"REGISTRY",
"tool_failed",
"ERROR",
{
"tool": name,
"error": str(e),
"error_type": type(e).__name__
}
)
raise
# -------------------------
# DISCOVERY (NEW)
# -------------------------
def all_tools(self) -> list[BaseTool]:
return list(self._tools.values())
def names(self) -> list[str]:
return list(self._tools.keys())
def exists(self, name: str) -> bool:
return name in self._tools
# =========================
# SINGLETON
# =========================
registry = ToolRegistry()