File size: 3,634 Bytes
b7edd52
 
 
 
 
 
 
 
 
5e03012
 
b7edd52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5e03012
b7edd52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7e8c521
 
 
b7edd52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5e03012
b7edd52
 
 
 
 
 
5e03012
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import logging

from langchain.agents import create_agent
from langchain_core.tools import BaseTool
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_mcp_adapters.sessions import StreamableHttpConnection
from langgraph.graph.state import CompiledStateGraph

from agents.lazy_agent import LazyLoadingAgent
from agents.middlewares import ConfigurableModelMiddleware
from agents.prompts.competitive_programming import SYSTEM_PROMPT
from core import get_model, settings

logger = logging.getLogger(__name__)

ALLOWED_TOOLS = {
    # LeetCode - User Stats & Profile
    "leetcode_get_rating",
    "leetcode_get_profile",
    "leetcode_get_details",
    "leetcode_get_badges",
    "leetcode_get_solved",
    "leetcode_get_contest_ranking",
    "leetcode_get_contest_history",
    "leetcode_get_submissions",
    "leetcode_get_ac_submissions",
    "leetcode_get_calendar",
    "leetcode_get_skill_stats",
    "leetcode_get_languages",
    "leetcode_get_progress",
    "leetcode_get_contest_ranking_info",

    # Codeforces - User Stats & Content
    "codeforces_get_rating",
    "codeforces_get_contest_history",
    "codeforces_get_user_status",
    "codeforces_get_user_blogs",
    "codeforces_get_solved_problems",
    "codeforces_get_blog_entry",
    "codeforces_get_blog_comments",

    # AtCoder
    "atcoder_get_rating",
    "atcoder_get_history",

    # CodeChef
    "codechef_get_rating",

    # GeeksforGeeks
    "gfg_get_rating",
    "gfg_get_submissions",
    "gfg_get_posts",
}


class CompetitiveProgrammingAgent(LazyLoadingAgent):
    """CP Stat Agent with async initialization for contest and rating info."""

    def __init__(self) -> None:
        super().__init__()
        self._mcp_tools: list[BaseTool] = []
        self._mcp_client: MultiServerMCPClient | None = None

    async def load(self) -> None:
        """Initialize the CP Stat agent by loading MCP tools from the Contest API."""
        self._model = get_model(settings.DEFAULT_MODEL)

        if not settings.CONTEST_API_URL:
            logger.info("CONTEST_API_URL is not set, CP Stat agent will have no tools")
            self._mcp_tools = []
            self._graph = self._create_graph()
            self._loaded = True
            return

        try:
            connections = {
                "cpstat": StreamableHttpConnection(
                    transport="streamable_http",
                    url=settings.CONTEST_API_URL,
                )
            }

            self._mcp_client = MultiServerMCPClient(connections)
            logger.info(f"CP Stat client initialized successfully with URL: {settings.CONTEST_API_URL}")

#            all_tools = await self._mcp_client.get_tools()
#            self._mcp_tools = filter_mcp_tools(all_tools, ALLOWED_TOOLS)
            self._mcp_tools = await self._mcp_client.get_tools()
            
        except Exception as e:
            logger.error(f"Failed to initialize CP Stat agent: {e}")
            self._mcp_tools = []
            self._mcp_client = None

        # Create and store the graph
        self._graph = self._create_graph()
        self._loaded = True

    def _create_graph(self) -> CompiledStateGraph:
        """Create the CP Stat agent graph."""
        return create_agent(
            model=self._model,
            tools=self._mcp_tools,
            middleware=[
                ConfigurableModelMiddleware(),
            ],
            name="competitive-programming-agent",
            system_prompt=SYSTEM_PROMPT,
            debug=True,
        )


# Create the agent instance
competitive_programming_agent = CompetitiveProgrammingAgent()