添加了背景图片功能
This commit is contained in:
parent
02eea5bfb4
commit
758785e57b
0
.gitignore
vendored
Normal file
0
.gitignore
vendored
Normal file
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.12
|
||||||
6
.storage/config.json
Normal file
6
.storage/config.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"provider": "DeepSeek",
|
||||||
|
"api_key": "",
|
||||||
|
"base_url": "https://aihubmix.com/v1",
|
||||||
|
"language": "Chinese"
|
||||||
|
}
|
||||||
BIN
__pycache__/config.cpython-312.pyc
Normal file
BIN
__pycache__/config.cpython-312.pyc
Normal file
Binary file not shown.
BIN
agents/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
agents/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
agents/__pycache__/agent_profiles.cpython-312.pyc
Normal file
BIN
agents/__pycache__/agent_profiles.cpython-312.pyc
Normal file
Binary file not shown.
BIN
agents/__pycache__/base_agent.cpython-312.pyc
Normal file
BIN
agents/__pycache__/base_agent.cpython-312.pyc
Normal file
Binary file not shown.
BIN
agents/__pycache__/research_agent.cpython-312.pyc
Normal file
BIN
agents/__pycache__/research_agent.cpython-312.pyc
Normal file
Binary file not shown.
51
app.py
51
app.py
@ -312,6 +312,7 @@ if mode == "Deep Research":
|
|||||||
})
|
})
|
||||||
|
|
||||||
research_context = st.text_area("补充背景 (可选)", placeholder="任何额外的背景信息...", height=80)
|
research_context = st.text_area("补充背景 (可选)", placeholder="任何额外的背景信息...", height=80)
|
||||||
|
research_image = st.file_uploader("上传背景图片(可选)", type=['png', 'jpg', 'jpeg', 'gif'], key='research_bg')
|
||||||
|
|
||||||
start_research_btn = st.button("🚀 开始多模型协作", type="primary", disabled=not research_topic)
|
start_research_btn = st.button("🚀 开始多模型协作", type="primary", disabled=not research_topic)
|
||||||
|
|
||||||
@ -319,6 +320,16 @@ if mode == "Deep Research":
|
|||||||
st.session_state.research_started = True
|
st.session_state.research_started = True
|
||||||
st.session_state.research_output = ""
|
st.session_state.research_output = ""
|
||||||
st.session_state.research_steps_output = []
|
st.session_state.research_steps_output = []
|
||||||
|
# 如果上传了背景图片,保存到 assets
|
||||||
|
research_bg_path = None
|
||||||
|
if research_image:
|
||||||
|
research_bg_path = st.session_state.storage.save_asset(research_image)
|
||||||
|
if research_bg_path:
|
||||||
|
st.success("背景图片已上传并保存")
|
||||||
|
try:
|
||||||
|
st.image(research_image, caption="已上传背景图片预览", use_column_width=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
manager = ResearchManager(
|
manager = ResearchManager(
|
||||||
api_key=api_key,
|
api_key=api_key,
|
||||||
@ -370,16 +381,20 @@ if mode == "Deep Research":
|
|||||||
st.session_state.research_output = final_plan
|
st.session_state.research_output = final_plan
|
||||||
st.success("✅ 综合方案生成完毕")
|
st.success("✅ 综合方案生成完毕")
|
||||||
|
|
||||||
# Auto-save history
|
# Auto-save history (附带背景图片路径如果存在)
|
||||||
st.session_state.storage.save_history(
|
|
||||||
session_type="council",
|
|
||||||
topic=research_topic,
|
|
||||||
content=final_plan,
|
|
||||||
metadata = {
|
metadata = {
|
||||||
"rounds": max_rounds,
|
"rounds": max_rounds,
|
||||||
"experts": [e["name"] for e in experts_config],
|
"experts": [e["name"] for e in experts_config],
|
||||||
"language": output_language
|
"language": output_language
|
||||||
}
|
}
|
||||||
|
if research_bg_path:
|
||||||
|
metadata["background_image"] = research_bg_path
|
||||||
|
|
||||||
|
st.session_state.storage.save_history(
|
||||||
|
session_type="council",
|
||||||
|
topic=research_topic,
|
||||||
|
content=final_plan,
|
||||||
|
metadata=metadata
|
||||||
)
|
)
|
||||||
st.toast("✅ 记录已保存到历史档案")
|
st.toast("✅ 记录已保存到历史档案")
|
||||||
|
|
||||||
@ -436,6 +451,7 @@ elif mode == "Debate Workshop":
|
|||||||
placeholder="提供更多上下文信息,如:\n- 当前状况\n- 已有的资源和限制\n- 相关数据和事实",
|
placeholder="提供更多上下文信息,如:\n- 当前状况\n- 已有的资源和限制\n- 相关数据和事实",
|
||||||
height=100
|
height=100
|
||||||
)
|
)
|
||||||
|
context_image = st.file_uploader("上传背景图片(可选)", type=['png', 'jpg', 'jpeg', 'gif'], key='debate_bg')
|
||||||
context = context if 'context' in dir() else ""
|
context = context if 'context' in dir() else ""
|
||||||
|
|
||||||
with col2:
|
with col2:
|
||||||
@ -554,6 +570,21 @@ elif mode == "Debate Workshop":
|
|||||||
model=ag_model
|
model=ag_model
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 如果在界面上传了背景图片,自动保存到 assets
|
||||||
|
debate_bg_path = None
|
||||||
|
try:
|
||||||
|
if 'context_image' in locals() and context_image:
|
||||||
|
debate_bg_path = st.session_state.storage.save_asset(context_image)
|
||||||
|
if debate_bg_path:
|
||||||
|
st.success("背景图片已上传并保存")
|
||||||
|
try:
|
||||||
|
st.image(context_image, caption="已上传背景图片预览", use_column_width=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
# ignore upload errors but continue
|
||||||
|
debate_bg_path = None
|
||||||
|
|
||||||
debate_manager = DebateManager(llm_client)
|
debate_manager = DebateManager(llm_client)
|
||||||
|
|
||||||
# 配置辩论
|
# 配置辩论
|
||||||
@ -629,7 +660,8 @@ elif mode == "Debate Workshop":
|
|||||||
metadata={
|
metadata={
|
||||||
"rounds": max_rounds,
|
"rounds": max_rounds,
|
||||||
"agents": selected_agents,
|
"agents": selected_agents,
|
||||||
"language": output_language
|
"language": output_language,
|
||||||
|
**({"background_image": debate_bg_path} if debate_bg_path else {})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
st.toast("✅ 记录已保存到历史档案")
|
st.toast("✅ 记录已保存到历史档案")
|
||||||
@ -695,6 +727,13 @@ elif st.session_state.mode == "History Archives":
|
|||||||
st.markdown(f"**时间**: {record['date']} | **类型**: {record['type']}")
|
st.markdown(f"**时间**: {record['date']} | **类型**: {record['type']}")
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
st.markdown(record['content'])
|
st.markdown(record['content'])
|
||||||
|
# 如果历史记录里有背景图片,显示预览
|
||||||
|
try:
|
||||||
|
bg_path = record.get('metadata', {}).get('background_image')
|
||||||
|
if bg_path:
|
||||||
|
st.image(bg_path, caption="关联背景图片", use_column_width=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
st.download_button(
|
st.download_button(
|
||||||
"📥 下载此记录",
|
"📥 下载此记录",
|
||||||
record['content'],
|
record['content'],
|
||||||
|
|||||||
6
main.py
Normal file
6
main.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
def main():
|
||||||
|
print("Hello from multi-agent!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
BIN
orchestrator/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
orchestrator/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
orchestrator/__pycache__/debate_manager.cpython-312.pyc
Normal file
BIN
orchestrator/__pycache__/debate_manager.cpython-312.pyc
Normal file
Binary file not shown.
BIN
orchestrator/__pycache__/research_manager.cpython-312.pyc
Normal file
BIN
orchestrator/__pycache__/research_manager.cpython-312.pyc
Normal file
Binary file not shown.
13
pyproject.toml
Normal file
13
pyproject.toml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[project]
|
||||||
|
name = "multi-agent"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = [
|
||||||
|
"anthropic>=0.75.0",
|
||||||
|
"openai>=2.14.0",
|
||||||
|
"pydantic>=2.12.5",
|
||||||
|
"python-dotenv>=1.2.1",
|
||||||
|
"streamlit>=1.52.2",
|
||||||
|
]
|
||||||
BIN
report/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
report/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
report/__pycache__/report_generator.cpython-312.pyc
Normal file
BIN
report/__pycache__/report_generator.cpython-312.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
utils/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/llm_client.cpython-312.pyc
Normal file
BIN
utils/__pycache__/llm_client.cpython-312.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/storage.cpython-312.pyc
Normal file
BIN
utils/__pycache__/storage.cpython-312.pyc
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Storage Manager - Handle local persistence of configuration and history/reports.
|
Storage Manager - Handle local persistence of configuration, history/reports, and assets.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
@ -11,16 +11,19 @@ from pathlib import Path
|
|||||||
STORAGE_DIR = ".storage"
|
STORAGE_DIR = ".storage"
|
||||||
CONFIG_FILE = "config.json"
|
CONFIG_FILE = "config.json"
|
||||||
HISTORY_DIR = "history"
|
HISTORY_DIR = "history"
|
||||||
|
ASSETS_DIR = "assets"
|
||||||
|
|
||||||
class StorageManager:
|
class StorageManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.root_dir = Path(STORAGE_DIR)
|
self.root_dir = Path(STORAGE_DIR)
|
||||||
self.config_path = self.root_dir / CONFIG_FILE
|
self.config_path = self.root_dir / CONFIG_FILE
|
||||||
self.history_dir = self.root_dir / HISTORY_DIR
|
self.history_dir = self.root_dir / HISTORY_DIR
|
||||||
|
self.assets_dir = self.root_dir / ASSETS_DIR
|
||||||
|
|
||||||
# Ensure directories exist
|
# Ensure directories exist
|
||||||
self.root_dir.mkdir(exist_ok=True)
|
self.root_dir.mkdir(exist_ok=True)
|
||||||
self.history_dir.mkdir(exist_ok=True)
|
self.history_dir.mkdir(exist_ok=True)
|
||||||
|
self.assets_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
def save_config(self, config_data: Dict[str, Any]):
|
def save_config(self, config_data: Dict[str, Any]):
|
||||||
"""Save UI configuration to file"""
|
"""Save UI configuration to file"""
|
||||||
@ -41,6 +44,43 @@ class StorageManager:
|
|||||||
print(f"Error loading config: {e}")
|
print(f"Error loading config: {e}")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
def save_asset(self, uploaded_file) -> str:
|
||||||
|
"""Save an uploaded file (e.g., background image) into assets directory.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uploaded_file: a file-like object (Streamlit UploadedFile) or bytes-like
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The saved file path as string, or None on failure.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Determine filename
|
||||||
|
if hasattr(uploaded_file, 'name'):
|
||||||
|
filename = uploaded_file.name
|
||||||
|
else:
|
||||||
|
filename = f"asset_{int(time.time())}"
|
||||||
|
|
||||||
|
# sanitize
|
||||||
|
safe_name = "".join([c for c in filename if c.isalnum() or c in (' ', '.', '_', '-')]).strip().replace(' ', '_')
|
||||||
|
dest = self.assets_dir / f"{int(time.time())}_{safe_name}"
|
||||||
|
|
||||||
|
# Write bytes
|
||||||
|
with open(dest, 'wb') as out:
|
||||||
|
# Streamlit UploadedFile has getbuffer()
|
||||||
|
if hasattr(uploaded_file, 'getbuffer'):
|
||||||
|
out.write(uploaded_file.getbuffer())
|
||||||
|
else:
|
||||||
|
# try reading
|
||||||
|
data = uploaded_file.read()
|
||||||
|
if isinstance(data, str):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
out.write(data)
|
||||||
|
|
||||||
|
return str(dest)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error saving asset: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
def save_history(self, session_type: str, topic: str, content: str, metadata: Dict[str, Any] = None):
|
def save_history(self, session_type: str, topic: str, content: str, metadata: Dict[str, Any] = None):
|
||||||
"""
|
"""
|
||||||
Save a session report/history
|
Save a session report/history
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user