feat: 添加子图API端点和前端测试面板,包含确定取消继续交互
Some checks failed
构建并部署 AI Agent 服务 / deploy (push) Failing after 6m3s

This commit is contained in:
2026-04-25 19:38:22 +08:00
parent 96dc01f8c2
commit 3bc9b19bab
4 changed files with 524 additions and 0 deletions

View File

@@ -379,6 +379,70 @@ class APIClient:
error(f"请求审核异常: {e}")
return ""
# ==================== 子图专用 API ====================
def call_dictionary_subgraph(self, action: str, query: str = "", user_id: str = "default") -> dict:
"""调用词典子图"""
try:
resp = requests.get(
f"{self.base_url}/subgraph/dictionary/{action}",
params={"query": query, "user_id": user_id},
timeout=10
)
if resp.status_code == 200:
return resp.json()
else:
warning(f"调用词典子图失败: HTTP {resp.status_code}")
return {"success": False, "error": "HTTP错误"}
except Exception as e:
error(f"调用词典子图异常: {e}")
return {"success": False, "error": str(e)}
def call_news_subgraph(self, action: str, query: str = "", user_id: str = "default") -> dict:
"""调用资讯子图"""
try:
resp = requests.get(
f"{self.base_url}/subgraph/news/{action}",
params={"query": query, "user_id": user_id},
timeout=10
)
if resp.status_code == 200:
return resp.json()
else:
warning(f"调用资讯子图失败: HTTP {resp.status_code}")
return {"success": False, "error": "HTTP错误"}
except Exception as e:
error(f"调用资讯子图异常: {e}")
return {"success": False, "error": str(e)}
def call_contact_subgraph(self, action: str, query: str = "", user_id: str = "default") -> dict:
"""调用通讯录子图"""
try:
resp = requests.get(
f"{self.base_url}/subgraph/contact/{action}",
params={"query": query, "user_id": user_id},
timeout=10
)
if resp.status_code == 200:
return resp.json()
else:
warning(f"调用通讯录子图失败: HTTP {resp.status_code}")
return {"success": False, "error": "HTTP错误"}
except Exception as e:
error(f"调用通讯录子图异常: {e}")
return {"success": False, "error": str(e)}
def get_subgraph_help(self) -> dict:
"""获取子图 API 使用帮助"""
try:
resp = requests.get(f"{self.base_url}/subgraph/help", timeout=5)
if resp.status_code == 200:
return resp.json()
else:
return {}
except Exception as e:
return {}
# 全局 API 客户端实例(单例模式)
api_client = APIClient()

View File

