diff --git a/app/chat_qa/__init__.py b/app/chat_qa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/chat_qa/context.py b/app/chat_qa/context.py new file mode 100644 index 0000000..adc479a --- /dev/null +++ b/app/chat_qa/context.py @@ -0,0 +1,13 @@ +from typing import TypedDict + +from langchain_huggingface import HuggingFaceEndpointEmbeddings +from sentry_sdk.integrations import aiohttp + +from app.repository.archive_messages_repository import ArchiveMessagesRepository +from app.repository.milvus.message_qa_repository import QARepository + + +class QAContext(TypedDict): + meta_mysql_repository: ArchiveMessagesRepository + qa_milvus_repository : QARepository + diff --git a/app/chat_qa/deduplication_qa/__init__.py b/app/chat_qa/deduplication_qa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/chat_qa/deduplication_qa/d_qa.py b/app/chat_qa/deduplication_qa/d_qa.py new file mode 100644 index 0000000..9a1b1b6 --- /dev/null +++ b/app/chat_qa/deduplication_qa/d_qa.py @@ -0,0 +1,122 @@ +""" +数据清洗,把提取的问题进行聚类,然后只提取一个 +""" +import json +from pathlib import Path + +from langchain_core.output_parsers import StrOutputParser +from langchain_core.prompts import PromptTemplate +from sklearn.cluster import DBSCAN +import numpy as np +import asyncio +from app.client.embedding_client_manager import EmbeddingClientManager, embedding_client +from app.conf.app_config import app_config +from app.llm import llm_low + +qa_file = Path(r"E:\qa_result.jsonl") # E:\qa_output\qa_result.jsonl + +qa_list = [] +with open(qa_file, 'r', encoding='utf-8') as f: + for line_num, line in enumerate(f, 1): + line = line.strip() + if not line: + continue + try: + data = json.loads(line) + if isinstance(data, list): + qa_list.extend(data) + elif isinstance(data, dict): + qa_list.append(data) + else: + print(f"警告: 第{line_num}行格式异常,跳过") + except json.JSONDecodeError as e: + print(f"警告: 第{line_num}行JSON解析失败: {e},跳过") + +print(f"成功读取 {len(qa_list)} 条QA数据") + +# qa_list = [ +# {"question": "教学软件是否为全流程制作,课前需要准备哪些设备?", "answer": "需要准备手绘板与手绘笔,手绘笔通常为配套。"}, +# {"question": "教学软件是否为全流程制作,课前需要准备哪些设备", "answer": "需要准备手绘板与手绘笔,手绘笔通常为配套"}, +# # ... 更多数据 +# ] +# 2. 对question进行向量化(异步调用远程模型) +questions = [item["question"] for item in qa_list] + +async def build()->list: + try: + embedding_client.init() + # embeddings_batch = await embedding_client.aembed_documents(questions) + # embeddings = [np.array(emb) for emb in embeddings_batch] + embedding_batch_size = 20 + embedding_ed_all: list[list[float]] = [] + for i in range(0, len(questions), embedding_batch_size): + embedding_part_texts = questions[i:i + embedding_batch_size] + embedding_eds = await embedding_client.aembed_documents(embedding_part_texts) + embedding_ed_all.extend(embedding_eds) + + # 3. DBSCAN聚类(基于余弦相似度,eps≈0.15-0.25) + # 相似度 = 1 - cosine_distance,eps=0.2 约等于相似度>0.8 + clustering = DBSCAN(eps=0.3, min_samples=1, metric='cosine').fit(embedding_ed_all) + + # 3. 组内LLM择优 + results = [] + unique_labels = set(clustering.labels_) + for label in unique_labels: + group = [qa_list[i] for i, l in enumerate(clustering.labels_) if l == label] + if len(group) == 1: + results.append(group[0]) + else: + best = await select_best_qa(group) + results.append(best) + print(f"组内去重:从 {len(group)} 条中保留最优,舍弃 {len(group) - 1} 条") + + except Exception as e: + print(f"处理失败: {str(e)}") + finally: + await embedding_client.close() + print("-----------------------------------------") + for item in results: + print(item) + return results + + +async def select_best_qa(qa_group: list) -> str: + """ + 从一组相似QA中,选出最完整、信息最丰富的一个 + """ + # 构建对比文本 + # qa_text = "\n\n".join([ + # f"【选项{i + 1}】\n问题:{item['question']}\n回答:{item['answer']}" + # for i, item in enumerate(qa_group) + # ]) + qa_text = "\n\n".join([ + f"question: {item['question']},answer: {item['answer']}" + for i, item in enumerate(qa_group) + ]) + prompt = """你是一位数据清洗专家。以下是一组语义相似的QA,请从中选出**最完整、信息最丰富、对用户最有价值**的一个。 + +评判标准(按优先级排序): +1. **回答完整性**:回答内容是否详尽,覆盖的信息点更多 +2. **问题明确度**:问题表述是否清晰、无歧义 +3. **信息密度**:单位字数内有效信息更多,无冗余废话 +4. **实用性**:对用户实际解决问题的帮助程度 +{qa_text} +请直接输出最完整结果。格式:{"question": "xxxxx", "answer": "bbbb"} +""" + + prompt = PromptTemplate(template=prompt, input_variables=["qa_text"]) + chain = prompt | llm_low | StrOutputParser() + response = await chain.ainvoke({"qa_text": qa_text}) + print(response) + return response + # # 解析结果,返回对应QA + # content = response.choices[0].message.content + # # 简单解析逻辑... + # import re + # match = re.search(r'选项(\d+)', content) + # best_idx = int(match.group(1)) - 1 if match else 0 + # + # return qa_group[best_idx] + +if __name__ == '__main__': + asyncio.run(build()) diff --git a/app/chat_qa/deduplication_qa/message_qa.py b/app/chat_qa/deduplication_qa/message_qa.py new file mode 100644 index 0000000..999f44c --- /dev/null +++ b/app/chat_qa/deduplication_qa/message_qa.py @@ -0,0 +1,77 @@ +""" +读取d_qa生成的qa数据,入库到向量库qa表中 +""" +import ast +import asyncio +import json +from pathlib import Path +from typing import List + +from app.client.embedding_client_manager import embedding_client +from app.client.milvus_client_manager import milvus_client +from app.repository.milvus.message_qa_repository import QARepository +# 字符串转 字典 +def safe_parse_json(raw_data): + # 本身就是字典,直接返回 + if isinstance(raw_data, dict): + return raw_data + if not isinstance(raw_data, str): + return None + s = raw_data.strip() + if not s: + return None + try: + return ast.literal_eval(s) + except (ValueError, SyntaxError): + try: + return json.loads(s) + except json.JSONDecodeError as e: + print(f"警告: JSON解析失败: {e},跳过") + return None +async def read_file(file_path:str)->List[dict[str, str]]: + qa_file = Path(file_path) + + qa_list = [] + with open(qa_file, 'r', encoding='utf-8') as f: + for line_num, line in enumerate(f, 1): + line = line.strip() + if not line: + continue + qa_list.append(safe_parse_json( line)) + return qa_list +async def save_qa_milvus(file_path:str): + try : + embedding_client.init() + milvus_client.init() + qa_milvus_repository = QARepository() + qa_milvus_repository.create_collection() + final_qas: List[dict[str, str]] = await read_file(file_path) + + question_list: List[str] = [qa["question"] for qa in final_qas] + + embedding_batch_size = 10 + embedding_ed_all: list[list[float]] = [] + for i in range(0, len(question_list), embedding_batch_size): + embedding_part_texts = question_list[i:i + embedding_batch_size] + embedding_eds = await embedding_client.aembed_documents(embedding_part_texts) + embedding_ed_all.extend(embedding_eds) + + # 构建对象列表 + qa_list = [] + for i, qa in enumerate(final_qas): + qa_list.append({ + "question": qa["question"], + "answer": qa.get("answer", ""), + "question_dense_vector": embedding_ed_all[i] if i < len(embedding_ed_all) else [], + "parent_id": qa.get("parent_id", 0) + }) + await qa_milvus_repository.save_qa_to_milvus(qa_list) + except Exception as e: + print(e) + finally: + await embedding_client.close() + milvus_client.close() + +if __name__ == '__main__': + file_path=r"E:\qa_output\data.txt" + asyncio.run(save_qa_milvus(file_path)) \ No newline at end of file diff --git a/app/chat_qa/graph.py b/app/chat_qa/graph.py new file mode 100644 index 0000000..c87c61e --- /dev/null +++ b/app/chat_qa/graph.py @@ -0,0 +1,80 @@ +import asyncio +from datetime import datetime, timedelta +from typing import List, Dict, Any + +from langgraph.constants import START, END +from langgraph.graph import StateGraph + +from app.chat_qa.context import QAContext +from app.chat_qa.nodes.finalize_node import finalize +from app.chat_qa.nodes.generate_qa_node import generate_qa +from app.chat_qa.nodes.quality_check_node import quality_check +from app.chat_qa.nodes.query_message_node import query_message +from app.chat_qa.nodes.route_by_quality_node import route_by_quality +from app.chat_qa.qa_state import QAState +from app.client.embedding_client_manager import embedding_client +from app.client.milvus_client_manager import milvus_client +from app.client.mysql_client_manager import db_assistant_mysql_client_manager +from app.repository.archive_messages_repository import ArchiveMessagesRepository +from app.repository.milvus.message_qa_repository import QARepository +from app.repository.milvus.summary_repository import SummaryRepository + +graph_builder = StateGraph(state_schema=QAState, context_schema=QAContext) +graph_builder.add_node("generate_qa", generate_qa) +graph_builder.add_node("quality_check", quality_check) +graph_builder.add_node("finalize", finalize) + + +graph_builder.add_edge(START, "generate_qa") +graph_builder.add_edge("generate_qa", "quality_check") + +graph_builder.add_conditional_edges("quality_check", + route_by_quality, + { + "pass": "finalize", + "retry": "generate_qa", + "fail": "finalize" + }) +graph_builder.add_edge("finalize", END) + +graph = graph_builder.compile() + +if __name__ == '__main__': + async def test(day_str: str): + print(f"开始日期:{day_str}") + db_assistant_mysql_client_manager.init() + embedding_client.init() + milvus_client.init() + async with db_assistant_mysql_client_manager.session_factory() as db_session: + archive_messages_mysql_repository = ArchiveMessagesRepository(db_session) + qa_milvus_repository = QARepository() + + # 根据日期查询向量库 + repo = SummaryRepository() + message_list: List[Dict[str, Any]] = repo.query_by_date(day_str) + print(f"向量库数据:{len(message_list)}") + message_content_list = [message["message_context"] for message in message_list] + for message_content in message_content_list: + state: QAState = QAState(msg_time=day_str, chat_history=message_content) + context = QAContext(meta_mysql_repository=archive_messages_mysql_repository, + qa_milvus_repository=qa_milvus_repository + ) + async for chunk in graph.astream(input=state, context=context,stream_mode="custom"): + print(chunk) + milvus_client.close() + await embedding_client.close() + + + start = datetime(2026, 5, 29) + end = datetime(2026, 6, 16) + + result = [] + temp = start + while temp <= end: + # 按 年-月-日 无补零格式输出 + date_format = f"{temp.year}-{str(temp.month).zfill(2)}-{str(temp.day).zfill(2)}" + + result.append(date_format) + temp += timedelta(days=1) + for date in result: + asyncio.run(test(date)) diff --git a/app/chat_qa/nodes/__init__.py b/app/chat_qa/nodes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/chat_qa/nodes/finalize_node.py b/app/chat_qa/nodes/finalize_node.py new file mode 100644 index 0000000..5d6b964 --- /dev/null +++ b/app/chat_qa/nodes/finalize_node.py @@ -0,0 +1,69 @@ +import json +from datetime import datetime +from pathlib import Path +from typing import List, Dict + +from langchain_core.output_parsers import JsonOutputParser +from langchain_core.prompts import PromptTemplate +from langchain_huggingface import HuggingFaceEndpointEmbeddings +from langgraph.runtime import Runtime +from sentry_sdk.integrations import aiohttp + +from app.chat_qa.context import QAContext +from app.chat_qa.qa_state import QAState +from app.client.embedding_client_manager import embedding_client +from app.llm import llm +from app.repository.milvus.message_qa_repository import QARepository +from app.core.log import logger + +""" +知识库入库 +""" +async def finalize(state: QAState, runtime: Runtime[QAContext]): + + final_qas: List[Dict] = state.get("final_qas", []) + chat_history: str = state["chat_history"] + + logger.info(f"原对胡数量:{chat_history}最终生成的QA数据:{len(final_qas)}") + + if len(final_qas)==0: + logger.info(f"生成QA失败,原对胡数量:{chat_history}最终生成的QA数据:{len(final_qas)}") + return + + output_dir = Path("E:/qa_output") + output_dir.mkdir(parents=True, exist_ok=True) + output_file = output_dir / "qa_result.jsonl" # 改用 .jsonl 后缀 + + try: + with open(output_file, 'a', encoding='utf-8') as f: + if isinstance(final_qas, list): + for qa in final_qas: + f.write(json.dumps(qa, ensure_ascii=False) + '\n') + else: + f.write(json.dumps(final_qas, ensure_ascii=False) + '\n') + + logger.info(f"成功追加 {len(final_qas) if isinstance(final_qas, list) else 1} 条QA数据到文件: {output_file}") + + except Exception as e: + logger.error(f"写入QA文件失败: {e}") + + # question_list: List[str] = [qa["question"] for qa in final_qas] + # + # embedding_batch_size = 10 + # embedding_ed_all: list[list[float]] = [] + # for i in range(0, len(question_list), embedding_batch_size): + # embedding_part_texts = question_list[i:i + embedding_batch_size] + # embedding_eds = await embedding_client.aembed_documents(embedding_part_texts) + # embedding_ed_all.extend(embedding_eds) + # + # # 构建对象列表 + # qa_list = [] + # for i, qa in enumerate(final_qas): + # qa_list.append({ + # "question": qa["question"], + # "answer": qa.get("answer", ""), + # "question_dense_vector": embedding_ed_all[i] if i < len(embedding_ed_all) else [], + # "parent_id": qa.get("parent_id", 0) + # }) + # await qa_milvus_repository.save_qa_to_milvus(qa_list) + diff --git a/app/chat_qa/nodes/generate_qa_node.py b/app/chat_qa/nodes/generate_qa_node.py new file mode 100644 index 0000000..e02a71f --- /dev/null +++ b/app/chat_qa/nodes/generate_qa_node.py @@ -0,0 +1,213 @@ +import json + +from langchain_core.messages import SystemMessage, HumanMessage +from langchain_core.output_parsers import JsonOutputParser +from langchain_core.prompts import PromptTemplate +from langgraph.runtime import Runtime + +from app.chat_qa.context import QAContext +from app.chat_qa.qa_state import QAState +from app.dto.quality_score import QualityScore +from app.llm import llm +from app.core.log import logger + + +#检查消息质量 +async def quality_check(chat_history_text:str)->int: + prompt = """ +你是一位培训质量评估专家。请分析以下客服/讲师与学员的对话记录,判断是否值得生成标准化的问答对(QA Pair)。 + +## 对话记录 +{chat_history_text} +## 说明 +- [用户]:表示用户的聊天 +- [销售]:表示客服/销售的回复/提问 +## 评估任务 +请从以下5个维度打分(1-10分),并给出综合判断。 + +## 核心评分原则(优先级从高到低) + +**第一原则:相关性优先** +- 对话是否属于培训咨询场景?(课程价格、报名条件、学习内容、就业方向、学习周期等) +- 如果是,基础分不低于40分 + +**第二原则:问答对应关系** +- 用户是否提出了明确的问题? +- 销售/客服是否给出了直接对应的答案? +- 如果"问题明确 + 答案对应",基础分不低于60分 + +**第三原则:信息完整性(在已回答问题的前提下评估)** +- 不要苛求答案必须覆盖用户所有潜在需求 +- 只要答案直接回应了用户提出的问题,即视为完整 + +--- + +## 五个评分维度(调整后权重) + +### 【相关性】(权重30%,1-10分) +- 是否属于培训咨询场景? + - 课程价格、费用、优惠 → 10分 + - 报名条件、适用人群、学历要求 → 10分 + - 课程内容、学习周期、上课方式 → 10分 + - 就业方向、证书、师资 → 10分 + - 其他培训相关 → 7-9分 + - 与培训无关(如闲聊、技术支持) → 0-3分 + +### 【问答对应度】(权重25%,1-10分) +- 用户问题是否明确?(3分) +- 销售答案是否直接对应问题?(4分) +- 答案是否存在明显错误或答非所问?(3分,无错误即满分) +- 例如:[用户] XXXXXX [销售] XXXXX 表示销售回答了用户的问题 +**评分细则:** +- 用户问A,销售答A = 10分 +- 用户问A,销售答A+B(额外信息) = 10分 +- 用户问A,销售答了一半A,又问了B = 7分 +- 用户问A,销售答非所问 = 0-3分 + +### 【答案准确性】(权重20%,1-10分) +- 答案事实是否正确?(5分) +- 答案是否无歧义、不会误导用户?(5分) + +### 【可复用价值】(权重15%,1-10分) +- 该问题是否是学员常问的问题?(5分) +- 该答案是否可以直接用于未来同类咨询?(5分) + +**重要:只要问题和答案对应,且属于培训场景,此项默认不低于6分** + +### 【表达清晰度】(权重10%,1-10分) +- 答案是否能让普通学员看懂?(5分) +- 答案是否有明显语病或混乱?(5分,无明显问题即满分) + +--- + +## 硬性否决规则(仅以下情况否决,其他一律不否决) + +1. **非培训场景**:对话内容与培训咨询完全无关(如技术支持、物流查询、闲聊) +2. **答案错误**:销售给出了错误信息且可能误导学员 +3. **答非所问**:用户问的是A,销售回答的是完全不相关的B + +**以下情况不再作为否决条件:** +- 答案只有数字/简单事实 +- 对话只有1轮 +- 销售抛出了新问题未闭环 +- 答案没有覆盖用户的所有潜在需求 +- 答案缺少"下一步行动建议" + +--- + + +## 输出格式(必须严格遵循JSON格式) +```json +{{ + "relevance": 10, + "qa_alignment": 10, + "accuracy": 10, + "reusability": 8, + "clarity": 8 +}} +""" + + prompt = PromptTemplate(template=prompt, input_variables=["chat_history_text"]) + output = JsonOutputParser() + chain = prompt | llm | output + result = {} + try: + result = await chain.ainvoke({"chat_history_text": chat_history_text}) + except Exception as e: + logger.error(f"QA质量检查prompt模板错误:{e}") + logger.info(f"消息质量评估:{result}") + score_obj = QualityScore( + relevance=result.get("relevance", 0), + qa_alignment=result.get("qa_alignment", 0), + accuracy=result.get("accuracy", 0), + reusability=result.get("reusability", 0), + clarity=result.get("clarity", 0) + ) + total = score_obj.total + return total + +""" +生成QA +""" +async def generate_qa(state: QAState, runtime: Runtime[QAContext]): + retry_count = state.get("retry_count", 0) + chat_history = state.get("chat_history", 0) + + # 生成QA的系统提示 + system_prompt = """你是一个专业的QA提取专家。请分析以下聊天记录,提取或生成1-2个高质量的QA对。 + 规则: + 1. 优先提取用户明确提出的问题及其对应的回答 + 2. 如果对话中没有明确的问题,根据讨论内容生成一个总结性问题 + 3. 答案必须基于聊天记录中的实际内容,不能编造 + 4. 如果某个问题在聊天记录中没有明确答案,则不生成QA + 5. 最多生成2个QA对,优先选择最有价值的信息 + 例如: + 聊天内容:[用户] 表明自己为准大学生,高考完,非在校大学生。询问线上课程价格是否为1800。[销售] 价格为11800 + 输出:{"question": "询问线上课程价格", "answer": "价格为11800"} + JSON规则(按优先级): + 1. 将中文引号 "" '' 替换为英文引号 "" '' + 2. 删除所有注释(// 和 /* */) + 3. 删除 markdown 代码块标记(```json ```) + 4. 删除 JSON 前后多余的文本说明 + 5. 修复末尾多余的逗号(如 },] 或 },}) + 6. 确保所有字符串用双引号包裹 + 7. 确保布尔值是小写的 true/false,null 是小写的 + 8. 如果键名没有引号,给键名加上双引号 + + 只输出修复后的纯 JSON,不要任何解释、不要 markdown 标记、不要注释。 + 输出格式必须是JSON,不要任何解释、不要 markdown 标记、不要注释: + { + "qa_pairs": [ + {"question": "...", "answer": "..."}, + {"question": "...", "answer": "..."} + ] + } + + """ + current_qas_list = [] + + logger.info(f"聊天内容:{chat_history}") + total = await quality_check(chat_history) + if total <= 75: + return {"retry_count" : (retry_count+1)} + # 调用LLM + messages = [ + SystemMessage(content=system_prompt), + HumanMessage(content=f"聊天记录:\n{chat_history}") + ] + + chain = llm + result = await chain.ainvoke(messages) + try: + res = json.loads(result.content) + # 提取生成的问答对 + new_qa = res.get("qa_pairs", []) + except Exception : + new_qa = is_valid_json(result.content) # 解析失败赋值字符串,后续调用 .get() 崩溃 + logger.info(f"生成QA内容:{new_qa}") + current_qas_list.append(new_qa) + return {"retry_count" : (retry_count+1), "current_qas": current_qas_list} + + # 创建一个校验json格式的函数 +async def is_valid_json(json_str: str)->str: + prompt = """你是一个 JSON 修复专家。请修复以下损坏的 JSON 文本,使其成为合法的标准 JSON。 + 修复规则(按优先级): + 1. 将中文引号 "" '' 替换为英文引号 "" '' + 2. 删除所有注释(// 和 /* */) + 3. 删除 markdown 代码块标记(```json ```) + 4. 删除 JSON 前后多余的文本说明 + 5. 修复末尾多余的逗号(如 },] 或 },}) + 6. 确保所有字符串用双引号包裹 + 7. 确保布尔值是小写的 true/false,null 是小写的 + 8. 如果键名没有引号,给键名加上双引号 + + 只输出修复后的纯 JSON,不要任何解释、不要 markdown 标记、不要注释。 + + 待修复的 JSON: + {input_json} + """ + prompt = PromptTemplate(template=prompt, input_variables=["chat_history_text"]) + output = JsonOutputParser() + chain = prompt | llm | output + result = await chain.ainvoke({"input_json": json_str}) + return result \ No newline at end of file diff --git a/app/chat_qa/nodes/quality_check_node.py b/app/chat_qa/nodes/quality_check_node.py new file mode 100644 index 0000000..303ffed --- /dev/null +++ b/app/chat_qa/nodes/quality_check_node.py @@ -0,0 +1,75 @@ +from langchain_core.messages import SystemMessage, HumanMessage +from langchain_core.output_parsers import JsonOutputParser +from langchain_core.prompts import PromptTemplate +from langgraph.runtime import Runtime + +from app.chat_qa.context import QAContext +from app.chat_qa.qa_state import QAState +from app.llm import llm +from app.core.log import logger +""" +相关问题质检, +""" +async def quality_check(state: QAState, runtime: Runtime[QAContext]): + + prompt="""你是一位培训机构QA质检员。请判断以下QA对是否符合常规培训相关的问题。 + ## 判断标准 + + 1. **问题是否属于培训常见问题**: + - 课程知识疑问(概念、原理、用法) + - 学习方法咨询(怎么学、学习顺序、技巧) + - 实操问题(代码、工具、步骤、报错) + - 考试/面试相关(考点、面试题、准备方法) + - 就业/职业规划(岗位、薪资、发展方向) + + 2. **答案是否对应问题**: + - 答案内容与问题相关 + - 如果聊天记录中没有明确答案,answer为空是合理的 + + 3. **以下情况判定为不合理**: + - 闲聊寒暄("在吗"、"你好"、"今天天气") + - 纯情绪表达("太难了"、"不想学了") + - 系统/账号问题("密码忘了"、"怎么登录") + - 问题过于模糊,没有具体指向("介绍一下"、"说说看") + + ## 输出格式(JSON) + { + "is_valid": true/false, + "score": 0.0-1.0, + "reason": "简要说明判定理由" + }""" + current_qas_list = state.get("current_qas", []) + chat_history = state["chat_history"] + + if len(current_qas_list) == 0: + return {"is_valid": True}# 聊天本身数据质量问题,直接跳过 + # 最终通过的QA + final_qas = [] + for current_qas in current_qas_list: + + messages = [ + SystemMessage(content=prompt), + HumanMessage(content=f"原聊天内容:{chat_history},待质检的QA对:\n{current_qas}") + ] + try: + output = JsonOutputParser() + chain = llm | output + result = await chain.ainvoke(messages) + # 容错 + if isinstance(result, list) and len(result) > 0: + # 如果是数组,取第一个元素 + data = result[0] + elif isinstance(result, dict): + data = result + else: + # 空兜底,避免报错 + data = {} + if result.get("is_valid", False): + final_qas.append(current_qas) + logger.info(f"QA质检结果:{result}") + except Exception as e: + logger.error(f"QA质检失败:{e}") + return {"is_valid": True, "final_qas": final_qas} # 异常:跳过 + if len(final_qas) == 0: + return {"is_valid": False} + return {"is_valid": True, "final_qas": final_qas} diff --git a/app/chat_qa/nodes/query_message_node.py b/app/chat_qa/nodes/query_message_node.py new file mode 100644 index 0000000..7a60bb7 --- /dev/null +++ b/app/chat_qa/nodes/query_message_node.py @@ -0,0 +1,30 @@ +from typing import List, Dict, Any + +from langgraph.runtime import Runtime + +from app.chat_qa.context import QAContext +from app.chat_qa.qa_state import QAState +from app.repository.milvus.summary_repository import SummaryRepository +from app.core.log import logger + +""" +查询历史记录 +""" +async def query_message(state: QAState, runtime: Runtime[QAContext]): + # 1 根据时间查询向量库 + # 从state获取日期 + date = state.get("msg_time") + + if not date: + return {"retry_count": state.get("retry_count", 0) + 1, "message_summary": []} + + # 根据日期查询向量库 + repo = SummaryRepository() + message_list: List[Dict[str, Any]] = repo.query_by_date(date) + logger.info(f"根据时间{ date}查询向量库结果:{len(message_list)}") + message_content_list = [message["message_context"] for message in message_list] + retry_count = state.get("retry_count", 0) + return { + "retry_count": retry_count + 1, + "chat_history": message_content_list + } diff --git a/app/chat_qa/nodes/route_by_quality_node.py b/app/chat_qa/nodes/route_by_quality_node.py new file mode 100644 index 0000000..064959a --- /dev/null +++ b/app/chat_qa/nodes/route_by_quality_node.py @@ -0,0 +1,18 @@ +from app.chat_qa.qa_state import QAState + + +# ==================== 条件路由 ==================== +def route_by_quality(state: QAState) -> str: + """根据质检结果和重试次数决定路由""" + is_valid = state.get("is_valid", False) + retry = state["retry_count"] + qas = state.get("current_qas", []) + + # 质检通过:有有效QA且评分足够 + if is_valid : + return "pass" + + # 质检不通过,但还有重试机会(最多3次) + if retry < 3: + return "retry" + return "fail" \ No newline at end of file diff --git a/app/chat_qa/qa_state.py b/app/chat_qa/qa_state.py new file mode 100644 index 0000000..f58cd0f --- /dev/null +++ b/app/chat_qa/qa_state.py @@ -0,0 +1,12 @@ +from typing import TypedDict, List, Dict, Optional + + +class QAState(TypedDict): + msg_time: str # 消息时间 + chat_history: str # 历史聊天记录 + current_qas: List[Dict] # 当前轮次生成的QA + is_valid: bool # 质检是否合格 + retry_count: int # 重试次数 + final_qas: List[Dict] # 最终通过的QA + error_message: Optional[str] # 错误信息 + generation_reasoning: str # 生成过程的思考记录 \ No newline at end of file diff --git a/app/client/embedding_client_manager.py b/app/client/embedding_client_manager.py index 60bad5e..d28a3a9 100644 --- a/app/client/embedding_client_manager.py +++ b/app/client/embedding_client_manager.py @@ -3,6 +3,8 @@ import time import aiohttp import requests +from aiohttp import ClientSession +from langchain_huggingface import HuggingFaceEndpointEmbeddings from app.conf.app_config import EmbeddingConfig, app_config @@ -44,7 +46,14 @@ class EmbeddingClientManager: embeddings = await self.aembed_documents([text]) return embeddings[0] if embeddings else [] - + # # 异步进入上下文 = 执行 init + # async def __aenter__(self): + # await self.init() + # return self + # + # # 异步退出上下文 = 执行 close + # async def __aexit__(self, exc_type, exc, tb): + # await self.close() embedding_client = EmbeddingClientManager(app_config.embedding) if __name__ == "__main__": diff --git a/app/core/liftspan.py b/app/core/liftspan.py new file mode 100644 index 0000000..cad2a78 --- /dev/null +++ b/app/core/liftspan.py @@ -0,0 +1,23 @@ +from contextlib import asynccontextmanager + +from fastapi import FastAPI + +from app.client.embedding_client_manager import embedding_client +from app.client.milvus_client_manager import milvus_client +from app.client.mysql_client_manager import db_assistant_mysql_client_manager + +""" +生命周期 +容器启动时执行 +yield +容器停止时执行 +""" +@asynccontextmanager +async def lifespan(app: FastAPI): + db_assistant_mysql_client_manager.init() + embedding_client.init() + milvus_client.init() + yield + await db_assistant_mysql_client_manager.close() + await embedding_client.close() + milvus_client.close() \ No newline at end of file diff --git a/app/dto/qa_info.py b/app/dto/qa_info.py new file mode 100644 index 0000000..ae8bd8b --- /dev/null +++ b/app/dto/qa_info.py @@ -0,0 +1,12 @@ +from dataclasses import Field +from typing import List + +from openai import BaseModel + + +class QAPair(BaseModel): + question: str = Field(description="从聊天记录中提取或生成的问题") + answer: str = Field(description="问题的答案,如果没有明确答案则留空") + +class QAList(BaseModel): + qa_pairs: List[QAPair] = Field(description="生成的QA对列表,1-2个") diff --git a/app/dto/quality_score.py b/app/dto/quality_score.py new file mode 100644 index 0000000..09ab1ee --- /dev/null +++ b/app/dto/quality_score.py @@ -0,0 +1,28 @@ +from dataclasses import dataclass + + +# | **相关性** | **10/10** | 课程价格 = 培训咨询核心场景 | +# | **问答对应度** | **10/10** | 用户问价格,销售答价格,直接对应 | +# | **答案准确性** | **10/10** | 价格数字明确,更正了之前的错误 | +# | **可复用价值** | **8/10** | 价格问答是高频问题,答案可直接复用 | +# | **表达清晰度** | **8/10** | 数字清楚,语言通俗,虽有道歉但不影响理解 | +@dataclass +class QualityScore: + relevance: int + qa_alignment: int + accuracy: int + reusability: int + clarity: int + + @property + def total(self) -> int: + weights = [0.3, 0.25, 0.20, 0.15, 0.10] + scores = [ + self.relevance, + self.qa_alignment, + self.accuracy, + self.reusability, + self.clarity + ] + valid_scores = [s if s is not None else 0 for s in scores] + return sum(s * w for s, w in zip(valid_scores, weights)) * 10 # 转换为百分制 \ No newline at end of file diff --git a/app/llm.py b/app/llm.py index b18a76e..21a9b86 100644 --- a/app/llm.py +++ b/app/llm.py @@ -11,8 +11,18 @@ http_client = Client( llm = init_chat_model(model=app_config.llm.model_name, api_key=app_config.llm.api_key, base_url=app_config.llm.base_url, - temperature=1, + temperature=0.8, extra_body={"thinking": {"type": "disabled"}}, max_retries=3, request_timeout=120, http_client=http_client) + + +llm_low = init_chat_model(model=app_config.llm.model_name, + api_key=app_config.llm.api_key, + base_url=app_config.llm.base_url, + temperature=0.1, + extra_body={"thinking": {"type": "disabled"}}, + max_retries=3, + request_timeout=120, + http_client=http_client) \ No newline at end of file diff --git a/app/repository/archive_messages_repository.py b/app/repository/archive_messages_repository.py index 16127cf..de5b4e4 100644 --- a/app/repository/archive_messages_repository.py +++ b/app/repository/archive_messages_repository.py @@ -10,7 +10,7 @@ class ArchiveMessagesRepository: def __init__(self, session: AsyncSession): self.session = session - async def get_message_statistics_by_date(self, start_date: str = None, end_date: str = None) -> List[ArchiveMessages]: + async def get_message_statistics_by_date(self, start_date: int = None, end_date: int = None) -> List[ArchiveMessages]: """ 根据日期范围获取消息记录 @@ -29,14 +29,14 @@ class ArchiveMessagesRepository: params = {} if start_date: - conditions.append(" and DATE(FROM_UNIXTIME(msgtime / 1000)) >= :start_date") + conditions.append(" and msgtime >= :start_date") params["start_date"] = start_date if end_date: - conditions.append("DATE(FROM_UNIXTIME(msgtime / 1000)) <= :end_date") + conditions.append(" msgtime <= :end_date") params["end_date"] = end_date - base_query += " WHERE 1=1 and roomid='' and msgtype='text' " - #base_query += " WHERE (from_user='wmI1AkDQAA3h0jxrRpeaHZhMKeHExA4w' )or( from_user='LiHeYi' and to_user='[\"wmI1AkDQAA3h0jxrRpeaHZhMKeHExA4w\"]') and roomid='' and msgtype='text' " + #base_query += " WHERE 1=1 and roomid='' and msgtype='text' " + base_query += " WHERE (from_user='BuShouShiJinBuGaiMing') and roomid='' and msgtype='text' " if conditions: base_query += " AND ".join(conditions)+" " base_query += " GROUP BY DATE(FROM_UNIXTIME(msgtime / 1000)), from_user ORDER BY created_at DESC, from_user;" diff --git a/app/repository/milvus/message_qa_repository.py b/app/repository/milvus/message_qa_repository.py new file mode 100644 index 0000000..01c805b --- /dev/null +++ b/app/repository/milvus/message_qa_repository.py @@ -0,0 +1,101 @@ +from datetime import datetime +from typing import Optional, List, Dict, Any + +from pymilvus import MilvusClient, DataType + +from app.client.milvus_client_manager import milvus_client +from app.conf.app_config import app_config +from app.core.log import logger + + +class QARepository: + collection_name: str = 'message_qa' + + def __init__(self): + self.dim = app_config.milvus.embedding_size + self._ensure_connection() + + def _ensure_connection(self): + if milvus_client.client is None: + milvus_client.init() + + def create_collection(self, dim: int = None) -> bool: + """ + 创建消息摘要集合 + + Args: + dim: 向量维度,默认从配置读取 + + Returns: + 是否成功创建(已存在返回False) + """ + if dim is not None: + self.dim = dim + + if milvus_client.has_collection(self.collection_name): + return False + + schema = milvus_client.client.create_schema( + auto_id=True, + enable_dynamic_field=True, + description="QA向量集合" + ) + + schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True) + schema.add_field(field_name="question", datatype=DataType.VARCHAR, max_length=1024) + schema.add_field(field_name="answer", datatype=DataType.VARCHAR, max_length=65535) + schema.add_field(field_name="parent_id", datatype=DataType.INT64) + schema.add_field(field_name="question_dense_vector", datatype=DataType.FLOAT_VECTOR, dim=1024) + schema.add_field(field_name="created_at", datatype=DataType.INT64) + + index_params = milvus_client.client.prepare_index_params() + index_params.add_index( + field_name="question_dense_vector", + index_type="HNSW", + metric_type="COSINE", + params={"M": 32, "efConstruction": 300} + ) + milvus_client.client.create_collection( + collection_name=self.collection_name, + schema=schema, + index_params=index_params + ) + + return True + + async def save_qa_to_milvus(self, qa_list: List[Dict[str, Any]]) -> List[int]: + """ + 将QA数据入库到Milvus + + Args: + qa_pairs: QA对列表,格式 [{"question": "...", "answer": "..."}, ...] + parent_id: 父记录ID,默认为0 + + Returns: + 插入的记录ID列表 + """ + try: + # 构建入库数据 + created_at = int(datetime.now().timestamp()) + data = [] + for qa in qa_list: + data.append({ + "question": qa.get("question", ""), + "answer": qa.get("answer", ""), + "parent_id": qa.get("parent_id", 0), + "question_dense_vector": qa.get("question_dense_vector", []), + "created_at": created_at + }) + + # 插入数据 + result = milvus_client.client.insert( + collection_name=self.collection_name, + data=data + ) + + logger.info(f"QA数据入库成功,插入 {len(data)} 条记录") + return result.get("ids", []) + + except Exception as e: + logger.error(f"QA数据入库失败: {str(e)}", exc_info=True) + return [] \ No newline at end of file diff --git a/app/repository/milvus/summary_repository.py b/app/repository/milvus/summary_repository.py index 88a15dc..32f1f9d 100644 --- a/app/repository/milvus/summary_repository.py +++ b/app/repository/milvus/summary_repository.py @@ -154,3 +154,26 @@ class SummaryRepository: def close(self): """关闭连接""" milvus_client.close() + + def query_by_date(self, date_str: str) -> List[Dict[str, Any]]: + """ + 根据日期查询消息摘要 + Args: + date_str: 日期字符串,格式 YYYY-M-D(如 2026-1-1) + Returns: + 查询结果列表,每条记录包含 msg_time, msg_type, from_user, to_user, room_id, summary, created_at + """ + self._ensure_connection() + + if not milvus_client.has_collection(self.collection_name): + return [] + + expr = f'msg_time == "{date_str}"' + + result = milvus_client.client.query( + collection_name=self.collection_name, + filter=expr, + output_fields=["msg_time", "msg_type", "from_user", "to_user", "message_context", "summary", "created_at"] + ) + + return result \ No newline at end of file diff --git a/app/summary/service.py b/app/summary/service.py index e71e955..9c0df16 100644 --- a/app/summary/service.py +++ b/app/summary/service.py @@ -24,11 +24,27 @@ class SummaryService: self.embedding_client = embedding_client self.summary_repository = summary_repository + async def get_day_ms_timestamp(self, date_str: str): + """ + 输入日期字符串 如 "2025-06-10" + :return: start_ms(当日0点毫秒时间戳), end_ms(当日23:59:59毫秒时间戳) + """ + # 解析日期,生成当日 00:00:00 + day_start = datetime.strptime(date_str, "%Y-%m-%d") + # 当日最后一秒 23:59:59 + day_end = day_start + timedelta(days=1) - timedelta(seconds=1) + + # timestamp() 返回秒,*1000 转毫秒,转整数 + start_ms = int(day_start.timestamp() * 1000) + end_ms = int(day_end.timestamp() * 1000) + return start_ms, end_ms + async def get_message_summary(self, date: str = None): stime = time.time() if date: - day_ArchiveMessages = await self.archive_messages_repository.get_message_statistics_by_date(start_date=date, - end_date=date) + start_ts, end_ts = await self.get_day_ms_timestamp(date) + day_ArchiveMessages = await self.archive_messages_repository.get_message_statistics_by_date(start_date=start_ts, + end_date=end_ts) logger.info(f"{date}共产生了{len(day_ArchiveMessages)}条会话") else: day_ArchiveMessages = await self.archive_messages_repository.get_message_statistics_by_date() @@ -48,7 +64,7 @@ class SummaryService: for date_a in date_user_message_a: date_user_b = date_a.to_user - # if date_user_b != "[\"wmI1AkDQAA3h0jxrRpeaHZhMKeHExA4w\"]": + # if date_user_b != "[\"wmI1AkDQAAdVhy2ENtY6fecaw9-pi4uQ\"]": # continue date_user_a = date_a.from_user @@ -56,8 +72,9 @@ class SummaryService: date_user_a_append = "[\"" + date_user_a + "\"]" # 判断只要存在就跳过 if date_user_a + date_user_b in date_user_message_a_set or date_user_b_clean + date_user_a_append in date_user_message_a_set: + logger.info(f"已存在{date_user_a}和{date_user_b}在{day_date}对话,跳过") continue - logger.info(f"查询{date_user_a}和{date_user_b}对话开始") + logger.info(f"查询{date_user_a}和{date_user_b}在{day_date}对话开始") list1 = await self.archive_messages_repository.get_message_statistics_by_date_user(day_date, date_user_a, date_user_b) @@ -67,6 +84,7 @@ class SummaryService: date_user_a_append) # 查询过的聊天账号,后续不再查询 date_user_message_a_set.add(date_user_a + date_user_b) + date_user_message_a_set.add(date_user_b_clean + date_user_a_append) coro_list = list1 + list2 coro_list.sort(key=lambda x: x.created_at, reverse=False) @@ -80,30 +98,48 @@ class SummaryService: filter_gossip_message_res, 'content') else str(filter_gossip_message_res) logger.info(f"查询{date_user_a}和{date_user_b}对话进行保留语义骨架,去除闲聊填充") # 摘要 - summary_res = await self.date_message_summary(coro_list) + summary_res = await self.date_message_summary(coro_list, day_date) summary_text = str(summary_res.content) if hasattr(summary_res, 'content') else str(summary_res) logger.info(f"查询{date_user_a}和{date_user_b}对话进行摘要") except Exception as e: - logger.error(f"操作LLM失败: {e}") - # 摘要向量 - batch_embeddings = await self.embedding_client.aembed_documents( - [summary_text, filter_gossip_message_text]) + logger.error(f"{date_user_a}和{date_user_b}对话操作LLM失败: {e}") + batch_embeddings=[] try: - self.summary_repository.insert( - msg_time=[day_date], - msg_type=[0], - from_user=[date_a.from_user], - to_user=[date_user_b_clean], - room_id=[date_a.roomid or ""], - message_context=[filter_gossip_message_text], - summary=[summary_text], - message_dense_vector=[batch_embeddings[1]], - summary_dense_vector=[batch_embeddings[0]] - ) - logger.info(f"查询{date_user_a}和{date_user_b}对话成功入库") + # 摘要向量 + logger.info(f"查询{date_user_a}和{date_user_b}去除闲聊填充数据:{filter_gossip_message_text}") + logger.info(f"查询{date_user_a}和{date_user_b}摘要:{summary_text}") + batch_embeddings = await self.embedding_client.aembed_documents( + [summary_text, filter_gossip_message_text]) + logger.info(f"查询{date_user_a}和{date_user_b}对话向量数{len(batch_embeddings)}成功入库") except Exception as e: - logger.error(f"操作milvus失败: {e}") + logger.warning(f"{date_user_a}和{date_user_b}对话embeddings失败,尝试重试: {e}") + try: + time.sleep(1) + batch_embeddings = await self.embedding_client.aembed_documents( + [summary_text, filter_gossip_message_text]) + logger.info(f"查询{date_user_a}和{date_user_b}对话向量数{len(batch_embeddings)}重试成功入库") + except Exception as retry_error: + logger.error(f"{date_user_a}和{date_user_b}对话embeddings重试后仍然失败: {retry_error}") + + if not batch_embeddings or len(batch_embeddings) < 2: + batch_embeddings=[[[0]],[[1]]] + else: + try: + self.summary_repository.insert( + msg_time=[day_date], + msg_type=[0], + from_user=[date_a.from_user], + to_user=[date_user_b_clean], + room_id=[date_a.roomid or ""], + message_context=[filter_gossip_message_text], + summary=[summary_text], + message_dense_vector=[batch_embeddings[1]], + summary_dense_vector=[batch_embeddings[0]] + ) + logger.info(f"查询{date_user_a}和{date_user_b}对话成功入库") + except Exception as e: + logger.error(f"{date_user_a}和{date_user_b}对话操作milvus失败: {e}") logger.info(f"运行结束:{(time.time()-stime)}") async def filter_gossip_message(self, coro_list: List[ArchiveMessages]) -> str: @@ -131,10 +167,9 @@ class SummaryService: prompt_template = PromptTemplate(template=prompt, input_variables=["message_str"]) chain = prompt_template | llm result = await chain.ainvoke({"message_str": message_str}) - logger.info(f"filter_gossip_message result: {result}") return result - async def date_message_summary(self, coro_list: List[ArchiveMessages]) -> str: + async def date_message_summary(self, coro_list: List[ArchiveMessages], day_date: str) -> str: prompt = """ # 聊天历史轻量化摘要任务 任务:生成极简轮次摘要,用于替换原始对话节省上下文窗口 @@ -143,7 +178,6 @@ class SummaryService: ## 说明 其中INTERNAL表示销售,EXTERNAL表示客户 输出格式示例(无多余文字): - 【日期】 202X年X月X日 ** 核心诉求** 用户反馈订单 #12345 物流停滞超7天未更新。 询问是否支持跨店满减叠加优惠券。 @@ -154,13 +188,12 @@ class SummaryService: [明日 10:00] 跟进物流签收状态并回访用户。 ** 关键标签**:#物流异常#优惠规则咨询#情绪安抚 """ - lines = [f"{msg.created_at} {msg.from_role}:{msg.content}" for msg in coro_list] + lines = [f" {msg.from_role}:{msg.content}" for msg in coro_list] message_str = "\n".join(lines) - prompt_template = PromptTemplate(template=prompt, input_variables=["message_str"]) + prompt_template = PromptTemplate(template=prompt, input_variables=["message_str","day_date"]) chain = prompt_template | llm - result = await chain.ainvoke({"message_str": message_str}) - logger.info(f"date_message_summary result: {result}") + result = await chain.ainvoke({"message_str": message_str,"day_date":day_date}) return result @@ -183,14 +216,15 @@ async def build(day:str): if __name__ == '__main__': # - start = datetime(2026, 5, 22) - end = datetime(2026, 6, 14) + start = datetime(2026, 6, 17) + end = datetime(2026, 6, 17) result = [] temp = start while temp <= end: # 按 年-月-日 无补零格式输出 date_format = f"{temp.year}-{temp.month}-{temp.day}" + result.append(date_format) temp += timedelta(days=1) for date in result: diff --git a/app/summary/task.py b/app/summary/task.py index dac475e..7a5349a 100644 --- a/app/summary/task.py +++ b/app/summary/task.py @@ -1,88 +1,68 @@ -import asyncio -import logging from datetime import datetime, timedelta from typing import Optional from apscheduler.schedulers.asyncio import AsyncIOScheduler +from fastapi import FastAPI +from app.client.embedding_client_manager import EmbeddingClientManager, embedding_client +from app.client.milvus_client_manager import milvus_client from app.client.mysql_client_manager import db_assistant_mysql_client_manager from app.repository.archive_messages_repository import ArchiveMessagesRepository +from app.repository.milvus.summary_repository import SummaryRepository from app.summary.service import SummaryService +from app.core.log import logger - -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(levelname)s - %(message)s', - handlers=[logging.FileHandler('summary_task.log'), logging.StreamHandler()] -) -logger = logging.getLogger(__name__) - +app = FastAPI(title="消息摘要服务", version="1.0") +scheduler = AsyncIOScheduler(timezone='Asia/Shanghai') async def generate_daily_summary(date: Optional[str] = None): - """ - 生成指定日期的消息摘要,如果不传日期则生成前一天的摘要 - - Args: - date: 日期字符串,格式 YYYY-MM-DD,不传则默认前一天 - """ if not date: yesterday = datetime.now() - timedelta(days=1) - date = yesterday.strftime("%Y-%m-%d") - + date = yesterday.strftime("%Y-%-m-%-d") # 格式: 2026-6-15 + logger.info(f"开始生成 {date} 的消息摘要...") - + try: db_assistant_mysql_client_manager.init() + embedding_client.init() + milvus_client.init() + async with db_assistant_mysql_client_manager.session_factory() as db_assistant: archive_messages_repository = ArchiveMessagesRepository(db_assistant) - service = SummaryService(archive_messages_repository) - summaries = await service.get_message_summary(date) - - logger.info(f"生成完成,共生成 {len(summaries)} 条摘要") - for summary in summaries: - logger.info(f"日期: {summary.date}, 发送人: {summary.from_user}, 接收人: {summary.to_user}") - - return summaries + summary_repository = SummaryRepository() + service = SummaryService(archive_messages_repository, embedding_client, summary_repository) + await service.get_message_summary(date) + + logger.info(f"{date} 消息摘要生成完成") except Exception as e: logger.error(f"生成摘要失败: {str(e)}", exc_info=True) raise + finally: + await embedding_client.close() - -def start_scheduler(): - """ - 启动定时任务调度器,每天凌晨2点执行 - """ - scheduler = AsyncIOScheduler(timezone='Asia/Shanghai') - +@app.on_event("startup") +async def startup_event(): scheduler.add_job( generate_daily_summary, trigger='cron', hour=2, minute=0, second=0, - id='daily_summary_task', + id='daily_summary', name='每日消息摘要任务', replace_existing=True ) - - logger.info("定时任务调度器已启动,每天凌晨2:00执行消息摘要任务") - scheduler.start() - - try: - asyncio.get_event_loop().run_forever() - except (KeyboardInterrupt, SystemExit): - logger.info("正在关闭定时任务调度器...") - scheduler.shutdown() + logger.info("定时任务调度器已启动,每天凌晨2:00自动执行消息摘要任务") + + +@app.on_event("shutdown") +async def shutdown_event(): + scheduler.shutdown() + logger.info("定时任务调度器已关闭") if __name__ == '__main__': - import sys - - if len(sys.argv) > 1: - # 如果传入了日期参数,直接生成指定日期的摘要 - target_date = sys.argv[1] - asyncio.run(generate_daily_summary(target_date)) - else: - # 否则启动定时任务调度器 - start_scheduler() \ No newline at end of file + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=8000) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 9a9ab94..6316954 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,8 +16,11 @@ dependencies = [ "langchain-huggingface>=1.2.2", "langgraph>=1.2.4", "loguru>=0.7.3", + "numpy>=2.4.6", "omegaconf>=2.3.0", "pymilvus>=3.0.0", "pyyaml>=6.0.3", + "scikit-learn>=1.9.0", + "sentence-transformers>=5.6.0", "sqlalchemy>=2.0.50", ] diff --git a/uv.lock b/uv.lock index bf4892b..03602a2 100644 --- a/uv.lock +++ b/uv.lock @@ -439,6 +439,29 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/ff/371ea7d252656ee1eb6d83eeeef3d1d0c6baf1d6497687d081ea03814670/cryptography-48.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:9a49ca6c81417f6a5edb50375a60cccdd70fa0a91a5211829dbea74eba94d2ac", size = 3793408, upload-time = "2026-06-09T22:32:15.191Z" }, ] +[[package]] +name = "cuda-bindings" +version = "12.9.4" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "cuda-pathfinder", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, +] +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a9/c1/dabe88f52c3e3760d861401bb994df08f672ec893b8f7592dc91626adcf3/cuda_bindings-12.9.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fda147a344e8eaeca0c6ff113d2851ffca8f7dfc0a6c932374ee5c47caa649c8", size = 12151019, upload-time = "2025-10-21T14:51:43.167Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/56/e465c31dc9111be3441a9ba7df1941fe98f4aa6e71e8788a3fb4534ce24d/cuda_bindings-12.9.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:32bdc5a76906be4c61eb98f546a6786c5773a881f3b166486449b5d141e4a39f", size = 11906628, upload-time = "2025-10-21T14:51:49.905Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/84/1e6be415e37478070aeeee5884c2022713c1ecc735e6d82d744de0252eee/cuda_bindings-12.9.4-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56e0043c457a99ac473ddc926fe0dc4046694d99caef633e92601ab52cbe17eb", size = 11925991, upload-time = "2025-10-21T14:51:56.535Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/af/6dfd8f2ed90b1d4719bc053ff8940e494640fe4212dc3dd72f383e4992da/cuda_bindings-12.9.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8b72ee72a9cc1b531db31eebaaee5c69a8ec3500e32c6933f2d3b15297b53686", size = 11922703, upload-time = "2025-10-21T14:52:03.585Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/19/90ac264acc00f6df8a49378eedec9fd2db3061bf9263bf9f39fd3d8377c3/cuda_bindings-12.9.4-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d80bffc357df9988dca279734bc9674c3934a654cab10cadeed27ce17d8635ee", size = 11924658, upload-time = "2025-10-21T14:52:10.411Z" }, +] + +[[package]] +name = "cuda-pathfinder" +version = "1.5.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/c8/26f2e4aae92f11522a96043892ba39a90eac610d5242523aa863212bc1c7/cuda_pathfinder-1.5.5-py3-none-any.whl", hash = "sha256:0228c023f95d1480f143ef5c8922d27a2ab052087a942e81dc289c9eb8f91689", size = 51671, upload-time = "2026-05-27T01:21:25.413Z" }, +] + [[package]] name = "detect-installer" version = "0.1.0" @@ -1048,6 +1071,15 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/8d/302cb2057b7513327b4d575cff6b1d066ee6431a5357fc3f8867cd684406/jiter-0.15.0-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d5d6090cdc1b7c9e780dfb04949a990adb1e301a2fc0bbcee7de4638d33f9a", size = 344469, upload-time = "2026-05-19T10:09:46.864Z" }, ] +[[package]] +name = "joblib" +version = "1.5.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hash = "sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3", size = 331603, upload-time = "2025-12-15T08:41:46.427Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, +] + [[package]] name = "jsonpatch" version = "1.33" @@ -1333,6 +1365,15 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + [[package]] name = "multidict" version = "6.7.1" @@ -1432,6 +1473,24 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, ] +[[package]] +name = "narwhals" +version = "2.22.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/3c/c4ef2164a71c1a63d7f1ae411c4082c5fa872405106db60a4b7114989ad7/narwhals-2.22.1.tar.gz", hash = "sha256:d62920805a0a43b7ff8b54b0c0d3142d796f8a9301836ada37e573d6a33cbcd9", size = 647493, upload-time = "2026-06-05T12:34:34.051Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/48/ca/36339329c4604adbcc99c899b7eb1ce1a555c499b6a6860757dc9bfed36d/narwhals-2.22.1-py3-none-any.whl", hash = "sha256:60567d774edf77db53906f89d9fbd164e66e56d66d388e1e6990f17ac33cfb53", size = 454815, upload-time = "2026-06-05T12:34:32.289Z" }, +] + +[[package]] +name = "networkx" +version = "3.6.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, +] + [[package]] name = "numpy" version = "2.4.6" @@ -1493,6 +1552,140 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, ] +[[package]] +name = "nvidia-cublas-cu12" +version = "12.8.4.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921, upload-time = "2025-03-07T01:44:31.254Z" }, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.8.90" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621, upload-time = "2025-03-07T01:40:21.213Z" }, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.8.93" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029, upload-time = "2025-03-07T01:42:13.562Z" }, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.8.90" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765, upload-time = "2025-03-07T01:40:01.615Z" }, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.10.2.21" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, +] +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, +] + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.3.3.83" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, +] +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, +] + +[[package]] +name = "nvidia-cufile-cu12" +version = "1.13.1.3" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834, upload-time = "2025-03-07T01:45:50.723Z" }, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.9.90" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976, upload-time = "2025-03-07T01:46:23.323Z" }, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.7.3.90" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "nvidia-cusparse-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, +] +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, +] + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.5.8.93" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, +] +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, +] + +[[package]] +name = "nvidia-cusparselt-cu12" +version = "0.7.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691, upload-time = "2025-02-26T00:15:44.104Z" }, +] + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.27.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229, upload-time = "2025-06-26T04:11:28.385Z" }, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.8.93" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, +] + +[[package]] +name = "nvidia-nvshmem-cu12" +version = "3.4.5" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b5/09/6ea3ea725f82e1e76684f0708bbedd871fc96da89945adeba65c3835a64c/nvidia_nvshmem_cu12-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:042f2500f24c021db8a06c5eec2539027d57460e1c1a762055a6554f72c369bd", size = 139103095, upload-time = "2025-09-06T00:32:31.266Z" }, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.8.90" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, +] + [[package]] name = "omegaconf" version = "2.3.0" @@ -2231,6 +2424,30 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/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 = "safetensors" +version = "0.8.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/06/f955dbbb1859e3bd23c8ac6141af5106e7ad5fedec4a3a6e3d60f94b7001/safetensors-0.8.0.tar.gz", hash = "sha256:fabaf3e0f18a6618d9b36560682562157f77c2b71fcffc7b432be2baed9d753d", size = 325846, upload-time = "2026-06-09T07:52:25.563Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/a0/f718cda65b05407d228f97602cf60dca269c979867aa5beb25410de26cd3/safetensors-0.8.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c554f85858e05226d3c2828e32395e677434685d6d94594a41643361c5e837f0", size = 473568, upload-time = "2026-06-09T07:52:18.829Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/b1/fa7c600e7dceae12e9606c7578cbc9ff1e1ed55844883ee5c92205e86226/safetensors-0.8.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:c80201d22cbf405b80647a60ada77bba06c8fba2da2743ba1e89cdcc39a81f25", size = 484562, upload-time = "2026-06-09T07:52:17.518Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/7d/65a7de0af421317bb36a067241e4235fff194eed60b961ed6d3f59a3fc60/safetensors-0.8.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a46e5ff292c356d6991e60942ba7f79817682d3a2cef0702136448cb9c4d235", size = 502844, upload-time = "2026-06-09T07:52:07.624Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/91/4f/3175c9d75634e0e0dda0082794193521035edd7c70a6f212bf33ca06ddf4/safetensors-0.8.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4124502b78f03534117c848f87a39b8f31e577b15eff423bf8bfb95f2a8c30d0", size = 511823, upload-time = "2026-06-09T07:52:09.565Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/87/846c289e7aa2299eff406335717cf43ce8777194ece8aad75772e0411615/safetensors-0.8.0-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc0a787ba8a35be368ee3574edfa2b1ad389eebd0a72e482ae275490e3f6c98", size = 633461, upload-time = "2026-06-09T07:52:11.128Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/22/8d64d9df2c45d5ded401df889d0ad90882804ca172d79ec4f0df8f727fe0/safetensors-0.8.0-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040070828e36dc8e122178bbbd5830ff9e97920affb84cbe0f46442497bed358", size = 545148, upload-time = "2026-06-09T07:52:13.603Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/28/50/f203ff3a3ddfe19308efc83c5a3a29ed02bf786732ec35e68bf9162f3365/safetensors-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6f3f93c9a0a7cc2788ee63fb763353d4bd2e89b0751bc78fcf7dda00bea774", size = 516040, upload-time = "2026-06-09T07:52:16.29Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/fb/cdaed17ceb2948784fd9c36b6fd3e951b608547cea81a48e8ee6f8cfdfcb/safetensors-0.8.0-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:fcdd41ec4628fee5799f807c73c353629130fbd942aa23d83c623dd6c9d52d78", size = 513832, upload-time = "2026-06-09T07:52:12.37Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/49/1e15de264dcc3b77943d2d0c56a95809956883b1c2d6d585c792523f180b/safetensors-0.8.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e9f537aa183a38ace122d27303dcd986b26bd2a7591f9181d7f0c396f4677ca", size = 559930, upload-time = "2026-06-09T07:52:14.743Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/43/bf38443278eab4b1be1fce2931e2b012ad9cb7df52ada751d0aab8f7659a/safetensors-0.8.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87eec7ffed2b809f05a398a8becb7d013f19f7837cd15d9748580d6cf30dbaf4", size = 678670, upload-time = "2026-06-09T07:52:20.032Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/e3/68cd3fa5b48488e84add63e04cb12f3bc28ae4638c06d4508c6e88823d0e/safetensors-0.8.0-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:4a95ae2b05d7726d751da4ebf626a2ca782b706e101bd894c95bc2450b1cffcc", size = 786679, upload-time = "2026-06-09T07:52:21.322Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/29/4b/1c19c509d56e01f4fbb3d0a2e597450f6cc04d1d56cf52defb0a62dfd715/safetensors-0.8.0-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae091f16662658bdc019a4ff6cb4c085bb7d725eb5978b183ffd265863b6d2d", size = 765683, upload-time = "2026-06-09T07:52:22.594Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/27/43/41c1621732edd934d868a00d1b891584c892a7b62a9aab82ea5a0a5623ee/safetensors-0.8.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8e080062fcde23be189565e1c3305d16751a218ecf9412c8601e64204eb6f846", size = 722361, upload-time = "2026-06-09T07:52:23.924Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8e/3f/73ccf82579412b4a71c4ca673f10b5f1f888d7cf5af7fe24f27d30307be4/safetensors-0.8.0-cp310-abi3-win32.whl", hash = "sha256:2ddf52eac562eda224f99acfa7889d02968c1fd59a5b011ae7d8137c37e9c02d", size = 342401, upload-time = "2026-06-09T07:52:28.895Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1b/6d/3fba214c1e5e0f69991677ec3bc17023f0421776975e1de0c682dca475e2/safetensors-0.8.0-cp310-abi3-win_amd64.whl", hash = "sha256:096ec1a98435df7beb08853bb5aa9081a84f23d0adc67ed1a0a10550f608373f", size = 355540, upload-time = "2026-06-09T07:52:27.832Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/fc/7eedc3510d97878876e32774eebbeb61c43f148a96e915c84229a3e967aa/safetensors-0.8.0-cp310-abi3-win_arm64.whl", hash = "sha256:f7838e5135a406ad3e02efdcb8cf2e5397d368b0154537c4fec682dbc544d452", size = 340500, upload-time = "2026-06-09T07:52:26.745Z" }, +] + [[package]] name = "sales-assistant-py" version = "0.1.0" @@ -2248,9 +2465,12 @@ dependencies = [ { name = "langchain-huggingface" }, { name = "langgraph" }, { name = "loguru" }, + { name = "numpy" }, { name = "omegaconf" }, { name = "pymilvus" }, { name = "pyyaml" }, + { name = "scikit-learn" }, + { name = "sentence-transformers" }, { name = "sqlalchemy" }, ] @@ -2268,12 +2488,134 @@ requires-dist = [ { name = "langchain-huggingface", specifier = ">=1.2.2" }, { name = "langgraph", specifier = ">=1.2.4" }, { name = "loguru", specifier = ">=0.7.3" }, + { name = "numpy", specifier = ">=2.4.6" }, { name = "omegaconf", specifier = ">=2.3.0" }, { name = "pymilvus", specifier = ">=3.0.0" }, { name = "pyyaml", specifier = ">=6.0.3" }, + { name = "scikit-learn", specifier = ">=1.9.0" }, + { name = "sentence-transformers", specifier = ">=5.6.0" }, { name = "sqlalchemy", specifier = ">=2.0.50" }, ] +[[package]] +name = "scikit-learn" +version = "1.9.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "joblib" }, + { name = "narwhals" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/6f/37092bdb25f712817231799fc5674d8e704066a8a70c1d2d40517e18b4ab/scikit_learn-1.9.0.tar.gz", hash = "sha256:8833266989d3a5110178a9fae30783675460724d0e1efb13b14901d2c660c557", size = 7750767, upload-time = "2026-06-02T11:54:32.706Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ac/20/75f915ff375d6249e6550ac740fdbbd66159a068fd3af1400ff62036b07a/scikit_learn-1.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2bd41b0d201bc81575531b96b713d3eb5e5f50fb0b82101ff0f92294fdc236ac", size = 8741122, upload-time = "2026-06-02T11:53:24.08Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/d5/2b5148f2279196775e1db2aeb85d14b70ac80e7e32b3b28e7ebeafb0901d/scikit_learn-1.9.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:5be45aa4a42a68a533913a6ed736cf309de2226411c79ef8d609a5456f1939b1", size = 8261512, upload-time = "2026-06-02T11:53:27.183Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/ee/5adbc77656b71f9456a2f5a7a9fdb4bcf9207a6b962889f1c2f9323afa4e/scikit_learn-1.9.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e50ed4da51974e86e940690e9a3d82e729b62b5a49f7c9bac534d515d39d86f", size = 8837603, upload-time = "2026-06-02T11:53:30.328Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/c2/63fdda36c56437eeb44aaf9493c8bcd62ce230ab1598924fc626ffbfa943/scikit_learn-1.9.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:056c92bb67ad4c28463c2f2653d9701449201e7e7a9e94e321be0f71c4fef2b8", size = 9132097, upload-time = "2026-06-02T11:53:33.456Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/a4/c8e67227c680e2259c8864ae72ff48b06e16a6f51253a22167aa02a8aa4e/scikit_learn-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:4306775fad04cc4b472a1b15af1ae9cede1540fbfcc17fbce3767cd8dc7ae283", size = 8211173, upload-time = "2026-06-02T11:53:36.602Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/fd/3c0863792e98e67e9184aa4029288a175935eb65443afcd30d4f143450cf/scikit_learn-1.9.0-cp312-cp312-win_arm64.whl", hash = "sha256:26e22435f63bcdcf396b574273f29f13dd531f5ea035801f5be10ba1540a4e60", size = 7867451, upload-time = "2026-06-02T11:53:39.075Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/01/cf3310626b6d48d3e9be69a1223f9180360b5e6edb045f50fade723ce494/scikit_learn-1.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:80746d63bd4b6eaca54d36fe5feaf4d28bb38dc6f9470f81c7cad7c40155f119", size = 8705188, upload-time = "2026-06-02T11:53:41.964Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/04/5acd7ae280c5f93b6ac5ef6cdec14eef4c8d1cd91d85b3292989c94d96b1/scikit_learn-1.9.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5b934c45c252844a91d69fda3a34cff5e7307e1db10d77cb10a3980312c74713", size = 8228299, upload-time = "2026-06-02T11:53:44.817Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/39/ffe829a5b8ecb40a518724a997794657fdc354ada5e8fe8e64d998c0bac9/scikit_learn-1.9.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:38c3dcb9a1ffb85505ec53d54c7b4aea0cff70050425a7760c2af661ac85df05", size = 8789690, upload-time = "2026-06-02T11:53:47.461Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/88/8dab5de10c638c083772a6be83a3d8106ced492f74a928c8693638e5bb50/scikit_learn-1.9.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da76d09304a4706db7cc1e3ebaa3b6b98a67365cc11d2996c4f1e58ba47df714", size = 9087723, upload-time = "2026-06-02T11:53:50.702Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/3f/7917ca72464038f6240ec70c29f94862d08a34a74291ae4d4ec5eb8186a0/scikit_learn-1.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:5808d98f15c6bf6d9d96d2348c1997392a5888ce7097e664105f930c4bca1277", size = 8184330, upload-time = "2026-06-02T11:53:53.396Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/c7/15739eb2f61fda3c54639e9942414e5a19ad8a8d1f5a3266afad7cb7df80/scikit_learn-1.9.0-cp313-cp313-win_arm64.whl", hash = "sha256:d77f54c017633791bc0225a43e2f8d03745fdcfe4880268fcc4df15f505dec2e", size = 7840653, upload-time = "2026-06-02T11:53:56.035Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/7d/c9a35cf59b20a86fec24d306f1547b78dec194b08d367ce2a3e4854169d9/scikit_learn-1.9.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9656acd4e93f74e0b66c8a36c88830a99252dfa900044d36bc2212ae89a47162", size = 8713289, upload-time = "2026-06-02T11:53:58.788Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/a7/552a7821597c632b907f7bfe8f36f9f572777af8ef8a48353041cf8e091a/scikit_learn-1.9.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:24360002ae845e7866522b0a5bbf690802e7bc388cac8663502e78aa98598aa2", size = 8245141, upload-time = "2026-06-02T11:54:01.694Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7d/79/f4a0c4fe9711154cddabf913471153af79056382ddc612cfe5ee0ff4b72e/scikit_learn-1.9.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5162ad10a418c8a282dde04c9aa06965de3e9a65f33c1440c0ae69bb1a09d913", size = 8847671, upload-time = "2026-06-02T11:54:04.448Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f0/af/4d72d9e475ac83719160c662619e4bf7b95c19507cd582e7d0167a3c3dae/scikit_learn-1.9.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fea2cc5677ab49d6f5bade978c866da44957b712d92e9635e8b4f723013c3cb", size = 9118104, upload-time = "2026-06-02T11:54:07.205Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/d5/6a58eea2cb9abbb9b3f2bb8b2cfb3243d1152d69f442d256c7af71304769/scikit_learn-1.9.0-cp314-cp314-win_amd64.whl", hash = "sha256:64fa347efc1c839c487433e40c5144d38c336e8a2b59c81aa8660373945c2673", size = 8290674, upload-time = "2026-06-02T11:54:10.087Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/5b/d4c879cf358f1187141cf90ced473f087183489090244f50c124a2ee478b/scikit_learn-1.9.0-cp314-cp314-win_arm64.whl", hash = "sha256:1b944b6db288f6b926e3650026ddafb988929de95d11fc2cc5fa117773c9ba42", size = 7978807, upload-time = "2026-06-02T11:54:12.769Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/43/bfae3121ec67ae09150d453c442c7c1cc166e9aefe056e6ab3b7728a5cfc/scikit_learn-1.9.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:4ccacf04ca5f4b492158a5f28afe0ace43f81b2571e4b9a66d34848b46128949", size = 9031941, upload-time = "2026-06-02T11:54:15.436Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/75/b0/20a4546eb17f3b25d3c66df15810411c14ed5065bcfab50b53c96fb627b2/scikit_learn-1.9.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:ee1a8db2c18c08e34c7412d4b10be1cac214cd4ea7dc9715a6a327eb49a37c96", size = 8613528, upload-time = "2026-06-02T11:54:18.842Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/3c/e440e039bb82cd19004edaaad00acbde0fb9b461083c3ecf37941c557312/scikit_learn-1.9.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:147e9329ef0e39f75d4cffa02b2aa48d827832684926cd5210d9a2cb5c57246b", size = 8855050, upload-time = "2026-06-02T11:54:21.699Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/26/b341b8dab5998da6270a3a42c2152c578501354d36f944b5856757035ef8/scikit_learn-1.9.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bad8f8b9950321b54c965fdcbac6c6c55e79e16646b49977bcf3668d3870a1a", size = 9097190, upload-time = "2026-06-02T11:54:24.454Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fb/de/b650b4d69b84468cfa2e28a3ff7b8103743029e6446ce1a97fe060ef688c/scikit_learn-1.9.0-cp314-cp314t-win_amd64.whl", hash = "sha256:78fc56eafd4edb9575d2d8950d1dd152061abb573341a1cb7e099fc40f6c6666", size = 8963204, upload-time = "2026-06-02T11:54:27.428Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/f3/ff83d76d7418112e5a61326443cdda87be3545dd8d6599c95b2481a4419e/scikit_learn-1.9.0-cp314-cp314t-win_arm64.whl", hash = "sha256:051075bda8b7aab87b1906ab3d4740a1e1224a19d7b3781a576736edc94e76aa", size = 8222661, upload-time = "2026-06-02T11:54:30.192Z" }, +] + +[[package]] +name = "scipy" +version = "1.17.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/48/b992b488d6f299dbe3f11a20b24d3dda3d46f1a635ede1c46b5b17a7b163/scipy-1.17.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", size = 31610954, upload-time = "2026-02-23T00:17:49.855Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/02/cf107b01494c19dc100f1d0b7ac3cc08666e96ba2d64db7626066cee895e/scipy-1.17.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76", size = 28172662, upload-time = "2026-02-23T00:18:01.64Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/a9/599c28631bad314d219cf9ffd40e985b24d603fc8a2f4ccc5ae8419a535b/scipy-1.17.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", size = 20344366, upload-time = "2026-02-23T00:18:12.015Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/f5/906eda513271c8deb5af284e5ef0206d17a96239af79f9fa0aebfe0e36b4/scipy-1.17.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b", size = 22704017, upload-time = "2026-02-23T00:18:21.502Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/34/16f10e3042d2f1d6b66e0428308ab52224b6a23049cb2f5c1756f713815f/scipy-1.17.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", size = 32927842, upload-time = "2026-02-23T00:18:35.367Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/8e/1e35281b8ab6d5d72ebe9911edcdffa3f36b04ed9d51dec6dd140396e220/scipy-1.17.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", size = 35235890, upload-time = "2026-02-23T00:18:49.188Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c5/5c/9d7f4c88bea6e0d5a4f1bc0506a53a00e9fcb198de372bfe4d3652cef482/scipy-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", size = 35003557, upload-time = "2026-02-23T00:18:54.74Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/94/7698add8f276dbab7a9de9fb6b0e02fc13ee61d51c7c3f85ac28b65e1239/scipy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", size = 37625856, upload-time = "2026-02-23T00:19:00.307Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/84/dc08d77fbf3d87d3ee27f6a0c6dcce1de5829a64f2eae85a0ecc1f0daa73/scipy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87", size = 36549682, upload-time = "2026-02-23T00:19:07.67Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bc/98/fe9ae9ffb3b54b62559f52dedaebe204b408db8109a8c66fdd04869e6424/scipy-1.17.1-cp312-cp312-win_arm64.whl", hash = "sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3", size = 24547340, upload-time = "2026-02-23T00:19:12.024Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", size = 31590199, upload-time = "2026-02-23T00:19:17.192Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", size = 28154001, upload-time = "2026-02-23T00:19:22.241Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", size = 20325719, upload-time = "2026-02-23T00:19:26.329Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/83/15087d945e0e4d48ce2377498abf5ad171ae013232ae31d06f336e64c999/scipy-1.17.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", size = 22683595, upload-time = "2026-02-23T00:19:30.304Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429, upload-time = "2026-02-23T00:19:35.536Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952, upload-time = "2026-02-23T00:19:42.259Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063, upload-time = "2026-02-23T00:19:47.547Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449, upload-time = "2026-02-23T00:19:53.238Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", size = 36510943, upload-time = "2026-02-23T00:20:50.89Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/fd/3be73c564e2a01e690e19cc618811540ba5354c67c8680dce3281123fb79/scipy-1.17.1-cp313-cp313-win_arm64.whl", hash = "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", size = 24545621, upload-time = "2026-02-23T00:20:55.871Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6f/6b/17787db8b8114933a66f9dcc479a8272e4b4da75fe03b0c282f7b0ade8cd/scipy-1.17.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", size = 31936708, upload-time = "2026-02-23T00:19:58.694Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/2e/524405c2b6392765ab1e2b722a41d5da33dc5c7b7278184a8ad29b6cb206/scipy-1.17.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", size = 28570135, upload-time = "2026-02-23T00:20:03.934Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/c3/5bd7199f4ea8556c0c8e39f04ccb014ac37d1468e6cfa6a95c6b3562b76e/scipy-1.17.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", size = 20741977, upload-time = "2026-02-23T00:20:07.935Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/b8/8ccd9b766ad14c78386599708eb745f6b44f08400a5fd0ade7cf89b6fc93/scipy-1.17.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", size = 23029601, upload-time = "2026-02-23T00:20:12.161Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667, upload-time = "2026-02-23T00:20:17.208Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159, upload-time = "2026-02-23T00:20:23.087Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771, upload-time = "2026-02-23T00:20:28.636Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910, upload-time = "2026-02-23T00:20:34.743Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/06/1c/1172a88d507a4baaf72c5a09bb6c018fe2ae0ab622e5830b703a46cc9e44/scipy-1.17.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", size = 36562980, upload-time = "2026-02-23T00:20:40.575Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/b0/eb757336e5a76dfa7911f63252e3b7d1de00935d7705cf772db5b45ec238/scipy-1.17.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", size = 24856543, upload-time = "2026-02-23T00:20:45.313Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cf/83/333afb452af6f0fd70414dc04f898647ee1423979ce02efa75c3b0f2c28e/scipy-1.17.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", size = 31584510, upload-time = "2026-02-23T00:21:01.015Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/a6/d05a85fd51daeb2e4ea71d102f15b34fedca8e931af02594193ae4fd25f7/scipy-1.17.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", size = 28170131, upload-time = "2026-02-23T00:21:05.888Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/db/7b/8624a203326675d7746a254083a187398090a179335b2e4a20e2ddc46e83/scipy-1.17.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", size = 20342032, upload-time = "2026-02-23T00:21:09.904Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/35/2c342897c00775d688d8ff3987aced3426858fd89d5a0e26e020b660b301/scipy-1.17.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", size = 22678766, upload-time = "2026-02-23T00:21:14.313Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007, upload-time = "2026-02-23T00:21:19.663Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333, upload-time = "2026-02-23T00:21:25.278Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066, upload-time = "2026-02-23T00:21:31.358Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763, upload-time = "2026-02-23T00:21:37.247Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/39/f0e8ea762a764a9dc52aa7dabcfad51a354819de1f0d4652b6a1122424d6/scipy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", size = 37290984, upload-time = "2026-02-23T00:22:35.023Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/56/fe201e3b0f93d1a8bcf75d3379affd228a63d7e2d80ab45467a74b494947/scipy-1.17.1-cp314-cp314-win_arm64.whl", hash = "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", size = 25192877, upload-time = "2026-02-23T00:22:39.798Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/ad/f8c414e121f82e02d76f310f16db9899c4fcde36710329502a6b2a3c0392/scipy-1.17.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", size = 31949750, upload-time = "2026-02-23T00:21:42.289Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/b0/c741e8865d61b67c81e255f4f0a832846c064e426636cd7de84e74d209be/scipy-1.17.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", size = 28585858, upload-time = "2026-02-23T00:21:47.706Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/1b/3985219c6177866628fa7c2595bfd23f193ceebbe472c98a08824b9466ff/scipy-1.17.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", size = 20757723, upload-time = "2026-02-23T00:21:52.039Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/19/2a04aa25050d656d6f7b9e7b685cc83d6957fb101665bfd9369ca6534563/scipy-1.17.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", size = 23043098, upload-time = "2026-02-23T00:21:56.185Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397, upload-time = "2026-02-23T00:22:01.404Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163, upload-time = "2026-02-23T00:22:07.024Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291, upload-time = "2026-02-23T00:22:12.585Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317, upload-time = "2026-02-23T00:22:18.513Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/2f/b29eafe4a3fbc3d6de9662b36e028d5f039e72d345e05c250e121a230dd4/scipy-1.17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", size = 37345327, upload-time = "2026-02-23T00:22:24.442Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/39/338d9219c4e87f3e708f18857ecd24d22a0c3094752393319553096b98af/scipy-1.17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", size = 25489165, upload-time = "2026-02-23T00:22:29.563Z" }, +] + +[[package]] +name = "sentence-transformers" +version = "5.6.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "scikit-learn" }, + { name = "scipy" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "transformers" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/56/d2cb00765a6b15c994a7fccf20f9032f16e8193ca49147cb5155166ad744/sentence_transformers-5.6.0.tar.gz", hash = "sha256:0e7164d051e416c1853ade7c274ff52af3f9da0f4be7f0b83d734c27699e1057", size = 453194, upload-time = "2026-06-16T14:01:56.42Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/c1/dc1582b79e9a2eb0cddf9559cd9bcdff084f541d6fe881fdd9d98630dba7/sentence_transformers-5.6.0-py3-none-any.whl", hash = "sha256:d2075b5e687a1611005e20ab04a6846994d51adfcf39610aed066af3c0c0b81f", size = 596411, upload-time = "2026-06-16T14:01:55.103Z" }, +] + [[package]] name = "sentry-sdk" version = "2.62.0" @@ -2377,6 +2719,18 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/54/196d0c1db10af76baa4f64894448505d60d3cdf70ef92cbb35f46a4e4c71/starlette-1.2.1-py3-none-any.whl", hash = "sha256:4de0082d08c8f6764a85a54cf1120d6939507a19905c7768acad2a9f875d2b89", size = 73350, upload-time = "2026-05-31T01:07:50.09Z" }, ] +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + [[package]] name = "tenacity" version = "9.1.4" @@ -2386,6 +2740,15 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" }, ] +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, +] + [[package]] name = "tiktoken" version = "0.13.0" @@ -2435,29 +2798,88 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.23.1" +version = "0.22.2" source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/60/21f715d9faba5f5407ff759472ade058ec4a507ad62bcea47cb847239a73/tokenizers-0.23.1.tar.gz", hash = "sha256:1feeeadf865a7915adc25445dea30e9933e593c31bb96c277cee36de227c8bfa", size = 365748, upload-time = "2026-04-27T14:43:25.606Z" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/6f/f80cfef4a312e1fb34baf7d85c72d4411afde10978d4657f8cdd811d3ccc/tokenizers-0.22.2.tar.gz", hash = "sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917", size = 372115, upload-time = "2026-01-05T10:45:15.988Z" } wheels = [ - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/39/b87a87d5bb9470610b80a2d31df42fcffeaf35118b8b97952b2aff598cc7/tokenizers-0.23.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e03d6ffcbe0d56ee9c1ccd070e70a13fa750727c0277e138152acbc0252c2224", size = 3146732, upload-time = "2026-04-27T14:43:15.427Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/6a/068ed9f6e444c9d7e9d55ce134181325700f3d7f30410721bdc8f848d727/tokenizers-0.23.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:e0948bbb1ac1d7cdfc9fb6d62c596e3b7550036ad60ecd654a66ad273326324e", size = 3054954, upload-time = "2026-04-27T14:43:13.745Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/36/e006edf031154cba92b8416057d92c3abe3635e4c4b0aa0b5b9bb39dde70/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bf13402aff9bc533c89cb849ec3b412dc3fbeacc9744840e423d7bf3f7dc0e3", size = 3374081, upload-time = "2026-04-27T14:43:01.241Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/ef/7735d226f9c7f874a6bee5e3f27fb25ecabdf207d37b8cf45286d0795893/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f836ca703b89ae07919a309f9651f7a88fd5a33d5f718ba5ad0870ec0256bad6", size = 3247641, upload-time = "2026-04-27T14:43:03.856Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/d9/24827036f6e21297bfffda0768e58eb6096a4f411e932964a01707857931/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae848657742035523fdf261773630cb819a26995fcd3d9ecae0c1daf6e5a4959", size = 3585624, upload-time = "2026-04-27T14:43:10.664Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/9a/22f3582b3a4f49358293a5206e25317621ee4526bfe9cdaa0f07a12e770e/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53b09e85775d5187941e7bab30e941b4134ab4a7dd8c68e783d231fb7ca27c51", size = 3844062, upload-time = "2026-04-27T14:43:05.643Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/65/b8f8814eef95800f20721384136d9a1d22241d50b2874357cb70542c392f/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea5a0ce170074329faaa8ea3f6400ecde604b6678192688533af80980daae71a", size = 3460098, upload-time = "2026-04-27T14:43:08.854Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/d5/1353e5f677ec27c2494fb6a6725e82d56c985f53e90ec511369e7e4f02c6/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5075b405006415ea148a992d093699c66eb01952bf59f4d5727089a98bda45a4", size = 3346235, upload-time = "2026-04-27T14:43:12.377Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/89/39b6b8fc073fb6d413d0147aa333dc7eff7be65639ac9d19930a0b21bf33/tokenizers-0.23.1-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:56f3a77de629917652f876294dc9fe6bad4a0c43bc229dc72e59bb23a0f4729a", size = 3426398, upload-time = "2026-04-27T14:43:07.264Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0f/80/127c854da64827e5b79264ce524993a90dddcb320e5cd42412c5c02f9e8a/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9d10a6d957ef01896dc274e890eee27d41bd0e74ef31e60616f0fc311345184e", size = 9823279, upload-time = "2026-04-27T14:43:17.222Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/ba/44c2502feb1a058f096ddfb4e0996ef3225a01a388e1a9b094e91689fe93/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1974288a609c343774f1b897c8b482c791ab17b75ab5c8c2b1737565c1d82288", size = 9644986, upload-time = "2026-04-27T14:43:19.45Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/c1/464019a9fb059870bfe4eebb4ba12208f3042035e258bf5e782906bd3847/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:120468fb4c24faf0543c835a4fabafa4deb3f20a035c9b6e83d0b553a97615d4", size = 9976181, upload-time = "2026-04-27T14:43:21.463Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/79/94/3ac1432bda31626071e9b6a12709b97ae05131c804b94c8f3ac622c5da32/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e3d8f40ea6268047de7046906326abed5134f27d4e8447b23763afe5808c8a96", size = 10113853, upload-time = "2026-04-27T14:43:23.617Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/dd/631b21433c771b1382535326f0eca80b9c9cee2e64961dd993bc9ac4669e/tokenizers-0.23.1-cp310-abi3-win32.whl", hash = "sha256:93120a930b919416da7cd10a2f606ac9919cc69cacae7980fa2140e277660948", size = 2536263, upload-time = "2026-04-27T14:43:29.888Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/97/c9/2553f72aaf65a2797d4229e37fa7fbe38ffbf3e32912d31bdd78b3323e59/tokenizers-0.23.1-cp310-abi3-win_amd64.whl", hash = "sha256:e7bfaf995c1bdbbd21d13539decb6650967013759318627d85daeb7881af16b7", size = 2798223, upload-time = "2026-04-27T14:43:28.51Z" }, - { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cd/2b/2be299bab55fc595e3d38567edb1a87f86e594842968fa9515a07bdcf422/tokenizers-0.23.1-cp310-abi3-win_arm64.whl", hash = "sha256:a26197957d8e4425dfba746315f3c425ea00cfa8367c5fbc4ec73447893dcea9", size = 2664127, upload-time = "2026-04-27T14:43:26.949Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/97/5dbfabf04c7e348e655e907ed27913e03db0923abb5dfdd120d7b25630e1/tokenizers-0.22.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c", size = 3100275, upload-time = "2026-01-05T10:41:02.158Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/47/174dca0502ef88b28f1c9e06b73ce33500eedfac7a7692108aec220464e7/tokenizers-0.22.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001", size = 2981472, upload-time = "2026-01-05T10:41:00.276Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d6/84/7990e799f1309a8b87af6b948f31edaa12a3ed22d11b352eaf4f4b2e5753/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7", size = 3290736, upload-time = "2026-01-05T10:40:32.165Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/59/09d0d9ba94dcd5f4f1368d4858d24546b4bdc0231c2354aa31d6199f0399/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd", size = 3168835, upload-time = "2026-01-05T10:40:38.847Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/47/50/b3ebb4243e7160bda8d34b731e54dd8ab8b133e50775872e7a434e524c28/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5", size = 3521673, upload-time = "2026-01-05T10:40:56.614Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/fa/89f4cb9e08df770b57adb96f8cbb7e22695a4cb6c2bd5f0c4f0ebcf33b66/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e", size = 3724818, upload-time = "2026-01-05T10:40:44.507Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/04/ca2363f0bfbe3b3d36e95bf67e56a4c88c8e3362b658e616d1ac185d47f2/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b", size = 3379195, upload-time = "2026-01-05T10:40:51.139Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67", size = 3274982, upload-time = "2026-01-05T10:40:58.331Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1d/28/5f9f5a4cc211b69e89420980e483831bcc29dade307955cc9dc858a40f01/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4", size = 9478245, upload-time = "2026-01-05T10:41:04.053Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/fb/66e2da4704d6aadebf8cb39f1d6d1957df667ab24cff2326b77cda0dcb85/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a", size = 9560069, upload-time = "2026-01-05T10:45:10.673Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/16/04/fed398b05caa87ce9b1a1bb5166645e38196081b225059a6edaff6440fac/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a", size = 9899263, upload-time = "2026-01-05T10:45:12.559Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/a1/d62dfe7376beaaf1394917e0f8e93ee5f67fea8fcf4107501db35996586b/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5", size = 10033429, upload-time = "2026-01-05T10:45:14.333Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/18/a545c4ea42af3df6effd7d13d250ba77a0a86fb20393143bbb9a92e434d4/tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92", size = 2502363, upload-time = "2026-01-05T10:45:20.593Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48", size = 2747786, upload-time = "2026-01-05T10:45:18.411Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" }, +] + +[[package]] +name = "torch" +version = "2.10.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "cuda-bindings", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d3/54/a2ba279afcca44bbd320d4e73675b282fcee3d81400ea1b53934efca6462/torch-2.10.0-2-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:13ec4add8c3faaed8d13e0574f5cd4a323c11655546f91fbe6afa77b57423574", size = 79498202, upload-time = "2026-02-10T21:44:52.603Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/23/2c9fe0c9c27f7f6cb865abcea8a4568f29f00acaeadfc6a37f6801f84cb4/torch-2.10.0-2-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:e521c9f030a3774ed770a9c011751fb47c4d12029a3d6522116e48431f2ff89e", size = 79498254, upload-time = "2026-02-10T21:44:44.095Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/7a/abada41517ce0011775f0f4eacc79659bc9bc6c361e6bfe6f7052a6b9363/torch-2.10.0-3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:98c01b8bb5e3240426dcde1446eed6f40c778091c8544767ef1168fc663a05a6", size = 915622781, upload-time = "2026-03-11T14:17:11.354Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/c6/4dfe238342ffdcec5aef1c96c457548762d33c40b45a1ab7033bb26d2ff2/torch-2.10.0-3-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:80b1b5bfe38eb0e9f5ff09f206dcac0a87aadd084230d4a36eea5ec5232c115b", size = 915627275, upload-time = "2026-03-11T14:16:11.325Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/f0/72bf18847f58f877a6a8acf60614b14935e2f156d942483af1ffc081aea0/torch-2.10.0-3-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:46b3574d93a2a8134b3f5475cfb98e2eb46771794c57015f6ad1fb795ec25e49", size = 915523474, upload-time = "2026-03-11T14:17:44.422Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/39/590742415c3030551944edc2ddc273ea1fdfe8ffb2780992e824f1ebee98/torch-2.10.0-3-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:b1d5e2aba4eb7f8e87fbe04f86442887f9167a35f092afe4c237dfcaaef6e328", size = 915632474, upload-time = "2026-03-11T14:15:13.666Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/8e/34949484f764dde5b222b7fe3fede43e4a6f0da9d7f8c370bb617d629ee2/torch-2.10.0-3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:0228d20b06701c05a8f978357f657817a4a63984b0c90745def81c18aedfa591", size = 915523882, upload-time = "2026-03-11T14:14:46.311Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/af/758e242e9102e9988969b5e621d41f36b8f258bb4a099109b7a4b4b50ea4/torch-2.10.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:5fd4117d89ffd47e3dcc71e71a22efac24828ad781c7e46aaaf56bf7f2796acf", size = 145996088, upload-time = "2026-01-21T16:24:44.171Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/23/8e/3c74db5e53bff7ed9e34c8123e6a8bfef718b2450c35eefab85bb4a7e270/torch-2.10.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:787124e7db3b379d4f1ed54dd12ae7c741c16a4d29b49c0226a89bea50923ffb", size = 915711952, upload-time = "2026-01-21T16:23:53.503Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/01/624c4324ca01f66ae4c7cd1b74eb16fb52596dce66dbe51eff95ef9e7a4c/torch-2.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:2c66c61f44c5f903046cc696d088e21062644cbe541c7f1c4eaae88b2ad23547", size = 113757972, upload-time = "2026-01-21T16:24:39.516Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/5c/dee910b87c4d5c0fcb41b50839ae04df87c1cfc663cf1b5fca7ea565eeaa/torch-2.10.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:6d3707a61863d1c4d6ebba7be4ca320f42b869ee657e9b2c21c736bf17000294", size = 79498198, upload-time = "2026-01-21T16:24:34.704Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/6f/f2e91e34e3fcba2e3fc8d8f74e7d6c22e74e480bbd1db7bc8900fdf3e95c/torch-2.10.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5c4d217b14741e40776dd7074d9006fd28b8a97ef5654db959d8635b2fe5f29b", size = 146004247, upload-time = "2026-01-21T16:24:29.335Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/fb/5160261aeb5e1ee12ee95fe599d0541f7c976c3701d607d8fc29e623229f/torch-2.10.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6b71486353fce0f9714ca0c9ef1c850a2ae766b409808acd58e9678a3edb7738", size = 915716445, upload-time = "2026-01-21T16:22:45.353Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/16/502fb1b41e6d868e8deb5b0e3ae926bbb36dab8ceb0d1b769b266ad7b0c3/torch-2.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:c2ee399c644dc92ef7bc0d4f7e74b5360c37cdbe7c5ba11318dda49ffac2bc57", size = 113757050, upload-time = "2026-01-21T16:24:19.204Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1a/0b/39929b148f4824bc3ad6f9f72a29d4ad865bcf7ebfc2fa67584773e083d2/torch-2.10.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:3202429f58309b9fa96a614885eace4b7995729f44beb54d3e4a47773649d382", size = 79851305, upload-time = "2026-01-21T16:24:09.209Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/14/21fbce63bc452381ba5f74a2c0a959fdf5ad5803ccc0c654e752e0dbe91a/torch-2.10.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:aae1b29cd68e50a9397f5ee897b9c24742e9e306f88a807a27d617f07adb3bd8", size = 146005472, upload-time = "2026-01-21T16:22:29.022Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/fd/b207d1c525cb570ef47f3e9f836b154685011fce11a2f444ba8a4084d042/torch-2.10.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6021db85958db2f07ec94e1bc77212721ba4920c12a18dc552d2ae36a3eb163f", size = 915612644, upload-time = "2026-01-21T16:21:47.019Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/53/0197f868c75f1050b199fe58f9bf3bf3aecac9b4e85cc9c964383d745403/torch-2.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff43db38af76fda183156153983c9a096fc4c78d0cd1e07b14a2314c7f01c2c8", size = 113997015, upload-time = "2026-01-21T16:23:00.767Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/13/e76b4d9c160e89fff48bf16b449ea324bda84745d2ab30294c37c2434c0d/torch-2.10.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:cdf2a523d699b70d613243211ecaac14fe9c5df8a0b0a9c02add60fb2a413e0f", size = 79498248, upload-time = "2026-01-21T16:23:09.315Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/93/716b5ac0155f1be70ed81bacc21269c3ece8dba0c249b9994094110bfc51/torch-2.10.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:bf0d9ff448b0218e0433aeb198805192346c4fd659c852370d5cc245f602a06a", size = 79464992, upload-time = "2026-01-21T16:23:05.162Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/2b/51e663ff190c9d16d4a8271203b71bc73a16aa7619b9f271a69b9d4a936b/torch-2.10.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:233aed0659a2503b831d8a67e9da66a62c996204c0bba4f4c442ccc0c68a3f60", size = 146018567, upload-time = "2026-01-21T16:22:23.393Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5e/cd/4b95ef7f293b927c283db0b136c42be91c8ec6845c44de0238c8c23bdc80/torch-2.10.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:682497e16bdfa6efeec8cde66531bc8d1fbbbb4d8788ec6173c089ed3cc2bfe5", size = 915721646, upload-time = "2026-01-21T16:21:16.983Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/56/97/078a007208f8056d88ae43198833469e61a0a355abc0b070edd2c085eb9a/torch-2.10.0-cp314-cp314-win_amd64.whl", hash = "sha256:6528f13d2a8593a1a412ea07a99812495bec07e9224c28b2a25c0a30c7da025c", size = 113752373, upload-time = "2026-01-21T16:22:13.471Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/94/71994e7d0d5238393df9732fdab607e37e2b56d26a746cb59fdb415f8966/torch-2.10.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:f5ab4ba32383061be0fb74bda772d470140a12c1c3b58a0cfbf3dae94d164c28", size = 79850324, upload-time = "2026-01-21T16:22:09.494Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/65/1a05346b418ea8ccd10360eef4b3e0ce688fba544e76edec26913a8d0ee0/torch-2.10.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:716b01a176c2a5659c98f6b01bf868244abdd896526f1c692712ab36dbaf9b63", size = 146006482, upload-time = "2026-01-21T16:22:18.42Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1d/b9/5f6f9d9e859fc3235f60578fa64f52c9c6e9b4327f0fe0defb6de5c0de31/torch-2.10.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:d8f5912ba938233f86361e891789595ff35ca4b4e2ac8fe3670895e5976731d6", size = 915613050, upload-time = "2026-01-21T16:20:49.035Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/4d/35352043ee0eaffdeff154fad67cd4a31dbed7ff8e3be1cc4549717d6d51/torch-2.10.0-cp314-cp314t-win_amd64.whl", hash = "sha256:71283a373f0ee2c89e0f0d5f446039bdabe8dbc3c9ccf35f0f784908b0acd185", size = 113995816, upload-time = "2026-01-21T16:22:05.312Z" }, ] [[package]] @@ -2472,6 +2894,38 @@ wheels = [ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/75/1a0392bcc21c44dcdf87b3cf2d137e7829be2c083a1e38d44efca3d57a16/tqdm-4.68.2-py3-none-any.whl", hash = "sha256:d4240441fb5353290b87d6a85968c9decc131a99b8c7faa28269d829de669ede", size = 78578, upload-time = "2026-06-09T13:26:40.731Z" }, ] +[[package]] +name = "transformers" +version = "5.12.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "regex" }, + { name = "safetensors" }, + { name = "tokenizers" }, + { name = "tqdm" }, + { name = "typer" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/7c/8240f612819718100a9346dc28dea6a11370c3ca9c8c6eabadd3dea4ef29/transformers-5.12.1.tar.gz", hash = "sha256:679ee731c8225347889ad4fb3b2c926a62e9da3b7d284e9d12c791da7272466b", size = 8924054, upload-time = "2026-06-15T17:27:50.604Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/56/bbd60dd8668055803bf8ba55a81f9b8a8b31497f620109a9671d26a2076d/transformers-5.12.1-py3-none-any.whl", hash = "sha256:2a5e109d2021265df7098ffbb738295acaf5ad256f12cbc586db2ea4dcbb1a8a", size = 11150587, upload-time = "2026-06-15T17:27:46.679Z" }, +] + +[[package]] +name = "triton" +version = "3.6.0" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/a8/cdf8b3e4c98132f965f88c2313a4b493266832ad47fb52f23d14d4f86bb5/triton-3.6.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74caf5e34b66d9f3a429af689c1c7128daba1d8208df60e81106b115c00d6fca", size = 188266850, upload-time = "2026-01-20T16:00:43.041Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/0b/37d991d8c130ce81a8728ae3c25b6e60935838e9be1b58791f5997b24a54/triton-3.6.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10c7f76c6e72d2ef08df639e3d0d30729112f47a56b0c81672edc05ee5116ac9", size = 188289450, upload-time = "2026-01-20T16:00:49.136Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/f8/9c66bfc55361ec6d0e4040a0337fb5924ceb23de4648b8a81ae9d33b2b38/triton-3.6.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d002e07d7180fd65e622134fbd980c9a3d4211fb85224b56a0a0efbd422ab72f", size = 188400296, upload-time = "2026-01-20T16:00:56.042Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/3d/9e7eee57b37c80cec63322c0231bb6da3cfe535a91d7a4d64896fcb89357/triton-3.6.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a17a5d5985f0ac494ed8a8e54568f092f7057ef60e1b0fa09d3fd1512064e803", size = 188273063, upload-time = "2026-01-20T16:01:07.278Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f6/56/6113c23ff46c00aae423333eb58b3e60bdfe9179d542781955a5e1514cb3/triton-3.6.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:46bd1c1af4b6704e554cad2eeb3b0a6513a980d470ccfa63189737340c7746a7", size = 188397994, upload-time = "2026-01-20T16:01:14.236Z" }, +] + [[package]] name = "typer" version = "0.25.1"