Calendar integration: add timezone config and fix tool call parsing
- Add timezone field to CalendarConfig for local timezone support - Update CustomProvider to parse calendar tool calls from JSON in LLM responses - Add pytz dependency to pyproject.toml for timezone handling
This commit is contained in:
parent
bc53dc6535
commit
6364a195c5
@ -252,6 +252,7 @@ class CalendarConfig(Base):
|
||||
token_file: str = "" # Path to store OAuth2 token (default: ~/.nanobot/calendar_token.json)
|
||||
calendar_id: str = "primary" # Calendar ID to use (default: primary calendar)
|
||||
auto_schedule_from_email: bool = True # Automatically schedule meetings from emails
|
||||
timezone: str = "UTC" # Timezone for parsing times (e.g., "America/New_York", "Europe/London", "UTC")
|
||||
|
||||
|
||||
class ExecToolConfig(Base):
|
||||
|
||||
@ -62,22 +62,37 @@ class CustomProvider(LLMProvider):
|
||||
# If no structured tool calls, try to parse from content (Ollama sometimes returns JSON in content)
|
||||
# Only parse if content looks like it contains a tool call JSON (to avoid false positives)
|
||||
content = msg.content or ""
|
||||
if not tool_calls and content and '"name"' in content and '"parameters"' in content:
|
||||
# Check for standard format: {"name": "...", "parameters": {...}}
|
||||
has_standard_format = '"name"' in content and '"parameters"' in content
|
||||
# Check for calendar tool format: {"action": "...", ...}
|
||||
has_calendar_format = '"action"' in content and ("calendar" in content.lower() or any(action in content for action in ["list_events", "create_event", "update_event", "delete_event"]))
|
||||
|
||||
if not tool_calls and content and (has_standard_format or has_calendar_format):
|
||||
import re
|
||||
# Look for JSON tool call patterns: {"name": "exec", "parameters": {...}}
|
||||
# Look for JSON tool call patterns: {"name": "exec", "parameters": {...}} or {"action": "list_events", ...}
|
||||
# Find complete JSON objects by matching braces
|
||||
pattern = r'\{\s*"name"\s*:\s*"(\w+)"'
|
||||
# Try "action" pattern first (for calendar tool), then "name" pattern
|
||||
patterns = [
|
||||
(r'\{\s*"action"\s*:\s*"(\w+)"', "action"), # Calendar tool format
|
||||
(r'\{\s*"name"\s*:\s*"(\w+)"', "name"), # Standard format
|
||||
]
|
||||
start_pos = 0
|
||||
max_iterations = 5 # Safety limit
|
||||
max_iterations = 10 # Increased for multiple patterns
|
||||
iteration = 0
|
||||
while iteration < max_iterations:
|
||||
iteration += 1
|
||||
match = re.search(pattern, content[start_pos:])
|
||||
match = None
|
||||
pattern_type = None
|
||||
for pattern, ptype in patterns:
|
||||
match = re.search(pattern, content[start_pos:])
|
||||
if match:
|
||||
pattern_type = ptype
|
||||
break
|
||||
if not match:
|
||||
break
|
||||
|
||||
json_start = start_pos + match.start()
|
||||
name = match.group(1)
|
||||
key_value = match.group(1)
|
||||
|
||||
# Find the matching closing brace by counting braces
|
||||
brace_count = 0
|
||||
@ -98,7 +113,24 @@ class CustomProvider(LLMProvider):
|
||||
try:
|
||||
json_str = content[json_start:json_end]
|
||||
tool_obj = json_repair.loads(json_str)
|
||||
# Only accept if it has both name and parameters, and name is a valid tool name
|
||||
|
||||
# Handle calendar tool format: {"action": "...", ...}
|
||||
if isinstance(tool_obj, dict) and "action" in tool_obj:
|
||||
# This is a calendar tool call in JSON format
|
||||
action = tool_obj.get("action")
|
||||
if action and action in ["list_events", "create_event", "update_event", "delete_event", "delete_events", "check_availability"]:
|
||||
# Convert to calendar tool call format
|
||||
tool_calls.append(ToolCallRequest(
|
||||
id=f"call_{len(tool_calls)}",
|
||||
name="calendar",
|
||||
arguments=tool_obj # Pass the whole object as arguments
|
||||
))
|
||||
# Remove the tool call from content
|
||||
content = content[:json_start] + content[json_end:].strip()
|
||||
start_pos = json_start # Stay at same position since we removed text
|
||||
continue
|
||||
|
||||
# Handle standard format: {"name": "...", "parameters": {...}}
|
||||
# Note: This list should match tools registered in AgentLoop._register_default_tools()
|
||||
valid_tools = [
|
||||
# File tools
|
||||
|
||||
@ -46,6 +46,7 @@ dependencies = [
|
||||
"google-api-python-client>=2.0.0",
|
||||
"google-auth-httplib2>=0.2.0",
|
||||
"google-auth-oauthlib>=1.0.0",
|
||||
"pytz>=2024.1",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user