语言检测并动态更新语种 TODO 后续切换为llm识别用户语种意图模式

This commit is contained in:
zcr
2026-05-04 14:53:38 +08:00
parent dcf29a3b84
commit cbee81ee44
7 changed files with 304 additions and 11 deletions

View File

@@ -66,4 +66,5 @@ dependencies = [
"python-magic>=0.4.27", "python-magic>=0.4.27",
"ddgs>=9.14.1", "ddgs>=9.14.1",
"aiofiles>=24.1.0", "aiofiles>=24.1.0",
"fast-langdetect>=1.0.0",
] ]

View File

@@ -1,15 +1,17 @@
import logging import logging
from typing import Callable from typing import Callable, Any, Optional, Dict
from dataclasses import dataclass from dataclasses import dataclass
from deepagents import create_deep_agent from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend, CompositeBackend, StateBackend from deepagents.backends import FilesystemBackend, CompositeBackend, StateBackend
from langchain.agents.middleware import SummarizationMiddleware, ToolRetryMiddleware, wrap_model_call, ModelRequest, ModelResponse, wrap_tool_call, dynamic_prompt from fast_langdetect import detect
from langchain_core.messages import ToolMessage, SystemMessage from langchain.agents.middleware import SummarizationMiddleware, ToolRetryMiddleware, wrap_model_call, ModelRequest, ModelResponse, wrap_tool_call, dynamic_prompt, before_model, AgentMiddleware, hook_config
from langchain_core.messages import ToolMessage, SystemMessage, AIMessage, HumanMessage
from langgraph.checkpoint.mongodb import MongoDBSaver from langgraph.checkpoint.mongodb import MongoDBSaver
from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer
from langgraph.constants import END from langgraph.constants import END
from langgraph.prebuilt.tool_node import ToolCallRequest from langgraph.prebuilt.tool_node import ToolCallRequest
from langgraph.runtime import Runtime
from langgraph.store.memory import InMemoryStore from langgraph.store.memory import InMemoryStore
from langgraph.types import Command from langgraph.types import Command
from pymongo import MongoClient from pymongo import MongoClient
@@ -96,7 +98,7 @@ async def report_control(request: ToolCallRequest, handler: Callable[[ToolCallRe
def user_role_prompt(request: ModelRequest) -> str: def user_role_prompt(request: ModelRequest) -> str:
"""Generate system prompts based on use_report status and language preference.""" """Generate system prompts based on use_report status and language preference."""
use_report = request.runtime.context.use_report use_report = request.runtime.context.use_report
language = request.runtime.context.language # 默认简体中文 language = request.runtime.context.language
# ==================== 报告功能状态提示(支持中英文) ==================== # ==================== 报告功能状态提示(支持中英文) ====================
if use_report: if use_report:
@@ -132,7 +134,13 @@ def user_role_prompt(request: ModelRequest) -> str:
CRITICAL: CRITICAL:
- Be sure to use the above settings when generating line drawings/images. - Be sure to use the above settings when generating line drawings/images.
- Do not refer to these three settings repeatedly when generating reports or text-only answers.""" - Do not refer to these three settings repeatedly when generating reports or text-only answers."""
langguage_prompt = f"""
## Custom Language Rules
- All content of the final report and all reply content MUST be fully written in: {language}
- No mixed languages, no bilingual contrast, no extra English annotations.
- Maintain native, fluent, professional expression conforming to the language habits of {language}.
- All professional terms, captions, notes and reference descriptions must follow the unified {language} specification.
"""
final_prompt = backend_prompt + SYSTEM_PROMPT_MAPPING[f'SYSTEM_BASE_PROMPT_en'] + report_status + SYSTEM_PROMPT_MAPPING[f"SYSTEM_RULES_PROMPT_en"] final_prompt = backend_prompt + SYSTEM_PROMPT_MAPPING[f'SYSTEM_BASE_PROMPT_en'] + report_status + SYSTEM_PROMPT_MAPPING[f"SYSTEM_RULES_PROMPT_en"]
logger.info( logger.info(
@@ -142,6 +150,58 @@ def user_role_prompt(request: ModelRequest) -> str:
return final_prompt return final_prompt
from langchain.agents.middleware import AgentState
class LanguageDetectionMiddleware(AgentMiddleware):
"""使用 fast-langdetect基于 fastText自动检测语言"""
def __init__(self, min_length: int = 8, default_lang: str = "zh"):
self.min_length = min_length
self.default_lang = default_lang
def before_model(self, state: AgentState, runtime=None) -> Optional[Dict[str, Any]]:
messages = state.get("messages", [])
if not messages:
return None
last_msg = messages[-1]
if not isinstance(last_msg, HumanMessage):
return None
content = last_msg.content if hasattr(last_msg, "content") else str(last_msg)
content = content[0].get("text").strip()
if len(content) < self.min_length:
return None
try:
detected_lang = "en"
confidence = 0
# 单语言检测(最常用)
res = detect(text=content, model="auto", k=1)
if res and res[0].get("lang") and res[0].get("score", 0) > 0.5:
detected_lang = res[0]["lang"]
confidence = res[0]["score"]
print(f"🔍 fast-langdetect 检测到: {detected_lang} (score={confidence:.4f})")
runtime.context.language = detected_lang
return {
"language": detected_lang,
"preferred_language": detected_lang,
"language_confidence": float(confidence),
}
except Exception as e:
print(f"语言检测失败: {e}")
return {"language": self.default_lang}
async def abefore_model(self, state: AgentState, runtime=None):
return self.before_model(state, runtime)
def build_main_agent(workspace_dir, enable_thinking): def build_main_agent(workspace_dir, enable_thinking):
research_subagent = build_researcher_subagent(workspace_dir) research_subagent = build_researcher_subagent(workspace_dir)
# painter_subagent = build_painter_subagent(workspace_dir) # painter_subagent = build_painter_subagent(workspace_dir)
@@ -151,6 +211,7 @@ def build_main_agent(workspace_dir, enable_thinking):
user_profile_subagent user_profile_subagent
] ]
middleware = [ middleware = [
LanguageDetectionMiddleware(min_length=8, default_lang="en"),
user_role_prompt, user_role_prompt,
report_control, report_control,
SummarizationMiddleware( SummarizationMiddleware(

View File

@@ -1,3 +1,5 @@
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from src.server.deep_agent.init_prompt import build_researcher_prompt from src.server.deep_agent.init_prompt import build_researcher_prompt
from src.server.deep_agent.tools.crawl_tool import create_crawl4ai_batch_tool from src.server.deep_agent.tools.crawl_tool import create_crawl4ai_batch_tool
from src.server.deep_agent.tools.report_generator_tool import create_report_generator_tool from src.server.deep_agent.tools.report_generator_tool import create_report_generator_tool
@@ -6,6 +8,52 @@ from src.server.deep_agent.tools.structured_retrieval_tool import create_structu
from src.server.deep_agent.tools.user_persona_tool import query_report_profile from src.server.deep_agent.tools.user_persona_tool import query_report_profile
@dynamic_prompt
def language_control(request: ModelRequest) -> str:
"""Generate system prompts based on use_report status and language preference."""
language = request.runtime.context.language # 默认简体中文
final_prompt = f"""
You are a professional furniture design researcher.
Your primary goal:
- Generate a high-quality, structured furniture design research report based on the user's request and user profile.
- The report should be clear, insightful, and written in well-structured Markdown format.
- It should include design trends, materials, color directions, representative cases, and relevant references.
You are allowed to:
- Retrieve user profile information (e.g., style, room type, preferences)
- Generate research keywords
- Search for relevant topics and sources
- Crawl and read web content
- Extract structured insights
- Generate the final report
Tool usage guidelines:
- If necessary, first retrieve the user profile to better understand preferences.
- Use meaningful and relevant keywords for research.
- When crawling web content, try to process multiple sources efficiently (avoid repeated calls).
- Focus on extracting key insights such as trends, materials, colors, and case studies.
- Use the report_generator tool to produce the final report.
Important rules:
- Your objective is to complete a high-quality report, not to strictly follow a fixed sequence of steps.
- You may adapt your approach depending on the situation.
- Avoid calling the same tool repeatedly (especially crawl tools).
- If some data is missing, proceed with available information and clearly mention any limitations.
- Once the report is generated, consider the task complete and stop further actions.
## Custom Language Rules
- All content of the final report and all reply content MUST be fully written in: {language}
- No mixed languages, no bilingual contrast, no extra English annotations.
- Maintain native, fluent, professional expression conforming to the language habits of {language}.
- All professional terms, captions, notes and reference descriptions must follow the unified {language} specification.
"""
return final_prompt
def build_researcher_subagent(workspace_dir): def build_researcher_subagent(workspace_dir):
crawl4ai_batch = create_crawl4ai_batch_tool(workspace_dir) crawl4ai_batch = create_crawl4ai_batch_tool(workspace_dir)
structured_retrieval = create_structured_retrieval_tool(workspace_dir) structured_retrieval = create_structured_retrieval_tool(workspace_dir)
@@ -28,10 +76,11 @@ This sub-agent will:
- Produce a complete research report - Produce a complete research report
Do NOT use this sub-agent for: Do NOT use this sub-agent for:
- User profile collection (handled by user_profile_subagent) - User profile collection
- Image generation or editing tasks - Image generation or editing tasks
""", """,
"system_prompt": build_researcher_prompt(), "system_prompt": build_researcher_prompt(),
"middleware": [language_control],
"tools": [ "tools": [
query_report_profile, query_report_profile,
topic_research, topic_research,

View File

@@ -1,6 +1,101 @@
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from src.server.deep_agent.init_prompt import build_user_persona_prompt from src.server.deep_agent.init_prompt import build_user_persona_prompt
from src.server.deep_agent.tools.user_persona_tool import query_report_profile, update_report_profile, check_profile_complete from src.server.deep_agent.tools.user_persona_tool import query_report_profile, update_report_profile, check_profile_complete
@dynamic_prompt
def language_control(request: ModelRequest) -> str:
"""Generate system prompts based on use_report status and language preference."""
language = request.runtime.context.language # 默认简体中文
final_prompt = f"""
You are a user profile collection assistant.
Your goal:
- Extract and maintain structured user profile information from the conversation.
- The profile is used for generating furniture design reports.
Profile fields may include:
- style (design style or aesthetic preference)
- room_type (type of room or space)
- budget (optional)
- other relevant design preferences
What you should do:
- Understand the user's input and identify any profile-related information.
- If new information is found, update the profile accordingly.
- If no new information is provided, keep the existing profile unchanged.
- Ensure previously stored information is preserved unless the user explicitly modifies it.
Tool usage guidelines:
- Use query_report_profile when you need to know the current profile.
- Use update_report_profile only when new or updated information is detected.
- Use check_profile_complete to determine if required fields are sufficient for report generation.
Behavior rules:
- Do NOT generate reports.
- Do NOT guess or fabricate missing information.
- Only extract information that is clearly stated or strongly implied by the user.
- Be concise and structured in your output.
When profile is incomplete:
- Ask the user for the missing information in a natural way.
When profile is complete:
- Respond with a clear signal that profile collection is done, for example:
"Profile is complete. Ready for report generation."
Language rules:
- Always respond in the same language as the user.
- Do not mix languages.
- Keep the output consistent and natural.
Strict Language Enforcement:
- You MUST use only one language in the entire response.
- The language must match the user's input.
- Mixing multiple languages is strictly prohibited.
"""
final_prompt = f"""
You are a professional furniture design researcher.
## Core Objectives
- Generate high-quality, in-depth & structured furniture design research reports in standard Markdown format.
- Strictly combine user requirements and complete user profile information for customized analysis.
- The report must cover: design trend analysis, mainstream material selection, color palette orientation, classic representative cases and industry reference information.
## Permitted Capabilities
- Retrieve and parse user profile data (design style preference, room type, usage scenario, aesthetic tendency, etc.).
- Extract core research keywords for industry investigation.
- Search, crawl and summarize multi-source industry information.
- Refine structured, actionable design insights.
- Call the report_generator tool to output the final standardized report.
## Tool Usage Specifications
- Prioritize obtaining complete user profile before research to improve report relevance.
- Use precise, industry-oriented search keywords.
- Crawl and integrate multiple sources at one time to avoid redundant and repeated tool calls.
- Focus on screening effective information: trend characteristics, material performance, color matching logic, typical brand cases.
- Do not over-rely on tool processes; flexibly adjust research ideas according to information integrity.
## Critical Rules
- Task priority: deliver a complete, high-quality research report.
- No rigid step-by-step execution; adjust research logic adaptively based on actual conditions.
- Prohibit frequent repeated calls to crawl and search tools.
- If partial industry data is missing, continue writing with existing valid information and mark data limitations clearly in the report.
- Stop all tool calls and work immediately after the final report is generated.
## Custom Language Rules
- All content of the final report and all reply content MUST be fully written in: {language}
- No mixed languages, no bilingual contrast, no extra English annotations.
- Maintain native, fluent, professional expression conforming to the language habits of {language}.
- All professional terms, captions, notes and reference descriptions must follow the unified {language} specification.
"""
return final_prompt
user_profile_subagent = { user_profile_subagent = {
"name": "user_profile_subagent", "name": "user_profile_subagent",
"description": """ "description": """
@@ -22,6 +117,7 @@ Do NOT use this sub-agent for:
- Image generation or editing - Image generation or editing
""", """,
"system_prompt": build_user_persona_prompt(), "system_prompt": build_user_persona_prompt(),
"middleware": [language_control],
"tools": [ "tools": [
query_report_profile, query_report_profile,
update_report_profile, update_report_profile,

View File

@@ -79,8 +79,8 @@ from langchain.tools import tool
@tool @tool
async def topic_research(topic: List[str], max_urls: int = 5) -> str: async def topic_research(topic: List[str], max_urls: int = 5) -> str:
""" """
深度调研工具DuckDuckGo版本 In-depth research tool (DuckDuckGo version).
根据多个主题关键词进行搜索,返回去重后的高质量 URL 列表JSON字符串 Search based on multiple topic keywords and return a high-quality URL list (JSON string) after deduplication.
""" """
# DuckDuckGo 是同步库,需要丢到线程池 # DuckDuckGo 是同步库,需要丢到线程池

View File

@@ -13,7 +13,7 @@ collection = db["user_profiles"]
@tool @tool
def query_report_profile(config: RunnableConfig, ) -> dict: def query_report_profile(config: RunnableConfig, ) -> dict:
""" """
查询用户报告画像 Query user report portrait
""" """
thread_id = config['configurable']['thread_id'] thread_id = config['configurable']['thread_id']
doc = collection.find_one({"thread_id": thread_id}) doc = collection.find_one({"thread_id": thread_id})
@@ -28,7 +28,7 @@ def query_report_profile(config: RunnableConfig, ) -> dict:
@tool @tool
def update_report_profile(config: RunnableConfig, profile: dict) -> dict: def update_report_profile(config: RunnableConfig, profile: dict) -> dict:
""" """
更新用户画像信息 Update user portrait information
""" """
thread_id = config['configurable']['thread_id'] thread_id = config['configurable']['thread_id']
collection.update_one( collection.update_one(
@@ -47,7 +47,7 @@ def update_report_profile(config: RunnableConfig, profile: dict) -> dict:
@tool @tool
def check_profile_complete(profile: dict) -> dict: def check_profile_complete(profile: dict) -> dict:
""" """
判断画像是否完整 Determine whether the image is complete
""" """
required = ["style", "room_type", "budget"] required = ["style", "room_type", "budget"]
missing = [f for f in required if f not in profile] missing = [f for f in required if f not in profile]

86
uv.lock generated
View File

@@ -699,6 +699,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
] ]
[[package]]
name = "colorlog"
version = "6.10.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a2/61/f083b5ac52e505dfc1c624eafbf8c7589a0d7f32daa398d2e7590efa5fda/colorlog-6.10.1.tar.gz", hash = "sha256:eb4ae5cb65fe7fec7773c2306061a8e63e02efc2c72eba9d27b0fa23c94f1321", size = 17162, upload-time = "2025-10-16T16:14:11.978Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6d/c1/e419ef3723a074172b68aaa89c9f3de486ed4c2399e2dbd8113a4fdcaf9e/colorlog-6.10.1-py3-none-any.whl", hash = "sha256:2d7e8348291948af66122cff006c9f8da6255d224e7cf8e37d8de2df3bad8c9c", size = 11743, upload-time = "2025-10-16T16:14:10.512Z" },
]
[[package]] [[package]]
name = "crawl4ai" name = "crawl4ai"
version = "0.8.6" version = "0.8.6"
@@ -1142,6 +1154,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/51/37/b3ea9cd5558ff4cb51957caca2193981c6b0ff30bd0d2630ac62505d99d0/fake_useragent-2.2.0-py3-none-any.whl", hash = "sha256:67f35ca4d847b0d298187443aaf020413746e56acd985a611908c73dba2daa24", size = 161695, upload-time = "2025-04-14T15:32:17.732Z" }, { url = "https://files.pythonhosted.org/packages/51/37/b3ea9cd5558ff4cb51957caca2193981c6b0ff30bd0d2630ac62505d99d0/fake_useragent-2.2.0-py3-none-any.whl", hash = "sha256:67f35ca4d847b0d298187443aaf020413746e56acd985a611908c73dba2daa24", size = 161695, upload-time = "2025-04-14T15:32:17.732Z" },
] ]
[[package]]
name = "fast-langdetect"
version = "1.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "fasttext-predict" },
{ name = "requests" },
{ name = "robust-downloader" },
]
sdist = { url = "https://files.pythonhosted.org/packages/53/15/85b0137066be418b6249d8e8d98e2b16c072c65b80c293b9438fdea1be5e/fast_langdetect-1.0.0.tar.gz", hash = "sha256:ea8ac6a8914e0ff1bfc1bbc0f25992eb913ddb69e63ea1b24e907e263d0cd113", size = 796192, upload-time = "2025-09-17T06:32:26.86Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f6/71/0db1ac89f8661048ebc22d62f503a2e147cb6872c5f2aeb659c1f02c1694/fast_langdetect-1.0.0-py3-none-any.whl", hash = "sha256:aab9e3435cc667ac8ba8b1a38872f75492f65b7087901d0f3a02a88d436cd22a", size = 789944, upload-time = "2025-09-17T06:32:25.363Z" },
]
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.136.0" version = "0.136.0"
@@ -1282,6 +1308,50 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/6b/fd/5390ec4f49100f3ecb9968a392f9e6d039f1e3fe0ecd28443716ff01e589/fastar-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:76c1359314355eafbc6989f20fb1ad565a3d10200117923b9da765a17e2f6f11", size = 461049, upload-time = "2026-04-13T17:11:25.918Z" }, { url = "https://files.pythonhosted.org/packages/6b/fd/5390ec4f49100f3ecb9968a392f9e6d039f1e3fe0ecd28443716ff01e589/fastar-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:76c1359314355eafbc6989f20fb1ad565a3d10200117923b9da765a17e2f6f11", size = 461049, upload-time = "2026-04-13T17:11:25.918Z" },
] ]
[[package]]
name = "fasttext-predict"
version = "0.9.2.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fc/0e/9defbb9385bcb1104cc1d686a14f7d9fafe5fe43f220cccb00f33d91bb47/fasttext_predict-0.9.2.4.tar.gz", hash = "sha256:18a6fb0d74c7df9280db1f96cb75d990bfd004fa9d669493ea3dd3d54f84dbc7", size = 16332, upload-time = "2024-11-23T17:24:44.801Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fb/fa/612bf85ce8928120843279ae256f4fffbb9758af81536ddf25f9136b1759/fasttext_predict-0.9.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dcf8661da4f515551523470a745df246121f7e19736fcf3f48f04287963e6279", size = 104836, upload-time = "2024-11-23T17:23:25.219Z" },
{ url = "https://files.pythonhosted.org/packages/7a/04/106b6fe3f980d6a4f41bfb3106be22d42f87b1e8beb2959361ee4ee08960/fasttext_predict-0.9.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99dbfcc3f353da2639fd04fc574a65ff4195b018311f790583147cdc6eb122f4", size = 97377, upload-time = "2024-11-23T17:23:26.319Z" },
{ url = "https://files.pythonhosted.org/packages/57/b9/b4962c92bd93dd234ea1d1cab643a86d948dab3f269e34a554a004ed6524/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:427e99ba963b2c744ed7233304037a83b7adece97de6f361cfd356aa43cb87f3", size = 283102, upload-time = "2024-11-23T17:23:27.497Z" },
{ url = "https://files.pythonhosted.org/packages/1d/18/92203820cf00b9a34f40f10456e4ed3019010a9b13a87e11d8b98cd98933/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b9480cc75a906571a8e5fc717b91b4783f1820aaa5ed36a304d689280de8602", size = 307416, upload-time = "2024-11-23T17:23:28.68Z" },
{ url = "https://files.pythonhosted.org/packages/06/8d/334cd9acb84e569d37617444661ca7b59d1bc1a83abe42aa845d23fb1273/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11ef7af2a4431c76d2226e47334e86b9c4a78a98f6cb68b1ce9a1fc20e04c904", size = 296055, upload-time = "2024-11-23T17:23:29.934Z" },
{ url = "https://files.pythonhosted.org/packages/08/0b/2c83cc67eb5a29f182c8ea425e4b026db0593712edb8eaaf082501ca349f/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:ecb0b854596ba847742597b35c2d0134fcf3a59214d09351d01535854078d56b", size = 237279, upload-time = "2024-11-23T17:23:31.358Z" },
{ url = "https://files.pythonhosted.org/packages/14/81/0f1b3bda499ffeb7109fe51d9321dc74100db5a4801e3f9a9efe2348922d/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fbbcfefac10f625d95fc42f28d76cc5bf0c12875f147b5a79108a2669e64a2dc", size = 1214253, upload-time = "2024-11-23T17:23:33.529Z" },
{ url = "https://files.pythonhosted.org/packages/d1/e6/b1a177a990c29b043a9658f9f4ec7234576ad31939362f9760c237f91d6d/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a8cb78a00c04b7eb7da18b4805f8557b36911dc4375c947d8938897d2e131841", size = 1099909, upload-time = "2024-11-23T17:23:34.983Z" },
{ url = "https://files.pythonhosted.org/packages/09/a0/7f23c7c4398f399552f39144849868991da543b66b9bfa8f49a6550fdd46/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:299ae56ad53e1381c65030143da7bcae12546fd32bc019215592ec1ee40fd19e", size = 1384102, upload-time = "2024-11-23T17:23:37.237Z" },
{ url = "https://files.pythonhosted.org/packages/e4/2c/568cf15fd48e4cefd0e605af62da5f5f51db3b012f8441d201d0a1173eb1/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:091938062002fe30d214f6e493a3a1e6180d401212d37eea23c29f4b55f3f347", size = 1281283, upload-time = "2024-11-23T17:23:39.676Z" },
{ url = "https://files.pythonhosted.org/packages/e7/68/0967ec3d5333c23fae1f1bdb851fa896f8f6068ef0ca3a8afee1aa2ee57d/fasttext_predict-0.9.2.4-cp312-cp312-win32.whl", hash = "sha256:981b8d9734623f8f9a8003970f765e14b1d91ee82c59c35e8eba6b76368fa95e", size = 91089, upload-time = "2024-11-23T17:23:41.082Z" },
{ url = "https://files.pythonhosted.org/packages/a7/c5/11c1f50b47f492d562974878ec34b6a0b84699f8b05e1cc3a75c65349784/fasttext_predict-0.9.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:bd3c33971c241577b0767e55d97acfda790f77378f9d5ee7872b6ee4bd63130b", size = 104889, upload-time = "2024-11-23T17:23:42.193Z" },
{ url = "https://files.pythonhosted.org/packages/89/fc/5cd65224c33e33d6faec3fa1047162dc266ed2213016139d936bd36fb7c3/fasttext_predict-0.9.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddb85e62c95e4e02d417c782e3434ef65554df19e3522f5230f6be15a9373c05", size = 104916, upload-time = "2024-11-23T17:23:43.367Z" },
{ url = "https://files.pythonhosted.org/packages/d9/53/8d542773e32c9d98dd8c680e390fe7e6d4fc92ab3439dc1bb8e70c46c7ad/fasttext_predict-0.9.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:102129d45cf98dda871e83ae662f71d999b9ef6ff26bc842ffc1520a1f82930c", size = 97502, upload-time = "2024-11-23T17:23:44.447Z" },
{ url = "https://files.pythonhosted.org/packages/50/99/049fd6b01937705889bd9a00c31e5c55f0ae4b7704007b2ef7a82bf2b867/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05ba6a0fbf8cb2141b8ca2bc461db97af8ac31a62341e4696a75048b9de39e10", size = 282951, upload-time = "2024-11-23T17:23:46.31Z" },
{ url = "https://files.pythonhosted.org/packages/83/cb/79b71709edbb53c3c5f8a8b60fe2d3bc98d28a8e75367c89afedf3307aa9/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c7a779215571296ecfcf86545cb30ec3f1c6f43cbcd69f83cc4f67049375ea1", size = 307377, upload-time = "2024-11-23T17:23:47.685Z" },
{ url = "https://files.pythonhosted.org/packages/7c/4a/b15b7be003e76613173cc77d9c6cce4bf086073079354e0177deaa768f59/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddd2f03f3f206585543f5274b1dbc5f651bae141a1b14c9d5225c2a12e5075c2", size = 295746, upload-time = "2024-11-23T17:23:49.024Z" },
{ url = "https://files.pythonhosted.org/packages/e3/d3/f030cd45bdd4b052fcf23e730fdf0804e024b0cad43d7c7f8704faaec2f5/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:748f9edc3222a1fb7a61331c4e06d3b7f2390ae493f91f09d372a00b81762a8d", size = 236939, upload-time = "2024-11-23T17:23:50.306Z" },
{ url = "https://files.pythonhosted.org/packages/a2/01/6f2985afd58fdc5f4ecd058d5d9427d03081d468960982df97316c03f6bb/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1aee47a40757cd24272b34eaf9ceeea86577fd0761b0fd0e41599c6549abdf04", size = 1214189, upload-time = "2024-11-23T17:23:51.647Z" },
{ url = "https://files.pythonhosted.org/packages/75/07/931bcdd4e2406e45e54d57e056c2e0766616a5280a18fbf6ef078aa439ab/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6ff0f152391ee03ffc18495322100c01735224f7843533a7c4ff33c8853d7be1", size = 1099889, upload-time = "2024-11-23T17:23:53.127Z" },
{ url = "https://files.pythonhosted.org/packages/a2/eb/6521b4bbf387252a96a6dc0f54986f078a93db0a9d4ba77258dcf1fa8be7/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4d92f5265318b41d6e68659fd459babbff692484e492c5013995b90a56b517c9", size = 1383959, upload-time = "2024-11-23T17:23:54.521Z" },
{ url = "https://files.pythonhosted.org/packages/b7/6b/d56606761afb3a3912c52971f0f804e2e9065f049c412b96c47d6fca6218/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3a7720cce1b8689d88df76cac1425e84f9911c69a4e40a5309d7d3435e1bb97c", size = 1281097, upload-time = "2024-11-23T17:23:55.9Z" },
{ url = "https://files.pythonhosted.org/packages/91/83/55bb4a37bb3b3a428941f4e1323c345a662254f576f8860b3098d9742510/fasttext_predict-0.9.2.4-cp313-cp313-win32.whl", hash = "sha256:d16acfced7871ed0cd55b476f0dbdddc7a5da1ffc9745a3c5674846cf1555886", size = 91137, upload-time = "2024-11-23T17:23:57.886Z" },
{ url = "https://files.pythonhosted.org/packages/9c/1d/c1ccc8790ce54200c84164d99282f088dddb9760aeefc8860856aafa40b4/fasttext_predict-0.9.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:96a23328729ce62a851f8953582e576ca075ee78d637df4a78a2b3609784849e", size = 104896, upload-time = "2024-11-23T17:23:59.028Z" },
{ url = "https://files.pythonhosted.org/packages/a4/c9/a1ccc749c59e2480767645ecc03bd842a7fa5b2b780d69ac370e6f8298d2/fasttext_predict-0.9.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b1357d0d9d8568db84668b57e7c6880b9c46f757e8954ad37634402d36f09dba", size = 109401, upload-time = "2024-11-23T17:24:00.191Z" },
{ url = "https://files.pythonhosted.org/packages/90/1f/33182b76eb0524155e8ff93e7939feaf5325385e5ff2a154f383d9a02317/fasttext_predict-0.9.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9604c464c5d86c7eba34b040080be7012e246ef512b819e428b7deb817290dae", size = 102131, upload-time = "2024-11-23T17:24:02.052Z" },
{ url = "https://files.pythonhosted.org/packages/2b/df/1886daea373382e573f28ce49e3fc8fb6b0ee0c84e2b0becf5b254cd93fb/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6da186c2e4497cbfaba9c5424e58c7b72728b25d980829eb96daccd7cface1", size = 287396, upload-time = "2024-11-23T17:24:03.294Z" },
{ url = "https://files.pythonhosted.org/packages/35/8f/d1c2c0f0251bee898d508253a437683b0480a1074cfb25ded1f7fdbb925a/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366ed2ca4f4170418f3585e92059cf17ee2c963bf179111c5b8ba48f06cd69d1", size = 311090, upload-time = "2024-11-23T17:24:04.625Z" },
{ url = "https://files.pythonhosted.org/packages/5d/52/07d6ed46148662fae84166bc69d944caca87fabc850ebfbd9640b20dafe7/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f1877edbb815a43e7d38cc7332202e759054cf0b5a4b7e34a743c0f5d6e7333", size = 300359, upload-time = "2024-11-23T17:24:06.486Z" },
{ url = "https://files.pythonhosted.org/packages/fa/a1/751ff471a991e5ed0bae9e7fa6fc8d8ab76b233a7838a27d70d62bed0c8e/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_31_armv7l.whl", hash = "sha256:f63c31352ba6fc910290b0fe12733770acd8cfa0945fcb9cf3984d241abcfc9d", size = 241164, upload-time = "2024-11-23T17:24:08.501Z" },
{ url = "https://files.pythonhosted.org/packages/94/19/e251f699a0e9c001fa672ea0929c456160faa68ecfafc19e8def09982b6a/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:898e14b03fbfb0a8d9a5185a0a00ff656772b3baa37cad122e06e8e4d6da3832", size = 1218629, upload-time = "2024-11-23T17:24:10.04Z" },
{ url = "https://files.pythonhosted.org/packages/1d/46/1af2f779f8cfd746496a226581f747d3051888e3e3c5b2ca37231e5d04f8/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:a33bb5832a69fc54d18cadcf015677c1acb5ccc7f0125d261df2a89f8aff01f6", size = 1100535, upload-time = "2024-11-23T17:24:11.5Z" },
{ url = "https://files.pythonhosted.org/packages/4c/b7/900ccd74a9ba8be7ca6d04bba684e9c43fb0dbed8a3d12ec0536228e2c32/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7fe9e98bd0701d598bf245eb2fbf592145cd03551684a2102a4b301294b9bd87", size = 1387651, upload-time = "2024-11-23T17:24:13.135Z" },
{ url = "https://files.pythonhosted.org/packages/0b/5a/99fdaed054079f7c96e70df0d7016c4eb6b9e487a614396dd8f849244a52/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dcb8c5a74c1785f005fd83d445137437b79ac70a2dfbfe4bb1b09aa5643be545", size = 1286189, upload-time = "2024-11-23T17:24:14.615Z" },
{ url = "https://files.pythonhosted.org/packages/87/6a/9114d65b3f7a9c20a62b9d2ca3b770ee65de849e4131cc7aa58cdc50cb07/fasttext_predict-0.9.2.4-cp313-cp313t-win32.whl", hash = "sha256:a85c7de3d4480faa12b930637fca9c23144d1520786fedf9ba8edd8642ed4aea", size = 95905, upload-time = "2024-11-23T17:24:15.868Z" },
{ url = "https://files.pythonhosted.org/packages/31/fb/6d251f3fdfe3346ee60d091f55106513e509659ee005ad39c914182c96f4/fasttext_predict-0.9.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:be0933fa4af7abae09c703d28f9e17c80e7069eb6f92100b21985b777f4ea275", size = 110325, upload-time = "2024-11-23T17:24:16.984Z" },
]
[[package]] [[package]]
name = "fastuuid" name = "fastuuid"
version = "0.14.0" version = "0.14.0"
@@ -1344,6 +1414,7 @@ dependencies = [
{ name = "deepagents" }, { name = "deepagents" },
{ name = "end" }, { name = "end" },
{ name = "faiss-cpu" }, { name = "faiss-cpu" },
{ name = "fast-langdetect" },
{ name = "fastapi", extra = ["standard"] }, { name = "fastapi", extra = ["standard"] },
{ name = "field" }, { name = "field" },
{ name = "gunicorn" }, { name = "gunicorn" },
@@ -1409,6 +1480,7 @@ requires-dist = [
{ name = "deepagents", specifier = ">=0.4.3" }, { name = "deepagents", specifier = ">=0.4.3" },
{ name = "end", specifier = ">=1.3.1" }, { name = "end", specifier = ">=1.3.1" },
{ name = "faiss-cpu", specifier = ">=1.13.2" }, { name = "faiss-cpu", specifier = ">=1.13.2" },
{ name = "fast-langdetect", specifier = ">=1.0.0" },
{ name = "fastapi", extras = ["standard"], specifier = ">=0.128.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.128.0" },
{ name = "field", specifier = ">=0.2.0" }, { name = "field", specifier = ">=0.2.0" },
{ name = "gunicorn", specifier = ">=25.0.1" }, { name = "gunicorn", specifier = ">=25.0.1" },
@@ -4671,6 +4743,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" }, { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" },
] ]
[[package]]
name = "robust-downloader"
version = "0.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorlog" },
{ name = "requests" },
{ name = "tqdm" },
]
sdist = { url = "https://files.pythonhosted.org/packages/63/20/8d28efa080f58fa06f6378875ac482ee511c076369e5293a2e65128cf9a0/robust-downloader-0.0.2.tar.gz", hash = "sha256:08c938b96e317abe6b037e34230a91bda9b5d613f009bca4a47664997c61de90", size = 15785, upload-time = "2023-11-13T03:00:20.637Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/56/a1/779e9d0ebbdc704411ce30915a1105eb01aeaa9e402d7e446613ff8fb121/robust_downloader-0.0.2-py3-none-any.whl", hash = "sha256:8fe08bfb64d714fd1a048a7df6eb7b413eb4e624309a49db2c16fbb80a62869d", size = 15534, upload-time = "2023-11-13T03:00:18.957Z" },
]
[[package]] [[package]]
name = "rpds-py" name = "rpds-py"
version = "0.30.0" version = "0.30.0"