fix: fix the issue of bind_tools not working. now, any model with tool tag can use toolkit (if you don't have OpenAI API key, some analysis are ignored.

This commit is contained in:
autotntfan 2025-07-13 22:38:55 +08:00
parent 15a6f2af29
commit 05ff663a63
1 changed files with 44 additions and 11 deletions

View File

@ -25,15 +25,44 @@ log = logging.getLogger(__name__)
def _ollama_has_tools_flag(model_name: str) -> bool:
"""
Return True iff `ollama show <model_name>` contains `"tools": true`.
Return True iff `ollama show <model_name>` contains tools capability.
If the command fails (e.g. Windows, sandbox), fall back to False.
"""
try:
output = subprocess.check_output(
shlex.split(f"ollama show {model_name}"), text=True
)
return '"tools": true' in output
except (NotImplementedError, AttributeError) as e:
# Check for multiple possible tools indicators
tools_indicators = [
'"tools": true', # Old format
'tools ', # New format in Capabilities section
'tools\n', # Alternative new format
'tools\t', # Tab-separated format
]
# Also check if we're in the Capabilities section
lines = output.split('\n')
in_capabilities = False
for line in lines:
line_stripped = line.strip().lower()
if 'capabilities' in line_stripped:
in_capabilities = True
elif in_capabilities and line_stripped and not line.startswith(' '):
# We've left the capabilities section
in_capabilities = False
elif in_capabilities and 'tools' in line_stripped:
log.debug("Found tools capability for model %s", model_name)
return True
# Fallback to checking for any tools indicator
for indicator in tools_indicators:
if indicator in output:
log.debug("Found tools indicator '%s' for model %s", indicator, model_name)
return True
log.debug("No tools capability found for model %s", model_name)
return False
except (NotImplementedError, AttributeError, subprocess.CalledProcessError) as e:
log.debug("Could not inspect model %s: %s", model_name, e)
return False
@ -61,14 +90,18 @@ def safe_bind_tools(
if not hasattr(llm, "bind_tools"):
return llm
# Special-case ChatOllama: check the `"tools": true` tag first
if isinstance(llm, BaseChatModel) and not _ollama_has_tools_flag(llm.model):
log.info(
"[safe_bind_tools] Model %s lacks tools support -- skipping.",
llm.model,
)
return llm
# Special-case ChatOllama: check for tools capability
if llm.__class__.__name__ == 'ChatOllama':
# Get model name from different possible attributes
model_name = getattr(llm, 'model', None) or getattr(llm, 'model_name', None)
if model_name and not _ollama_has_tools_flag(model_name):
log.info(
"[safe_bind_tools] Model %s lacks tools support -- skipping.",
model_name,
)
return llm
# Generic path: try to bind; fall back gracefully on failure
try:
return llm.bind_tools(tools)