gperdrizet commited on
Commit
da09bef
·
verified ·
1 Parent(s): c174f50

Edits and improvements to Gradio UI

Browse files
assets/html.py CHANGED
@@ -3,18 +3,58 @@
3
  TITLE = (
4
  '''
5
  <center>
6
- <h1>Agentic RSS reader</h1>
 
7
  </center>
8
  '''
9
  )
10
 
11
  DESCRIPTION = (
12
  '''
13
- <p>Uses sister Space
 
 
 
 
14
  <a href='https://huggingface.co/spaces/Agents-MCP-Hackathon/rss-mcp-server'>
15
- RSS feed reader</a> via MCP. Click 'Connect to MCP server' to get started.
16
- Check out the <a href='https://github.com/gperdrizet/MCP-hackathon/tree/main'>
 
 
17
  main project repo on GitHub</a>. Both Spaces by
18
  <a href=https://www.linkedin.com/in/gperdrizet/'>George Perdrizet</a>.</p>
 
 
 
 
 
 
 
 
 
 
 
 
19
  '''
20
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  TITLE = (
4
  '''
5
  <center>
6
+ <h1>RASS (retrieval augmented simple syndication) Agent</h1>
7
+ <h2>Agentic RSS feed reader</h2>
8
  </center>
9
  '''
10
  )
11
 
12
  DESCRIPTION = (
13
  '''
14
+ <p><b>Problem</b>: I love RSS feeds, but need help keeping up with all of the content from my subscriptions.
15
+
16
+ <b>Solution</b>: Build a tool to allow LLMs to find and interact with RSS feeds on behalf of the user.</p>
17
+ <h2>Introduction</h2>
18
+ <p>This demonstration uses sister space
19
  <a href='https://huggingface.co/spaces/Agents-MCP-Hackathon/rss-mcp-server'>
20
+ RSS feed reader</a> via MCP to interact with RSS feeds. Click 'Connect to MCP
21
+ server' to get started. If it takes a minute or two to reply, don't worry the inference
22
+ container was probably cold and spinning up. Check out the
23
+ <a href='https://github.com/gperdrizet/MCP-hackathon/tree/main'>
24
  main project repo on GitHub</a>. Both Spaces by
25
  <a href=https://www.linkedin.com/in/gperdrizet/'>George Perdrizet</a>.</p>
26
+
27
+ I love RSS feeds - they remind me of a time when the internet was a weird and
28
+ wonderful place, filled with interesting content hiding behind every link. The tools
29
+ to produce and navigate that content have improved by leaps and bounds. However,
30
+ the improvement has not come without some losses. Content often feels homogeneous and
31
+ it is too often painfully apparent that your favorite platform has a large degree of
32
+ control over what content you see and what content you don't.
33
+
34
+ This tool give the user back some of that control. It let's them decide what content
35
+ and sources they are interested in. I built it because I want access to diverse,
36
+ unfiltered publishing by many sources, paired modern AI to help me navigate it.
37
+ I want the model to help me ingest my feed, not create it for me!
38
  '''
39
  )
40
+
41
+ FEATURES_TOOLS ='''
42
+ ## Features
43
+
44
+ 1. Inference with Anthropic's efficient claude-3-haiku model.
45
+ 2. Custom MCP client with asynchronous server side events, retry and error handling based on the excellent repo by [Adel Zaalouk](https://github.com/zanetworker/mcp-playground/tree/main).
46
+ 3. Multi-turn re-prompting to allow LLM workflows with multiple tool calls.
47
+ 4. Queue and worker system to show user what's going on 'under the hood' while the model calls tools and generates replies.
48
+
49
+ ## Tools
50
+
51
+ 1. `get_feed()`: Given a website name or URL, find its RSS feed and
52
+ return recent article titles, links and a generated summary of content if
53
+ avalible. Caches results for fast retrieval by other tools. Embeds content
54
+ to vector database for subsequent RAG.
55
+ 2. `context_search()`: Vector search on article content for RAG context.
56
+ 3. `find_article()`: Uses vector search on article content to find title of article
57
+ that user is referring to.
58
+ 4. `get_summary()`: Gets article summary from Redis cache using article title.
59
+ 5. `get_link()`: Gets article link from Redis cache using article title.
60
+ '''
client/mcp_client.py CHANGED
@@ -71,7 +71,7 @@ class MCPTimeoutError(Exception):
71
  class MCPClientWrapper:
72
  '''Main client wrapper class for interacting with Model Context Protocol (MCP) endpoints'''
73
 
74
- def __init__(self, endpoint: str, timeout: float = 30.0, max_retries: int = 3):
75
  '''Initialize MCP client with endpoint URL
76
 
77
  Args:
 
71
  class MCPClientWrapper:
72
  '''Main client wrapper class for interacting with Model Context Protocol (MCP) endpoints'''
73
 
74
+ def __init__(self, endpoint: str, timeout: float = 360.0, max_retries: int = 3):
75
  '''Initialize MCP client with endpoint URL
76
 
77
  Args:
client/tool_workflows.py CHANGED
@@ -9,10 +9,10 @@ from client import prompts
9
  from client.anthropic_bridge import AnthropicBridge
10
 
11
  INTERMEDIATE_REPLY_HINTS = {
12
- 'context_search': 'Let me find some additional context before I generate a final answer.',
13
- 'find_article': 'I will find the title of that article.',
14
- 'get_summary': 'I will summarize that article',
15
- 'get_link': 'I will get the link to that article'
16
  }
17
 
18
  async def tool_loop(
@@ -37,7 +37,7 @@ async def tool_loop(
37
  tool_call = result['tool_call']
38
  tool_name = tool_call['name']
39
 
40
- if tool_name == 'get_feed':
41
  reply = await get_feed_call(
42
  user_query,
43
  result,
 
9
  from client.anthropic_bridge import AnthropicBridge
10
 
11
  INTERMEDIATE_REPLY_HINTS = {
12
+ 'rss_mcp_server_context_search': 'Let me find some additional context before I generate a final answer.',
13
+ 'rss_mcp_server_find_article': 'I will find the title of that article.',
14
+ 'rss_mcp_server_get_summary': 'I will summarize that article',
15
+ 'rss_mcp_server_get_link': 'I will get the link to that article'
16
  }
17
 
18
  async def tool_loop(
 
37
  tool_call = result['tool_call']
38
  tool_name = tool_call['name']
39
 
40
+ if tool_name == 'rss_mcp_server_get_feed':
41
  reply = await get_feed_call(
42
  user_query,
43
  result,
rss_client.py CHANGED
@@ -40,8 +40,7 @@ logger = logging.getLogger(__name__)
40
 
41
  # Handle MCP server connection and interactions
42
  RSS_CLIENT = MCPClientWrapper(
43
- #'https://agents-mcp-hackathon-rss-mcp-server.hf.space/gradio_api/mcp/sse',
44
- 'http://127.0.0.1:7860/gradio_api/mcp/sse'
45
  )
46
  logger.info('Started MCP client')
47
 
@@ -57,6 +56,7 @@ logger.info('Started Anthropic API bridge')
57
  OUTPUT_QUEUE = queue.Queue()
58
  logger.info('Created response queue')
59
 
 
60
  def user_message(message: str, history: list) -> Tuple[str, list]:
61
  '''Adds user message to conversation and returns for immediate posting.
62
 
@@ -102,11 +102,12 @@ def send_message(chat_history: list):
102
  yield chat_history
103
 
104
 
105
- with gr.Blocks(title='MCP RSS client') as demo:
106
  with gr.Row():
107
  gr.HTML(html.TITLE)
108
 
109
  gr.Markdown(html.DESCRIPTION)
 
110
 
111
  # MCP connection/tool dump
112
  connect_btn = gr.Button('Connect to MCP server')
@@ -128,7 +129,7 @@ with gr.Blocks(title='MCP RSS client') as demo:
128
  # Chat interface
129
  chatbot = gr.Chatbot(
130
  value=[],
131
- height=250,
132
  type='messages',
133
  show_copy_button=True
134
  )
 
40
 
41
  # Handle MCP server connection and interactions
42
  RSS_CLIENT = MCPClientWrapper(
43
+ 'https://agents-mcp-hackathon-rss-mcp-server.hf.space/gradio_api/mcp/sse'
 
44
  )
45
  logger.info('Started MCP client')
46
 
 
56
  OUTPUT_QUEUE = queue.Queue()
57
  logger.info('Created response queue')
58
 
59
+
60
  def user_message(message: str, history: list) -> Tuple[str, list]:
61
  '''Adds user message to conversation and returns for immediate posting.
62
 
 
102
  yield chat_history
103
 
104
 
105
+ with gr.Blocks(title='RASS agent') as demo:
106
  with gr.Row():
107
  gr.HTML(html.TITLE)
108
 
109
  gr.Markdown(html.DESCRIPTION)
110
+ gr.Markdown(html.FEATURES_TOOLS)
111
 
112
  # MCP connection/tool dump
113
  connect_btn = gr.Button('Connect to MCP server')
 
129
  # Chat interface
130
  chatbot = gr.Chatbot(
131
  value=[],
132
+ height=500,
133
  type='messages',
134
  show_copy_button=True
135
  )