summaryrefslogtreecommitdiff
path: root/src/ollama_web/tools/registry.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ollama_web/tools/registry.py')
-rw-r--r--src/ollama_web/tools/registry.py56
1 files changed, 50 insertions, 6 deletions
diff --git a/src/ollama_web/tools/registry.py b/src/ollama_web/tools/registry.py
index e3b7824..51bdf29 100644
--- a/src/ollama_web/tools/registry.py
+++ b/src/ollama_web/tools/registry.py
@@ -14,6 +14,37 @@ from .search import web_search
@dataclass
+class ToolArtifact:
+ """Binary output produced by a tool, kept outside its text result."""
+
+ kind: str
+ mime: str
+ name: str
+ data: bytes
+ file_id: str | None = None
+ for_user: bool = True
+ for_assistant: bool = True
+
+ def public_dict(self) -> dict[str, Any]:
+ """Return browser-safe metadata without the binary payload."""
+ return {
+ "id": self.file_id,
+ "kind": self.kind,
+ "mime": self.mime,
+ "name": self.name,
+ "size": len(self.data),
+ }
+
+
+@dataclass
+class ToolExecutionResult:
+ """A tool's LLM-facing text and separately handled binary artifacts."""
+
+ text: str
+ artifacts: list[ToolArtifact] = field(default_factory=list)
+
+
+@dataclass
class ToolRegistry:
"""A simple registry mapping tool names to callable implementations."""
@@ -75,6 +106,20 @@ class ToolRegistry:
def get(self, name: str) -> Callable[..., object] | None:
return self._tools.get(name)
+ def execute_detailed(
+ self, name: str, arguments: dict[str, object] | str
+ ) -> ToolExecutionResult:
+ """Execute a tool while preserving any binary artifacts separately."""
+ result = self._execute_raw(name, arguments)
+ if isinstance(result, ToolExecutionResult):
+ return result
+ if isinstance(result, str):
+ return ToolExecutionResult(result)
+ try:
+ return ToolExecutionResult(json.dumps(result, ensure_ascii=False, default=str))
+ except (TypeError, ValueError):
+ return ToolExecutionResult(str(result))
+
def execute(self, name: str, arguments: dict[str, object] | str) -> str:
"""Execute a named tool and return a JSON-encoded string result.
@@ -87,6 +132,10 @@ class ToolRegistry:
A JSON string representation of the tool's return value, or an error
object when the tool is unknown or raises.
"""
+ return self.execute_detailed(name, arguments).text
+
+ def _execute_raw(self, name: str, arguments: dict[str, object] | str) -> object:
+ """Execute a named tool without flattening a structured result."""
func = self.get(name)
if func is None:
return json.dumps({"error": f"Unknown tool: {name}"})
@@ -106,12 +155,7 @@ class ToolRegistry:
except Exception as exc: # noqa: BLE001
return json.dumps({"error": f"{type(exc).__name__}: {exc}"})
- if isinstance(result, str):
- return result
- try:
- return json.dumps(result, ensure_ascii=False, default=str)
- except (TypeError, ValueError):
- return str(result)
+ return result
def default_registry() -> ToolRegistry: