Add local network IP binding for federation support
- Add get_local_ip() function to detect local network IP (192.x.x.x or 100.x.x.x) - Bind server to specific local IP instead of 0.0.0.0 for security - Only expose to local network, not internet - Fall back to localhost if not on private network This enables federation between multiple Macs on the same local network while keeping the server secure from external access.
This commit is contained in:
+55
-16
@@ -51,13 +51,36 @@ def format_tool_description(tool) -> str:
|
||||
|
||||
|
||||
def format_messages_with_tools(messages: list, tools: Optional[list] = None) -> str:
|
||||
"""Format chat messages into a single prompt using ChatML format.
|
||||
|
||||
Note: Tools are currently ignored - the model will respond normally.
|
||||
"""
|
||||
"""Format chat messages into a single prompt using ChatML format."""
|
||||
formatted = []
|
||||
|
||||
# Tools are accepted but ignored for now - model responds normally
|
||||
# Add tool instructions if tools are present
|
||||
if tools:
|
||||
tool_instructions = """You have access to tools. When asked to create, write, or modify files, USE the tools.
|
||||
|
||||
To use a tool, output ONLY valid JSON in this exact format:
|
||||
{"tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "write", "arguments": "{\\"filePath\\": \"filename.py\\", \\"content\\": \"print('hello')\\"}"}}]}
|
||||
|
||||
The "arguments" field must be a JSON string (serialized) with escaped quotes.
|
||||
|
||||
Available tools:"""
|
||||
|
||||
for tool in tools:
|
||||
tool_instructions += "\n" + format_tool_description(tool)
|
||||
|
||||
tool_instructions += "\n\nDO NOT explain how to do things. DO use tools to actually do them. Output ONLY the JSON when using tools."
|
||||
|
||||
# Add to system message or create one
|
||||
has_system = False
|
||||
for msg in messages:
|
||||
if msg.role == "system":
|
||||
msg.content = tool_instructions + "\n\n" + (msg.content or "")
|
||||
has_system = True
|
||||
break
|
||||
|
||||
if not has_system:
|
||||
from api.models import ChatMessage
|
||||
messages.insert(0, ChatMessage(role="system", content=tool_instructions))
|
||||
|
||||
for msg in messages:
|
||||
role = msg.role
|
||||
@@ -86,18 +109,34 @@ def parse_tool_calls(text: str) -> tuple:
|
||||
import json
|
||||
import re
|
||||
|
||||
# Try to find JSON with tool_calls
|
||||
# Try to find JSON with tool_calls (handle both quoted and unquoted)
|
||||
try:
|
||||
# Look for JSON object with tool_calls
|
||||
json_match = re.search(r'\{[^}]*"tool_calls"[^}]*\}', text, re.DOTALL)
|
||||
if json_match:
|
||||
data = json.loads(json_match.group())
|
||||
if "tool_calls" in data:
|
||||
tool_calls = data["tool_calls"]
|
||||
# Remove the JSON from the text
|
||||
content = text[:json_match.start()].strip()
|
||||
return content, tool_calls
|
||||
except (json.JSONDecodeError, AttributeError):
|
||||
# Look for tool_calls pattern (with or without quotes, with or without braces)
|
||||
pattern = r'tool_calls\s*:\s*(\[.*?\])(?=\s*\}|\s*$)'
|
||||
match = re.search(pattern, text, re.DOTALL)
|
||||
if match:
|
||||
array_str = match.group(1)
|
||||
# Try to parse as JSON
|
||||
try:
|
||||
tool_calls = json.loads(array_str)
|
||||
except json.JSONDecodeError:
|
||||
# Handle JavaScript-style objects with unquoted keys
|
||||
fixed = array_str
|
||||
# Replace unquoted keys with quoted keys
|
||||
fixed = re.sub(r'([{,])\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:', r'\1"\2":', fixed)
|
||||
# Replace single quotes with double quotes
|
||||
fixed = fixed.replace("'", '"')
|
||||
tool_calls = json.loads(fixed)
|
||||
|
||||
# Find and remove the tool_calls section from text
|
||||
full_pattern = r'\{?\s*tool_calls\s*:\s*\[.*?\]\s*\}?'
|
||||
full_match = re.search(full_pattern, text, re.DOTALL)
|
||||
if full_match:
|
||||
content = text[:full_match.start()].strip()
|
||||
else:
|
||||
content = text[:match.start()].strip()
|
||||
return content, tool_calls
|
||||
except (Exception):
|
||||
pass
|
||||
|
||||
# Try alternative format: look for function call patterns
|
||||
|
||||
Reference in New Issue
Block a user