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:
parent
15a6f2af29
commit
05ff663a63
|
|
@ -25,15 +25,44 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def _ollama_has_tools_flag(model_name: str) -> bool:
|
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.
|
If the command fails (e.g. Windows, sandbox), fall back to False.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output(
|
output = subprocess.check_output(
|
||||||
shlex.split(f"ollama show {model_name}"), text=True
|
shlex.split(f"ollama show {model_name}"), text=True
|
||||||
)
|
)
|
||||||
return '"tools": true' in output
|
# Check for multiple possible tools indicators
|
||||||
except (NotImplementedError, AttributeError) as e:
|
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)
|
log.debug("Could not inspect model %s: %s", model_name, e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -61,14 +90,18 @@ def safe_bind_tools(
|
||||||
if not hasattr(llm, "bind_tools"):
|
if not hasattr(llm, "bind_tools"):
|
||||||
return llm
|
return llm
|
||||||
|
|
||||||
# Special-case ChatOllama: check the `"tools": true` tag first
|
# Special-case ChatOllama: check for tools capability
|
||||||
if isinstance(llm, BaseChatModel) and not _ollama_has_tools_flag(llm.model):
|
if llm.__class__.__name__ == 'ChatOllama':
|
||||||
log.info(
|
# Get model name from different possible attributes
|
||||||
"[safe_bind_tools] Model %s lacks tools support -- skipping.",
|
model_name = getattr(llm, 'model', None) or getattr(llm, 'model_name', None)
|
||||||
llm.model,
|
|
||||||
)
|
if model_name and not _ollama_has_tools_flag(model_name):
|
||||||
return llm
|
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
|
# Generic path: try to bind; fall back gracefully on failure
|
||||||
try:
|
try:
|
||||||
return llm.bind_tools(tools)
|
return llm.bind_tools(tools)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue