File size: 5,094 Bytes
59e6760
 
 
9d761b8
434392c
f7d462d
94a9110
4f9b2d4
f7d462d
ec21b79
f7d462d
 
 
 
59e6760
4f9b2d4
9d761b8
 
434392c
9d761b8
 
 
59e6760
4f9b2d4
9d761b8
4f9b2d4
 
 
94a9110
4f9b2d4
9d761b8
434392c
94a9110
434392c
94a9110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434392c
59e6760
4f9b2d4
9d761b8
4f9b2d4
434392c
9d761b8
4f9b2d4
9d761b8
4f9b2d4
434392c
59e6760
4f9b2d4
59e6760
4f9b2d4
434392c
9d761b8
4f9b2d4
 
 
 
 
 
 
9d761b8
434392c
9d761b8
4f9b2d4
 
9d761b8
 
 
 
 
 
f7d462d
4f9b2d4
 
9d761b8
434392c
94a9110
434392c
9d761b8
434392c
94a9110
434392c
9d761b8
 
4f9b2d4
9d761b8
434392c
4f9b2d4
9d761b8
434392c
4f9b2d4
434392c
9d761b8
 
4f9b2d4
9d761b8
434392c
4f9b2d4
9d761b8
434392c
 
 
9d761b8
 
4f9b2d4
9d761b8
434392c
4f9b2d4
9d761b8
434392c
4f9b2d4
434392c
9d761b8
59e6760
434392c
f7d462d
 
 
4f9b2d4
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import gradio as gr
import requests
import json
import os
import shutil
import threading
import mimetypes
from models import OptimizeRequest, AutotuneRequest, QARequest
from api import start_api

threading.Thread(target=start_api, daemon=True).start()

# Base URL for internal calls
BASE_INTERNAL = "http://127.0.0.1:8000"


def call_api(endpoint: str, payload: dict) -> str:
    try:
        r = requests.post(f"{BASE_INTERNAL}{endpoint}", json=payload, timeout=120)
        return json.dumps(r.json(), indent=2)
    except Exception as e:
        return str(e)


def upload_docs_tool(files, docs_path="data/docs"):
    """
    Upload documents to the server's docs folder.

    Accepts local file paths or URLs. Returns a list of MCP FileData-like dicts.
    """
    os.makedirs(docs_path, exist_ok=True)
    saved = []

    for f in files:
        if f.startswith("http://") or f.startswith("https://"):
            # Download file from URL
            r = requests.get(f, stream=True)
            fname = f.split("/")[-1]
            dest = os.path.join(docs_path, fname)
            with open(dest, "wb") as out_file:
                shutil.copyfileobj(r.raw, out_file)
        else:
            # Local file path
            fname = os.path.basename(f)
            dest = os.path.join(docs_path, fname)
            shutil.copy(f, dest)

        mime_type = mimetypes.guess_type(dest)[0] or "application/octet-stream"
        saved.append({
            "path": dest,
            "url": f"file://{os.path.abspath(dest)}",
            "orig_name": fname,
            "mime_type": mime_type,
            "is_stream": False,
            "meta": {}
        })

    return {"status": "ok", "uploaded_files": saved, "docs_path": docs_path}


def optimize_rag_tool(payload: str) -> str:
    """🔧 Explicit optimization request: user provides all pipeline configs manually."""
    return call_api("/optimize_rag", json.loads(payload))


def autotune_tool(payload: str) -> str:
    """🔧 Autotune RAG: recommends chunk sizes and embedding models automatically."""
    return call_api("/autotune_rag", json.loads(payload))


def generate_qa_tool(payload: str) -> str:
    """🧩 Generates a validation QA dataset for RAG evaluation."""
    return call_api("/generate_validation_qa", json.loads(payload))


# Dynamically assign Pydantic model docstrings to MCP tool functions
optimize_rag_tool.__doc__ = OptimizeRequest.__doc__
autotune_tool.__doc__ = AutotuneRequest.__doc__
generate_qa_tool.__doc__ = QARequest.__doc__


def model_to_json(model_cls) -> str:
    return json.dumps({k: v.default for k, v in model_cls.__fields__.items()}, indent=2)


# Default inputs
DEFAULT_UPLOAD_PATH = "data/docs"
DEFAULT_OPTIMIZE_JSON = model_to_json(OptimizeRequest)
DEFAULT_AUTOTUNE_JSON = model_to_json(AutotuneRequest)
DEFAULT_QA_JSON = model_to_json(QARequest)

with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# Ragmint MCP Client")

    # Upload Documents
    with gr.Column():
        gr.Markdown("## Upload Documents")
        gr.Markdown("📂 Upload files (local paths or URLs) to your `data/docs` folder")
        upload_files = gr.File(file_count="multiple", type="filepath")
        upload_path = gr.Textbox(value=DEFAULT_UPLOAD_PATH, label="Docs Path")
        upload_btn = gr.Button("Upload", variant="primary")
        upload_out = gr.JSON(label="Response")
        upload_btn.click(upload_docs_tool, inputs=[upload_files, upload_path], outputs=upload_out)
        gr.Markdown("---")

    # Optimize RAG
    with gr.Column():
        gr.Markdown("## Optimize RAG")
        gr.Markdown(OptimizeRequest.__doc__ or "No description available.")
        optimize_input = gr.Textbox(lines=12, value=DEFAULT_OPTIMIZE_JSON, label="OptimizeRequest JSON")
        optimize_btn = gr.Button("Submit", variant="primary")
        optimize_out = gr.Textbox(lines=15, label="Response")
        optimize_btn.click(optimize_rag_tool, inputs=optimize_input, outputs=optimize_out)
        gr.Markdown("---")

    # Autotune RAG
    with gr.Column():
        gr.Markdown("## Autotune RAG")
        gr.Markdown(AutotuneRequest.__doc__ or "No description available.")
        autotune_input = gr.Textbox(lines=12, value=DEFAULT_AUTOTUNE_JSON, label="AutotuneRequest JSON")
        autotune_btn = gr.Button("Submit", variant="primary")
        autotune_out = gr.Textbox(lines=15)
        autotune_btn.click(autotune_tool, inputs=autotune_input, outputs=autotune_out)
        gr.Markdown("---")

    # Generate QA
    with gr.Column():
        gr.Markdown("## Generate QA")
        gr.Markdown(QARequest.__doc__ or "No description available.")
        qa_input = gr.Textbox(lines=12, value=DEFAULT_QA_JSON, label="QARequest JSON")
        qa_btn = gr.Button("Submit", variant="primary")
        qa_out = gr.Textbox(lines=15, label="Response")
        qa_btn.click(generate_qa_tool, inputs=qa_input, outputs=qa_out)
        gr.Markdown("---")

if __name__ == "__main__":
    demo.launch(
        server_name="0.0.0.0",
        server_port=7860,
        mcp_server=True,
        show_error=True
    )