CoolFace
Apppublic

muffin2006/document-classification-env

sourceHugging Faceupdated 6mo agoView on Hugging Face
1likes
app_v3.py397 linesDownload Raw Back to root
1import gradio as gr2import threading3import os4import pickle5import time6import json7from flask import Flask, request, jsonify8from environment import DocumentClassificationEnv9from baseline_inference import run_task, load_or_train10from agent import TicketAgent11from rl_trainer import RLTrainer12import numpy as np13 14print("=" * 60)15print("    MetaX AI Agent - HACKATHON EDITION")16print("=" * 60)17print("Loading AI models...")18 19models = {}20for d in ["easy", "medium", "hard"]:21    models[d] = load_or_train(d)22    print(f"  [OK] {d.upper()} model loaded")23 24agent = TicketAgent(model_dir=".")25print("[OK] Agent ready")26 27CATEGORIES = {28    "easy": ["General", "Billing", "Support", "Technical", "HR"],29    "medium": [30        "General",31        "Billing",32        "Support",33        "Technical",34        "HR",35        "Legal",36        "Sales",37        "Marketing",38        "Operations",39        "Complaints",40    ],41    "hard": [f"Cat_{i}" for i in range(22)],42}43 44api = Flask(__name__)45api_envs = {}46 47rl_state = {"trainer": None, "is_training": False}48 49 50@api.route("/api/reset", methods=["POST"])51def api_reset():52    data = request.json or {}53    difficulty = data.get("difficulty", "easy")54    seed = data.get("seed", 42)55    env = DocumentClassificationEnv(task_difficulty=difficulty, seed=seed)56    obs, _ = env.reset(seed=seed)57    api_envs["current"] = env58    return jsonify(59        {60            "observation": {61                k: v.tolist() if hasattr(v, "tolist") else v for k, v in obs.items()62            }63        }64    )65 66 67@api.route("/api/step", methods=["POST"])68def api_step():69    data = request.json or {}70    action = data.get("action", 0)71    env = api_envs.get("current")72    if env is None:73        return jsonify({"error": "Call /api/reset first"}), 40074    obs, reward, done, _, info = env.step(int(action))75    return jsonify(76        {77            "observation": {78                k: v.tolist() if hasattr(v, "tolist") else v for k, v in obs.items()79            },80            "reward": reward,81            "done": done,82            "info": info,83        }84    )85 86 87@api.route("/api/run", methods=["POST"])88def api_run():89    data = request.json or {}90    difficulty = data.get("difficulty", "easy")91    score, t = run_task(difficulty)92    return jsonify({"difficulty": difficulty, "score": score, "time": t})93 94 95@api.route("/api/agent/process", methods=["POST"])96def api_agent_process():97    data = request.json or {}98    text = data.get("text", "")99    difficulty = data.get("difficulty", "easy")100    ticket_id = data.get("ticket_id", None)101    if not text:102        return jsonify({"error": "text field required"}), 400103    result = agent.process_ticket(text, difficulty=difficulty, ticket_id=ticket_id)104    return jsonify(result)105 106 107@api.route("/api/agent/classify", methods=["POST"])108def api_agent_classify():109    data = request.json or {}110    text = data.get("text", "")111    difficulty = data.get("difficulty", "easy")112    category, scores = agent.classify(text, difficulty)113    priority = agent.get_priority(text)114    return jsonify({"category": category, "priority": priority, "scores": scores})115 116 117@api.route("/api/rl/train", methods=["POST"])118def api_rl_train():119    global rl_state120    data = request.json or {}121    difficulty = data.get("difficulty", "easy")122    episodes = data.get("episodes", 20)123 124    if rl_state.get("is_training"):125        return jsonify({"status": "Training already in progress"}), 400126 127    env = DocumentClassificationEnv(task_difficulty=difficulty, seed=42)128    trainer = RLTrainer(env, num_episodes=episodes)129    rl_state["trainer"] = trainer130    rl_state["is_training"] = True131 132    result = trainer.train_step()133    eval_result = trainer.evaluate(num_episodes=5)134    curve = trainer.generate_learning_curve()135    summary = trainer.get_metrics_summary()136 137    rl_state["is_training"] = False138 139    return jsonify(140        {141            "training_result": result,142            "evaluation": eval_result,143            "learning_curve": curve,144            "summary": summary,145        }146    )147 148 149@api.route("/api/rl/status", methods=["GET"])150def api_rl_status():151    if rl_state.get("trainer") is None:152        return jsonify({"status": "No training data"})153    return jsonify(rl_state["trainer"].get_metrics_summary())154 155 156def run_flask():157    api.run(host="0.0.0.0", port=7861, debug=False)158 159 160SAMPLE_TICKETS = {161    "Billing Complaint": "My invoice shows an incorrect amount! I was charged $500 but should have been charged $75. This is unacceptable!",162    "Critical Bug": "The application crashes whenever I try to upload a file larger than 10MB. This is critical!",163    "HR Policy": "I have a question about the company's maternity leave policy. How many weeks of paid leave am I entitled to?",164    "Login Issue": "I can't log into my account. The password reset link isn't working. Please help!",165    "Sales Inquiry": "I would like to inquire about upgrading our current subscription to include additional enterprise features.",166    "Legal Request": "We need legal review of the new vendor contract before signing.",167    "Frustrated Customer": "I'm extremely disappointed with the service. This is the third time this month I've had issues.",168}169 170env_state = {"env": None, "difficulty": "easy", "trainer": None}171 172 173def create_env(difficulty):174    e = DocumentClassificationEnv(task_difficulty=difficulty, seed=42)175    obs, _ = e.reset()176    env_state["env"] = e177    env_state["difficulty"] = difficulty178    model = models[difficulty]179    cats = CATEGORIES[difficulty]180    proba = model.predict_proba([obs["content"]])[0]181    top3 = sorted(enumerate(proba), key=lambda x: -x[1])[:3]182    explain = "\n".join([f"  {cats[i]}: {p * 100:.1f}%" for i, p in top3])183    pred_idx = int(model.predict([obs["content"]])[0])184    pred_cat = cats[pred_idx]185    return (186        f"Environment Ready | {difficulty.upper()}",187        obs["content"],188        f"ML Prediction: {pred_cat}\n\nTop 3:\n{explain}",189        "",190    )191 192 193def classify_doc(category_idx):194    e = env_state["env"]195    if e is None:196        return "Create environment first!", "", "", ""197    obs, reward, done, _, info = e.step(int(category_idx))198    result = (199        f"{'CORRECT' if info.get('is_correct') else 'WRONG'} | Reward: {reward:.2f}"200    )201    if done:202        acc = info.get("episode_accuracy", 0)203        result += f"\nEpisode Complete! Accuracy: {acc:.1%}"204        return result, "Episode complete", "", str(info)205    difficulty = env_state["difficulty"]206    model = models[difficulty]207    cats = CATEGORIES[difficulty]208    proba = model.predict_proba([obs["content"]])[0]209    top3 = sorted(enumerate(proba), key=lambda x: -x[1])[:3]210    explain = "\n".join([f"  {cats[i]}: {p * 100:.1f}%" for i, p in top3])211    pred_idx = int(model.predict([obs["content"]])[0])212    pred_cat = cats[pred_idx]213    return (214        result,215        obs["content"],216        f"ML Prediction: {pred_cat}\n\nTop 3:\n{explain}",217        str(info),218    )219 220 221def process_ticket_ui(ticket_text, difficulty):222    if not ticket_text.strip():223        return "Please enter ticket text!", "", "", "", "", ""224    result = agent.process_ticket(ticket_text, difficulty=difficulty)225    cat_out = f"{result['category']}\n   Confidence: {result['confidence'] * 100:.1f}%"226    pri_out = f"{result['priority'].upper()}"227    dept_out = f"{result['department']}\n   {result['email']}\n   SLA: {result['sla']}"228    top3_out = "\n".join([f"   {c}: {p * 100:.1f}%" for c, p in result["top3"]])229    ref_out = f"{result['ref_id']}\n   {result['timestamp'][:19]}"230    reply_out = result["reply"]231    return cat_out, pri_out, dept_out, top3_out, ref_out, reply_out232 233 234def run_rl_training(difficulty, num_episodes):235    difficulty = difficulty or "easy"236    num_episodes = num_episodes or 20237    try:238        env = DocumentClassificationEnv(task_difficulty=difficulty, seed=42)239        trainer = RLTrainer(env, num_episodes=num_episodes)240        env_state["trainer"] = trainer241        result = trainer.train_step()242        curve_img = trainer.generate_learning_curve()243        summary = trainer.get_metrics_summary()244        status = f"Training Complete!\n\nResults:\n   Episodes: {num_episodes}\n   Avg Reward: {result.get('avg_reward', 0):.2f}\n   Avg Accuracy: {result.get('avg_accuracy', 0):.1%}"245        eval_result = trainer.evaluate(num_episodes=5)246        status += f"\n\nEvaluation Accuracy: {eval_result.get('accuracy', 0):.1%}"247        return status, curve_img if curve_img else "", str(summary)248    except Exception as e:249        return f"Error: {str(e)}", "", ""250 251 252def load_sample(sample_name):253    return SAMPLE_TICKETS.get(sample_name, "")254 255 256def run_evaluation():257    rows = []258    for d in ["easy", "medium", "hard"]:259        score, t = run_task(d)260        rows.append([d.upper(), f"{score:.4f}", f"{score * 100:.1f}%", "Ready"])261    return rows262 263 264def process_image(file_obj):265    if file_obj is None:266        return "No image uploaded. Click 'Upload' button, select an image, then click 'Analyze Image'."267    return f"Image received: {type(file_obj)}. Image analysis requires PyTorch installation."268 269 270with gr.Blocks(title="MetaX AI - Hackathon Demo") as demo:271    gr.Markdown("""272    <div style="text-align: center; padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 20px; margin-bottom: 25px;">273        <h1 style="color: white; margin: 0; font-size: 2.5em;">MetaX AI Agent</h1>274        <p style="color: white; opacity: 0.95;">Document Classification | RL Training | AI-Powered</p>275    </div>276    """)277 278    with gr.Tab("AI Agent Demo"):279        gr.Markdown("### AI-Powered Ticket Classification")280        with gr.Row():281            with gr.Column(scale=1):282                sample_dd = gr.Dropdown(283                    choices=list(SAMPLE_TICKETS.keys()), label="Load Sample"284                )285                ticket_input = gr.Textbox(286                    label="Ticket Text",287                    lines=5,288                    placeholder="Enter customer message...",289                )290                diff_agent = gr.Radio(291                    ["easy", "medium", "hard"], value="medium", label="Difficulty"292                )293                btn_process = gr.Button("Process Ticket", variant="primary", size="lg")294            with gr.Column(scale=1):295                cat_out_box = gr.Textbox(label="Category", lines=2)296                pri_out_box = gr.Textbox(label="Priority", lines=2)297                dept_out_box = gr.Textbox(label="Routing", lines=2)298                top3_out_box = gr.Textbox(label="Top Predictions", lines=2)299        with gr.Row():300            ref_out_box = gr.Textbox(label="Reference", lines=1)301        reply_out_box = gr.Textbox(label="AI Response", lines=8)302        sample_dd.change(load_sample, inputs=sample_dd, outputs=ticket_input)303        btn_process.click(304            process_ticket_ui,305            inputs=[ticket_input, diff_agent],306            outputs=[307                cat_out_box,308                pri_out_box,309                dept_out_box,310                top3_out_box,311                ref_out_box,312                reply_out_box,313            ],314        )315 316    with gr.Tab("RL Training"):317        gr.Markdown("### Train RL Agent")318        with gr.Row():319            with gr.Column(scale=1):320                diff_rl = gr.Radio(321                    ["easy", "medium", "hard"], value="easy", label="Difficulty"322                )323                episodes_slider = gr.Slider(10, 100, value=30, step=5, label="Episodes")324                btn_train = gr.Button("Start Training", variant="primary", size="lg")325            with gr.Column(scale=2):326                train_status = gr.Textbox(label="Status", lines=8)327        learning_curve_img = gr.Image(label="Training Progress")328        btn_train.click(329            run_rl_training,330            inputs=[diff_rl, episodes_slider],331            outputs=[train_status, learning_curve_img, train_status],332        )333 334    with gr.Tab("Multi-Modal"):335        gr.Markdown("### Image Upload (Experimental)")336        gr.Markdown(337            "Note: Full image analysis requires PyTorch. Install: `pip install torch transformers`"338        )339        with gr.Row():340            file_input = gr.File(341                label="Upload Image", file_count="single", file_types=["image"]342            )343            image_btn = gr.Button("Analyze Image")344        image_output = gr.Textbox(label="Result", lines=4)345        image_btn.click(process_image, inputs=file_input, outputs=image_output)346 347    with gr.Tab("Interactive Env"):348        gr.Markdown("### Test Classification Environment")349        with gr.Row():350            diff = gr.Radio(351                ["easy", "medium", "hard"], value="easy", label="Difficulty"352            )353            btn_create = gr.Button("Create Environment", variant="primary")354            status = gr.Textbox(label="Status")355        with gr.Row():356            doc_content = gr.Textbox(label="Document", lines=4)357            explain_box = gr.Textbox(label="Model Reasoning", lines=4)358        with gr.Row():359            category = gr.Number(label="Category Index", value=0, precision=0)360            btn_classify = gr.Button("Classify")361            result = gr.Textbox(label="Result", lines=2)362        btn_create.click(363            create_env, inputs=diff, outputs=[status, doc_content, explain_box, result]364        )365        btn_classify.click(366            classify_doc,367            inputs=category,368            outputs=[result, doc_content, explain_box, result],369        )370 371    with gr.Tab("Performance"):372        gr.Markdown("### Model Performance")373        btn_eval = gr.Button("Run Evaluation", variant="primary")374        score_table = gr.Dataframe(375            headers=["Task", "Score", "Accuracy", "Status"], label="Results"376        )377        btn_eval.click(run_evaluation, outputs=score_table)378 379    with gr.Tab("Info"):380        gr.Markdown("""381        ## API Endpoints (port 7861)382        - POST /api/reset383        - POST /api/step  384        - POST /api/agent/process385        - POST /api/rl/train386        - GET /api/rl/status387        388        ## Run389        python app_v3.py390        Then open http://localhost:7860391        """)392 393if __name__ == "__main__":394    t = threading.Thread(target=run_flask, daemon=True)395    t.start()396    demo.launch(server_name="0.0.0.0", server_port=7860)397