main.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. # main.py
  2. import threading
  3. import time
  4. import gradio as gr
  5. import json
  6. from src.agents.sleep_agent import sleep_agent
  7. from src.agents.mind_echo_agent import create_mind_echo_agent
  8. # 启动 SleepAgent A2A 服务(后台线程)
  9. threading.Thread(target=lambda: sleep_agent.run(port=6000), daemon=True).start()
  10. time.sleep(1)
  11. mind_agent = create_mind_echo_agent()
  12. def extract_music_info(response_text):
  13. """从智能体响应中提取音乐信息"""
  14. try:
  15. # 尝试查找JSON格式的音乐数据
  16. start_idx = response_text.find('{')
  17. end_idx = response_text.rfind('}') + 1
  18. if start_idx != -1 and end_idx > start_idx:
  19. json_str = response_text[start_idx:end_idx]
  20. data = json.loads(json_str)
  21. if "tracks" in data and data["tracks"]:
  22. # 提取第一首歌曲信息
  23. first_track = data["tracks"][0]
  24. return {
  25. "title": first_track.get("title", "未知歌曲"),
  26. "artist": first_track.get("artist", "未知艺术家"),
  27. "playlist_count": data.get("total_tracks", 0),
  28. "mood": data.get("mood", ""),
  29. "full_data": data
  30. }
  31. except:
  32. pass
  33. # 如果没有找到音乐数据,返回默认信息
  34. return {
  35. "title": "放松音乐推荐",
  36. "artist": "MindEchoAI",
  37. "playlist_count": 3,
  38. "mood": "放松"
  39. }
  40. def chat(user_input: str):
  41. """处理用户输入并返回响应"""
  42. response = mind_agent.run(user_input)
  43. music_info = extract_music_info(response)
  44. # 返回响应文本和音乐信息
  45. return response, music_info
  46. def update_music_player(music_info):
  47. """更新音乐播放器显示"""
  48. if not music_info:
  49. return gr.update(visible=False), gr.update(visible=False)
  50. # 构建播放器显示文本
  51. player_text = f"""
  52. 🎵 **正在播放:{music_info['title']}**
  53. 👤 艺术家:{music_info['artist']}
  54. 💫 心情:{music_info['mood']}
  55. 📊 播放列表:{music_info['playlist_count']} 首歌曲
  56. *注:此为模拟播放器,实际音乐服务需后续集成*
  57. """
  58. return gr.update(value=player_text, visible=True), gr.update(visible=True)
  59. with gr.Blocks(
  60. title="MindEchoAgent · 心境回响",
  61. theme=gr.themes.Soft(),
  62. css="""
  63. .music-player {
  64. border: 1px solid #e0e0e0;
  65. border-radius: 12px;
  66. padding: 16px;
  67. margin-top: 20px;
  68. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  69. color: white;
  70. box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  71. }
  72. .music-player h3 {
  73. margin-top: 0;
  74. color: white;
  75. border-bottom: 1px solid rgba(255,255,255,0.2);
  76. padding-bottom: 8px;
  77. }
  78. .player-controls {
  79. display: flex;
  80. justify-content: center;
  81. gap: 12px;
  82. margin-top: 12px;
  83. }
  84. .player-controls button {
  85. background: rgba(255,255,255,0.2);
  86. border: none;
  87. border-radius: 50%;
  88. width: 44px;
  89. height: 44px;
  90. cursor: pointer;
  91. color: white;
  92. font-size: 18px;
  93. transition: all 0.3s ease;
  94. }
  95. .player-controls button:hover {
  96. background: rgba(255,255,255,0.3);
  97. transform: scale(1.05);
  98. }
  99. """
  100. ) as demo:
  101. # 标题区
  102. gr.Markdown("""
  103. # 🧠🎵 MindEchoAgent · 心境回响
  104. ### 情绪陪伴 + 音乐推荐 + 必要时升级睡眠专家
  105. """)
  106. with gr.Row():
  107. with gr.Column(scale=2):
  108. # 输入区
  109. with gr.Group():
  110. gr.Markdown("### 💭 分享你的心境")
  111. inp = gr.Textbox(
  112. label="",
  113. placeholder="例如:我最近晚上睡不着,很焦虑... 或者 需要一些放松的音乐",
  114. lines=3,
  115. container=False
  116. )
  117. # 发送按钮
  118. btn = gr.Button("✨ 发送", variant="primary", size="lg")
  119. # 响应输出区
  120. with gr.Group():
  121. gr.Markdown("### 🤖 AI 回响")
  122. out = gr.Textbox(
  123. label="",
  124. lines=8,
  125. interactive=False,
  126. container=False,
  127. show_copy_button=True
  128. )
  129. with gr.Column(scale=1):
  130. # 音乐播放器面板
  131. gr.Markdown("### 🎧 音乐推荐")
  132. # 音乐播放器
  133. music_player = gr.HTML(
  134. value="<div style='text-align: center; padding: 20px; color: #666;'>等待推荐音乐...</div>",
  135. visible=False,
  136. elem_classes="music-player"
  137. )
  138. # 播放器控制按钮(隐藏,通过JavaScript控制)
  139. player_controls = gr.HTML("""
  140. <div class="player-controls" style="display: none;">
  141. <button onclick="playerControl('prev')">⏮️</button>
  142. <button onclick="playerControl('play')">▶️</button>
  143. <button onclick="playerControl('pause')">⏸️</button>
  144. <button onclick="playerControl('next')">⏭️</button>
  145. <button onclick="playerControl('volume_up')">🔊</button>
  146. <button onclick="playerControl('volume_down')">🔉</button>
  147. </div>
  148. """, visible=False)
  149. # 交互逻辑
  150. btn.click(
  151. fn=chat,
  152. inputs=inp,
  153. outputs=[out, music_player]
  154. ).then(
  155. fn=update_music_player,
  156. inputs=music_player,
  157. outputs=[music_player, player_controls]
  158. )
  159. # JavaScript控制函数
  160. demo.load(
  161. fn=None,
  162. inputs=None,
  163. outputs=None,
  164. )
  165. # 示例输入
  166. gr.Examples(
  167. examples=[
  168. ["今天工作压力好大,想听点放松的音乐"],
  169. ["心情特别开心,想要有活力的歌"],
  170. ["晚上睡不着,有点焦虑"],
  171. ["需要专注工作的背景音乐"],
  172. ["运动时想听兴奋的音乐"]
  173. ],
  174. inputs=inp,
  175. outputs=[out, music_player],
  176. fn=chat,
  177. cache_examples=True,
  178. label="💡 快速示例"
  179. )
  180. # 页脚
  181. gr.Markdown("---")
  182. gr.Markdown(
  183. """
  184. <div style="text-align: center; color: #888; font-size: 0.9em;">
  185. 🎵 用AI感知情绪,用音乐温暖心灵 · MindEchoAgent v1.0<br>
  186. ⚠️ 音乐播放为模拟演示,实际播放功能需后续集成
  187. </div>
  188. """
  189. )
  190. if __name__ == "__main__":
  191. demo.queue().launch(
  192. server_name="0.0.0.0",
  193. server_port=7860,
  194. share=False,
  195. show_error=True
  196. )