Oliver-ai-bot_2.0/backend/app/models/tool.py
Vadym Samoilenko 7511c27750 Phase 2: Tool calling + Microsoft 365 integrations
- Add tool framework (BaseTool ABC, ToolRegistry, ToolContext/ToolResult)
- Implement agentic loop in LLMFactory.stream_with_tools() with max_rounds and timeout
- Add 9 Microsoft Graph tools: Calendar (3), Mail (3), Teams (1), Planner (2)
- Add Graph Token Manager with Fernet encryption and auto-refresh
- Add consent flow endpoints (start/callback/status/revoke)
- Add admin tool management endpoints (list/toggle)
- Add SSE tool events (tool_start, tool_result, tool_error) in chat endpoint
- Frontend: ToolCallCard component, tool call tracking in chat store
- Frontend: Admin Integrations tab with per-tool enable/disable
- Frontend: Consent banner and M365 connect flow
- Migration 008: tool_definitions, user_graph_tokens, message_tool_calls tables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:26:53 +00:00

41 lines
1.8 KiB
Python

"""
Tool Definition and Message Tool Call models
"""
from sqlalchemy import Column, String, Boolean, DateTime, Integer, Text, ForeignKey
from sqlalchemy.dialects.postgresql import UUID, JSONB
from app.database import Base
import uuid
from datetime import datetime
class ToolDefinition(Base):
"""Registry of available tools"""
__tablename__ = "tool_definitions"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
name = Column(String(100), unique=True, nullable=False)
display_name = Column(String(200), nullable=False)
description = Column(Text, nullable=False)
category = Column(String(50), nullable=False)
is_enabled = Column(Boolean, default=False, nullable=False)
allowed_modes = Column(JSONB, default=["assistant"], nullable=False)
requires_graph_consent = Column(Boolean, default=True, nullable=False)
required_scopes = Column(JSONB, default=list, nullable=False)
parameter_schema = Column(JSONB, default=dict, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
class MessageToolCall(Base):
"""Audit log for tool invocations within messages"""
__tablename__ = "message_tool_calls"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
message_id = Column(UUID(as_uuid=True), ForeignKey("messages.id", ondelete="CASCADE"), nullable=False, index=True)
tool_name = Column(String(100), nullable=False)
arguments = Column(JSONB, default=dict, nullable=False)
result = Column(JSONB, nullable=True)
success = Column(Boolean, nullable=True)
duration_ms = Column(Integer, nullable=True)
error_message = Column(Text, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)