WinstonDeng commited on
Commit
17b5c7c
·
verified ·
1 Parent(s): 49fc911

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -86
app.py CHANGED
@@ -15,9 +15,47 @@ STEPFUN_LOGO = "https://huggingface.co/stepfun-ai/Step-3.5-Flash/resolve/main/st
15
  st.set_page_config(
16
  page_title="Step-3.5-Flash",
17
  page_icon="🚀",
18
- layout="wide",
19
  )
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  @st.cache_data(ttl=3600)
23
  def fetch_model_config():
@@ -25,8 +63,8 @@ def fetch_model_config():
25
  response = httpx.get(HF_CONFIG_URL, timeout=10.0)
26
  if response.status_code == 200:
27
  return response.json()
28
- except Exception as e:
29
- st.error(f"拉取 config.json 失败: {e}")
30
  return None
31
 
32
 
@@ -35,7 +73,10 @@ def format_messages(history, system_prompt: str, user_message: str):
35
  if system_prompt.strip():
36
  messages.append({"role": "system", "content": system_prompt})
37
  for msg in history:
38
- messages.append({"role": msg["role"], "content": msg["content"]})
 
 
 
39
  messages.append({"role": "user", "content": user_message})
40
  return messages
41
 
@@ -88,15 +129,23 @@ def chat_stream(message: str, history: list, system_prompt: str, max_tokens: int
88
  yield reasoning, f"❌ 错误: {str(e)}"
89
 
90
 
 
 
 
 
 
 
 
 
 
 
 
91
  def main():
92
  st.title("🚀 Step-3.5-Flash")
93
- st.caption("基于 [Step-3.5-Flash](https://huggingface.co/stepfun-ai/Step-3.5-Flash) 的智能对话助手")
94
 
95
  # 初始化 session state
96
  if "messages" not in st.session_state:
97
  st.session_state.messages = []
98
- if "thinking" not in st.session_state:
99
- st.session_state.thinking = ""
100
 
101
  # 侧边栏设置
102
  with st.sidebar:
@@ -109,7 +158,6 @@ def main():
109
  st.divider()
110
  if st.button("🗑️ 清空对话", use_container_width=True):
111
  st.session_state.messages = []
112
- st.session_state.thinking = ""
113
  st.rerun()
114
 
115
  st.divider()
@@ -118,86 +166,75 @@ def main():
118
  if config:
119
  st.json(config)
120
 
121
- # 主界面:左右布局
122
- col_thinking, col_chat = st.columns([1, 4])
123
-
124
- # 左侧:思考过程
125
- with col_thinking:
126
- st.subheader("💭 思考过程")
127
- thinking_container = st.container(height=500)
128
- with thinking_container:
129
- if st.session_state.thinking:
130
- st.markdown(st.session_state.thinking)
131
- else:
132
- st.caption("等待输入...")
133
-
134
- # 右侧:对话
135
- with col_chat:
136
- st.subheader("💬 对话")
137
-
138
- # 显示历史消息
139
- chat_container = st.container(height=450)
140
- with chat_container:
141
- for msg in st.session_state.messages:
142
- with st.chat_message(msg["role"], avatar=STEPFUN_LOGO if msg["role"] == "assistant" else None):
143
- st.markdown(msg["content"])
144
-
145
- # 输入框
146
- if prompt := st.chat_input("输入消息..."):
147
- # 添加用户消息
148
- st.session_state.messages.append({"role": "user", "content": prompt})
149
-
150
- # 显示用户消息
151
- with chat_container:
152
- with st.chat_message("user"):
153
- st.markdown(prompt)
154
-
155
- # 生成回复
156
- with chat_container:
157
- with st.chat_message("assistant", avatar=STEPFUN_LOGO):
158
- response_placeholder = st.empty()
159
- thinking_placeholder = col_thinking.empty()
160
-
161
- full_response = ""
162
- full_thinking = ""
163
-
164
- for thinking, response in chat_stream(
165
- prompt,
166
- st.session_state.messages[:-1],
167
- system_prompt,
168
- max_tokens,
169
- temperature,
170
- top_p,
171
- ):
172
- full_thinking = thinking
173
- full_response = response if response else "▌"
174
- response_placeholder.markdown(full_response)
175
-
176
- # 更新思考过程
177
- with thinking_placeholder.container(height=500):
178
- if full_thinking:
179
- st.markdown(full_thinking)
180
-
181
- # 保存消息
182
- st.session_state.messages.append({"role": "assistant", "content": full_response})
183
- st.session_state.thinking = full_thinking
184
- st.rerun()
185
-
186
- # 示例问题
187
- st.divider()
188
- st.subheader("💡 试试这些")
189
- examples = [
190
- "请解释一下什么是机器学习?",
191
- "帮我写一个 Python 快速排序算法",
192
- "1000以内有多少个质数?",
193
- "一个农夫需要把狼、羊和白菜都带过河,请问农夫该怎么办?",
194
- ]
195
- cols = st.columns(len(examples))
196
- for i, example in enumerate(examples):
197
- if cols[i].button(example, key=f"example_{i}", use_container_width=True):
198
- st.session_state.messages.append({"role": "user", "content": example})
199
  st.rerun()
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
  if __name__ == "__main__":
203
  main()
 
15
  st.set_page_config(
16
  page_title="Step-3.5-Flash",
17
  page_icon="🚀",
18
+ layout="centered",
19
  )
20
 
21
+ # 自定义样式
22
+ st.markdown("""
23
+ <style>
24
+ /* 思考气泡样式 - 6行高度,超长滚动 */
25
+ .thinking-bubble {
26
+ background: linear-gradient(135deg, #f0f4f8 0%, #e2e8f0 100%);
27
+ border: 1px solid #cbd5e1;
28
+ border-radius: 12px;
29
+ padding: 12px 16px;
30
+ margin-bottom: 8px;
31
+ max-height: 156px; /* 约6行 */
32
+ overflow-y: auto;
33
+ font-size: 13px;
34
+ line-height: 1.6;
35
+ color: #64748b;
36
+ white-space: pre-wrap;
37
+ word-break: break-word;
38
+ }
39
+ .thinking-bubble::-webkit-scrollbar {
40
+ width: 4px;
41
+ }
42
+ .thinking-bubble::-webkit-scrollbar-thumb {
43
+ background: #94a3b8;
44
+ border-radius: 2px;
45
+ }
46
+ .thinking-header {
47
+ font-size: 12px;
48
+ color: #94a3b8;
49
+ margin-bottom: 4px;
50
+ font-weight: 500;
51
+ }
52
+
53
+ /* 隐藏 Streamlit 默认元素 */
54
+ #MainMenu {visibility: hidden;}
55
+ footer {visibility: hidden;}
56
+ </style>
57
+ """, unsafe_allow_html=True)
58
+
59
 
60
  @st.cache_data(ttl=3600)
61
  def fetch_model_config():
 
63
  response = httpx.get(HF_CONFIG_URL, timeout=10.0)
64
  if response.status_code == 200:
65
  return response.json()
66
+ except:
67
+ pass
68
  return None
69
 
70
 
 
73
  if system_prompt.strip():
74
  messages.append({"role": "system", "content": system_prompt})
75
  for msg in history:
76
+ if msg["role"] in ["user", "assistant"]:
77
+ content = msg.get("content", "")
78
+ if content:
79
+ messages.append({"role": msg["role"], "content": content})
80
  messages.append({"role": "user", "content": user_message})
81
  return messages
82
 
 
129
  yield reasoning, f"❌ 错误: {str(e)}"
130
 
131
 
132
+ def render_thinking_bubble(thinking_text: str):
133
+ """渲染思考气泡"""
134
+ if thinking_text:
135
+ # 转义 HTML 特殊字符
136
+ escaped_text = thinking_text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
137
+ st.markdown(f"""
138
+ <div class="thinking-header">💭 思考过程</div>
139
+ <div class="thinking-bubble">{escaped_text}</div>
140
+ """, unsafe_allow_html=True)
141
+
142
+
143
  def main():
144
  st.title("🚀 Step-3.5-Flash")
 
145
 
146
  # 初始化 session state
147
  if "messages" not in st.session_state:
148
  st.session_state.messages = []
 
 
149
 
150
  # 侧边栏设置
151
  with st.sidebar:
 
158
  st.divider()
159
  if st.button("🗑️ 清空对话", use_container_width=True):
160
  st.session_state.messages = []
 
161
  st.rerun()
162
 
163
  st.divider()
 
166
  if config:
167
  st.json(config)
168
 
169
+ # 显示历史消息
170
+ for msg in st.session_state.messages:
171
+ if msg["role"] == "user":
172
+ with st.chat_message("user"):
173
+ st.markdown(msg["content"])
174
+ elif msg["role"] == "assistant":
175
+ with st.chat_message("assistant", avatar=STEPFUN_LOGO):
176
+ # 显示思考过程气泡
177
+ if msg.get("thinking"):
178
+ render_thinking_bubble(msg["thinking"])
179
+ st.markdown(msg["content"])
180
+
181
+ # 输入框
182
+ if prompt := st.chat_input("输入消息..."):
183
+ # 添加并显示用户消息
184
+ st.session_state.messages.append({"role": "user", "content": prompt})
185
+ with st.chat_message("user"):
186
+ st.markdown(prompt)
187
+
188
+ # 生成回复
189
+ with st.chat_message("assistant", avatar=STEPFUN_LOGO):
190
+ thinking_placeholder = st.empty()
191
+ response_placeholder = st.empty()
192
+
193
+ full_response = ""
194
+ full_thinking = ""
195
+
196
+ for thinking, response in chat_stream(
197
+ prompt,
198
+ st.session_state.messages[:-1],
199
+ system_prompt,
200
+ max_tokens,
201
+ temperature,
202
+ top_p,
203
+ ):
204
+ full_thinking = thinking
205
+ full_response = response if response else ""
206
+
207
+ # 更新思考气泡
208
+ if full_thinking:
209
+ with thinking_placeholder:
210
+ render_thinking_bubble(full_thinking)
211
+
212
+ # 更新回答
213
+ response_placeholder.markdown(full_response)
214
+
215
+ # 保存消息(包含思考过程)
216
+ st.session_state.messages.append({
217
+ "role": "assistant",
218
+ "content": full_response,
219
+ "thinking": full_thinking,
220
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  st.rerun()
222
 
223
+ # 示例问题(底部)
224
+ if not st.session_state.messages:
225
+ st.divider()
226
+ st.caption("💡 试试这些问题:")
227
+ examples = [
228
+ "请解释一下什么是机器学习?",
229
+ "帮我写一个 Python 快速排序算法",
230
+ "1000以内有多少个质数?",
231
+ ]
232
+ cols = st.columns(len(examples))
233
+ for i, example in enumerate(examples):
234
+ if cols[i].button(example, key=f"ex_{i}", use_container_width=True):
235
+ st.session_state.messages.append({"role": "user", "content": example})
236
+ st.rerun()
237
+
238
 
239
  if __name__ == "__main__":
240
  main()