File size: 6,740 Bytes
c1a43bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
"""
CLI Proxy API Plus - Streamlit Frontend for Hugging Face Spaces
Main application entry point
"""

import streamlit as st
import httpx
import os
import time

# ============================================
# 頁面配置
# ============================================
st.set_page_config(
    page_title="CLI Proxy API Plus",
    page_icon="🚀",
    layout="wide",
    initial_sidebar_state="expanded",
    menu_items={
        'Get Help': 'https://github.com/router-for-me/CLIProxyAPIPlus',
        'Report a bug': 'https://github.com/router-for-me/CLIProxyAPIPlus/issues',
        'About': """
        # CLI Proxy API Plus
        
        統一的 AI API 代理服務,支援多種 AI 提供者。
        
        **版本**: HF Spaces Edition
        """
    }
)

# ============================================
# 全局配置
# ============================================
API_BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8317")
HF_SPACE_URL = os.getenv("SPACE_URL", "")
REQUEST_TIMEOUT = 60.0

# ============================================
# 會話狀態初始化
# ============================================
if "api_status" not in st.session_state:
    st.session_state.api_status = "unknown"
if "last_check" not in st.session_state:
    st.session_state.last_check = 0

# ============================================
# API 狀態檢查函數
# ============================================
def check_api_status():
    """檢查 Go API 服務器狀態"""
    try:
        response = httpx.get(
            f"{API_BASE_URL}/v1/models",
            timeout=5.0
        )
        if response.status_code == 200:
            return "online"
        return "error"
    except httpx.ConnectError:
        return "offline"
    except Exception as e:
        return f"error: {str(e)}"

def get_api_health():
    """獲取 API 健康狀態詳情"""
    try:
        response = httpx.get(
            f"{API_BASE_URL}/v0/management/health",
            timeout=5.0
        )
        if response.status_code == 200:
            return response.json()
        return None
    except:
        return None

# ============================================
# 側邊欄
# ============================================
with st.sidebar:
    # Logo 和標題
    st.markdown("""
    <div style="text-align: center; padding: 20px 0;">
        <h1 style="font-size: 2em; margin-bottom: 0;">🚀</h1>
        <h2 style="margin-top: 0;">CLI Proxy API</h2>
        <p style="color: gray; font-size: 0.9em;">Plus Edition</p>
    </div>
    """, unsafe_allow_html=True)
    
    st.markdown("---")
    
    # API 狀態檢查
    current_time = time.time()
    if current_time - st.session_state.last_check > 30:  # 30秒檢查一次
        st.session_state.api_status = check_api_status()
        st.session_state.last_check = current_time
    
    status = st.session_state.api_status
    if status == "online":
        st.success("✅ API 服務運行中")
    elif status == "offline":
        st.error("❌ API 服務離線")
        st.caption("請等待服務啟動...")
    else:
        st.warning(f"⚠️ API 狀態: {status}")
    
    st.markdown("---")
    
    # 導航說明
    st.markdown("### 📋 功能導航")
    st.markdown("""
    - **💬 Chat** - API 測試介面
    - **🔑 Auth** - 認證管理
    - **📊 Stats** - 使用統計
    - **⚙️ Settings** - 系統設定
    """)
    
    st.markdown("---")
    
    # HF Spaces 資訊
    if HF_SPACE_URL:
        st.caption(f"🌐 Space: {HF_SPACE_URL}")
    
    st.caption("📦 Hugging Face Spaces Edition")

# ============================================
# 主頁面內容
# ============================================
st.title("🚀 CLI Proxy API Plus")
st.markdown("### 統一的 AI API 代理服務")

st.markdown("""
歡迎使用 **CLI Proxy API Plus**!這是一個統一的 AI API 代理服務,
讓您可以通過標準化的 API 接口訪問多種 AI 提供者。
""")

# ============================================
# 功能卡片
# ============================================
st.markdown("## 🎯 快速開始")

col1, col2, col3, col4 = st.columns(4)

with col1:
    st.page_link("pages/1_💬_Chat.py", label="💬 API 測試", icon="💬")
    st.caption("測試 API 請求和響應")

with col2:
    st.page_link("pages/2_🔑_Auth.py", label="🔑 認證管理", icon="🔑")
    st.caption("管理 OAuth Token")

with col3:
    st.page_link("pages/3_📊_Stats.py", label="📊 使用統計", icon="📊")
    st.caption("查看使用量統計")

with col4:
    st.page_link("pages/4_⚙️_Settings.py", label="⚙️ 設定", icon="⚙️")
    st.caption("系統配置")

st.markdown("---")

# ============================================
# 支援的提供者
# ============================================
st.markdown("## 🤖 支援的 AI 提供者")

providers = [
    {"name": "Claude", "icon": "🟠", "desc": "Anthropic Claude API"},
    {"name": "OpenAI", "icon": "🟢", "desc": "GPT-4, GPT-3.5"},
    {"name": "Gemini", "icon": "🔵", "desc": "Google Gemini API"},
    {"name": "GitHub Copilot", "icon": "⚫", "desc": "GitHub Copilot"},
    {"name": "Kiro", "icon": "🟡", "desc": "AWS CodeWhisperer"},
    {"name": "Codex", "icon": "🟣", "desc": "OpenAI Codex"},
]

provider_cols = st.columns(len(providers))
for i, provider in enumerate(providers):
    with provider_cols[i]:
        st.markdown(f"""
        <div style="text-align: center; padding: 15px; border-radius: 10px; background: #f0f2f6;">
            <div style="font-size: 2em;">{provider['icon']}</div>
            <div style="font-weight: bold; margin-top: 5px;">{provider['name']}</div>
            <div style="font-size: 0.8em; color: gray;">{provider['desc']}</div>
        </div>
        """, unsafe_allow_html=True)

st.markdown("---")

# ============================================
# API 端點說明
# ============================================
st.markdown("## 📡 API 端點")

st.markdown("""
| 端點 | 方法 | 說明 |
|------|------|------|
| `/v1/chat/completions` | POST | OpenAI 兼容 Chat API |
| `/v1/messages` | POST | Claude Messages API |
| `/v1/models` | GET | 列出可用模型 |
| `/v0/management/*` | * | 管理介面 API |
""")

st.markdown("---")

# ============================================
# 頁腳
# ============================================
st.markdown("""
<div style="text-align: center; padding: 20px; color: gray;">
    <p>CLI Proxy API Plus - Hugging Face Spaces Edition</p>
    <p>
        <a href="https://github.com/router-for-me/CLIProxyAPIPlus" target="_blank">GitHub</a> | 
        <a href="https://huggingface.co/spaces" target="_blank">Hugging Face</a>
    </p>
</div>
""", unsafe_allow_html=True)