Merge commit 'e1e4bb4706' into dev_mod

This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-04-13 20:35:04 -07:00
commit 5d3142332b
85 changed files with 2357 additions and 3132 deletions

View file

@ -139,9 +139,19 @@ async def get_editor_content(
status_code=409,
detail="This document is still being processed. Please wait a moment and try again.",
)
if state == "failed":
reason = (
doc_status.get("reason", "Unknown error")
if isinstance(doc_status, dict)
else "Unknown error"
)
raise HTTPException(
status_code=422,
detail=f"Processing failed: {reason}. You can delete this document and re-upload it.",
)
raise HTTPException(
status_code=400,
detail="This document has no viewable content yet. It may still be syncing. Try again in a few seconds, or re-upload if the issue persists.",
detail="This document has no content. It may not have been processed correctly. Try deleting and re-uploading it.",
)
markdown_content = "\n\n".join(chunk_contents)

View file

@ -636,9 +636,16 @@ async def delete_search_source_connector(
)
# Delete the connector record
search_space_id = db_connector.search_space_id
is_mcp = db_connector.connector_type == SearchSourceConnectorType.MCP_CONNECTOR
await session.delete(db_connector)
await session.commit()
if is_mcp:
from app.agents.new_chat.tools.mcp_tool import invalidate_mcp_tools_cache
invalidate_mcp_tools_cache(search_space_id)
logger.info(
f"Connector {connector_id} ({connector_name}) deleted successfully. "
f"Total documents deleted: {total_deleted}"
@ -3624,3 +3631,114 @@ async def get_drive_picker_token(
status_code=500,
detail="Failed to retrieve access token. Check server logs for details.",
) from e
# =============================================================================
# MCP Tool Trust (Allow-List) Routes
# =============================================================================
class MCPTrustToolRequest(BaseModel):
tool_name: str
@router.post("/connectors/mcp/{connector_id}/trust-tool")
async def trust_mcp_tool(
connector_id: int,
body: MCPTrustToolRequest,
session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_active_user),
):
"""Add a tool to the MCP connector's trusted (always-allow) list.
Once trusted, the tool executes without HITL approval on subsequent calls.
"""
try:
result = await session.execute(
select(SearchSourceConnector).filter(
SearchSourceConnector.id == connector_id,
SearchSourceConnector.connector_type
== SearchSourceConnectorType.MCP_CONNECTOR,
)
)
connector = result.scalars().first()
if not connector:
raise HTTPException(status_code=404, detail="MCP connector not found")
config = dict(connector.config or {})
trusted: list[str] = list(config.get("trusted_tools", []))
if body.tool_name not in trusted:
trusted.append(body.tool_name)
config["trusted_tools"] = trusted
connector.config = config
from sqlalchemy.orm.attributes import flag_modified
flag_modified(connector, "config")
await session.commit()
from app.agents.new_chat.tools.mcp_tool import invalidate_mcp_tools_cache
invalidate_mcp_tools_cache(connector.search_space_id)
return {"status": "ok", "trusted_tools": trusted}
except HTTPException:
raise
except Exception as e:
logger.error(f"Failed to trust MCP tool: {e!s}", exc_info=True)
await session.rollback()
raise HTTPException(
status_code=500, detail=f"Failed to trust tool: {e!s}"
) from e
@router.post("/connectors/mcp/{connector_id}/untrust-tool")
async def untrust_mcp_tool(
connector_id: int,
body: MCPTrustToolRequest,
session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_active_user),
):
"""Remove a tool from the MCP connector's trusted list.
The tool will require HITL approval again on subsequent calls.
"""
try:
result = await session.execute(
select(SearchSourceConnector).filter(
SearchSourceConnector.id == connector_id,
SearchSourceConnector.connector_type
== SearchSourceConnectorType.MCP_CONNECTOR,
)
)
connector = result.scalars().first()
if not connector:
raise HTTPException(status_code=404, detail="MCP connector not found")
config = dict(connector.config or {})
trusted: list[str] = list(config.get("trusted_tools", []))
if body.tool_name in trusted:
trusted.remove(body.tool_name)
config["trusted_tools"] = trusted
connector.config = config
from sqlalchemy.orm.attributes import flag_modified
flag_modified(connector, "config")
await session.commit()
from app.agents.new_chat.tools.mcp_tool import invalidate_mcp_tools_cache
invalidate_mcp_tools_cache(connector.search_space_id)
return {"status": "ok", "trusted_tools": trusted}
except HTTPException:
raise
except Exception as e:
logger.error(f"Failed to untrust MCP tool: {e!s}", exc_info=True)
await session.rollback()
raise HTTPException(
status_code=500, detail=f"Failed to untrust tool: {e!s}"
) from e