Add Deep Agents UI, pipeline fixes, and agent improvements.

Includes deep-agents-ui integration, rework detection via Gitea,
tool-call sanitization fixes, and startup scripts.
This commit is contained in:
dapa46
2026-06-18 19:33:26 +03:00
parent ba83d0cfe4
commit 0f38d8d588
83 changed files with 22561 additions and 179 deletions
+28 -6
View File
@@ -5,6 +5,7 @@ from typing import Any
from langchain.agents.middleware import AgentMiddleware, AgentState
from langchain_core.messages import ToolMessage
from langchain_core.tools import BaseTool
class SanitizeToolCallsMiddleware(AgentMiddleware[AgentState[Any], Any]):
@@ -13,9 +14,26 @@ class SanitizeToolCallsMiddleware(AgentMiddleware[AgentState[Any], Any]):
def __init__(self, known_tools: set[str]):
self.known_tools = known_tools
self.tools_by_name: dict[str, BaseTool] = {}
def _reject(self, request) -> ToolMessage:
name = request.tool_call.get("name", "")
@staticmethod
def _normalize_tool_name(name: str) -> str:
# gpt-oss иногда шлёт read_file<|channel|>commentary вместо read_file
if "<|channel|>" in name:
name = name.split("<|channel|>", 1)[0]
return name.strip()
def _prepare_request(self, request) -> str:
"""Нормализует имя и перепривязывает tool после lookup в ToolNode."""
raw_name = request.tool_call.get("name", "")
name = self._normalize_tool_name(raw_name)
if name != raw_name:
request.tool_call["name"] = name
if request.tool is None and name in self.tools_by_name:
request.tool = self.tools_by_name[name]
return name
def _reject(self, request, name: str) -> ToolMessage:
available = sorted(self.known_tools)
return ToolMessage(
content=(
@@ -28,13 +46,17 @@ class SanitizeToolCallsMiddleware(AgentMiddleware[AgentState[Any], Any]):
)
def wrap_tool_call(self, request, handler):
name = request.tool_call.get("name", "")
name = self._prepare_request(request)
if name not in self.known_tools:
return self._reject(request)
return self._reject(request, name)
if request.tool is None:
return self._reject(request, name)
return handler(request)
async def awrap_tool_call(self, request, handler):
name = request.tool_call.get("name", "")
name = self._prepare_request(request)
if name not in self.known_tools:
return self._reject(request)
return self._reject(request, name)
if request.tool is None:
return self._reject(request, name)
return await handler(request)