File size: 4,348 Bytes
89ed8da
1d20e23
 
 
 
89ed8da
1d20e23
 
 
 
 
89ed8da
1d20e23
 
89ed8da
1d20e23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89ed8da
1d20e23
 
89ed8da
1d20e23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89ed8da
1d20e23
 
 
 
 
 
 
 
89ed8da
1d20e23
89ed8da
1d20e23
 
 
 
 
28e2b46
1d20e23
 
 
89ed8da
1d20e23
 
 
 
 
 
 
 
89ed8da
1d20e23
 
89ed8da
1d20e23
 
 
 
 
 
 
 
89ed8da
 
 
1d20e23
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
import gradio as gr
from openai import OpenAI
import os
import glob
from pypdf import PdfReader

# Initialize client using Hugging Face routing
client = OpenAI(
    base_url="https://router.huggingface.co/v1",
    api_key=os.environ.get("HF_TOKEN"),
)

# --- Document Context Logic ---
DOCS_DIR = "docs" # Folder for your JMeter cheat sheets, project specs, etc.

def load_pdf_context():
    """Reads all PDFs in the DOCS_DIR once at startup and extracts text."""
    context = ""
    if not os.path.exists(DOCS_DIR):
        os.makedirs(DOCS_DIR)
        print(f"Created '{DOCS_DIR}' directory. Upload your PDFs here.")
        return context
        
    pdf_files = glob.glob(os.path.join(DOCS_DIR, "*.pdf"))
    if not pdf_files:
        print("No PDFs found in the docs folder.")
        return context
        
    print(f"Loading {len(pdf_files)} PDF(s) into context...")
    for file_path in pdf_files:
        try:
            reader = PdfReader(file_path)
            context += f"\n--- Start Document: {os.path.basename(file_path)} ---\n"
            for page in reader.pages:
                text = page.extract_text()
                if text:
                    context += text + "\n"
            context += f"--- End Document: {os.path.basename(file_path)} ---\n\n"
        except Exception as e:
            print(f"Error loading {file_path}: {e}")
            
    return context

DOCUMENT_CONTEXT = load_pdf_context()
# -----------------------------------

def respond(message, history):
    # System Message tailored for an experienced Dev learning JMeter
    system_content = (
        "You are a highly experienced Performance Engineer and Apache JMeter expert. "
        "The user you are helping is an experienced software developer who is new to JMeter and stress testing. "
        "Skip basic programming concepts and focus strictly on JMeter architecture (Test Plans, Thread Groups, Samplers, Listeners, Timers), "
        "performance testing theory (Load vs. Stress vs. Spike testing), and best practices (e.g., using JSR223 Samplers with Groovy instead of BeanShell, running in CLI/non-GUI mode). "
        "Be concise, technical, and highly practical. Provide code snippets or XML structures where helpful.\n\n"
        "Here is the project-specific context and documentation you should use to answer questions:\n"
        f"{DOCUMENT_CONTEXT}"
    )
    
    messages = [{"role": "system", "content": system_content}]
    
    # Add conversation history
    for val in history:
        if val['role'] == 'user':
            messages.append({"role": "user", "content": val['content']})
        else:
            messages.append({"role": "assistant", "content": val['content']})

    # Process the current message
    user_content = []
    if message["text"]:
        user_content.append({"type": "text", "text": message["text"]})
    
    # Image/File handling placeholder
    for file in message["files"]:
        pass 

    messages.append({"role": "user", "content": user_content})

    response = ""
    
    try:
        stream = client.chat.completions.create(
            # You can keep this model or switch to another available on HF-Pro
            model="Qwen/Qwen2.5-Coder-32B-Instruct:nscale", 
            messages=messages,
            stream=True
        )

        for chunk in stream:
            if hasattr(chunk, 'choices') and len(chunk.choices) > 0:
                token = chunk.choices[0].delta.content
                if token:
                    response += token
                    yield response
    except Exception as e:
        yield f"Error encountered: {str(e)} - Please verify the model endpoint or your API token."

# Interface Setup
demo = gr.ChatInterface(
    respond,
    multimodal=True, 
    title="Apache JMeter Performance Expert ⚙️",
    description="Your technical guide for building robust JMeter test plans, analyzing performance metrics, and executing effective stress tests. Backed by your project documentation.",
    examples=[
        {"text": "What is the difference between a Load Test and a Stress Test?"},
        {"text": "How do I extract a dynamic token from a JSON response to use in my next request?"},
        {"text": "Why should I run my tests in non-GUI mode, and what is the command for it?"}
    ]
)

if __name__ == "__main__":
    demo.launch()