diff options
Diffstat (limited to 'src/ollama_web')
| -rw-r--r-- | src/ollama_web/llm.py | 18 | ||||
| -rw-r--r-- | src/ollama_web/mcp.py | 20 |
2 files changed, 8 insertions, 30 deletions
diff --git a/src/ollama_web/llm.py b/src/ollama_web/llm.py index 11e93d2..693cfa2 100644 --- a/src/ollama_web/llm.py +++ b/src/ollama_web/llm.py @@ -10,8 +10,9 @@ from typing import Any, cast import ollama from ollama import Message + from .config import settings -from .mcp import is_dangerous_mcp_tool, redact_secrets +from .mcp import redact_secrets from .tools.registry import ToolRegistry, default_registry # Maximum successive tool-call rounds before we force a final answer. @@ -38,14 +39,7 @@ def _safe_tool_result(result: str) -> str: return str(redacted) -def _execute_tool_with_policy( - reg: ToolRegistry, - name: str, - args: Any, -) -> str: - if is_dangerous_mcp_tool(name): - return json.dumps({"error": "MCP tool requires explicit approval"}, ensure_ascii=False) - return reg.execute(name, args if isinstance(args, dict) else json.dumps(args)) + def get_client(host: str | None = None) -> ollama.Client: @@ -265,8 +259,9 @@ def chat_with_tools( for call in calls: name = call.get("name", "") args = call.get("arguments", {}) + yield {"type": "tool_start", "name": name, "arguments": _safe_tool_arguments(args)} - result = _execute_tool_with_policy(reg, name, args) + result = reg.execute(name, args if isinstance(args, dict) else json.dumps(args)) result = _safe_tool_result(_trim_tool_result(result, settings.max_tool_result_chars)) yield {"type": "tool_end", "name": name, "result": result} tool_results.append((name, result)) @@ -443,10 +438,11 @@ def stream_chat_with_tools( for call in tool_calls: name = call.get("name", "") args = call.get("arguments", {}) + yield {"type": "tool_start", "name": name, "arguments": _safe_tool_arguments(args)} t1 = time.time() try: - result = _execute_tool_with_policy(reg, name, args) + result = reg.execute(name, args if isinstance(args, dict) else json.dumps(args)) except Exception as exc: # noqa: BLE001 logger.warning("tool %s execution failed in %.2fs: %s", name, time.time() - t1, exc) result = f"Tool execution failed: {exc}" diff --git a/src/ollama_web/mcp.py b/src/ollama_web/mcp.py index 3437a62..e52860b 100644 --- a/src/ollama_web/mcp.py +++ b/src/ollama_web/mcp.py @@ -26,18 +26,8 @@ DEFAULT_TIMEOUT = 30.0 _MCP_TOOL_PREFIX = "mcp__" _SAFE_NAME_RE = re.compile(r"^[A-Za-z0-9_-]{1,64}$") _MAX_TOOL_DESCRIPTION_CHARS = 1000 + _MAX_SCHEMA_DESCRIPTION_CHARS = 500 -_DANGEROUS_TOOL_WORDS = ( - "delete", - "remove", - "write", - "exec", - "shell", - "command", - "run", - "token", - "secret", -) _SECRET_KEY_RE = re.compile(r"(?i)(authorization|api[_-]?key|token|secret|cookie|session)") _SECRET_VALUE_PATTERNS = ( re.compile(r"(?i)Bearer\s+[A-Za-z0-9._~+/=-]+"), @@ -259,14 +249,6 @@ def wrap_untrusted_tool_output(text: str) -> str: return f"{_UNTRUSTED_PREFIX}\n<tool-output>\n{body}\n</tool-output>" -def is_dangerous_mcp_tool(name: str) -> bool: - """Return whether an MCP tool name should require explicit approval.""" - parsed = _parse_tool_name(name) - if parsed is None: - return False - lowered = parsed[1].lower() - return any(word in lowered for word in _DANGEROUS_TOOL_WORDS) - def _to_ollama_tool(server_name: str, tool: Any) -> dict[str, Any]: """Convert an MCP ``Tool`` object into an ollama-compatible tool dict. |