@@ -0,0 +1,222 @@
"""
子图测试面板组件
包含词典、资讯、通讯录三个子图的测试界面
使用确定取消继续交互
"""
import streamlit as st
from api_client import api_client
from state import AppState
def render_subgraph_panel():
"""渲染子图测试面板"""
st.markdown("## 🔧 子图测试面板")
with st.expander("📚 词典子图", expanded=False):
_render_dictionary_panel()
with st.expander("📰 资讯子图", expanded=False):
_render_news_panel()
with st.expander("📇 通讯录子图", expanded=False):
_render_contact_panel()
def _render_dictionary_panel():
"""渲染词典子图测试面板"""
# 会话状态管理
if "dict_action" not in st.session_state:
st.session_state.dict_action = "auto"
if "dict_query" not in st.session_state:
st.session_state.dict_query = ""
if "dict_result" not in st.session_state:
st.session_state.dict_result = None
if "dict_confirm" not in st.session_state:
st.session_state.dict_confirm = False
# 选择 Action
action_col1, action_col2 = st.columns([1, 2])
with action_col1:
action = st.selectbox(
"操作",
options=["auto", "query", "translate", "daily", "extract"],
index=["auto", "query", "translate", "daily", "extract"].index(st.session_state.dict_action),
key="dict_action_selector"
)
with action_col2:
query = st.text_input("查询内容", value=st.session_state.dict_query, key="dict_query_input")
# 按钮行
btn_col1, btn_col2, btn_col3 = st.columns([1, 1, 1])
with btn_col1:
if st.button("▶️ 运行", key="dict_run", use_container_width=True):
st.session_state.dict_action = action
st.session_state.dict_query = query
with st.spinner("调用子图中..."):
result = api_client.call_dictionary_subgraph(action, query)
st.session_state.dict_result = result
st.session_state.dict_confirm = False
st.rerun()
# 显示结果
if st.session_state.dict_result:
result = st.session_state.dict_result
if result.get("success"):
st.success("✅ 调用成功")
st.markdown("### 结果")
st.markdown(result.get("result", ""))
# 确定/取消/继续按钮
confirm_col1, confirm_col2, confirm_col3 = st.columns([1, 1, 1])
with confirm_col1:
if st.button("✅ 确定", key="dict_confirm", use_container_width=True):
st.session_state.dict_confirm = True
st.info("已确认结果")
with confirm_col2:
if st.button("❌ 取消", key="dict_cancel", use_container_width=True):
st.session_state.dict_result = None
st.rerun()
with confirm_col3:
if st.button("⏭️ 继续", key="dict_continue", use_container_width=True):
st.session_state.dict_confirm = True
st.info("已继续")
# 显示原始数据(可选)
with st.expander("🔍 原始数据", expanded=False):
st.json(result.get("raw_data", {}))
else:
st.error(f"❌ 调用失败: {result.get('error')}")
def _render_news_panel():
"""渲染资讯子图测试面板"""
# 会话状态管理
if "news_action" not in st.session_state:
st.session_state.news_action = "auto"
if "news_query" not in st.session_state:
st.session_state.news_query = ""
if "news_result" not in st.session_state:
st.session_state.news_result = None
if "news_confirm" not in st.session_state:
st.session_state.news_confirm = False
# 选择 Action
action_col1, action_col2 = st.columns([1, 2])
with action_col1:
action = st.selectbox(
"操作",
options=["auto", "query", "analyze", "keywords", "report"],
index=["auto", "query", "analyze", "keywords", "report"].index(st.session_state.news_action),
key="news_action_selector"
)
with action_col2:
query = st.text_input("查询内容/URL", value=st.session_state.news_query, key="news_query_input")
# 按钮行
btn_col1, btn_col2, btn_col3 = st.columns([1, 1, 1])
with btn_col1:
if st.button("▶️ 运行", key="news_run", use_container_width=True):
st.session_state.news_action = action
st.session_state.news_query = query
with st.spinner("调用子图中..."):
result = api_client.call_news_subgraph(action, query)
st.session_state.news_result = result
st.session_state.news_confirm = False
st.rerun()
# 显示结果
if st.session_state.news_result:
result = st.session_state.news_result
if result.get("success"):
st.success("✅ 调用成功")
st.markdown("### 结果")
st.markdown(result.get("result", ""))
# 确定/取消/继续按钮
confirm_col1, confirm_col2, confirm_col3 = st.columns([1, 1, 1])
with confirm_col1:
if st.button("✅ 确定", key="news_confirm", use_container_width=True):
st.session_state.news_confirm = True
st.info("已确认结果")
with confirm_col2:
if st.button("❌ 取消", key="news_cancel", use_container_width=True):
st.session_state.news_result = None
st.rerun()
with confirm_col3:
if st.button("⏭️ 继续", key="news_continue", use_container_width=True):
st.session_state.news_confirm = True
st.info("已继续")
# 显示原始数据(可选)
with st.expander("🔍 原始数据", expanded=False):
st.json(result.get("raw_data", {}))
else:
st.error(f"❌ 调用失败: {result.get('error')}")
def _render_contact_panel():
"""渲染通讯录子图测试面板"""
# 会话状态管理
if "contact_action" not in st.session_state:
st.session_state.contact_action = "auto"
if "contact_query" not in st.session_state:
st.session_state.contact_query = ""
if "contact_result" not in st.session_state:
st.session_state.contact_result = None
if "contact_confirm" not in st.session_state:
st.session_state.contact_confirm = False
# 选择 Action
action_col1, action_col2 = st.columns([1, 2])
with action_col1:
action = st.selectbox(
"操作",
options=["auto", "list", "add", "emails", "draft", "sniff"],
index=["auto", "list", "add", "emails", "draft", "sniff"].index(st.session_state.contact_action),
key="contact_action_selector"
)
with action_col2:
query = st.text_input("查询内容", value=st.session_state.contact_query, key="contact_query_input")
# 按钮行
btn_col1, btn_col2, btn_col3 = st.columns([1, 1, 1])
with btn_col1:
if st.button("▶️ 运行", key="contact_run", use_container_width=True):
st.session_state.contact_action = action
st.session_state.contact_query = query
with st.spinner("调用子图中..."):
result = api_client.call_contact_subgraph(action, query)
st.session_state.contact_result = result
st.session_state.contact_confirm = False
st.rerun()
# 显示结果
if st.session_state.contact_result:
result = st.session_state.contact_result
if result.get("success"):
st.success("✅ 调用成功")
st.markdown("### 结果")
st.markdown(result.get("result", ""))
# 确定/取消/继续按钮
confirm_col1, confirm_col2, confirm_col3 = st.columns([1, 1, 1])
with confirm_col1:
if st.button("✅ 确定", key="contact_confirm", use_container_width=True):
st.session_state.contact_confirm = True
st.info("已确认结果")
with confirm_col2:
if st.button("❌ 取消", key="contact_cancel", use_container_width=True):
st.session_state.contact_result = None
st.rerun()
with confirm_col3:
if st.button("⏭️ 继续", key="contact_continue", use_container_width=True):
st.session_state.contact_confirm = True
st.info("已继续")
# 显示原始数据(可选)
with st.expander("🔍 原始数据", expanded=False):
st.json(result.get("raw_data", {}))
else:
st.error(f"❌ 调用失败: {result.get('error')}")

View File

@@ -19,12 +19,14 @@ if __name__ == '__main__':
from components.sidebar import render_sidebar
from components.chat_area import render_chat_area
from components.info_panel import render_info_panel
from components.subgraph_panel import render_subgraph_panel
else:
from .config import config
from .state import AppState
from .components.sidebar import render_sidebar
from .components.chat_area import render_chat_area
from .components.info_panel import render_info_panel
from .components.subgraph_panel import render_subgraph_panel
# =============================================================================
@@ -127,6 +129,10 @@ def main():
# 中间主区域:全宽的聊天区域
render_chat_area()
# 底部:子图测试面板
st.divider()
render_subgraph_panel()
if __name__ == "__main__":