JAYASWAROOP commited on
Commit
d5236dc
Β·
verified Β·
1 Parent(s): c49fbc4

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +148 -0
  2. prompt.py +35 -0
  3. requirements.txt +4 -2
  4. utils.py +129 -0
app.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from utils import run_agent_sync
3
+
4
+ st.set_page_config(page_title="MCP POC", page_icon="πŸ€–", layout="wide")
5
+
6
+ st.title("Model Context Protocol(MCP) - Learning Path Generator")
7
+
8
+ # Initialize session state for progress
9
+ if 'current_step' not in st.session_state:
10
+ st.session_state.current_step = ""
11
+ if 'progress' not in st.session_state:
12
+ st.session_state.progress = 0
13
+ if 'last_section' not in st.session_state:
14
+ st.session_state.last_section = ""
15
+ if 'is_generating' not in st.session_state:
16
+ st.session_state.is_generating = False
17
+
18
+ # Sidebar for API and URL configuration
19
+ st.sidebar.header("Configuration")
20
+
21
+ # API Key input
22
+ google_api_key = st.sidebar.text_input("Google API Key", type="password")
23
+
24
+ # Pipedream URLs
25
+ st.sidebar.subheader("Pipedream URLs")
26
+ youtube_pipedream_url = st.sidebar.text_input("YouTube URL (Required)",
27
+ placeholder="Enter your Pipedream YouTube URL")
28
+
29
+ # Secondary tool selection
30
+ secondary_tool = st.sidebar.radio(
31
+ "Select Secondary Tool:",
32
+ ["Drive", "Notion"]
33
+ )
34
+
35
+ # Secondary tool URL input
36
+ if secondary_tool == "Drive":
37
+ drive_pipedream_url = st.sidebar.text_input("Drive URL",
38
+ placeholder="Enter your Pipedream Drive URL")
39
+ notion_pipedream_url = None
40
+ else:
41
+ notion_pipedream_url = st.sidebar.text_input("Notion URL",
42
+ placeholder="Enter your Pipedream Notion URL")
43
+ drive_pipedream_url = None
44
+
45
+ # Quick guide before goal input
46
+ st.info("""
47
+ **Quick Guide:**
48
+ 1. Enter your Google API key and YouTube URL (required)
49
+ 2. Select and configure your secondary tool (Drive or Notion)
50
+ 3. Enter a clear learning goal, for example:
51
+ - "I want to learn python basics in 3 days"
52
+ - "I want to learn data science basics in 10 days"
53
+ """)
54
+
55
+ # Main content area
56
+ st.header("Enter Your Goal")
57
+ user_goal = st.text_input("Enter your learning goal:",
58
+ help="Describe what you want to learn, and we'll generate a structured path using YouTube content and your selected tool.")
59
+
60
+ # Progress area
61
+ progress_container = st.container()
62
+ progress_bar = st.empty()
63
+
64
+ def update_progress(message: str):
65
+ """Update progress in the Streamlit UI"""
66
+ st.session_state.current_step = message
67
+
68
+ # Determine section and update progress
69
+ if "Setting up agent with tools" in message:
70
+ section = "Setup"
71
+ st.session_state.progress = 0.1
72
+ elif "Added Google Drive integration" in message or "Added Notion integration" in message:
73
+ section = "Integration"
74
+ st.session_state.progress = 0.2
75
+ elif "Creating AI agent" in message:
76
+ section = "Setup"
77
+ st.session_state.progress = 0.3
78
+ elif "Generating your learning path" in message:
79
+ section = "Generation"
80
+ st.session_state.progress = 0.5
81
+ elif "Learning path generation complete" in message:
82
+ section = "Complete"
83
+ st.session_state.progress = 1.0
84
+ st.session_state.is_generating = False
85
+ else:
86
+ section = st.session_state.last_section or "Progress"
87
+
88
+ st.session_state.last_section = section
89
+
90
+ # Show progress bar
91
+ progress_bar.progress(st.session_state.progress)
92
+
93
+ # Update progress container with current status
94
+ with progress_container:
95
+ # Show section header if it changed
96
+ if section != st.session_state.last_section and section != "Complete":
97
+ st.write(f"**{section}**")
98
+
99
+ # Show message with tick for completed steps
100
+ if message == "Learning path generation complete!":
101
+ st.success("All steps completed! πŸŽ‰")
102
+ else:
103
+ prefix = "βœ“" if st.session_state.progress >= 0.5 else "β†’"
104
+ st.write(f"{prefix} {message}")
105
+
106
+ # Generate Learning Path button
107
+ if st.button("Generate Learning Path", type="primary", disabled=st.session_state.is_generating):
108
+ if not google_api_key:
109
+ st.error("Please enter your Google API key in the sidebar.")
110
+ elif not youtube_pipedream_url:
111
+ st.error("YouTube URL is required. Please enter your Pipedream YouTube URL in the sidebar.")
112
+ elif (secondary_tool == "Drive" and not drive_pipedream_url) or (secondary_tool == "Notion" and not notion_pipedream_url):
113
+ st.error(f"Please enter your Pipedream {secondary_tool} URL in the sidebar.")
114
+ elif not user_goal:
115
+ st.warning("Please enter your learning goal.")
116
+ else:
117
+ try:
118
+ # Set generating flag
119
+ st.session_state.is_generating = True
120
+
121
+ # Reset progress
122
+ st.session_state.current_step = ""
123
+ st.session_state.progress = 0
124
+ st.session_state.last_section = ""
125
+
126
+ result = run_agent_sync(
127
+ google_api_key=google_api_key,
128
+ youtube_pipedream_url=youtube_pipedream_url,
129
+ drive_pipedream_url=drive_pipedream_url,
130
+ notion_pipedream_url=notion_pipedream_url,
131
+ user_goal=user_goal,
132
+ progress_callback=update_progress
133
+ )
134
+
135
+ # Display results
136
+ st.header("Your Learning Path")
137
+ # print(result)
138
+ if result and "messages" in result:
139
+ for msg in result["messages"]:
140
+ st.markdown(f"πŸ“š {msg.content}")
141
+
142
+ else:
143
+ st.error("No results were generated. Please try again.")
144
+ st.session_state.is_generating = False
145
+ except Exception as e:
146
+ st.error(f"An error occurred: {str(e)}")
147
+ st.error("Please check your API keys and URLs, and try again.")
148
+ st.session_state.is_generating = False
prompt.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ user_goal_prompt = """
2
+ Main Instruction: You are a day wise learning path generator. You will be given a goal. You have to generate a comprehensive day-wise learning path for the user goal in a Drive document/Notion page and create a corresponding YouTube playlist containing the core learning videos.
3
+ Step-by-Step Execution Flow:
4
+ You must follow these steps sequentially to fulfill the user's request:
5
+ 1. Plan the Learning Path Structure: Internally, devise a day-wise structure of topics relevant to the user's learning goal. Determine the core topics needed to achieve the goal, aiming for a logical progression. Limit the number of days/topics to a manageable size for a foundational path.
6
+ 2. Research Potential Video Resources: For each topic identified in the plan, search and identify multiple relevant YouTube video URLs that could serve as learning resources. This step aims for broad discovery.
7
+ 3. Select Core Videos for the Learning Path: From the researched videos, select the single most suitable video for each day/topic in your planned structure (from Step 1). These selected videos should be foundational, provide excellent overviews, or be highly impactful for that specific topic and the overall learning goal. The total number of selected videos will match the number of days/topics planned. These selected videos will form the content of both the document and the playlist.
8
+ 4. Format the Document Content: Create the content that will go into the document/Notion page. Using the structure from Step 1 and the core videos selected in Step 3, format the day-wise learning path according to the 'Learning path sample format'. Ensure the content includes a clear main title for the learning path and uses headers/titles for each day/section.
9
+ 5. Create and Populate Drive Document/Notion Page:
10
+ a. Create a new document in Google Drive/Notion page(while creating get the document/notion page id for to read and write). choosing based on the tools available to you.
11
+ b. Paste the formatted day-wise learning path content from Step 4 into the document/Notion page. Ensure all YouTube links are properly formatted as clickable links within the document.
12
+ c. Save the document/Notion page ID for further use.
13
+ 6. Create Public YouTube Playlist:
14
+ a. Create one public YouTube playlist with a relevant title for the overall learning path.
15
+ b. Save the YouTube playlist ID for further use(to add youtube video urls from the learning path).
16
+ c. Add only the core videos selected in Step 3 (the same videos listed in the document) to this playlist.
17
+ if you are unable to find a previously created playlist by you, try the step 6 again.
18
+ 7. (Optional) Suggest Further Resources: (If deemed relevant for the topic based on your knowledge) Add a small section at the end of the document/Notion page suggesting "Top Channels or Institutes to Follow" for further learning on the main topic.
19
+ 8. Provide Outputs: Ensure the final response to the user includes the links to the created Google Drive document/Notion page and the YouTube playlist. The final output should explicitly state: "Here is your learning path document link: [link]" and "Here is your YouTube playlist link: [link] (with relevant content)".
20
+
21
+ General Instructions & Guidelines:
22
+ 1. Act like a team player, coordinating between tools.
23
+ 2. Utilize the provided tool descriptions. Choose tools like Google Drive/Notion and YouTube API based on their availability and your capabilities.
24
+ 3. You can use multiple tools simultaneously.
25
+ 4. Do not ask for confirmation from the user; proceed with the best possible outcome.
26
+ 5. If encountering errors (e.g., unable to edit), find alternatives (e.g., create a new document).
27
+ 6. When searching for resources, use terms users would generally use.
28
+ 7. Remember to track document/page and playlist IDs for potential future interactions.
29
+
30
+ Learning path sample format within a day/section (to be used with overall document titles and headers):
31
+ Day X:
32
+ Topic: Topic name X
33
+ YouTube Link: URL of the core video selected for Topic X
34
+ (Continue for subsequent days...)
35
+ """
requirements.txt CHANGED
@@ -1,3 +1,5 @@
1
- altair
2
- pandas
 
 
3
  streamlit
 
