Adiciona campo de ferramentas aos servidores MCP e implementa rotas para gerenciamento de sessões e ferramentas na API.
This commit is contained in:
parent
e98744b7a4
commit
dbdb72ce0e
@ -0,0 +1,32 @@
|
|||||||
|
"""add_tools_field_to_mcp_servers
|
||||||
|
|
||||||
|
Revision ID: 2d612b95d0ea
|
||||||
|
Revises: da8e7fb4da5d
|
||||||
|
Create Date: 2025-04-28 12:39:21.430144
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = '2d612b95d0ea'
|
||||||
|
down_revision: Union[str, None] = 'da8e7fb4da5d'
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""Upgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('mcp_servers', sa.Column('tools', sa.JSON(), nullable=False, server_default='[]'))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""Downgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('mcp_servers', 'tools')
|
||||||
|
# ### end Alembic commands ###
|
Binary file not shown.
@ -7,11 +7,16 @@ from datetime import datetime
|
|||||||
from src.config.database import get_db
|
from src.config.database import get_db
|
||||||
from src.core.middleware import get_api_key
|
from src.core.middleware import get_api_key
|
||||||
from src.schemas.schemas import (
|
from src.schemas.schemas import (
|
||||||
Client, ClientCreate,
|
Client,
|
||||||
Contact, ContactCreate,
|
ClientCreate,
|
||||||
Agent, AgentCreate,
|
Contact,
|
||||||
MCPServer, MCPServerCreate,
|
ContactCreate,
|
||||||
Tool, ToolCreate,
|
Agent,
|
||||||
|
AgentCreate,
|
||||||
|
MCPServer,
|
||||||
|
MCPServerCreate,
|
||||||
|
Tool,
|
||||||
|
ToolCreate,
|
||||||
)
|
)
|
||||||
from src.services import (
|
from src.services import (
|
||||||
client_service,
|
client_service,
|
||||||
@ -26,7 +31,16 @@ from src.core.exceptions import AgentNotFoundError
|
|||||||
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService
|
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService
|
||||||
from google.adk.sessions import DatabaseSessionService
|
from google.adk.sessions import DatabaseSessionService
|
||||||
from google.adk.memory import InMemoryMemoryService
|
from google.adk.memory import InMemoryMemoryService
|
||||||
|
from google.adk.events import Event
|
||||||
|
from google.adk.sessions import Session as Adk_Session
|
||||||
from src.config.settings import settings
|
from src.config.settings import settings
|
||||||
|
from src.services.session_service import (
|
||||||
|
get_session_events,
|
||||||
|
get_session_by_id,
|
||||||
|
delete_session,
|
||||||
|
get_sessions_by_agent,
|
||||||
|
get_sessions_by_client,
|
||||||
|
)
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -38,283 +52,394 @@ session_service = DatabaseSessionService(db_url=POSTGRES_CONNECTION_STRING)
|
|||||||
artifacts_service = InMemoryArtifactService()
|
artifacts_service = InMemoryArtifactService()
|
||||||
memory_service = InMemoryMemoryService()
|
memory_service = InMemoryMemoryService()
|
||||||
|
|
||||||
@router.post("/chat", response_model=ChatResponse, responses={
|
|
||||||
400: {"model": ErrorResponse},
|
@router.post(
|
||||||
404: {"model": ErrorResponse},
|
"/chat",
|
||||||
500: {"model": ErrorResponse}
|
response_model=ChatResponse,
|
||||||
})
|
responses={
|
||||||
|
400: {"model": ErrorResponse},
|
||||||
|
404: {"model": ErrorResponse},
|
||||||
|
500: {"model": ErrorResponse},
|
||||||
|
},
|
||||||
|
)
|
||||||
async def chat(
|
async def chat(
|
||||||
request: ChatRequest,
|
request: ChatRequest,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
final_response_text = await run_agent(
|
final_response_text = await run_agent(
|
||||||
request.agent_id,
|
request.agent_id,
|
||||||
request.contact_id,
|
request.contact_id,
|
||||||
request.message,
|
request.message,
|
||||||
session_service,
|
session_service,
|
||||||
artifacts_service,
|
artifacts_service,
|
||||||
memory_service,
|
memory_service,
|
||||||
db
|
db,
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"response": final_response_text,
|
"response": final_response_text,
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"timestamp": datetime.now().isoformat()
|
"timestamp": datetime.now().isoformat(),
|
||||||
}
|
}
|
||||||
|
|
||||||
except AgentNotFoundError as e:
|
except AgentNotFoundError as e:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Rotas para Sessões
|
||||||
|
@router.get("/sessions/client/{client_id}", response_model=List[Adk_Session])
|
||||||
|
def get_client_sessions(
|
||||||
|
client_id: uuid.UUID,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
api_key: str = Security(get_api_key),
|
||||||
|
):
|
||||||
|
return get_sessions_by_client(db, client_id)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/sessions/agent/{agent_id}", response_model=List[Adk_Session])
|
||||||
|
def get_agent_sessions(
|
||||||
|
agent_id: uuid.UUID,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
api_key: str = Security(get_api_key),
|
||||||
|
skip: int = 0,
|
||||||
|
limit: int = 100,
|
||||||
|
):
|
||||||
|
return get_sessions_by_agent(db, agent_id, skip, limit)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/sessions/{session_id}", response_model=Adk_Session)
|
||||||
|
def get_session(
|
||||||
|
session_id: str,
|
||||||
|
api_key: str = Security(get_api_key),
|
||||||
|
):
|
||||||
|
return get_session_by_id(session_service, session_id)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/sessions/{session_id}/messages",
|
||||||
|
response_model=List[Event],
|
||||||
|
)
|
||||||
|
async def get_agent_messages(
|
||||||
|
session_id: str,
|
||||||
|
api_key: str = Security(get_api_key),
|
||||||
|
):
|
||||||
|
return get_session_events(session_service, session_id)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete(
|
||||||
|
"/sessions/{session_id}",
|
||||||
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
|
)
|
||||||
|
def remove_session(
|
||||||
|
session_id: str,
|
||||||
|
api_key: str = Security(get_api_key),
|
||||||
|
):
|
||||||
|
return delete_session(session_service, session_id)
|
||||||
|
|
||||||
|
|
||||||
# Rotas para Clientes
|
# Rotas para Clientes
|
||||||
@router.post("/clients/", response_model=Client, status_code=status.HTTP_201_CREATED)
|
@router.post("/clients/", response_model=Client, status_code=status.HTTP_201_CREATED)
|
||||||
def create_client(
|
def create_client(
|
||||||
client: ClientCreate,
|
client: ClientCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return client_service.create_client(db, client)
|
return client_service.create_client(db, client)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/clients/", response_model=List[Client])
|
@router.get("/clients/", response_model=List[Client])
|
||||||
def read_clients(
|
def read_clients(
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return client_service.get_clients(db, skip, limit)
|
return client_service.get_clients(db, skip, limit)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/clients/{client_id}", response_model=Client)
|
@router.get("/clients/{client_id}", response_model=Client)
|
||||||
def read_client(
|
def read_client(
|
||||||
client_id: uuid.UUID,
|
client_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_client = client_service.get_client(db, client_id)
|
db_client = client_service.get_client(db, client_id)
|
||||||
if db_client is None:
|
if db_client is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cliente não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Cliente não encontrado"
|
||||||
|
)
|
||||||
return db_client
|
return db_client
|
||||||
|
|
||||||
|
|
||||||
@router.put("/clients/{client_id}", response_model=Client)
|
@router.put("/clients/{client_id}", response_model=Client)
|
||||||
def update_client(
|
def update_client(
|
||||||
client_id: uuid.UUID,
|
client_id: uuid.UUID,
|
||||||
client: ClientCreate,
|
client: ClientCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_client = client_service.update_client(db, client_id, client)
|
db_client = client_service.update_client(db, client_id, client)
|
||||||
if db_client is None:
|
if db_client is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cliente não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Cliente não encontrado"
|
||||||
|
)
|
||||||
return db_client
|
return db_client
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/clients/{client_id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.delete("/clients/{client_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
def delete_client(
|
def delete_client(
|
||||||
client_id: uuid.UUID,
|
client_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
if not client_service.delete_client(db, client_id):
|
if not client_service.delete_client(db, client_id):
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cliente não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Cliente não encontrado"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Rotas para Contatos
|
# Rotas para Contatos
|
||||||
@router.post("/contacts/", response_model=Contact, status_code=status.HTTP_201_CREATED)
|
@router.post("/contacts/", response_model=Contact, status_code=status.HTTP_201_CREATED)
|
||||||
def create_contact(
|
def create_contact(
|
||||||
contact: ContactCreate,
|
contact: ContactCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return contact_service.create_contact(db, contact)
|
return contact_service.create_contact(db, contact)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/contacts/{client_id}", response_model=List[Contact])
|
@router.get("/contacts/{client_id}", response_model=List[Contact])
|
||||||
def read_contacts(
|
def read_contacts(
|
||||||
client_id: uuid.UUID,
|
client_id: uuid.UUID,
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return contact_service.get_contacts_by_client(db, client_id, skip, limit)
|
return contact_service.get_contacts_by_client(db, client_id, skip, limit)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/contact/{contact_id}", response_model=Contact)
|
@router.get("/contact/{contact_id}", response_model=Contact)
|
||||||
def read_contact(
|
def read_contact(
|
||||||
contact_id: uuid.UUID,
|
contact_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_contact = contact_service.get_contact(db, contact_id)
|
db_contact = contact_service.get_contact(db, contact_id)
|
||||||
if db_contact is None:
|
if db_contact is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Contato não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Contato não encontrado"
|
||||||
|
)
|
||||||
return db_contact
|
return db_contact
|
||||||
|
|
||||||
|
|
||||||
@router.put("/contact/{contact_id}", response_model=Contact)
|
@router.put("/contact/{contact_id}", response_model=Contact)
|
||||||
def update_contact(
|
def update_contact(
|
||||||
contact_id: uuid.UUID,
|
contact_id: uuid.UUID,
|
||||||
contact: ContactCreate,
|
contact: ContactCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_contact = contact_service.update_contact(db, contact_id, contact)
|
db_contact = contact_service.update_contact(db, contact_id, contact)
|
||||||
if db_contact is None:
|
if db_contact is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Contato não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Contato não encontrado"
|
||||||
|
)
|
||||||
return db_contact
|
return db_contact
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/contact/{contact_id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.delete("/contact/{contact_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
def delete_contact(
|
def delete_contact(
|
||||||
contact_id: uuid.UUID,
|
contact_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
if not contact_service.delete_contact(db, contact_id):
|
if not contact_service.delete_contact(db, contact_id):
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Contato não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Contato não encontrado"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Rotas para Agentes
|
# Rotas para Agentes
|
||||||
@router.post("/agents/", response_model=Agent, status_code=status.HTTP_201_CREATED)
|
@router.post("/agents/", response_model=Agent, status_code=status.HTTP_201_CREATED)
|
||||||
def create_agent(
|
def create_agent(
|
||||||
agent: AgentCreate,
|
agent: AgentCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return agent_service.create_agent(db, agent)
|
return agent_service.create_agent(db, agent)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/agents/{client_id}", response_model=List[Agent])
|
@router.get("/agents/{client_id}", response_model=List[Agent])
|
||||||
def read_agents(
|
def read_agents(
|
||||||
client_id: uuid.UUID,
|
client_id: uuid.UUID,
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return agent_service.get_agents_by_client(db, client_id, skip, limit)
|
return agent_service.get_agents_by_client(db, client_id, skip, limit)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/agent/{agent_id}", response_model=Agent)
|
@router.get("/agent/{agent_id}", response_model=Agent)
|
||||||
def read_agent(
|
def read_agent(
|
||||||
agent_id: uuid.UUID,
|
agent_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_agent = agent_service.get_agent(db, agent_id)
|
db_agent = agent_service.get_agent(db, agent_id)
|
||||||
if db_agent is None:
|
if db_agent is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Agente não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Agente não encontrado"
|
||||||
|
)
|
||||||
return db_agent
|
return db_agent
|
||||||
|
|
||||||
|
|
||||||
@router.put("/agent/{agent_id}", response_model=Agent)
|
@router.put("/agent/{agent_id}", response_model=Agent)
|
||||||
async def update_agent(
|
async def update_agent(
|
||||||
agent_id: uuid.UUID,
|
agent_id: uuid.UUID, agent_data: Dict[str, Any], db: Session = Depends(get_db)
|
||||||
agent_data: Dict[str, Any],
|
|
||||||
db: Session = Depends(get_db)
|
|
||||||
):
|
):
|
||||||
"""Atualiza um agente existente"""
|
"""Atualiza um agente existente"""
|
||||||
return await agent_service.update_agent(db, agent_id, agent_data)
|
return await agent_service.update_agent(db, agent_id, agent_data)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/agent/{agent_id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.delete("/agent/{agent_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
def delete_agent(
|
def delete_agent(
|
||||||
agent_id: uuid.UUID,
|
agent_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
if not agent_service.delete_agent(db, agent_id):
|
if not agent_service.delete_agent(db, agent_id):
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Agente não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Agente não encontrado"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Rotas para MCPServers
|
# Rotas para MCPServers
|
||||||
@router.post("/mcp-servers/", response_model=MCPServer, status_code=status.HTTP_201_CREATED)
|
@router.post(
|
||||||
|
"/mcp-servers/", response_model=MCPServer, status_code=status.HTTP_201_CREATED
|
||||||
|
)
|
||||||
def create_mcp_server(
|
def create_mcp_server(
|
||||||
server: MCPServerCreate,
|
server: MCPServerCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return mcp_server_service.create_mcp_server(db, server)
|
return mcp_server_service.create_mcp_server(db, server)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/mcp-servers/", response_model=List[MCPServer])
|
@router.get("/mcp-servers/", response_model=List[MCPServer])
|
||||||
def read_mcp_servers(
|
def read_mcp_servers(
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return mcp_server_service.get_mcp_servers(db, skip, limit)
|
return mcp_server_service.get_mcp_servers(db, skip, limit)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/mcp-servers/{server_id}", response_model=MCPServer)
|
@router.get("/mcp-servers/{server_id}", response_model=MCPServer)
|
||||||
def read_mcp_server(
|
def read_mcp_server(
|
||||||
server_id: uuid.UUID,
|
server_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_server = mcp_server_service.get_mcp_server(db, server_id)
|
db_server = mcp_server_service.get_mcp_server(db, server_id)
|
||||||
if db_server is None:
|
if db_server is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Servidor MCP não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Servidor MCP não encontrado"
|
||||||
|
)
|
||||||
return db_server
|
return db_server
|
||||||
|
|
||||||
|
|
||||||
@router.put("/mcp-servers/{server_id}", response_model=MCPServer)
|
@router.put("/mcp-servers/{server_id}", response_model=MCPServer)
|
||||||
def update_mcp_server(
|
def update_mcp_server(
|
||||||
server_id: uuid.UUID,
|
server_id: uuid.UUID,
|
||||||
server: MCPServerCreate,
|
server: MCPServerCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_server = mcp_server_service.update_mcp_server(db, server_id, server)
|
db_server = mcp_server_service.update_mcp_server(db, server_id, server)
|
||||||
if db_server is None:
|
if db_server is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Servidor MCP não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Servidor MCP não encontrado"
|
||||||
|
)
|
||||||
return db_server
|
return db_server
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/mcp-servers/{server_id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.delete("/mcp-servers/{server_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
def delete_mcp_server(
|
def delete_mcp_server(
|
||||||
server_id: uuid.UUID,
|
server_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
if not mcp_server_service.delete_mcp_server(db, server_id):
|
if not mcp_server_service.delete_mcp_server(db, server_id):
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Servidor MCP não encontrado")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Servidor MCP não encontrado"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Rotas para Tools
|
# Rotas para Tools
|
||||||
@router.post("/tools/", response_model=Tool, status_code=status.HTTP_201_CREATED)
|
@router.post("/tools/", response_model=Tool, status_code=status.HTTP_201_CREATED)
|
||||||
def create_tool(
|
def create_tool(
|
||||||
tool: ToolCreate,
|
tool: ToolCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return tool_service.create_tool(db, tool)
|
return tool_service.create_tool(db, tool)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/tools/", response_model=List[Tool])
|
@router.get("/tools/", response_model=List[Tool])
|
||||||
def read_tools(
|
def read_tools(
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
return tool_service.get_tools(db, skip, limit)
|
return tool_service.get_tools(db, skip, limit)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/tools/{tool_id}", response_model=Tool)
|
@router.get("/tools/{tool_id}", response_model=Tool)
|
||||||
def read_tool(
|
def read_tool(
|
||||||
tool_id: uuid.UUID,
|
tool_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_tool = tool_service.get_tool(db, tool_id)
|
db_tool = tool_service.get_tool(db, tool_id)
|
||||||
if db_tool is None:
|
if db_tool is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ferramenta não encontrada")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Ferramenta não encontrada"
|
||||||
|
)
|
||||||
return db_tool
|
return db_tool
|
||||||
|
|
||||||
|
|
||||||
@router.put("/tools/{tool_id}", response_model=Tool)
|
@router.put("/tools/{tool_id}", response_model=Tool)
|
||||||
def update_tool(
|
def update_tool(
|
||||||
tool_id: uuid.UUID,
|
tool_id: uuid.UUID,
|
||||||
tool: ToolCreate,
|
tool: ToolCreate,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
db_tool = tool_service.update_tool(db, tool_id, tool)
|
db_tool = tool_service.update_tool(db, tool_id, tool)
|
||||||
if db_tool is None:
|
if db_tool is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ferramenta não encontrada")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Ferramenta não encontrada"
|
||||||
|
)
|
||||||
return db_tool
|
return db_tool
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/tools/{tool_id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.delete("/tools/{tool_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
def delete_tool(
|
def delete_tool(
|
||||||
tool_id: uuid.UUID,
|
tool_id: uuid.UUID,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
api_key: str = Security(get_api_key)
|
api_key: str = Security(get_api_key),
|
||||||
):
|
):
|
||||||
if not tool_service.delete_tool(db, tool_id):
|
if not tool_service.delete_tool(db, tool_id):
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ferramenta não encontrada")
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND, detail="Ferramenta não encontrada"
|
||||||
|
)
|
||||||
|
@ -18,14 +18,6 @@ class Settings(BaseSettings):
|
|||||||
"postgresql://postgres:root@localhost:5432/evo_ai"
|
"postgresql://postgres:root@localhost:5432/evo_ai"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Configurações do OpenAI
|
|
||||||
OPENAI_API_KEY: Optional[str] = os.getenv("OPENAI_API_KEY")
|
|
||||||
|
|
||||||
# Configurações da aplicação
|
|
||||||
APP_NAME: str = "app"
|
|
||||||
USER_ID: str = "user_1"
|
|
||||||
SESSION_ID: str = "session_001"
|
|
||||||
|
|
||||||
# Configurações de logging
|
# Configurações de logging
|
||||||
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
|
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
|
||||||
LOG_DIR: str = "logs"
|
LOG_DIR: str = "logs"
|
||||||
|
@ -79,6 +79,7 @@ class MCPServer(Base):
|
|||||||
description = Column(Text, nullable=True)
|
description = Column(Text, nullable=True)
|
||||||
config_json = Column(JSON, nullable=False, default={})
|
config_json = Column(JSON, nullable=False, default={})
|
||||||
environments = Column(JSON, nullable=False, default={})
|
environments = Column(JSON, nullable=False, default={})
|
||||||
|
tools = Column(JSON, nullable=False, default=[])
|
||||||
type = Column(String, nullable=False, default="official")
|
type = Column(String, nullable=False, default="official")
|
||||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||||
@ -96,4 +97,16 @@ class Tool(Base):
|
|||||||
config_json = Column(JSON, nullable=False, default={})
|
config_json = Column(JSON, nullable=False, default={})
|
||||||
environments = Column(JSON, nullable=False, default={})
|
environments = Column(JSON, nullable=False, default={})
|
||||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||||
|
|
||||||
|
class Session(Base):
|
||||||
|
__tablename__ = "sessions"
|
||||||
|
# A diretiva abaixo faz com que o Alembic ignore esta tabela nas migrações
|
||||||
|
__table_args__ = {'extend_existing': True, 'info': {'skip_autogenerate': True}}
|
||||||
|
|
||||||
|
id = Column(String, primary_key=True)
|
||||||
|
app_name = Column(String)
|
||||||
|
user_id = Column(String)
|
||||||
|
state = Column(JSON)
|
||||||
|
create_time = Column(DateTime(timezone=True))
|
||||||
|
update_time = Column(DateTime(timezone=True))
|
Binary file not shown.
@ -14,6 +14,7 @@ class MCPServerConfig(BaseModel):
|
|||||||
"""Configuração de um servidor MCP"""
|
"""Configuração de um servidor MCP"""
|
||||||
id: UUID
|
id: UUID
|
||||||
envs: Dict[str, str] = Field(default_factory=dict, description="Variáveis de ambiente do servidor")
|
envs: Dict[str, str] = Field(default_factory=dict, description="Variáveis de ambiente do servidor")
|
||||||
|
tools: List[str] = Field(default_factory=list, description="Lista de ferramentas do servidor")
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
@ -109,6 +109,7 @@ class MCPServerBase(BaseModel):
|
|||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
config_json: Dict[str, Any] = Field(default_factory=dict)
|
config_json: Dict[str, Any] = Field(default_factory=dict)
|
||||||
environments: Dict[str, Any] = Field(default_factory=dict)
|
environments: Dict[str, Any] = Field(default_factory=dict)
|
||||||
|
tools: List[str] = Field(default_factory=list)
|
||||||
type: str = Field(default="official")
|
type: str = Field(default="official")
|
||||||
|
|
||||||
class MCPServerCreate(MCPServerBase):
|
class MCPServerCreate(MCPServerBase):
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -48,7 +48,7 @@ async def run_agent(
|
|||||||
logger.info("Configurando Runner")
|
logger.info("Configurando Runner")
|
||||||
agent_runner = Runner(
|
agent_runner = Runner(
|
||||||
agent=root_agent,
|
agent=root_agent,
|
||||||
app_name=get_root_agent.name,
|
app_name=agent_id,
|
||||||
session_service=session_service,
|
session_service=session_service,
|
||||||
artifact_service=artifacts_service,
|
artifact_service=artifacts_service,
|
||||||
memory_service=memory_service,
|
memory_service=memory_service,
|
||||||
@ -57,7 +57,7 @@ async def run_agent(
|
|||||||
|
|
||||||
logger.info(f"Buscando sessão para contato {contact_id}")
|
logger.info(f"Buscando sessão para contato {contact_id}")
|
||||||
session = session_service.get_session(
|
session = session_service.get_session(
|
||||||
app_name=root_agent.name,
|
app_name=agent_id,
|
||||||
user_id=contact_id,
|
user_id=contact_id,
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
)
|
)
|
||||||
@ -65,7 +65,7 @@ async def run_agent(
|
|||||||
if session is None:
|
if session is None:
|
||||||
logger.info(f"Criando nova sessão para contato {contact_id}")
|
logger.info(f"Criando nova sessão para contato {contact_id}")
|
||||||
session = session_service.create_session(
|
session = session_service.create_session(
|
||||||
app_name=root_agent.name,
|
app_name=agent_id,
|
||||||
user_id=contact_id,
|
user_id=contact_id,
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
)
|
)
|
||||||
@ -85,7 +85,7 @@ async def run_agent(
|
|||||||
logger.info(f"Resposta final recebida: {final_response_text}")
|
logger.info(f"Resposta final recebida: {final_response_text}")
|
||||||
|
|
||||||
completed_session = session_service.get_session(
|
completed_session = session_service.get_session(
|
||||||
app_name=root_agent.name,
|
app_name=agent_id,
|
||||||
user_id=contact_id,
|
user_id=contact_id,
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
)
|
)
|
||||||
|
@ -66,29 +66,29 @@ def create_agent(db: Session, agent: AgentCreate) -> Agent:
|
|||||||
"""Cria um novo agente"""
|
"""Cria um novo agente"""
|
||||||
try:
|
try:
|
||||||
# Validação adicional de sub-agentes
|
# Validação adicional de sub-agentes
|
||||||
if agent.type != 'llm':
|
if agent.type != "llm":
|
||||||
if not isinstance(agent.config, dict):
|
if not isinstance(agent.config, dict):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail="Configuração inválida: deve ser um objeto com sub_agents"
|
detail="Configuração inválida: deve ser um objeto com sub_agents",
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'sub_agents' not in agent.config:
|
if "sub_agents" not in agent.config:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail="Configuração inválida: sub_agents é obrigatório para agentes do tipo sequential, parallel ou loop"
|
detail="Configuração inválida: sub_agents é obrigatório para agentes do tipo sequential, parallel ou loop",
|
||||||
)
|
)
|
||||||
|
|
||||||
if not agent.config['sub_agents']:
|
if not agent.config["sub_agents"]:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail="Configuração inválida: sub_agents não pode estar vazio"
|
detail="Configuração inválida: sub_agents não pode estar vazio",
|
||||||
)
|
)
|
||||||
|
|
||||||
if not validate_sub_agents(db, agent.config['sub_agents']):
|
if not validate_sub_agents(db, agent.config["sub_agents"]):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail="Um ou mais sub-agentes não existem"
|
detail="Um ou mais sub-agentes não existem",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Processa a configuração antes de criar o agente
|
# Processa a configuração antes de criar o agente
|
||||||
@ -114,9 +114,13 @@ def create_agent(db: Session, agent: AgentCreate) -> Agent:
|
|||||||
detail=f"Variável de ambiente '{env_key}' não fornecida para o servidor MCP {mcp_server.name}",
|
detail=f"Variável de ambiente '{env_key}' não fornecida para o servidor MCP {mcp_server.name}",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Adiciona o servidor processado
|
# Adiciona o servidor processado com suas ferramentas
|
||||||
processed_servers.append(
|
processed_servers.append(
|
||||||
{"id": str(server["id"]), "envs": server["envs"]}
|
{
|
||||||
|
"id": str(server["id"]),
|
||||||
|
"envs": server["envs"],
|
||||||
|
"tools": server["tools"],
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
config["mcp_servers"] = processed_servers
|
config["mcp_servers"] = processed_servers
|
||||||
@ -147,7 +151,7 @@ def create_agent(db: Session, agent: AgentCreate) -> Agent:
|
|||||||
logger.error(f"Erro ao criar agente: {str(e)}")
|
logger.error(f"Erro ao criar agente: {str(e)}")
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
detail="Erro ao criar agente"
|
detail="Erro ao criar agente",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -186,7 +190,11 @@ async def update_agent(
|
|||||||
|
|
||||||
# Adiciona o servidor processado
|
# Adiciona o servidor processado
|
||||||
processed_servers.append(
|
processed_servers.append(
|
||||||
{"id": str(server["id"]), "envs": server["envs"]}
|
{
|
||||||
|
"id": str(server["id"]),
|
||||||
|
"envs": server["envs"],
|
||||||
|
"tools": server["tools"],
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
config["mcp_servers"] = processed_servers
|
config["mcp_servers"] = processed_servers
|
||||||
|
@ -74,6 +74,15 @@ class MCPService:
|
|||||||
logger.warning(f"Removidas {removed_count} ferramentas incompatíveis.")
|
logger.warning(f"Removidas {removed_count} ferramentas incompatíveis.")
|
||||||
|
|
||||||
return filtered_tools
|
return filtered_tools
|
||||||
|
|
||||||
|
def _filter_tools_by_agent(self, tools: List[Any], agent_tools: List[str]) -> List[Any]:
|
||||||
|
"""Filtra ferramentas compatíveis com o agente."""
|
||||||
|
filtered_tools = []
|
||||||
|
for tool in tools:
|
||||||
|
logger.info(f"Ferramenta: {tool.name}")
|
||||||
|
if tool.name in agent_tools:
|
||||||
|
filtered_tools.append(tool)
|
||||||
|
return filtered_tools
|
||||||
|
|
||||||
async def build_tools(self, mcp_config: Dict[str, Any], db: Session) -> Tuple[List[Any], AsyncExitStack]:
|
async def build_tools(self, mcp_config: Dict[str, Any], db: Session) -> Tuple[List[Any], AsyncExitStack]:
|
||||||
"""Constrói uma lista de ferramentas a partir de múltiplos servidores MCP."""
|
"""Constrói uma lista de ferramentas a partir de múltiplos servidores MCP."""
|
||||||
@ -109,6 +118,10 @@ class MCPService:
|
|||||||
if tools and exit_stack:
|
if tools and exit_stack:
|
||||||
# Filtra ferramentas incompatíveis
|
# Filtra ferramentas incompatíveis
|
||||||
filtered_tools = self._filter_incompatible_tools(tools)
|
filtered_tools = self._filter_incompatible_tools(tools)
|
||||||
|
|
||||||
|
# Filtra ferramentas compatíveis com o agente
|
||||||
|
agent_tools = server.get('tools', [])
|
||||||
|
filtered_tools = self._filter_tools_by_agent(filtered_tools, agent_tools)
|
||||||
self.tools.extend(filtered_tools)
|
self.tools.extend(filtered_tools)
|
||||||
|
|
||||||
# Registra o exit_stack com o AsyncExitStack
|
# Registra o exit_stack com o AsyncExitStack
|
||||||
|
148
src/services/session_service.py
Normal file
148
src/services/session_service.py
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
from google.adk.sessions import DatabaseSessionService
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from src.models.models import Session as SessionModel
|
||||||
|
from google.adk.events import Event
|
||||||
|
from google.adk.sessions import Session as SessionADK
|
||||||
|
from typing import Optional, List
|
||||||
|
from fastapi import HTTPException, status
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
|
from src.services.agent_service import get_agent, get_agents_by_client
|
||||||
|
from src.services.contact_service import get_contact
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_sessions_by_client(
|
||||||
|
db: Session,
|
||||||
|
client_id: uuid.UUID,
|
||||||
|
) -> List[SessionModel]:
|
||||||
|
"""Busca sessões de um cliente com paginação"""
|
||||||
|
try:
|
||||||
|
agents_by_client = get_agents_by_client(db, client_id)
|
||||||
|
sessions = []
|
||||||
|
for agent in agents_by_client:
|
||||||
|
sessions.extend(get_sessions_by_agent(db, agent.id))
|
||||||
|
|
||||||
|
return sessions
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
logger.error(f"Erro ao buscar sessões do cliente {client_id}: {str(e)}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail="Erro ao buscar sessões",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_sessions_by_agent(
|
||||||
|
db: Session,
|
||||||
|
agent_id: uuid.UUID,
|
||||||
|
skip: int = 0,
|
||||||
|
limit: int = 100,
|
||||||
|
) -> List[SessionModel]:
|
||||||
|
"""Busca sessões de um agente com paginação"""
|
||||||
|
try:
|
||||||
|
agent_id_str = str(agent_id)
|
||||||
|
query = db.query(SessionModel).filter(SessionModel.app_name == agent_id_str)
|
||||||
|
|
||||||
|
return query.offset(skip).limit(limit).all()
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
logger.error(f"Erro ao buscar sessões do agente {agent_id_str}: {str(e)}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail="Erro ao buscar sessões",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_session_by_id(
|
||||||
|
session_service: DatabaseSessionService, session_id: str
|
||||||
|
) -> Optional[SessionADK]:
|
||||||
|
"""Busca uma sessão pelo ID"""
|
||||||
|
try:
|
||||||
|
if not session_id or "_" not in session_id:
|
||||||
|
logger.error(f"ID de sessão inválido: {session_id}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="ID de sessão inválido. Formato esperado: app_name_user_id",
|
||||||
|
)
|
||||||
|
|
||||||
|
parts = session_id.split("_", 1)
|
||||||
|
if len(parts) != 2:
|
||||||
|
logger.error(f"Formato de ID de sessão inválido: {session_id}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Formato de ID de sessão inválido. Formato esperado: app_name_user_id",
|
||||||
|
)
|
||||||
|
|
||||||
|
user_id, app_name = parts
|
||||||
|
|
||||||
|
session = session_service.get_session(
|
||||||
|
app_name=app_name,
|
||||||
|
user_id=user_id,
|
||||||
|
session_id=session_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
if session is None:
|
||||||
|
logger.error(f"Sessão não encontrada: {session_id}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Sessão não encontrada: {session_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
return session
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erro ao buscar sessão {session_id}: {str(e)}")
|
||||||
|
if isinstance(e, HTTPException):
|
||||||
|
raise e
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail=f"Erro ao buscar sessão: {str(e)}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_session(session_service: DatabaseSessionService, session_id: str) -> None:
|
||||||
|
"""Deleta uma sessão pelo ID"""
|
||||||
|
try:
|
||||||
|
session = get_session_by_id(session_service, session_id)
|
||||||
|
# Se chegou aqui, a sessão existe (get_session_by_id já valida)
|
||||||
|
|
||||||
|
session_service.delete_session(
|
||||||
|
app_name=session.app_name,
|
||||||
|
user_id=session.user_id,
|
||||||
|
session_id=session_id,
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
except HTTPException:
|
||||||
|
# Repassa exceções HTTP do get_session_by_id
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erro ao deletar sessão {session_id}: {str(e)}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail=f"Erro ao deletar sessão: {str(e)}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_session_events(
|
||||||
|
session_service: DatabaseSessionService, session_id: str
|
||||||
|
) -> List[Event]:
|
||||||
|
"""Busca os eventos de uma sessão pelo ID"""
|
||||||
|
try:
|
||||||
|
session = get_session_by_id(session_service, session_id)
|
||||||
|
# Se chegou aqui, a sessão existe (get_session_by_id já valida)
|
||||||
|
|
||||||
|
if not hasattr(session, 'events') or session.events is None:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return session.events
|
||||||
|
except HTTPException:
|
||||||
|
# Repassa exceções HTTP do get_session_by_id
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erro ao buscar eventos da sessão {session_id}: {str(e)}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail=f"Erro ao buscar eventos da sessão: {str(e)}",
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user