mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-06 20:15:17 +02:00
Relocate the entire new_chat/tools/ package (62 files incl. registry, hitl, MCP cluster, and all connector subpackages: gmail/slack/discord/teams/drive/etc.) to the shared kernel. The package turned out to be a clean cohesive cluster: its only references to non-tools new_chat modules were comments, and its middleware deps were already flipped to shared in slice 5c. Flip 33 live importers (multi-agent, flows, routes, services, anonymous_agent, tests). Re-export shims remain for the frozen single-agent stack: a package __init__ mirroring the public surface (new_chat.__init__ imports it) plus invalid_tool + registry submodule shims (chat_deepagent imports those). Resolves slice 5c's two transient back-edges: shared/middleware/action_log (TYPE_CHECKING ToolDefinition) and tool_call_repair (local INVALID_TOOL_NAME) now point at app.agents.shared.tools.
53 lines
2 KiB
Python
53 lines
2 KiB
Python
"""
|
|
The ``invalid`` fallback tool.
|
|
|
|
When the model emits a tool call whose name doesn't match any registered
|
|
tool, :class:`ToolCallNameRepairMiddleware` rewrites the call to ``invalid``
|
|
with the original name and a parser/validation error string. This tool's
|
|
execution then returns that error to the model so it can self-correct.
|
|
|
|
Ported from OpenCode's ``packages/opencode/src/tool/invalid.ts`` —
|
|
LangChain has no equivalent fallback path; the default behavior on an
|
|
unknown tool name is a hard ``ToolNotFoundError`` which kills the turn.
|
|
|
|
Critically, the :class:`ToolDefinition` for this tool is **excluded** from
|
|
the system-prompt tool list and from ``LLMToolSelectorMiddleware`` selection
|
|
(see ``ToolDefinition.always_include`` filtering in the registry) — the
|
|
model never advertises ``invalid`` as a callable. It only ever shows up
|
|
in the tool registry so LangGraph can dispatch the rewritten call.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from langchain_core.tools import tool
|
|
|
|
INVALID_TOOL_NAME = "invalid"
|
|
INVALID_TOOL_DESCRIPTION = "Do not use"
|
|
|
|
|
|
def _format_invalid_message(tool: str | None, error: str | None) -> str:
|
|
"""Return the user-visible error string. Mirrors ``invalid.ts``."""
|
|
name = tool or "<unknown>"
|
|
detail = error or "(no error message provided)"
|
|
return (
|
|
f"The arguments provided to the tool `{name}` are invalid: {detail}\n"
|
|
f"Read the tool's docstring carefully and try again with valid arguments."
|
|
)
|
|
|
|
|
|
@tool(name_or_callable=INVALID_TOOL_NAME, description=INVALID_TOOL_DESCRIPTION)
|
|
def invalid_tool(tool: str | None = None, error: str | None = None) -> str:
|
|
"""Return a human-readable explanation of a tool-call validation failure.
|
|
|
|
Activated only when :class:`ToolCallNameRepairMiddleware` rewrites a
|
|
failed tool call to ``invalid`` with the original tool name and the
|
|
error message produced during validation.
|
|
"""
|
|
return _format_invalid_message(tool, error)
|
|
|
|
|
|
__all__ = [
|
|
"INVALID_TOOL_DESCRIPTION",
|
|
"INVALID_TOOL_NAME",
|
|
"invalid_tool",
|
|
]
|