1
+ langchain
2
+ langgraph
3
+ langchain-mcp-adapters
4
+ langchain-google-genai
5
  streamlit
utils.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_core.messages import HumanMessage
2
+ from langchain_core.runnables import RunnableConfig
3
+ from prompt import user_goal_prompt
4
+ from langgraph.prebuilt import create_react_agent
5
+ from langchain_mcp_adapters.client import MultiServerMCPClient
6
+ from langchain_google_genai import ChatGoogleGenerativeAI
7
+ from typing import Optional, Tuple, Any, Callable
8
+ import asyncio
9
+
10
+ cfg = RunnableConfig(recursion_limit=100)
11
+
12
+ def initialize_model(google_api_key: str) -> ChatGoogleGenerativeAI:
13
+ return ChatGoogleGenerativeAI(
14
+ model="gemini-2.5-flash",
15
+ google_api_key=google_api_key
16
+ )
17
+
18
+ async def setup_agent_with_tools(
19
+ google_api_key: str,
20
+ youtube_pipedream_url: str,
21
+ drive_pipedream_url: Optional[str] = None,
22
+ notion_pipedream_url: Optional[str] = None,
23
+ progress_callback: Optional[Callable[[str], None]] = None
24
+ ) -> Any:
25
+ """
26
+ Set up the agent with YouTube (mandatory) and optional Drive or Notion tools.
27
+ """
28
+ try:
29
+ if progress_callback:
30
+ progress_callback("Setting up agent with tools... βœ…")
31
+
32
+ # Initialize tools configuration with mandatory YouTube
33
+ tools_config = {
34
+ "youtube": {
35
+ "url": youtube_pipedream_url,
36
+ "transport": "streamable_http"
37
+ }
38
+ }
39
+
40
+ # Add Drive if URL provided
41
+ if drive_pipedream_url:
42
+ tools_config["drive"] = {
43
+ "url": drive_pipedream_url,
44
+ "transport": "streamable_http"
45
+ }
46
+ if progress_callback:
47
+ progress_callback("Added Google Drive integration... βœ…")
48
+
49
+ # Add Notion if URL provided
50
+ if notion_pipedream_url:
51
+ tools_config["notion"] = {
52
+ "url": notion_pipedream_url,
53
+ "transport": "streamable_http"
54
+ }
55
+ if progress_callback:
56
+ progress_callback("Added Notion integration... βœ…")
57
+
58
+ if progress_callback:
59
+ progress_callback("Initializing MCP client... βœ…")
60
+ # Initialize MCP client with configured tools
61
+ mcp_client = MultiServerMCPClient(tools_config)
62
+
63
+ if progress_callback:
64
+ progress_callback("Getting available tools... βœ…")
65
+ # Get all tools
66
+ tools = await mcp_client.get_tools()
67
+
68
+ if progress_callback:
69
+ progress_callback("Creating AI agent... βœ…")
70
+ # Create agent with initialized model
71
+ mcp_orch_model = initialize_model(google_api_key)
72
+ agent = create_react_agent(mcp_orch_model, tools)
73
+
74
+ if progress_callback:
75
+ progress_callback("Setup complete! Starting to generate learning path... βœ…")
76
+
77
+ return agent
78
+ except Exception as e:
79
+ print(f"Error in setup_agent_with_tools: {str(e)}")
80
+ raise
81
+
82
+ def run_agent_sync(
83
+ google_api_key: str,
84
+ youtube_pipedream_url: str,
85
+ drive_pipedream_url: Optional[str] = None,
86
+ notion_pipedream_url: Optional[str] = None,
87
+ user_goal: str = "",
88
+ progress_callback: Optional[Callable[[str], None]] = None
89
+ ) -> dict:
90
+ """
91
+ Synchronous wrapper for running the agent.
92
+ """
93
+ async def _run():
94
+ try:
95
+ agent = await setup_agent_with_tools(
96
+ google_api_key=google_api_key,
97
+ youtube_pipedream_url=youtube_pipedream_url,
98
+ drive_pipedream_url=drive_pipedream_url,
99
+ notion_pipedream_url=notion_pipedream_url,
100
+ progress_callback=progress_callback
101
+ )
102
+
103
+ # Combine user goal with prompt template
104
+ learning_path_prompt = "User Goal: " + user_goal + "\n" + user_goal_prompt
105
+
106
+ if progress_callback:
107
+ progress_callback("Generating your learning path...")
108
+
109
+ # Run the agent
110
+ result = await agent.ainvoke(
111
+ {"messages": [HumanMessage(content=learning_path_prompt)]},
112
+ config=cfg
113
+ )
114
+
115
+ if progress_callback:
116
+ progress_callback("Learning path generation complete!")
117
+
118
+ return result
119
+ except Exception as e:
120
+ print(f"Error in _run: {str(e)}")
121
+ raise
122
+
123
+ # Run in new event loop
124
+ loop = asyncio.new_event_loop()
125
+ asyncio.set_event_loop(loop)
126
+ try:
127
+ return loop.run_until_complete(_run())
128
+ finally:
129
+ loop.close()