update
This commit is contained in:
parent
8679916ced
commit
e0f2308e4d
|
|
@ -334,6 +334,16 @@ class SimulationManager:
|
|||
elif state.enable_twitter:
|
||||
realtime_output_path = os.path.join(sim_dir, "twitter_profiles.csv")
|
||||
realtime_platform = "twitter"
|
||||
|
||||
# Nền tảng dùng cho metadata cost.
|
||||
if state.enable_twitter and state.enable_reddit:
|
||||
runtime_platform = "parallel"
|
||||
elif state.enable_twitter:
|
||||
runtime_platform = "twitter"
|
||||
elif state.enable_reddit:
|
||||
runtime_platform = "reddit"
|
||||
else:
|
||||
runtime_platform = None
|
||||
|
||||
profiles = generator.generate_profiles_from_entities(
|
||||
entities=filtered.entities,
|
||||
|
|
@ -343,6 +353,7 @@ class SimulationManager:
|
|||
parallel_count=parallel_profile_count, # Số dòng luồng Async
|
||||
realtime_output_path=realtime_output_path, # Lưu log thời gian thực
|
||||
output_platform=realtime_platform, # Đuôi file xuất
|
||||
metadata_platform=runtime_platform,
|
||||
simulation_id=simulation_id,
|
||||
project_id=state.project_id,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class TextProcessor:
|
|||
# Xoá các dòng trống liên tiếp (Chỉ giữ lại tối đa 2 lần xuống dòng liên tiếp)
|
||||
text = re.sub(r'\n{3,}', '\n\n', text)
|
||||
|
||||
# 移除行首行尾空白
|
||||
# Loại bỏ khoảng trắng đầu và cuối
|
||||
lines = [line.strip() for line in text.split('\n')]
|
||||
text = '\n'.join(lines)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,36 @@ def _build_metadata(model: str) -> Dict[str, Any]:
|
|||
return metadata
|
||||
|
||||
|
||||
def _normalize_messages_for_qwen(messages: Any) -> Any:
|
||||
"""Ensure Qwen-compatible ordering: a single system message at index 0."""
|
||||
if not isinstance(messages, list):
|
||||
return messages
|
||||
|
||||
if not messages:
|
||||
return messages
|
||||
|
||||
system_contents = []
|
||||
non_system_messages = []
|
||||
|
||||
for item in messages:
|
||||
if isinstance(item, dict) and str(item.get("role", "")).lower() == "system":
|
||||
content = item.get("content")
|
||||
if content is not None and str(content).strip():
|
||||
system_contents.append(str(content))
|
||||
continue
|
||||
non_system_messages.append(item)
|
||||
|
||||
# No system messages detected, keep original payload.
|
||||
if not system_contents:
|
||||
return messages
|
||||
|
||||
merged_system = {
|
||||
"role": "system",
|
||||
"content": "\n\n".join(system_contents),
|
||||
}
|
||||
return [merged_system] + non_system_messages
|
||||
|
||||
|
||||
def install_openai_cost_patch(
|
||||
*,
|
||||
simulation_id: Optional[str],
|
||||
|
|
@ -58,6 +88,9 @@ def install_openai_cost_patch(
|
|||
|
||||
def sync_create_wrapper(self, *args, **kwargs):
|
||||
model = kwargs.get("model", "unknown_model")
|
||||
if "qwen" in str(model).lower() and "messages" in kwargs:
|
||||
kwargs = dict(kwargs)
|
||||
kwargs["messages"] = _normalize_messages_for_qwen(kwargs.get("messages"))
|
||||
response = original_sync_create(self, *args, **kwargs)
|
||||
try:
|
||||
record_llm_cost(
|
||||
|
|
@ -71,6 +104,9 @@ def install_openai_cost_patch(
|
|||
|
||||
async def async_create_wrapper(self, *args, **kwargs):
|
||||
model = kwargs.get("model", "unknown_model")
|
||||
if "qwen" in str(model).lower() and "messages" in kwargs:
|
||||
kwargs = dict(kwargs)
|
||||
kwargs["messages"] = _normalize_messages_for_qwen(kwargs.get("messages"))
|
||||
response = await original_async_create(self, *args, **kwargs)
|
||||
try:
|
||||
record_llm_cost(
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ class ParallelIPCHandler:
|
|||
"""
|
||||
# Nếu có chỉ định nền tảng, chỉ phỏng vấn trên nền tảng đó
|
||||
if platform in ("twitter", "reddit"):
|
||||
result = await self._interview_single_platform(agent_id, prompt, platform)
|
||||
result = await self._interview_single_platform(agent_id, prompt, platform)
|
||||
|
||||
if "error" in result:
|
||||
self.send_response(command_id, "failed", error=result["error"])
|
||||
|
|
@ -996,11 +996,27 @@ def create_model(config: Dict[str, Any], use_boost: bool = False):
|
|||
config: Dictionary cấu hình mô phỏng
|
||||
use_boost: Có dùng cấu hình LLM tăng tốc hay không (nếu khả dụng)
|
||||
"""
|
||||
# Kiểm tra có cấu hình tăng tốc không
|
||||
def _is_placeholder(value: str) -> bool:
|
||||
v = (value or "").strip().lower()
|
||||
return v in {"your_api_key_here", "your_base_url_here", "your_model_name_here"}
|
||||
|
||||
def _is_http_url(value: str) -> bool:
|
||||
v = (value or "").strip().lower()
|
||||
return v.startswith("http://") or v.startswith("https://")
|
||||
|
||||
# Kiểm tra có cấu hình tăng tốc hợp lệ không
|
||||
boost_api_key = os.environ.get("LLM_BOOST_API_KEY", "")
|
||||
boost_base_url = os.environ.get("LLM_BOOST_BASE_URL", "")
|
||||
boost_model = os.environ.get("LLM_BOOST_MODEL_NAME", "")
|
||||
has_boost_config = bool(boost_api_key)
|
||||
has_boost_config = (
|
||||
bool(boost_api_key.strip())
|
||||
and bool(boost_model.strip())
|
||||
and bool(boost_base_url.strip())
|
||||
and not _is_placeholder(boost_api_key)
|
||||
and not _is_placeholder(boost_base_url)
|
||||
and not _is_placeholder(boost_model)
|
||||
and _is_http_url(boost_base_url)
|
||||
)
|
||||
|
||||
# Chọn LLM theo tham số và trạng thái cấu hình
|
||||
if use_boost and has_boost_config:
|
||||
|
|
@ -1011,6 +1027,8 @@ def create_model(config: Dict[str, Any], use_boost: bool = False):
|
|||
config_label = "[Boost LLM]"
|
||||
else:
|
||||
# Dùng cấu hình chung
|
||||
if use_boost and not has_boost_config:
|
||||
print("[Boost LLM] Invalid or placeholder boost config, fallback to [General LLM].")
|
||||
llm_api_key = os.environ.get("LLM_API_KEY", "")
|
||||
llm_base_url = os.environ.get("LLM_BASE_URL", "")
|
||||
llm_model = os.environ.get("LLM_MODEL_NAME", "")
|
||||
|
|
@ -1028,6 +1046,10 @@ def create_model(config: Dict[str, Any], use_boost: bool = False):
|
|||
raise ValueError("Missing API key config. Please set LLM_API_KEY in the project root .env file")
|
||||
|
||||
if llm_base_url:
|
||||
if not _is_http_url(llm_base_url):
|
||||
raise ValueError(
|
||||
f"Invalid LLM base URL: {llm_base_url}. It must start with http:// or https://"
|
||||
)
|
||||
os.environ["OPENAI_API_BASE_URL"] = llm_base_url
|
||||
|
||||
print(f"{config_label} model={llm_model}, base_url={llm_base_url[:40] if llm_base_url else 'default'}...")
|
||||
|
|
|
|||
|
|
@ -862,7 +862,7 @@ const parseInterview = (text) => {
|
|||
const quotesText = quotesMatch[1]
|
||||
// Prioritize matching > "text" format
|
||||
let quoteMatches = quotesText.match(/> "([^"]+)"/g)
|
||||
// Backtrack: Matches > "text" or > \u201Ctext\u201D (Chinese quotation marks)
|
||||
// Backtrack: Matches > "text" or > \u201Ctext\u201D (Vietnamese quotation marks)
|
||||
if (!quoteMatches) {
|
||||
quoteMatches = quotesText.match(/> [\u201C""]([^\u201D""]+)[\u201D""]/g)
|
||||
}
|
||||
|
|
@ -2089,9 +2089,9 @@ const extractFinalContent = (response) => {
|
|||
}
|
||||
|
||||
// Try to find the content after "Final Answer:"
|
||||
const chineseFinalMatch = response.match(/Final Answer[::]\s*\n*([\s\S]*)$/i)
|
||||
if (chineseFinalMatch) {
|
||||
return chineseFinalMatch[1].trim()
|
||||
const vietnameseFinalMatch = response.match(/Final Answer[::]\s*\n*([\s\S]*)$/i)
|
||||
if (vietnameseFinalMatch) {
|
||||
return vietnameseFinalMatch[1].trim()
|
||||
}
|
||||
|
||||
// Nếu bắt đầu bằng ## hoặc # hoặc >, có thể là nội dung markdown trực tiếp
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@
|
|||
<textarea
|
||||
v-model="formData.simulationRequirement"
|
||||
class="code-input"
|
||||
placeholder="// Describe your simulation or prediction request in natural language (e.g. If Wuhan University announces the revocation of disciplinary action against someone, what public opinion trends would emerge?)"
|
||||
placeholder="Describe your simulation or prediction request in natural language (e.g. If Wuhan University announces the revocation of disciplinary action against someone, what public opinion trends would emerge?)"
|
||||
rows="6"
|
||||
:disabled="loading"
|
||||
></textarea>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "mirofish",
|
||||
"version": "0.1.0",
|
||||
"description": "MiroFish - 简洁通用的群体智能引擎,预测万物",
|
||||
"description": "MiroFish - A simple and versatile swarm intelligence engine that predicts everything",
|
||||
"scripts": {
|
||||
"setup": "npm install && cd frontend && npm install",
|
||||
"setup:backend": "cd backend && uv sync",
|
||||
|
|
|
|||
Loading…
Reference in New Issue