File size: 3,274 Bytes
5250e7c
d62c40e
393d365
cfff901
 
5250e7c
d62c40e
5ebb5b8
 
cfff901
 
 
5ebb5b8
 
 
 
 
5250e7c
393d365
 
 
 
 
 
5ebb5b8
 
 
393d365
 
 
 
 
 
cfff901
 
 
393d365
 
5250e7c
5ebb5b8
393d365
5250e7c
cfff901
393d365
 
 
d62c40e
cfff901
393d365
 
 
 
5ebb5b8
393d365
 
5250e7c
 
 
5ebb5b8
 
393d365
 
 
5ebb5b8
 
 
 
 
 
 
 
 
5250e7c
393d365
aa093b2
393d365
5250e7c
5ebb5b8
5250e7c
5ebb5b8
5250e7c
cfff901
 
5ebb5b8
 
 
 
 
cfff901
 
393d365
 
5250e7c
 
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
import os
import gradio as gr
import spaces
import fitz
import docx
from huggingface_hub import InferenceClient

# 1. 引擎配置与强制授权
# 关键修复:headers 在此处传入
hf_token = os.getenv("HF_TOKEN")
model_id = "MiniMaxAI/MiniMax-M2.5"

client = InferenceClient(
    model=model_id, 
    token=hf_token,
    headers={"Authorization": f"Bearer {hf_token}"} if hf_token else None
)

def extract_text(file_path):
    if not file_path: return ""
    try:
        ext = str(file_path).lower()
        if ext.endswith(".pdf"):
            doc = fitz.open(file_path)
            text = "".join([page.get_text() for page in doc])
            doc.close()
            return text[:15000]
        elif ext.endswith(".docx"):
            doc = docx.Document(file_path)
            return "\n".join([p.text for p in doc.paragraphs])[:15000]
        elif ext.endswith(".txt"):
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                return f.read()[:15000]
        return ""
    except:
        return ""

@spaces.GPU(duration=60)
def chat_fn(message, history):
    # 彻底压扁历史记录
    clean_messages = []
    for turn in history:
        clean_messages.append({"role": turn["role"], "content": str(turn["content"])})
    
    prompt_text = message.get("text", "")
    files = message.get("files", [])
    
    if files:
        f = files[0]
        file_path = f.get("path") if isinstance(f, dict) else f
        context = extract_text(file_path)
        if context:
            prompt_text = f"【参考文档】:\n{context}\n\n【用户指令】: {prompt_text}"
        
    clean_messages.append({"role": "user", "content": prompt_text})

    response = ""
    try:
        # 修复:移除 chat_completion 里的 headers 参数
        stream = client.chat_completion(
            clean_messages, 
            max_tokens=2048, 
            stream=True, 
            temperature=0.7
        )
        
        for msg in stream:
            if hasattr(msg, 'choices') and len(msg.choices) > 0:
                delta = msg.choices[0].delta
                if hasattr(delta, 'content') and delta.content:
                    response += delta.content
                    yield response
        
        if response:
            yield response + "\n\n---\n> **Powered by OpenIPOS Global 算力节点 | 访问 api.openipos.com 获取私有部署**"
            
    except Exception as e:
        yield f"⚠️ 算力调度提示: {str(e)}。由于万亿级模型访问量大,若持续报错请检查 Token 权限。"

# 3. 极简黑金 UI
with gr.Blocks(fill_height=True) as demo:
    gr.HTML("""
        <div style="display: flex; align-items: center; gap: 20px; padding: 10px;">
            <img src="https://s3.bmp.ovh/2026/03/30/rIAGKg0O.png" style="height: 60px; width: auto;">
            <div>
                <h1 style="margin: 0; font-size: 24px;">OpenIPOS MegaNode</h1>
                <p style="margin: 0; color: #666;">中文精品人工智能算力出口 (MiniMax-M2.5)</p>
            </div>
        </div>
    """)
    gr.ChatInterface(chat_fn, multimodal=True)
    gr.Markdown("© 2026 OpenIPOS Global Limited. 算力驱动:Hugging Face Inference Providers")

demo.launch(theme=gr.themes.Soft())