This is an automated email from the ASF dual-hosted git repository.

yasith pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airavata-portals.git


The following commit(s) were added to refs/heads/main by this push:
     new d159cd974 Working MCP client with completed documentation (#41)
d159cd974 is described below

commit d159cd974b04e230b2249cedb16b67d1601199ff
Author: Amisha Sao <[email protected]>
AuthorDate: Wed Aug 6 14:11:15 2025 -0500

    Working MCP client with completed documentation (#41)
    
    MCP client was developed
    Chatbot UI was designed and cleaned
    MCP client was connected with servers and chatbot
    Used Langchain tooling to call MCP servers
    Added chatbot support for markdown
    Made the MCP client work with Qwen3-4b (locally) and gpt-4o
---
 .DS_Store                                          |  Bin 0 -> 8196 bytes
 .gitignore                                         |    4 +-
 airavata-mcp-client-chatbot/README.md              |  162 ++-
 airavata-mcp-client-chatbot/backend/.gitignore     |    3 +-
 airavata-mcp-client-chatbot/backend/app.py         |    2 +-
 .../backend/mcp_client/cybershuttle_mcp_client.py  |  451 ++++++++
 .../backend/mcp_client/open_ai_mcp_client.py       |    7 +-
 .../widget/package-lock.json                       | 1215 +++++++++++++++++++-
 airavata-mcp-client-chatbot/widget/package.json    |    6 +-
 .../widget/src/components/Results.tsx              |   39 +-
 10 files changed, 1838 insertions(+), 51 deletions(-)

diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 000000000..1f9467ca0
Binary files /dev/null and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
index 723ef36f4..9b5ea0fdd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-.idea
\ No newline at end of file
+
+node_modules/
+.DS_Store
\ No newline at end of file
diff --git a/airavata-mcp-client-chatbot/README.md 
b/airavata-mcp-client-chatbot/README.md
index 328eb3d0c..7c5239da7 100644
--- a/airavata-mcp-client-chatbot/README.md
+++ b/airavata-mcp-client-chatbot/README.md
@@ -1,9 +1,80 @@
-# Cybershuttle LangChain + Qwen3 Integration
+
+# Cybershuttle AI Chatbot
+This is an open-source Model Context Protocol (MCP) client chatbot that users 
can prompt and interact with the remainder of the Cybershuttle interface, 
directly from a prompt. The user submits a request through the chatbot to the 
MCP client, which has a common protocol (or standard mode of communication with 
the MCP servers). As seen below, when the request goes to each specific MCP 
server, it uses REST API endpoints to complete tasks requested by the user. As 
shown in the diagram below, [...]
+
+<img width="2216" height="1537" alt="image" 
src="https://github.com/user-attachments/assets/0dcc4456-bf87-4633-9af7-ace28aa71547";
 />
+
+## Features
+- **Natural Language Interface** – Query Cybershuttle resources (datasets, 
notebooks, models) using plain English.
+- **MCP Protocol Support** – Communicates with multiple MCP servers for 
modular and scalable integration.
+- **Custom MCP Servers** – FastAPI-based connectors to Airavata’s 
research-service API and Cybershuttle catalog.
+- **Open-Source Model Integration** – Supports running inference with locally 
or remotely hosted open-source LLMs.
+- **Flexible Deployment** – Includes both CLI and embeddable widget options 
for use in other applications.
+- **End-to-End Workflows** – Enables query → resource discovery → model 
execution → result delivery in one flow.
+
+## 💡 Architecture
+
+```
+React Frontend (port 3000)
+       ↓
+Your API Server (port 5000)
+       ↓  
+Your LangChain Agent
+       ↓
+Your MCP Server (port 8000)
+       ↓
+Cybershuttle Platform
+```
+
+## Installation
+1. Clone the repo:
+```
+git clone https://github.com/amishasao/airavata-portals-mcp-client-fork.git
+cd airavata-portals-mcp-client-fork/airavata-mcp-client-chatbot/backend
+```
+2. Install backend dependencies:
+```
+pip install -r requirements.txt
+```
+3. Set up environment variables:
+```
+# get an OpenAI API key from their website
+export OPENAI_API_KEY="openai-api-key"
+# create a Sandbox account and create a new E2B API key
+export E2B_API_KEY="sandbox-api-key"
+# run the server and copy/paste the api.dev link here
+export MCP_SERVER_URL="link-here"
+```
+4. Install frontend dependencies
+```
+npm install
+```
+
+## Usage
+1. Start the MCP backend:
+```
+cd airavata-portals-mcp-client-fork/airavata-mcp-client-chatbot/backend
+python app.py
+```
+This will start the backend at localhost:5000.
+
+2. (opt.) Test server health:
+```
+curl http://localhost:5000/api/health
+```
+3. In a new terminal, start the frontend:
+```
+cd airavata-portals-mcp-client-fork/airavata-mcp-client-chatbot/widget
+npm run start
+```
+This will start the UI at localhost:3000.
+
+## Cybershuttle LangChain + Qwen3 Integration
 
 Connecting the React frontend to the LangChain + Qwen3 agent in 
cybershuttle/mcp-server repository.
 
-## 🚀 How to Run
-### Step 1: In 2 seperate Windows open the cybershuttle/mcp-server repository, 
and the apacha/airavata-portals repository
+### 🚀 How to Run
+#### Step 1: In 2 seperate Windows open the cybershuttle/mcp-server 
repository, and the apacha/airavata-portals repository
 
 **Terminal 1 - Your MCP Server Repository (cybershuttle/mcp-server):**
 ```bash
@@ -25,24 +96,24 @@ npm start
 
 ## 🔍 What Each Terminal Does
 
-### Terminal 1: MCP Server
+#### Terminal 1: MCP Server
 - **Purpose**: Connects to Cybershuttle research catalog
 - **Port**: 8000
 - **Status**: Should show "Server is healthy"
 
-### Terminal 2: Your API Server
+#### Terminal 2: Your API Server
 - **Purpose**: Exposes your LangChain agent as HTTP API
 - **Port**: 5000 (replaces his OpenAI backend)
 - **Status**: Should show "Agent: Ready"
 
-### Terminal 3: React Frontend
+#### Terminal 3: React Frontend
 - **Purpose**: The web interface users interact with
 - **Port**: 3000
 - **Status**: Opens browser to localhost:3000
 
 ## 🧪 Testing
 
-### Quick Test:
+#### Quick Test:
 ```bash
 curl http://localhost:5000/api/health
 ```
@@ -63,22 +134,7 @@ curl -X POST http://localhost:5000/api/chat \
   -H "Content-Type: application/json" \
   -d '{"message": "Are there neuroscience resources in Cybershuttle?"}'
 ```
-
-## 💡 Architecture
-
-```
-React Frontend (port 3000)
-       ↓
-Your API Server (port 5000)
-       ↓  
-Your LangChain Agent
-       ↓
-Your MCP Server (port 8000)
-       ↓
-Cybershuttle Platform
-```
-
-## 🎯 Success Indicators
+### 🎯 Success Indicators
 
 1. **MCP Server**: Shows "Server is healthy"
 2. **Ollama**: `curl localhost:11434/api/version` works
@@ -86,4 +142,62 @@ Cybershuttle Platform
 4. **Frontend**: Loads at localhost:3000
 5. **Integration**: User queries get responses from your Qwen3 agent
 
-The frontend will work exactly like before, but now powered by open-source 
Qwen3 instead of OpenAI!
\ No newline at end of file
+The frontend will work exactly like before, but now powered by open-source 
Qwen3 instead of OpenAI!
+
+## Project Structure
+```
+airavata-mcp-client-chatbot               
+├─ backend                                
+│  ├─ mcp_client                          
+│  │  ├─ client_side_ollama_prompting.py  
+│  │  ├─ cybershuttle_mcp_client.py       
+│  │  ├─ initial_ollama_prompting.py      
+│  │  ├─ mcp_config.json                  
+│  │  ├─ open_ai_mcp_client.py            
+│  │  ├─ requirements.txt                 
+│  │  └─ __init__.py                      
+│  ├─ app.py                              
+│  ├─ config.py                           
+│  └─ requirements.txt                    
+├─ cli                                    
+│  ├─ package-lock.json                   
+│  ├─ package.json                        
+│  └─ tsconfig.json                       
+├─ widget                                 
+│  ├─ build                           
+│  ├─ public                     
+│  ├─ src                                 
+│  │  ├─ components                       
+│  │  │  ├─ Chatbox.css                   
+│  │  │  ├─ Chatbox.tsx                   
+│  │  │  ├─ Chatbox2.css                  
+│  │  │  ├─ Results.css                   
+│  │  │  ├─ Results.tsx                   
+│  │  │  └─ Results2.css                  
+│  │  ├─ App.css                          
+│  │  ├─ App.test.tsx                     
+│  │  ├─ App.tsx                          
+│  │  ├─ index.css                        
+│  │  ├─ index.tsx                        
+│  │  ├─ logo.svg                         
+│  │  ├─ react-app-env.d.ts               
+│  │  ├─ reportWebVitals.ts               
+│  │  └─ setupTests.ts                    
+│  ├─ package-lock.json                   
+│  ├─ package.json                        
+│  ├─ README.md                           
+│  └─ tsconfig.json                       
+└─ README.md
+```
+
+## Contributing
+1. Fork the repository
+2. Create a feature branch
+3. Make changes and add tests in a separate folder
+4. Submit a detailed pull request with explanations on what improvements have 
been made
+
+## More Information
+This project was presented, and the poster is shown below.
+
+![Slide2](https://github.com/user-attachments/assets/373857de-dd4b-4585-9ab1-020fa202f340)
+
diff --git a/airavata-mcp-client-chatbot/backend/.gitignore 
b/airavata-mcp-client-chatbot/backend/.gitignore
index 09aa33643..8632a355e 100644
--- a/airavata-mcp-client-chatbot/backend/.gitignore
+++ b/airavata-mcp-client-chatbot/backend/.gitignore
@@ -1,2 +1,3 @@
 *.env
-mcp_client/__pycache__/*
\ No newline at end of file
+mcp_client/__pycache__/*
+.DS_Store
\ No newline at end of file
diff --git a/airavata-mcp-client-chatbot/backend/app.py 
b/airavata-mcp-client-chatbot/backend/app.py
index cf794f06e..206db24c6 100644
--- a/airavata-mcp-client-chatbot/backend/app.py
+++ b/airavata-mcp-client-chatbot/backend/app.py
@@ -3,7 +3,7 @@ from flask_cors import CORS
 import sys
 import asyncio
 import os
-from mcp_client.open_ai_mcp_client import run_agent_query, close_mcp
+from mcp_client.open_ai_mcp_client import run_agent_query
 
 app = Flask(__name__)
 CORS(app)
diff --git 
a/airavata-mcp-client-chatbot/backend/mcp_client/cybershuttle_mcp_client.py 
b/airavata-mcp-client-chatbot/backend/mcp_client/cybershuttle_mcp_client.py
index e69de29bb..4dd9e871a 100644
--- a/airavata-mcp-client-chatbot/backend/mcp_client/cybershuttle_mcp_client.py
+++ b/airavata-mcp-client-chatbot/backend/mcp_client/cybershuttle_mcp_client.py
@@ -0,0 +1,451 @@
+import openai
+import requests
+import json
+import os
+from typing import Dict, Any, List
+
+client = openai.OpenAI(
+    api_key=os.getenv("OPENAI_API_KEY", "<Add your OpenAI API key here>")
+)
+
+MCP_SERVER_URL = "http://127.0.0.1:8000";
+
+functions = [
+    {
+        "name": "list_resources",
+        "description": "List all resources (datasets, notebooks, repositories, 
models) from Cybershuttle catalog with filtering options",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "resource_type": {
+                    "type": "string",
+                    "description": "Filter by resource type (dataset, 
notebook, repository, model)",
+                    "enum": ["dataset", "notebook", "repository", "model"]
+                },
+                "tags": {
+                    "type": "string",
+                    "description": "Filter by tags"
+                },
+                "name": {
+                    "type": "string",
+                    "description": "Filter by name"
+                },
+                "limit": {
+                    "type": "integer",
+                    "description": "Number of results to return",
+                    "default": 10
+                }
+            }
+        }
+    },
+    {
+        "name": "get_resource",
+        "description": "Get detailed information about a specific resource by 
ID",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "resource_id": {
+                    "type": "string",
+                    "description": "ID of the resource to retrieve"
+                }
+            },
+            "required": ["resource_id"]
+        }
+    },
+    {
+        "name": "search_resources",
+        "description": "Search for resources by type and name",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "resource_type": {
+                    "type": "string",
+                    "description": "Type of resource to search for",
+                    "enum": ["dataset", "notebook", "repository", "model"]
+                },
+                "name": {
+                    "type": "string",
+                    "description": "Name to search for"
+                }
+            },
+            "required": ["resource_type", "name"]
+        }
+    },
+    {
+        "name": "create_dataset",
+        "description": "Create a new dataset resource in the catalog",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "data": {
+                    "type": "object",
+                    "description": "Dataset metadata and configuration",
+                    "properties": {
+                        "name": {"type": "string", "description": "Dataset 
name"},
+                        "description": {"type": "string", "description": 
"Dataset description"},
+                        "tags": {"type": "array", "items": {"type": "string"}, 
"description": "Tags for categorization"}
+                    }
+                }
+            },
+            "required": ["data"]
+        }
+    },
+    {
+        "name": "create_notebook",
+        "description": "Create a new notebook resource in the catalog",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "data": {
+                    "type": "object",
+                    "description": "Notebook metadata and configuration",
+                    "properties": {
+                        "name": {"type": "string", "description": "Notebook 
name"},
+                        "description": {"type": "string", "description": 
"Notebook description"},
+                        "tags": {"type": "array", "items": {"type": "string"}, 
"description": "Tags for categorization"}
+                    }
+                }
+            },
+            "required": ["data"]
+        }
+    },
+    {
+        "name": "create_repository",
+        "description": "Create a new repository resource from GitHub URL",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "github_url": {
+                    "type": "string",
+                    "description": "GitHub repository URL"
+                }
+            },
+            "required": ["github_url"]
+        }
+    },
+    {
+        "name": "create_model",
+        "description": "Create a new model resource in the catalog",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "data": {
+                    "type": "object",
+                    "description": "Model metadata and configuration",
+                    "properties": {
+                        "name": {"type": "string", "description": "Model 
name"},
+                        "description": {"type": "string", "description": 
"Model description"},
+                        "tags": {"type": "array", "items": {"type": "string"}, 
"description": "Tags for categorization"}
+                    }
+                }
+            },
+            "required": ["data"]
+        }
+    },
+    {
+        "name": "list_projects",
+        "description": "List all projects in the user's workspace",
+        "parameters": {
+            "type": "object",
+            "properties": {}
+        }
+    },
+    {
+        "name": "create_project",
+        "description": "Create a new project that can contain multiple 
resources",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "data": {
+                    "type": "object",
+                    "description": "Project metadata and configuration",
+                    "properties": {
+                        "name": {"type": "string", "description": "Project 
name"},
+                        "description": {"type": "string", "description": 
"Project description"}
+                    }
+                }
+            },
+            "required": ["data"]
+        }
+    },
+    {
+        "name": "start_project_session",
+        "description": "Launch an interactive session for a project",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "project_id": {
+                    "type": "string",
+                    "description": "ID of the project to start session for"
+                },
+                "session_name": {
+                    "type": "string",
+                    "description": "Name for the session"
+                }
+            },
+            "required": ["project_id", "session_name"]
+        }
+    },
+    {
+        "name": "list_sessions",
+        "description": "List all active sessions",
+        "parameters": {
+            "type": "object",
+            "properties": {
+                "status": {
+                    "type": "string",
+                    "description": "Filter by session status"
+                }
+            }
+        }
+    },
+    {
+        "name": "get_all_tags",
+        "description": "Get all available tags from the catalog for filtering 
and organization",
+        "parameters": {
+            "type": "object",
+            "properties": {}
+        }
+    }
+]
+
+
+def call_mcp_function(function_name: str, parameters: Dict[str, Any]) -> 
Dict[str, Any]:
+    """Call a function on the Cybershuttle MCP server."""
+    try:
+        endpoint_map = {
+            "list_resources": "/resources",
+            "get_resource": "/resources/{resource_id}",
+            "search_resources": "/resources/search",
+            "create_dataset": "/resources/dataset",
+            "create_notebook": "/resources/notebook",
+            "create_repository": "/resources/repository",
+            "create_model": "/resources/model",
+            "list_projects": "/projects",
+            "create_project": "/projects",
+            "start_project_session": "/hub/start-session/{project_id}",
+            "list_sessions": "/sessions",
+            "get_all_tags": "/resources/tags"
+        }
+
+        method_map = {
+            "list_resources": "GET",
+            "get_resource": "GET",
+            "search_resources": "GET",
+            "create_dataset": "POST",
+            "create_notebook": "POST",
+            "create_repository": "POST",
+            "create_model": "POST",
+            "list_projects": "GET",
+            "create_project": "POST",
+            "start_project_session": "GET",
+            "list_sessions": "GET",
+            "get_all_tags": "GET"
+        }
+
+        endpoint = endpoint_map.get(function_name)
+        method = method_map.get(function_name)
+
+        if not endpoint or not method:
+            return {"error": f"Unknown function: {function_name}"}
+
+        url = f"{MCP_SERVER_URL}{endpoint}"
+
+        if function_name == "get_resource":
+            url = url.format(resource_id=parameters.get("resource_id"))
+            params = {}
+        elif function_name == "start_project_session":
+            url = url.format(project_id=parameters.get("project_id"))
+            params = {"session_name": parameters.get("session_name")}
+        elif function_name == "create_repository":
+            params = {"github_url": parameters.get("github_url")}
+        else:
+            if method == "GET":
+                params = parameters
+            else:
+                params = {}
+
+        if method == "GET":
+            response = requests.get(url, params=params)
+        elif method == "POST":
+            if function_name in ["create_dataset", "create_notebook", 
"create_model", "create_project"]:
+                response = requests.post(url, json=parameters.get("data"))
+            else:
+                response = requests.post(url, params=params)
+        else:
+            return {"error": f"Unsupported method: {method}"}
+
+        if response.status_code == 200:
+            return response.json()
+        else:
+            return {"error": f"API call failed with status 
{response.status_code}: {response.text}"}
+
+    except Exception as e:
+        return {"error": f"Failed to call MCP function: {str(e)}"}
+
+
+def display_resources(resources: List[Dict[str, Any]]) -> str:
+    """Format resources for display."""
+    if not resources:
+        return "No resources found."
+
+    formatted = "\n**Cybershuttle Resources:**\n"
+    for resource in resources:
+        formatted += f"• **{resource.get('name', 'Unknown')}** 
({resource.get('type', 'Unknown')})\n"
+        formatted += f"  {resource.get('description', 'No description')}\n"
+        formatted += f"  Tags: {', '.join(resource.get('tags', []))}\n"
+        formatted += f"  ID: {resource.get('id')}\n\n"
+
+    return formatted
+
+
+def display_projects(projects: List[Dict[str, Any]]) -> str:
+    """Format projects for display."""
+    if not projects:
+        return "No projects found."
+
+    formatted = "\n**Cybershuttle Projects:**\n"
+    for project in projects:
+        formatted += f"• **{project.get('name', 'Unknown')}**\n"
+        formatted += f"  {project.get('description', 'No description')}\n"
+        formatted += f"  Owner: {project.get('owner_id')}\n"
+        formatted += f"  ID: {project.get('id')}\n\n"
+
+    return formatted
+
+
+def display_sessions(sessions: List[Dict[str, Any]]) -> str:
+    """Format sessions for display."""
+    if not sessions:
+        return "No sessions found."
+
+    formatted = "\n**Active Sessions:**\n"
+    for session in sessions:
+        formatted += f"• **{session.get('name', 'Unknown')}**\n"
+        formatted += f"  Status: {session.get('status')}\n"
+        formatted += f"  Project: {session.get('project_id')}\n"
+        formatted += f"  ID: {session.get('id')}\n\n"
+
+    return formatted
+
+
+def main():
+    """Main interactive loop for the Cybershuttle MCP demo."""
+    print("Welcome to the Cybershuttle MCP Demo!")
+    print("This demo showcases how an AI agent can interact with the 
Cybershuttle research platform.")
+    print("You can ask questions about datasets, notebooks, models, projects, 
and sessions.")
+    print("Type 'exit' to quit.\n")
+
+    example_prompts = [
+        "Show me all datasets in the catalog",
+        "Find notebooks related to machine learning",
+        "Create a new project for my research",
+        "List all active sessions",
+        "Search for repositories about deep learning",
+        "What tags are available in the catalog?",
+        "Start a session for project XYZ"
+    ]
+
+    print("Example prompts you can try:")
+    for i, prompt in enumerate(example_prompts, 1):
+        print(f"   {i}. {prompt}")
+    print()
+
+    while True:
+        user_message = input("You: ")
+
+        if user_message.lower() in ['exit', 'quit', 'bye']:
+            print("Thank you for using the Cybershuttle MCP Demo!")
+            break
+
+        if not user_message.strip():
+            continue
+
+        print("AI Agent: Processing your request...")
+
+        try:
+            response = client.chat.completions.create(
+                model="gpt-4-1106-preview",
+                messages=[
+                    {
+                        "role": "system",
+                        "content": """You are an AI assistant specialized in 
helping researchers interact with the Cybershuttle research platform. 
+                        You can help users find, create, and manage datasets, 
notebooks, models, repositories, projects, and sessions.
+                        Always be helpful and provide clear, actionable 
responses. When displaying results, format them nicely for readability.
+                        If you need to call multiple functions to fulfill a 
request, do so systematically."""
+                    },
+                    {"role": "user", "content": user_message}
+                ],
+                functions=functions,
+                function_call="auto",
+                max_tokens=1000
+            )
+
+            message = response.choices[0].message
+
+            if message.function_call:
+                func_call = message.function_call
+                print(f"Calling function: {func_call.name}")
+
+                try:
+                    args = json.loads(func_call.arguments)
+                except json.JSONDecodeError:
+                    print("Error: Invalid function arguments")
+                    continue
+
+                function_result = call_mcp_function(func_call.name, args)
+
+                if "error" in function_result:
+                    print(f"Error: {function_result['error']}")
+                    continue
+
+                formatted_result = ""
+                if func_call.name == "list_resources":
+                    formatted_result = display_resources(function_result)
+                elif func_call.name == "list_projects":
+                    formatted_result = display_projects(function_result)
+                elif func_call.name == "list_sessions":
+                    formatted_result = display_sessions(function_result)
+                elif func_call.name == "get_all_tags":
+                    if isinstance(function_result, list):
+                        # Commenting out my implementation and using Sutej's
+                        # formatted_result = f"**Available Tags:** {', 
'.join(function_result)}"
+                        formatted_result = f"**Available Tags:** {', 
'.join(tag.get('value', '') for tag in function_result)}"
+                    else:
+                        formatted_result = f"**Available Tags:** 
{function_result}"
+                else:
+                    formatted_result = json.dumps(function_result, indent=2)
+
+                followup = client.chat.completions.create(
+                    model="gpt-4-1106-preview",
+                    messages=[
+                        {
+                            "role": "system",
+                            "content": """You are an AI assistant for the 
Cybershuttle research platform. 
+                            Provide helpful, conversational responses about 
the results. Be encouraging and offer suggestions for next steps."""
+                        },
+                        {"role": "user", "content": user_message},
+                        {
+                            "role": "function",
+                            "name": func_call.name,
+                            "content": formatted_result
+                        }
+                    ],
+                    max_tokens=500
+                )
+
+                print(f"Results:\n{formatted_result}")
+                print(f"\nAI Agent: {followup.choices[0].message.content}")
+
+            else:
+                print(f"AI Agent: {message.content}")
+
+        except Exception as e:
+            print(f"Error: {str(e)}")
+            print("Please try again or type 'exit' to quit.")
+
+        print()
+
+
+if __name__ == "__main__":
+    main()
diff --git 
a/airavata-mcp-client-chatbot/backend/mcp_client/open_ai_mcp_client.py 
b/airavata-mcp-client-chatbot/backend/mcp_client/open_ai_mcp_client.py
index 63145dfc4..697716d61 100644
--- a/airavata-mcp-client-chatbot/backend/mcp_client/open_ai_mcp_client.py
+++ b/airavata-mcp-client-chatbot/backend/mcp_client/open_ai_mcp_client.py
@@ -16,7 +16,12 @@ load_dotenv()
 llm = ChatOpenAI(
     model="gpt-4o",
     temperature=0.1,
-    max_tokens=1000
+    max_tokens=1000,
+    messages=[{
+        "role": "system",
+        "content": "Always format your response using Markdown, including for 
code, tables, and lists."
+    }]
+
 )
 
 client = None
diff --git a/airavata-mcp-client-chatbot/widget/package-lock.json 
b/airavata-mcp-client-chatbot/widget/package-lock.json
index 0da703153..501f51c93 100644
--- a/airavata-mcp-client-chatbot/widget/package-lock.json
+++ b/airavata-mcp-client-chatbot/widget/package-lock.json
@@ -16,11 +16,15 @@
         "@types/node": "^16.18.126",
         "@types/react": "^19.1.8",
         "@types/react-dom": "^19.1.6",
-        "axios": "^1.11.0",
+
+        "axios": "^1.10.0",
+        "markdown": "^0.5.0",
         "react": "^19.1.0",
         "react-chatbotify": "^2.2.0",
         "react-dom": "^19.1.0",
         "react-icons": "^5.5.0",
+        "react-markdown": "^10.1.0",
+
         "react-router-dom": "^7.7.0",
         "react-scripts": "5.0.1",
         "typescript": "^4.9.5",
@@ -3645,6 +3649,15 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/debug": {
+      "version": "4.1.12",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz";,
+      "integrity": 
"sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/ms": "*"
+      }
+    },
     "node_modules/@types/eslint": {
       "version": "8.56.12",
       "resolved": 
"https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz";,
@@ -3671,6 +3684,15 @@
       "integrity": 
"sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
       "license": "MIT"
     },
+    "node_modules/@types/estree-jsx": {
+      "version": "1.0.5",
+      "resolved": 
"https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz";,
+      "integrity": 
"sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "*"
+      }
+    },
     "node_modules/@types/express": {
       "version": "4.17.23",
       "resolved": 
"https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz";,
@@ -3716,6 +3738,15 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/hast": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz";,
+      "integrity": 
"sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "*"
+      }
+    },
     "node_modules/@types/html-minifier-terser": {
       "version": "6.1.0",
       "resolved": 
"https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz";,
@@ -3783,12 +3814,27 @@
       "integrity": 
"sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
       "license": "MIT"
     },
+    "node_modules/@types/mdast": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz";,
+      "integrity": 
"sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "*"
+      }
+    },
     "node_modules/@types/mime": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz";,
       "integrity": 
"sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
       "license": "MIT"
     },
+    "node_modules/@types/ms": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz";,
+      "integrity": 
"sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+      "license": "MIT"
+    },
     "node_modules/@types/node": {
       "version": "16.18.126",
       "resolved": 
"https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz";,
@@ -3924,6 +3970,12 @@
       "integrity": 
"sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
       "license": "MIT"
     },
+    "node_modules/@types/unist": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz";,
+      "integrity": 
"sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+      "license": "MIT"
+    },
     "node_modules/@types/ws": {
       "version": "8.18.1",
       "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz";,
@@ -4348,6 +4400,12 @@
       "deprecated": "Use your platform's native atob() and btoa() methods 
instead",
       "license": "BSD-3-Clause"
     },
+    "node_modules/abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz";,
+      "integrity": 
"sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+      "license": "ISC"
+    },
     "node_modules/accepts": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz";,
@@ -5220,6 +5278,16 @@
         "@babel/core": "^7.0.0-0"
       }
     },
+    "node_modules/bail": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz";,
+      "integrity": 
"sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": 
"https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz";,
@@ -5566,6 +5634,16 @@
         "node": ">=4"
       }
     },
+    "node_modules/ccount": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz";,
+      "integrity": 
"sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz";,
@@ -5591,6 +5669,46 @@
         "node": ">=10"
       }
     },
+    "node_modules/character-entities": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz";,
+      "integrity": 
"sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
+    "node_modules/character-entities-html4": {
+      "version": "2.1.0",
+      "resolved": 
"https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz";,
+      "integrity": 
"sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
+    "node_modules/character-entities-legacy": {
+      "version": "3.0.0",
+      "resolved": 
"https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz";,
+      "integrity": 
"sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
+    "node_modules/character-reference-invalid": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz";,
+      "integrity": 
"sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/check-types": {
       "version": "11.2.3",
       "resolved": 
"https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz";,
@@ -5838,6 +5956,16 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/comma-separated-tokens": {
+      "version": "2.0.3",
+      "resolved": 
"https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz";,
+      "integrity": 
"sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/commander": {
       "version": "8.3.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz";,
@@ -6525,6 +6653,19 @@
       "integrity": 
"sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
       "license": "MIT"
     },
+    "node_modules/decode-named-character-reference": {
+      "version": "1.2.0",
+      "resolved": 
"https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz";,
+      "integrity": 
"sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
+      "license": "MIT",
+      "dependencies": {
+        "character-entities": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/dedent": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz";,
@@ -6685,6 +6826,19 @@
       "integrity": 
"sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "license": "MIT"
     },
+    "node_modules/devlop": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz";,
+      "integrity": 
"sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+      "license": "MIT",
+      "dependencies": {
+        "dequal": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/didyoumean": {
       "version": "1.2.2",
       "resolved": 
"https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz";,
@@ -7812,6 +7966,16 @@
         "node": ">=4.0"
       }
     },
+    "node_modules/estree-util-is-identifier-name": {
+      "version": "3.0.0",
+      "resolved": 
"https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz";,
+      "integrity": 
"sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+      "license": "MIT",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
     "node_modules/estree-walker": {
       "version": "1.0.1",
       "resolved": 
"https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz";,
@@ -7958,6 +8122,12 @@
       "integrity": 
"sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "license": "MIT"
     },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz";,
+      "integrity": 
"sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "license": "MIT"
+    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": 
"https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz";,
@@ -8883,6 +9053,46 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/hast-util-to-jsx-runtime": {
+      "version": "2.3.6",
+      "resolved": 
"https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz";,
+      "integrity": 
"sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/unist": "^3.0.0",
+        "comma-separated-tokens": "^2.0.0",
+        "devlop": "^1.0.0",
+        "estree-util-is-identifier-name": "^3.0.0",
+        "hast-util-whitespace": "^3.0.0",
+        "mdast-util-mdx-expression": "^2.0.0",
+        "mdast-util-mdx-jsx": "^3.0.0",
+        "mdast-util-mdxjs-esm": "^2.0.0",
+        "property-information": "^7.0.0",
+        "space-separated-tokens": "^2.0.0",
+        "style-to-js": "^1.0.0",
+        "unist-util-position": "^5.0.0",
+        "vfile-message": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/hast-util-whitespace": {
+      "version": "3.0.0",
+      "resolved": 
"https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz";,
+      "integrity": 
"sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/hast": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
     "node_modules/he": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz";,
@@ -9004,6 +9214,16 @@
         "node": ">=12"
       }
     },
+    "node_modules/html-url-attributes": {
+      "version": "3.0.1",
+      "resolved": 
"https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz";,
+      "integrity": 
"sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
     "node_modules/html-webpack-plugin": {
       "version": "5.6.3",
       "resolved": 
"https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz";,
@@ -9303,6 +9523,12 @@
       "integrity": 
"sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
       "license": "ISC"
     },
+    "node_modules/inline-style-parser": {
+      "version": "0.2.4",
+      "resolved": 
"https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz";,
+      "integrity": 
"sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
+      "license": "MIT"
+    },
     "node_modules/internal-slot": {
       "version": "1.1.0",
       "resolved": 
"https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz";,
@@ -9326,6 +9552,30 @@
         "node": ">= 10"
       }
     },
+    "node_modules/is-alphabetical": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz";,
+      "integrity": 
"sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
+    "node_modules/is-alphanumerical": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz";,
+      "integrity": 
"sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+      "license": "MIT",
+      "dependencies": {
+        "is-alphabetical": "^2.0.0",
+        "is-decimal": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/is-array-buffer": {
       "version": "3.0.5",
       "resolved": 
"https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz";,
@@ -9471,6 +9721,16 @@
         "url": "https://github.com/sponsors/ljharb";
       }
     },
+    "node_modules/is-decimal": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz";,
+      "integrity": 
"sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/is-docker": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz";,
@@ -9558,6 +9818,16 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/is-hexadecimal": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz";,
+      "integrity": 
"sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/is-map": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz";,
@@ -11250,6 +11520,16 @@
       "integrity": 
"sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
       "license": "MIT"
     },
+    "node_modules/longest-streak": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz";,
+      "integrity": 
"sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/loose-envify": {
       "version": "1.4.0",
       "resolved": 
"https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz";,
@@ -11331,6 +11611,20 @@
         "tmpl": "1.0.5"
       }
     },
+    "node_modules/markdown": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz";,
+      "integrity": 
"sha512-ctGPIcuqsYoJ493sCtFK7H4UEgMWAUdXeBhPbdsg1W0LsV9yJELAHRsMmWfTgao6nH0/x5gf9FmsbxiXnrgaIQ==",
+      "dependencies": {
+        "nopt": "~2.1.1"
+      },
+      "bin": {
+        "md2html": "bin/md2html.js"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/math-intrinsics": {
       "version": "1.1.0",
       "resolved": 
"https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz";,
@@ -11340,6 +11634,159 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/mdast-util-from-markdown": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz";,
+      "integrity": 
"sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "@types/unist": "^3.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "devlop": "^1.0.0",
+        "mdast-util-to-string": "^4.0.0",
+        "micromark": "^4.0.0",
+        "micromark-util-decode-numeric-character-reference": "^2.0.0",
+        "micromark-util-decode-string": "^2.0.0",
+        "micromark-util-normalize-identifier": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0",
+        "unist-util-stringify-position": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/mdast-util-mdx-expression": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz";,
+      "integrity": 
"sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree-jsx": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "devlop": "^1.0.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "mdast-util-to-markdown": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/mdast-util-mdx-jsx": {
+      "version": "3.2.0",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz";,
+      "integrity": 
"sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree-jsx": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "@types/unist": "^3.0.0",
+        "ccount": "^2.0.0",
+        "devlop": "^1.1.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "mdast-util-to-markdown": "^2.0.0",
+        "parse-entities": "^4.0.0",
+        "stringify-entities": "^4.0.0",
+        "unist-util-stringify-position": "^4.0.0",
+        "vfile-message": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/mdast-util-mdxjs-esm": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz";,
+      "integrity": 
"sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree-jsx": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "devlop": "^1.0.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "mdast-util-to-markdown": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/mdast-util-phrasing": {
+      "version": "4.1.0",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz";,
+      "integrity": 
"sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "unist-util-is": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/mdast-util-to-hast": {
+      "version": "13.2.0",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz";,
+      "integrity": 
"sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "@ungap/structured-clone": "^1.0.0",
+        "devlop": "^1.0.0",
+        "micromark-util-sanitize-uri": "^2.0.0",
+        "trim-lines": "^3.0.0",
+        "unist-util-position": "^5.0.0",
+        "unist-util-visit": "^5.0.0",
+        "vfile": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/mdast-util-to-markdown": {
+      "version": "2.1.2",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz";,
+      "integrity": 
"sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "@types/unist": "^3.0.0",
+        "longest-streak": "^3.0.0",
+        "mdast-util-phrasing": "^4.0.0",
+        "mdast-util-to-string": "^4.0.0",
+        "micromark-util-classify-character": "^2.0.0",
+        "micromark-util-decode-string": "^2.0.0",
+        "unist-util-visit": "^5.0.0",
+        "zwitch": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/mdast-util-to-string": {
+      "version": "4.0.0",
+      "resolved": 
"https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz";,
+      "integrity": 
"sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/mdast": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
     "node_modules/mdn-data": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz";,
@@ -11400,17 +11847,459 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/micromatch": {
-      "version": "4.0.8",
-      "resolved": 
"https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz";,
-      "integrity": 
"sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+    "node_modules/micromark": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz";,
+      "integrity": 
"sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
       "license": "MIT",
       "dependencies": {
-        "braces": "^3.0.3",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
+        "@types/debug": "^4.0.0",
+        "debug": "^4.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "devlop": "^1.0.0",
+        "micromark-core-commonmark": "^2.0.0",
+        "micromark-factory-space": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-combine-extensions": "^2.0.0",
+        "micromark-util-decode-numeric-character-reference": "^2.0.0",
+        "micromark-util-encode": "^2.0.0",
+        "micromark-util-normalize-identifier": "^2.0.0",
+        "micromark-util-resolve-all": "^2.0.0",
+        "micromark-util-sanitize-uri": "^2.0.0",
+        "micromark-util-subtokenize": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-core-commonmark": {
+      "version": "2.0.3",
+      "resolved": 
"https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz";,
+      "integrity": 
"sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "devlop": "^1.0.0",
+        "micromark-factory-destination": "^2.0.0",
+        "micromark-factory-label": "^2.0.0",
+        "micromark-factory-space": "^2.0.0",
+        "micromark-factory-title": "^2.0.0",
+        "micromark-factory-whitespace": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-classify-character": "^2.0.0",
+        "micromark-util-html-tag-name": "^2.0.0",
+        "micromark-util-normalize-identifier": "^2.0.0",
+        "micromark-util-resolve-all": "^2.0.0",
+        "micromark-util-subtokenize": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-destination": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz";,
+      "integrity": 
"sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-label": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz";,
+      "integrity": 
"sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "devlop": "^1.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-space": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz";,
+      "integrity": 
"sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-title": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz";,
+      "integrity": 
"sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-factory-space": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-whitespace": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz";,
+      "integrity": 
"sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-factory-space": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-character": {
+      "version": "2.1.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz";,
+      "integrity": 
"sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-chunked": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz";,
+      "integrity": 
"sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-classify-character": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz";,
+      "integrity": 
"sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-combine-extensions": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz";,
+      "integrity": 
"sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-numeric-character-reference": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz";,
+      "integrity": 
"sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-string": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz";,
+      "integrity": 
"sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-decode-numeric-character-reference": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-encode": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz";,
+      "integrity": 
"sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/micromark-util-html-tag-name": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz";,
+      "integrity": 
"sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/micromark-util-normalize-identifier": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz";,
+      "integrity": 
"sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-resolve-all": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz";,
+      "integrity": 
"sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-sanitize-uri": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz";,
+      "integrity": 
"sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-encode": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-subtokenize": {
+      "version": "2.1.0",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz";,
+      "integrity": 
"sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "devlop": "^1.0.0",
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-symbol": {
+      "version": "2.0.1",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz";,
+      "integrity": 
"sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/micromark-util-types": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz";,
+      "integrity": 
"sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs";
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified";
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.8",
+      "resolved": 
"https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz";,
+      "integrity": 
"sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+      "license": "MIT",
+      "dependencies": {
+        "braces": "^3.0.3",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
       }
     },
     "node_modules/mime": {
@@ -11638,6 +12527,18 @@
       "integrity": 
"sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
       "license": "MIT"
     },
+    "node_modules/nopt": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz";,
+      "integrity": 
"sha512-x8vXm7BZ2jE1Txrxh/hO74HTuYZQEbo8edoRcANgdZ4+PCV+pbjd/xdummkmjjC7LU5EjPzlu8zEq/oxWylnKA==",
+      "license": "MIT",
+      "dependencies": {
+        "abbrev": "1"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      }
+    },
     "node_modules/normalize-path": {
       "version": "3.0.0",
       "resolved": 
"https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz";,
@@ -12022,6 +12923,31 @@
         "node": ">=6"
       }
     },
+    "node_modules/parse-entities": {
+      "version": "4.0.2",
+      "resolved": 
"https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz";,
+      "integrity": 
"sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "character-entities-legacy": "^3.0.0",
+        "character-reference-invalid": "^2.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "is-alphanumerical": "^2.0.0",
+        "is-decimal": "^2.0.0",
+        "is-hexadecimal": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
+    "node_modules/parse-entities/node_modules/@types/unist": {
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz";,
+      "integrity": 
"sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+      "license": "MIT"
+    },
     "node_modules/parse-json": {
       "version": "5.2.0",
       "resolved": 
"https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz";,
@@ -13667,6 +14593,16 @@
       "integrity": 
"sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
       "license": "MIT"
     },
+    "node_modules/property-information": {
+      "version": "7.1.0",
+      "resolved": 
"https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz";,
+      "integrity": 
"sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/proxy-addr": {
       "version": "2.0.7",
       "resolved": 
"https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz";,
@@ -13996,6 +14932,33 @@
       "integrity": 
"sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
       "license": "MIT"
     },
+    "node_modules/react-markdown": {
+      "version": "10.1.0",
+      "resolved": 
"https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz";,
+      "integrity": 
"sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "devlop": "^1.0.0",
+        "hast-util-to-jsx-runtime": "^2.0.0",
+        "html-url-attributes": "^3.0.0",
+        "mdast-util-to-hast": "^13.0.0",
+        "remark-parse": "^11.0.0",
+        "remark-rehype": "^11.0.0",
+        "unified": "^11.0.0",
+        "unist-util-visit": "^5.0.0",
+        "vfile": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      },
+      "peerDependencies": {
+        "@types/react": ">=18",
+        "react": ">=18"
+      }
+    },
     "node_modules/react-refresh": {
       "version": "0.11.0",
       "resolved": 
"https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz";,
@@ -14313,6 +15276,39 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/remark-parse": {
+      "version": "11.0.0",
+      "resolved": 
"https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz";,
+      "integrity": 
"sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "micromark-util-types": "^2.0.0",
+        "unified": "^11.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/remark-rehype": {
+      "version": "11.1.2",
+      "resolved": 
"https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz";,
+      "integrity": 
"sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "mdast-util-to-hast": "^13.0.0",
+        "unified": "^11.0.0",
+        "vfile": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
     "node_modules/renderkid": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz";,
@@ -15224,6 +16220,16 @@
       "deprecated": "Please use @jridgewell/sourcemap-codec instead",
       "license": "MIT"
     },
+    "node_modules/space-separated-tokens": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz";,
+      "integrity": 
"sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/spdy": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz";,
@@ -15592,6 +16598,20 @@
         "url": "https://github.com/sponsors/ljharb";
       }
     },
+    "node_modules/stringify-entities": {
+      "version": "4.0.4",
+      "resolved": 
"https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz";,
+      "integrity": 
"sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+      "license": "MIT",
+      "dependencies": {
+        "character-entities-html4": "^2.0.0",
+        "character-entities-legacy": "^3.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/stringify-object": {
       "version": "3.3.0",
       "resolved": 
"https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz";,
@@ -15698,6 +16718,24 @@
         "webpack": "^5.0.0"
       }
     },
+    "node_modules/style-to-js": {
+      "version": "1.1.17",
+      "resolved": 
"https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz";,
+      "integrity": 
"sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==",
+      "license": "MIT",
+      "dependencies": {
+        "style-to-object": "1.0.9"
+      }
+    },
+    "node_modules/style-to-object": {
+      "version": "1.0.9",
+      "resolved": 
"https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz";,
+      "integrity": 
"sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==",
+      "license": "MIT",
+      "dependencies": {
+        "inline-style-parser": "0.2.4"
+      }
+    },
     "node_modules/stylehacks": {
       "version": "5.1.1",
       "resolved": 
"https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz";,
@@ -16283,6 +17321,26 @@
         "node": ">=8"
       }
     },
+    "node_modules/trim-lines": {
+      "version": "3.0.1",
+      "resolved": 
"https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz";,
+      "integrity": 
"sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
+    "node_modules/trough": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz";,
+      "integrity": 
"sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
+    },
     "node_modules/tryer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz";,
@@ -16561,6 +17619,37 @@
         "node": ">=4"
       }
     },
+    "node_modules/unified": {
+      "version": "11.0.5",
+      "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz";,
+      "integrity": 
"sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "bail": "^2.0.0",
+        "devlop": "^1.0.0",
+        "extend": "^3.0.0",
+        "is-plain-obj": "^4.0.0",
+        "trough": "^2.0.0",
+        "vfile": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/unified/node_modules/is-plain-obj": {
+      "version": "4.1.0",
+      "resolved": 
"https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz";,
+      "integrity": 
"sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus";
+      }
+    },
     "node_modules/unique-string": {
       "version": "2.0.0",
       "resolved": 
"https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz";,
@@ -16573,6 +17662,74 @@
         "node": ">=8"
       }
     },
+    "node_modules/unist-util-is": {
+      "version": "6.0.0",
+      "resolved": 
"https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz";,
+      "integrity": 
"sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/unist-util-position": {
+      "version": "5.0.0",
+      "resolved": 
"https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz";,
+      "integrity": 
"sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/unist-util-stringify-position": {
+      "version": "4.0.0",
+      "resolved": 
"https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz";,
+      "integrity": 
"sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/unist-util-visit": {
+      "version": "5.0.0",
+      "resolved": 
"https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz";,
+      "integrity": 
"sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-is": "^6.0.0",
+        "unist-util-visit-parents": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/unist-util-visit-parents": {
+      "version": "6.0.1",
+      "resolved": 
"https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz";,
+      "integrity": 
"sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-is": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
     "node_modules/universalify": {
       "version": "2.0.1",
       "resolved": 
"https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz";,
@@ -16730,6 +17887,34 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/vfile": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz";,
+      "integrity": 
"sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "vfile-message": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
+    "node_modules/vfile-message": {
+      "version": "4.0.3",
+      "resolved": 
"https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz";,
+      "integrity": 
"sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-stringify-position": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified";
+      }
+    },
     "node_modules/w3c-hr-time": {
       "version": "1.0.2",
       "resolved": 
"https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz";,
@@ -17667,6 +18852,16 @@
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus";
       }
+    },
+    "node_modules/zwitch": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz";,
+      "integrity": 
"sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm";
+      }
     }
   }
 }
diff --git a/airavata-mcp-client-chatbot/widget/package.json 
b/airavata-mcp-client-chatbot/widget/package.json
index 5ba16f649..1b0f20489 100644
--- a/airavata-mcp-client-chatbot/widget/package.json
+++ b/airavata-mcp-client-chatbot/widget/package.json
@@ -11,11 +11,15 @@
     "@types/node": "^16.18.126",
     "@types/react": "^19.1.8",
     "@types/react-dom": "^19.1.6",
-    "axios": "^1.11.0",
+
+    "axios": "^1.10.0",
+    "markdown": "^0.5.0",
     "react": "^19.1.0",
     "react-chatbotify": "^2.2.0",
     "react-dom": "^19.1.0",
     "react-icons": "^5.5.0",
+    "react-markdown": "^10.1.0",
+
     "react-router-dom": "^7.7.0",
     "react-scripts": "5.0.1",
     "typescript": "^4.9.5",
diff --git a/airavata-mcp-client-chatbot/widget/src/components/Results.tsx 
b/airavata-mcp-client-chatbot/widget/src/components/Results.tsx
index 4f3034ac7..e9406ccd8 100644
--- a/airavata-mcp-client-chatbot/widget/src/components/Results.tsx
+++ b/airavata-mcp-client-chatbot/widget/src/components/Results.tsx
@@ -2,8 +2,10 @@ import React, { useState, useEffect, useRef } from "react";
 import { useLocation } from "react-router-dom";
 import "./Results2.css";
 import Chatbox from "./Chatbox";
+import ReactMarkdown from "react-markdown";
 import FormattedMessage from "./FormattedMessage";
 
+
 export interface Message {
   id: string;
   from: "user" | "bot";
@@ -34,6 +36,7 @@ const Results: React.FC<ResultsProps> = ({ messages = [], 
onSendMessage }) => {
         text: state.question,
         timestamp: new Date(),
       };
+
       setDisplayedMessages([initialMessage]);
 
       // add bot response after delay
@@ -70,20 +73,28 @@ const Results: React.FC<ResultsProps> = ({ messages = [], 
onSendMessage }) => {
           <div
             key={msg.id}
             className={`messageRow ${msg.from}`}
+
             style={{
               animation: `slideIn 0.3s ease-out ${idx * 0.1}s both`,
             }}
           >
-            <div className="messageGroup">
-              <div className={`messageBubble ${msg.from}`}>
-                {msg.from === "bot" ? (
-                  <FormattedMessage text={msg.text} />
-                ) : (
-                  <span className="messageText">{msg.text}</span>
-                )}
-              </div>
-              <div className={`messageTimestamp ${msg.from}`}>
-                {formatTime(msg.timestamp)}
+
+            <div className={`messageRow ${msg.from}`}>
+              <div className="messageGroup">
+                <div className={`messageBubble ${msg.from}`}>
+                  {/* <span className="messageText">{msg.text}</span> */}
+                  <span className="messageText">
+                    {msg.from === "bot" ? (
+                      <ReactMarkdown>{msg.text}</ReactMarkdown>
+                    ) : (
+                      msg.text
+                    )}
+                  </span>
+                </div>
+                <div className={`messageTimestamp ${msg.from}`}>
+                  {formatTime(msg.timestamp)}
+                </div>
+
               </div>
             </div>
           </div>
@@ -93,11 +104,15 @@ const Results: React.FC<ResultsProps> = ({ messages = [], 
onSendMessage }) => {
 
       <Chatbox
         fixedBottom
-        onSend={onSendMessage}
+
+        onSend={onSendMessage} // src code in Chatbox.tsx
+
         messages={displayedMessages}
       />
     </div>
   );
 };
 
-export default Results;
\ No newline at end of file
+
+export default Results;
+


Reply via email to