语言检测并动态更新语种 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",
"ddgs>=9.14.1",
"aiofiles>=24.1.0",
"fast-langdetect>=1.0.0",
]

View File

@@ -1,15 +1,17 @@
import logging
from typing import Callable
from typing import Callable, Any, Optional, Dict
from dataclasses import dataclass
from deepagents import create_deep_agent
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 langchain_core.messages import ToolMessage, SystemMessage
from fast_langdetect import detect
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.serde.jsonplus import JsonPlusSerializer
from langgraph.constants import END
from langgraph.prebuilt.tool_node import ToolCallRequest
from langgraph.runtime import Runtime
from langgraph.store.memory import InMemoryStore
from langgraph.types import Command
from pymongo import MongoClient
@@ -96,7 +98,7 @@ async def report_control(request: ToolCallRequest, handler: Callable[[ToolCallRe
def user_role_prompt(request: ModelRequest) -> str:
"""Generate system prompts based on use_report status and language preference."""
use_report = request.runtime.context.use_report
language = request.runtime.context.language # 默认简体中文
language = request.runtime.context.language
# ==================== 报告功能状态提示(支持中英文) ====================
if use_report:
@@ -132,7 +134,13 @@ def user_role_prompt(request: ModelRequest) -> str:
CRITICAL:
- 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."""
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"]
logger.info(
@@ -142,6 +150,58 @@ def user_role_prompt(request: ModelRequest) -> str:
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):
research_subagent = build_researcher_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
]
middleware = [
LanguageDetectionMiddleware(min_length=8, default_lang="en"),
user_role_prompt,
report_control,
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.tools.crawl_tool import create_crawl4ai_batch_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
@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):
crawl4ai_batch = create_crawl4ai_batch_tool(workspace_dir)
structured_retrieval = create_structured_retrieval_tool(workspace_dir)
@@ -28,10 +76,11 @@ This sub-agent will:
- Produce a complete research report
Do NOT use this sub-agent for:
- User profile collection (handled by user_profile_subagent)
- User profile collection
- Image generation or editing tasks
""",
"system_prompt": build_researcher_prompt(),
"middleware": [language_control],
"tools": [
query_report_profile,
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.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 = {
"name": "user_profile_subagent",
"description": """
@@ -22,6 +117,7 @@ Do NOT use this sub-agent for:
- Image generation or editing
""",
"system_prompt": build_user_persona_prompt(),
"middleware": [language_control],
"tools": [
query_report_profile,
update_report_profile,

View File

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

View File

@@ -13,7 +13,7 @@ collection = db["user_profiles"]
@tool
def query_report_profile(config: RunnableConfig, ) -> dict:
"""
查询用户报告画像
Query user report portrait
"""
thread_id = config['configurable']['thread_id']
doc = collection.find_one({"thread_id": thread_id})
@@ -28,7 +28,7 @@ def query_report_profile(config: RunnableConfig, ) -> dict:
@tool
def update_report_profile(config: RunnableConfig, profile: dict) -> dict:
"""
更新用户画像信息
Update user portrait information
"""
thread_id = config['configurable']['thread_id']
collection.update_one(
@@ -47,7 +47,7 @@ def update_report_profile(config: RunnableConfig, profile: dict) -> dict:
@tool
def check_profile_complete(profile: dict) -> dict:
"""
判断画像是否完整
Determine whether the image is complete
"""
required = ["style", "room_type", "budget"]
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" },
]
[[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]]
name = "crawl4ai"
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" },
]
[[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]]
name = "fastapi"
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" },
]
[[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]]
name = "fastuuid"
version = "0.14.0"
@@ -1344,6 +1414,7 @@ dependencies = [
{ name = "deepagents" },
{ name = "end" },
{ name = "faiss-cpu" },
{ name = "fast-langdetect" },
{ name = "fastapi", extra = ["standard"] },
{ name = "field" },
{ name = "gunicorn" },
@@ -1409,6 +1480,7 @@ requires-dist = [
{ name = "deepagents", specifier = ">=0.4.3" },
{ name = "end", specifier = ">=1.3.1" },
{ name = "faiss-cpu", specifier = ">=1.13.2" },
{ name = "fast-langdetect", specifier = ">=1.0.0" },
{ name = "fastapi", extras = ["standard"], specifier = ">=0.128.0" },
{ name = "field", specifier = ">=0.2.0" },
{ 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" },
]
[[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]]
name = "rpds-py"
version = "0.30.0"