Web app bug fix.
This commit is contained in:
@@ -20,13 +20,25 @@ def main():
|
|||||||
"""主函数"""
|
"""主函数"""
|
||||||
st.set_page_config(
|
st.set_page_config(
|
||||||
page_title="Insight Agent",
|
page_title="Insight Agent",
|
||||||
page_icon="",
|
page_icon="🔍",
|
||||||
layout="wide"
|
layout="wide"
|
||||||
)
|
)
|
||||||
|
|
||||||
st.title("Insight Agent")
|
st.title("Insight Agent")
|
||||||
st.markdown("私有舆情数据库深度分析AI代理")
|
st.markdown("私有舆情数据库深度分析AI代理")
|
||||||
|
|
||||||
|
# 检查URL参数
|
||||||
|
try:
|
||||||
|
# 尝试使用新版本的query_params
|
||||||
|
query_params = st.query_params
|
||||||
|
auto_query = query_params.get('query', '')
|
||||||
|
auto_search = query_params.get('auto_search', 'false').lower() == 'true'
|
||||||
|
except AttributeError:
|
||||||
|
# 兼容旧版本
|
||||||
|
query_params = st.experimental_get_query_params()
|
||||||
|
auto_query = query_params.get('query', [''])[0]
|
||||||
|
auto_search = query_params.get('auto_search', ['false'])[0].lower() == 'true'
|
||||||
|
|
||||||
# ----- 配置被硬编码 -----
|
# ----- 配置被硬编码 -----
|
||||||
# 强制使用 Kimi
|
# 强制使用 Kimi
|
||||||
llm_provider = "kimi"
|
llm_provider = "kimi"
|
||||||
@@ -40,8 +52,13 @@ def main():
|
|||||||
|
|
||||||
with col1:
|
with col1:
|
||||||
st.header("研究查询")
|
st.header("研究查询")
|
||||||
|
|
||||||
|
# 如果有自动查询,使用它作为默认值
|
||||||
|
default_query = auto_query if auto_query else ""
|
||||||
|
|
||||||
query = st.text_area(
|
query = st.text_area(
|
||||||
"请输入您要研究的问题",
|
"请输入您要研究的问题",
|
||||||
|
value=default_query,
|
||||||
placeholder="例如:2025年人工智能发展趋势",
|
placeholder="例如:2025年人工智能发展趋势",
|
||||||
height=100
|
height=100
|
||||||
)
|
)
|
||||||
@@ -61,6 +78,12 @@ def main():
|
|||||||
with col2_btn:
|
with col2_btn:
|
||||||
start_research = st.button("开始研究", type="primary", use_container_width=True)
|
start_research = st.button("开始研究", type="primary", use_container_width=True)
|
||||||
|
|
||||||
|
# 自动搜索逻辑
|
||||||
|
if auto_search and auto_query and 'auto_search_executed' not in st.session_state:
|
||||||
|
st.session_state.auto_search_executed = True
|
||||||
|
start_research = True
|
||||||
|
query = auto_query
|
||||||
|
|
||||||
# 验证配置
|
# 验证配置
|
||||||
if start_research:
|
if start_research:
|
||||||
if not query.strip():
|
if not query.strip():
|
||||||
|
|||||||
@@ -20,13 +20,25 @@ def main():
|
|||||||
"""主函数"""
|
"""主函数"""
|
||||||
st.set_page_config(
|
st.set_page_config(
|
||||||
page_title="Media Agent",
|
page_title="Media Agent",
|
||||||
page_icon="",
|
page_icon="🔍",
|
||||||
layout="wide"
|
layout="wide"
|
||||||
)
|
)
|
||||||
|
|
||||||
st.title("Media Agent")
|
st.title("Media Agent")
|
||||||
st.markdown("具备强大多模态能力的AI代理")
|
st.markdown("具备强大多模态能力的AI代理")
|
||||||
|
|
||||||
|
# 检查URL参数
|
||||||
|
try:
|
||||||
|
# 尝试使用新版本的query_params
|
||||||
|
query_params = st.query_params
|
||||||
|
auto_query = query_params.get('query', '')
|
||||||
|
auto_search = query_params.get('auto_search', 'false').lower() == 'true'
|
||||||
|
except AttributeError:
|
||||||
|
# 兼容旧版本
|
||||||
|
query_params = st.experimental_get_query_params()
|
||||||
|
auto_query = query_params.get('query', [''])[0]
|
||||||
|
auto_search = query_params.get('auto_search', ['false'])[0].lower() == 'true'
|
||||||
|
|
||||||
# ----- 配置被硬编码 -----
|
# ----- 配置被硬编码 -----
|
||||||
# 强制使用 Gemini
|
# 强制使用 Gemini
|
||||||
llm_provider = "gemini"
|
llm_provider = "gemini"
|
||||||
@@ -40,8 +52,13 @@ def main():
|
|||||||
|
|
||||||
with col1:
|
with col1:
|
||||||
st.header("研究查询")
|
st.header("研究查询")
|
||||||
|
|
||||||
|
# 如果有自动查询,使用它作为默认值
|
||||||
|
default_query = auto_query if auto_query else ""
|
||||||
|
|
||||||
query = st.text_area(
|
query = st.text_area(
|
||||||
"请输入您要研究的问题",
|
"请输入您要研究的问题",
|
||||||
|
value=default_query,
|
||||||
placeholder="例如:2025年人工智能发展趋势",
|
placeholder="例如:2025年人工智能发展趋势",
|
||||||
height=100
|
height=100
|
||||||
)
|
)
|
||||||
@@ -61,6 +78,12 @@ def main():
|
|||||||
with col2_btn:
|
with col2_btn:
|
||||||
start_research = st.button("开始研究", type="primary", use_container_width=True)
|
start_research = st.button("开始研究", type="primary", use_container_width=True)
|
||||||
|
|
||||||
|
# 自动搜索逻辑
|
||||||
|
if auto_search and auto_query and 'auto_search_executed' not in st.session_state:
|
||||||
|
st.session_state.auto_search_executed = True
|
||||||
|
start_research = True
|
||||||
|
query = auto_query
|
||||||
|
|
||||||
# 验证配置
|
# 验证配置
|
||||||
if start_research:
|
if start_research:
|
||||||
if not query.strip():
|
if not query.strip():
|
||||||
|
|||||||
@@ -27,6 +27,18 @@ def main():
|
|||||||
st.title("Query Agent")
|
st.title("Query Agent")
|
||||||
st.markdown("具备强大网页搜索能力的AI代理")
|
st.markdown("具备强大网页搜索能力的AI代理")
|
||||||
|
|
||||||
|
# 检查URL参数
|
||||||
|
try:
|
||||||
|
# 尝试使用新版本的query_params
|
||||||
|
query_params = st.query_params
|
||||||
|
auto_query = query_params.get('query', '')
|
||||||
|
auto_search = query_params.get('auto_search', 'false').lower() == 'true'
|
||||||
|
except AttributeError:
|
||||||
|
# 兼容旧版本
|
||||||
|
query_params = st.experimental_get_query_params()
|
||||||
|
auto_query = query_params.get('query', [''])[0]
|
||||||
|
auto_search = query_params.get('auto_search', ['false'])[0].lower() == 'true'
|
||||||
|
|
||||||
# ----- 配置被硬编码 -----
|
# ----- 配置被硬编码 -----
|
||||||
# 强制使用 DeepSeek
|
# 强制使用 DeepSeek
|
||||||
llm_provider = "deepseek"
|
llm_provider = "deepseek"
|
||||||
@@ -40,8 +52,13 @@ def main():
|
|||||||
|
|
||||||
with col1:
|
with col1:
|
||||||
st.header("研究查询")
|
st.header("研究查询")
|
||||||
|
|
||||||
|
# 如果有自动查询,使用它作为默认值
|
||||||
|
default_query = auto_query if auto_query else ""
|
||||||
|
|
||||||
query = st.text_area(
|
query = st.text_area(
|
||||||
"请输入您要研究的问题",
|
"请输入您要研究的问题",
|
||||||
|
value=default_query,
|
||||||
placeholder="例如:2025年人工智能发展趋势",
|
placeholder="例如:2025年人工智能发展趋势",
|
||||||
height=100
|
height=100
|
||||||
)
|
)
|
||||||
@@ -61,6 +78,12 @@ def main():
|
|||||||
with col2_btn:
|
with col2_btn:
|
||||||
start_research = st.button("开始研究", type="primary", use_container_width=True)
|
start_research = st.button("开始研究", type="primary", use_container_width=True)
|
||||||
|
|
||||||
|
# 自动搜索逻辑
|
||||||
|
if auto_search and auto_query and 'auto_search_executed' not in st.session_state:
|
||||||
|
st.session_state.auto_search_executed = True
|
||||||
|
start_research = True
|
||||||
|
query = auto_query
|
||||||
|
|
||||||
# 验证配置
|
# 验证配置
|
||||||
if start_research:
|
if start_research:
|
||||||
if not query.strip():
|
if not query.strip():
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ def start_app(app_name):
|
|||||||
processes[app_name]['port']
|
processes[app_name]['port']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
# 等待应用启动
|
# 等待应用启动
|
||||||
startup_success, startup_message = wait_for_app_startup(app_name, 15)
|
startup_success, startup_message = wait_for_app_startup(app_name, 15)
|
||||||
|
|||||||
+122
-28
@@ -106,6 +106,7 @@
|
|||||||
.embedded-content {
|
.embedded-content {
|
||||||
height: calc(100% - 60px);
|
height: calc(100% - 60px);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 控制台输出区域 */
|
/* 控制台输出区域 */
|
||||||
@@ -332,6 +333,11 @@
|
|||||||
setInterval(updateTime, 1000);
|
setInterval(updateTime, 1000);
|
||||||
checkStatus();
|
checkStatus();
|
||||||
setInterval(checkStatus, 5000);
|
setInterval(checkStatus, 5000);
|
||||||
|
|
||||||
|
// 延迟预加载iframe以确保应用启动完成
|
||||||
|
setTimeout(() => {
|
||||||
|
preloadIframes();
|
||||||
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Socket.IO连接
|
// Socket.IO连接
|
||||||
@@ -389,29 +395,49 @@
|
|||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
button.innerHTML = '<span class="loading"></span> 搜索中...';
|
button.innerHTML = '<span class="loading"></span> 搜索中...';
|
||||||
|
|
||||||
fetch('/api/search', {
|
// 确保所有iframe已初始化
|
||||||
method: 'POST',
|
if (!iframesInitialized) {
|
||||||
headers: {
|
preloadIframes();
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ query: query })
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
showMessage('搜索请求已发送到所有运行中的应用', 'success');
|
|
||||||
} else {
|
|
||||||
showMessage(data.message || '搜索失败', 'error');
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch(error => {
|
// 向所有运行中的应用发送搜索请求(通过新窗口方式避免刷新现有iframe)
|
||||||
console.error('搜索错误:', error);
|
let totalRunning = 0;
|
||||||
showMessage('搜索请求失败', 'error');
|
const ports = { insight: 8501, media: 8502, query: 8503 };
|
||||||
})
|
|
||||||
.finally(() => {
|
Object.keys(appStatus).forEach(app => {
|
||||||
|
if (appStatus[app] === 'running') {
|
||||||
|
totalRunning++;
|
||||||
|
|
||||||
|
// 为每个应用创建一个临时的搜索iframe,避免干扰主iframe
|
||||||
|
const searchIframe = document.createElement('iframe');
|
||||||
|
searchIframe.style.display = 'none';
|
||||||
|
searchIframe.style.position = 'absolute';
|
||||||
|
searchIframe.style.top = '-9999px';
|
||||||
|
|
||||||
|
const searchUrl = `http://localhost:${ports[app]}?query=${encodeURIComponent(query)}&auto_search=true`;
|
||||||
|
console.log(`向 ${app} 发送搜索请求: ${searchUrl}`);
|
||||||
|
|
||||||
|
searchIframe.src = searchUrl;
|
||||||
|
document.body.appendChild(searchIframe);
|
||||||
|
|
||||||
|
// 几秒后移除临时iframe
|
||||||
|
setTimeout(() => {
|
||||||
|
if (searchIframe.parentNode) {
|
||||||
|
searchIframe.parentNode.removeChild(searchIframe);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (totalRunning === 0) {
|
||||||
button.disabled = false;
|
button.disabled = false;
|
||||||
button.innerHTML = '搜索';
|
button.innerHTML = '搜索';
|
||||||
});
|
showMessage('没有运行中的应用,无法执行搜索', 'error');
|
||||||
|
} else {
|
||||||
|
button.disabled = false;
|
||||||
|
button.innerHTML = '搜索';
|
||||||
|
showMessage(`已向 ${totalRunning} 个应用发送搜索请求`, 'success');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换应用
|
// 切换应用
|
||||||
@@ -472,6 +498,40 @@
|
|||||||
consoleOutput.scrollTop = consoleOutput.scrollHeight;
|
consoleOutput.scrollTop = consoleOutput.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预加载的iframe存储
|
||||||
|
let preloadedIframes = {};
|
||||||
|
let iframesInitialized = false;
|
||||||
|
|
||||||
|
// 预加载所有iframe(只执行一次)
|
||||||
|
function preloadIframes() {
|
||||||
|
if (iframesInitialized) return;
|
||||||
|
|
||||||
|
const ports = { insight: 8501, media: 8502, query: 8503 };
|
||||||
|
const content = document.getElementById('embeddedContent');
|
||||||
|
|
||||||
|
for (const [app, port] of Object.entries(ports)) {
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.src = `http://localhost:${port}`;
|
||||||
|
iframe.style.width = '100%';
|
||||||
|
iframe.style.height = '100%';
|
||||||
|
iframe.style.border = 'none';
|
||||||
|
iframe.style.position = 'absolute';
|
||||||
|
iframe.style.top = '0';
|
||||||
|
iframe.style.left = '0';
|
||||||
|
iframe.style.display = 'none';
|
||||||
|
iframe.id = `iframe-${app}`;
|
||||||
|
|
||||||
|
// 直接添加到content区域
|
||||||
|
content.appendChild(iframe);
|
||||||
|
preloadedIframes[app] = iframe;
|
||||||
|
|
||||||
|
console.log(`预加载 ${app} 应用完成`);
|
||||||
|
}
|
||||||
|
|
||||||
|
iframesInitialized = true;
|
||||||
|
console.log('所有iframe预加载完成,准备进行无缝切换');
|
||||||
|
}
|
||||||
|
|
||||||
// 更新嵌入页面
|
// 更新嵌入页面
|
||||||
function updateEmbeddedPage(app) {
|
function updateEmbeddedPage(app) {
|
||||||
const header = document.getElementById('embeddedHeader');
|
const header = document.getElementById('embeddedHeader');
|
||||||
@@ -485,16 +545,47 @@
|
|||||||
|
|
||||||
header.textContent = appNames[app] || app;
|
header.textContent = appNames[app] || app;
|
||||||
|
|
||||||
// 如果应用正在运行,显示iframe
|
// 如果应用正在运行,显示对应的iframe
|
||||||
if (appStatus[app] === 'running') {
|
if (appStatus[app] === 'running') {
|
||||||
const ports = { insight: 8501, media: 8502, query: 8503 };
|
// 确保iframe已初始化
|
||||||
content.innerHTML = `<iframe src="http://localhost:${ports[app]}" style="width: 100%; height: 100%; border: none;"></iframe>`;
|
if (!iframesInitialized) {
|
||||||
|
preloadIframes();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐藏所有iframe
|
||||||
|
Object.values(preloadedIframes).forEach(iframe => {
|
||||||
|
iframe.style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 移除占位符
|
||||||
|
const placeholder = content.querySelector('.status-placeholder');
|
||||||
|
if (placeholder) {
|
||||||
|
placeholder.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示当前应用的iframe
|
||||||
|
if (preloadedIframes[app]) {
|
||||||
|
preloadedIframes[app].style.display = 'block';
|
||||||
|
console.log(`切换到 ${app} 应用 - 无刷新切换`);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
content.innerHTML = `
|
// 隐藏所有iframe
|
||||||
<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: #666; flex-direction: column;">
|
Object.values(preloadedIframes).forEach(iframe => {
|
||||||
|
iframe.style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示状态信息
|
||||||
|
let placeholder = content.querySelector('.status-placeholder');
|
||||||
|
if (!placeholder) {
|
||||||
|
placeholder = document.createElement('div');
|
||||||
|
placeholder.className = 'status-placeholder';
|
||||||
|
placeholder.style.cssText = 'display: flex; align-items: center; justify-content: center; height: 100%; color: #666; flex-direction: column; position: absolute; top: 0; left: 0; width: 100%;';
|
||||||
|
content.appendChild(placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
placeholder.innerHTML = `
|
||||||
<div style="margin-bottom: 10px;">${appNames[app]} 未运行</div>
|
<div style="margin-bottom: 10px;">${appNames[app]} 未运行</div>
|
||||||
<div style="font-size: 12px;">状态: ${appStatus[app]}</div>
|
<div style="font-size: 12px;">状态: ${appStatus[app]}</div>
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,10 +605,13 @@
|
|||||||
// 更新应用状态
|
// 更新应用状态
|
||||||
function updateAppStatus(data) {
|
function updateAppStatus(data) {
|
||||||
for (const [app, info] of Object.entries(data)) {
|
for (const [app, info] of Object.entries(data)) {
|
||||||
appStatus[app] = info.status;
|
// 适配实际的API格式:{app: {status: string, port: int, output_lines: int}}
|
||||||
|
const status = info.status === 'running' ? 'running' : 'stopped';
|
||||||
|
appStatus[app] = status;
|
||||||
|
|
||||||
const indicator = document.getElementById(`status-${app}`);
|
const indicator = document.getElementById(`status-${app}`);
|
||||||
if (indicator) {
|
if (indicator) {
|
||||||
indicator.className = `status-indicator ${info.status}`;
|
indicator.className = `status-indicator ${status}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user